/* ============================================================
   GTM Operators — site mock, shared design system
   ============================================================ */

/* Palette, type and the flip mechanic follow ../services-page.html — tight
   Helvetica Neue for anything that reads as a heading, system mono reserved
   for small labels, warm grey ground, square corners, ink-inverted card backs.
   The one red accent is carried over from the project convention. */
:root {
  --ground: #EAEAE7;
  --card: #F9F9F7;
  --text: #16181C;
  --soft: #55595F;
  --line: #D3D3CD;
  --invert: #F4F4F2;          /* paper on ink */
  --grid: rgba(20, 22, 28, 0.035);
  --accent: #C92121;
  --accent-2: #EF4343;

  --sans: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, "Segoe UI", Arial, sans-serif;
  --mono: ui-monospace, "SF Mono", "SFMono-Regular", Menlo, "Cascadia Code", "Roboto Mono", monospace;

  /* The drafting grid is 68px. mock/ used 1200px/2rem, so 1200 ÷ 68 = 17.6 and the
     grid never met the content column — it read as texture. 1156 = 68 × 17 and a
     34px gutter leaves a 1088px (68 × 16) column, so the rules now land on it. */
  --pitch: 68px;
  --maxw: 1156px;
  --pad: 34px;
  --radius: 0;
  --bar-h: 4rem;

  /* paper-on-ink alphas — these were three hand-written rgb() literals */
  --on-ink: color-mix(in srgb, var(--invert) 82%, transparent);
  --on-ink-soft: color-mix(in srgb, var(--invert) 60%, transparent);
  --on-ink-faint: color-mix(in srgb, var(--invert) 30%, transparent);

  /* the hover border, written out four times before */
  --edge: color-mix(in srgb, var(--accent) 40%, var(--line));

  --shadow-panel: 0 18px 44px -18px rgb(20 20 20 / 0.22);
  --shadow-nav: 0 18px 30px -20px rgb(20 20 20 / 0.2);

  --micro: 0.7rem;   /* 11.2px: the floor for any functional mono label */
  --t-fast: 0.16s ease;
  --t-med: 0.2s ease;

  --z-grid: -1;
  --z-content: 0;
  --z-bar: 40;
  --z-skip: 100;

  /* declares the theme to the UA so native controls and scrollbars match */
  color-scheme: light;
}

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

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--ground);
  color: var(--text);
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* mock/ had overflow-x:hidden here. It masked overflow rather than fixing it, and
     an overflow other than visible on an ancestor makes that ancestor the scroll
     container — which would break the sticky header the moment a wrapper is added. */
  position: relative;
}

/* the 68px drafting grid from services-page.html — the one piece of
   atmosphere on the page, fixed so it reads as paper rather than decoration */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: var(--z-grid);
  pointer-events: none;
  background-image:
    linear-gradient(var(--grid) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid) 1px, transparent 1px);
  background-size: var(--pitch) var(--pitch);
}
/* mock/ had to lift main/.bar/.foot/.mockbar above a z-index:0 grid, which meant any
   new top-level element rendered under a grey wash. The grid now sits at -1 instead. */
main, .bar, .foot, .mockbar { position: relative; }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
/* the parts of the page the browser draws still carry the design */
::selection { background: var(--text); color: var(--invert); }
.sum ::selection, .tile__face--back ::selection { background: var(--invert); color: var(--text); }
html { caret-color: var(--accent); accent-color: var(--accent); }
h1, h2, h3 { text-wrap: balance; }
.lede, .tile__problem, .tile__fix, .step__desc, .value p { text-wrap: pretty; }

/* Kills the ~300ms double-tap-zoom wait on every control, and replaces the
   default blue tap flash with something that belongs to this palette. */
a, button, .tile, summary, [role="button"] {
  touch-action: manipulation;
  -webkit-tap-highlight-color: color-mix(in srgb, var(--accent) 16%, transparent);
}

img { max-width: 100%; height: auto; }

/* safe-area insets: the header and footer are full-bleed, so on a notched
   phone in landscape they'd otherwise run under the cutout */
.wrap {
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: max(var(--pad), env(safe-area-inset-left)) max(var(--pad), env(safe-area-inset-right));
}

/* This copy is placeholder that the pillar owners will replace, so assume a
   very long unbroken token will eventually land in one of these cells. */
.tile__problem, .tile__fix, .tile__get, .tile__desc,
.vf__said, .vf__before, .vf__after,
.rest__problem, .rest__get,
.guard li, .lede, .engine__desc, .nav__pillar__desc {
  overflow-wrap: break-word;
  min-width: 0;
}

/* fixed, not absolute: absolute anchors it to the document, so on a scrolled
   page the focused skip link can sit above the viewport */
.skip {
  position: fixed; left: -9999px;
  background: var(--text); color: var(--invert);
  padding: 0.6rem 1rem; z-index: var(--z-skip); font-family: var(--mono); font-size: 0.75rem;
}
.skip:focus { left: 1rem; top: 1rem; }

/* WCAG 2.4.11 — the sticky header is ~96px tall, so anything the browser
   scrolls to (tab focus, an in-page anchor) would land underneath it. */
a, button, [tabindex], :target { scroll-margin-top: 7rem; }

/* ---------- type primitives ---------- */

/* Headings are sans with tight negative tracking — mono is for labels only.
   This is the single biggest difference from the earlier pass, and it's what
   makes services-page.html read as designed rather than as a terminal. */
h1, h2, h3, h4 { font-family: var(--sans); font-weight: 700; letter-spacing: -0.025em; margin: 0; }
h1 { letter-spacing: -0.035em; }


/* Functional in-card label ("How you'd know" and the like), sentence case.
   Section heads use .eyebrow on every page, per mock4's services-page look
   (eyebrow + heading + lead per band). */
.label {
  font-family: var(--mono);
  font-size: 0.74rem;
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--soft);
  margin: 0;
}

.lede {
  font-size: clamp(1.05rem, 1.6vw, 1.28rem);
  line-height: 1.62;
  color: var(--soft);
  max-width: 62ch;
  margin: 0;
}
.lede strong { color: var(--text); font-weight: 500; }

/* vertical rhythm — one class, so nothing fights over section padding */
.band { padding: clamp(3.5rem, 9vh, 6rem) 0; }
.band--tight { padding: clamp(2.5rem, 6vh, 3.75rem) 0; }
.band--hero { padding: clamp(4rem, 11vh, 7rem) 0 clamp(3rem, 8vh, 5rem); }
.band--ruled { border-top: 1px solid var(--line); }

/* Full-bleed grounds. A <section> already spans the viewport — only .wrap narrows
   the content — so a background on the band paints edge to edge for free. mock/
   never used this: one ground colour ran the whole page and every section carried
   the same .band--ruled hairline, which is what made six sections read as one. */
.band--ink { background: var(--text); color: var(--invert); border-top-color: var(--text); }
.band--card { background: var(--card); }
.band--ink .label, .band--ink .eyebrow { color: var(--on-ink-soft); }
.band--ink .lede { color: var(--on-ink); }
.band--ink .head__op { color: var(--accent-2); }

/* escape hatch for content that must span the viewport from inside a .wrap */
.bleed { margin-inline: calc(50% - 50vw); width: 100vw; max-width: 100vw; }

/* A --card band and a --card tile front are the same colour, so panels would vanish
   into the ground. Inside a card band the raised surfaces step down to --ground
   instead — the relationship stays, the tones swap. */
.band--card .tile__face--front,
.band--card .toggle,
.band--card .person { background: var(--ground); }
.people li:has(.person--net) { grid-column: 1 / -1; }
.person--net { border-style: dashed; grid-template-columns: auto auto 1fr; align-items: baseline; gap: 0.35rem 1.25rem; }
.person--net .person__line { font-size: 0.95rem; }
@media (max-width: 779.98px) { .person--net { grid-template-columns: 1fr; } }

/* People read better as outlines on ink than as four bright panels — the faces
   device above them should carry the weight of the section. */
.band--ink .person { background: transparent; border-color: var(--on-ink-faint); }
.band--ink .person:hover { background: color-mix(in srgb, var(--invert) 8%, transparent); border-color: var(--accent-2); }
.band--ink .person__name { color: var(--invert); }
.band--ink .person:hover .person__name { color: var(--accent-2); }
.band--ink .person__pillar { color: var(--accent-2); }
.band--ink .person__line { color: var(--on-ink-soft); }

/* ---------- heading scale ----------
   mock/ had none: every section heading was an inline style="font-size:clamp(...)",
   8 recipes across 35 inline attributes, all landing between 1.9 and 2.2rem. That
   flat range is why nothing on the page read as more important than anything else. */
.h-display { font-size: clamp(2.5rem, 6.6vw, 4.9rem); line-height: 1.02; letter-spacing: -0.038em; max-width: 18ch; }
.h-section { font-size: clamp(1.75rem, 4.2vw, 3rem); line-height: 1.08; letter-spacing: -0.03em; max-width: 26ch; }
.h-sub     { font-size: clamp(1.15rem, 2.3vw, 1.55rem); line-height: 1.3; max-width: 34ch; }

/* ---------- section header ----------
   The operator glyph sits in a gutter exactly one drafting-grid module wide, so the
   motif does structural work — it marks which row of the ledger a section belongs to
   — instead of being decoration. This is the answer to the open "do we use +/x/-"
   question: yes, as an organiser; the equation itself is table stakes and stays small. */
