/* site-v14 · LANE OPUS · "Entries & Plates", row-locked.
   Entries left, plates right; each plate hangs from the first line of its entry
   and scrolls with it. No JS in the layout. Fonts: ms10-* (Geist / Geist Mono, OFL 1.1). */

@font-face {
  font-family: "MS10 Geist";
  src: url("/assets/fonts/ms10-geist-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "MS10 Geist";
  src: url("/assets/fonts/ms10-geist-500.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
/* iRoll plate artwork only (founder exception r3): the hero's own faces, OFL 1.1. */
@font-face {
  font-family: "MS10 Barlow Condensed";
  src: url("/assets/fonts/ms10-barlow-condensed-900.woff2") format("woff2");
  font-weight: 900;
  font-style: normal;
  font-display: block;
}
@font-face {
  font-family: "MS10 DM Mono";
  src: url("/assets/fonts/ms10-dm-mono-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: block;
}
@font-face {
  font-family: "MS10 Geist Mono";
  src: url("/assets/fonts/ms10-geist-mono-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

:root {
  /* One ink on warm paper. Colour enters only through plates. */
  --paper: oklch(98.2% 0.0041 91.4);   /* #faf9f6 */
  --ink: oklch(19.08% 0.002 106.6);    /* #141413 · 17.5:1 on paper */
  --grey: oklch(39.45% 0.0036 84.6);   /* #474644 · 8.9:1 on paper */
  --underline: color-mix(in oklch, var(--ink) 40%, var(--paper));

  --sans: "MS10 Geist", system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
  --mono: "MS10 Geist Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  /* Two sizes: 15px sentences, 11px tracked caps. */
  --fs: 0.9375rem;
  --lh: 1.6;
  --fs-s: 0.6875rem;
  --lh-s: 1.5;
  --track: 0.1em;
  /* Line-box top to cap top of a caps line: half-leading + (ascent − cap height).
     Geist Mono: ascent 1.005, descent 0.295, cap 0.71 → (1.5 − 1.3) / 2 + 0.295 = 0.395em. */
  --cap: calc(var(--fs-s) * 0.395);

  --margin: clamp(1.25rem, 2.78vw, 2.5rem);
  --gap-entry: clamp(3.5rem, 6.67vw, 6rem);
  --measure: 34em;

  color-scheme: light;
  scrollbar-gutter: stable;
  text-wrap: pretty;
  overflow-wrap: break-word;
  font-synthesis: none;
  -webkit-text-size-adjust: 100%;
  -webkit-tap-highlight-color: transparent;
}

*,
*::before,
*::after {
  box-sizing: border-box;
  min-width: 0;
}

html {
  background: var(--paper);
  color: var(--ink);
}

body {
  margin: 0 auto;
  max-inline-size: 90rem;
  min-block-size: 100svh;
  padding-inline: var(--margin);
  font: 400 var(--fs) / var(--lh) var(--sans);
  font-kerning: normal;
}

h1, h2, p, ul, figure { margin: 0; }
ul { padding: 0; list-style: none; }
b { font-weight: 500; }
img, video {
  display: block;
  max-inline-size: 100%;
  block-size: auto;
}
[hidden] { display: none !important; }
/* Read by screen readers, never seen: the deck's a11y.new_tab on links that open a new tab. */
.vh {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ---------- the small register: tracked caps ---------- */

.wordmark,
.nav,
.label,
.title,
.plate figcaption,
.logo figcaption,
.swatches li,
.ctl,
.foot {
  font-family: var(--mono);
  font-size: var(--fs-s);
  line-height: var(--lh-s);
  font-weight: 400;
  letter-spacing: var(--track);
}
.label,
.title,
.plate figcaption,
.logo figcaption { text-transform: uppercase; }
.title { text-wrap: balance; }
.label,
.plate figcaption,
.logo figcaption,
.swatches li,
.ctl,
.foot { color: var(--grey); }

/* ---------- links: text, underlined; external ones carry ↗ ---------- */

a {
  color: inherit;
  text-decoration-line: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.24em;
  text-decoration-color: var(--underline);
  touch-action: manipulation;
}
a:active { opacity: 0.6; }
.ext::after {
  content: "\2009\2197";
  content: "\2009\2197" / "";
  text-decoration-line: none;
}
.wordmark a,
.nav a { text-decoration-line: none; }
.nav a[aria-current="page"] {
  text-decoration-line: underline;
  text-decoration-color: currentColor;
}

@media (hover: hover) and (pointer: fine) {
  a:hover { text-decoration-color: currentColor; }
  .wordmark a:hover,
  .nav a:hover { text-decoration-line: underline; }
}

:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
}

/* ---------- masthead: letter-spaced name, tiny caps nav ---------- */

.mast {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  row-gap: 1.25rem;
  padding-block-start: var(--margin);
}
.wordmark {
  grid-area: 1 / 1;
  font-size: var(--fs);
  letter-spacing: 0.5em;
}
.wordmark a { display: inline-block; padding-block: 0.25rem; }
.nav {
  grid-area: 2 / 1 / 3 / 3;
  display: flex;
  justify-content: space-between;
  column-gap: 1.25rem;
}
.nav-main { display: flex; column-gap: 1.25rem; }
.nav a { display: block; padding-block: 0.25rem; }

@media (width >= 48rem) {
  .mast {
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    align-items: baseline;
  }
  .wordmark {
    grid-area: 1 / 2;
    z-index: 1;
    margin-inline-end: -0.5em;
  }
  .nav {
    grid-area: 1 / 1 / 2 / 4;
    display: grid;
    grid-template-columns: subgrid;
  }
  .nav-main { grid-column: 1; display: block; }
  .nav-aux { grid-column: 3; justify-self: end; }
}

/* ---------- entries & plates ---------- */

.entries {
  padding-block: clamp(4rem, 10vw, 8rem) 0;
}
.entry + .entry { margin-block-start: var(--gap-entry); }
.entry { scroll-margin-block-start: var(--margin); }

.label + .title { margin-block-start: 0.25rem; }
.copy {
  margin-block-start: 0.75rem;
  max-inline-size: var(--measure);
}
.copy > * + * { margin-block-start: 0.75rem; }
.copy > .link { margin-block-start: 0.5rem; }
.copy > .link + .link { margin-block-start: 0.25rem; }
.results > li + li { margin-block-start: 0.375rem; }

/* A plate: the artefact, then one caps line (caption left, controls right). */
.plates {
  display: grid;
  row-gap: 3rem;
  align-content: start;
  margin-block-start: 1.75rem;
}
.plate {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: 1.5rem;
  row-gap: 0.25rem;
  margin-block-start: 1.75rem;
  inline-size: min(100%, 40rem);
}
.plates > .plate { margin-block-start: 0; }
.plate > :is(img, .stage, .swatches) {
  order: -1;
  flex: 1 0 100%;
}
.plate > figcaption { margin-block-start: 0.625rem; }
.plate--half { inline-size: min(66%, 26rem); }
.plate--small { inline-size: 6rem; }
.plates--cluster { row-gap: 1.5rem; }

/* SafariNow's two marks under the team photo: small, single ink, still legible. */
.logos {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 1rem 2.5rem;
}
.logo {
  display: grid;
  justify-items: start;
  row-gap: 0.625rem;
  margin: 0;
}
.logo > img {
  grid-row: 1;
  block-size: 3rem;
  inline-size: auto;
}
.logo--word > img { block-size: 2rem; }
.plate--wordmark > img { block-size: 1.5rem; }

/* A small artefact shown at its own native pixel size (the VIC-20), caption beneath. */
.plate--native {
  display: grid;
  justify-items: start;
  row-gap: 0.625rem;
  inline-size: auto;
}
.plate--native > img {
  grid-row: 1;
  inline-size: auto;
  block-size: auto;
}
.plate--native > figcaption {
  grid-row: 2;
  margin-block-start: 0;
}
.logo > figcaption { grid-row: 2; }

/* 1996 thesis: the five projected patterns, drawn from the thesis data (SVG, ink on paper). */
.swatches {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1.25rem 0.75rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.swatches li {
  display: grid;
  justify-items: start;
  row-gap: 0.5rem;
}
.swatches img {
  inline-size: 4.5rem;
  block-size: 4.5rem;
}
/* Reserved for the founder's ink drawing of the method: its near-white ground melts into the paper. */
.plate--method img { mix-blend-mode: multiply; }
.plate--mark > img {
  block-size: 2rem;
  inline-size: auto;
  object-fit: contain;
  object-position: left center;
}

.stage {
  position: relative;
  aspect-ratio: var(--ar-w, 16) / var(--ar-h, 9);
}
.plate--4x3 { --ar-w: 4; --ar-h: 3; }
.stage > :is(video, img:first-child) {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
}
/* Client logo laid over a plate (founder r3): white, small, top-left corner. */
.stage > .overlay-logo {
  position: absolute;
  inset-block-start: 6%;
  inset-inline-start: 4%;
  inline-size: 17%;
  block-size: auto;
  pointer-events: none;
}

/* iRoll: a 16:9 recreation of the iroll.co.za hero (founder r3). Laid out in container
   units from the live hero measured at 1440 × 780 (centred in 1440 × 810): kicker DM Mono
   16px +0.2em with its 24px rule, title Barlow Condensed 900 104/93.6 −0.03em, riders
   580px wide at x 775. The canvas behind them carries the theme's ported lightning. */
.iroll {
  container-type: inline-size;
  overflow: clip;
  background: #000;
  color: #f7fafc;
}
.iroll > canvas,
.iroll-art {
  position: absolute;
  inset: 0;
}
.iroll > canvas {
  inline-size: 100%;
  block-size: 100%;
}
.iroll-art { z-index: 1; }
.iroll-kicker {
  position: absolute;
  inset-block-start: 4.375cqw;
  inset-inline-start: 4.1667cqw;
  display: flex;
  align-items: center;
  gap: 0.6944cqw;
  margin: 0;
  font: 400 1.1111cqw / 1.6 "MS10 DM Mono", ui-monospace, monospace;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  white-space: nowrap;
  color: #2bb580;
}
@media (width < 30rem) {
  .iroll-kicker { font-size: max(calc(1.1111cqw + 1px), 6px); }
}
.iroll-kicker::before {
  content: "";
  inline-size: 1.6667cqw;
  block-size: max(1px, 0.0694cqw);
  background: #2bb580;
}
.iroll-title {
  position: absolute;
  inset-block-start: 19.125cqw;
  inset-inline-start: 4.1667cqw;
  margin: 0;
  font: 900 7.2222cqw / 0.9 "MS10 Barlow Condensed", "Arial Narrow", sans-serif;
  letter-spacing: -0.03em;
  text-transform: uppercase;
  color: #f7fafc;
}
.iroll-accent { color: #2bb580; }
.iroll-outline {
  color: #000;
  -webkit-text-stroke: max(1px, 0.1736cqw) #2bb580;
  paint-order: stroke fill;
}
.iroll-riders {
  position: absolute;
  inset-block-start: 7.2639cqw;
  inset-inline-start: 53.8194cqw;
  inline-size: 40.2778cqw;
  block-size: auto;
}

.ctl {
  display: flex;
  column-gap: 1.25rem;
  margin-inline-start: auto;
  margin-block-start: 0.625rem;
}
.ctl button {
  appearance: none;
  margin: 0;
  padding: 0.25rem 0;
  border: 0;
  border-radius: 0;
  background: none;
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
  cursor: pointer;
  touch-action: manipulation;
  user-select: none;
  -webkit-user-select: none;
}
.ctl button[aria-pressed="true"] {
  color: var(--ink);
  text-decoration-line: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.3em;
}
.ctl button:active { opacity: 0.6; }
@media (width < 30rem) {
  .ctl {
    flex-basis: 100%;
    flex-wrap: wrap;
    gap: 0.5rem 1.5rem;
    margin-inline-start: 0;
    margin-block-start: 0.375rem;
  }
  .ctl button { padding-block: 0.5rem; }
}
@media (hover: hover) and (pointer: fine) {
  .ctl button:hover { color: var(--ink); }
}

/* Full screen: the plate alone on paper, film contained, its caps line beneath. */
.plate:fullscreen {
  --fw: min(100vw - 2 * var(--margin), (100vh - 2 * var(--margin) - 3rem) * var(--ar-w, 16) / var(--ar-h, 9));
  inline-size: 100%;
  margin: 0;
  padding: var(--margin) calc((100vw - var(--fw)) / 2);
  align-content: center;
  background: var(--paper);
}
.plate:-webkit-full-screen {
  --fw: min(100vw - 2 * var(--margin), (100vh - 2 * var(--margin) - 3rem) * var(--ar-w, 16) / var(--ar-h, 9));
  inline-size: 100%;
  margin: 0;
  padding: var(--margin) calc((100vw - var(--fw)) / 2);
  align-content: center;
  background: var(--paper);
}

/* Review toggle: ?plates=0 → the text-only version. */
.no-plates :is(.plate, .plates) { display: none; }

/* ---------- footer ---------- */

.foot {
  display: grid;
  row-gap: 0.5rem;
  margin-block-start: calc(var(--gap-entry) * 1.5);
  padding-block-end: var(--margin);
}
.foot { text-transform: uppercase; }

/* ---------- two registers from 1024px: entries | plates, row-locked ---------- */

@media (width >= 64rem) {
  .entries,
  .foot {
    display: grid;
    grid-template-columns:
      [text] minmax(0, 6fr)
      [chan] minmax(0, 1fr)
      [plate] minmax(0, 6fr);
    align-items: start;
  }
  .entry {
    grid-column: 1 / -1;
    display: grid;
    grid-template-columns: subgrid;
    grid-template-rows: auto auto 1fr;
    align-items: start;
  }
  .entry > .label { grid-area: 1 / text; }
  .entry > .title { grid-area: 2 / text; }
  .entry > .copy { grid-area: 3 / text; }
  .entry > :is(.plate, .plates) {
    grid-area: 1 / plate / span 3;
    margin-block-start: var(--cap);
  }
  .plate { inline-size: 100%; }
  .plate--half { inline-size: 50%; }
  .plate--small { inline-size: 7.5rem; }
  .plate--native { inline-size: auto; }
  .swatches { grid-template-columns: repeat(5, minmax(0, 1fr)); }

  .foot > * { grid-column: text; }
  .foot > .foot-agents { grid-area: 1 / plate; }
}

/* From 1280px the label takes its own column: a dated spine, like a CV. */
@media (width >= 80rem) {
  .entries,
  .foot {
    grid-template-columns:
      [label] minmax(0, 2fr)
      [text] minmax(0, 5fr)
      [chan] minmax(0, 1fr)
      [plate] minmax(0, 6fr);
  }
  .entry { grid-template-rows: auto 1fr; }
  .entry > .label { grid-area: 1 / label; }
  .entry > .title { grid-area: 1 / text; margin-block-start: 0; }
  .entry > .copy { grid-area: 2 / text; }
  .entry > :is(.plate, .plates) { grid-area: 1 / plate / span 2; }
}

/* ---------- v13c · the Plekify film plate (founder r5, ported from plekify.com's hero film) ----
   A 16:9 poster, a flat ink scrim and one centred play button; PLAY opens a native dialog
   stage with the film at full width, sound on and native controls while staged. Appended:
   every v13b line above is untouched (immutable-CSS law). */

.stage.film::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  background: rgb(20 17 13 / 14%);          /* the scrim: flat ink, no gradient, no vignette */
  pointer-events: none;
}

.film-play {
  position: absolute;
  inset-block-start: 50%;
  inset-inline-start: 50%;
  z-index: 1;                               /* the scrim never dims the button */
  display: grid;
  place-items: center;
  translate: -50% -50%;
  inline-size: clamp(3.5rem, 11%, 4.5rem);  /* 11% of the poster width; 56-72px */
  aspect-ratio: 1;
  padding: 0;
  border: 1px solid #14110D;                /* 1px ink stroke at 100% */
  border-radius: 50%;
  background: rgb(244 239 228 / 92%);       /* paper #F4EFE4 at 92% */
  box-shadow: 0 1px 0 rgb(20 17 13 / 12%);  /* the 1px print-ghost, offset 1px down */
  color: #14110D;
  cursor: pointer;
  touch-action: manipulation;
  transition: background-color 160ms linear, color 160ms linear;
}
/* The glyph is drawn into a 24-unit box: 30% of the diameter wide, 34% tall, the whole
   triangle nudged 6% of the diameter right of centre (x 9.84-17.04, y 7.92-16.08). */
.film-play svg {
  inline-size: 100%;
  block-size: 100%;
}
.film-play:active { opacity: 0.6; }
.film-play:focus-visible {
  outline: 2px solid #9B2C1F;
  outline-offset: 3px;
}
@media (hover: hover) and (pointer: fine) {
  .film-play:hover { background: #14110D; color: #F4EFE4; }
}
@media (prefers-reduced-motion: reduce) {
  .film-play { transition: none; }
}

/* The stage (founder r2): the film pinned to the top of the viewport at full width, its own
   16:9 and never letterboxed or centred; below it a flat 38% ink band to the viewport's
   bottom edge. The page stays legible through the band, and a click on the band closes. */
.film-stage {
  inset: 0;
  inline-size: 100vw;
  max-inline-size: none;
  block-size: 100vh;
  block-size: 100dvh;
  max-block-size: none;
  margin: 0;
  padding: 0;
  border: 0;
  background: rgb(20 17 13 / 38%);          /* the band: flat ink, no gradient */
  overflow: hidden;
}
.film-stage::backdrop { background: transparent; }  /* no dimming beyond the 38% band */
.film-stage video {
  inline-size: 100%;
  block-size: auto;                         /* full width, flush to the top */
  background: #14110D;
}

/* While the film is staged the page behind it cannot scroll. */
html.film-staged { overflow: hidden; }

/* ---------- v13d · r3 (founder live review, 2026-10-15). Every v13c line above is
   untouched (immutable-CSS law); the four r3 layout rulings are appended below. -------- */

/* 1 · SERVICES — the clean artwork now leads the entry at the entry's top-left, full width
   (max 1120), with no frame or shade; the official Shopify logo is a separate crisp image
   beneath it with its left edge flush with the artwork's. */
.plate--services {
  row-gap: 0;
  inline-size: min(100%, 1120px);
  margin-block: 0 1.75rem;
}
.plate--services > .plate-logo {
  order: 0;                                 /* after the artwork, not before it */
  flex: 0 0 auto;
  inline-size: 168px;
  block-size: auto;
  margin-block-start: 20px;
}
@media (width >= 64rem) {
  #services { grid-template-rows: auto auto auto 1fr; }
  #services > .plate--services {
    grid-area: 1 / 1 / 2 / -1;
    margin-block-start: 0;
  }
  #services > .label { grid-area: 2 / text; }
  #services > .title { grid-area: 3 / text; }
  #services > .copy { grid-area: 4 / text; }
}
@media (width >= 80rem) {
  #services { grid-template-rows: auto auto 1fr; }
  #services > .label { grid-area: 2 / label; }
  #services > .title { grid-area: 2 / text; }
  #services > .copy { grid-area: 3 / text; }
}
@media (width < 45rem) {
  .plate--services {
    inline-size: auto;
    margin-inline: calc(-1 * var(--margin));  /* full-bleed artwork on phones */
  }
  .plate--services > .plate-logo {
    inline-size: 132px;
    margin-block-start: 16px;
    margin-inline-start: var(--margin);       /* the logo keeps the page's left edge */
  }
}

/* 2 · OPEN OCEAN — the 16:9 stage is itself the link to the new build (ProFilm idiom; the
   .ctl buttons stay outside it), carrying the white logo at the width measured off the
   live store plate. */
.stage > .overlay-logo--oo { inline-size: 29.4%; }

/* 3 · SAFARINOW — both marks now sit on the team photo, bottom-left, side by side with the
   original first, each on its own paper chip so ink stays legible over the water. */
.stage--team { --ar-w: 1120; --ar-h: 764; }  /* the photo's own aspect: no crop */
.sn-logos {
  position: absolute;
  inset-block-end: 24px;
  inset-inline-start: 24px;
  display: flex;
  align-items: flex-end;
  gap: 12px;
}
.sn-logos > img {
  box-sizing: content-box;                  /* the chip grows around the mark */
  display: block;
  inline-size: 188px;
  block-size: auto;
  padding: 10px;
  background: #f4efe4;
  border-radius: 2px;
}
.sn-logos > img + img { inline-size: 150px; }
@media (width < 45rem) {
  .sn-logos {
    inset-block-end: 14px;
    inset-inline-start: 14px;
  }
  .sn-logos > img { inline-size: 120px; padding: 7px; }
  .sn-logos > img + img { inline-size: 96px; }
}

/* 4 · IROLL — the kicker runs the full stage width (justified, paper at 80%), CURRENT takes
   solid iRoll green under its ink stroke, and the bolts drop to 35% and clear the title's
   box. Sizes in cqw track the shipped recreation; 583px stage = 100cqw. */
.iroll-kicker {
  font-size: 2.3672cqw;                     /* the 51-char line lands edge to edge */
  letter-spacing: 0.14em;
  inset-inline-end: 4.1667cqw;              /* 24px at the 583px stage */
  color: rgb(244 239 228 / 80%);
}
.iroll-kicker > span {
  flex: 1;
  text-align: justify;
  text-align-last: justify;
}
@media (width < 30rem) {
  .iroll-kicker { font-size: max(2.3672cqw, 6px); }
}
.iroll-outline {
  color: #2bb580;                           /* the same green as the rest of the sheet */
  -webkit-text-stroke: max(1px, 0.2573cqw) #14110d;  /* 1.5px at 583; 1px at ≤350 */
}
.iroll > canvas {
  opacity: 35%;
  -webkit-mask-image: radial-gradient(ellipse 17cqw 13.5cqw at 16.2cqw 28.9cqw, transparent 0 76%, #000 100%);
  mask-image: radial-gradient(ellipse 17cqw 13.5cqw at 16.2cqw 28.9cqw, transparent 0 76%, #000 100%);
}

/* ---------- v13e · r4 (founder live review, 2026-10-15). Every v13d line above is
   untouched (immutable-CSS law); the two r4 rulings are appended below. ---------------- */

/* 1 · SAFARINOW — the two transparent marks now sit bare on the team photo, bottom-left,
   bottom edges aligned, original left. The v13d paper chip is neutralized behind them:
   no padding, no background, no radius, no border. 80/64px hold at BOTH widths — the
   measured legibility floor at the 350px stage — and only the inset and gap tighten. */
.sn-logos {
  inset-block-end: 16px;
  inset-inline-start: 16px;
  gap: 12px;
  z-index: 1;                               /* above the photo */
  pointer-events: none;
}
.sn-logos > img {
  box-sizing: border-box;
  inline-size: 80px;
  padding: 0;
  background: none;
  border: 0;
  border-radius: 0;
  box-shadow: none;
}
.sn-logos > img + img { inline-size: 64px; }
@media (width < 45rem) {
  .sn-logos {
    inset-block-end: 12px;
    inset-inline-start: 12px;
    gap: 10px;
  }
  .sn-logos > img { inline-size: 80px; padding: 0; }  /* no scale-down at 350 */
  .sn-logos > img + img { inline-size: 64px; }
}

/* 2 · SERVICES — the r3 full-width band is gone: the entry returns to the standard
   row-locked entry (label/title/copy in the text column, the plate in the plate column,
   top-aligned). The art is the ink-only transparent PNG at its natural ratio
   (1120×625 — no crop, no frame, no seam); the Shopify logo sits beneath it, its left
   edge flush with the art's, 112/96px wide, 14/12px gap. */
@media (width >= 64rem) {
  #services { grid-template-rows: auto auto 1fr; }
  #services > .label { grid-area: 1 / text; }
  #services > .title { grid-area: 2 / text; }
  #services > .copy { grid-area: 3 / text; }
}
@media (width >= 80rem) {
  #services { grid-template-rows: auto 1fr; }
  #services > .label { grid-area: 1 / label; }
  #services > .title { grid-area: 1 / text; }
  #services > .copy { grid-area: 2 / text; }
}
#services > .plate { row-gap: 14px; }       /* the art → logo gap (mobile 12) */
#services .plate-logo {
  flex: 0 0 auto;                           /* its own line at 112px, never stretched */
  inline-size: 112px;
  block-size: auto;
}
@media (width < 45rem) {
  #services > .plate { row-gap: 12px; }
  #services .plate-logo { inline-size: 96px; }
}

/* ---------- v15.3 · founder live review (2026-10-17). The SERVICES artwork is mirrored
   horizontally (its ink field now gathers from the left and settles toward the column's
   outer edge), and the Shopify logo moves to the artwork's right: same 112/96px size and
   14/12px gap, its right edge flush with the art's. -------------------------------- */
#services > .plate > .plate-art { transform: scaleX(-1); }
#services .plate-logo { margin-inline-start: auto; }  /* right edge flush with the art's */

/* ---------- v15.4 · founder live review (2026-10-17). The logo no longer hangs from the
   artwork's outer edge: it hangs from the plane's NEAR FRONT-LOWER CORNER (ink vertex at
   x 977 of the 1120-wide art), right edge on that corner's vertical, and it rises into the
   dead paper under the slab so the gap reads as a caption gap, not a break. Percentages
   resolve against the plate width, so both holds at every breakpoint. ------------------- */
#services > .plate { row-gap: 0; }
#services .plate-logo {
  margin-inline-start: auto;
  margin-inline-end: 12.7%;    /* 977/1120 → right edge under the near corner */
  margin-block-start: -3.4%;   /* 61/1120 dead band below the corner, less a caption gap */
}

/* ---------- v16 · founder live review (2026-10-30). Both OWN VENTURE films retire and each
   brand's official primary lockup takes its place: the same 16:9 plate field the other
   entries use (so text and plate stay top-aligned, 50/50), the logo centred inside it with
   air on every side — never filling the field. Widths are optical: the wide Plekify lockup
   (4.166:1) reads at 60%, the stacked Murmurgo lockup (1.81:1) at 45%. The .stage--brand
   class carries no ground of its own; the paper stays the paper. ---------------------- */
.stage--brand { display: grid; place-items: center; }
.stage.stage--brand > img {
  inline-size: 60%;
  block-size: auto;
  object-fit: contain;
}
#murmurgo .stage.stage--brand > img { inline-size: 45%; }

/* ---------- v18 · founder live review (2026-11-01). SafariNow takes the brand-plate idiom
   of the two ventures above it: its official wordmark centred in the same 16:9 field, air
   on every side, caption beneath (the .stage--brand default of 60% already suits the
   4.22:1 mark, so the plate itself needs no rule). The team photo steps down one row and
   sits beside the SMS film, whose heading and book text retire with it, so the year-2000
   row reads as two artefacts of the same year. The iRoll and Open Ocean entries move
   beneath the SafariNow story in the document itself. ------------------------------- */

/* THE 2000 ROW — two artefacts of the same year, levelled. The pair spans text-to-plate
   and repeats the page's own rhythm inside itself: the 5fr | 1fr | 6fr registers become
   5.5fr | 1fr | 5.5fr, so both plates take the same width and the channel between them is
   the page's channel. Below 64rem they simply stack: label, photo, film. */
.plates--pair {
  row-gap: 1.75rem;
  align-items: start;   /* each caption hugs its own artefact; no stretched empty frame */
}
@media (width >= 64rem) {
  #sms { grid-template-rows: auto auto; }
  #sms > .plates--pair {
    grid-area: 2 / text / 3 / -1;
    grid-template-columns: 5.5fr 1fr 5.5fr;
    margin-block-start: 1rem;
  }
  .plates--pair > .plate:nth-child(1) { grid-column: 1; }
  .plates--pair > .plate:nth-child(2) { grid-column: 3; }
}
@media (width >= 80rem) {
  #sms { grid-template-rows: 1fr; }
  #sms > .plates--pair {
    grid-area: 1 / text / 2 / -1;
    margin-block-start: var(--cap);   /* plate top on the label's cap, as every row does */
  }
}

/* ---------- v19 · founder live review (2026-11-02). Three rulings on the SafariNow lane:
   1 · the type-set brand names under the Plekify, Murmurgo and SafariNow marks retire
   (the document drops the three <figcaption> lines — the marks spell the names), 2 · the
   2000 row becomes two equal 4:3 plates meeting on the page's plate line, and 3 · each
   entry's text column centres against the height of its plate. Every v18 line above is
   untouched (immutable-CSS law); the three rulings are appended below. ---------------- */

/* 1 · BRAND PLATES — no rule: the PLEKIFY / MURMURGO / SAFARINOW captions are gone from
   the document. Each plate is now the mark in its 16:9 field and nothing else; the images
   keep their alt text, so a screen reader still hears which mark it is. */

/* 2 · THE 2000 ROW — the film takes the plate column at its full 583 (the same width as
   the iRoll and Open Ocean plates beneath it) and the team photo takes everything left of
   the plate line — text column + channel — so both artefacts are 583 and butt on the line
   where every plate on the page begins. The photograph is masked from its own 1.466:1 to
   the film's 4:3, an equal ~51 px off each side of the 1120 px frame: the four surfers
   start at x 240 and the boards end at x 920, well inside the 1019 that remain. Below
   80rem the pair keeps the v18 rhythm (two equal plates, the page's channel between
   them), levelled by the same 4:3 mask. ------------------------------------------------ */
@media (width >= 64rem) {
  .plates--pair > .plate:nth-child(1) > img {
    aspect-ratio: 4 / 3;                   /* the film's ratio: equal heights, levelled */
    object-fit: cover;
    object-position: 50% 50%;              /* the crop is equal on both sides */
  }
}
@media (width >= 80rem) {
  #sms > .plates--pair {
    grid-template-columns: 6fr 6fr;        /* text+channel | plate: the seam is the line */
  }
  .plates--pair > .plate:nth-child(2) { grid-column: 2; }
}

/* 3 · THE ROW'S CENTRE — the text column now centres against its plate. The entry's
   desktop rows become two empty rails with the title and the copy between them; the plate
   spans all four, so the rails take exactly the height the plate leaves over and the
   title + copy block centres as one. The label rides on the title's first line rather
   than drifting to the middle of the row alone. Where the text is taller than the plate
   (services, first computer, kapstadt) the rails collapse to nothing and the row reads
   exactly as before: the plate still hangs from the first line, as the sheet's charter
   says. ------------------------------------------------------------------------------ */
@media (width >= 80rem) {
  .entry { grid-template-rows: 1fr auto auto 1fr; }
  .entry > .label { grid-area: 2 / label; }
  .entry > .title { grid-area: 2 / text; margin-block-start: 0; }
  .entry > .copy { grid-area: 3 / text; }
  .entry > :is(.plate, .plates) { grid-area: 1 / plate / span 4; }

  #services { grid-template-rows: 1fr auto auto 1fr; }
  #services > .label { grid-area: 2 / label; }
  #services > .title { grid-area: 2 / text; }
  #services > .copy { grid-area: 3 / text; }
  #services > .plate { grid-area: 1 / plate / span 4; }

  #sms > .label { grid-area: 1 / label; }  /* the one row with no text block to centre */

  /* The gallery pages (/yoga/, /windsurf/) are one long stack of photographs, not a row:
     centring a short text block against 1400 px of plates would strand it mid-gallery, so
     their entries keep the v18 top alignment. */
  .entries--flow .entry { grid-template-rows: auto 1fr; }
  .entries--flow .entry > .title { grid-area: 1 / text; }
  .entries--flow .entry > .copy { grid-area: 2 / text; }
  .entries--flow .entry > :is(.plate, .plates) { grid-area: 1 / plate / span 2; }
}

/* ---------- v20 · founder live review (2026-11-02). Three rulings on the front page:
   1 · the SERVICES plate (ink artwork + official Shopify logo) centres vertically
   against its text column like every other row, instead of hanging from the first
   line; 2 · the Shopify logo centres horizontally in the plate column, its v15.4
   near-corner hang retired; 3 · the Plekify and Murmurgo plates carry each venture's
   current social sharing image (og:image, 1200 × 630) at the column's full width,
   whole and unframed. Every v19 line above is untouched (immutable-CSS law). ------ */

/* 1 + 2 · SERVICES — the art and the logo centre as one block in the row; the logo
   centres in the column on a plain caption gap. The v15.4 offsets (right edge on the
   plane's near corner, negative rise) retire with the right-edge hang. */
@media (width >= 64rem) {
  #services > .plate {
    align-self: center;
    margin-block-start: 0;
  }
}
#services .plate-logo {
  margin-inline: auto;                    /* both edges auto: the column's centre */
  margin-block-start: 14px;               /* a plain caption gap under the art */
}
@media (width < 45rem) {
  #services .plate-logo { margin-block-start: 12px; }
}

/* 3 · THE VENTURE CARDS — each social sharing image fills the plate column at its own
   1200 × 630; the v16 field (16:9, mark at 45/60%) retires for these two entries only.
   SafariNow keeps the 16:9 brand field. The card is the artefact: no crop, no frame. */
#plekify > .plate--brand .stage--brand,
#murmurgo > .plate--brand .stage--brand {
  aspect-ratio: 1200 / 630;
}
#plekify > .plate--brand .stage--brand > img,
#murmurgo > .plate--brand .stage--brand > img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: contain;
}