.head { display: grid; grid-template-columns: var(--pitch) 1fr; gap: 0 1.5rem; align-items: start; }
.head__op {
  font-family: var(--mono);
  font-weight: 500;
  font-size: clamp(1.9rem, 4vw, 2.8rem);
  line-height: 0.86;
  color: var(--accent);
  text-align: center;
}
.head__op--soft { color: var(--soft); }
.head__body { display: grid; gap: 0.9rem; min-width: 0; }
.head__kick { font-size: clamp(1rem, 1.5vw, 1.14rem); color: var(--soft); margin: 0; max-width: 56ch; line-height: 1.55; }
.band--ink .head__kick { color: var(--on-ink); }

/* the two ad-hoc inline layouts mock/ used, promoted to classes */
.actions { display: flex; flex-wrap: wrap; gap: 0.75rem; }
.stack { display: grid; gap: 1rem; }
.h-display--wide { font-size: clamp(2.4rem, 5.4vw, 4rem); max-width: 30ch; }

/* ============================================================
   DIAGRAMS — the pitch has three ideas (four operators, one face; embed then
   leave; four functions, one system) and text was carrying all of them. Inline
   SVG, ink + the one red, mono labels, so they sit on the drafting grid like
   the rest of the page instead of on top of it.
   ============================================================ */

/* ---- hero: headline full width, then lede beside the engagement timeline ---- */
.hero__grid { display: grid; gap: 2.5rem; margin-top: 1.8rem; align-items: end; }
@media (min-width: 1024px) {
  .hero__grid { grid-template-columns: minmax(0, 29rem) minmax(0, 1fr); gap: 2.5rem 4rem; }
}
.tl-wrap { margin: 0; min-width: 0; }
.tl { display: block; width: 100%; height: auto; overflow: visible; }
.tl text { font-family: var(--mono); font-size: 14px; letter-spacing: 0.02em; fill: var(--soft); }
.tl2__us { fill: var(--text); }
.tl2__team { fill: var(--accent); }
.tl2__k rect { fill: var(--invert); }
.tl2__k text { fill: var(--text); font-weight: 700; font-size: 11px; letter-spacing: 0; }
.tl2__hand { stroke: var(--text); stroke-width: 1; stroke-dasharray: 3 4; }
.tl__lab--team { fill: var(--accent); }
.tl__lab--hand { fill: var(--text); }
.tl__cap { font-family: var(--mono); font-size: 0.8rem; color: var(--soft); margin: 0.9rem 0 0; line-height: 1.6; }

/* one authored moment: the stripe wipes in left to right, so the transfer plays as time.
   CSS only, so it runs without JS; the reduced-motion block zeroes duration and delay. */
@keyframes tl-wipe { to { clip-path: inset(0 0 0 0); } }
@keyframes tl-in { to { opacity: 1; } }
.tl2__bands { clip-path: inset(0 100% 0 0); animation: tl-wipe 1.4s cubic-bezier(0.22, 0.61, 0.36, 1) 0.1s forwards; }
.tl2__hand, .tl__lab { opacity: 0; animation: tl-in 0.4s ease forwards; }
.tl__lab { animation-delay: 0.4s; }
.tl2__hand, .tl__lab--hand { animation-delay: 1.1s; }
.tl__lab--team { animation-delay: 1.4s; }

/* ---- the account, drawn: your company, the one face, the three behind it ---- */
.acct-wrap { margin: 2rem 0 0; min-width: 0; }
.acct { display: block; width: 100%; max-width: 40rem; height: auto; }
.acct text { font-family: var(--mono); font-size: 12px; letter-spacing: 0.02em; fill: var(--soft); }
.acct .acct__box { fill: var(--card); stroke: var(--soft); stroke-width: 1; }
.acct .acct__face { fill: var(--text); stroke: var(--text); }
.acct .acct__face-txt { fill: var(--invert); font-weight: 700; font-size: 20px; letter-spacing: 0; }
.acct .acct__k { fill: var(--text); font-weight: 700; font-size: 14px; letter-spacing: 0; }
.acct .acct__wire { stroke: var(--line); stroke-width: 1; fill: none; }
.acct .acct__wire--main { stroke: var(--text); stroke-width: 2.5; }
.acct .acct__ring { fill: none; stroke: var(--accent); stroke-width: 1; stroke-dasharray: 3 4; }
.acct .acct__net { fill: var(--ground); stroke: var(--soft); stroke-width: 1; stroke-dasharray: 2 3; }
.acct .acct__net-wire { stroke: var(--line); stroke-width: 1; stroke-dasharray: 2 3; fill: none; }


/* ---- the four steps sit on a rail, so they read as the hero timeline zoomed in ---- */
.steps--rail { position: relative; padding-top: 1.25rem; margin-top: 2.5rem; }
.steps--rail::before { content: ""; position: absolute; left: 0; right: 0; top: 0.3rem; height: 1px; background: var(--line); }
.steps--rail .step { position: relative; }
.steps--rail .step::before { content: ""; position: absolute; left: 0; top: -1.25rem; width: 9px; height: 9px; background: var(--text); }
.steps--rail .step--end::before { background: var(--accent); }

/* ---- pillar pages: where this pillar sits in the ledger ---- */
.where { display: flex; align-items: flex-start; gap: 0; list-style: none; margin: 1.5rem 0 0; padding: 0; position: relative; flex: 1 1 100%; }
.pillar__meta { flex-wrap: wrap; }
.where::before { content: ""; position: absolute; left: 0; right: 0; top: calc(var(--pitch) / 2 - 0.5px); height: 1px; background: var(--line); z-index: -1; }
.where__op { width: var(--pitch); margin-right: 1.25rem; display: grid; gap: 0.5rem; justify-items: center; text-align: center; }
.where__op > b { width: var(--pitch); height: var(--pitch); display: grid; place-items: center; font-family: var(--mono); font-weight: 500; font-size: 1.6rem; border: 1px solid var(--line); background: var(--ground); color: var(--soft); }
.where__op > span { font-family: var(--mono); font-size: var(--micro); text-transform: uppercase; letter-spacing: 0.14em; color: var(--soft); line-height: 1.4; }
.where__op.is-here > b { background: var(--text); border-color: var(--text); color: var(--invert); }
.where__op.is-here > span { color: var(--text); }
.where__op--sum > b { border-color: var(--accent); color: var(--accent); }

/* header: nav, booking button and hamburger share one right-hand group, so the
   button stays in the bar when the nav collapses instead of collapsing with it */
.bar__end { display: flex; align-items: center; gap: 0.75rem; }

/* the four figures under the hero - tighter than the pillar-page proof band because
   "<$1M -> $15M+" in mono at 2.4rem does not fit a quarter of the column */
.proofs--strip { gap: 1.5rem; }
.proofs--strip .proof__fig { font-size: clamp(1.2rem, 2.2vw, 1.75rem); overflow-wrap: anywhere; }


/* ---------- buttons ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  font-family: var(--sans);
  font-size: 0.98rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  text-decoration: none;
  border: 1px solid var(--text);
  padding: 0.9rem 1.4rem;
  background: var(--text);
  color: var(--invert);
  cursor: pointer;
  transition: transform 0.18s ease;
}
.btn:hover { transform: translateY(-2px); }

.btn--ghost { background: transparent; color: var(--text); }
.btn--sm { padding: 0.6rem 1rem; font-size: 0.86rem; }

/* inline text link with the mono arrow treatment */
.more {
  font-family: var(--mono);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--accent);
  text-decoration: none;
  border-bottom: 1px solid transparent;
}
.more:hover { border-bottom-color: var(--accent); }
/* #C92121 on ink is about 2:1 — lift it to the brighter red on dark faces */
.tile__face--back .more { color: var(--accent-2); }
.tile__face--back .more:hover { border-bottom-color: var(--accent-2); }

/* plain inline link — for links that sit mid-sentence, where the mono
   uppercase treatment above would read as a label instead of prose */
.link { color: var(--text); text-decoration: underline; text-decoration-color: var(--accent); text-underline-offset: 3px; }
.link:hover { color: var(--accent); }

/* ---------- chips ---------- */

.chips { display: flex; flex-wrap: wrap; gap: 0.5rem; padding: 0; margin: 0; list-style: none; }
.chip {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--card);
  padding: 0.45rem 0.8rem;
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.04em;
  color: var(--soft);
}
.chip--op { border-color: var(--edge); color: var(--text); background: var(--ground); }
.chip__op { font-weight: 800; color: var(--accent); }

/* ============================================================
   HEADER + SERVICES HOVER PANEL
   The mechanic the session asked to see. CSS-first: works on
   :hover and :focus-within with no JS. JS only adds click/touch
   and the .is-open hook used for screenshots.
   ============================================================ */

.bar {
  position: sticky;
  top: 0;
  z-index: var(--z-bar);
  border-bottom: 1px solid var(--line);
  background: color-mix(in srgb, var(--ground) 90%, transparent);
  backdrop-filter: saturate(160%) blur(8px);
}
.bar__inner {
  position: relative;   /* the Services panel anchors to this, not to the trigger */
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: var(--bar-h);
}

.brand {
  display: inline-flex;
  align-items: center;
  min-height: 24px;        /* WCAG 2.5.8 AA — was 19px tall */
  font-family: var(--mono);
  font-size: 0.76rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--text);
  text-decoration: none;
  white-space: nowrap;
}
.brand span { color: var(--accent); }
/* Less-More logo (14 Oct): the purple-to-lavender vector lockup from mock-content/brand/, the one place colour
   enters the otherwise greyscale site. 43px tall inside the 4rem bar. */
.brand__logo { display: block; height: 43px; width: auto; }

.nav { display: flex; align-items: center; gap: 0.4rem; }
.nav__list { display: flex; align-items: center; gap: 0.2rem; list-style: none; margin: 0; padding: 0; }
.nav__item { position: relative; }

.nav__link {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-family: var(--mono);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--soft);
  text-decoration: none;
  background: none;
  border: 0;
  padding: 0.75rem 0.85rem;
  cursor: pointer;
  transition: color 0.16s ease;
}
.nav__link:hover, .nav__link[aria-current="page"] { color: var(--text); }
.nav__link[aria-current="page"] { color: var(--accent); }

.nav__caret { transition: transform 0.2s ease; font-size: var(--micro); }

/* The panel spans the whole content column, like a mega-menu.
   It used to hang off the trigger itself — but the nav sits hard right, so a
   right-anchored panel put the trigger at its far-right corner and reaching
   the first pillar meant moving diagonally out of the hover region, which shut
   the panel mid-travel. Left-anchoring overflowed the viewport at 1280–1440.
   Full width fixes both: from the trigger you only ever move straight down. */
.nav__item--panel { position: static; }

.nav__panel {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
  gap: 0.25rem;
  background: var(--ground);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-panel);
  padding: 0.6rem;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px);
  /* visibility is deliberately NOT transitioned: as a discrete property it
     holds its start value at progress 0, so the panel stayed hit-untestable
     for the first frames and clicks fell through to the page behind it.
     It flips instantly; only opacity and transform animate. */
  transition: opacity 0.18s ease, transform 0.18s ease;
}
/* Bridges the ~7px of dead bar between the trigger and the panel, so moving
   straight down doesn't drop :hover. Hung off the TRIGGER, not the panel —
   on the panel it spanned the full content column and sat over the bottom
   edge of "Book a call", swallowing clicks meant for the button. */
.nav__item--panel > .nav__link { position: relative; }
.nav__item--panel > .nav__link::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  height: 10px;
}
.nav__item--panel:hover > .nav__panel,
.nav__item--panel:focus-within > .nav__panel,
.nav__item--panel.is-open > .nav__panel {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}
.nav__item--panel:hover > .nav__link .nav__caret,
.nav__item--panel.is-open > .nav__link .nav__caret { transform: rotate(180deg); }
.nav__item--panel:hover > .nav__link,
.nav__item--panel.is-open > .nav__link { color: var(--text); }

.nav__pillar {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.4rem;
  align-content: start;
  padding: 0.85rem 0.9rem 1rem;
  border-radius: 0;
  text-decoration: none;
  transition: background 0.14s ease;
}
.nav__pillar:hover { background: var(--card); }
.nav__pillar__name {
  font-family: var(--mono);
  font-size: 0.74rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--text);
}
.nav__pillar:hover .nav__pillar__name { color: var(--accent); }
.nav__pillar__desc { font-size: 0.86rem; color: var(--soft); line-height: 1.45; }

/* mobile disclosure */
.bar__toggle { display: none; }

/* ============================================================
   PILLAR PAGE
   ============================================================ */

.pillar__head { display: grid; gap: 1.5rem; }
.pillar__head h1 {
  font-size: clamp(2.1rem, 5.6vw, 3.6rem);
  line-height: 1.06;
  max-width: 26ch;
}
.pillar__meta { display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem 1rem; }

/* guardrails — "this is / this is not" */
.guards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr));
  gap: 1rem;
  margin-top: 0.5rem;
}
/* Deliberately NOT a card. If the guardrails, the value frameworks, the tiles
   and the operator block all wear the same rounded-bordered-#FAFAFA chrome,
   nothing reads as more important than anything else. A rule and a label is
   enough here; the card treatment is spent on the value framework instead. */
.guard {
  border-top: 2px solid var(--text);
  padding: 1rem 0 0;
}
.guard--not { border-top-color: var(--line); }
.guard h2, .guard h3 {
  font-family: var(--mono);
  font-size: 0.78rem;
  font-weight: 700;
  margin-bottom: 0.7rem;
}
.guard--is h2 { color: var(--text); }
.guard--not h2 { color: var(--soft); }
.guard ul { margin: 0; padding-left: 1.05rem; display: grid; gap: 0.4rem; }
.guard li { color: var(--soft); font-size: 0.95rem; line-height: 1.55; }
.guard--is li::marker { color: var(--accent); }

/* ============================================================
   VALUE FRAMEWORK  (Command of the Message)
   before → negative consequences ┊ after → outcomes → metrics
   Each consequence sits on the same grid row as the outcome
   that cancels it, so the pairing is legible, not implied.
   ============================================================ */

.vfs { display: grid; gap: clamp(2rem, 5vh, 3.25rem); }

.vf {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--card);
  padding: clamp(1.5rem, 3.4vw, 2.4rem);
}
.vf__tags {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 0.7rem;
  font-family: var(--mono); font-size: var(--micro); text-transform: uppercase;
  letter-spacing: 0.14em; color: var(--soft); margin-bottom: 1rem;
}
.vf__tags .discipline { color: var(--accent); }
.vf__tags .sep { width: 1px; height: 0.85em; background: var(--line); }

.vf h3 { font-size: clamp(1.25rem, 2.7vw, 1.8rem); line-height: 1.16; margin-bottom: 1.2rem; }

/* the client's words — sans, because it's their voice not ours */
.vf__said {
  margin: 0 0 1.75rem;
  border-left: 2px solid var(--accent);
  padding-left: 1.35rem;
  font-family: var(--sans);
  font-size: clamp(1.05rem, 2vw, 1.32rem);
  font-weight: 300;
  line-height: 1.45;
  letter-spacing: -0.01em;
  color: var(--text);
}

/* the ledger */
.vf__ledger {
  position: relative;
  display: grid;
  grid-template-columns: 1fr 5px 1fr;
  gap: 0 clamp(1.1rem, 2.6vw, 2.1rem);
  margin: 0;
}
/* Absolute, not a grid item: `grid-row: 1 / -1` only spans the *explicit*
   grid, and every row here is implicit, so it collapsed to one row. */
.vf__spine {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 5px;
  background-image: radial-gradient(circle at 50% 50%, var(--accent) 1.7px, transparent 2.1px);
  background-size: 5px 13px;
  background-repeat: repeat-y;
  opacity: 0.5;
}
.vf__col-head {
  font-family: var(--mono);
  font-size: var(--micro);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  padding-bottom: 0.85rem;
  margin: 0;
}
.vf__col-head--before { grid-column: 1; color: var(--soft); }
.vf__col-head--after { grid-column: 3; color: var(--accent); }

.vf__before, .vf__after { margin: 0; padding: 0.75rem 0; font-size: 0.97rem; line-height: 1.55; }
.vf__before { grid-column: 1; color: var(--soft); }
.vf__after { grid-column: 3; color: var(--text); }
/* Rule the pairs apart, but not above the first one.
   DOM order is fixed: 1 spine, 2-3 column heads, then before/after pairs.
   Scoped to the two-column layout only — unscoped, the :not(:nth-child())
   specificity (0-3-0) beat the stacked overrides below and left stray rules. */
@media (min-width: 780.02px) {
  .vf__ledger > .vf__before:not(:nth-child(4)),
  .vf__ledger > .vf__after:not(:nth-child(5)) { border-top: 1px solid var(--line); }
}

/* metrics — how you'd know it worked */
.vf__metrics { margin-top: 1.75rem; padding-top: 1.4rem; border-top: 1px solid var(--line); }
.vf__metrics .eyebrow { margin-bottom: 0.85rem; }
.vf__proof {
  margin: 1.25rem 0 0;
  font-size: 0.92rem;
  color: var(--soft);
  line-height: 1.55;
}
.vf__proof em { font-style: normal; color: var(--text); font-weight: 500; }

/* ---------- "the rest" — compact problem → what you get ---------- */

.rest { border-top: 1px solid var(--line); }
.rest__list { list-style: none; margin: 0; padding: 0; }
.rest__row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.35rem 2rem;
  align-items: baseline;
  padding: 1.15rem 0;
  border-bottom: 1px solid var(--line);
}
.rest__problem { color: var(--soft); font-size: 0.99rem; line-height: 1.5; }
.rest__get {
  font-family: var(--sans);
  font-size: 1.02rem;
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--text);
  line-height: 1.35;
}
.rest__get::before { content: "→ "; color: var(--accent); }

/* ---------- operator / team block ---------- */

.op-card {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 1.5rem;
  align-items: start;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--card);
  padding: clamp(1.4rem, 3vw, 2.1rem);
}
.op-card__mark {
  width: 3.4rem; height: 3.4rem;
  display: grid; place-items: center;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--ground);
  font-family: var(--mono); font-weight: 800; font-size: 1.2rem;
  color: var(--accent);
}
.op-card h3 { font-size: 1.35rem; margin-bottom: 0.35rem; }
.op-card__role {
  font-family: var(--mono); font-size: var(--micro);
  letter-spacing: 0.02em; color: var(--soft); margin: 0 0 0.85rem;
}
.op-card p { margin: 0 0 0.9rem; color: var(--soft); font-size: 0.97rem; line-height: 1.6; }

/* ---------- proof strip ---------- */

.proofs { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr)); gap: 2rem; }
.proof__fig {
  font-family: var(--sans);
  font-size: clamp(1.6rem, 3.6vw, 2.4rem);
  font-weight: 700;
  letter-spacing: -0.03em;
  color: var(--text);
  line-height: 1.05;
  margin: 0 0 0.5rem;
}
.proof__lab { font-family: var(--mono); font-size: 0.78rem; color: var(--soft); margin: 0; line-height: 1.5; }

/* ============================================================
   HOME — ledger, flip tiles, engine
   ============================================================ */