/* 1b · EVERY PLATE TAKES THE ROW'S MIDDLE. v19 gave the text side two rails so it
   centres against a taller plate; this is the same ruling from the plate side, so a
   plate shorter than its text (services, and the Murmurgo card) sits on the row's
   centre line instead of the top. Where the plate is the taller column nothing moves. */
@media (width >= 64rem) {
  .entry > :is(.plate, .plates) { align-self: center; }
}

/* ---------- v22 · founder live review (2026-11-02). The Murmurgo B2B plate joins the
   v20 venture-card ruling: its WETU social sharing image fills the plate column at the
   card's own 1200 × 630. v21 shipped the article without extending the v20 §3
   selectors, so the card fell back to the v16 mark field (16:9, image at 60%) and
   rendered small. v13k.css stays untouched per the immutable-CSS law. ---------------- */
#murmurgo-b2b > .plate--brand .stage--brand {
  aspect-ratio: 1200 / 630;
}
#murmurgo-b2b > .plate--brand .stage--brand > img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: contain;
}

/* ---------- v23 · founder live review (2026-11-02). Both venture headings take their
   brand's own B2B badge line — murmurgo.com's bottom-left badge, verbatim: a pill "B2B"
   + the brand line. Murmurgo's pill is its live badge pink (captured 2026-11-02:
   #e21366, white 12px/500, 999px radius, 0.06em tracking, 6px 10px padding) with
   "Transaction-enable your WETU itineraries with Shopify"; Plekify's pill is its card
   vermilion (#d83814, sampled from the deployed og card's brand tile) with "PLEKIFY -
   Sell your rooms on your own Shopify". The page stays ink on paper — colour enters
   only as these two marks, set at the heading's own mono-caps scale. v13l.css stays
   untouched per the immutable-CSS law. ----------------------------------------------- */