/* + × − = ledger, carried over from services-page-long.html */
.ledger { border-top: 1px solid var(--line); }
.ledger__row {
  display: grid;
  /* the glyph column is one drafting-grid module, so the ledger lines up with the
     .head gutter and the "=" close — the motif keeps the same rail all the way down */
  grid-template-columns: var(--pitch) 1fr auto auto;
  gap: 1.5rem;
  align-items: center;
  padding: 1.4rem 0;
  border-bottom: 1px solid var(--line);
  text-decoration: none;
  color: inherit;
}
a.ledger__row:hover .ledger__what { color: var(--accent); }
a.ledger__row:hover .ledger__arw { opacity: 1; transform: translateX(0); color: var(--accent); }
/* the rows are links but nothing said so — mock/ ledger had no affordance at all */
.ledger__arw {
  font-family: var(--mono);
  color: var(--soft);
  opacity: 0;
  transform: translateX(-4px);
  transition: transform var(--t-fast), opacity var(--t-fast), color var(--t-fast);
}
.ledger__op { font-family: var(--mono); font-size: 1.9rem; font-weight: 800; color: var(--accent); line-height: 1; text-align: center; }
.ledger__what { font-family: var(--sans); font-size: clamp(1.1rem, 2.4vw, 1.5rem); font-weight: 700; letter-spacing: -0.02em; transition: color 0.16s ease; }
.ledger__who { font-family: var(--mono); font-size: var(--micro); text-transform: uppercase; letter-spacing: 0.12em; color: var(--soft); }
.ledger__row--sum { background: var(--text); margin-top: -1px; padding-inline: 1.2rem; border-bottom: 0; }
.ledger__row--sum .ledger__op,
.ledger__row--sum .ledger__what { color: var(--invert); }
.ledger__row--sum .ledger__who { color: var(--on-ink-soft); }

/* ---- operator groups over the tiles, per services-page.html ----
   The glyph is the group marker: every tile under it moves revenue that way. */
.group { margin-top: clamp(2.5rem, 5vw, 3.75rem); }
.group:first-of-type { margin-top: 0; }
.group__head {
  display: flex;
  align-items: baseline;
  gap: 1.25rem;
  padding-bottom: 1.2rem;
  border-bottom: 1px solid var(--line);
}
.group__op {
  font-family: var(--mono);
  font-size: clamp(2rem, 4.5vw, 3rem);
  line-height: 0.8;
  font-weight: 500;
  flex: none;
  width: 1.1em;
  text-align: center;
  color: var(--accent);
}
.group__title h3 { font-size: clamp(1.15rem, 2vw, 1.5rem); font-weight: 700; margin: 0 0 0.3rem; }
.group__title p { margin: 0; color: var(--soft); font-size: 0.98rem; }
.group .tiles { margin-top: 1.5rem; }

/* flip tiles */
.tiles__bar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 1rem; margin-bottom: 2rem; }
.toggle { display: flex; border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; background: var(--card); }
.toggle button {
  font-family: var(--mono); font-size: var(--micro); text-transform: uppercase; letter-spacing: 0.12em;
  padding: 0.5rem 0.85rem; border: 0; background: transparent; color: var(--soft); cursor: pointer;
  transition: background 0.16s ease, color 0.16s ease;
}
.toggle button:hover { color: var(--text); }
.toggle button[aria-pressed="true"] { background: var(--text); color: var(--invert); }

/* ---- flip tiles, per services-page.html ----
   Both faces share one grid cell instead of being absolutely positioned, so
   the tile sizes to its tallest content instead of needing a fixed height.
   Front is panel, back is ink-inverted — the inversion is what makes the turn
   feel like an answer rather than a second card. */
/* auto-FILL, not auto-fit: auto-fit collapses the empty tracks, so a group
   holding a single tile stretched it across the whole row and it read as a
   different component. auto-fill keeps the tracks, so one tile is the same
   width as every other tile on the page. */
.tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 15.5rem), 1fr)); gap: 1rem; list-style: none; margin: 0; padding: 0; }
/* The outcomes DB holds one `-` row against six `x`, so that group is genuinely a
   single tile. auto-fill left it alone in a five-column row looking unfinished. */
.tiles--one { grid-template-columns: minmax(0, 26rem); }
.tile { perspective: 1400px; display: grid; }
.tile__inner {
  display: grid;
  grid-template-columns: 1fr;
  min-height: 13.5rem;
  transform-style: preserve-3d;
  transition: transform 0.55s cubic-bezier(0.22, 0.61, 0.36, 1);
}
.tile.is-flipped .tile__inner { transform: rotateY(180deg); }
/* on a fine pointer the turn is the hover — no click needed */
@media (hover: hover) and (pointer: fine) {
  .tile:hover .tile__inner { transform: rotateY(180deg); }
  .tile.is-flipped:hover .tile__inner { transform: none; }
}
.tile__face {
  grid-area: 1 / 1 / 2 / 2;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  border: 1px solid var(--line);
  padding: 1.25rem 1.35rem;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 0.85rem;
}
.tile__face--front { background: var(--card); }
.tile__face--back {
  background: var(--text);
  color: var(--invert);
  border-color: var(--text);
  transform: rotateY(180deg);
}
.tile__disc { font-family: var(--mono); font-size: var(--micro); text-transform: uppercase; letter-spacing: 0.12em; color: var(--soft); }
.tile__face--back .tile__disc { color: var(--on-ink-soft); }
.tile__problem { font-size: 1.1rem; line-height: 1.38; letter-spacing: -0.01em; font-weight: 500; color: var(--text); margin: 0; }
.tile__desc { font-size: 0.88rem; line-height: 1.5; color: var(--soft); margin: 0; }
.tile__get { font-family: var(--sans); font-size: 1.18rem; font-weight: 700; letter-spacing: -0.02em; line-height: 1.2; margin: 0 0 0.5rem; }
.tile__fix { font-size: 0.96rem; line-height: 1.45; color: var(--on-ink); margin: 0; }
.tile__foot { margin-top: auto; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.5rem; }
/* Flex blockifies these, so they lose the inline-text-link exemption and have
   to meet the 24px target minimum on their own. They were 17–19px tall. */
.tile__foot .more { display: inline-flex; align-items: center; min-height: 24px; }
.tile__flip {
  display: inline-flex;
  align-items: center;
  min-height: 24px;
  font-family: var(--mono);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--soft);
  background: none;
  border: 0;
  border-bottom: 1px solid var(--line);
  padding: 0 0 3px;
  cursor: pointer;
}
.tile__face--back .tile__flip { color: var(--on-ink-soft); border-bottom-color: var(--on-ink-faint); }
.tile__flip:hover { color: var(--text); border-bottom-color: var(--text); }
.tile__face--back .tile__flip:hover { color: var(--invert); border-bottom-color: var(--invert); }

/* Hover already turns the tile on a fine pointer, so the buttons are the
   touch and keyboard path. Without JS they do nothing — hide them and let
   hover/focus carry it. */
.no-js .tile__flip { display: none; }
.no-js .tile:focus-within .tile__inner { transform: rotateY(180deg); }
.no-js .toggle { display: none; }

/* engine diagram — the second route into the pillars */
.engine { display: grid; gap: 0.75rem; }
.engine__flow { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0.75rem; align-items: stretch; }
.engine__flow--3 { grid-template-columns: repeat(3, 1fr); }
.engine__node {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--card);
  padding: 1.1rem 1.2rem;
  text-decoration: none;
  display: grid;
  gap: 0.4rem;
  align-content: start;
  transition: border-color 0.18s ease, background 0.18s ease;
}
.engine__node:hover { border-color: var(--edge); background: var(--ground); }
.engine__name { font-family: var(--sans); font-size: 1.08rem; font-weight: 700; letter-spacing: -0.02em; color: var(--text); }
.engine__node:hover .engine__name { color: var(--accent); }
.engine__desc { font-size: 0.85rem; color: var(--soft); line-height: 1.45; }
.engine__band {
  border: 1px dashed var(--line);
  border-radius: var(--radius);
  padding: 0.9rem 1.2rem;
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.5rem 1rem;
  text-decoration: none;
}
.engine__band:hover { border-color: var(--edge); }
.engine__band .engine__name { font-size: 0.95rem; }

/* team teaser */
.people { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr)); gap: 1rem; list-style: none; margin: 0; padding: 0; }
.person {
  border: 1px solid var(--line); border-radius: var(--radius); background: var(--card);
  padding: 1.25rem; display: grid; gap: 0.45rem; align-content: start; text-decoration: none;
  transition: border-color 0.18s ease, background 0.18s ease;
}
.person:hover { border-color: var(--edge); background: var(--ground); }
.person__name { font-family: var(--sans); font-size: 1.3rem; font-weight: 700; letter-spacing: -0.02em; color: var(--text); }
.person:hover .person__name { color: var(--accent); }
.person__pillar { font-family: var(--mono); font-size: var(--micro); text-transform: uppercase; letter-spacing: 0.14em; color: var(--accent); }
.person__line { font-size: 0.87rem; color: var(--soft); line-height: 1.45; }

/* ---------- closing CTA ---------- */

.cta { text-align: center; }
.cta h2 { font-size: clamp(1.7rem, 4.2vw, 2.6rem); line-height: 1.1; margin-bottom: 1rem; }
.cta p { color: var(--soft); margin: 0 auto 2rem; max-width: 44ch; }

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

.foot {
  border-top: 1px solid var(--line);
  padding-block: 2rem 3rem;
  font-family: var(--mono);
  font-size: var(--micro);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--soft);
}
.foot__inner { display: flex; flex-wrap: wrap; gap: 0.7rem 1.5rem; justify-content: space-between; }
.foot a { color: var(--soft); text-decoration: none; }
.foot a:hover { color: var(--accent); }

/* ---------- mock banner (this is a mock, say so) ---------- */

.mockbar {
  background: var(--text);
  color: color-mix(in srgb, var(--invert) 78%, transparent);
  font-family: var(--mono);
  font-size: var(--micro);
  letter-spacing: 0.06em;
  padding-block: 0.5rem;
}
.mockbar b { color: var(--invert); font-weight: 700; }
.mockbar__inner { display: flex; flex-wrap: wrap; gap: 0.4rem 1.2rem; justify-content: space-between; }

/* ============================================================
   mock3 — the differentiator components
   ------------------------------------------------------------
   00-positioning.md: "we help you win, keep and grow revenue" is table stakes, and
   the two claims that actually defend a position are the delivery model (one face,
   four operators) and the handover. In mock/ the first was section 5 and the second
   was a subordinate clause. These give both a structure of their own.
   ============================================================ */

/* ---------- the framing line, promoted out of a .lede ---------- */
.framing {
  font-weight: 300;
  font-size: clamp(1.4rem, 3.6vw, 2.3rem);
  letter-spacing: -0.025em;
  line-height: 1.3;
  max-width: 26ch;
  margin: 0;
}
.framing b { font-weight: 600; }


/* ---------- the handover, as four steps ---------- */
.steps { display: flex; flex-wrap: wrap; align-items: stretch; gap: 0.6rem; margin-top: 1.75rem; list-style: none; padding: 0; }
.step { flex: 1 1 10rem; padding: 0.9rem 1.25rem 0 0; display: grid; gap: 0.3rem; align-content: start; }
.step__name { font-weight: 700; letter-spacing: -0.02em; }
.step__desc { font-size: 0.86rem; color: var(--soft); line-height: 1.45; }
/* the last step is the one an agency has no incentive to offer: red marker, ink name */
.step--end .step__name { color: var(--accent); }

/* ---------- the three positioning lines ---------- */
.values { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr)); gap: 1rem; margin-top: 2rem; }
.value { border-top: 1px solid var(--line); padding: 1.1rem 0 0; display: grid; gap: 0.55rem; align-content: start; }
.value h3 { font-size: 1.25rem; letter-spacing: -0.02em; }
.value p { margin: 0; color: var(--soft); font-size: 0.93rem; line-height: 1.55; }

/* ---------- who runs a pillar — lighter than a full op-card ---------- */
.runby { display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem 1rem; margin-top: 1.75rem; padding-top: 1.25rem; border-top: 1px solid var(--line); }
.runby__lab { font-family: var(--mono); font-size: var(--micro); letter-spacing: 0.02em; color: var(--soft); }
.runby__who { font-weight: 600; letter-spacing: -0.01em; }

/* ---------- an honest state for what isn't written yet ---------- */
.op-card--pending .op-card__mark { color: var(--soft); border-color: var(--line); }
.pending { font-family: var(--mono); font-size: 0.78rem; letter-spacing: 0.02em; color: var(--soft); border: 1px dashed var(--line); padding: 0.4rem 0.7rem; margin: 0; line-height: 1.5; }
/* fit-content, not max-content: a long note in a badge must wrap, not force the card
   — and through the single-column .stack, every other card — past the viewport */
.pending { width: fit-content; max-width: 100%; }
.pending--ink { color: var(--on-ink-soft); border-color: var(--on-ink-faint); }
.op-card > div { min-width: 0; }

/* ---------- the "=" close ----------
   mock/ opened on the operator motif and never returned to it; every page ended on
   the same centred CTA. Closing on the "=" makes the equation resolve. */
.sum { background: var(--text); color: var(--invert); border-top-color: var(--text); }
.sum__inner { display: grid; grid-template-columns: var(--pitch) 1fr; gap: 1.5rem; align-items: start; }
.sum__op { margin-top: 0.1em; }
.sum__op { font-family: var(--mono); font-weight: 500; font-size: clamp(2.4rem, 6vw, 4rem); line-height: 0.8; color: var(--accent-2); text-align: center; }
.sum__body { display: grid; gap: 1.1rem; min-width: 0; }
.sum h2 { font-size: clamp(1.6rem, 4vw, 2.6rem); line-height: 1.06; letter-spacing: -0.03em; max-width: 22ch; }
.sum p { margin: 0; color: var(--on-ink); max-width: 48ch; font-size: 1.02rem; }
.sum .btn { border-color: var(--invert); background: var(--invert); color: var(--text); }
.sum .btn--ghost { background: transparent; color: var(--invert); }
.sum .btn--ghost:hover { background: var(--invert); color: var(--text); }

/* ============================================================
   RESPONSIVE
   ============================================================ */