.pill--b2b,
.pill--plk {
  display: inline-block;
  border-radius: 999px;
  padding: 6px 9px;
  line-height: 1;
  font-weight: 500;
  letter-spacing: 0.06em;
  margin-inline-end: 0.6em;
  vertical-align: middle;
  color: #fff;
}
.pill--b2b { background: #e21366; }   /* murmurgo's live B2B badge pink */
.pill--plk { background: #d83814; }   /* Plekify's vermilion, from the og card's tile */

/* ---------- v27 · contact note form (2026-11-02). Compact Turnstile-ready form
   under the CONTACT heading — Sonnet-5.5 copy + design; ink on paper: hairline
   bottoms, mono-caps micro-labels, square 1px-ink button, no colour, no radius.
   Wired via /contact-config.js (endpoint + sitekey; docroot, not immutable); until
   wired the form shows the email fallback line. v13m.css stays immutable. -------- */
.note { margin-top: 1.5rem; font: 400 var(--fs)/var(--lh) var(--sans); color: var(--ink); }
.note-row { display: grid; gap: 1rem; margin-top: 1rem; }
.note-row--pair { grid-template-columns: 1fr 1fr; }
.note-row--send { grid-template-columns: 1fr auto; align-items: end; }
.note-field { display: block; }
.note-label { display: block; font: 400 var(--fs-s) var(--mono); letter-spacing: 0.1em; text-transform: uppercase; color: var(--grey); }
.note input, .note textarea {
  width: 100%; font: 400 var(--fs)/var(--lh) var(--sans); color: var(--ink);
  background: var(--paper); border: 0; border-bottom: 1px solid var(--underline);
  border-radius: 0; padding: 0.25rem 0; appearance: none; box-shadow: none;
}
.note textarea { resize: none; min-height: 3.2rem; }
.note input:focus, .note textarea:focus { outline: none; border-bottom-color: var(--ink); }
.note-check { min-height: 65px; }
.note-fallback { font: 400 var(--fs)/var(--lh) var(--sans); color: var(--grey); margin: 0; }
.note-fallback a { color: var(--ink); text-decoration: underline; }
.note-send {
  font: 400 var(--fs-s) var(--mono); letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--ink); background: var(--paper);
  border: 1px solid var(--ink); border-radius: 0; box-shadow: none;
  padding: 0.5rem 1rem; cursor: pointer;
}
.note-send:hover, .note-send:focus-visible { background: var(--ink); color: var(--paper); }
.note-send[disabled] { color: var(--grey); border-color: var(--underline); cursor: default; }
.note-send[disabled]:hover { background: var(--paper); color: var(--grey); }
.note-status { margin: 0.75rem 0 0; font: 400 var(--fs)/var(--lh) var(--sans); color: var(--ink); }
.note-status--marked { border-left: 1px solid var(--ink); padding-left: 0.75rem; }
@media (max-width: 582px) {
  .note-row--pair { grid-template-columns: 1fr; }
  .note-row--send { grid-template-columns: 1fr; }
}

/* ---------- v29 · contact form: attachments, check collapses when solved, tighter send row (2026-11-03) ---------- */
.note-row--attach { display: block; margin-top: 0.45rem; }
.note-attach {
  display: inline-flex; align-items: center; gap: 0.45em;
  font: 400 0.625rem/1 var(--mono); letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--grey); background: none; border: 0; border-radius: 0; padding: 0;
  cursor: pointer;
}
.note-attach-icon { inline-size: 13px; block-size: 13px; flex: none; color: currentColor; }
.note-attach-label { text-decoration: underline; text-decoration-color: transparent; text-underline-offset: 0.2em; }
.note-attach:hover .note-attach-label,
.note-attach:focus-visible .note-attach-label { text-decoration-color: var(--underline); }
.note-attach:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
.note-attach-input[hidden] { display: none; }
.note-files {
  list-style: none; margin: 0.55rem 0 0; padding: 0;
  display: grid; gap: 0.35rem;
  font: 400 0.8125rem/1.4 var(--sans); color: var(--ink);
}
.note-files[hidden] { display: none; }
.note-file { display: flex; gap: 0.6em; align-items: baseline; }
.note-file-name { overflow-wrap: anywhere; }
.note-file-size { color: var(--grey); font-family: var(--mono); }
.note-file-x {
  font: 400 0.8125rem/1 var(--sans); color: var(--ink);
  background: none; border: 0; border-radius: 0; padding: 0; cursor: pointer;
}
.note-file-x:hover, .note-file-x:focus-visible {
  text-decoration: underline; text-decoration-color: var(--underline); text-underline-offset: 0.2em;
}
.note--solved .note-check { position: absolute; left: -9999px; top: auto; }
.note-check { min-height: 0; }
.note-row--send { margin-top: 0.45rem; }
/* With the check out of flow the button is the row's only grid item and would
   stretch across the 1fr track; keep v27's right-aligned button on wide screens
   (the 582px collapse still gives full width on phones). */