@media (max-width: 900px) {
  .engine__flow { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 779.98px) {
  :root { --pad: 1.25rem; }
  body { font-size: 16px; }

  /* nav collapses into a disclosure */
  .bar__toggle {
    display: inline-flex; align-items: center; gap: 0.5rem;
    font-family: var(--mono); font-size: var(--micro); text-transform: uppercase;
    letter-spacing: 0.12em; background: none; border: 1px solid var(--line);
    border-radius: var(--radius); color: var(--text); padding: 0.5rem 0.8rem; cursor: pointer;
  }
  .nav {
    display: none;
    position: absolute; left: 0; right: 0; top: 100%;
    flex-direction: column; align-items: stretch;
    background: var(--ground); border-bottom: 1px solid var(--line);
    padding: 0.75rem var(--pad) 1.25rem;
    box-shadow: var(--shadow-nav);
  }
  .bar.is-navopen .nav { display: flex; }
  .nav__list { flex-direction: column; align-items: stretch; gap: 0; }
  .nav__link { padding: 0.85rem 0; justify-content: space-between; }

  /* panel becomes an inline accordion — no hover on touch */
  .nav__panel {
    position: static; min-width: 0; opacity: 1; visibility: visible; transform: none;
    border: 0; border-left: 1px solid var(--line); border-radius: 0;
    box-shadow: none; padding: 0 0 0.5rem 0.85rem; margin-bottom: 0.5rem;
    display: none;
  }
  .nav__item--panel.is-open > .nav__panel { display: block; }
  .nav__pillar { grid-template-columns: 1fr; gap: 0.15rem; padding: 0.55rem 0; }

  /* Without JS the hamburger and the accordion can't open, which would leave
     mobile with no navigation at all. Show it all, always. */
  .no-js .bar__toggle { display: none; }
  .no-js .bar__inner { flex-wrap: wrap; }
  .no-js .bar__end { display: contents; }   /* nav + button become .bar__inner's own children */
  .no-js .nav { order: 3; }                  /* brand and button share row 1, nav takes row 2 */
  .no-js .nav {
    display: flex;
    position: static;
    width: 100%;
    align-items: stretch;
    padding: 0 0 0.75rem;
    border-bottom: 0;
    box-shadow: none;
  }
  .no-js .nav__panel { display: block; }
  .no-js .nav__caret { display: none; }

  /* Stacked: there are no columns left, so the column headers would be
     labelling nothing. Drop them; each pair reads cost → the gain that
     cancels it, carried by the rule colour and the arrow. */
  .vf__ledger { grid-template-columns: 1fr; gap: 0; }
  .vf__spine { display: none; }
  .vf__col-head { display: none; }
  .vf__ledger > .vf__before,
  .vf__ledger > .vf__after { grid-column: 1; padding: 0.55rem 0 0.55rem 0.95rem; border-top: 0; }
  .vf__before { border-left: 1px solid var(--line); }
  .vf__after {
    border-left: 1px solid color-mix(in srgb, var(--accent) 45%, transparent);
    margin-bottom: 1.1rem;
  }
  .vf__after::before {
    content: "→ ";
    color: var(--accent);
    font-family: var(--mono);
    font-weight: 700;
  }

  .rest__row { grid-template-columns: 1fr; gap: 0.3rem; }
  .ledger__row { grid-template-columns: 2.5rem 1fr; row-gap: 0.4rem; }
  .ledger__who { grid-column: 2; }
  .ledger__arw { display: none; }   /* no hover to reveal it on */
  .op-card { grid-template-columns: 1fr; }

  /* --- mock3 components --- */
  /* the glyph gutter is a whole 68px module; at phone widths that's a third of the
     column, so the header stacks and the glyph drops to label size */
  .head { grid-template-columns: 1fr; gap: 0.5rem; }
  .head__op { text-align: left; font-size: 1.6rem; }
  .sum__inner { grid-template-columns: 1fr; gap: 0.75rem; }
  .sum__op { text-align: left; }
  .tl text { font-size: 20px; }           /* the viewBox scales down ~0.57x here */
  .tl2__k text { font-size: 14px; }           /* the viewBox scales down ~0.57x here */
  .where__op { width: calc(var(--pitch) * 0.75); margin-right: 0.75rem; }
  .where__op > b { width: calc(var(--pitch) * 0.75); height: calc(var(--pitch) * 0.75); font-size: 1.3rem; }
  .where::before { top: calc(var(--pitch) * 0.375 - 0.5px); }
}

@media (max-width: 560px) {
  .engine__flow { grid-template-columns: 1fr; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-delay: 0ms !important;
    transition-duration: 0.01ms !important;
  }
  /* No rotation at all: the faces crossfade in place, the way
     services-page.html handles it. Both live in the same grid cell, and the
     back is later in the DOM, so opacity alone decides which one you see. */
  .tile__inner { transition: none !important; transform: none !important; }
  .tile__face { backface-visibility: visible; -webkit-backface-visibility: visible; }
  .tile__face--back { transform: none; opacity: 0; }
  .tile.is-flipped .tile__face--front { opacity: 0; }
  .tile.is-flipped .tile__face--back { opacity: 1; }

  /* mock/ bug: with JS off, the back face was unreachable under reduced motion.
     `.no-js .tile:focus-within .tile__inner { transform: rotateY(180deg) }` is the
     only route to the back without JS, and the `transform: none !important` above
     cancels it — with no opacity counterpart, so nothing showed. Keyboard users on
     a reduced-motion OS saw the front face and nothing else. */
  .no-js .tile:focus-within .tile__face--front { opacity: 0; }
  .no-js .tile:focus-within .tile__face--back { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) and (hover: hover) and (pointer: fine) {
  .tile:hover .tile__face--front { opacity: 0; }
  .tile:hover .tile__face--back { opacity: 1; }
  .tile.is-flipped:hover .tile__face--front { opacity: 1; }
  .tile.is-flipped:hover .tile__face--back { opacity: 0; }
}

/* ============================================================
   mock4 — the look is mock/'s again (15 Sep, by request)
   ------------------------------------------------------------
   One ground colour, a hairline between sections, the eyebrow as the page identifier,
   mock/'s heading sizes, a centred close. mock3's fixes and grid math stay underneath.
   ============================================================ */

/* the one tracked-caps line per page, mock/'s definition */
.eyebrow {
  font-family: var(--mono);
  font-size: 0.72rem;
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.2em;
  color: var(--soft);
  margin: 0;
}

/* mock/'s sizes, as tokens instead of the 35 inline attributes it used.
   Display 4.6 / section 2.2 / mid 2.0 / sub 1.6 rem at the top of each clamp. */
.h-display { font-size: clamp(2.3rem, 6.4vw, 4.6rem); line-height: 1.04; letter-spacing: -0.035em; max-width: 24ch; }
.h-section { font-size: clamp(1.5rem, 3.2vw, 2.2rem);  line-height: 1.15; letter-spacing: -0.025em; max-width: 32ch; }
.h-mid     { font-size: clamp(1.35rem, 2.8vw, 2rem);   line-height: 1.18; letter-spacing: -0.025em; max-width: 34ch; }
.h-sub     { font-size: clamp(1.2rem, 2.4vw, 1.6rem);  line-height: 1.3;  max-width: 36ch; }

/* the centred close carries the honest-pending note under its button */
.cta .pending { margin: 1.25rem auto 0; text-align: left; }

/* the placeholder note on the team page names a file */
.pending code { font-family: inherit; font-size: inherit; color: var(--text); }
.band--hero .pending { margin-top: 0.5rem; }

/* ============================================================
   mock4 — services-page.html pass (15 Sep, third pass, by request)
   ------------------------------------------------------------
   The home page in the language of ../services-page.html: greyscale, an eyebrow + heading
   + lead opening every band, the flip cards with "The problem" / "What you get" tags, the
   engine as panel blocks with a flow row, four numbered cells for how we work, and a
   left-aligned close with the arrow button. Shared parts (no red, the close) apply to
   every page; the pillar pages keep their mock3 template otherwise.
   ============================================================ */

/* Greyscale. services-page.html has no red; CLAUDE.md: "Greyscale only — no red, despite
   older notes". Everything that was --accent is ink now, and on ink faces it is paper.
   Delete these two lines to get the one-red-accent version back. */
:root { --accent: var(--text); --accent-2: var(--invert); }

/* ---- band head: eyebrow · heading · lead, services-page's sizes ---- */
.band__head { margin-bottom: clamp(36px, 4vw, 56px); }
.band__head h2 {
  font-size: clamp(1.6rem, 3.2vw, 2.6rem);
  letter-spacing: -0.025em;
  line-height: 1.06;
  margin: 16px 0 0;
  max-width: 24ch;
}
.band__head .lead { margin: 16px 0 0; color: var(--soft); max-width: 58ch; font-size: 1.05rem; line-height: 1.55; }
.band__head .lead b { color: var(--text); font-weight: 600; }
.band__head .toggle { margin-top: 24px; display: inline-flex; }

/* ---- hero: services-page's header sizes ---- */
.h-display { font-size: clamp(2.3rem, 6vw, 4.6rem); line-height: 1.0; letter-spacing: -0.035em; max-width: 18ch; }
.band--hero .lede { font-size: clamp(1.05rem, 1.7vw, 1.3rem); line-height: 1.5; }

/* ---- the arrow on the primary action ---- */
.btn .arw { font-family: var(--mono); transition: transform 0.18s ease; }
.btn:hover .arw { transform: translateX(4px); }

/* ---- small mono note (services-page's .micro) ---- */
.micro { font-family: var(--mono); font-size: 0.78rem; letter-spacing: 0.04em; color: var(--soft); margin: 0; }

/* ---- the condensed − group ---- */
.minor { display: flex; align-items: baseline; gap: 20px; margin-top: clamp(40px, 5vw, 60px); padding-top: 28px; border-top: 1px solid var(--line); }
.minor h3 { font-size: clamp(1.15rem, 2vw, 1.5rem); letter-spacing: -0.02em; margin: 0 0 6px; }
.minor p { margin: 0; color: var(--soft); font-size: 1rem; line-height: 1.5; max-width: 62ch; }
.minor .more { margin-left: 0.5rem; }

/* ---- engine: panel blocks, and the revenue motion as a row ---- */
.blocks { display: flex; flex-direction: column; gap: 16px; }
.blk {
  display: block; border: 1px solid var(--line); background: var(--card); padding: 24px 26px;
  text-decoration: none; color: inherit; transition: border-color 0.18s ease, background 0.18s ease;
}
a.blk:hover { border-color: var(--soft); background: var(--ground); }
.blk__tag { font-family: var(--mono); font-size: 0.7rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--soft); display: flex; align-items: center; gap: 9px; margin-bottom: 12px; }
.blk__op { color: var(--text); font-size: 1rem; }
.blk h3 { font-size: 1.22rem; letter-spacing: -0.02em; margin: 0 0 6px; }
.blk p { margin: 0; color: var(--soft); font-size: 0.96rem; line-height: 1.5; }
.flow__tag { font-family: var(--mono); font-size: 0.7rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--soft); margin: 0 0 14px; }
.flow__row { display: grid; grid-template-columns: 1fr auto 1fr auto 1.1fr; align-items: stretch; gap: 14px; }
.flow__row .blk { padding: 18px 18px; }
.flow__arw { align-self: center; font-family: var(--mono); font-size: 1.4rem; color: var(--soft); text-align: center; }
.flow__cut { align-self: stretch; display: flex; align-items: center; justify-content: center; position: relative; padding: 0 6px; }
.flow__cut::before { content: ""; position: absolute; top: 6px; bottom: 6px; left: 50%; border-left: 1px dashed var(--line); }
.flow__cut span { position: relative; background: var(--ground); font-family: var(--mono); font-size: var(--micro); letter-spacing: 0.14em; text-transform: uppercase; color: var(--soft); writing-mode: vertical-rl; transform: rotate(180deg); padding: 8px 0; }
@media (max-width: 700px) {
  .flow__row { grid-template-columns: 1fr; }
  .flow__arw { transform: rotate(90deg); }
  .flow__cut { padding: 6px 0; }
  .flow__cut::before { top: 50%; left: 6px; right: 6px; bottom: auto; border-left: 0; border-top: 1px dashed var(--line); }
  .flow__cut span { writing-mode: horizontal-tb; transform: none; }
}

/* ---- how we work: four numbered cells sharing hairlines ---- */
.steps-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 1px; background: var(--line); border: 1px solid var(--line); }
.step-cell { background: var(--ground); padding: 30px 26px 34px; }
.step-cell__n { font-family: var(--mono); font-size: 0.82rem; letter-spacing: 0.1em; color: var(--soft); }
.step-cell h3 { font-size: 1.3rem; letter-spacing: -0.02em; margin: 16px 0 10px; }
.step-cell p { margin: 0; color: var(--soft); font-size: 0.98rem; line-height: 1.5; }

/* ---- close: left-aligned, services-page's sizes ---- */
.close { padding: clamp(64px, 9vw, 116px) 0; }
.close h2 { font-size: clamp(1.9rem, 4.6vw, 3.4rem); letter-spacing: -0.03em; line-height: 1.04; margin: 0 0 20px; max-width: 20ch; }
.close p { margin: 0 0 34px; color: var(--soft); max-width: 46ch; font-size: 1.05rem; }
.close p.pending { margin: 1.25rem 0 0; font-size: 0.78rem; max-width: 100%; }

/* ---- mobile: the cells and blocks stack, the hero sizes step down with the clamp ---- */
@media (max-width: 779.98px) {
  .minor { gap: 14px; }
  .flow__row .blk { padding: 18px; }
}

/* ---- contact form: three fields in the system's own chrome ---- */
.form { display: grid; gap: 1.5rem; max-width: 46rem; }
.form__row { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr)); gap: 1.5rem; }
.field { display: grid; gap: 0.55rem; align-content: start; }
.field label { font-family: var(--mono); font-size: 0.74rem; font-weight: 500; letter-spacing: 0.01em; color: var(--soft); }
.field input, .field textarea {
  width: 100%; min-width: 0;
  font: inherit; font-size: 1rem; color: var(--text);
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 0.85rem 1rem;
  transition: border-color var(--t-fast);
}
.field textarea { resize: vertical; min-height: 8rem; line-height: 1.5; }
.field input::placeholder, .field textarea::placeholder { color: color-mix(in srgb, var(--soft) 70%, transparent); }
.field input:hover, .field textarea:hover { border-color: var(--soft); }
.field input:focus-visible, .field textarea:focus-visible { outline: 2px solid var(--text); outline-offset: 2px; border-color: var(--text); }
.field__hint { font-family: var(--mono); font-size: var(--micro); color: var(--soft); margin: 0; }
.form__foot { display: flex; flex-wrap: wrap; align-items: center; gap: 0.75rem 1.5rem; margin-top: 0.25rem; }

/* ---- the card back is the link to its pillar; no Back button (16 Sep, by request) ---- */
a.tile__face--back { text-decoration: none; color: var(--invert); cursor: pointer; }
a.tile__face--back .more { gap: 0.45rem; border-bottom: 1px solid transparent; transition: border-color var(--t-fast); }
a.tile__face--back:hover .more { border-bottom-color: var(--invert); }
a.tile__face--back:focus-visible { outline: 2px solid var(--invert); outline-offset: -5px; }

/* ---- lifted from Katya's pillar page (16 Sep): reasons cards, proof notes, "not the answer" list, scope lines ---- */
.reasons { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr)); gap: 1rem; list-style: none; margin: 0; padding: 0; }
.reason { border: 1px solid var(--line); background: var(--card); padding: 1.1rem 1.25rem 1.25rem; font-size: 0.98rem; line-height: 1.5; color: var(--text); }
.reason::before { content: "\201C"; display: block; font-family: var(--mono); font-size: 1.4rem; line-height: 1; color: var(--soft); margin-bottom: 0.6rem; }
.proof__note { font-size: 0.92rem; color: var(--soft); line-height: 1.5; margin: 0.7rem 0 0; max-width: 34ch; }
.nots { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--line); }
.nots li { display: grid; grid-template-columns: 1.5rem 1fr; gap: 0.75rem; padding: 0.9rem 0; border-bottom: 1px solid var(--line); color: var(--soft); font-size: 1rem; line-height: 1.5; }
.nots li::before { content: "\00D7"; font-family: var(--mono); color: var(--text); font-weight: 500; }
.nots b { color: var(--text); font-weight: 600; }
.vf__scope { margin: 0.9rem 0 0; font-size: 0.88rem; color: var(--soft); line-height: 1.55; }
.vf__scope b { color: var(--text); font-weight: 600; }

/* ---- 16 Sep: Hiring and RevOps as half-height horizontals under the motion; the network's K ---- */
.blocks__row { display: grid; grid-template-columns: 1fr; gap: 14px; }  /* stacked, one above the other (16 Sep) */
.blk--short { padding: 12px 18px 14px; display: grid; grid-template-columns: auto 1fr; gap: 0.45rem 1rem; align-items: baseline; }
.blk--short .blk__tag { grid-column: 1 / -1; margin-bottom: 0.2rem; }
.blk--short h3 { font-size: 1.05rem; margin: 0; }
.blk--short p { font-size: 0.9rem; }
@media (max-width: 700px) { .blk--short { grid-template-columns: 1fr; } }
:root { --kollective: #6D4FD3; }
.k-mark { color: var(--kollective); }

/* ---- the + tiles as a slow carousel (16 Sep) ----
   One flex track, twice the tiles, translated by half its width plus half a gap so the loop
   has no seam. Hover, focus and a flipped tile pause it; the edges fade so the cut looks
   intended. The tiles keep their flip: perspective and rotateY live on .tile / .tile__inner,
   the roll lives on the track, and the two transforms don't meet. */
.carousel {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
}
.tiles--track {
  display: flex;
  gap: 1rem;
  width: max-content;
  margin: 0;
  animation: tiles-roll 70s linear infinite;
  will-change: transform;
}
.tiles--track .tile { flex: 0 0 17rem; }
.carousel:hover .tiles--track,
.carousel:focus-within .tiles--track,
.carousel:has(.tile.is-flipped) .tiles--track { animation-play-state: paused; }
@keyframes tiles-roll { to { transform: translateX(calc(-50% - 0.5rem)); } }
@media (max-width: 779.98px) { .tiles--track .tile { flex-basis: 15rem; } }
@media (prefers-reduced-motion: reduce) {
  .tiles--track { animation: none; }
  .carousel { overflow-x: auto; -webkit-mask-image: none; mask-image: none; }
  .tile--clone { display: none; }
}

/* ---- contact: pillar tick boxes (24 Sep). Built to read as form controls, not cards:
        same height, border, fill and focus ring as the inputs above, a drawn square
        checkbox, one line of text. The native box stays in the tab order, visually
        hidden, so keyboard and screen readers get a real checkbox. ---- */
.picks { border: 0; margin: 0; padding: 0; min-width: 0; }
.picks legend { font-family: var(--mono); font-size: 0.74rem; font-weight: 500; letter-spacing: 0.01em; color: var(--soft); padding: 0; margin-bottom: 0.55rem; }
.picks__opt { color: color-mix(in srgb, var(--soft) 75%, transparent); margin-left: 0.5rem; }
.picks__grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.75rem 1.5rem; }  /* 2 x 2, same columns as Name / Work email */
@media (max-width: 380px) { .picks__grid { grid-template-columns: 1fr; } }
.field .pick {  /* .field scoping beats ".field label" (mono, 0.74rem) */
  position: relative; display: flex; align-items: center; gap: 0.65rem; cursor: pointer;
  border: 1px solid var(--line); border-radius: var(--radius); background: var(--card);
  padding: 0.85rem 1rem; color: var(--text);
  font-family: var(--sans); font-size: 1rem; font-weight: 400; letter-spacing: normal; line-height: 1.5;
  transition: border-color var(--t-fast);
}
.pick input { position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0; pointer-events: none; }
.pick__box {
  flex: none; width: 1rem; height: 1rem; border: 1px solid var(--soft); background: var(--card);
  display: grid; place-items: center; color: var(--invert); font-size: 0.7rem; line-height: 1;
}
.pick:hover { border-color: var(--soft); }
.pick:has(input:focus-visible) { outline: 2px solid var(--text); outline-offset: 2px; border-color: var(--text); }
.pick:has(input:checked) { border-color: var(--text); }
.pick:has(input:checked) .pick__box { background: var(--text); border-color: var(--text); }
.pick:has(input:checked) .pick__box::before { content: "\2713"; }
.field .pick--quiet { color: var(--soft); }


/* ---- Growth page: self-serve vs enterprise across four stages (30 Sep) ----
   A swimlane: stage columns on top, one bar per motion. Ink = product leads,
   ink edge on panel = product leads with sales assisting, dashed = sales leads.
   Below 760px the columns drop away and each bar names the stages it covers. */


/* ---- Growth page: references as an ink strip at the foot of each before/after card (30 Sep) ----
   Katya asked for louder proof. The strip bleeds to the card edges (negative margins match
   .vf padding) and reuses the ink-inverted look of the tile backs. */
.vf__ref {
  display: flex; align-items: stretch; justify-content: space-between; gap: 1.5rem;
  margin: 1.6rem calc(-1 * clamp(1.5rem, 3.4vw, 2.4rem)) calc(-1 * clamp(1.5rem, 3.4vw, 2.4rem));
  padding: 1.4rem clamp(1.5rem, 3.4vw, 2.4rem);
  background: var(--text); color: var(--invert);
}
.vf__ref-body { display: flex; flex-direction: column; gap: 0.35rem; }
.vf__ref-tag { font-family: var(--mono); font-size: var(--micro); letter-spacing: 0.14em; text-transform: uppercase; color: var(--on-ink-soft); }
.vf__ref-co { font-weight: 700; font-size: 1.35rem; letter-spacing: -0.02em; line-height: 1.15; }
.vf__ref-line { margin: 0; color: var(--on-ink); font-size: 0.98rem; line-height: 1.5; max-width: 52ch; }
.vf__ref-more { margin: 0.2rem 0 0; color: var(--on-ink-soft); font-size: 0.9rem; }
.vf__ref-more b { color: var(--on-ink); font-weight: 600; }
/* 14 Oct: the number sits on the left, the story on the right, the company at the end of the line */
.vf__ref { justify-content: flex-start; }
.vf__ref-fig { display: flex; flex-direction: column; justify-content: center; align-items: flex-start; text-align: left; flex: none; min-width: 9.5rem; max-width: 13rem; padding-right: 1.5rem; border-right: 1px solid var(--on-ink-faint); }
.vf__ref-fig b { font-size: clamp(2.2rem, 4.5vw, 3.2rem); font-weight: 700; letter-spacing: -0.04em; line-height: 1; }
.vf__ref-fig span { font-family: var(--mono); font-size: var(--micro); letter-spacing: 0.12em; text-transform: uppercase; color: var(--on-ink-soft); margin-top: 0.4rem; }
@media (max-width: 560px) {
  .vf__ref { flex-direction: column; }
  .vf__ref-fig { max-width: none; padding: 0 0 1rem; border-right: 0; border-bottom: 1px solid var(--on-ink-faint); }
}

/* ---- Growth page: diagram stages link to their card (30 Sep) ---- */

.vf { scroll-margin-top: calc(var(--bar-h) + 1.5rem); }
.vf:target, .vf:focus { outline: 2px solid var(--text); outline-offset: 4px; }
.vf:focus:not(:focus-visible):not(:target) { outline: none; }
.rest .tile__face--back .tile__foot { margin-top: auto; }
/* Only the face you can see takes clicks: hit-testing ignores backface-visibility, so on
   touch the hidden back face (a link on the home page) sat over the front's flip button.
   On a fine pointer the hover decides which face shows, so it decides the clicks too. */
.tile:not(.is-flipped) .tile__face--back,
.tile.is-flipped .tile__face--front { pointer-events: none; }
@media (hover: hover) and (pointer: fine) {
  .tile:hover:not(.is-flipped) .tile__face--back,
  .tile.is-flipped:hover .tile__face--front { pointer-events: auto; }
  .tile:hover:not(.is-flipped) .tile__face--front,
  .tile.is-flipped:hover .tile__face--back { pointer-events: none; }
}