@media (min-width: 583px) {
  .note--solved .note-send { justify-self: end; }
}

/* ---------- v30 · contact form: the Cloudflare badge returns (founder 2026-11-03).
   The success tick + cloudflare logo stay VISIBLE as a protected-by-Cloudflare signal,
   but free-floating: the compact widget is scaled to 80% inside a fixed 120×112 slot,
   and its border line is erased by a paper ring overlay (pointer-events none, so
   Privacy·Help stay clickable). v29's solved-collapse is undone — the badge remains in
   flow; the button top-aligns so it still hugs the form. v13o.css immutable. --------- */
.note-check { position: relative; width: 120px; height: 112px; overflow: hidden; }
.note-check .cf-turnstile { transform: scale(0.8); transform-origin: top left; }
.note-check::after {
  content: ""; position: absolute; inset: 0; z-index: 1;
  border: 2px solid var(--paper); border-radius: 4px; pointer-events: none;
}
.note--solved .note-check { position: relative; left: auto; }
.note-row--send { grid-template-columns: auto 1fr; align-items: start; }
.note-send { justify-self: end; }
@media (max-width: 582px) {
  .note-row--send { display: flex; flex-direction: column-reverse; align-items: stretch; }
  .note-check { align-self: flex-start; margin-top: 0.55rem; }
}

/* ---------- v34 · iRoll plate (founder live review, 2026-11-08). v13q.css is the new
   working sheet; v13p.css is immutable from here. --------------------------------------- */

/* 1 · CURRENT is outline-only: no green fill, a green stroke of its own (was solid green
   under a 1.5px ink stroke). 2px at the 583px stage, never below 1.2px. */
.iroll-outline {
  color: transparent;
  -webkit-text-stroke: max(1.2px, 0.3431cqw) #2bb580;
}

/* 2 · The lightning is no longer a background whisper: the canvas rises 35% → 60%. The
   v13d mask (title box cleared) stays in force. Cadence change travels in v13l.js. */
.iroll > canvas { opacity: 60%; }

/* 3 · The iRoll mark joins the artwork, white, bottom-left, on the same insets as the
   kicker and title (4.1667cqw left / 4.375cqw top & bottom). 56px wide at the 583px
   stage; the 1117:918 source gives ~46px tall, clear of the title's last line. */
.iroll-logo {
  position: absolute;
  inset-block-end: 4.375cqw;
  inset-inline-start: 4.1667cqw;
  inline-size: 9.6055cqw;
  block-size: auto;
}