/* Growth page: a founder quote under "Who you'd work with" (Oct) */
.runby__quote { margin: 1.6rem 0 0; padding-left: 1.1rem; border-left: 2px solid var(--text); max-width: 60ch; }
.runby__quote blockquote { margin: 0; font-size: 1.02rem; line-height: 1.55; color: var(--text); }
.runby__quote figcaption { margin-top: 0.6rem; font-family: var(--mono); font-size: var(--micro); letter-spacing: 0.12em; text-transform: uppercase; color: var(--soft); }
.runby__quote figcaption b { color: var(--text); margin-right: 0.5rem; }

/* Growth page: proof band (Oct). Numbers in the heading face, labels in mono. */
.proofband__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 1px; background: var(--line); border: 1px solid var(--line); }
.proofband__cell { background: var(--card); padding: 26px 24px 28px; display: flex; flex-direction: column; gap: 0.5rem; }
.proofband__cell b { font-size: clamp(2.2rem, 4vw, 3rem); font-weight: 700; letter-spacing: -0.04em; line-height: 1; }
.proofband__lab { font-family: var(--mono); font-size: var(--micro); letter-spacing: 0.12em; text-transform: uppercase; color: var(--text); }
.proofband__cell p { margin: 0.2rem 0 0; color: var(--soft); font-size: 0.95rem; line-height: 1.45; }

/* the account walking its lane */

/* ===== Diagram versions 1-5 (Oct, for comparison) ===== */
.vx { border-top: 1px solid var(--line); padding: clamp(56px, 8vw, 96px) 0; }
.vx__head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.4rem 1rem; margin-bottom: 1.8rem; }
.vx__n { font-family: var(--mono); font-size: var(--micro); letter-spacing: 0.14em; text-transform: uppercase; background: var(--text); color: var(--invert); padding: 0.3rem 0.55rem; }
.vx__t { font-weight: 700; font-size: 1.35rem; letter-spacing: -0.02em; }
.vx__idea { color: var(--soft); font-size: 0.95rem; flex-basis: 100%; }
.vx__note { margin: 1.6rem 0 0; font-family: var(--mono); font-size: var(--micro); letter-spacing: 0.06em; color: var(--soft); }

/* V4 route map */
.v4__map { width: 100%; height: auto; display: block; overflow: visible; }
.v4__grid line { stroke: var(--line); stroke-width: 1; stroke-dasharray: 3 5; }
.v4__line { fill: none; stroke: var(--text); stroke-width: 10; stroke-linecap: round; stroke-dasharray: 1; stroke-dashoffset: 1; transition: stroke-dashoffset 1.6s ease; }
.v4__line--ent { stroke-width: 10; transition-delay: .8s; }
.v4__line--ent2 { transition-delay: 1.8s; }
.v4__hollow { fill: none; stroke: var(--ground); stroke-width: 4; opacity: 0; transition: opacity .4s ease 3s; }
.v4.is-in .v4__hollow { opacity: 1; }
.v4.is-in .v4__line { stroke-dashoffset: 0; }
.v4__stops circle { fill: var(--ground); stroke: var(--text); stroke-width: 3; opacity: 0; transition: opacity .4s ease 1.2s; }
.v4.is-in .v4__stops circle { opacity: 1; }
.v4__names text { font-family: var(--mono); font-size: 15px; letter-spacing: 0.08em; text-transform: uppercase; fill: var(--text); text-anchor: middle; }
.v4__route { font-weight: 700; font-size: 18px; fill: var(--text); font-family: var(--sans); }
.v4__tag { font-family: var(--mono); font-size: 13px; letter-spacing: 0.1em; text-transform: uppercase; fill: var(--soft); }
.v4__dot { fill: var(--invert); stroke: var(--text); stroke-width: 3; opacity: 0; }
.v4.is-in .v4__dot { opacity: 1; transition: opacity .3s ease 2.6s; }
.v4__dot--ent { fill: var(--text); stroke: var(--invert); }

/* 4B: three rows (Oct). Thin hollow = sales assists, wide hollow = sales leads. */
.v4b__assist { fill: none; stroke: var(--ground); stroke-width: 1.8; opacity: 0; transition: opacity .4s ease 3s; }
.v4.is-in .v4b__assist { opacity: 1; }
.v4b__dot--team { fill: var(--invert); stroke: var(--text); stroke-width: 3; opacity: 0; }
.v4.is-in .v4b__dot--team { opacity: 1; transition: opacity .3s ease 2.6s; }
/* 4B entries: three ways in, merging at Acquisition. Dashed hollow = marketing-led. */
.v4.v4b .v4b__in { transition-delay: 0s; }
.v4b__mkt { fill: none; stroke: var(--ground); stroke-width: 4; stroke-dasharray: 10 8; opacity: 0; transition: opacity .4s ease 1.4s; }
.v4.is-in .v4b__mkt { opacity: 1; }
.v4.v4b .v4b__in-hollow { transition-delay: 1.4s; }
.v4b__entry { text-anchor: start; }
.v4b__rider { transition: none !important; }
.v4b__rider--sales { fill: var(--text); stroke: var(--invert); }
/* 4B: marketing is not ours (see "What this is not"), so its way in is grey until it reaches Acquisition */
.v4.v4b .v4b__ghost { stroke: #BDBEB8; }
.v4b__mkt { stroke-dasharray: 6 10; }
.v4b__ghost-label { fill: #A3A49E; }
.v4b__rider.is-ghost { fill: var(--ground); stroke: #BDBEB8; stroke-dasharray: none; }


/* ---- runby portrait (14 Oct, UI test): square head crop next to the operator's name.
        Greyscale to stay inside the palette; the photos have their backgrounds removed,
        so the panel colour shows through. Sources: the portraits in Kath's 14 Oct team file, cropped to a
        head-and-shoulders square at 160px (2x). ---- */
.runby__face {
  width: 72px; height: 72px; flex: none; object-fit: cover;
  background: var(--card); border: 1px solid var(--line);
}

.foot__logo { display: block; height: 32px; width: auto; }

/* one sentence per line in multi-sentence headings (sentences.py) */
.sl { display: block; }

/* ---- carousel tiles crossfade instead of turning (14 Oct) ----
   The carousel's edge fade is a CSS mask, and a mask on an ancestor flattens 3D in some
   browsers (Safari among them): the rotateY turn either never showed or showed the front
   mirrored, so the tiles looked like they did not flip. Inside .carousel the faces now
   crossfade in place, same rules as the reduced-motion path above: hover shows the back,
   a click on the flip button inverts it. */
.carousel .tile__inner { transform: none !important; }
.carousel .tile__face { backface-visibility: visible; -webkit-backface-visibility: visible; transition: opacity 0.3s ease; }
.carousel .tile__face--back { transform: none; opacity: 0; }
.carousel .tile.is-flipped .tile__face--front { opacity: 0; }
.carousel .tile.is-flipped .tile__face--back { opacity: 1; }
@media (hover: hover) and (pointer: fine) {
  .carousel .tile:hover .tile__face--front { opacity: 0; }
  .carousel .tile:hover .tile__face--back { opacity: 1; }
  .carousel .tile.is-flipped:hover .tile__face--front { opacity: 1; }
  .carousel .tile.is-flipped:hover .tile__face--back { opacity: 0; }
}

/* ---- quote card, from Katya's Pipeline & Sales page (14 Oct): Growth's Dmitry Dygalo quote ---- */
.qcard { border: 1px solid var(--line); background: var(--card); padding: clamp(28px, 4vw, 52px) clamp(28px, 5vw, 64px); margin: 1.75rem 0 0; }
.qcard__mark { font-family: var(--mono); font-size: 2.6rem; line-height: 1; color: var(--soft); opacity: 0.35; margin: 0 0 10px; }
.qcard__text { font-size: clamp(1.15rem, 2vw, 1.55rem); line-height: 1.45; font-style: italic; color: var(--text); margin: 0 0 28px; max-width: 72ch; }
.qcard__byline { display: flex; align-items: center; justify-content: flex-end; gap: 14px; padding-top: 22px; border-top: 1px solid var(--line); }
.qcard__avatar { width: 44px; height: 44px; border: 1px solid var(--text); display: flex; align-items: center; justify-content: center; font-family: var(--mono); font-size: 0.78rem; font-weight: 700; color: var(--text); flex-shrink: 0; }
.qcard__name { display: block; font-weight: 700; font-size: 0.96rem; }
.qcard__role { display: block; font-family: var(--mono); font-size: 0.78rem; color: var(--soft); margin-top: 2px; }

/* hero CTA on the pillar pages (14 Oct), same as Katya's "Let's talk pipeline and revenue": jumps to the close */
.pillar__cta { margin: 0.4rem 0 1.6rem; justify-self: start; width: fit-content; }

/* "Who you'd work with" (14 Oct): the one-line bio sits next to the photo, under the name,
   in place of the pillar label; the photo is in colour */
.runby { align-items: flex-start; flex-wrap: nowrap; gap: 1.1rem; }
.runby__text { display: grid; gap: 0.35rem; justify-items: start; max-width: 60ch; }
.runby__bio { margin: 0; font-size: 1.02rem; line-height: 1.5; color: var(--soft); }
.runby .more { margin-top: 0.3rem; }
.eyebrow + .runby { border-top: 0; padding-top: 0; margin-top: 0; }

/* portraits are round (14 Oct) */
.runby__face { border-radius: 50%; }
