/* ============================================================
   Client micro-site — THE shared shell. One file, every client.

   This file is loaded by every page of every client portal. It is the
   single copy of the shell, which is what makes cross-page and
   cross-client drift structurally impossible rather than merely
   discouraged. Before this existed each page inlined its own copy of
   the shell and the copies drifted; the 2026-08-06 portal audit found
   a page rendering an 89px header against its siblings' 109px, and the
   opt-in shell-consistency gate never saw it.

   Values come from the brand overlay's tokens (below); this sheet reads var() only.
   The one exception is :root's motion tokens just below: motion is the system's, never a brand's.
   Canon: plugins/custom/marketing/harper-identity/knowledge/KNW_BR_MC_Visual-Design-System.md
          .claude/rules/content/mobile-first.md (the seven laws)

   Structure of a client portal page:
     .banner        confidentiality line, above everything
     nav.ring       tier 1 = phase (Proposal / Delivery), tier 2 = documents
     header.hero    the document opening
     section        the body
     footer         wordmark, tagline, copyright
   ============================================================ */

:root {

  /* motion belongs to the system, not to a brand, so it lives here and every brand inherits it: the values
     of design-tokens.json "motion" (and its generated tokens.css), held to it by scripts/check-motion.mjs */
  --motion-ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --motion-ease-layout: cubic-bezier(0.33, 1, 0.68, 1);
  --motion-press: 120ms; --motion-hover: 150ms; --motion-turn: 200ms; --motion-reveal-sharp: 300ms; --motion-reveal: 400ms;
  --motion-layout: 700ms; --motion-content-in: 250ms; --motion-content-in-delay: 300ms; --motion-content-out: 120ms;

}


/* The brand overlay (tokens + font-faces) is a separate sheet, loaded BEFORE
   this one: /shared/brands/{brand}.css — harperos.css by default, declared per
   family via `brand:` in _family.mjs. This file is the BLOCK CANON: structure
   only, reading var() — a raw color or font literal here is a build error
   (check-block-system rule 5). */

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

/* clip, never hidden, where the browser has it: both stop the page scrolling sideways (law 5),
   but hidden makes the body a scroll container, and a sticky nav inside one never sticks; it
   scrolled away with the page until Oct 1, 2026 */
html, body { overflow-x: hidden; overflow-x: clip; max-width: 100vw; }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: 16px;
  line-height: 1.6;
  color: var(--ink);
  background: var(--field);
  -webkit-font-smoothing: antialiased;
}

/* ---------- type ladder — canon screen_fluid, matching the shipped shell ----------
   h1 carries the TITLE role: clamp(40,8vw,64). h2 is the SECTION role: clamp(36,6vw,60).
   h4 is deliberately NOT a display face — it is the JetBrains Mono metadata label. */
/* Law 4 (canon, MC 2026-08-13): the display face OPENS — H1 opens the document,
   H2 opens a section. H3 is a step INSIDE a section, not a new one, so it takes
   the body face with weight carrying its rank. Grouping h3 here was why every
   client page in the portfolio rendered subsection heads in Ponomar. */
h1, .ts-h1, h2 {
  font-family: var(--font-display);
  font-weight: 400;
  color: var(--ink);
  margin: 0;
  letter-spacing: -0.01em;
}
h3 {
  font-family: var(--font-body);
  font-weight: 600;
  color: var(--ink);
  margin: 0;
  letter-spacing: -0.01em;
}
h1, .ts-h1 { font-size: var(--type-title); line-height: 1.1; }  /* .ts-h1: the type specimen's title sample, drawn without a second <h1> */
h2 { font-size: var(--type-section); line-height: 1.1; }
h3 { font-size: var(--type-subsection); line-height: 1.3; }
/* H4 is the JetBrains Mono metadata label (uppercase by authoring convention),
   not a small serif heading. Canon §Type scale. */
h4 {
  font-family: var(--font-mono);
  font-size: 18px;
  font-weight: 500;
  line-height: 1.3;
  color: var(--ink);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin: 0;
}
p { margin: 0; }
strong { font-weight: 600; }
a { color: var(--accent-label, var(--accent)); text-decoration: none; }
/* a link inside prose carries a green underline, so it still signals itself once its
   text is ink. The nav, the footer and a card's own link are not prose and stay clean. */
.body a, .blist a, .ln a, .note a, .ptable a, .tbl a, .swu a, .plede a, .aln a {
  text-decoration: var(--link-underline, none); text-decoration-color: var(--accent);
  text-decoration-thickness: 1px; text-underline-offset: 3px; }
.accent { color: var(--accent-text, var(--accent)); }

/* ---------- the subhead rule ----------
   Exactly ONE subhead per section, ONE SENTENCE (MC 2026-07-16). Everything after
   is body. The general-sibling guard forces any 2nd-or-later .body to body size by
   construction, so the defect cannot recur even if .sub is forgotten. (brand canon,
   MC 2026-07-01 — "encode that once and for all") */
.body { font-size: var(--type-lede); line-height: 1.55; color: var(--ink-muted); margin-top: var(--s5); max-width: 60ch; }
.body.tight { margin-top: var(--s4); }
.body.sub { font-size: 16px; line-height: 1.55; }
.wrap .body ~ .body { font-size: 16px; line-height: 1.55; }
.body strong { color: var(--ink); font-weight: 600; }
.muted { color: var(--ink-muted); }
.subtle { color: var(--ink-subtle); }

/* ---------- layout ---------- */
.wrap { max-width: var(--maxw); margin: 0 auto; padding: 0 var(--gutter); }
@media (min-width: 768px)  { :root { --gutter: var(--s6); } }  /* 32px */
@media (min-width: 1024px) { :root { --gutter: var(--s8); } }  /* 64px */

/* Sections separate by space and the 1px rule, never by a change of background.
   Canon §Surface rule. There is no .alt section class by design. */
section { padding: var(--s8) 0; border-top: 1px solid var(--rule); }
section:first-of-type { border-top: none; }

.eyebrow {
  font-family: var(--font-mono);
  font-size: 12px; font-weight: 500;
  text-transform: uppercase; letter-spacing: 0.14em;
  color: var(--accent-label, var(--accent));
  margin: 0 0 var(--s5);
}

/* ---------- focus: one ring, every interactive element (Affordance) ---------- */
:focus-visible {
  outline: 2px solid var(--accent-text, var(--accent));  /* a control holds 3:1 */
  outline-offset: 2px;
}
/* the skip link: the first stop on every page, out of sight until a keyboard reaches it (KNW_ST_MC_Accessibility.md, Structure) */
.skip { position: absolute; left: var(--s4); top: -100px; z-index: 100; display: inline-flex; align-items: center; min-height: 44px; padding: 0 var(--s4); background: var(--ink); color: var(--field); font-size: 15px; font-weight: 600; text-decoration: none; }
.skip:focus { top: var(--s2); }
/* the page's banner landmark around the nav; it draws no box, so the nav stays sticky against the page */
.site-head { display: contents; }


/* ---------- the confidential banner — the document's first line, above the nav.
   Ink field, mono 11, centred: it states who the document is for. ---------- */
.banner { background: var(--ink); color: var(--field); font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.16em; text-align: center; padding: var(--s2) var(--s4); line-height: 1.6; }
/* Eased tracking on a phone. The full tracking wraps a long banner line at
   375px, so the tracking eases below 768px and there is room for all of it
   above. It does not hold every name to one line: measured Sep 23, 2026, the
   four longest client names run two lines and 51px at 11px, and ran two lines
   and 48px at the 10px this carried until that day's ruling — the wrap was
   never the point size. Every micro label is 11px (MC, 2026-09-23). */
@media (max-width: 767px) {
  /* The longest banner line in the portfolio runs 51 characters with
     "Prepared for" and "Confidential". It wraps to two lines here, as it did
     before the ruling. What the eased tracking buys, measured across all 251
     banner lines at 375px on Sep 23, 2026: 195 hold one line against 134 at
     the full tracking, so it rescues 61 names from a wrap. Two or three names
     will not show it — the first sample taken here showed no change at all. */
  .banner { font-size: 11px; letter-spacing: 0.06em; padding: var(--s2); }
}

/* ---------- nav ring — the progressive reveal ---------- */
.ring {
  /* STATIC on the phone, sticky from tablet up. A phase carrying eight
     documents wraps to three rows at 375px — roughly 264px, a third of the
     viewport — and pinning that would hold a third of the screen hostage for
     the whole read. Static, it shows every document when you are at the top and
     gets out of the way once you start reading, which is when you want the
     screen. On a wide viewport the same nav is two rows and pinning is a
     convenience rather than a tax. */
  position: static;
  background: var(--field);
  border-bottom: 1px solid var(--rule);
}
@media (min-width: 768px) { .ring { position: sticky; top: 0; z-index: 50; } }
/* nav lift (body.navlift): the hairline under the nav arrives only once the hero has scrolled away */
body.navlift .ring { border-bottom-color: transparent; transition: border-color var(--motion-reveal) var(--motion-ease-out); }
body.navlift.past-hero .ring { border-bottom-color: var(--rule); }
.ring .inner {
  max-width: var(--maxw); margin: 0 auto; padding: var(--s3) var(--gutter);
  display: flex; align-items: center; gap: var(--s2) var(--s5);
  justify-content: space-between; flex-wrap: wrap;
}
@media (min-width: 768px) { .ring .inner { flex-wrap: nowrap; } }
/* The wordmark composes from the harperOS atom: ink body, green `_` terminal.
   No underline — the shipped shell's `a` carries no border. */
.wordmark {
  /* sized to the website wordmark (28px, brand.ts .bp .wordmark) — MC 2026-07-29 */
  font-family: var(--font-display); font-size: 28px; color: var(--ink);
  letter-spacing: -0.01em;
  line-height: 1; white-space: nowrap; border-bottom: none;
  display: inline-flex; align-items: center; min-height: 44px;
}
.wordmark .u { color: var(--accent); }
@media (hover: hover) and (pointer: fine) { .wordmark:hover { color: var(--ink); opacity: 1; } }

/* Steps are a segmented tab bar on the phone — a full-width row of three equal
   cells under the wordmark, every document always visible, labels centered,
   numbers hidden (the label is the tab; the number returns at desktop). No
   scroller, no hamburger, no ragged wrap: three peers get three equal cells
   (Norman: visible controls; the segmented control is the standard pattern
   for a small fixed set). One inline row from 768 up. */
.steps {
  /* auto-fill, not a fixed 3: a phase carries however many documents it carries,
     and the row has to hold 3 for one client and 6 for another without either
     one being hand-tuned. At 375px the 104px floor still yields 3 columns, so
     the three-document families render exactly as they did before. */
  display: grid; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
  width: 100%; align-items: stretch;
}
.steps .step { justify-content: center; padding: var(--s3) var(--s1); white-space: normal; text-align: center; }
.steps .step .n { display: none; }
@media (min-width: 768px) {
  /* wrap, not nowrap: the delivery phase grows by one document every week, and
     a row that cannot wrap pushes the later updates off the right edge where
     the page's overflow guard hides them completely. */
  .steps { display: flex; flex-wrap: wrap; gap: var(--s2); align-items: center; width: auto; }
  .steps .step { justify-content: flex-start; padding: var(--s3); }
  .steps .step .n { display: inline; }
}
.step {
  display: flex; align-items: center; gap: var(--s2);
  font-family: var(--font-mono); font-size: 12px; letter-spacing: 0.04em;
  text-transform: uppercase; white-space: nowrap;
  padding: var(--s3); min-height: 44px;
  border-bottom: 2px solid transparent; color: var(--ink-muted);
  cursor: pointer;
}
.step .n { color: var(--ink-subtle); }
@media (hover: hover) and (pointer: fine) { .step:hover { color: var(--ink); border-bottom-color: var(--rule); } }
.step:active { color: var(--ink); }
.step[aria-current="page"] { color: var(--ink); border-bottom-color: var(--accent); }
/* A locked step is genuinely inert: muted, no pointer, not focusable, not a link
   target. A thing that does nothing never wears the costume of a control.
   Canon §Interaction (Affordance — the honest signifier). */
.step.locked {
  color: var(--ink-subtle); opacity: 0.55;
  cursor: default; pointer-events: none;
}
.legend { font-family: var(--font-mono); font-size: 11px; color: var(--ink-subtle); text-transform: uppercase; letter-spacing: 0.1em; }

/* ---------- tier 1 — the phase tabs (Proposal / Delivery) ----------
   A client portal has two lives: the documents that won the work, and the
   record of the work being delivered. They are different reading contexts, so
   they get different sections rather than one flat list of eleven links — and
   the phase is carried in the URL (/proposal/…, /delivery/…) so the address bar
   says the same thing the nav does.

   The phase tab sits beside the wordmark on row one; the documents of the
   ACTIVE phase sit on row two. Switching phase lands on that phase's first
   document, so the second row is always the row you are reading in. */
.phases { display: flex; gap: var(--s2); align-items: center; flex-wrap: wrap; }
.phase {
  font-family: var(--font-mono); font-size: 12px; letter-spacing: 0.04em;
  text-transform: uppercase; white-space: nowrap;
  display: inline-flex; align-items: center; min-height: 44px;
  padding: var(--s3) var(--s2); color: var(--ink-subtle);
  border-bottom: 2px solid transparent;
}
@media (hover: hover) and (pointer: fine) { .phase:hover { color: var(--ink); } }
.phase[aria-current="true"] { color: var(--ink); border-bottom-color: var(--accent); }
/* A portal before signature has a proposal and no delivery yet. The Delivery
   phase still shows — it is what comes next, and a client should see the whole
   arc — but it is genuinely inert: muted, no pointer, not focusable, not a link
   target. A thing that does nothing never wears the costume of a control.
   Canon §Interaction (Affordance — the honest signifier). */
.phase.locked {
  color: var(--ink-subtle); opacity: 0.55;
  cursor: default; pointer-events: none;
}

/* ---------- tier 2 — the documents inside the active phase ----------
   A hairline above it, so the two tiers read as one nav block with an internal
   division rather than as two stacked bars. */
/* ---------- a wide table scrolls, never clips ----------
   html/body carry overflow-x:hidden (the seven laws, law 5). That guard stops
   the PAGE scrolling sideways, which also means anything wider than the
   viewport is silently cut off with no indication it exists. A data table is
   the usual offender. Giving it its own scroll box is the opt-in the law
   provides for. Canon: .claude/rules/content/mobile-first.md, law 7. */
.tscroll { overflow-x: auto; max-width: 100%; -webkit-overflow-scrolling: touch; }
.tscroll > table { min-width: 100%; }

.subring { border-top: 1px solid var(--rule-soft); }
.subring .inner {
  max-width: var(--maxw); margin: 0 auto; padding: 0 var(--gutter);
}

/* ---------- hero ---------- */
.hero { padding: var(--s8) 0 0; }
/* a hero sitting directly on a band keeps the site hero's bottom space, so its last line never touches the band */
.hero:has(+ .band) { padding-bottom: var(--s7); }
@media (min-width: 1024px) { .hero:has(+ .band) { padding-bottom: var(--s8); } }
.hero h1 { max-width: 18ch; }
.meta { font-family: var(--font-mono); font-size: 12px; color: var(--ink-subtle); text-transform: uppercase; letter-spacing: 0.1em; margin-top: var(--s6); }
/* the declared small-mono tier — replaces the inline style= repetitions */
.meta-sm { font-family: var(--font-mono); font-size: 12px; color: var(--ink-subtle); letter-spacing: 0.04em; margin-top: var(--s3); }
/* a small explanatory note under a figure or control */
/* the note, as the approved pages render it — 15px muted + accent bar. The
   approved client pages override the old 13px ink-subtle note with
   this treatment everywhere it appears (R3, MC's ruling pending; 13px fails
   his not-too-small-to-read anchor). */
.note { font-size: 15px; line-height: 1.55; color: var(--ink-muted); margin-top: var(--s3); padding-left: var(--s4); border-left: 2px solid var(--accent); max-width: 60ch; }

/* ---------- cards / grid (mobile-first: 1 col, enhance up) ---------- */
.grid { display: grid; grid-template-columns: 1fr; gap: var(--s5); margin-top: var(--s6); }
@media (min-width: 768px) { .grid.cols-2 { grid-template-columns: 1fr 1fr; } .grid.cols-3 { grid-template-columns: 1fr 1fr 1fr; } }
.card { background: var(--alt); border: 1px solid var(--rule); padding: var(--s5); }
.card h4 { margin-bottom: var(--s2); }
.card .tag { font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--accent-label, var(--accent)); }
/* Question card: mono label, question at body tier, and a designed answer void.
   The void is what makes the neutral-fill rung honest — the card is visibly half-full. */
.card .q { font-size: 16px; line-height: 1.5; font-weight: 600; color: var(--ink); margin-top: var(--s3); }

/* verbatim / quote */
.quote { border: 1px solid var(--rule); border-left: 2px solid var(--accent); background: var(--alt); padding: var(--s5) var(--s6); font-size: 15px; line-height: 1.5; color: var(--ink); margin-top: var(--s6); max-width: 60ch; }
.quote .who { display: block; font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink-subtle); margin-top: var(--s3); }

/* the Our -> Your arc marker */
.arc { display: flex; flex-wrap: wrap; gap: var(--s2); font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.12em; color: var(--ink-subtle); margin-bottom: var(--s5); }
.arc b { color: var(--accent-label, var(--accent)); font-weight: 500; }

/* rows */
.row { display: grid; grid-template-columns: 1fr; gap: var(--s3); padding: var(--s5) 0; border-top: 1px solid var(--rule-soft); }
@media (min-width: 768px) { .row { grid-template-columns: 1fr 1.4fr; gap: var(--s6); } }
.row .k { font-weight: 600; }

/* ---------- calculator ----------
   NOT a dark panel: the footer is the only dark surface (canon §Surface rule).
   It reads as a card — the square atom, hairline border, generous space. */
.calc {
  background: var(--alt); border: 1px solid var(--rule);
  color: var(--ink); padding: var(--s4); margin-top: var(--s6);
}
@media (min-width: 768px) { .calc { padding: var(--s6); } }
.calc label {
  display: block; font-family: var(--font-mono); font-size: 12px;
  text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--ink-subtle); margin: var(--s5) 0 var(--s2);
}
/* Tap targets: every control clears 44px on a touch surface. */
.calc input[type=range] {
  width: 100%; accent-color: var(--accent);
  min-height: 44px; cursor: pointer;
}
.calc select {
  width: 100%; background: var(--field); color: var(--ink);
  border: 1px solid var(--rule); padding: var(--s3);
  font-family: var(--font-mono); font-size: 14px;
  min-height: 44px; cursor: pointer; border-radius: var(--radius);
}
@media (hover: hover) and (pointer: fine) { .calc select:hover { border-color: var(--ink); } }
.calc .out { font-family: var(--font-display); font-size: var(--type-figure-large); color: var(--accent-text, var(--accent)); margin-top: var(--s5); line-height: 1.1; }
.calc .upside { font-family: var(--font-mono); font-size: 14px; color: var(--ink-subtle); margin-top: var(--s2); }
.calc .upside b { color: var(--ink); font-weight: 500; }
.calc .val { font-family: var(--font-mono); color: var(--ink); }
/* Confidence is encoded in type weight and label, not colour: the status palette is
   scoped to diffs, charts and ops dashboards — never a marketing surface.
   Canon §Tokens ("The scope is the rule"). */
.calc .conf {
  display: inline-block; font-family: var(--font-mono); font-size: 11px;
  text-transform: uppercase; letter-spacing: 0.08em;
  padding: 2px 8px; margin-left: var(--s2);
  border: 1px solid currentColor; vertical-align: middle;
}
.calc .conf.high { color: var(--ink); font-weight: 500; }
.calc .conf.med  { color: var(--ink-muted); }
.calc .conf.low  { color: var(--ink-subtle); }
.calc .conf-note { font-size: 13px; color: var(--ink-subtle); margin-top: var(--s2); min-height: 1.2em; }

/* ---------- swatches — a design system's colors, each shown as it ships ----------
   The chip is filled from the token itself, so it shows what the brand overlay
   loads; the value printed beside it is read from the same file. */
.swatches { display: grid; grid-template-columns: 1fr; gap: var(--s4); margin-top: var(--s6); }
@media (min-width: 768px) { .swatches.cols-2 { grid-template-columns: 1fr 1fr; } .swatches.cols-3 { grid-template-columns: 1fr 1fr 1fr; } }
.sw { background: var(--alt); border: 1px solid var(--rule); padding: var(--s4); }
.sw .chip { display: block; height: 64px; border: 1px solid var(--rule); margin-bottom: var(--s3); }
.sw .swn { margin: 0; font-size: 16px; font-weight: 600; color: var(--ink); }
.sw .swv { margin: var(--s1) 0 0; font-family: var(--font-mono); font-size: 12px; color: var(--ink-muted); }
.sw .swu { margin: var(--s2) 0 0; font-size: 15px; line-height: 1.55; color: var(--ink-muted); }
.sw .swc { margin: var(--s2) 0 0; font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: .1em; color: var(--ink-subtle); }
.chip.t-field { background: var(--field); } .chip.t-alt { background: var(--alt); } .chip.t-ink { background: var(--ink); }
.chip.t-ink-muted { background: var(--ink-muted); } .chip.t-ink-subtle { background: var(--ink-subtle); }
.chip.t-rule { background: var(--rule); } .chip.t-rule-soft { background: var(--rule-soft); }
.chip.t-accent { background: var(--accent); } .chip.t-accent-soft { background: var(--accent-soft); }
.chip.t-accent-text { background: var(--accent-text, var(--accent)); }
.chip.t-accent-label { background: var(--accent-label, var(--accent)); }

/* ---------- entries — an index of pieces, one row each, the whole row the link ---------- */
.entries { margin-top: var(--s6); border-top: 1px solid var(--rule); }
.entry { display: block; position: relative; padding: var(--s5) var(--s7) var(--s5) 0; border-bottom: 1px solid var(--rule); color: inherit; }
@media (hover: hover) and (pointer: fine) { .entry:hover { border-bottom-color: var(--ink); } }
.entry .ek { margin: 0; font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: .12em; color: var(--ink-subtle); }
.entry .et { margin: var(--s2) 0 0; font-size: 18px; font-weight: 600; line-height: 1.3; color: var(--ink); max-width: var(--measure); }
.entry .ex { margin: var(--s2) 0 0; font-size: 16px; line-height: 1.55; color: var(--ink-muted); max-width: 60ch; }
.entry .earr { position: absolute; right: var(--s4); top: var(--s5); width: 20px; height: 20px; color: var(--accent-text, var(--accent)); transition: transform var(--motion-turn) var(--motion-ease-out); }
@media (hover: hover) and (pointer: fine) { .entry:hover .earr { transform: translateX(4px); } }
/* entries · feature: the entries an index leads with, as white cards in whole rows; the arrow sits
   at the card's foot, the title on the subsection rung */
.entries.feature { display: grid; grid-template-columns: 1fr; gap: var(--s4); border-top: none; }
.entries.feature .entry { display: flex; flex-direction: column; min-width: 0; background: var(--alt); border: 1px solid var(--rule); padding: var(--s5); transition: border-color var(--motion-turn) var(--motion-ease-out); }
@media (hover: hover) and (pointer: fine) { .entries.feature .entry:hover { border-color: var(--ink); } }
.entries.feature .entry .et { font-size: 18px; }
.entries.feature .entry .earr { position: static; margin-top: auto; padding-top: var(--s5); }
@media (min-width: 768px) { .entries.feature.n2 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .entries.feature.n3 { grid-template-columns: repeat(3, 1fr); } }
/* entries · table: a dated index as rows (date, an optional category, the title), each row one link.
   Stacked on a phone; columns from the tablet up. */
.entries.etable { border-top: 1px solid var(--rule); }
.etable .trow { display: grid; grid-template-columns: 1fr; gap: 4px; padding: var(--s4) 0; border-bottom: 1px solid var(--rule); color: inherit; text-decoration: none; }
.etable .thead { display: none; }
.etable .tdate, .etable .tcat, .etable .thead span { font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: .12em; color: var(--ink-subtle); }
.etable .ttitle { font-size: 16px; line-height: 1.45; color: var(--ink); }
@media (hover: hover) and (pointer: fine) { .etable a.trow:hover .ttitle { text-decoration: underline; text-underline-offset: 3px; } }
@media (min-width: 768px) {
  .etable .trow { grid-template-columns: 160px 1fr; gap: var(--s5); align-items: baseline; }
  .etable.wcat .trow { grid-template-columns: 160px 180px 1fr; }
  .etable .thead { display: grid; padding: var(--s3) 0; }
}
/* entries · course: one card per course, its numbered lessons and a start link at the foot */
.entries.course { display: grid; grid-template-columns: 1fr; gap: var(--s4); border-top: none; margin-top: var(--s6); }
@media (min-width: 768px) { .entries.course { grid-template-columns: repeat(2, 1fr); } }
.ccard { display: flex; flex-direction: column; background: var(--alt); border: 1px solid var(--rule); padding: var(--s6) var(--s5); }
.ccard .chead { display: flex; justify-content: space-between; align-items: baseline; gap: var(--s3); }
.ccard .ek { margin: 0; font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: .12em; color: var(--ink-subtle); }
.ccard .cnum { font-family: var(--font-mono); font-size: 11px; color: var(--ink-subtle); }
.ccard .ct { margin-top: var(--s2); display: inline-flex; align-items: center; min-height: 44px; font-size: 20px; font-weight: 600; line-height: 1.3; color: var(--ink); text-decoration: none; }
@media (hover: hover) and (pointer: fine) { .ccard .ct:hover { text-decoration: underline; text-underline-offset: 3px; } }
.ccard .ex { margin: var(--s2) 0 0; font-size: 16px; line-height: 1.55; color: var(--ink-muted); }
.ccard .clessons { list-style: none; margin: var(--s5) 0 0; padding: 0; border-top: 1px solid var(--rule); }
.ccard .clessons a { display: flex; gap: var(--s3); min-height: 44px; padding: var(--s3) 0; border-bottom: 1px solid var(--rule-soft); font-size: 15px; line-height: 1.4; color: var(--ink); text-decoration: none; }
@media (hover: hover) and (pointer: fine) { .ccard .clessons a:hover { color: var(--accent-text, var(--accent)); } }
.ccard .clessons .ln { flex: none; min-width: 20px; font-family: var(--font-mono); font-size: 11px; color: var(--ink-subtle); }
.ccard .cfoot { margin-top: auto; padding-top: var(--s5); display: flex; justify-content: space-between; align-items: center; gap: var(--s3); }
.ccard .cstart { display: inline-flex; align-items: center; gap: 6px; min-height: 44px; font-size: 15px; font-weight: 600; color: var(--ink); text-decoration: none; }
.ccard .cstart .carr { width: 16px; height: 16px; color: var(--accent-text, var(--accent)); transition: transform var(--motion-turn) var(--motion-ease-out); }
@media (hover: hover) and (pointer: fine) { .ccard .cstart:hover .carr { transform: translateX(3px); } }
.ccard .ccount { font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: .12em; color: var(--ink-subtle); }

/* ---------- the article register — the reading ladder a long piece is set in ----------
   A page takes it with register: "article". The headline rungs step down, because an
   article is read straight through rather than scanned, and its sections run on with
   no rule between them. */
/* the article register, every size on a rung of the Visual Design System's table (the creative
   director's review, Oct 2, 2026: 52, 23 and 17.28 sat on no rung): the title on the private
   overview's title rung, a section on the pull-line rung, a sub-section on the H3 rung, the
   subhead (a section's first .body) on the 18px rung, and the running text after it at 16px */
.article h1, .article .ts-h1 { font-size: var(--type-section); line-height: 1.1; }
.article h2 { font-size: var(--type-step); line-height: 1.15; }
.article h3 { font-family: var(--font-body); font-weight: 600; font-size: var(--type-subsection); line-height: 1.25; }
.article .body { font-size: 18px; line-height: 1.7; }
.article .body.sub, .article .wrap .body ~ .body { font-size: 16px; line-height: 1.7; }
/* running text holds to 60 characters on a page read straight through, its first paragraph too */
.article .wrap .body { max-width: 60ch; }
.article section { border-top: none; padding: var(--s6) 0; }
.article section:first-of-type { padding-top: var(--s4); }
.article .hero { padding-bottom: var(--s5); }
.byline { display: flex; align-items: center; gap: var(--s4); padding-bottom: var(--s5); border-bottom: 1px solid var(--rule); }
.byline .avatar { width: 44px; height: 44px; object-fit: cover; display: block; flex: none; }
.byline .who { font-size: 16px; color: var(--ink); }
.byline .who .role { display: block; font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: .12em; color: var(--ink-subtle); margin-top: 4px; }
.byline .when { margin: 0 0 0 auto; font-family: var(--font-mono); font-size: 12px; color: var(--ink-subtle); }
.signoff { margin-top: var(--s7); padding-top: var(--s5); border-top: 1px solid var(--rule); }
.signoff .label { margin: 0; font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: .12em; color: var(--ink-subtle); }
.signoff .name { margin: var(--s2) 0 0; font-family: var(--font-display); font-size: 20px; color: var(--ink); }
.signoff .name .role { display: block; font-family: var(--font-body); font-size: 14px; color: var(--ink-subtle); margin-top: 2px; }

/* ---------- the design-system blocks: type specimen, space scale, marks, actions, icons ----------
   Each draws with the system's own rules: a specimen row renders a real heading or the
   real block, a bar takes its step's own token, a mark sits on the ground it is made for. */
.tspec { margin-top: var(--s6); border-top: 1px solid var(--rule); }
.tsr { padding: var(--s5) 0; border-bottom: 1px solid var(--rule); }
.tsr .tsn { margin: 0; font-family: var(--font-mono); font-size: 12px; text-transform: uppercase; letter-spacing: .1em; color: var(--ink); }
.tsr .tss { margin: var(--s1) 0 0; font-family: var(--font-mono); font-size: 11px; color: var(--ink-subtle); }
.tsr .tsx { margin-top: var(--s3); }
.tsr .tsx > * { margin-top: 0; }
.tsr .tsx .card { max-width: 480px; }
.tsface { margin: 0; font-size: var(--type-step); line-height: 1.3; color: var(--ink); }  /* the pull-line rung */
.ff-display { font-family: var(--font-display); } .ff-body { font-family: var(--font-body); } .ff-mono { font-family: var(--font-mono); }
.spscale { margin-top: var(--s6); }
.spr { display: grid; grid-template-columns: 72px 56px 1fr; align-items: center; gap: var(--s4); padding: var(--s2) 0; border-bottom: 1px solid var(--rule-soft); }
.spr code { font-family: var(--font-mono); font-size: 12px; color: var(--ink); }
/* inline code on the public site: the mono family, a step under the text around it */
.site code { font-family: var(--font-mono); font-size: .9em; }
.spr .spv { font-family: var(--font-mono); font-size: 12px; color: var(--ink-subtle); }
.spbar { display: block; height: 12px; background: var(--ink-muted); }
.spbar.s1 { width: var(--s1); } .spbar.s2 { width: var(--s2); } .spbar.s3 { width: var(--s3); } .spbar.s4 { width: var(--s4); } .spbar.s5 { width: var(--s5); }
.spbar.s6 { width: var(--s6); } .spbar.s7 { width: var(--s7); } .spbar.s8 { width: var(--s8); } .spbar.s9 { width: var(--s9); } .spbar.s10 { width: var(--s10); }
.marks { display: grid; grid-template-columns: 1fr; gap: var(--s4); margin-top: var(--s6); }
@media (min-width: 768px) { .marks.cols-2 { grid-template-columns: 1fr 1fr; } .marks.cols-3 { grid-template-columns: 1fr 1fr 1fr; } }
/* scoped under .marks: the today/tomorrow label and the old metagrid label share the name
   .mk, and an unscoped rule drew both as white boxes (Oct 1, 2026) */
.marks .mk { margin: 0; background: var(--alt); border: 1px solid var(--rule); }
.marks .mk .mkimg { height: 160px; display: flex; align-items: center; justify-content: center; padding: var(--s5); border-bottom: 1px solid var(--rule); }
.marks .mk.g-field .mkimg { background: var(--field); } .marks .mk.g-box .mkimg { background: var(--alt); } .marks .mk.g-ink .mkimg { background: var(--ink); }
.marks .mk img { max-width: 100%; max-height: 100%; object-fit: contain; display: block; }
.marks .mk figcaption { padding: var(--s4); }
.marks .mk .swn { margin: 0; font-size: 16px; font-weight: 600; color: var(--ink); }
.marks .mk .swu { margin: var(--s2) 0 0; font-size: 15px; line-height: 1.55; color: var(--ink-muted); }
.marks .mk .swv { margin: var(--s2) 0 0; font-family: var(--font-mono); font-size: 12px; }
.ctas .tlink { align-self: center; display: inline-flex; align-items: center; min-height: 44px; font-size: 15px; }
.icongrid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s4); margin-top: var(--s6); }
@media (min-width: 768px) { .icongrid.cols-3 { grid-template-columns: repeat(3, 1fr); } .icongrid.cols-4 { grid-template-columns: repeat(4, 1fr); } }
.icn { background: var(--alt); border: 1px solid var(--rule); padding: var(--s4); }
.icn .ico { display: block; }
.icn .swv { margin: var(--s3) 0 0; font-family: var(--font-mono); font-size: 12px; color: var(--ink); }
.icn .swu { margin: var(--s1) 0 0; font-size: 15px; line-height: 1.5; color: var(--ink-muted); }

/* ---------- footer — the one dark surface, ink, every page (canon §Surface rule) ---------- */
footer { background: var(--ink); color: var(--field); padding: var(--s8) 0 var(--s7); }
footer a { color: var(--field); }
footer .mark { font-family: var(--font-display); font-size: 30px; color: var(--field); line-height: 1; letter-spacing: -0.01em; }
footer .mark .u { color: var(--accent); }
/* the tagline is said, not named: Inter at 14px, as on the homepage and About (MC 2026-09-17) */
footer .line { margin-top: var(--s3); font-family: var(--font-body); font-size: 14px; line-height: 1.6; color: var(--footer-line); }
footer .conf { margin-top: var(--s6); font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: .14em; color: var(--footer-conf); }
/* the link row a family declares (the site: Terms, Privacy, Support); each link a 44px tap target */
footer .flinks { margin-top: var(--s2); display: flex; flex-wrap: wrap; column-gap: var(--s5); font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: .14em; }
footer .flinks a { color: var(--footer-line); display: inline-flex; align-items: center; min-height: 44px; }

/* ---------- internal build marker ----------
   Inert scaffolding, not a callout: green marks an element, it never floods an area
   (canon §Tokens). Strip these before any promotion to a client-facing surface. */
.stub-note {
  background: transparent; border: 1px solid var(--rule);
  border-left: 2px solid var(--accent);
  padding: var(--s4); font-size: 13px; color: var(--ink-subtle);
  font-family: var(--font-mono); line-height: 1.5; margin-top: var(--s5);
}

/* ---------- the hero meta-grid — who / by / when as a vertical ruled block ----------
   The family-standard hero treatment,
   corrected from a horizontal-columns variant on MC's call, 2026-07-25: labeled rows
   read vertically, label column beside the value, a hairline rule above and below —
   the formality of a title page. The document top is eyebrow · h1 at system scale ·
   one body statement · this block. No covernote. */
.metagrid { display: flex; flex-direction: column; gap: var(--s3); margin-top: var(--s6); margin-bottom: var(--s6); padding: var(--s5) 0; border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule); max-width: 760px; }
.metagrid > div { display: grid; grid-template-columns: 1fr; gap: var(--s1); }
@media (min-width: 768px) { .metagrid > div { grid-template-columns: 150px 1fr; gap: 0 var(--s6); align-items: baseline; } }
.metagrid .mk { font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink-subtle); }
.metagrid .mv { font-size: 15px; line-height: 1.5; color: var(--ink); margin-top: 0; }

/* ---------- the continue block — the document chain's forward door ----------
   At the end of a document, before the footer: the next document, prominent —
   never expect the reader to find the top nav (MC 2026-07-25). The whole block
   is the link; one green — the arrow, the direction of travel; hover is the
   border waking and the arrow leaning, nothing louder. */
.continue { display: block; border: 1px solid var(--rule); padding: var(--s5); margin-top: var(--s7); text-decoration: none; transition: border-color var(--motion-turn) var(--motion-ease-out); }
@media (hover: hover) and (pointer: fine) { .continue:hover { border-color: var(--ink-muted); } }
.continue .ck { font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink-subtle); display: block; }
.continue .cn { font-family: var(--font-display); font-size: var(--type-step); line-height: 1.2; color: var(--ink); display: block; margin-top: var(--s2); }
.continue .cn .carr { color: var(--accent-text, var(--accent)); margin-left: var(--s3); display: inline-block; transition: transform var(--motion-turn) var(--motion-ease-out); }
@media (hover: hover) and (pointer: fine) { .continue:hover .cn .carr { transform: translateX(4px); } }
.continue .cl { font-size: 15px; line-height: 1.5; color: var(--ink-muted); display: block; margin-top: var(--s2); }
@media (min-width: 768px) { .continue { padding: var(--s6); } }

/* ---------- the dense ladder — SCOPED to tech-brief-class reference surfaces ONLY ----------
   Client documents (overview, proposal, approach, delivery plan, the portal pages) read
   at the system scale above — they are the product and they do not whisper (MC audit
   2026-07-25; one family was reading at 40px section heads while the other client
   families and the marketing site read at 60). Values are the shipped
   tech-brief family (precedented, not invented). A genuinely dense reference page opts in
   with <body class="dense">; it never re-types its own sizes. (MC ruling 2026-07-16:
   60px section heads overwhelm a content-heavy TECH-BRIEF page — that scope, no wider.) */
.dense h1 { font-size: var(--type-title); }  /* was 52 — misencoded; every shipped page overrode it */
.dense h2 { font-size: var(--type-section-dense); }
.dense h3 { font-size: var(--type-subsection); }
.dense .body { font-size: 18px; }
.dense .wrap .body ~ .body { font-size: 16px; }

/* ---------- the bulleted list — body copy with the green square marker ---------- */
.list { list-style: none; margin: var(--s5) 0 0; padding: 0; display: flex; flex-direction: column; gap: var(--s3); max-width: 60ch; }
.list li { font-size: 16px; line-height: 1.55; color: var(--ink-muted); position: relative; padding-left: var(--s4); }
.list li::before { content: ''; position: absolute; left: 0; top: 9px; width: 4px; height: 4px; background: var(--accent); }
.list li strong { color: var(--ink); font-weight: 600; }

/* Container ladder: the hairline rung — a defined set, grouped, still of the page.
   Distinct from .card (neutral fill = an object on the page). */
.set { border: 1px solid var(--rule); padding: var(--s5); margin-top: var(--s6); max-width: 68ch; }
.set .list { margin-top: 0; max-width: none; }

/* Themes grid — ported from an approved client proposal's "what you are looking to
   unlock" module. Two adaptations: .tl takes ink-subtle (accent stays reserved for actions),
   and .by is omitted — naming a handling agent presumes a solution, which Orientation
   has not earned. */
.themes { margin-top: var(--s6); display: grid; grid-template-columns: 1fr; border-top: 1px solid var(--rule); border-left: 1px solid var(--rule); }
.theme { padding: var(--s6); border-right: 1px solid var(--rule); border-bottom: 1px solid var(--rule); }
.tl { font-family: var(--font-mono); font-size: 12px; text-transform: uppercase; letter-spacing: .13em; color: var(--accent-label, var(--accent)); margin-bottom: var(--s5); }
.ti { padding: var(--s4) 0; border-top: 1px solid var(--rule-soft); }
.ti:first-of-type { border-top: none; padding-top: 0; }
.ti .p { font-size: 15px; font-weight: 600; color: var(--ink); line-height: 1.4; }
.ti .s { font-size: 14px; color: var(--ink-muted); line-height: 1.45; margin-top: var(--s1); }
@media (min-width: 768px) { .themes { grid-template-columns: repeat(2, 1fr); } }

/* ---------- level-2 dropdown — a step with children opens VERTICALLY ----------
   The Anthropic model, ratified by MC 2026-08-13 (SPEC_2026-08-13_WB_MC_Portal-
   Nav-Level2-Dropdown): one horizontal row of level-1 steps; a step whose section
   holds more than one document becomes a trigger — label + chevron (down closed,
   up open) — and its children list vertically in a panel under it. Never a second
   horizontal row of documents. Current-location marking is unchanged: the parent
   trigger carries aria-current on a child page (green underline via the existing
   .step rule), and inside the panel the current child is an inert accent span —
   a page never links to itself (the 2026-08-06 audit rule, carried forward).
   No shadow on the panel — Restraint forbids it; the hairline border separates. */
.drop { position: relative; display: flex; }
.dropbtn { background: none; border-top: 0; border-left: 0; border-right: 0; flex: 1 1 auto;
  /* explicit, not font:inherit — this rule sits after .step in the cascade, so an
     inherit here overrides the step's mono with the body face (the wrong-font Demo). */
  font-family: var(--font-mono); font-size: 12px; letter-spacing: 0.04em; text-transform: uppercase; }
.chev { display: inline-block; transition: transform var(--motion-press) var(--motion-ease-out); color: var(--ink-subtle); }
.drop.open .chev { transform: rotate(180deg); }
.menu {
  /* right-anchored: the steps live at the right end of the nav, so a left-anchored
     panel walks off the viewport edge and the overflow guard clips it silently.
     Pure white, not the warm-white field: the panel floats over field-colored
     content, and field-on-field has no edge (MC, 2026-08-13). Hover is the light
     green — grey-on-grey read as no signal. */
  display: none; position: absolute; top: 100%; right: 0; z-index: 60;
  min-width: 260px; background: var(--alt); border: 1px solid var(--rule);
  padding: var(--s2) 0;
}
.drop.open .menu { display: block; }
@media (hover: hover) and (pointer: fine) {
  .drop:hover .menu, .drop:focus-within .menu { display: block; }
  .drop:hover .chev, .drop:focus-within .chev { transform: rotate(180deg); }
}
.menu a, .menu .cur {
  display: block; padding: var(--s3) var(--s4);
  font-family: var(--font-mono); font-size: 12px; letter-spacing: 0.04em;
  text-transform: uppercase; color: var(--ink-muted);
  border-bottom: none; white-space: nowrap;
}
@media (hover: hover) and (pointer: fine) { .menu a:hover { color: var(--ink); background: var(--accent-soft); } }
.menu .cur { color: var(--accent-text, var(--accent)); }
/* On the phone the panel spans the nav, not the cell — the anchored panel would
   clip at the right edge for a late step; the full-width panel is the Anthropic
   mobile behavior and needs no second layout. */
@media (max-width: 767px) {
  .ring .inner { position: relative; }
  .drop { position: static; }
  .menu { left: 0; right: 0; min-width: 0; }
}

/* ---- block layer ----
   The closed block vocabulary of the client-page block system. Every class the
   renderer (scripts/render-client-pages.mjs) emits is defined HERE and only here,
   at canon values. A generated page carries no <style> of its own — that is the
   invariant: you can change blocks, you cannot change design.
   Contract: SPEC_2026-08-13_BR_MC_Client-Page-Block-System.md (brand plugin).
   Existing shell classes above (.hero, .card, .grid, .tscroll, .note, .quote,
   .eyebrow, .body) are part of the vocabulary and are not re-declared. */

/* lockup sub-label (Law 2: the rung is 12px/500) */
/* ---- the site shell (shell: "site") — the marketing surface ----
   The one button treatment: ink fill, alt text, square. Colors are tokens
   (rule 5); the nav variant is smaller, riding inside the ring. */
.ctas { margin-top: var(--s6); display: flex; flex-wrap: wrap; gap: var(--s3); }
.btn { font-family: var(--font-body); font-weight: 500; font-size: 15px; padding: 14px 24px; display: inline-block; background: var(--ink); color: var(--alt); border: 1px solid var(--ink); text-decoration: none; line-height: 1; transition: opacity var(--motion-hover) var(--motion-ease-out); }
@media (hover: hover) and (pointer: fine) { .btn:hover { opacity: 0.85; } }

/* press: a button dips while pressed, so a tap feels received before the page answers (KNW_ST_MC_Motion-Patterns.md, press) */
@media (prefers-reduced-motion: no-preference) {
  .btn { transition: opacity var(--motion-hover) var(--motion-ease-out), transform var(--motion-press) var(--motion-ease-out); }
  .btn:active { transform: scale(0.97); }
}
/* cursor: the wordmark's underscore blinks three times as the page opens, then rests, the one living
   detail in the header (KNW_ST_MC_Motion-Patterns.md, cursor) */
@keyframes cursor-blink { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }
@media (prefers-reduced-motion: no-preference) {
  .wordmark .u { animation: cursor-blink 1060ms steps(1) 600ms 3; } /* motion: allow cursor blink period, a terminal caret's rhythm, pacing not a response */
}
.sv[data-motion="count-up"] { font-variant-numeric: tabular-nums; }
/* the ghost button: the quieter second action beside the primary one */
.btn.ghost { background: transparent; color: var(--ink); }
@media (hover: hover) and (pointer: fine) { .btn.ghost:hover { opacity: 1; background: var(--ink); color: var(--alt); } }
/* a person's portrait: a 160px square on the accent ground, above the card's text */
.card .photo { width: 160px; height: 160px; object-fit: cover; display: block; background: var(--accent); margin-bottom: var(--s4); }
/* the nav button: a 44px tap target (Law 8), its type, width and padding unchanged */
nav.ring .steps .btn.nav-cta { padding: 10px 18px; font-size: 14px; color: var(--alt); min-height: 44px; display: inline-flex; align-items: center; }

/* ---- the site shell nav: mobile hamburger (nav.ring.site only) ----
   Desktop shows the links row; under 768 the hamburger takes over.
   Structure only — colors are tokens. */
nav.ring.site .m-menu { display: none; position: relative; }
nav.ring.site .m-menu > summary { list-style: none; cursor: pointer; width: 44px; height: 44px; display: flex; flex-direction: column; justify-content: center; gap: 7px; align-items: stretch; padding: 14px 10px; -webkit-tap-highlight-color: transparent; box-sizing: border-box; }
nav.ring.site .m-menu > summary::-webkit-details-marker { display: none; }
nav.ring.site .m-menu > summary span { display: block; height: 2px; width: 100%; background: var(--ink); transition: transform var(--motion-turn) var(--motion-ease-out), opacity var(--motion-turn) var(--motion-ease-out); }
nav.ring.site .m-menu[open] > summary span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
nav.ring.site .m-menu[open] > summary span:nth-child(2) { opacity: 0; }
nav.ring.site .m-menu[open] > summary span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }
nav.ring.site .m-panel { position: absolute; right: 0; top: calc(100% + 16px); min-width: 220px; background: var(--field); border: 1px solid var(--rule); display: flex; flex-direction: column; z-index: 60; }
nav.ring.site .m-panel a { padding: 16px 24px; color: var(--ink); border-bottom: 1px solid var(--rule); font-size: 15px; text-decoration: none; }
nav.ring.site .m-panel a:last-child { border-bottom: none; color: var(--accent-label, var(--accent)); }
@media (max-width: 767px) {
  nav.ring.site .steps { display: none; }
  nav.ring.site .m-menu { display: block; }
}
/* the site nav from 768px: the wordmark left, the links centred in the space between, the booking
   button right, as a product site sets it (MC, Oct 3, 2026: "crammed to the left", the Gumloop bar) */
@media (min-width: 768px) {
  nav.ring.site .steps { flex: 1; display: flex; align-items: center; gap: var(--s6); }
  nav.ring.site .steps .step:first-child { margin-left: auto; }
  nav.ring.site .steps .nav-cta { margin-left: auto; }
}

/* ---- the site register (body.site) — the marketing surface breathes ----
   One register per surface (Law 5). Wider section air, muted statements,
   air under the heading. The ladder, the faces, and the 16px floor are
   untouched — this register spends space and color, never new sizes. */
body.site section { padding: var(--s8) 0; }
body.site .hero { padding: var(--s8) 0 var(--s7); }
/* hero parent: the page this one belongs under, one quiet line above the label, a full tap target */
/* the parent link is under 24px, so its text is the accent label (ink) and its green is the underline, as a link in prose */
.hero .parent { display: inline-flex; align-items: center; gap: 6px; min-height: 44px; margin: 0 0 var(--s2); font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: .12em; color: var(--accent-label, var(--ink-muted)); text-decoration: underline; text-decoration-color: var(--accent-text, var(--accent)); text-decoration-thickness: 1px; text-underline-offset: 3px; }
@media (hover: hover) and (pointer: fine) { .hero .parent:hover { color: var(--ink); } }
/* the site hero's subtitle is one size: a body line under the statement continues it */
body.site header.hero .body.sub { font-size: 20px; line-height: 1.55; }
/* article register: an untitled opening section continues the standfirst at one paragraph gap */
body.site.article header.hero.cont { padding-bottom: 0; }
body.site.article header.hero.cont + section { padding-top: 0; }
body.site .wrap h2 { margin-bottom: var(--s5); }
body.site .wrap .body { color: var(--ink-muted); }
body.site .agenda { border-top: none; }
body.site .agenda .d-step { padding: var(--s6) 0; }
@media (min-width: 768px) {
  /* --section-pad: a brand that names none keeps --s9 (the preview overlay harperos-v2 takes --s10) */
  body.site section { padding: var(--section-pad, var(--s9)) 0; }
  body.site .hero { padding: var(--s9) 0 var(--s8); }
}
/* the article register keeps its own rhythm on the site: its sections run on at s6, and the
   site's marketing air never reaches a page read straight through (the creative director's
   review, Oct 2, 2026: 272px between an essay's sections) */
body.site.article section { padding: var(--s6) 0; }
body.site.article section:first-of-type { padding-top: var(--s4); }
body.site.article .hero { padding-bottom: var(--s5); }
body.site.article section > .wrap { padding-top: 0; padding-bottom: 0; }
/* a standalone control is a 44px target (Law 8): a card's profile link, the hero's note link */
.cmeta a, .hero .note a { display: inline-flex; align-items: center; min-height: 44px; }

.catlabel { font-family: var(--font-mono); font-size: 12px; font-weight: 500;
  text-transform: uppercase; letter-spacing: .14em; color: var(--accent-label, var(--accent));
  margin: var(--s8) 0 var(--s2); padding-top: var(--s5); border-top: 1px solid var(--rule); }
.catlabel.first { border-top: none; padding-top: 0; margin-top: var(--s7); }
/* a chips label inside a function band names more of the same function, so it takes no
   divider and sits close to what it extends, in the label gray (Law 4: green marks the band) */

/* list block — bullets are body copy (16px), green square marker */
.blist { list-style: none; margin: var(--s4) 0 0; padding: 0;
  display: flex; flex-direction: column; gap: var(--s3); max-width: 62ch; }
.blist li { font-size: 16px; line-height: 1.55; color: var(--ink-muted);
  position: relative; padding-left: var(--s4); }
.blist li::before { content: ''; position: absolute; left: 0; top: 9px;
  width: 5px; height: 5px; background: var(--accent); }
.blist li strong { color: var(--ink); font-weight: 600; }

/* table block — mono 11 header, 16px body, no fills (Tufte) */
.ptable { width: 100%; border-collapse: collapse; margin-top: var(--s5); }
.ptable td { padding: var(--s4); border-bottom: 1px solid var(--rule-soft);
  vertical-align: top; font-size: 16px; line-height: 1.5; color: var(--ink-muted); }
.ptable td.term { font-weight: 600; color: var(--ink); width: 190px; }
/* a description cell: the body of the row, after its name; it takes the cell's own rule and fills
   the width the name and the amount leave (the open item "a table's middle cells", Oct 2, 2026) */
.ptable td.desc { color: var(--ink-muted); }
.ptable td.amt { text-align: right; font-family: var(--font-mono); white-space: nowrap; width: 120px; color: var(--ink); }
.ptable tr.head td { font-family: var(--font-mono); font-size: 11px; text-transform: uppercase;
  letter-spacing: .12em; color: var(--ink-subtle); font-weight: 500;
  border-bottom: 1px solid var(--rule); padding-bottom: var(--s3); }

/* meta block — ONE spelling; the .metagrid above is legacy, kept for unmigrated pages */
.meta-grid { margin-top: var(--s7); display: grid; grid-template-columns: 1fr;
  gap: 2px var(--s4); padding-top: var(--s6); border-top: 1px solid var(--rule); max-width: 760px; }
.meta-grid dt { font-family: var(--font-mono); font-size: 11px; text-transform: uppercase;
  letter-spacing: .14em; color: var(--ink-subtle); padding-top: 3px; }
.meta-grid dd { font-size: 15px; color: var(--ink); margin: 0; }
.meta-grid dd > a { display: inline-flex; align-items: center; min-height: 44px; } /* a standalone link is a 44px target (Law 8) */
.meta-grid dd .name { font-family: var(--font-body); font-size: 16px; font-weight: 600; line-height: 1.3; }
@media (min-width: 768px) { .meta-grid { grid-template-columns: 150px 1fr; gap: var(--s3) var(--s6); } }

/* card block internals — kicker 11 mono (box-label rung), title Inter 600 16 (a name is a point title; Ponomar opens a page or a section only), body 16 */
.card .kick { font-family: var(--font-mono); font-size: 11px; text-transform: uppercase;
  letter-spacing: .12em; color: var(--ink-subtle); margin-bottom: var(--s2); }
.card .nm { font-family: var(--font-body); font-size: 16px; font-weight: 600;
  line-height: 1.3; color: var(--ink); }
/* component copy: 15px muted, the box-text rung */
.card .ln { font-size: 15px; color: var(--ink-muted); margin-top: var(--s2); line-height: 1.5; }
.card ul { list-style: none; margin: var(--s4) 0 0; padding: 0;
  display: flex; flex-direction: column; gap: var(--s2); }
.card li { font-size: 16px; color: var(--ink-muted); position: relative;
  padding-left: var(--s4); line-height: 1.5; }
.card li::before { content: ''; position: absolute; left: 0; top: 9px;
  width: 4px; height: 4px; background: var(--accent); }

/* chip row — inert labels, never controls (Affordance) */
/* logos — the proof strip of client marks: grayscale, quiet, whole rows */
.logos { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--s5) var(--s6); align-items: center; margin-top: var(--s7); padding-top: var(--s6); border-top: 1px solid var(--rule); max-width: var(--measure); }
@media (min-width: 768px){ .logos { grid-template-columns: repeat(4, 1fr); gap: var(--s6) var(--s7); } }
.logos img { height: 30px; width: auto; max-width: min(165px, 100%); object-fit: contain; justify-self: center; filter: grayscale(1); opacity: 0.42; }

/* chips — a bordered mono box. The fill is ALWAYS white (--alt), never the page
   field: a box the same color as the page behind it reads as a hairline outline
   rather than an object, and loses legibility. Ratified by MC 2026-08-14 after
   the same .chip shipped white on every proposal and grey on every delivery
   plan (RC1: one block, two page-local definitions). --alt is element fill;
   --field is the page. A chip is an element. */
.chips { margin-top: var(--s4); display: flex; flex-wrap: wrap; gap: var(--s2); }
.chips .chip, .toolrow .chip, .ecap .chip { font-family: var(--font-mono); font-size: 12px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink);
  border: 1px solid var(--rule); background: var(--alt); padding: var(--s2) var(--s3); }

/* sequence block — numbered steps; step title is a NAME (Law 6), display face 20 */
.agenda { margin-top: var(--s6); border-top: 1px solid var(--rule); }
.agenda .d-step { display: grid; grid-template-columns: auto 1fr; gap: var(--s4);
  padding: var(--s5) 0; border-bottom: 1px solid var(--rule-soft); align-items: baseline; }
.agenda .sn { font-family: var(--font-mono); font-size: 13px; font-weight: 500;
  letter-spacing: .1em; color: var(--accent-label, var(--accent)); }
.agenda .st { font-family: var(--font-display); font-size: 20px; font-weight: 400;
  color: var(--ink); line-height: 1.15; }
.agenda .sd { font-size: 16px; color: var(--ink-muted); margin-top: var(--s2);
  line-height: 1.5; max-width: 62ch; }

/* quote attribution (block layer form) */
.quote .qby { margin-top: var(--s4); font-family: var(--font-mono); font-size: 11px;
  text-transform: uppercase; letter-spacing: .1em; color: var(--ink-subtle); }

/* block layer — card extensions (quote, price, trailing meta line) */
.card .cq { font-size: 16px; line-height: 1.5; color: var(--ink); margin-top: var(--s3); font-style: italic; }
.card .pr { font-family: var(--font-mono); font-size: 22px; color: var(--ink); margin-top: var(--s3); }
.card .pr span { font-size: 13px; color: var(--ink-subtle); }
.card .cmeta { margin-top: var(--s4); padding-top: var(--s3); border-top: 1px solid var(--rule-soft);
  font-family: var(--font-mono); font-size: 11px; text-transform: uppercase;
  letter-spacing: .1em; color: var(--ink-subtle); }
.card .cmeta strong { color: var(--ink); font-weight: 500; text-transform: none; letter-spacing: 0; font-size: 13px; }
.card .pr .was { font-size: 14px; color: var(--ink-subtle); text-decoration: line-through; margin-right: var(--s2); }

/* ============================================================
   THE DERIVED BLOCK LAYER — lifted VERBATIM from the approved
   client pages (the block-library loop, 2026-08-14).
   Source of truth: the computed rendering MC approved. Two laws:
   · Never define --measure — the approved pages reference it
     undefined, so it resolves to nothing; that IS the approved
     rendering (full-width headings, 60ch only on prose).
   · Values here follow the approved-page anchor; MC's five pending
     rulings (R1-R5, calibration SPEC) may adjust them — until
     ruled, the approved page wins.
   Constructs: compare (.vs) · stats · price/boxes (.bx/.tbox/.lvl)
   · caveat · agent cards (.acards/.acard) · agent-spec (.enc/.erail/.tt)
   · panel (.fnb/.fgroup) · prooflist (.plist) · inline steps
   (.howsteps) · report table (.tbl) · sublab · figcap · pull · op
   · the reveal behavior (.seq under .anim, reduced-motion-gated).
   ============================================================ */
.vs, .fnb, .plist, .stats, .trio, .continue, .wrap .grid { max-width: var(--measure); }

.figcap { font-family: var(--font-mono); font-size: 12px; letter-spacing: 0.02em; color: var(--ink-muted); max-width: 60ch; line-height: 1.5; margin-top: var(--s3); }

/* ---- the assessment table (.tbl) — the construct this section's manifest has
   named since 2026-08-14 and never defined. Lifted from the approved Dashlane
   marketing and product assessments (2026-09-29), which carried it in their own
   page styles, so it reached no other surface and no ruling ever swept it.
   Two values move on the way in, and both are MC's ruling of 2026-09-23 that
   every micro label sits on one rung: the column head 10.5px -> 11px and the
   source line 10px -> 11px. Everything else is the approved page verbatim.
   .dl is the subject's column — the one the whole comparison is about. ---- */
.tbl { margin-top: var(--s5); overflow-x: auto; max-width: 100%; -webkit-overflow-scrolling: touch; }

.tbl table { border-collapse: collapse; width: 100%; min-width: 920px; table-layout: fixed; background: var(--alt); border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule); }

.tbl th { text-align: left; font-family: var(--font-mono); font-size: 11px; font-weight: 500; text-transform: uppercase; letter-spacing: 0.07em; color: var(--ink-subtle); border-bottom: 1px solid var(--rule); padding: var(--s3) var(--s4); }

.tbl th.dl { background: var(--accent-soft); color: var(--accent-label, var(--accent)); }

.tbl td { border-bottom: 1px solid var(--rule-soft); padding: var(--s3) var(--s4); vertical-align: top; line-height: 1.5; font-size: 13px; color: var(--ink-muted); overflow-wrap: break-word; }

.tbl td:first-child { font-weight: 600; color: var(--ink); font-size: 13.5px; }

.tbl td.dl { background: color-mix(in srgb, var(--accent-soft) 45%, white); color: var(--ink); }

.tbl.num td { font-family: var(--font-mono); font-size: 12.5px; }

.tbl.num td:first-child { font-family: var(--font-body); font-size: 13.5px; }

.tbl.num td a { white-space: nowrap; }

.tbl td strong { color: var(--ink); font-weight: 600; }

.tbl td strong.vgood { color: var(--accent-text, var(--accent)); font-weight: 600; }

.tbl td .src { display: block; font-family: var(--font-mono); font-size: 11px; font-weight: 400; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ink-subtle); margin-top: 4px; }

.tbl td .cb { display: block; position: relative; padding-left: 12px; }

.tbl td .cb::before { content: ''; position: absolute; left: 0; top: 8px; width: 4px; height: 4px; background: var(--accent); }

.tbl td .cb + .cb { margin-top: 6px; }

/* The verdict glyph (.gl up/dn/op) that leads an assessment's subhead is defined
   in THE PAGE FRAME below; the subhead block emits it. */

.pull, .wrap .quote { max-width: calc(var(--measure) * 0.75); margin: var(--s7) 0; }

/* the pull line: a line set apart in the text face, never the display face (MC, Oct 6, 2026), held to
   a readable measure, with the accent rule that marks it as set apart rather than as a second title */
.pull { font-family: var(--font-body); font-size: 20px; font-weight: 600; line-height: 1.45; color: var(--ink); max-width: 640px; border-left: 2px solid var(--accent); padding-left: var(--s5); }
/* in an article the pull shares its rung with the section title, so it carries the accent rule and
   reads as a line set apart, never as a second heading (the creative director's review, Oct 2, 2026) */
.article .trio.one { max-width: 680px; }  /* a quote in an article holds the text column's measure */

.sublab { font-family: var(--font-mono); font-size: 12px; font-weight: 500; text-transform: uppercase; letter-spacing: 0.1em; color: var(--accent-label, var(--accent)); margin-top: var(--s7); padding-top: var(--s5); border-top: 1px solid var(--rule); }

.sublab + .body, .sublab + .list { margin-top: var(--s3); }

.plist { margin-top: var(--s3); }

.plist .pr { padding: var(--s4) 0; border-bottom: 1px solid var(--rule-soft); }

.plist .pr:last-child { border-bottom: none; }

.plist .pk { font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink); margin-bottom: var(--s2); }

.plist .pq { font-size: 15px; line-height: 1.5; color: var(--ink); }

.plist .pw { display: block; font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink-subtle); margin-top: var(--s2); }

@media (min-width: 768px) {
  .plist .pr { display: grid; grid-template-columns: 180px 1fr; gap: var(--s4); align-items: baseline; }
  .plist .pk { margin-bottom: 0; }
}

.vs { margin-top: var(--s6); }

.vs .vs-head { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s4); padding-bottom: var(--s3); border-bottom: 1px solid var(--rule); }

.vs .vs-head .spacer { display: none; }

.vs .vs-head .h { font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink); line-height: 1.5; }

.vs .vs-head .arr { color: var(--accent-text, var(--accent)); font-size: 14px; line-height: 1; margin-right: var(--s2); display: inline-block; }

.vs .vs-row { padding: var(--s4) 0; border-bottom: 1px solid var(--rule-soft); }

.vs .vs-row:last-child { border-bottom: none; }

.vs .k { font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink); margin-bottom: var(--s2); }

.vs .one, .vs .os-v { font-size: 15px; line-height: 1.5; color: var(--ink-muted); }

.vs .os-v .rar { color: var(--accent-text, var(--accent)); margin-right: var(--s2); display: inline-block; }

.vs .pair { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s4); }

@media (min-width: 768px) {
  .vs .vs-head { grid-template-columns: 180px 1fr 1fr; }
  .vs .vs-head .spacer { display: block; }
  .vs .vs-row { display: grid; grid-template-columns: 180px 1fr 1fr; gap: var(--s4); align-items: baseline; }
  .vs .k { margin-bottom: 0; }
  .vs .pair { display: contents; }
}

.fnb { margin-top: var(--s6); border: 1px solid var(--rule); padding: var(--s5); }

@media (min-width: 768px) {
  .fnb { padding: var(--s6); }
}

.fnb .fk { font-family: var(--font-mono); font-size: 12px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink); }

.fnb .agents { display: flex; flex-wrap: wrap; gap: var(--s2); margin-top: var(--s5); }
/* the NAME chip — a proper noun in a quiet white box (the approved soft chip;
   uppercase mono would lie about what an agent name is). The label chip
   (.chips .chip) stays mono 12. Both fills white, per MC's chip ruling. */
.fnb .agents .chip, .flowv .fagents .chip, .overview-doc .ecap .chip { font-family: var(--font-body); font-size: 15px; text-transform: none; letter-spacing: 0; line-height: 1.35; color: var(--ink); border: 1px solid var(--rule); background: var(--alt); padding: var(--s3) var(--s4); }

.fnb .fgroup { margin-top: var(--s6); padding-top: var(--s5); border-top: 1px solid var(--rule-soft); }

.fnb .fgroup:first-of-type { margin-top: var(--s5); padding-top: 0; border-top: none; }

.fnb .fgroup .gl { font-family: var(--font-mono); font-size: 12px; font-weight: 500; text-transform: uppercase; letter-spacing: 0.1em; color: var(--accent-label, var(--accent)); }

.fnb .fgroup .gl .gn { color: var(--ink-subtle); margin-right: var(--s3); }

.fnb .fgroup .agents { display: grid; grid-template-columns: 1fr; gap: var(--s2); margin-top: var(--s3); }

@media (min-width: 768px) {
  .fnb .fgroup .agents { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
}

.fnb .flands { margin-top: var(--s6); padding-top: var(--s5); border-top: 1px solid var(--rule-soft); }

.fnb .flands .darr { display: block; color: var(--accent-text, var(--accent)); font-size: 16px; line-height: 1; margin-bottom: var(--s4); }

.fnb .flands .lbox { border: 1px solid var(--rule); border-top: 2px solid var(--accent); background: var(--alt); padding: var(--s5); }

.fnb .flands .lbox .ll { font-family: var(--font-mono); font-size: 12px; font-weight: 500; text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink); }

.fnb .flands .lbox .lt { font-size: 15px; line-height: 1.5; color: var(--ink-muted); margin-top: var(--s3); max-width: 60ch; }

.fnb .agents .chip { font-family: var(--font-body); font-size: 15px; text-transform: none; letter-spacing: 0; line-height: 1.35; color: var(--ink); padding: var(--s3) var(--s4); }

.stats { display: grid; grid-template-columns: 1fr; gap: var(--s4); margin-top: var(--s6); }

@media (min-width: 768px) {
  .stats { grid-template-columns: repeat(3, 1fr); }
  .stats.stats2 { grid-template-columns: repeat(2, 1fr); }
}

.stats .st { border-top: 1px solid var(--rule); padding-top: var(--s3); }

.stats .sv { font-family: var(--font-mono); font-size: var(--type-figure); color: var(--ink); line-height: 1.1; font-variant-numeric: tabular-nums; }

.stats .sl { font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink-subtle); margin-top: var(--s2); }

@media (min-width: 768px) {
  .stats4 { grid-template-columns: repeat(4, 1fr); }
}

@media (prefers-reduced-motion: no-preference) {
  .anim .seq > * { opacity: 0; transform: translateY(12px); transition: opacity var(--motion-reveal) var(--motion-ease-out), transform var(--motion-reveal) var(--motion-ease-out); }
  .anim .seq.in > * { opacity: 1; transform: none; }
  .anim .seq > :nth-child(2) { transition-delay: 0.07s; }
  .anim .seq > :nth-child(3) { transition-delay: 0.14s; }
  .anim .seq > :nth-child(n+4) { transition-delay: 0.21s; }
  .anim .seq > .fjoin { transform: scaleY(0); }
  .anim .seq.in > .fjoin { transform: scaleY(1); }
  .anim .seq.pair > :nth-child(2) { transition-delay: 0.21s; }
  .anim .vs.seq .arr { opacity: 0; transform: translateX(-10px); transition: opacity var(--motion-reveal) var(--motion-ease-out) 0.21s, transform var(--motion-reveal) var(--motion-ease-out) 0.21s; }
  .anim .vs.seq.in .arr { opacity: 1; transform: none; }
}

.lvl, .tbox, .acards, .ops, .price, .howsteps, .stack, .continue, .wrap .grid { max-width: var(--measure); }

.caveat { border: 1px solid var(--rule); background: var(--alt); padding: var(--s5); margin-top: var(--s6); max-width: var(--measure); }

@media (min-width: 768px) {
  .caveat { padding: var(--s6); }
}

.caveat .cvk { display: block; font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--accent-label, var(--accent)); }

.caveat .cvt { font-size: 15px; line-height: 1.55; color: var(--ink); margin-top: var(--s3); max-width: 60ch; }

.howsteps { margin-top: var(--s6); max-width: 60ch; }

.hstep { display: grid; grid-template-columns: auto 1fr; gap: var(--s4); padding: var(--s4) 0; align-items: baseline; }

.hstep:first-child { padding-top: 0; }

.hstep + .hstep { border-top: 1px solid var(--rule-soft); }

.hstep .sn { font-family: var(--font-mono); font-size: 12px; color: var(--ink-subtle); }

.hstep .sc { font-size: 15px; line-height: 1.55; color: var(--ink-muted); }

.hstep .sc strong { color: var(--ink); font-weight: 600; }

.lvl, .tbox { display: grid; grid-template-columns: 1fr; gap: var(--s4); margin-top: var(--s6); }

@media (min-width: 768px) {
  .lvl { grid-template-columns: repeat(3, 1fr); }
  .tbox { grid-template-columns: 1fr 1fr; }
}

.bx { border: 1px solid var(--rule); background: var(--alt); padding: var(--s5); }

.sublab + .body { margin-top: var(--s3); }

.bx .bk { font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink); }

.bx .bv { font-size: 15px; line-height: 1.5; color: var(--ink-muted); margin-top: var(--s3); }

.bx .list { margin-top: var(--s4); max-width: none; gap: var(--s2); }

.bx .list li { font-size: 15px; line-height: 1.5; padding-left: var(--s3); }

.bx .list li::before { top: 8px; }

.bx .bp { font-family: var(--font-mono); font-size: 19px; color: var(--ink); margin-top: var(--s3); }

.bx .bp .was { font-size: 14px; color: var(--ink-subtle); text-decoration: line-through; margin-right: var(--s3); }

.bx .bp .per { font-size: 12px; color: var(--ink-muted); margin-left: var(--s2); }
/* a pricing section's lead boxes: the price two steps up, in the same mono face (Oct 8, 2026) */
.tbox.lead .bx .bp { font-size: 24px; }

.acards { display: grid; grid-template-columns: 1fr; gap: var(--s5); margin-top: var(--s6); }

@media (min-width: 768px) {
  .acards { grid-template-columns: 1fr 1fr; }
}

.acard { border: 1px solid var(--rule); background: var(--alt); padding: var(--s5); display: flex; flex-direction: column; }

.acard .ak { font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink-subtle); }

.acard .anm { font-family: var(--font-display); font-size: 20px; line-height: 1.15; color: var(--ink); margin-top: var(--s2); }

.acard .aln { font-size: 15px; line-height: 1.5; color: var(--ink-muted); margin-top: var(--s3); flex: 1; }

.acard .list { margin-top: var(--s3); max-width: none; gap: var(--s2); flex: 1; }

.acard .list li { font-size: 15px; line-height: 1.5; padding-left: var(--s3); }

.acard .list li::before { top: 8px; }

.acard .aown { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.02em; color: var(--ink); margin-top: var(--s4); padding-top: var(--s3); border-top: 1px solid var(--rule-soft); }

.ops { display: grid; grid-template-columns: 1fr; gap: var(--s3); margin-top: var(--s6); }

@media (min-width: 768px) {
  .ops { grid-template-columns: 1fr 1fr; }
}

.op { border: 1px solid var(--rule); background: var(--alt); padding: var(--s4); }

.op .on { font-family: var(--font-mono); font-size: 12px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink); }

.op .ov { font-size: 14px; line-height: 1.5; color: var(--ink-muted); margin-top: var(--s2); }

.price { margin-top: var(--s6); border: 1px solid var(--rule); padding: var(--s5); }

@media (min-width: 768px) {
  .price { padding: var(--s6); }
}

.price .pnum { font-family: var(--font-mono); font-size: var(--type-price); color: var(--accent-text, var(--accent)); line-height: 1.1; }

.price .pnum .per { font-size: 0.45em; color: var(--ink-muted); margin-left: var(--s2); }

.price .plede { font-size: 15px; line-height: 1.5; color: var(--ink); margin-top: var(--s3); }

.price .prow { padding: var(--s4) 0; border-top: 1px solid var(--rule-soft); margin-top: 0; }

.price .prow:first-of-type { margin-top: var(--s6); }

.price .sublab + .prow { margin-top: var(--s5); }

.price .pl { display: block; font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink-subtle); margin-bottom: var(--s2); }

.price .pv { font-size: 15px; line-height: 1.5; color: var(--ink-muted); }

@media (min-width: 768px) {
  .price .prow { display: grid; grid-template-columns: 150px 1fr; gap: var(--s4); align-items: baseline; }
  .price .pl { margin-bottom: 0; }
}

.ptable .pr { padding: var(--s4) 0; border-bottom: 1px solid var(--rule-soft); }
.ptable .pr:last-child { border-bottom: none; }
.enc { border: 1px solid var(--rule); background: var(--alt); padding: var(--s5); margin-top: var(--s5); }
.enc .ek { font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink-subtle); }
.enc .enm { font-family: var(--font-display); font-size: 20px; line-height: 1.15; color: var(--ink); margin-top: var(--s2); }
.enc .egoal { font-size: 15px; line-height: 1.5; color: var(--ink-muted); margin-top: var(--s2); max-width: 60ch; }
.erow .epur { color: var(--ink); font-weight: 600; }
.enc .list { margin-top: var(--s4); max-width: none; gap: var(--s2); }
.enc .list li { font-size: 15px; line-height: 1.5; padding-left: var(--s3); }
.enc .list li::before { top: 8px; }
.erail { margin-top: var(--s5); }
.erow { padding: var(--s4) 0; border-top: 1px solid var(--rule-soft); }
.erow .el { display: block; font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink-subtle); margin-bottom: var(--s2); }
.erow .ev { font-size: 15px; line-height: 1.5; color: var(--ink-muted); }
.tt { display: grid; grid-template-columns: 1fr; gap: var(--s2); }
.tt .half .mk { font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink-subtle); display: block; margin-bottom: 2px; }
.tt .today { font-size: 15px; line-height: 1.5; color: var(--ink-muted); }
.tt .tmrw { font-size: 15px; line-height: 1.5; color: var(--ink); }
.tt .earr { color: var(--accent-text, var(--accent)); font-size: 14px; line-height: 1; }
.tt .earr.h { display: none; }
.ecap { display: flex; flex-wrap: wrap; gap: var(--s2); }
.ecap .chip { background: var(--alt); }
.fnhead { margin-top: var(--s7); padding-top: var(--s5); border-top: 1px solid var(--rule); }
.sublab + .fnhead { margin-top: var(--s5); padding-top: 0; border-top: none; }
.fnhead .fnk { font-family: var(--font-mono); font-size: 12px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--accent-label, var(--accent)); }
.fnhead .fnn { font-family: var(--font-display); font-size: var(--type-step); line-height: 1.15; color: var(--ink); margin-top: var(--s2); }
.fnhead .fnl { font-size: 15px; line-height: 1.5; color: var(--ink-muted); margin-top: var(--s2); max-width: 60ch; }
.fnhead .fnn.withicon { display: flex; align-items: center; gap: var(--s3); }
.fnhead .fnn.withicon .ico { width: 28px; height: 28px; }
/* a function's name inside a chapter: the sub-label's rung, with its icon (Oct 7, 2026) */
.overview-doc h4.sublab.fnsub { align-items: center; }
/* under a function at that rung, its agent cards name the agent one step down, in the body face */
.overview-doc section.chapter:has(h4.fnsub) .enc.rail .enm.withicon { font-family: var(--font-body); font-size: 16px; font-weight: 600; line-height: 24px; letter-spacing: 0; }
/* the purpose reads in the box text's gray, under its name (a child never outweighs its parent) */
.overview-doc section.chapter:has(h4.fnsub) .enc.rail .egoal { font-size: 15px; font-weight: 400; color: var(--ink-muted); }
.overview-doc section.chapter:has(h4.fnsub) .enc.rail .enm.withicon .ico { width: 18px; height: 18px; }
.overview-doc h4.sublab.fnsub .ico { width: 20px; height: 20px; flex: none; }
.overview-doc h4.sublab.fnsub .fnlab { font-weight: 400; color: var(--ink-subtle); }
/* the agent card (Oct 1, 2026): one question a row, label left and answer right, in one
   column; the head is the shared agent icon beside the role, the purpose bold under it; the
   workflow row is the hero, Today muted, an arrow down, Tomorrow in ink on an accent rule;
   one label style throughout; the entities a card names are boxes carrying their icon */
.enc.rail .ehead { padding-bottom: var(--s5); }
.enc.rail .enm.withicon { display: flex; align-items: center; gap: var(--s3); font-family: var(--font-display); font-size: var(--type-card-title); font-weight: 400; line-height: 1.15; color: var(--ink); margin: 0; }
.enc.rail .enm.withicon .ico { width: 26px; height: 26px; flex: none; }
.enc.rail .egoal { font-size: 16px; font-weight: 600; line-height: 1.5; color: var(--ink); max-width: 64ch; margin-top: var(--s3); }
.enc.rail .erail { margin-top: 0; }
.enc.rail .erow .el { color: var(--ink-subtle); }
.enc.rail .eb > .ev { margin: 0; font-size: 15px; line-height: 1.55; color: var(--ink-muted); max-width: 72ch; }
.enc.rail .eb > .list { margin-top: 0; }
.enc.rail .flow { display: grid; gap: var(--s2); }
.enc.rail .flow .mk { display: block; font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink-subtle); margin-bottom: var(--s1); }
/* Today and Tomorrow are symmetrical: the same size, the same ink, the same rule; only the
   rule's color says which is the change */
.enc.rail .flow .was, .enc.rail .flow .now { border-left: 2px solid var(--rule); padding-left: var(--s4); }
.enc.rail .flow .now { border-left-color: var(--accent); }
.enc.rail .flow p { margin: 0; font-size: 15px; line-height: 1.55; color: var(--ink); }
.enc.rail .flow .arw { width: 18px; height: 18px; color: var(--ink-subtle); margin-left: var(--s4); }
.enc.rail .ecap .chip { display: inline-flex; align-items: center; gap: var(--s2); }
/* the light card (Oct 1, 2026): the full card's head alone, set across the row; an approach's
   agents, which a proposal fills in with the rows */
.fx.lightgrid { display: grid; grid-template-columns: 1fr; gap: var(--s4); margin-top: var(--s4); }
@media (min-width: 768px) { .fx.lightgrid { grid-template-columns: repeat(3, minmax(0, 1fr)); } .fx.lightgrid.two { grid-template-columns: repeat(2, minmax(0, 1fr)); } .fx.lightgrid.one { grid-template-columns: 1fr; } }
.enc.light { margin-top: 0; padding: var(--s5); }
.enc.light .enm.withicon, .overview-doc .enc.light .enm.withicon { display: flex; align-items: center; gap: var(--s3); font-family: var(--font-display); font-size: var(--type-agent-name); font-weight: 400; line-height: 1.2; letter-spacing: -0.01em; color: var(--ink); margin: 0; }
.enc.light .enm.withicon .ico { width: 22px; height: 22px; flex: none; }
.enc.light .egoal { font-size: 15px; line-height: 1.55; color: var(--ink-muted); margin-top: var(--s3); }
.enc.rail .ecap .chip .ico { width: 16px; height: 16px; flex: none; color: var(--ink-subtle); }
/* the inline point list: the marker beside the title, the detail under the title */
.pointrow.inline > .point { display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: var(--s3); align-items: center; padding: var(--s4) 0; }
.pointrow.inline > .point > .ico, .pointrow.inline > .point > .nmark { margin-bottom: 0; grid-row: 1; }
.pointrow.inline > .point > :not(.ico):not(.nmark) { grid-column: 2; }
.pointrow.inline .detail { margin-top: var(--s1); }
/* a chapter number in a phase's contents: mono, gray, unboxed, the width of its digits (Oct 7, 2026) */
.nmark.ref { width: auto; height: auto; border: none; color: var(--ink-subtle); letter-spacing: 0.08em; min-width: 4ch; justify-content: flex-start; }
/* a text underline stays under the words; the padding widens the tap target to 44px without
   moving it (a border here sat on the line below) */
.pointrow.inline .phrase a { color: inherit; text-decoration: underline; text-decoration-color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: 4px; display: inline-block; padding: 12px 0; margin: -12px 0; }
@media (hover: hover) and (pointer: fine) { .pointrow.inline .phrase a:hover { text-decoration-color: currentColor; } }
.eown { font-family: var(--font-mono); font-size: 12px; letter-spacing: 0.02em; color: var(--ink); }
.sublab + .body, .sublab + .list, .sublab + .lvl, .sublab + .ecap { margin-top: var(--s3); }
.body + .ecap { margin-top: var(--s4); }
.lvl { display: grid; grid-template-columns: 1fr; gap: var(--s4); margin-top: var(--s6); max-width: var(--measure); }
@media (min-width: 768px) {
  .ptable .pr { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s4); align-items: baseline; }
}
@media (min-width: 768px) {
  .enc { padding: var(--s6); }
}
@media (min-width: 768px) {
  .erow { display: grid; grid-template-columns: 110px 1fr; gap: var(--s4); align-items: baseline; }
  .erow .el { margin-bottom: 0; }
}
@media (min-width: 768px) {
  .tt { grid-template-columns: 1fr auto 1fr; gap: var(--s4); align-items: baseline; }
  .tt .earr.h { display: block; }
  .tt .earr.v { display: none; }
}
@media (min-width: 768px) {
  .lvl { grid-template-columns: repeat(3, 1fr); }
}

/* trio cards, the vertical flow, the logo wall, paired quotes — lifted from an approved client overview */
.trio { display: grid; grid-template-columns: 1fr; gap: var(--s5); margin-top: var(--s6); }
@media (min-width: 768px) {
  .trio { grid-template-columns: repeat(3, 1fr); }
}
.trio .t { background: var(--alt); border: 1px solid var(--rule); padding: var(--s5); display: flex; flex-direction: column; }
.trio .num { font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink-subtle); }
.trio .nm, .card .nm { font-family: var(--font-body); font-size: 16px; font-weight: 600; line-height: 1.3; color: var(--ink); }  /* a name is a point title, in Inter 600: Ponomar opens a page or a section and nothing below (MC, Oct 6, 2026) */
.trio .nm { margin-top: var(--s3); }
.trio .ln, .card .ln { font-size: 15px; line-height: 1.5; color: var(--ink-muted); margin-top: var(--s3); }
.trio .ln { flex: 1; }
.trio .tag { font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--accent-label, var(--accent)); margin-top: var(--s5); padding-top: var(--s4); border-top: 1px solid var(--rule-soft); }
.flowv { margin-top: var(--s6); max-width: 640px; }
.flowv .fnode { border: 1px solid var(--rule); padding: var(--s3) var(--s4); font-size: 15px; line-height: 1.5; color: var(--ink-muted); }
.flowv .fnode .fk { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-subtle); margin-bottom: var(--s1); }
.flowv .fjoin { width: 1px; height: var(--s5); background: var(--rule); margin-left: var(--s5); transform-origin: top; }
.flowv .fagents { display: flex; flex-wrap: wrap; gap: var(--s2); margin-top: var(--s2); }
.logowall { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--s5) var(--s6); align-items: center; margin-top: var(--s7); padding-top: var(--s6); border-top: 1px solid var(--rule); max-width: var(--measure); }
@media (min-width: 768px) {
  .logowall { grid-template-columns: repeat(4, 1fr); gap: var(--s6) var(--s7); }
}
.logowall img { height: 30px; width: auto; max-width: 165px; object-fit: contain; justify-self: center; filter: grayscale(1); opacity: 0.42; }
.qpair { display: grid; grid-template-columns: 1fr; gap: var(--s4); margin-top: var(--s7); max-width: var(--measure); }
@media (min-width: 768px) {
  .qpair { grid-template-columns: 1fr 1fr; gap: var(--s5); }
}
.qpair .quote { margin: 0; max-width: none; }

/* the pillar marker + the tool row — lifted from an approved client proposal */
.eyebrow.pillar { margin: 0 0 var(--s5); }
.eyebrow.pillar .pn, .eyebrow.pillar .pd { color: inherit; font-weight: inherit; }
.toolrow { display: flex; flex-wrap: wrap; gap: var(--s2); margin-top: var(--s5); }
.fx { margin-top: var(--s2); }

/* the report register's small constructs — lifted from an approved client intelligence report */
.heromnu { font-family: var(--font-mono); font-size: 12px; letter-spacing: 0.04em; color: var(--ink-subtle); margin-top: var(--s5); }
.sev { font-family: var(--font-mono); font-size: 11px; font-weight: 500; text-transform: uppercase; letter-spacing: 0.12em; color: var(--accent-label, var(--accent)); margin: var(--s7) 0 var(--s2); }
.sev.med { color: var(--ink-subtle); }
.gl { display: inline-block; margin-right: 8px; }
.gl.up { color: var(--accent-text, var(--accent)); }
.gl.dn { color: var(--ink-muted); }
.gl.op { color: var(--ink-subtle); }
h3 + .blist, h3 + .tscroll, h3 + .tbl { margin-top: var(--s3); }

/* ---- THE PAGE FRAME — the top half of every approved page's local styles,
   lifted after the creative director's cold read caught the gap. The dead
   --measure stays undefined by law: these max-widths resolve to none, which
   IS the approved rendering (full-wrap headings); the shell's older 18ch
   hero cap is overridden back to the approved full measure. ---- */
.wrap h1, .wrap .ts-h1, .wrap h2, .wrap h3 { max-width: var(--measure); }
.hero h1 { max-width: none; }
.wrap .body { max-width: var(--measure); }
.wrap .body ~ .body { max-width: 60ch; font-size: 16px; line-height: 1.55; }
/* a paragraph under a sub-label is running text, never the section's subhead, even when it is
   the section's first paragraph (What we stand for's first conviction, Oct 2, 2026) */
.wrap .sublab + .body { max-width: 60ch; font-size: 16px; line-height: 1.55; }
.article .wrap .sublab + .body { font-size: 16px; line-height: 1.7; }
section > .wrap { padding-top: var(--s4); padding-bottom: var(--s4); }
.wrap > :last-child { margin-bottom: 0; }
@media (min-width: 768px) {
  section > .wrap { padding-top: var(--s6); padding-bottom: var(--s6); }
  .hero > .wrap { padding-top: var(--s6); padding-bottom: 0; }
}
/* the report register's subsection rhythm + wide data lists (approved intel page) */
h3 { margin-top: var(--s6); }
h3 + .blist, h3 + .tscroll, h3 + .tbl { margin-top: var(--s3); }
.dense .blist { max-width: 70ch; }

/* The sub-subhead (.h4) — one rung under a subhead, inside an assessment's source
   list. Not the mono h4 metadata label above; this one is a heading. Lifted from
   the approved Dashlane product assessment, 2026-09-29. */
h4.h4 { font-family: var(--font-body); font-size: 15px; font-weight: 600; text-transform: none; letter-spacing: normal; color: var(--ink); margin-top: var(--s6); }
h4.h4 + .blist { margin-top: var(--s3); }

/* ---- the embed scope (.em) — the container every embed is wrapped in, named in
   the block canon since 2026-08-14 and never given a rule, because no LIVE page
   carried an embed until Dashlane graduated (2026-09-29) and page-integrity reads
   public/clients only. It holds no look: each embed owns its own rhythm. It holds
   the one thing a container owes the page, which is not to widen it. ---- */
.em { display: block; max-width: 100%; }

/* ============================================================
   THE POINT LAYER — the icon, point, logo-panel and workflow
   constructs first built on /overview-a (2026-09-16/17), merged
   into the block canon when MC approved
   SPEC_2026-09-17_BR_MC_Design-System-Landing.md.

   Manual: KNW_ST_MC_Block-Library.md. Every class below is an
   atom, a block or a view named there, and each one is rendered
   on the specimen at /design-system/blocks.

   Additive by construction. Every base class here had zero uses
   on any page when it was added (measured over 383 files), and a
   modifier only ever appears compounded with one of them, so no
   page already published can change.

   Icons are drawn from content/brand/icons.mjs, one drawing per
   concept; the stroke rides on the SVG as currentColor, so the
   color is the token set here.
   ============================================================ */

/* atom · icon — the 24px line drawing, in ink */
.ico { display: block; width: 24px; height: 24px; flex: none; color: var(--ink); }

/* atom · number — a numeral in the icon's place, size and line (S3: every
   numeral is JetBrains Mono) */
.nmark { display: inline-flex; align-items: center; justify-content: center; flex: none; box-sizing: border-box; width: 24px; height: 24px; border: 1.5px solid var(--ink); font-family: var(--font-mono); font-size: 12px; font-weight: 500; line-height: 1; color: var(--ink); }

/* atom · arrow — the one direction mark in a diagram: the icon line and an
   open head, ink-muted. It points right; the modifier turns it. */
.arw { display: block; width: 24px; height: 24px; flex: none; color: var(--ink-muted); transform-origin: 50% 50%; }
.arw.down { transform: rotate(90deg); }
.arw.up { transform: rotate(-90deg); }

/* atom · phrase — the bold lead of a point: the body's size and color,
   weight 600 carries the rank (MC 2026-09-16) */
.phrase { margin: 0; font-size: 16px; line-height: 1.55; font-weight: 600; color: var(--ink-muted); }

/* atom · card head — the marker and the box title on one line (S2). A box
   title is a point title in a box: Inter 600 at 16, gray, four words or fewer
   (MC 2026-09-17: one treatment for a named thing beside its marker, boxed or
   not; Ponomar stays with the headlines). Its 24px line box matches the
   marker, so a title that wraps keeps its marker on the first line. */
.cardhead { display: flex; align-items: flex-start; gap: var(--s3); }
.cardhead .nm { margin: 0; font-family: var(--font-body); font-size: 16px; font-weight: 600; line-height: 24px; color: var(--ink-muted); }

/* atom · white box for a visual — a diagram, a panel or a product view
   always sits in one */
.figbox { background: var(--alt); border: 1px solid var(--rule); padding: var(--s5); margin-top: var(--s6); }
@media (min-width: 768px) { .figbox { padding: var(--s6); } }

/* ---- block · point row ----
   Two or three points side by side, no box, divided by a hairline. A point
   is its marker (an icon, or a number where the order is the content), the
   phrase, then its text 8px below. Stacked on a phone; .stack keeps it
   stacked at every width (the text side of a split). */
.pointrow { display: grid; grid-template-columns: 1fr; margin-top: var(--s6); }
.pointrow > .point { padding: var(--s5) 0; }
.pointrow > .point:first-child { padding-top: 0; }
.pointrow > .point:last-child { padding-bottom: 0; }
.pointrow > .point + .point { border-top: 1px solid var(--rule-soft); }
.pointrow > .point > .ico, .pointrow > .point > .nmark { margin-bottom: var(--s4); }
.pointrow .detail { margin: var(--s2) 0 0; font-size: 16px; line-height: 1.55; color: var(--ink-muted); }
@media (min-width: 768px) {
  .pointrow:not(.stack) { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .pointrow.two:not(.stack) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pointrow:not(.stack) > .point { padding: 0 var(--s5); }
  .pointrow:not(.stack) > .point:first-child { padding-left: 0; }
  .pointrow:not(.stack) > .point:last-child { padding-right: 0; }
  .pointrow:not(.stack) > .point + .point { border-top: none; border-left: 1px solid var(--rule); }
}

/* ---- block · card grid, the point views ----
   The approved trio (.trio .t) with the card head in place of the kicker
   and name. Views: parts (a mono tag at the foot, S4), compare (From and
   To), quote, function (the agents it holds). .two and .one set the count;
   six cards take two whole rows (Law 3). Card copy is the 15px rung. */
@media (min-width: 768px) {
  .trio.two { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .trio.two.fill > :last-child { grid-column: 1 / -1; }
  .trio.two.fill.lead > :first-child { grid-row: span 2; }
  .trio.two.fill.lead > :last-child { grid-column: auto; }
  .trio.one { grid-template-columns: minmax(0, 1fr); }
}
.trio .cardhead + .ln, .trio .cardhead + .fromto, .trio .cardhead + .rolelist { margin-top: var(--s3); }

/* view · compare — both halves in the component copy and one label style
   (MC 2026-09-16: one From, one To, no second color) */
.fromto { display: grid; grid-template-columns: 44px minmax(0, 1fr); gap: var(--s2); align-items: baseline; }
.fromto .frk { font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink-subtle); }
.fromto .frv { font-size: 15px; line-height: 1.5; color: var(--ink-muted); }

/* view · function — the card head names the function; a quiet list names
   the agents it holds (the approved .acard list, at the same rung) */
.rolelist { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--s2); }
.rolelist li { font-size: 15px; line-height: 1.5; color: var(--ink-muted); position: relative; padding-left: var(--s3); }
.rolelist li::before { content: ''; position: absolute; left: 0; top: 8px; width: 4px; height: 4px; background: var(--accent); }
/* a function card may say what the agents would do before naming them: the line takes the card's spare height, the list sits under it */
.trio .ln + .rolelist { margin-top: var(--s4); }
/* the agents of a function card, as equal cells (MC, Oct 2, 2026: "have every box the same
   size", "a better thing than a box"): no box and no fill, a soft rule between the agents. A
   narrow card stacks them as equal rows, icon beside the name; a card wide enough sets them as
   equal columns, icon above the name, so three agents are three cells the same width. On a page
   with agent cards each is a link to its card, marked by an arrow on hover. */
.trio .t:has(> .rolelist.boxes) { container-type: inline-size; }
.rolelist.boxes { gap: 0; border-top: 1px solid var(--rule-soft); }
/* the agents sit right under the card's line, never pinned to the card's foot */
.trio .t:has(> .rolelist.boxes) > .ln { flex-grow: 0; }
.rolelist.boxes li { padding-left: 0; }
.rolelist.boxes li::before { content: none; }
.rolelist.boxes li + li { border-top: 1px solid var(--rule-soft); }
.rolelist.boxes a, .rolelist.boxes .bxi { position: relative; display: flex; align-items: center; gap: var(--s2); min-height: 44px; box-sizing: border-box; padding: var(--s3) var(--s5) var(--s3) 0; font-family: var(--font-body); font-size: 15px; line-height: 1.35; color: var(--ink); text-decoration: none; }
.rolelist.boxes a .ico, .rolelist.boxes .bxi .ico { width: 16px; height: 16px; flex: none; color: var(--ink-subtle); }
.rolelist.boxes a::after { content: "\2192"; position: absolute; right: 0; top: 50%; transform: translateY(-50%); font-family: var(--font-mono); color: var(--accent-text, var(--accent)); opacity: 0; transition: opacity var(--motion-turn) var(--motion-ease-out); }
@media (hover: hover) and (pointer: fine) { .rolelist.boxes a:hover { color: var(--accent-text, var(--accent)); } }
@media (hover: hover) and (pointer: fine) { .rolelist.boxes a:hover::after, .rolelist.boxes a:focus-visible::after { opacity: 1; } }
/* agents that carry their purpose: each agent is a full row,
   its name over the line that says what it does, stacked at every width (Oct 7, 2026) */
.rolelist.boxes.rich a, .rolelist.boxes.rich .bxi { align-items: flex-start; padding-top: var(--s4); padding-bottom: var(--s4); }
.rolelist.boxes.rich .ico { margin-top: 3px; }
.rolelist.boxes.rich .bt { display: flex; flex-direction: column; gap: 4px; }
.rolelist.boxes.rich .bn { font-weight: 500; color: var(--ink); }
.rolelist.boxes.rich .bp { font-size: 14px; line-height: 1.45; color: var(--ink-muted); }
@container (min-width: 420px) {
  .rolelist.boxes:not(.rich) { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; }
  .rolelist.boxes:not(.rich) li + li { border-top: none; border-left: 1px solid var(--rule-soft); }
  .rolelist.boxes:not(.rich) a, .rolelist.boxes:not(.rich) .bxi { flex-direction: column; align-items: flex-start; height: 100%; padding: var(--s4) var(--s5) var(--s4) var(--s4); }
  .rolelist.boxes:not(.rich) li:first-child a, .rolelist.boxes:not(.rich) li:first-child .bxi { padding-left: 0; }
  .rolelist.boxes a::after { top: var(--s4); right: var(--s3); transform: none; }
}
/* a stacked scope (one function a row, full width): the agents that carry their purpose sit
   two across, so four agents read as one even block instead of a long list (Oct 14, 2026) */
@container (min-width: 760px) {
  .trio.one .rolelist.boxes.rich { display: grid; grid-template-columns: 1fr 1fr; column-gap: var(--s5); }
  .trio.one .rolelist.boxes.rich li + li { border-top: none; }
  .trio.one .rolelist.boxes.rich li:nth-child(n+3) { border-top: 1px solid var(--rule-soft); }
}

/* view · quote — someone else's words: the quote icon, the words at 18px in
   ink, the speaker on the mono label rung. The weight is the box and its
   place on the page, never the size (S7). */
.trio .said { margin: var(--s4) 0 0; font-size: 16px; line-height: 1.55; color: var(--ink); flex: 1; }
.trio .said + .saidby { margin: var(--s4) 0 0; font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.1em; line-height: 1.5; color: var(--ink-subtle); }
/* titled quote: the speaker's role and company lead the card in Inter, the step-title rung (a
   person's role is content, never a mono label); the name sits by the photo and the company's
   logo closes the line, grayscale as in the client strip (Oct 24, 2026) */
.trio .t.titled .qrole { margin: 0; font-family: var(--font-body); font-size: 15px; font-weight: 600; line-height: 22px; color: var(--ink); }
.trio .t.titled .said { margin-top: var(--s3); }
.trio .t.titled .saidby { align-items: center; }
.trio .t.titled .qname { flex: 1; min-width: 0; }
.trio .t.titled .qlogo { flex: none; height: 22px; width: auto; max-width: 110px; object-fit: contain; filter: grayscale(1); opacity: .6; }
.trio .t.titled .qhead { margin: var(--s3) 0 0; font-family: var(--font-body); font-size: 18px; font-weight: 600; line-height: 1.4; letter-spacing: -0.005em; color: var(--ink); }
/* headed: who is speaking leads (photo, name over role, logo at the right), then the headline and the
   rest, in founderos.com's order (Oct 24, 2026) */
.trio .t.titled.headed .qwho { display: flex; align-items: center; gap: var(--s3); }
.trio .t.titled.headed .qwho { gap: var(--s4); }
.trio .t.titled.headed .qwho .avatar { width: 64px; height: 64px; object-fit: cover; display: block; flex: none; }
.trio .t.titled.headed .qid { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.trio .t.titled.headed .qname { font-family: var(--font-body); font-size: 15px; font-weight: 600; line-height: 22px; color: var(--ink); }
.trio .t.titled.headed .qrole { margin: 0; font-weight: 400; font-family: var(--font-mono); font-size: 12px; line-height: 18px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--ink-muted); }
.trio .t.titled.headed .qhead { margin-top: var(--s4); }
/* on a phone the role line already names the company, so the logo gives it the room; it returns
   from the tablet up */
.trio .t.titled.headed .qlogo { display: none; }
@media (min-width: 768px) { .trio .t.titled.headed .qlogo { display: block; } }
.trio .t.titled.headed .said { color: var(--ink-muted); }
.trio .t.titled .qlogo.sm { height: 17px; }
.trio .t.titled .qlogo.lg { height: 32px; }

/* ---- the testimonial blocks on Framer's components (Framer parity, round one, Oct 25, 2026) ----
   testimonial-slideshow (Framer's Slideshow, manual), portrait-row (Framer's Carousel) and featured-quote
   (Testimonial Tabs, one panel). Their motion is the slideshow and carousel patterns in motion.js
   (KNW_ST_MC_Motion-Patterns.md); every value here reads a token. */

/* a portrait cropped by the face: the frame sets its own size, the renderer writes the crop as percentages of it
   (--fh the photo's height, --ft its top, --fl its left), so every face sits on one eye line at one head size */
.fcrop { position: relative; display: block; overflow: hidden; flex: none; background: var(--field); }
.fcrop img { position: absolute; max-width: none; width: auto; height: var(--fh, 100%); top: var(--ft, 0); left: var(--fl, 0); }

/* testimonial slideshow. With no script the track is a row the reader scrolls; once the slideshow pattern starts
   it sets data-on, the view clips, and the track moves by --i slides over --motion-layout on the layout curve */
.tss { position: relative; margin-top: var(--s6); }
.tss-view { overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none; }
.tss-view::-webkit-scrollbar { display: none; }
.tss-track { display: flex; align-items: stretch; }
.tss-slide { flex: 0 0 100%; margin: 0; scroll-snap-align: start; display: flex; flex-direction: column; justify-content: center; gap: var(--s5); padding: 0 var(--s1); min-width: 0; }
.tss[data-on] .tss-view { overflow: hidden; overflow: clip; scroll-snap-type: none; touch-action: pan-y; }
/* clip, not hidden, once the script runs: an overflow-hidden box is still a scroll box, and iOS Safari scrolled it
   under a swipe, so a slide landed offset by the scroll and its text was cut at the screen edge (MC's iPhone,
   Oct 25, 2026); a clipped box cannot scroll, and the script also returns any stray scroll to zero */
.tss[data-on] .tss-track { transform: translateX(calc(var(--i, 0) * -100% + var(--dx, 0px))); transition: transform var(--motion-layout) var(--motion-ease-layout); }
.tss[data-on] .tss-track.drag { transition: none; }
.tss-q { margin: 0; padding: 0; border: 0; }
/* the headline is a pull line, so it is the text face (Law 1), on the step rung; the rest of the quote under it */
.tss-head { margin: 0; font-family: var(--font-body); font-size: var(--type-step); font-weight: 500; line-height: 1.3; letter-spacing: -0.01em; color: var(--ink); text-wrap: balance; }
.tss-rest { margin: var(--s4) 0 0; font-size: 16px; line-height: 1.6; color: var(--ink-muted); }
.tss-who { display: flex; align-items: center; gap: var(--s4); }
.tss-ph { width: 56px; height: 56px; }
.tss-id { display: flex; flex-direction: column; min-width: 0; text-align: left; }
.tss-nm { font-size: 15px; font-weight: 600; line-height: 22px; color: var(--ink); }
.tss-rl { font-family: var(--font-mono); font-size: 12px; line-height: 18px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--ink-muted); }
/* the logo names the company a second time, so on a phone the role line carries it and the logo gives way */
.tss-lg { display: none; flex: none; height: 20px; width: auto; max-width: 96px; object-fit: contain; filter: grayscale(1); opacity: .6; }
.tss-lg.sm { height: 15px; }
.tss-lg.lg { height: 28px; }
/* the controls: Previous, a dot per quote, Next, in one row under the quote; each a 44px target */
.tss-ctl { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: var(--s2) 0; margin-top: var(--s5); }
.tss-ctl[hidden] { display: none; }
.tss-dots { display: flex; }
.tss-dot { all: unset; box-sizing: border-box; cursor: pointer; width: 44px; height: 44px; display: flex; align-items: center; justify-content: center; }
.tss-dot::before { content: ""; width: 8px; height: 8px; background: var(--rule); transition: background-color var(--motion-hover) var(--motion-ease-out), width var(--motion-turn) var(--motion-ease-out); }
.tss-dot[aria-current="true"]::before { width: 20px; background: var(--ink); }
.tss-arrow { all: unset; flex: none; box-sizing: border-box; cursor: pointer; width: 44px; height: 44px; display: flex; align-items: center; justify-content: center; border: 1px solid var(--rule); color: var(--ink); background: var(--field); transition: border-color var(--motion-hover) var(--motion-ease-out); }
.tss-arrow .ico { width: 18px; height: 18px; }
.tss-arrow.prev .ico { transform: scaleX(-1); }
.tss-dot:focus-visible, .tss-arrow:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (hover: hover) and (pointer: fine) { .tss-arrow:hover { border-color: var(--ink-muted); } .tss-dot:hover::before { background: var(--ink-muted); } .tss-dot[aria-current="true"]:hover::before { background: var(--ink); } }
/* centered: Framer's SaaS Kit quote, the words and the person on one axis */
/* on a phone a six-line quote reads better from a straight left edge, so the axis starts at the tablet */
.tss.tss-centered .tss-q { max-width: 760px; }
/* boxed: the same slideshow set apart in a panel on the alternate field */
/* the logo view (Oct 25, 2026): the dots become the companies' logos, one optical size (the logo's own sm or lg
   height), the shown one in ink and the rest a light gray; the logo beside the name steps aside, since the row
   already names every company. Two rows of three on a phone, one row from 768px. */
.tss.tss-logos .tss-lg { display: none; }
/* the headline on the subsection rung, under the section's heading and never over it */
.tss.tss-logos .tss-head { font-size: var(--type-subsection); line-height: 1.3; }
/* each logo control carries the speaker's first name under it, in the label face: two quotes from one company
   (Advanced DRI's CEO and CFO) read as two people, and the six controls stay alike */
.tss-ldot { display: grid; grid-template-rows: 28px auto; align-items: center; justify-content: start; justify-items: start; row-gap: var(--s1); padding-top: var(--s2); padding-bottom: var(--s2); height: auto; min-height: 44px; }
.tss-dnm { font-family: var(--font-mono); font-size: 11px; line-height: 14px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-subtle); transition: color var(--motion-hover) var(--motion-ease-out); }
.tss-ldot[aria-current="true"] .tss-dnm { color: var(--ink); }
/* a step slides, like a carousel: the track moves one quote across over --motion-layout, so a reader scrolling past
   sees the quotes moving and stops on one (MC, Oct 26, 2026: "the move is what makes you stop it to read") */
/* the shown company's mark is underlined by one hairline bar that glides from logo to logo */
.tss.tss-logos .tss-dots { position: relative; }
.tss-bar { position: absolute; left: 0; top: 0; height: 2px; width: var(--bw, 0px); background: var(--ink); transform: translate(var(--bx, 0px), var(--by, 0px)); transition: transform var(--motion-layout) var(--motion-ease-layout), width var(--motion-layout) var(--motion-ease-layout); pointer-events: none; }
/* the controls answer the hand: arrows rest quiet and sharpen on hover or focus, and every control dips as it is pressed */
.tss.tss-logos .tss-arrow { color: var(--ink-muted); transition: border-color var(--motion-hover) var(--motion-ease-out), color var(--motion-hover) var(--motion-ease-out), transform var(--motion-press) var(--motion-ease-out); }
.tss.tss-logos .tss-arrow:focus-visible { color: var(--ink); border-color: var(--ink-muted); }
.tss.tss-logos .tss-arrow:active, .tss.tss-logos .tss-ldot:active { transform: scale(0.96); }
.tss.tss-logos .tss-ldot { transition: transform var(--motion-press) var(--motion-ease-out); }
@media (hover: hover) and (pointer: fine) { .tss.tss-logos .tss-arrow:hover { color: var(--ink); } }
/* autoplay: the bar is a track in the rule color and its fill, set by the script, runs left to right as the timer;
   with autoplay off or stopped the fill is full. The Pause button sits with the arrows and swaps its icon. */
.tss[data-autoplay] .tss-bar { background: var(--rule); }
.tss-bar > i { display: block; height: 100%; background: var(--ink); transform-origin: left center; }
.tss-play { all: unset; flex: none; box-sizing: border-box; cursor: pointer; width: 44px; height: 44px; display: flex; align-items: center; justify-content: center; border: 1px solid var(--rule); color: var(--ink-muted); background: var(--field); margin-left: var(--s2); transition: border-color var(--motion-hover) var(--motion-ease-out), color var(--motion-hover) var(--motion-ease-out), transform var(--motion-press) var(--motion-ease-out); }
.tss-play[hidden] { display: none; }
.tss-play .ico { width: 16px; height: 16px; }
.tss-play .ico + .ico, .tss:not([data-running]) .tss-play .ico:first-child { display: none; }
.tss:not([data-running]) .tss-play .ico + .ico { display: block; }
.tss-play:active { transform: scale(0.96); }
.tss-play:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; color: var(--ink); }
@media (hover: hover) and (pointer: fine) { .tss-play:hover { color: var(--ink); border-color: var(--ink-muted); } }
/* the logos view reads left-aligned on the section's text column at every width, like everything else on the page:
   the quote, the person, then the logo controls with the arrows and Pause directly after them (MC, Oct 26, 2026) */
.tss.tss-logos .tss-q { max-width: 62ch; }
.tss.tss-logos .tss-ctl { justify-content: flex-start; }
.tss.tss-logos .tss-arrow.prev { order: 1; }
.tss.tss-logos .tss-arrow.next { order: 2; margin-left: var(--s2); }
.tss.tss-logos .tss-play { order: 3; }
/* each control is a fixed cell, start-aligned on the text column: the logo, its first name, then room for the bar
   under the name, with a clear gap before the next row, so the bar never touches the row below (MC's iPhone, Oct 26) */
.tss.tss-logos .tss-dots { flex-basis: 100%; order: -1; flex-wrap: wrap; justify-content: flex-start; row-gap: var(--s5); max-width: 420px; margin: 0 0 var(--s4); }
.tss.tss-logos .tss-ldot { width: 33.33%; min-width: 44px; padding: 0 var(--s2) var(--s3) 0; }
.tss.tss-logos .tss-ldot::before { display: none; }
.tss-dlg { display: block; height: 20px; width: auto; max-width: 88px; object-fit: contain; filter: grayscale(1); opacity: .35; transition: opacity var(--motion-hover) var(--motion-ease-out); }
.tss-dlg.sm { height: 15px; }
.tss-dlg.lg { height: 28px; }
.tss-ldot[aria-current="true"] .tss-dlg { filter: grayscale(1) brightness(0); opacity: 1; }
@media (hover: hover) and (pointer: fine) { .tss-ldot:hover .tss-dlg { opacity: .7; } .tss-ldot[aria-current="true"]:hover .tss-dlg { opacity: 1; } }
.tss.tss-boxed { border: 1px solid var(--rule); background: var(--alt); padding: var(--s6) var(--s5) var(--s5); }
.tss.tss-boxed .tss-arrow { background: var(--alt); }
/* inside the panel a phone has no room for eight 44px targets on one line, so the dots take the first and the
   arrows sit together under them */
.tss.tss-boxed .tss-dots { order: -1; flex-basis: 100%; justify-content: center; }
.tss.tss-boxed .tss-arrow.next { margin-left: var(--s2); }
@media (min-width: 768px) {
  .tss-lg { display: block; margin-left: var(--s4); }
  .tss.tss-centered .tss-slide { align-items: center; text-align: center; }
  .tss.tss-boxed { padding: var(--s7) var(--s7) var(--s5); }
  .tss.tss-boxed .tss-dots { order: 0; flex-basis: auto; }
}
/* from 1024px the arrows leave the row for the two sides of the quote, as Framer's Slideshow sets them */
@media (min-width: 1024px) {
  .tss.tss-centered .tss-slide { padding: 0 var(--s9); }
  .tss.tss-logos .tss-dots { max-width: none; flex-basis: auto; flex-wrap: nowrap; gap: var(--s4); margin: 0 var(--s4) 0 0; order: 0; }
  .tss.tss-logos .tss-ldot { width: auto; }
  .tss.tss-centered .tss-arrow { position: absolute; top: calc(50% - 44px - var(--s5) / 2); }
  .tss.tss-centered .tss-arrow.prev { left: 0; }
  .tss.tss-centered .tss-arrow.next { right: 0; }
  .tss.tss-boxed .tss-ctl { justify-content: flex-end; gap: var(--s2); }
  .tss.tss-boxed .tss-dots { margin-right: auto; }
  .tss.tss-boxed .tss-arrow.prev { order: 1; }
  .tss.tss-boxed .tss-arrow.next { order: 2; }
}

/* portrait row: a native scroll-snap row of cards, each 272px wide at most, so a phone shows one card and the edge
   of the next and a desktop shows four; the carousel pattern steps it a card at a time from the arrows */
.prow { margin-top: var(--s6); }
.prow-track { display: flex; gap: var(--s4); margin: 0; padding: 0 0 var(--s2); list-style: none; overflow-x: auto; scroll-snap-type: x mandatory; overscroll-behavior-x: contain; scrollbar-width: none; }
.prow-track::-webkit-scrollbar { display: none; }
.prow-track:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }
.prow-card { flex: 0 0 min(78vw, 272px); scroll-snap-align: start; display: flex; }
.prow-card figure { margin: 0; overflow: hidden; display: flex; flex-direction: column; width: 100%; border: 1px solid var(--rule); background: var(--alt); }
.prow-ph { width: 100%; aspect-ratio: 4 / 5; }
.prow-txt { display: flex; flex-direction: column; flex: 1; gap: var(--s3); padding: var(--s4); }
/* every logo sits in one 26px band, so the headlines start on one line whatever the mark's height */
.prow-lgw { display: flex; align-items: center; height: 26px; }
.prow-lg { display: block; height: 18px; width: auto; max-width: 96px; object-fit: contain; object-position: left center; filter: grayscale(1); opacity: .6; }
.prow-lg.sm { height: 14px; }
.prow-lg.lg { height: 26px; }
/* the quote view sets the person's line under their words; the people view closes up, with no line to hold */
.prow.prow-quote .prow-txt { gap: var(--s3); }
.prow.prow-people .prow-txt { gap: var(--s2); }
.prow-q { margin: 0; padding: 0; border: 0; font-size: 17px; font-weight: 600; line-height: 1.4; letter-spacing: -0.005em; color: var(--ink); }
.prow-id { display: flex; flex-direction: column; margin-top: auto; padding-top: var(--s2); }
.prow-nm { font-size: 15px; font-weight: 600; line-height: 22px; color: var(--ink); }
.prow-rl { font-family: var(--font-mono); font-size: 12px; line-height: 18px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--ink-muted); }
.prow-ctl { display: flex; justify-content: flex-end; gap: var(--s2); margin-top: var(--s4); }
.prow-ctl[hidden] { display: none; }
.prow-arrow { all: unset; box-sizing: border-box; cursor: pointer; width: 44px; height: 44px; display: flex; align-items: center; justify-content: center; border: 1px solid var(--rule); color: var(--ink); transition: border-color var(--motion-hover) var(--motion-ease-out), opacity var(--motion-hover) var(--motion-ease-out); }
.prow-arrow .ico { width: 18px; height: 18px; }
.prow-arrow.prev .ico { transform: scaleX(-1); }
.prow-arrow[aria-disabled="true"] { opacity: .4; cursor: default; }
.prow-arrow:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (hover: hover) and (pointer: fine) { .prow-arrow:not([aria-disabled="true"]):hover { border-color: var(--ink-muted); } }
@media (min-width: 768px) { .prow-track { gap: var(--s5); } }

/* featured quote: one quote given a panel, Testimonial Tabs' layout. On a phone the logo, the quote, the person (a
   64px photo beside the name) and the figures stack; from 1024px the photo stands beside the quote as a 360px square,
   with the figures under it. One photo element moves between the two places, so it is downloaded once */
figure.fq { margin: var(--s6) 0 0; border: 1px solid var(--rule); background: var(--alt); padding: var(--s5); display: grid; grid-template-columns: 64px minmax(0, 1fr); grid-template-areas: "lg lg" "q q" "ph id"; column-gap: var(--s4); row-gap: var(--s5); align-items: center; }
/* the figures view adds a row for its one or two figures under the person */
figure.fq.fq-figures { grid-template-areas: "lg lg" "q q" "ph id" "figs figs"; }
.fq-lg { grid-area: lg; height: 24px; width: auto; max-width: 120px; object-fit: contain; object-position: left center; filter: grayscale(1); opacity: .6; }
.fq-lg.sm { height: 18px; }
.fq-lg.lg { height: 34px; }
/* with no figures beside it, the plain view holds its quote to a reading measure */
.fq.fq-plain .fq-q { max-width: 720px; }
.fq-q { grid-area: q; margin: 0; padding: 0; border: 0; }
.fq-head { margin: 0; font-family: var(--font-body); font-size: var(--type-step); font-weight: 500; line-height: 1.25; letter-spacing: -0.015em; color: var(--ink); text-wrap: balance; }
.fq-rest { margin: var(--s4) 0 0; font-size: 16px; line-height: 1.6; color: var(--ink-muted); max-width: 62ch; }
.fq-ph { grid-area: ph; width: 64px; height: 64px; }
.fq-id { grid-area: id; display: flex; flex-direction: column; min-width: 0; }
.fq-nm { font-size: 15px; font-weight: 600; line-height: 22px; color: var(--ink); }
.fq-rl { font-family: var(--font-mono); font-size: 12px; line-height: 18px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--ink-muted); }
.fq-figs { grid-area: figs; margin: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s3); }
.fq-fig { border: 1px solid var(--rule); background: var(--field); padding: var(--s4); }
.fq-v { font-family: var(--font-mono); font-size: var(--type-subsection); line-height: 1.1; color: var(--ink); white-space: nowrap; }
.fq-fig .fq-l { margin: var(--s2) 0 0; font-family: var(--font-mono); font-size: 11px; line-height: 1.5; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-subtle); }
@media (min-width: 768px) { figure.fq { padding: var(--s6); } }
@media (min-width: 1024px) {
  figure.fq { padding: var(--s6); column-gap: var(--s6); row-gap: var(--s5); grid-template-columns: minmax(0, 1fr) 360px; grid-template-rows: auto 1fr auto; grid-template-areas: "lg ph" "q ph" "id ph"; align-items: start; }
  figure.fq.fq-figures { grid-template-areas: "lg ph" "q ph" "id figs"; }
  .fq-head { font-size: var(--type-section); line-height: 1.15; }
  .fq-q { align-self: center; }
  .fq-ph { width: 360px; height: 360px; }
  .fq-id { align-self: end; border-top: 1px solid var(--rule); padding-top: var(--s4); }
  .fq-figs { align-self: end; }
}
@media (prefers-reduced-motion: reduce) {
  .tss[data-on] .tss-track, .tss-dot::before, .tss-arrow, .prow-arrow { transition: none; }
  .tss.tss-logos[data-on] .tss-slide, .tss.tss-logos[data-on] .tss-slide .tss-who, .tss.tss-logos[data-on] .tss-q, .tss-bar, .tss.tss-logos .tss-arrow, .tss.tss-logos .tss-ldot { transition: none; }
  .tss.tss-logos[data-on] .tss-slide .tss-who, .tss.tss-logos[data-on] .tss-q { transform: none; }
}

/* ---- block · split ----
   The text on one side, its visual in a white box on the other. Stacked
   below 1024 with the visual after its text; side by side from 1024, the
   box as tall as the text. .flip sets the visual first. */
.textfig { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--s6); margin-top: var(--s6); }
.textfig > .pointrow, .textfig > .figbox, .textfig > .pshot { margin-top: 0; }
/* beside a window the point row stretches to the window's height; each point keeps its title and line together
   at its top, so the line never floats below its title (round two review, Oct 25, 2026: 26px against 4px) */
.textfig > .pointrow.inline > .point { align-content: start; }
.textfig.flip > .pshot { order: -1; }
/* a window's label: the line above it naming what it shows, in the section eyebrow's mono, with a
   short accent rule before it so it reads as the window's title (Oct 7, 2026) */
.textfig > .figcol { min-width: 0; }
.textfig.flip > .figcol { order: -1; }
.figcol .pshot { margin-top: 0; }
.figlabel { display: flex; align-items: center; gap: var(--s3); margin: 0 0 var(--s4); font-family: var(--font-mono); font-size: 12px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink); }
.figlabel::before { content: ""; width: 24px; height: 1px; background: var(--accent); flex: none; }
@media (min-width: 1024px) {
  .textfig { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--s7); align-items: stretch; }
  .textfig.flip > .figbox { order: -1; }
}

/* ---- block · logo panel ----
   Other companies' marks in their own color (S8), one category to a row:
   the mono label, then the marks in columns. Each mark is sized to equal
   optical area by its width and height attributes, never by CSS. The
   brands view is the proof row: no label, larger, centred. */
.logorows > .lrow { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--s4); padding: var(--s5) 0; }
.logorows > .lrow:first-child { padding-top: 0; }
.logorows > .lrow:last-child { padding-bottom: 0; }
.logorows > .lrow + .lrow { border-top: 1px solid var(--rule-soft); }
.lrow .lk { margin: 0; font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink-subtle); }
.lrow .marks { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); grid-auto-rows: 36px; gap: var(--s4); align-items: center; }
.lrow .marks img { display: block; max-width: 100%; height: auto; }
.lrow.brands .marks { grid-auto-rows: 56px; justify-items: center; }
/* the closing row: everything a panel cannot show, in one line of body text (Oct 14, 2026) */
.lrow.rest .ltx { margin: 0; font-family: var(--font-body); font-size: 15px; line-height: 1.5; color: var(--ink); }
@media (min-width: 768px) {
  .logorows > .lrow { grid-template-columns: 200px minmax(0, 1fr); align-items: center; gap: var(--s5); }
  .lrow .marks { grid-template-columns: repeat(5, minmax(0, 1fr)); gap: var(--s5) var(--s4); }
  .logorows > .lrow.brands { grid-template-columns: minmax(0, 1fr); }
  .lrow.brands .marks { grid-auto-rows: 72px; }
}

/* ---- block · product view ----
   The product as it shows itself: a head (what it is, when), then rows of
   an icon, a name, its status and its state. Illustrative content says so. */
.pview { display: flex; flex-direction: column; justify-content: center; }
.pview .pvh { display: flex; justify-content: space-between; gap: var(--s4); padding-bottom: var(--s3); border-bottom: 1px solid var(--rule); font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink-subtle); }
.pview .pvr { display: grid; grid-template-columns: 24px minmax(0, 1fr); column-gap: var(--s3); align-items: center; padding: var(--s4) 0; }
.pview .pvr + .pvr { border-top: 1px solid var(--rule-soft); }
.pview .pvr:last-child { padding-bottom: 0; }
.pview .pvn, .pview .pvs { margin: 0; font-size: 15px; line-height: 1.45; }
.pview .pvn { font-weight: 600; color: var(--ink-muted); }
.pview .pvs { color: var(--ink-subtle); }
.pview .state { grid-column: 2; justify-self: start; margin-top: var(--s2); font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.1em; line-height: 1.5; color: var(--ink-subtle); border: 1px solid var(--rule); padding: 0 var(--s2); white-space: nowrap; }
.pview .state.go { color: var(--accent-text, var(--accent)); border-color: var(--accent); }
@media (min-width: 768px) {
  .pview .pvr { grid-template-columns: 24px minmax(0, 1fr) auto; }
  .pview .state { grid-column: auto; margin-top: 0; }
}

/* ---- block · workflow ----
   White boxes joined by the arrow atom (S5). A node's head is the number
   marker and the name on one line; its text is the 15px rung. Views:
     (none)    stacked, top to bottom, at every width
     .across   left to right from 1024, stacked below
     .branch   one step fans out to the functions and they return: a tree
               below 1024, the orchestration diagram from 1024
     .returns  the last step feeds the first: a return path under the row
               from 1024, a return note when stacked
   The joins are the arrow atom; a bent path is the same 1.5 line in CSS.
   Spacing is the tokens. The fixed lengths in the diagram rules below are
   the atoms' own sizes, and each is one of these:
     24px   the arrow atom and the number marker; 12px is half of it
     1.5px  the line; 0.75px is half of it, so a line is centred on its point
     1px    a box's rule
     22px   the run from the spine to a function box, which the arrow spans
     2px    where the arrow's shaft starts inside its 24px box */
.wflow { margin-top: var(--s6); max-width: 720px; }
.wnode { position: relative; background: var(--alt); border: 1px solid var(--rule); padding: var(--s4) var(--s5); }
.wnode .ln { margin: var(--s2) 0 0; font-size: 15px; line-height: 1.5; color: var(--ink-muted); }
.wnode .wtitle { margin: var(--s2) 0 0; font-size: 17px; font-weight: 600; line-height: 1.4; color: var(--ink); }
.wnode .wpoints { margin: var(--s3) 0 0; padding-left: 1.4em; font-size: 15px; line-height: 1.5; color: var(--ink); }
.wnode .wpoints li + li { margin-top: var(--s1); }
.wnode .wpillars { list-style: none; margin: var(--s4) 0 0; padding: 0; border-top: 1px solid var(--rule); }
.wnode .wpillars li { border-bottom: 1px solid var(--rule); }
.wnode .wpillars a { display: flex; gap: var(--s3); min-height: 44px; padding: var(--s2) 0; color: var(--ink); text-decoration: none; font-size: 15px; line-height: 1.4; box-sizing: border-box; align-items: center; }
@media (hover: hover) and (pointer: fine) { .wnode .wpillars a:hover span:last-child { text-decoration: underline; text-underline-offset: 3px; } }
.wnode .wpillars .pnum { flex: none; min-width: 2.2em; font-family: var(--font-mono); font-size: 12px; letter-spacing: 0.06em; color: var(--accent); }
/* the map: a sequence that lists its pillars, in the point row's calm treatment */
.wflow.map { max-width: none; }
.wflow.map > .wjoin { display: none; }
.wflow.map > .wnode { background: none; border: none; padding: var(--s5) 0; }
.wflow.map > .wnode:first-child { padding-top: 0; }
.wflow.map > .wjoin + .wnode { border-top: 1px solid var(--rule-soft); }
.wflow.map .wpillars { border-top: none; margin-top: var(--s3); }
.wflow.map .wpillars li { border-bottom: none; }
@media (min-width: 768px) {
  .wflow.map.across { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .wflow.map.across > .wnode { padding: 0 var(--s5); }
  .wflow.map.across > .wnode:first-child { padding-left: 0; }
  .wflow.map.across > .wnode:last-of-type { padding-right: 0; }
  .wflow.map.across > .wjoin + .wnode { border-top: none; border-left: 1px solid var(--rule); }
}
.wjoin { display: block; padding: var(--s1) 0 var(--s1) calc(var(--s5) + 1px); }
.wreturn { display: flex; align-items: center; gap: var(--s3); margin: var(--s2) 0 0 calc(var(--s5) + 1px); font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink-subtle); }
.wreturn .ico { color: var(--ink-muted); }
.wflow > .arw.up { display: none; }

/* atom · diagram label — a name inside a workflow is a label, not a box
   title: JetBrains Mono like every other label (MC 2026-09-17). Its 18px
   lines sit centred on the 24px marker. */
.wflow .cardhead .nm { font-family: var(--font-mono); font-size: 12px; font-weight: 500; line-height: 18px; padding-top: 3px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink); }

/* the fan — stacked, a spine with a branch into each function. The fan is a
   step of its own, so its number and label head the column; stacked, the
   marker sits on the spine and masks it with the page field. */
/* back the 22px run and half the marker, so the marker is centred on the spine */
.wfan > .cardhead { position: relative; margin-left: calc(-1 * (22px + 12px)); }
.wfan > .cardhead .nmark { background: var(--field); }
/* geometry: a node's marker centres at its padding + 1px border + 12px; the spine sits there,
   and the fan nodes start 22px past it so the arrow atom spans the gap exactly */
.wfan { position: relative; display: grid; gap: var(--s3); padding: var(--s4) 0 var(--s4) calc(var(--s5) + 35px); }
/* the spine runs on through the next join's top padding to where its arrow's shaft starts */
.wfan::before { content: ''; position: absolute; left: calc(var(--s5) + 12.25px); top: 0; bottom: calc(-1 * (var(--s1) + 2px)); width: 1.5px; background: var(--ink-muted); }
.wfan > .wnode { height: calc(2 * var(--s4) + 24px); display: flex; align-items: center; }
.wfan > .wnode > .arw { position: absolute; left: -23px; top: calc(var(--s4) - 1px); }
.wfan > .wtie { display: none; }

@media (min-width: 1024px) {
  .wflow.across, .wflow.branch { display: flex; max-width: none; }
  .wflow.across { align-items: stretch; }
  .wflow.across > .wnode, .wflow.branch > .wnode { flex: 1 1 0; min-width: 0; padding: var(--s4); }
  .wflow.across > .wjoin { flex: none; padding: calc(var(--s4) + 1px) var(--s1) 0; }
  .wflow.across .arw.down, .wflow.branch .arw.down { transform: none; }

  /* the orchestration diagram — the fan becomes a column: a bracket in with
     an arrow to each function, a bracket out, level with the nodes */
  .wflow.branch { align-items: center; }
  /* the steps around the column share one height: their top and bottom edges
     line up with its first and last function (the column's 16px inset and its
     rule, and the 12px the column's label needs above it) */
  .wflow.branch > .wnode { align-self: stretch; margin: calc(var(--s3) + var(--s4) + 1px) 0 calc(var(--s4) + 1px); }
  /* the arrows sit on the middle function's line, 6px under the row's centre */
  .wflow.branch > .wjoin { flex: none; padding: 0 var(--s1) 0 0; margin-top: var(--s3); }
  /* the column is one step, so a thin rule holds it together (MC 2026-09-17).
     It sits a join's width (24px arrow and 4px) from the step before it, like
     every other pair of steps; the line in crosses that gap. Its label sits on
     the rule, so the functions keep the one 16px inset above and below, and
     the label's marker sits 16px in, like every other step's. */
  /* the column's geometry: the in-spine sits 16px inside it and the functions start
     the 22px run past it; the out-spine sits 16px past the functions, so the column
     keeps 8px (24 less 16) beyond it */
  .wflow.branch > .wfan { flex: 0 0 auto; margin: var(--s3) 0 0 calc(24px + var(--s1)); border: 1px solid var(--rule); padding: var(--s4) var(--s5) var(--s4) calc(var(--s4) + 22px); }
  .wflow.branch > .wfan > .wnode { padding: var(--s4); }
  /* the label's marker is centred on the rule: half the marker above the column's
     outer edge, and the position is measured inside the 1px rule */
  .wflow.branch > .wfan > .cardhead { position: absolute; top: calc(-1 * (12px + 1px)); left: calc(var(--s4) - var(--s2)); margin: 0; padding: 0 var(--s2); background: var(--field); }
  .wflow.branch > .wfan::before { left: calc(var(--s4) - 0.75px); top: calc(2 * var(--s4) + 12px); bottom: calc(2 * var(--s4) + 12px); }
  .wflow.branch > .wfan::after { content: ''; position: absolute; right: calc(var(--s5) - var(--s4) - 0.75px); top: calc(2 * var(--s4) + 12px); bottom: calc(2 * var(--s4) + 12px); width: 1.5px; background: var(--ink-muted); }
  .wflow.branch > .wfan > .wtie { display: block; position: absolute; top: calc(50% - 0.75px); height: 1.5px; background: var(--ink-muted); }
  /* the line in starts at the step before (back across the join and the rule) and
     ends on the in-spine; the line out starts on the out-spine and ends where the
     next arrow's shaft starts, past the rule; each function's stub runs from its
     rule to the out-spine */
  .wflow.branch > .wfan > .wtie.into { left: calc(-1 * (24px + var(--s1) + 1px)); width: calc(24px + var(--s1) + 1px + var(--s4)); }
  .wflow.branch > .wfan > .wtie.outof { right: calc(-1 * (1px + 2px)); width: calc(var(--s5) - var(--s4) + 1px + 2px); }
  .wflow.branch > .wfan > .wnode::after { content: ''; position: absolute; right: calc(-1 * (var(--s4) + 1px)); top: calc(50% - 0.75px); width: var(--s4); height: 1.5px; background: var(--ink-muted); }

  /* the return path — under the row, from the last node back up into the first.
     The path is 32px deep and 8px off the bottom, so the row keeps 40px under it;
     its arms sit on the markers' centres; the up-arrow's box reaches 1px into the
     first node's rule, so its tip meets the box */
  .wflow.across.returns { position: relative; padding-bottom: calc(var(--s6) + var(--s2)); }
  .wflow.across.returns::before { content: ''; position: absolute; left: calc(var(--s4) + 12.25px); right: calc(var(--s4) + 12.25px); bottom: var(--s2); height: var(--s6); border: 1.5px solid var(--ink-muted); border-top: none; }
  .wflow.across.returns > .arw.up { display: block; position: absolute; left: calc(var(--s4) + 1px); bottom: calc(var(--s6) + var(--s2) - 24px + 1px); }
  .wflow.across.returns > .wreturn { display: none; }
}

/* ---- view · stats, held — three short figures stay three across on a phone ---- */
.stats.held { grid-template-columns: repeat(3, minmax(0, 1fr)); }
/* four figures hold two by two on a phone and run four across from 768 */
.stats.held.stats4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 768px) {
  .stats.held.stats4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* ---- behavior · motion (a page opts in with body.motion; MC 2026-09-17) ----
   After Emil Kowalski (emilkowal.ski/ui/great-animations): ease-out, pieces
   shorter than 300ms, and transform and opacity. Arrows also draw with
   clip-path, which his rule does not cover. The curve is a strong ease-out,
   so a thing responds at once and settles. No piece runs longer than 0.3s.
   It extends the reveal (.seq under .anim, which the page script sets only
   when motion is allowed), so a reader who prefers reduced motion, or a page
   without the script, sees every block at rest.
     workflow   the steps arrive in order and each arrow draws toward the
                next step; in a branch the brackets draw, the functions light
                up one after another, and the steps after the column wait
     stats      each figure rises a little further than its label and settles
     logos      the rows arrive in a short stagger, and the marks in each */
@media (prefers-reduced-motion: no-preference) {
  .anim .motion .seq > * { transition-duration: var(--motion-reveal-sharp); transition-timing-function: var(--motion-ease-out); }

  /* workflow: every child carries its place in the order as --d */
  .anim .motion .wflow.seq > :nth-child(1) { --d: 0.0s; }
  .anim .motion .wflow.seq > :nth-child(2) { --d: 0.12s; }
  .anim .motion .wflow.seq > :nth-child(3) { --d: 0.24s; }
  .anim .motion .wflow.seq > :nth-child(4) { --d: 0.36s; }
  .anim .motion .wflow.seq > :nth-child(5) { --d: 0.48s; }
  .anim .motion .wflow.seq > :nth-child(6) { --d: 0.6s; }
  .anim .motion .wflow.seq > :nth-child(7) { --d: 0.72s; }
  .anim .motion .wflow.seq > :nth-child(8) { --d: 0.84s; }
  .anim .motion .wflow.seq > :nth-child(9) { --d: 0.96s; }
  .anim .motion .wflow.seq > :nth-child(10) { --d: 1.08s; }
  .anim .motion .wflow.seq > * { transition-delay: calc(var(--d, 0s) + var(--x, 0s)); }
  .anim .motion .wflow.branch.seq > .wfan ~ * { --x: 0.9s; }
  .anim .motion .wflow.seq > .wjoin { opacity: 1; transform: none; }
  .anim .motion .wflow.seq > .wjoin .arw, .anim .motion .wfan > .wnode > .arw { clip-path: inset(0 100% 0 0); transition: clip-path var(--motion-reveal-sharp) var(--motion-ease-out); transition-delay: inherit; }
  .anim .motion .wflow.seq.in > .wjoin .arw, .anim .motion .wflow.seq.in .wfan > .wnode > .arw { clip-path: inset(0 0 0 0); }
  /* across: each step's marker turns green as the line reaches it, in order, so the phases read as a sequence */
  .anim .motion .wflow.across.seq > .wnode .nmark { transition: border-color var(--motion-reveal) var(--motion-ease-out); transition-delay: calc(var(--d, 0s) + 0.2s); }
  .anim .motion .wflow.across.seq.in > .wnode .nmark { border-color: var(--accent); }
  .anim .motion .wfan::before, .anim .motion .wfan::after { transform: scaleY(0); transform-origin: top; transition: transform var(--motion-reveal-sharp) var(--motion-ease-out); transition-delay: calc(var(--d, 0s) + 0.15s); }
  .anim .motion .wflow.seq.in .wfan::before, .anim .motion .wflow.seq.in .wfan::after { transform: scaleY(1); }
  .anim .motion .wfan > .wtie { transform: scaleX(0); transform-origin: left; transition: transform 0.25s var(--motion-ease-out); transition-delay: calc(var(--d, 0s) + 0.15s); } /* motion: allow the tie draws in step with its fan, timed to the drawn arrows */
  .anim .motion .wfan > .wtie.outof { transition-delay: calc(var(--d, 0s) + 0.75s); }
  .anim .motion .wfan::after { transition-delay: calc(var(--d, 0s) + 0.55s); }
  .anim .motion .wflow.seq.in .wfan > .wtie { transform: scaleX(1); }
  .anim .motion .wfan > .wnode { opacity: 0.25; transition: opacity var(--motion-reveal-sharp) var(--motion-ease-out); }
  .anim .motion .wflow.seq.in .wfan > .wnode { opacity: 1; }
  .anim .motion .wfan > .wnode::after { transform: scaleX(0); transform-origin: left; transition: transform var(--motion-turn) var(--motion-ease-out); }
  .anim .motion .wflow.seq.in .wfan > .wnode::after { transform: scaleX(1); }
  /* the column: its head comes first and the tie second, so the functions are children 3 onward */
  .anim .motion .wfan > .wnode:nth-child(3), .anim .motion .wfan > .wnode:nth-child(3) > .arw { transition-delay: calc(var(--d, 0s) + 0.25s); }
  .anim .motion .wfan > .wnode:nth-child(3)::after { transition-delay: calc(var(--d, 0s) + 0.37s); }
  .anim .motion .wfan > .wnode:nth-child(4), .anim .motion .wfan > .wnode:nth-child(4) > .arw { transition-delay: calc(var(--d, 0s) + 0.35s); }
  .anim .motion .wfan > .wnode:nth-child(4)::after { transition-delay: calc(var(--d, 0s) + 0.47s); }
  .anim .motion .wfan > .wnode:nth-child(5), .anim .motion .wfan > .wnode:nth-child(5) > .arw { transition-delay: calc(var(--d, 0s) + 0.45s); }
  .anim .motion .wfan > .wnode:nth-child(5)::after { transition-delay: calc(var(--d, 0s) + 0.57s); }
  .anim .motion .wfan > .wnode:nth-child(6), .anim .motion .wfan > .wnode:nth-child(6) > .arw { transition-delay: calc(var(--d, 0s) + 0.55s); }
  .anim .motion .wfan > .wnode:nth-child(6)::after { transition-delay: calc(var(--d, 0s) + 0.67s); }
  .anim .motion .wfan > .wnode:nth-child(7), .anim .motion .wfan > .wnode:nth-child(7) > .arw { transition-delay: calc(var(--d, 0s) + 0.65s); }
  .anim .motion .wfan > .wnode:nth-child(7)::after { transition-delay: calc(var(--d, 0s) + 0.77s); }
  .anim .motion .wfan > .wnode:nth-child(8), .anim .motion .wfan > .wnode:nth-child(8) > .arw { transition-delay: calc(var(--d, 0s) + 0.75s); }
  .anim .motion .wfan > .wnode:nth-child(8)::after { transition-delay: calc(var(--d, 0s) + 0.87s); }
  .anim .motion .wflow.across.returns::before { clip-path: inset(0 0 0 100%); transition: clip-path var(--motion-reveal-sharp) var(--motion-ease-out); transition-delay: 0.6s; }
  .anim .motion .wflow.across.returns.in::before { clip-path: inset(0 0 0 0); }

  /* the compare block's arrow sits outside .seq > *, so its 0.4s reveal is held to the bound here */
  .anim .motion .vs.seq .arr { transition-duration: var(--motion-reveal-sharp); transition-timing-function: var(--motion-ease-out); }

  /* stats: the figure settles a little after its label */
  .anim .motion .stats.seq .sv { transform: translateY(8px); transition: transform var(--motion-reveal-sharp) var(--motion-ease-out); transition-delay: inherit; }
  .anim .motion .stats.seq.in .sv { transform: none; }

  /* logo rows, then the marks in each */
  .anim .motion .logorows.seq > :nth-child(1) { --d: 0.0s; }
  .anim .motion .logorows.seq > :nth-child(2) { --d: 0.045s; }
  .anim .motion .logorows.seq > :nth-child(3) { --d: 0.09s; }
  .anim .motion .logorows.seq > :nth-child(4) { --d: 0.135s; }
  .anim .motion .logorows.seq > :nth-child(5) { --d: 0.18s; }
  .anim .motion .logorows.seq > :nth-child(6) { --d: 0.225s; }
  .anim .motion .logorows.seq > :nth-child(7) { --d: 0.27s; }
  .anim .motion .logorows.seq > :nth-child(8) { --d: 0.315s; }
  .anim .motion .logorows.seq > :nth-child(9) { --d: 0.36s; }
  .anim .motion .logorows.seq > :nth-child(10) { --d: 0.405s; }
  .anim .motion .logorows.seq > :nth-child(11) { --d: 0.45s; }
  .anim .motion .logorows.seq > :nth-child(12) { --d: 0.495s; }
  .anim .motion .logorows.seq > :nth-child(13) { --d: 0.54s; }
  .anim .motion .logorows.seq > :nth-child(14) { --d: 0.585s; }
  .anim .motion .logorows.seq > * { transition-delay: var(--d, 0s); }
  .anim .motion .logorows.seq .marks > img { opacity: 0; transition: opacity var(--motion-reveal-sharp) var(--motion-ease-out); }
  .anim .motion .logorows.seq.in .marks > img { opacity: 1; }
  .anim .motion .logorows.seq .marks > img:nth-child(1) { transition-delay: calc(var(--d, 0s) + 0.1s); }
  .anim .motion .logorows.seq .marks > img:nth-child(2) { transition-delay: calc(var(--d, 0s) + 0.13s); }
  .anim .motion .logorows.seq .marks > img:nth-child(3) { transition-delay: calc(var(--d, 0s) + 0.16s); }
  .anim .motion .logorows.seq .marks > img:nth-child(4) { transition-delay: calc(var(--d, 0s) + 0.19s); }
  .anim .motion .logorows.seq .marks > img:nth-child(5) { transition-delay: calc(var(--d, 0s) + 0.22s); }
  .anim .motion .logorows.seq .marks > img:nth-child(6) { transition-delay: calc(var(--d, 0s) + 0.25s); }
  .anim .motion .logorows.seq .marks > img:nth-child(7) { transition-delay: calc(var(--d, 0s) + 0.28s); }
  .anim .motion .logorows.seq .marks > img:nth-child(8) { transition-delay: calc(var(--d, 0s) + 0.31s); }
  .anim .motion .logorows.seq .marks > img:nth-child(9) { transition-delay: calc(var(--d, 0s) + 0.34s); }
  .anim .motion .logorows.seq .marks > img:nth-child(10) { transition-delay: calc(var(--d, 0s) + 0.37s); }
}

/* the reveal must not undo a turned arrow: the returns view's up arrow keeps its rotation */
@media (prefers-reduced-motion: no-preference) {
  .anim .seq > .arw.up, .anim .seq.in > .arw.up { transform: rotate(-90deg); }
}

/* ---- template · the private overview (body.overview-doc) ----
   A document sent to a named reader, not a web page: the cover opens it
   between two rules, headlines balance, and the colophon sits under the
   next step it belongs to. */
.overview-doc .wrap h1, .overview-doc .wrap h2 { text-wrap: balance; }
/* the lockup's scale and measure (MC 2026-09-17). The page title is the
   cover, so the Vision headline takes the section size: every headline is 48
   and every subhead 18. The ratio is Anthropic's (claude.com at 1440: the text
   under a section title is about a third of it). The lockup reads in a 720px
   column (36em at 20, 40em at 18); a headline may run to 816px (17em at 48).
   Ours ran 1052px; Anthropic holds paragraphs to 517-640px. --measure stays
   undefined. */
.overview-doc .wrap h1 { font-size: var(--type-section); max-width: 17em; }
/* a section title may run a little wider than its subhead, as Anthropic's do (704 over 672px) */
.overview-doc .wrap h2 { font-size: var(--type-section); max-width: 17em; }
.overview-doc .wrap .body { max-width: 36em; }
.overview-doc .wrap h1 + .body, .overview-doc .wrap h2 + .body { font-size: var(--type-lede); max-width: 40em; }
.overview-doc .wrap .body { text-wrap: pretty; }
.overview-doc .hero .meta-grid { margin: 0 0 var(--s7); padding: var(--s5) 0; border-bottom: 1px solid var(--rule); }
.overview-doc section.colophon { padding-top: 0; margin-top: calc(-1 * var(--s8)); border-top: none; }
.overview-doc section.colophon > .wrap { padding-top: var(--s5); }
/* The page's ladder (Oct 1, 2026). H1 the page; H2 a part: its number and green label, the
   big heading, the full section break; H3 a chapter inside the part: a grey label, the
   subheading size, a soft rule and half the space; H4 a subsection: a bold line in the body
   face, sentence case. Mono capitals mean two things only: a part's green label and a row's
   grey label. */
.overview-doc section.chapter { border-top: 1px solid var(--rule-soft); padding-top: var(--s6); padding-bottom: var(--s6); }
.overview-doc section.chapter > .wrap { padding-top: 0; }
.overview-doc section:not(.chapter) + section.chapter { margin-top: calc(-1 * var(--s5)); }
.overview-doc section.chapter .kick { margin: 0 0 var(--s3); font-family: var(--font-mono); font-size: 12px; font-weight: 500; text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink-subtle); }
.overview-doc section.chapter h3 { font-family: var(--font-display); font-weight: 400; font-size: var(--type-chapter); line-height: 1.15; letter-spacing: -0.01em; color: var(--ink); max-width: 22em; text-wrap: balance; margin: 0; }
.overview-doc section.chapter h3 + .body { margin-top: var(--s3); font-size: var(--type-chapter-lede); max-width: 40em; }
.overview-doc .eyebrow .pn { font-weight: inherit; color: inherit; }
.overview-doc h4.sublab { font-family: var(--font-body); font-size: 17px; font-weight: 600; line-height: 1.4; text-transform: none; letter-spacing: 0; color: var(--ink); border-top: 1px solid var(--rule-soft); display: flex; align-items: baseline; gap: var(--s3); }
/* a point inside a numbered section: one rung below the section, Inter 600 at the box-title size,
   with no hairline, so the section's points read as its parts (the book's ladder, Oct 6, 2026) */
.overview-doc h5.sublab.point { font-family: var(--font-body); font-size: 15px; font-weight: 600; line-height: 1.4; text-transform: none; letter-spacing: 0; color: var(--ink-muted); border-top: none; padding-top: 0; margin-top: var(--s6); }
/* the number in the pillar label's mono gray, so 1.1 reads as part of Pillar 1 */
.overview-doc h4.sublab .sn { font-family: var(--font-mono); font-size: 12px; font-weight: 500; letter-spacing: 0.1em; color: var(--ink-subtle); }
/* the older blocks on this register (MC, Sep 17, 2026: the approach page is built
   on it). Their names take the ladder's faces: Ponomar stays with the headlines,
   a function head is an H3, an agent's or a box's name is a box title, and bold
   text keeps the body's gray, as a point title does, and no text is black against
   it. A number or a key is a row label, never green. Both halves of a before and
   after read in the one box-text gray, joined by the arrow drawing. Inline code is
   the mono face. A note under a list, a box or a diagram sits a step's distance
   from it. Other registers keep the earlier treatment. */
/* The function head keeps the display face on the large rung (MC, 2026-09-23). This rule
   set the Inter H3 treatment that ruling rejected, and out-specified the ruled rule on
   every overview-doc page. Only the letter-spacing is the register's own now. */
.overview-doc .fnhead .fnn { letter-spacing: -0.01em; }
.overview-doc .enc .enm, .overview-doc .bx .bk { font-family: var(--font-body); font-size: 16px; font-weight: 600; line-height: 24px; letter-spacing: 0; text-transform: none; color: var(--ink-muted); }
.overview-doc .enc .enm { margin-top: var(--s1); }
.overview-doc .enc.rail .enm.withicon { font-family: var(--font-display); font-size: var(--type-card-title); font-weight: 400; line-height: 1.15; letter-spacing: -0.01em; color: var(--ink); margin-top: 0; }
/* the agent card's row labels hold one line: the 180px label column every keyed-row block
   on this register uses (.plist, .vs), where 110px broke "Workflows we would run" in two */
@media (min-width: 768px) { .overview-doc .erow { grid-template-columns: 180px 1fr; } }
.overview-doc .blist li strong, .overview-doc .tt .tmrw, .overview-doc .tt .earr { color: var(--ink-muted); }
/* from 768 the arrow sits beside the labels: its 24px centered on their 16px line */
.overview-doc .tt .earr.h { align-self: start; margin-top: -4px; }
.overview-doc :is(.pointrow, .trio, .wflow, .tbox, .lvl, .blist, .plist) + .note { margin-top: var(--s5); }
/* on the site a note is a plain aside: no rule beside it, which made every aside read as a quote
   (MC, Oct 3, 2026: "I never want to see this quote model") */
body.site .note { border-left: none; padding-left: 0; }
.overview-doc .plist .pq, .overview-doc .eown { color: var(--ink-muted); }
.overview-doc .plist .pk, .overview-doc .fnhead .fnk { color: var(--ink-subtle); }
.overview-doc .fnhead .fnl { font-size: 16px; }
.overview-doc code { font-family: var(--font-mono); font-size: 15px; }
/* the read-this-first strip reads in the lockup's 720px column, its text in the box-text gray */
.overview-doc .caveat { max-width: 720px; }
.overview-doc .caveat .cvt { color: var(--ink-muted); max-width: none; }
/* print is at rest: no transition runs (a transition outranks !important, so a
   page switched to print mid-reveal would otherwise print pieces in flight), and
   the returns view's up-arrow keeps its quarter turn */
@media print {
  .overview-doc *, .overview-doc *::before, .overview-doc *::after { transition: none !important; }
  .overview-doc .seq > :not(.arw.up), .overview-doc .seq .marks > img, .overview-doc .wfan > .wnode { opacity: 1 !important; transform: none !important; }
  .overview-doc .seq > .arw.up { opacity: 1 !important; transform: rotate(-90deg) !important; }
  .overview-doc .seq .arw, .overview-doc .wflow::before { clip-path: none !important; }
  .overview-doc .wfan::before, .overview-doc .wfan::after, .overview-doc .wfan > .wtie, .overview-doc .wfan > .wnode::after, .overview-doc .stats .sv { transform: none !important; }
}

/* ---------- reduced motion — a reader who asks for less gets none ----------
   The reveals already sit inside prefers-reduced-motion: no-preference. This stops
   what is left: every transition, every animation, and the smooth scroll. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important; animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important; scroll-behavior: auto !important;
  }
}

/* band: a strip ruled above and below, the section after it unruled (the homepage's client
   logos, as the live page draws them; MC, Oct 2, 2026). The hero's own bottom space sets the
   gap above it. Last in the sheet, and as specific as the site shell's section padding, so it
   holds at every width. */
section.band, body.site section.band { padding: 0; border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule); }
section.band > .wrap { padding-top: 0; padding-bottom: 0; }
section.band + section { border-top: none; }
/* a stats band holds its figures evenly, and the band's rules are the only lines: a stat inside it
   carries no rule of its own (MC, Oct 3, 2026: the labels sat on the bottom rule, under a doubled top) */
section.band .stats { margin: var(--s6) 0; }
section.band .stats .st { border-top: none; padding-top: 0; }
/* product-shot: the real product in an app window: a title bar, the file's real lines numbered (or a
   capture), and one caption line under it */
.pshot { margin: var(--s6) 0 0; }
.pshot .pwin { background: var(--alt); border: 1px solid var(--rule); overflow: hidden; }
.pshot .pbar { display: flex; align-items: center; gap: var(--s3); padding: 10px var(--s4); border-bottom: 1px solid var(--rule); background: var(--field); }
.pshot .ptitle { font-family: var(--font-mono); font-size: 11px; color: var(--ink-subtle); letter-spacing: .04em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pshot .pcode { margin: 0; padding: var(--s4) var(--s4) var(--s5); overflow-x: auto; font-family: var(--font-mono); font-size: 13px; line-height: 1.7; color: var(--ink); }
.pshot .pl { display: block; white-space: pre-wrap; padding-left: 3em; text-indent: -3em; }
.pshot .pn { display: inline-block; width: 3em; text-indent: 0; color: var(--ink-subtle); user-select: none; }
.pshot .pimg { display: block; width: 100%; height: auto; }
.pimgshot picture { display: block; max-width: 390px; }
@media (min-width: 768px) { .pimgshot picture { max-width: none; } section .pimgshot picture { max-width: 760px; } }  /* in a section, the reading width; in a hero, its column */
/* a product session as video (KNW_ST_MC_Photography.md, Video; content/brand/images.mjs videoShot): the wrapper
   takes the poster's box, the video lies over it and shows once it plays (public/shared/video.js), and the
   reader's button sits in its top-right corner, 44px square and solid, over the empty header strip of the session,
   never over the product's own controls at the bottom: Pause while it plays, Play under reduced motion, Replay once
   it has played through and holds its last frame. Without the script, only the poster. */
.pvid { position: relative; display: block; width: 100%; }
/* the box is the poster's own width, set the way a still's <picture> is (never fit-content: an unloaded lazy
   poster has no width yet, so the box collapsed and its button sat off the left of a phone) */
.pimgshot .pvid, .demo .dp .pvid { max-width: 390px; }
@media (min-width: 768px) { .pimgshot .pvid, .demo .dp .pvid { max-width: none; } section .pimgshot .pvid { max-width: 760px; } }
.pvid-v { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; opacity: 0; pointer-events: none; }
.pvid.on .pvid-v { opacity: 1; }
.pvid-btn { position: absolute; top: var(--s2); right: var(--s2); width: 44px; height: 44px; padding: 0; display: grid; place-items: center; background: var(--field); border: 1px solid var(--rule); color: var(--ink); cursor: pointer; }
.pvid-btn[hidden] { display: none; }
.pvid-btn:focus-visible { outline: 2px solid var(--accent-text, var(--accent)); outline-offset: 2px; }
.pvid-i { position: relative; display: block; width: 12px; height: 14px; }
.pvid-i::before, .pvid-i::after { content: ""; position: absolute; top: 0; width: 4px; height: 14px; background: currentColor; }
.pvid-i::before { left: 0; } .pvid-i::after { right: 0; }
.pvid.paused .pvid-i::before { width: 0; height: 0; background: none; border-style: solid; border-width: 7px 0 7px 12px; border-color: transparent transparent transparent currentColor; }
.pvid.paused .pvid-i::after { display: none; }
/* Replay: a square loop open on the left, its top end an arrowhead pointing back, drawn in the icon line (1.5, square corners, no fill) */
.pvid.ended .pvid-i { width: 14px; height: 14px; }
.pvid.ended .pvid-i::before { left: 2px; top: 2px; width: 12px; height: 11px; box-sizing: border-box; background: none; border: 1.5px solid currentColor; border-left-color: transparent; }
.pvid.ended .pvid-i::after { display: block; left: -1px; right: auto; top: -1.25px; width: 0; height: 0; background: none; border-style: solid; border-width: 4px 6px 4px 0; border-color: transparent currentColor transparent transparent; }
/* a portrait's <picture> (photoTag in content/brand/portraits.mjs) lays its img out as if the picture were not there */
picture.ph { display: contents; }
.pshot figcaption { margin-top: var(--s3); font-size: 15px; line-height: 1.5; color: var(--ink-muted); max-width: 60ch; }
@media (min-width: 768px) { .pshot .pcode { font-size: 14px; padding: var(--s5) var(--s5) var(--s6); } }
/* hero aside: one product shot beside the copy, the claude.com Claude Code hero translated. Stacked under
   the copy on a phone; copy left and the shot right from 1024px, centred on each other. */
.hero.split .hcopy { min-width: 0; }
.hero.split .haside { margin-top: var(--s6); }
.hero.split .haside .pshot { margin: 0; }
@media (min-width: 1024px) {
  .hero.split .wrap { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); column-gap: var(--s7); align-items: center; }
  .hero.split .haside { margin-top: 0; }
}
/* hero, stacked: the product as one full-width panel under the copy (KNW_ST_MC_Block-Library.md, the two hero
   forms). The title holds to an 816px measure; the panel is the product window on the accent-soft ground, square
   and flat with a 1px rule, and it spans the full content width (the gutter included), so the product takes the
   first screen. The section below owns the gap, so the hero keeps no bottom space. */
.hero.stacked h1 { max-width: 816px; }
/* the label and title as one group, the line and button as the other (the side-by-side pair from 1024px) */
.hero.stacked .hhead { min-width: 0; }
.hero.stacked .haside { margin: var(--s6) calc(-1 * var(--gutter)) 0; }
.hero.stacked .haside .pshot { margin: 0; padding: var(--s4); background: var(--accent-soft); border: 1px solid var(--rule); }
.hero.stacked .pimgshot .pvid, .hero.stacked .pimgshot picture { max-width: none; margin: 0 auto; }
body.site .hero.stacked { padding-bottom: 0; }
@media (min-width: 768px) {
  body.site .hero.stacked { padding-top: var(--s7); }
  .hero.stacked .haside { margin-top: var(--s7); }
  .hero.stacked .haside .pshot { padding: var(--s5); }
}
/* from 1024px the label and title sit left and the line, the button and the quiet line right, on one baseline,
   the Linear and Stripe arrangement: the copy takes two lines of height and the product the first screen */
@media (min-width: 1024px) {
  .hero.stacked .hcopy { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); column-gap: var(--s7); align-items: end; }
  .hero.stacked .hlede > :first-child { margin-top: 0; }
}
/* demo: the product at work, one use case at a time. The phase-tab idiom on a 1px rule above the
   session, the use cases as a plain list (beside it from 1024, under it below). Radio inputs, no script.
   The accent underline marks the use case on screen, the block's one green mark. */
.demo { margin: var(--s6) 0 0; display: grid; grid-template-columns: minmax(0, 1fr); row-gap: var(--s4); }
.demo .dr { position: absolute; opacity: 0; width: 1px; height: 1px; }
.demo .dmenu { display: flex; flex-wrap: nowrap; border-bottom: 1px solid var(--rule); }
.demo .dt { flex: 1 1 0; display: flex; align-items: center; justify-content: center; min-height: 44px;
  padding: var(--s2); margin-bottom: -1px; border-bottom: 2px solid transparent;
  font-family: var(--font-mono); font-size: 12px; line-height: 1.3; letter-spacing: 0.04em;
  text-transform: uppercase; text-align: center; color: var(--ink-subtle); cursor: pointer; }
@media (hover: hover) and (pointer: fine) { .demo .dt:hover { color: var(--ink); } }
.demo .dt:active { color: var(--ink); border-bottom-color: var(--rule); }
.demo .d0:checked ~ .dmenu .t0, .demo .d1:checked ~ .dmenu .t1,
.demo .d2:checked ~ .dmenu .t2, .demo .d3:checked ~ .dmenu .t3 { color: var(--ink); border-bottom-color: var(--accent); }
.demo .d0:focus-visible ~ .dmenu .t0, .demo .d1:focus-visible ~ .dmenu .t1,
.demo .d2:focus-visible ~ .dmenu .t2, .demo .d3:focus-visible ~ .dmenu .t3 { outline: 2px solid var(--accent-text, var(--accent)); outline-offset: 2px; }
.demo .dp { display: none; margin: 0; }
.demo .dp picture { display: block; max-width: 390px; }
.demo .pimg { display: block; width: 100%; height: auto; }
.demo .d0:checked ~ .dpanes .p0, .demo .d1:checked ~ .dpanes .p1,
.demo .d2:checked ~ .dpanes .p2, .demo .d3:checked ~ .dpanes .p3 { display: block; }
.demo .dcap { margin: 0; font-size: 15px; line-height: 1.5; color: var(--ink-muted); max-width: 60ch; }
.demo .dnotes { list-style: none; margin: var(--s4) 0 0; padding: 0; display: grid; gap: var(--s5); max-width: 60ch; }
.demo .dn { margin: 0; font-size: 16px; line-height: 1.5; color: var(--ink-muted); }
.demo .dn strong { display: block; font-weight: 600; color: var(--ink); }
@media (min-width: 768px) {
  .demo .dt { flex: none; padding: var(--s3) var(--s4); white-space: nowrap; }
  .demo .dp picture { max-width: none; }
}
@media (min-width: 1024px) {
  .demo.notes { grid-template-columns: minmax(0, 1fr) 300px; column-gap: var(--s7); }
  .demo.notes .dmenu { grid-column: 1; grid-row: 1; }
  .demo.notes .dpanes { grid-column: 1; grid-row: 2; }
  .demo.notes .dcap { grid-column: 1; grid-row: 3; }
  .demo.notes .dnotes { grid-column: 2; grid-row: 2; align-self: start; margin: 0; }
}
/* story: a narrative in two to five short paragraphs, at reading size in the reading measure */
/* the transcript shot: a real exchange, the person's turns set apart from the agent's, the source under it */
.txshot .tx { padding: var(--s4); display: grid; gap: var(--s4); font-size: 15px; line-height: 1.5; color: var(--ink); }
.txshot .tx-turn p, .txshot .tx-turn ul { margin: 0 0 var(--s2); }
.txshot .tx-turn ul { padding-left: var(--s4); }
.txshot .tx-who { font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: .1em; color: var(--ink-subtle); }
.txshot .tx-person { border-left: 2px solid var(--accent); padding-left: var(--s3); }
.txshot .tx-agent { padding-left: 0; }  /* the agent's turn sits on the window's own margin; the person's carries the rule */
.txshot .tx-gap { color: var(--ink-subtle); }
.txshot .tx-src { margin: var(--s2) 0 0; font-family: var(--font-mono); font-size: 11px; letter-spacing: .06em; color: var(--ink-subtle); }
@media (min-width: 768px) { .txshot .tx { padding: var(--s5); } }
/* the section icon: one registry icon above the label, in ink, at the point-title size */
.sec-icon { color: var(--ink); margin-bottom: var(--s4); }
.sec-icon .ico { display: block; width: 32px; height: 32px; }
.story { margin-top: var(--s5); max-width: 60ch; }
.story p { margin: 0 0 var(--s4); font-size: 16px; line-height: 1.6; color: var(--ink); }
.story p:last-child { margin-bottom: 0; }

/* collapse: a block behind a labeled toggle (details/summary), closed by default. The label is
   the mono label rung in green with a plus that turns to a minus, a 44px tap target; the block
   keeps its own spacing once open. */
details.collapse { margin-top: var(--s6); border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule); }
details.collapse > summary { list-style: none; cursor: pointer; display: flex; align-items: center; justify-content: space-between; gap: var(--s4); min-height: 44px; padding: var(--s4) 0; font-family: var(--font-mono); font-size: 12px; font-weight: 500; text-transform: uppercase; letter-spacing: .14em; color: var(--accent-label, var(--ink-muted)); } /* a 12px label is ink: green at 12px is 3.02:1 */
details.collapse > summary::-webkit-details-marker { display: none; }
details.collapse > summary::after { content: "+"; font-size: 18px; line-height: 1; color: var(--accent-text, var(--accent)); }
details.collapse[open] > summary::after { content: "\2212"; }
details.collapse > .trio { margin-top: 0; padding-bottom: var(--s6); }
/* a whole section's blocks behind the toggle: its first block sits under the label, the toggle closes the space */
details.collapse.section-collapse > .cbody { padding-bottom: var(--s6); }
details.collapse.section-collapse > .cbody > :first-child { margin-top: 0; }

/* faq: questions and answers, each answer closed under its question (details/summary). A row is a 1px
   rule, the question is the entry-title rung at 44px or taller, and the marker is the collapse toggle's
   plus, whose upright bar turns flat into a minus when the answer is open. The disclosure pattern in
   motion.js animates the opening (KNW_ST_MC_Motion-Patterns.md); with no script, the answer just opens. */
.faq { margin-top: var(--s6); max-width: 816px; border-top: 1px solid var(--rule); }
.faq .qa { border-bottom: 1px solid var(--rule); }
.faq .qa > summary { list-style: none; cursor: pointer; display: flex; align-items: center; justify-content: space-between; gap: var(--s5); min-height: 44px; padding: var(--s5) 0; font-family: var(--font-body); font-size: var(--type-entry-title); font-weight: 500; line-height: 1.35; color: var(--ink); -webkit-tap-highlight-color: transparent; }
.faq .qa > summary::-webkit-details-marker { display: none; }
.faq .qa > summary:active { opacity: .85; }
.faq .qm { position: relative; flex: none; width: 16px; height: 16px; color: var(--accent-text, var(--accent)); }
.faq .qm::before, .faq .qm::after { content: ""; position: absolute; left: 0; top: 50%; width: 100%; height: 2px; margin-top: -1px; background: currentColor; }
.faq .qm::after { transform: rotate(90deg); transition: transform var(--motion-turn) var(--motion-ease-out); }
.faq .qa[open]:not(.closing) .qm::after { transform: rotate(0deg); }
.faq .qd { overflow: hidden; transition: height var(--motion-reveal-sharp) var(--motion-ease-out); }
.faq .qa.closing .qd { transition-duration: var(--motion-turn); }
.faq .qd > p { margin: 0; padding: 0 var(--s7) var(--s5) 0; max-width: 60ch; font-size: 16px; line-height: 1.55; color: var(--ink-muted); transition: opacity var(--motion-turn) var(--motion-ease-out) 100ms; } /* motion: allow — the answer follows its row's opening by one beat, choreography as a sibling delay is */
.faq[data-dsc] .qa:not(.shown) .qd > p { opacity: 0; transition: opacity var(--motion-content-out) var(--motion-ease-out); }
/* the question is under 24px, so it stays ink on hover and takes the underline small linked text takes (.etable, .ccard) */
@media (hover: hover) and (pointer: fine) { .faq .qa > summary:hover .qq { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; } }

/* consent: the cookie banner a live site page draws (public/shared/site.js), the same bar as the
   React pages' CookieConsent: the footer's ink, its words at 14px, the two choices at 44px */
.consent { position: fixed; left: 0; right: 0; bottom: 0; z-index: 50; background: var(--ink); border-top: 1px solid var(--footer-line); padding: var(--s5) 0; }
.consent-in { display: flex; flex-direction: column; align-items: flex-start; gap: var(--s4); }
.consent p { margin: 0; max-width: 640px; font-size: 14px; line-height: 1.6; color: var(--footer-line); }
.consent a { color: var(--accent); border-bottom: 1px solid var(--accent); text-decoration: none; }
.consent-btns { display: flex; gap: var(--s3); flex: none; }
.consent button { height: 44px; padding: 0 var(--s5); font-family: var(--font-body); font-size: 15px; font-weight: 500; cursor: pointer; }
.consent-no { background: transparent; color: var(--field); border: 1px solid var(--footer-line); }
@media (hover: hover) and (pointer: fine) { .consent-no:hover { background: var(--field); color: var(--ink); } }
/* the one primary action keeps the accent fill; its words are ink, 6.34:1 (field text on the accent was 2.64:1) */
.consent-yes { background: var(--accent); color: var(--ink); border: 1px solid var(--accent); }
@media (hover: hover) and (pointer: fine) { .consent-yes:hover { background: var(--field); border-color: var(--field); } }
@media (min-width: 768px) { .consent-in { flex-direction: row; align-items: center; justify-content: space-between; gap: var(--s7); } }

/* view · shift — the compare cards as one line each: the aspect, the old way in the muted gray,
   an arrow in green, the new way in ink at 500. Stacked on a phone, one row of four
   from 768px. The words From and To stay for a screen reader. */
.vh { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.shift { margin-top: var(--s6); border-top: 1px solid var(--rule); }
.shift .srow { display: grid; grid-template-columns: 1fr; gap: var(--s2); padding: var(--s3) 0; border-bottom: 1px solid var(--rule-soft); }
.shift .srow .cardhead { margin: 0; }
.shift .sfrom { margin: 0; font-size: 15px; line-height: 1.5; color: var(--ink-muted); }
.shift .sarr { display: none; font-family: var(--font-mono); color: var(--accent-text, var(--accent)); }
.shift .sto { margin: 0; font-size: 15px; line-height: 1.5; color: var(--ink); font-weight: 500; }
@media (min-width: 768px) {
  .shift .srow { grid-template-columns: minmax(200px, 1.1fr) 1.4fr auto 1.4fr; align-items: center; gap: var(--s5); }
  .shift .sarr { display: block; }
}

/* view · versus — Framer's Comparison Table (round two, Oct 25, 2026). On a phone each row is the aspect, then its
   line; with the script, a two-option switch above the rows picks Today or With harperOS, and the two lines
   crossfade in one shared cell, so a row never changes height. With no script both lines show, each under its
   column's name in the label face. From 768px it is a three-column table: the aspect, the old way in the muted
   gray, and the new way in ink at 500 under a 2px accent rule on its column's name. */
.vs { margin-top: var(--s6); }
.vs-seg { display: flex; border: 1px solid var(--rule); margin-bottom: var(--s4); }
.vs-seg[hidden] { display: none; }
.vs-seg button { all: unset; box-sizing: border-box; flex: 1; min-height: 44px; display: flex; align-items: center; justify-content: center; padding: 0 var(--s3); cursor: pointer; font-family: var(--font-mono); font-size: 13px; letter-spacing: 0.02em; color: var(--ink-muted); background: var(--field); transition: background-color var(--motion-hover) var(--motion-ease-out), color var(--motion-hover) var(--motion-ease-out), transform var(--motion-press) var(--motion-ease-out); }
.vs-seg button + button { border-left: 1px solid var(--rule); }
.vs-seg button[aria-pressed="true"] { background: var(--ink); color: var(--field); }
.vs-seg button:active { transform: scale(0.98); }
.vs-seg button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (hover: hover) and (pointer: fine) { .vs-seg button[aria-pressed="false"]:hover { color: var(--ink); } }
.vs-t { width: 100%; border-collapse: collapse; border-top: 1px solid var(--rule); }
.vs-t thead { display: none; }
.vs-t tbody, .vs-t tr { display: block; }
.vs-t tr { display: grid; grid-template-columns: minmax(0, 1fr); row-gap: var(--s2); padding: var(--s3) 0; border-bottom: 1px solid var(--rule-soft); }
.vs-t th[scope="row"] { display: flex; align-items: center; gap: var(--s3); text-align: left; font-size: 15px; font-weight: 600; line-height: 1.4; color: var(--ink); }
.vs-t th[scope="row"] .ico { width: 18px; height: 18px; flex: none; color: var(--ink-muted); }
.vs-t td { display: block; margin: 0; font-size: 15px; line-height: 1.5; }
.vs-t td.vs-from { color: var(--ink-muted); }
.vs-t td.vs-to { color: var(--ink); font-weight: 500; }
/* the new way carries the accent arrow, so the eye lands on it; the labels keep the brand's own casing (harperOS) */
.vs-t td.vs-to::before { content: "\2192\00a0" / ""; font-family: var(--font-mono); font-weight: 400; color: var(--accent-text, var(--accent)); }
.vs:not([data-on]) .vs-t td.vs-to::before { display: none; }
.vs-l { display: block; font-family: var(--font-mono); font-size: 12px; font-weight: 400; line-height: 16px; letter-spacing: 0.02em; color: var(--ink-subtle); }
.vs[data-on] .vs-l { display: none; }
.vs[data-on] .vs-t td { grid-area: 2 / 1; transition: opacity var(--motion-content-out) var(--motion-ease-out), visibility var(--motion-content-out) step-end; }
.vs[data-on][data-show="from"] .vs-t td.vs-to, .vs[data-on][data-show="to"] .vs-t td.vs-from { opacity: 0; visibility: hidden; }
.vs[data-on][data-show="from"] .vs-t td.vs-from, .vs[data-on][data-show="to"] .vs-t td.vs-to { opacity: 1; visibility: visible; transition: opacity var(--motion-content-in) var(--motion-ease-out) var(--motion-content-out), visibility var(--motion-content-out) step-start; }
@media (min-width: 768px) {
  .vs-seg, .vs-seg[hidden] { display: none; }
  .vs-t { display: table; }
  .vs-t thead { display: table-header-group; }
  .vs-t tbody { display: table-row-group; }
  .vs-t tr, .vs[data-on] .vs-t tr { display: table-row; }
  .vs-t th, .vs-t td, .vs[data-on] .vs-t td { display: table-cell; padding: var(--s3) var(--s4) var(--s3) 0; vertical-align: middle; border-bottom: 1px solid var(--rule-soft); opacity: 1; visibility: visible; transition: none; }
  .vs-t thead th { font-family: var(--font-mono); font-size: 12px; font-weight: 400; letter-spacing: 0.02em; text-align: left; color: var(--ink-subtle); padding-top: var(--s3); padding-bottom: var(--s3); border-bottom: 1px solid var(--rule); }
  .vs-t thead th.vs-to { color: var(--ink); border-bottom: 2px solid var(--accent); }
  .vs-t th[scope="row"] { width: 30%; }
  .vs-t td.vs-from { width: 33%; }
  .vs .vs-l { display: none; }
  .vs:not([data-on]) .vs-t td.vs-to::before { display: inline; }
  .vs[data-on][data-show] .vs-t td.vs-from, .vs[data-on][data-show] .vs-t td.vs-to { opacity: 1; visibility: visible; transition: none; }
}
/* the rows change one after another, top to bottom, so the eye follows the change down the table */
.vs[data-on] .vs-t tr:nth-child(2) td { transition-delay: 0.04s; }
.vs[data-on] .vs-t tr:nth-child(3) td { transition-delay: 0.08s; }
.vs[data-on] .vs-t tr:nth-child(4) td { transition-delay: 0.12s; }
.vs[data-on] .vs-t tr:nth-child(5) td { transition-delay: 0.16s; }
.vs[data-on] .vs-t tr:nth-child(6) td { transition-delay: 0.2s; }
@media (min-width: 768px) {
  /* the new way's column takes the alternate field, drawn down row by row as the table arrives */
  .vs-t td.vs-to, .vs[data-on][data-show] .vs-t td.vs-to { background: var(--alt); padding-left: var(--s4); }
  .vs-t thead th.vs-to { padding-left: var(--s4); }
}
@media (min-width: 768px) and (prefers-reduced-motion: no-preference) {
  .anim .motion .vs.seq td.vs-to { background-color: transparent; transition: background-color var(--motion-reveal) var(--motion-ease-out); }
  .anim .motion .vs.seq.in td.vs-to { background-color: var(--alt); }
  .anim .motion .vs.seq tr:nth-child(2) td.vs-to { transition-delay: 0.04s; }
  .anim .motion .vs.seq tr:nth-child(3) td.vs-to { transition-delay: 0.08s; }
  .anim .motion .vs.seq tr:nth-child(4) td.vs-to { transition-delay: 0.12s; }
  .anim .motion .vs.seq tr:nth-child(5) td.vs-to { transition-delay: 0.16s; }
  .anim .motion .vs.seq tr:nth-child(6) td.vs-to { transition-delay: 0.2s; }
}
@media (prefers-reduced-motion: reduce) { .vs[data-on] .vs-t td, .vs-seg button { transition: none; } }

/* view · roster — the function cards as one line each: the function, then its agents in equal
   cells with the agent icon, the muted gray, a soft rule between rows. Stacked on a phone, the
   function above its agents; one line from 768px. */
.roster { margin-top: var(--s6); border-top: 1px solid var(--rule); }
.roster .rrow { display: grid; grid-template-columns: 1fr; gap: var(--s2); padding: var(--s3) 0; border-bottom: 1px solid var(--rule-soft); }
.roster .rrow .cardhead { margin: 0; }
.roster .ragents { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: var(--s4); }
.roster .ragents li { padding-left: 0; display: flex; align-items: center; gap: var(--s2); font-size: 15px; line-height: 1.4; color: var(--ink-muted); }
.roster .ragents li::before { content: none; }
.roster .ragents .ico { width: 16px; height: 16px; flex: none; color: var(--ink-subtle); }
@media (min-width: 768px) {
  .roster .rrow { grid-template-columns: minmax(200px, 1fr) 3fr; align-items: center; gap: var(--s5); }
}

/* a quote with the speaker's photo: the byline's avatar beside the name */
.trio .saidby.withav { display: flex; align-items: center; gap: var(--s3); }
.trio .saidby .avatar { width: 44px; height: 44px; object-fit: cover; display: block; flex: none; }

/* closer: the page's last line and its one action on a single row, the button beside the
   heading from 768px, stacked under it on a phone; tighter than a section */
section.closer, body.site section.closer { padding: var(--s8) 0; }
section.closer > .wrap { display: flex; flex-direction: column; align-items: flex-start; gap: var(--s5); }
section.closer h2 { margin: 0; }
section.closer .ctas { margin: 0; flex: none; }
@media (min-width: 768px) {
  section.closer > .wrap { flex-direction: row; align-items: center; justify-content: space-between; gap: var(--s7); }
}

/* view · org — the functions as a line-drawn org chart: the company node on top, a line down to
   a bar, a line down to each function's node, and under each function a spine with a tick out to
   each agent. Nodes are the only boxes; every line is the 1px rule, drawn orthogonally. Stacked
   on a phone and a tablet, each function keeping its spine; six columns from 1024px. */
.org { margin-top: var(--s6); }
.org .otop { display: flex; justify-content: flex-start; position: relative; padding-bottom: var(--s5); }
.org .otop::after { content: ""; position: absolute; left: var(--s4); bottom: 0; width: 1px; height: var(--s5); background: var(--rule); }
.org .onode { border: 1px solid var(--ink); background: var(--alt); padding: var(--s3) var(--s5); font-size: 15px; font-weight: 500; color: var(--ink); }
/* on a phone and a tablet a trunk runs down the left from the company to every function, a tick
   out to each; it stops at the last function's tick */
.org .ocols { display: grid; grid-template-columns: 1fr; gap: var(--s5); position: relative; margin-left: var(--s4); padding-left: var(--s5); border-left: 1px solid var(--rule); }
.org .ocol { position: relative; }
.org .ocol::before { content: ""; position: absolute; left: calc(-1 * var(--s5)); top: 18px; width: var(--s5); height: 1px; background: var(--rule); }
.org .ocol:last-child::after { content: ""; position: absolute; left: calc(-1 * var(--s5) - 1px); top: 19px; bottom: 0; width: 1px; background: var(--field); }
.org .ofn { display: flex; align-items: center; gap: var(--s2); border: 1px solid var(--rule); background: var(--alt); padding: var(--s2) var(--s3); font-size: 14px; font-weight: 500; line-height: 1.3; color: var(--ink); }
.org .ofn .ico { width: 16px; height: 16px; flex: none; }
.org .oagents { position: relative; gap: 0; margin: 0 0 0 var(--s4); padding: var(--s2) 0 0 var(--s5); border-left: 1px solid var(--rule); }
.org .oagents li { position: relative; padding: var(--s2) 0; font-size: 14px; line-height: 1.35; color: var(--ink-muted); }
.org .oagents li::before { content: ""; position: absolute; left: calc(-1 * var(--s5)); top: calc(var(--s2) + 0.65em); width: var(--s4); height: 1px; background: var(--rule); }
/* the spine stops at the last agent's tick */
.org .oagents li:last-child::after { content: ""; position: absolute; left: calc(-1 * var(--s5) - 1px); top: calc(var(--s2) + 0.65em + 1px); bottom: 0; width: 1px; background: var(--field); }
.org .oagents .ico { display: none; }
/* the columns and the bar follow the number of functions (--n, set by the renderer), so four
   functions draw a bar from the first to the last, never past it (Oct 7, 2026) */
@media (min-width: 1024px) {
  .org .otop { justify-content: center; }
  .org .otop::after { left: 50%; }
  .org .ocols { grid-template-columns: repeat(var(--n, 6), 1fr); gap: 0; padding-top: var(--s5); margin-left: 0; padding-left: 0; border-left: 0; }
  .org .ocol:last-child::after { content: none; }
  .org .ocols::before { content: ""; position: absolute; top: 0; left: calc(100% / (2 * var(--n, 6))); right: calc(100% / (2 * var(--n, 6))); height: 1px; background: var(--rule); }
  .org .ocol { margin: 0 var(--s2); }
  .org .ocol::before { top: calc(-1 * var(--s5)); left: 50%; width: 1px; height: var(--s5); }
}

/* form — a short survey: each question numbered in the mono green, its label in ink at 17px and a
   hint in the subtle gray; answers in the alt field with the soft rule, the accent on focus and on
   a chosen answer; every target 44px. The thank-you takes the form's place once it is sent. */
.form { margin-top: var(--s6); max-width: 680px; }
.form .fq { border: 0; margin: 0 0 var(--s7); padding: 0; min-width: 0; }
.form .fq-l { display: flex; gap: var(--s3); padding: 0; margin-bottom: var(--s4); font-size: 17px; font-weight: 500; line-height: 1.4; color: var(--ink); }
.form .fq-n { font-family: var(--font-mono); font-size: 13px; color: var(--accent-label, var(--ink-muted)); padding-top: 2px; flex: none; } /* a number under 24px: the accent label, never green text */
.form .fq-h { font-family: var(--font-mono); font-weight: 400; font-size: 11px; text-transform: uppercase; letter-spacing: .12em; color: var(--ink-muted); } /* ink-muted: an 11px hint, kept well above the 4.5:1 floor */
.form .fscale { display: flex; flex-wrap: wrap; gap: var(--s2); }
.form .fscale input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.form .fscale span { display: flex; align-items: center; justify-content: center; width: 44px; height: 44px; border: 1px solid var(--rule); background: var(--alt); font-family: var(--font-mono); font-size: 14px; color: var(--ink); cursor: pointer; }
@media (hover: hover) and (pointer: fine) { .form .fscale label:hover span { border-color: var(--accent); } }
.form .fscale input:checked + span { background: var(--accent); border-color: var(--accent); color: var(--field); }
.form .fscale input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 2px; }
.form textarea, .form input[type="text"], .form input[type="email"], .form select { width: 100%; box-sizing: border-box; font-family: var(--font-body); font-size: 15px; line-height: 1.5; color: var(--ink); background: var(--alt); border: 1px solid var(--rule); padding: var(--s3) var(--s4); resize: vertical; }
.form textarea:focus, .form input[type="text"]:focus, .form input[type="email"]:focus, .form select:focus { border-color: var(--accent); } /* the border joins the site's one ring, never replaces it: a 1px border is no ring */
/* a plain form: short labels, tighter rhythm, for a sign-up rather than a survey */
.form.plain .fq { margin-bottom: var(--s5); }
.form.plain .fq-l { font-size: 15px; margin-bottom: var(--s2); }
.form select { min-height: 48px; }
.form .fopts { display: flex; flex-direction: column; gap: var(--s2); }
.form .fopt { display: flex; gap: var(--s3); align-items: flex-start; min-height: 44px; box-sizing: border-box; padding: var(--s3) var(--s4); border: 1px solid var(--rule); background: var(--alt); font-size: 15px; line-height: 1.45; color: var(--ink-muted); cursor: pointer; }
@media (hover: hover) and (pointer: fine) { .form .fopt:hover, .form .fopt:has(input:checked) { border-color: var(--accent); } }
.form .fopt input { margin-top: 4px; accent-color: var(--accent); flex: none; }
.form .fopt strong { color: var(--ink); font-weight: 500; }
.form .fsend { display: flex; flex-direction: column; align-items: flex-start; gap: var(--s3); }
.form .ferr { margin: 0; font-size: 14px; color: var(--ink); }
.form .fstatus { margin: 0; } /* the screen-reader status line (sending, sent, limited); .vh keeps it off screen */
/* the states (public/shared/form.js, KNW_ST_MC_Forms.md): a field that fails carries the error rule on its
   control and its own line under it; the line is ink, never the error color, because the error color on the
   field measures 2.98:1 and text needs 4.5:1. A failed send's line sits under the button with the same rule. */
.form .ferr-f { margin: var(--s2) 0 0; padding-left: var(--s3); border-left: 2px solid var(--status-error); font-size: 14px; line-height: 1.45; color: var(--ink); }
.form .ferr:not([hidden]) { padding-left: var(--s3); border-left: 2px solid var(--status-error); }
.form .fq.invalid textarea, .form .fq.invalid input[type="text"], .form .fq.invalid input[type="email"], .form .fq.invalid input[type="tel"], .form .fq.invalid select,
.form .fq.invalid .fscale span, .form .fq.invalid .fopt { border-color: var(--status-error); }
.form[data-state="sending"] .btn { opacity: .6; cursor: progress; }
.form input[type="tel"] { width: 100%; box-sizing: border-box; font-family: var(--font-body); font-size: 15px; line-height: 1.5; color: var(--ink); background: var(--alt); border: 1px solid var(--rule); padding: var(--s3) var(--s4); }
.form input[type="tel"]:focus { border-color: var(--accent); }
.form .fconsent { color: var(--ink); }
/* the spam trap: clipped to nothing for every person, hidden from screen readers (aria-hidden), out of the tab order,
   still in the markup a script reads; clipped in place, never pushed off-page, so it never widens a phone's viewport */
.form .fhp { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; pointer-events: none; }
.fthanks { margin-top: var(--s6); max-width: 680px; border-left: 2px solid var(--accent); background: var(--alt); padding: var(--s5) var(--s6); }
.fthanks .ft { margin: 0 0 var(--s2); font-family: var(--font-display); font-size: 24px; color: var(--ink); }
.fthanks p { margin: 0; font-size: 16px; line-height: 1.55; color: var(--ink-muted); }

/* a mark is one download: the whole card is the link, its file named with the go-arrow
   (Buttons and links: a whole card that goes somewhere is one link; Law 8) */
.mk .mklink { display: block; color: inherit; text-decoration: none; }
.mk .mklink .swv { display: inline-flex; align-items: center; gap: var(--s2); color: var(--ink); }
.mk .mklink .swv svg { width: 14px; height: 14px; color: var(--accent); }
@media (hover: hover) and (pointer: fine) { .mk .mklink:hover .swv, .mk .mklink:focus-visible .swv { text-decoration: underline; } }

/* ---------- the site, after the Apple-standard review (Oct 3, 2026) ----------
   Graduated from the preview at /staging/next on Oct 3, 2026. A rule still awaiting approval is scoped
   to body.next, which only the preview carries. */
/* one heading scale on the site's marketing pages (MC, Oct 3, 2026), measured against Apple's sentence
   headlines (48-56px), Anthropic (58), Linear (64/48) and Claude (68/49): the title 56px, a section title
   40px, the homepage included. The reading register (essays, training, legal) keeps 48/30. */
body.site:not(.article) header.hero h1 { font-size: var(--type-site-title); line-height: 1.08; }
body.site:not(.article) section h2 { font-size: var(--type-site-section); line-height: 1.15; }
/* a chapter sits inside the part before it, so its title steps down to the h3 role of the type scale
   (clamp 22-28px, design-tokens.json), never near a part's 40px (Oct 6, 2026) */
body.site:not(.article) section.chapter h3 { font-size: var(--type-card-title); line-height: 1.2; }
/* mono marks labels about the page (eyebrows, dates, numbers, file names); what a person reads as
   content is Inter: step titles, people's names and roles, stat descriptions */
body.site .wflow .cardhead .nm { font-family: var(--font-body); font-size: 15px; font-weight: 600; text-transform: none; letter-spacing: 0; line-height: 22px; padding-top: 0; }
body.site .stats .sl { font-family: var(--font-body); font-size: 15px; text-transform: none; letter-spacing: 0; line-height: 1.45; color: var(--ink-muted); }
body.site .trio .said + .saidby { font-family: var(--font-body); font-size: 15px; text-transform: none; letter-spacing: 0; color: var(--ink-muted); }
body.site .card .kick { font-family: var(--font-body); font-size: 15px; text-transform: none; letter-spacing: 0; color: var(--ink-muted); }
body.site .byline .who .role { font-family: var(--font-body); font-size: 14px; text-transform: none; letter-spacing: 0; color: var(--ink-muted); margin-top: 2px; }
/* the footer as a directory: one column per group on a phone, four across from the tablet up */
footer .fcols { margin-top: var(--s6); display: grid; grid-template-columns: 1fr 1fr; gap: var(--s5) var(--s5); }
footer .fcol { display: flex; flex-direction: column; }
footer .fcol .fh { margin: 0 0 var(--s2); font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: .14em; color: var(--footer-conf); }
footer .fcol a { display: inline-flex; align-items: center; min-height: 44px; font-size: 15px; color: var(--footer-line); text-decoration: none; }
@media (hover: hover) and (pointer: fine) { footer .fcol a:hover { color: var(--field); } }
@media (min-width: 768px) { footer .fcols { grid-template-columns: repeat(4, 1fr); } }

/* ---- entries · lead and tabs: the blog index, set in type (the creative director's ruling on three
   designers' options, Oct 12, 2026, measured against anthropic.com/news: one display line, no covers, no
   boxes, the list on hairlines; MC: "so much bold, so much text everywhere") ---- */
.entries.lead { margin-top: var(--s6); border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule); }
.entries.lead .entry { display: block; padding: var(--s7) 0; border: none; color: inherit; }
.entries.lead .entry .ek { margin: 0; }
.entries.lead .entry .et { margin: var(--s3) 0 0; font-family: var(--font-display); font-weight: 400; font-size: var(--type-step); line-height: 1.2; color: var(--ink); max-width: 26em; }
.entries.lead .entry .ex { margin: var(--s3) 0 0; font-size: 18px; line-height: 1.55; color: var(--ink-muted); max-width: 60ch; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.entries.lead .entry .earr { display: block; position: static; margin-top: var(--s5); }
@media (hover: hover) and (pointer: fine) { .entries.lead .entry:hover .et { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 6px; } }

/* the feature row, open: three items under a hairline, never a box, titles medium and never bold (the
   creative director's ruling, Oct 12, 2026, after anthropic.com/news; MC: "we're the only ones using this
   big bold font"). A page opts in with open: true while the boxed row stays live elsewhere. */
.entries.feature.open { gap: var(--s6); }
.entries.feature.open .entry { background: none; border: none; border-top: 1px solid var(--rule); padding: var(--s4) 0 0; }
@media (hover: hover) and (pointer: fine) { .entries.feature.open .entry:hover { border-top-color: var(--ink); } }
.entries.feature.open .entry .et { font-size: var(--type-entry-title); font-weight: 500; line-height: 1.35; }
.entries.feature.open .entry .earr { padding-top: var(--s4); }
.entries.feature.open .entry .ex { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
@media (min-width: 768px) { .entries.feature.open.n3 { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

/* the tabs: the phase-tab idiom the demo block owns (mono capitals, a green rule under the open one) */
.entries.tabs { border-top: none; margin-top: var(--s6); }
.entries.tabs .etr { position: absolute; opacity: 0; width: 1px; height: 1px; pointer-events: none; }
.entries.tabs .etlabels { display: flex; flex-wrap: nowrap; margin: 0; border-bottom: 1px solid var(--rule); }
/* the tabs read as the two categories they are, in the text face at body size (MC, Oct 12, 2026: "SO subtle you can't see it") */
.entries.tabs .etlabels label { flex: 1 1 0; display: flex; align-items: center; justify-content: center; min-height: 48px; padding: var(--s3) var(--s4); margin-bottom: -1px; border-bottom: 2px solid transparent; font-family: var(--font-body); font-size: 17px; font-weight: 500; line-height: 1.3; text-align: center; color: var(--ink-muted); cursor: pointer; }
@media (hover: hover) and (pointer: fine) { .entries.tabs .etlabels label:hover { color: var(--ink); } }
.entry .elab { margin: 0 0 var(--s2); font-family: var(--font-body); font-size: 15px; font-weight: 500; line-height: 1.3; color: var(--ink); }
@media (min-width: 768px) { .entries.tabs .etlabels label { flex: none; padding: var(--s3) var(--s4); white-space: nowrap; } }
.entries.tabs .etpanel { display: none; }
.entries.tabs .etr:nth-of-type(1):checked ~ .etpanel:nth-of-type(1),
.entries.tabs .etr:nth-of-type(2):checked ~ .etpanel:nth-of-type(2),
.entries.tabs .etr:nth-of-type(3):checked ~ .etpanel:nth-of-type(3),
.entries.tabs .etr:nth-of-type(4):checked ~ .etpanel:nth-of-type(4),
.entries.tabs .etr:nth-of-type(5):checked ~ .etpanel:nth-of-type(5),
.entries.tabs .etr:nth-of-type(6):checked ~ .etpanel:nth-of-type(6) { display: block; }
.entries.tabs .etr:nth-of-type(1):checked ~ .etlabels label:nth-of-type(1),
.entries.tabs .etr:nth-of-type(2):checked ~ .etlabels label:nth-of-type(2),
.entries.tabs .etr:nth-of-type(3):checked ~ .etlabels label:nth-of-type(3),
.entries.tabs .etr:nth-of-type(4):checked ~ .etlabels label:nth-of-type(4),
.entries.tabs .etr:nth-of-type(5):checked ~ .etlabels label:nth-of-type(5),
.entries.tabs .etr:nth-of-type(6):checked ~ .etlabels label:nth-of-type(6) { color: var(--ink); border-bottom-color: var(--accent); }
.entries.tabs .etr:nth-of-type(1):focus-visible ~ .etlabels label:nth-of-type(1),
.entries.tabs .etr:nth-of-type(2):focus-visible ~ .etlabels label:nth-of-type(2),
.entries.tabs .etr:nth-of-type(3):focus-visible ~ .etlabels label:nth-of-type(3),
.entries.tabs .etr:nth-of-type(4):focus-visible ~ .etlabels label:nth-of-type(4),
.entries.tabs .etr:nth-of-type(5):focus-visible ~ .etlabels label:nth-of-type(5),
.entries.tabs .etr:nth-of-type(6):focus-visible ~ .etlabels label:nth-of-type(6) { outline: 2px solid var(--accent-text, var(--accent)); outline-offset: 2px; }

/* the list: one row a link on a hairline. On a phone the date and source share a mono line above the
   title; from 768px a row reads date | title | source | arrow */
.entries.tabs .elist { display: block; margin: 0; }
.entries.tabs .erow { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; grid-template-areas: "date src src" "title title arr"; gap: var(--s2) var(--s4); align-items: baseline; min-height: 44px; padding: var(--s4) 0; border-bottom: 1px solid var(--rule); color: inherit; }
.entries.tabs .erow .edate { grid-area: date; }
.entries.tabs .erow .esrc { grid-area: src; }
.entries.tabs .erow .etl { grid-area: title; }
.entries.tabs .erow .earr { grid-area: arr; position: static; align-self: center; width: 18px; height: 18px; }
.entries.tabs .erow .edate, .entries.tabs .erow .esrc { font-family: var(--font-mono); font-size: 12px; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-subtle); }
.entries.tabs .erow .etl { font-size: 17px; line-height: 1.45; color: var(--ink); }
@media (hover: hover) and (pointer: fine) { .entries.tabs .erow:hover .etl { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 4px; } }
@media (min-width: 768px) {
  .entries.tabs .erow { grid-template-columns: 120px minmax(0, 1fr) minmax(0, 200px) 18px; grid-template-areas: "date title src arr"; }
}
.entries.tabs .emore { margin-top: var(--s5); }
.entries.tabs .emore > summary { display: inline-flex; align-items: center; min-height: 44px; padding: 0 var(--s5); border: 1px solid var(--rule); background: var(--alt); font-family: var(--font-mono); font-size: 12px; text-transform: uppercase; letter-spacing: .12em; color: var(--ink); cursor: pointer; list-style: none; }
.entries.tabs .emore > summary::-webkit-details-marker { display: none; }
@media (hover: hover) and (pointer: fine) { .entries.tabs .emore > summary:hover { border-color: var(--ink); } }
.entries.tabs .emore[open] > summary { display: none; }

/* corners: every boxed element takes the theme's radius; harperOS sets 0 (the Square law), another theme may round.
   Square in every theme, by design: tables (data grids); lines (the fan bracket .wfan, the joins .fjoin, the tie .wtie);
   bars (the banner, the nav, the footer); and the note, which is a rule down its left side. */
.card, .entries.feature .entry, .ccard, .continue, .btn, .caveat, .bx, .acard, .op, .price, .enc, .trio .t, .figbox, .wnode, .pshot .pwin, .fnb, .flowv .fnode, .org .onode, .form textarea, .form input[type="text"], .form input[type="email"], .form input[type="tel"], .form select, .consent-yes, .consent-no, .marks .mk, .sw .chip, .org .ofn, .nmark, .consent, .chip, .icn, .state, blockquote.quote, .form .fopt, .entries.tabs .emore > summary, .sw, .pill, .card .photo, .quote.awaiting, nav.ring.site .m-panel, .pbar, .spbar, .mkimg, .form .fscale span { border-radius: var(--radius); }
.cardhead { border-radius: var(--radius) var(--radius) 0 0; }
/* the testimonial blocks take the theme's corner on every box and control they draw */
.tss.tss-boxed, .tss-arrow, .prow-card figure, .prow-arrow, figure.fq, .fq-fig { border-radius: var(--radius); }

/* the design-system site's catalog (public/design-system/sections, scripts/render-section-catalog.mjs): each
   section's variants drawn inside a dashed frame, the options table, and the theme shown live */
.catnav { display: flex; flex-wrap: wrap; gap: var(--s3) var(--s5); margin-top: var(--s6); }
.catnav a { display: inline-flex; align-items: center; min-height: 44px; color: var(--ink); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
.catgroup { border-top: 1px solid var(--rule); }
.catsec { margin-top: var(--s9); }
.catsec + .catsec { padding-top: var(--s8); border-top: 1px solid var(--rule); }
.catvar { margin-top: var(--s7); }
.catvn { margin: 0; font-weight: 600; color: var(--ink); }
.catvk { font-family: var(--font-mono); font-size: 12px; font-weight: 500; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-muted); margin-right: var(--s3); }
.catvd { margin: var(--s2) 0 0; color: var(--ink-muted); }
.catdraw { margin-top: var(--s5); padding: var(--s5) var(--s3); border: 1px dashed var(--rule); border-radius: var(--radius); }
@media (min-width: 768px) { .catdraw { padding: var(--s6) var(--s5); } }
.catdraw > :first-child { margin-top: 0; }
.cathero .hero { padding: 0; background: none; }
.catlab { margin: var(--s7) 0 var(--s4); font-family: var(--font-mono); font-size: 12px; font-weight: 500; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-muted); }
.catnote { margin-top: var(--s5); color: var(--ink-muted); }
.catpart { color: var(--ink-muted); }
.catsws { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s5); }
.catchip { display: block; height: 56px; border: 1px solid var(--rule); border-radius: var(--radius); }
.catcorner { width: 120px; background: var(--alt); }
.catts { margin: 0; font-family: var(--font-display); line-height: 1.15; color: var(--ink); }
.catts.ff-body { font-family: var(--font-body); }
.catts.ff-mono { font-family: var(--font-mono); }
.catsps { display: grid; gap: var(--s3); }
.catsp { display: flex; align-items: center; gap: var(--s4); }
.catbar { display: inline-block; height: 12px; background: var(--accent); }
@media (min-width: 768px) { .catsws { grid-template-columns: repeat(5, minmax(0, 1fr)); } }
.catuse { margin: var(--s4) 0 0; color: var(--ink-muted); }
.catset { margin-top: var(--s4); }
.catpre { margin: 0 0 var(--s5); padding: var(--s4); overflow-x: auto; background: var(--alt); border: 1px solid var(--rule); border-radius: var(--radius); font-family: var(--font-mono); font-size: 12px; line-height: 1.5; color: var(--ink); }
.catkey { margin: var(--s2) 0 0; color: var(--ink-muted); }
.catk { color: var(--ink-muted); }
details.collapse.catset > summary { color: var(--ink-muted); }
/* the finder's links: ink with the accent underline, each row a full tap target (Laws 4, 8 and 11) */
.catfind a { display: inline-flex; align-items: center; min-height: 44px; color: var(--ink); text-decoration: underline; text-decoration-color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: 3px; }
/* the options: each one stacks on a phone (its name, what it sets, then what it takes), a table from the tablet up */
.catopts, .catopts tbody, .catopts tr, .catopts td { display: block; }
.catopts tr.head { display: none; }
.catopts tr { padding: var(--s4) 0; border-bottom: 1px solid var(--rule); }
.catopts td { padding: 0; border: 0; }
.catopts td.catk { display: inline; margin-right: var(--s3); font-size: 14px; }
@media (min-width: 768px) {
  .catopts { display: table; } .catopts tbody { display: table-row-group; } .catopts tr, .catopts tr.head { display: table-row; padding: 0; }
  .catopts td { display: table-cell; padding: var(--s3) var(--s4); border-bottom: 1px solid var(--rule); } .catopts td.catk { display: table-cell; margin: 0; font-size: inherit; }
}

/* ---- Framer parity, round two (Oct 25, 2026) ----
   external-video and external-embed (Framer's YouTube and Embed, loaded on press by public/shared/embed.js), bento-grid
   (Bento Expand, Advanced Bento Grid), sticky-steps (Sticky Scroll), before-after (Before-After Slide), picture-points
   (Picture Points) and line-draw (Animator). Their behavior is the sticky-steps, compare, hotspots and draw patterns in
   motion.js (KNW_ST_MC_Motion-Patterns.md); every value here reads a token. */

/* a third party loaded on press: a box at the frame's size (16:9 for a video, the provider's own shape for a page)
   holding the title, a play mark and the line saying nothing loads before the press; embed.js puts the frame in the
   same box. A poster is a still from this site, under the mark, with the title below it on the field */
.xload { margin: var(--s6) 0 0; max-width: 760px; }
.xload-video { --xa: 16 / 9; }
.xload-press, .xload-frame { position: relative; display: flex; flex-direction: column; justify-content: flex-end; gap: var(--s2); width: 100%; aspect-ratio: var(--xa, 16 / 9); border: 1px solid var(--rule); border-radius: var(--radius); background: var(--alt); padding: var(--s5); color: var(--ink); text-decoration: none; overflow: hidden; }
.xload-frame { display: block; padding: 0; }
/* with no poster the box keeps its frame's shape but grows to hold its words on a phone (at 375 the 16:9 box is
   shorter than the mark, the title and the line); embed.js gives the frame the box's measured height, so nothing
   below moves when it loads */
.xload-press:not(.xload-has-poster) { min-height: min-content; }
/* the mark: a square in the brand's --xload-mark (ink for harperOS) holding the registry icon for what the press
   opens, or a plain square where the icon set has none (a map) */
.xload-mark { width: 56px; height: 56px; margin-bottom: auto; flex: none; display: flex; align-items: center; justify-content: center; background: var(--xload-mark); color: var(--field); border-radius: var(--radius); position: relative; transition: opacity var(--motion-hover) var(--motion-ease-out); }
.xload-mark .xload-ico { width: 24px; height: 24px; color: var(--field); }
.xload-mark-sq::after { content: ""; width: 18px; height: 18px; border: 1px solid var(--field); }
.xload-txt { display: flex; flex-direction: column; gap: var(--s2); position: relative; }
.xload-t { font-family: var(--font-body); font-size: 16px; font-weight: 600; line-height: 1.3; }
.xload-n { font-family: var(--font-mono); font-size: 12px; letter-spacing: 0.02em; color: var(--ink-muted); line-height: 1.5; }
.xload-press[data-asked] .xload-n { color: var(--ink); }
/* with a poster the still fills the box and the mark sits on its centre; the words go under the box, on the field */
.xload-has-poster { display: block; padding: 0; aspect-ratio: auto; border: 0; background: none; overflow: visible; }
.xload-pic { position: relative; display: block; aspect-ratio: var(--xa, 16 / 9); border: 1px solid var(--rule); border-radius: var(--radius); background: var(--field); overflow: hidden; }
.xload-pic picture { display: block; height: 100%; }
.xload-poster { display: block; width: 100%; height: 100%; object-fit: cover; object-position: top left; }
.xload-pic .xload-mark { position: absolute; left: calc(50% - 28px); top: calc(50% - 28px); margin: 0; }
.xload-has-poster .xload-txt { padding-top: var(--s4); }
.xload-played .xload-txt { display: flex; padding-top: var(--s4); }
.xload-press:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (hover: hover) and (pointer: fine) { .xload-press:hover .xload-mark { opacity: .85; } }

/* bento grid: one column on a phone and a tablet; from 1024px three columns, a cell taking one, two or three. A cell is
   its name and line over its product view, which is cropped from the top left at one height per row */
.bnt { margin-top: var(--s6); display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--s4); }
/* every cell is the box (--alt): a brand changes the box, never a cell */
.bnt-cell { display: flex; flex-direction: column; min-width: 0; background: var(--alt); border: 1px solid var(--rule); border-radius: var(--radius); overflow: hidden; color: var(--ink); text-decoration: none; }
.bnt-txt { display: flex; flex-direction: column; gap: var(--s2); padding: var(--s5) var(--s5) var(--s4); }
.bnt-t { font-family: var(--font-body); font-size: 16px; font-weight: 600; line-height: 1.3; }
.bnt-x { font-size: 15px; line-height: 1.5; color: var(--ink-muted); }
/* a linked cell carries the card's go-arrow, which leans as the border wakes (.entry .earr) */
.bnt-arr { width: 20px; height: 20px; margin-top: var(--s1); color: var(--accent-text, var(--accent)); transition: transform var(--motion-turn) var(--motion-ease-out); }
.bnt-shot { display: block; margin: auto var(--s5) 0; border: 1px solid var(--rule); border-bottom: 0; background: var(--field); overflow: hidden; aspect-ratio: 16 / 10; }
.bnt-shot picture { display: block; height: 100%; }
.bnt-img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: top left; }
a.bnt-cell { transition: border-color var(--motion-hover) var(--motion-ease-out); }
a.bnt-cell:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (hover: hover) and (pointer: fine) { a.bnt-cell:hover { border-color: var(--ink-muted); } a.bnt-cell:hover .bnt-arr { transform: translateX(4px); } }
@media (min-width: 1024px) {
  .bnt { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s5); }
  .bnt-s2 { grid-column: span 2; }
  .bnt-s3 { grid-column: span 3; }
  .bnt-shot { aspect-ratio: auto; height: 280px; }
}

/* sticky steps: with no script, under reduced motion and below 1024px each step carries its own picture above its
   words and nothing is held. From 1024px, once the sticky-steps pattern sets data-on, the picture is held beside the
   steps and each step's own picture gives way to it */
.sst { margin-top: var(--s6); }
.sst-steps { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: var(--s7); }
.sst-step { display: flex; flex-direction: column; gap: var(--s2); }
.sst-own { display: block; margin-bottom: var(--s3); border: 1px solid var(--rule); background: var(--field); overflow: hidden; aspect-ratio: 16 / 11; }
.sst-own picture, .sst-shot picture { display: block; height: 100%; }
.sst-img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: top left; }
.sst-n { font-family: var(--font-mono); font-size: 12px; letter-spacing: 0.1em; color: var(--ink-subtle); }
.sst-t { margin: 0; font-family: var(--font-body); font-size: 16px; font-weight: 600; line-height: 1.3; color: var(--ink); }
.sst-x { margin: 0; font-size: 16px; line-height: 1.6; color: var(--ink-muted); max-width: 46ch; }
.sst-pin { display: none; }
@media (min-width: 1024px) {
  .sst[data-on] { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: var(--s8); align-items: start; }
  .sst-visual-left[data-on] .sst-pin { order: -1; }
  .sst[data-on] .sst-own { display: none; }
  .sst[data-on] .sst-steps { gap: 0; }
  /* the step in the middle reads in ink; the others step back to the subtle ink, which still holds 4.5:1 (an opacity
     fade took the line to 2.27:1) */
  .sst[data-on] .sst-step { min-height: 70vh; justify-content: center; }
  .sst[data-on] .sst-n, .sst[data-on] .sst-t, .sst[data-on] .sst-x { color: var(--ink-subtle); transition: color var(--motion-reveal) var(--motion-ease-out); }
  .sst[data-on] .sst-step.on .sst-t { color: var(--ink); }
  .sst[data-on] .sst-step.on .sst-x { color: var(--ink-muted); }
  .sst[data-on] .sst-pin { display: block; position: sticky; top: var(--s9); }
  .sst-stack { position: relative; border: 1px solid var(--rule); background: var(--field); overflow: hidden; aspect-ratio: 16 / 11; }
  .sst-shot { position: absolute; inset: 0; opacity: 0; transition: opacity var(--motion-reveal) var(--motion-ease-out); }
  .sst-shot.on { opacity: 1; }
  .sst[data-scrub] .sst-shot { transition: none; }
  .sst-prog { display: flex; gap: var(--s2); margin-top: var(--s3); }
  .sst-prog[hidden] { display: none; }
  .sst-seg { all: unset; box-sizing: border-box; cursor: pointer; flex: 1; height: 44px; display: flex; align-items: center; }
  .sst-seg::before { content: ""; width: 100%; height: 2px; background: var(--rule); transition: background-color var(--motion-hover) var(--motion-ease-out); }
  .sst-seg[aria-current="step"]::before { background: var(--ink); }
  .sst-seg:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
}
@media (min-width: 1024px) and (hover: hover) and (pointer: fine) { .sst-seg:hover::before { background: var(--ink-muted); } .sst-seg[aria-current="step"]:hover::before { background: var(--ink); } }

/* before and after: with no script the two views stand one under the other, each labelled. Once the compare pattern
   sets data-on they share one frame: the before view is clipped at --pos from the left, the divider and its 44px grip
   sit at --pos, and the native range spans the frame so a drag, a click, a touch or the arrow keys move it */
.bfa { margin: var(--s6) 0 0; max-width: 960px; }
.bfa-frame { position: relative; display: flex; flex-direction: column-reverse; gap: var(--s4); }
.bfa-after, .bfa-before { position: relative; display: block; border: 1px solid var(--rule); background: var(--field); overflow: hidden; }
.bfa-img { display: block; width: 100%; height: auto; }
.bfa-lab { position: absolute; top: var(--s3); padding: var(--s1) var(--s2); background: var(--field); border: 1px solid var(--rule); font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink); }
.bfa-lab-b { left: var(--s3); }
.bfa-lab-a { right: var(--s3); }
.bfa-line, .bfa-range { display: none; }
.bfa[data-on] .bfa-frame { display: block; border: 1px solid var(--rule); overflow: hidden; touch-action: pan-y; }
.bfa[data-on] .bfa-after, .bfa[data-on] .bfa-before { border: 0; }
.bfa[data-on] .bfa-before { position: absolute; inset: 0; clip-path: inset(0 calc(100% - var(--pos, 50%)) 0 0); }
.bfa[data-on] .bfa-line { display: block; position: absolute; top: 0; bottom: 0; left: var(--pos, 50%); width: 1px; margin-left: -0.5px; background: var(--ink); pointer-events: none; }
.bfa-grip { position: absolute; top: 50%; left: -22px; width: 44px; height: 44px; margin-top: -22px; background: var(--field); border: 1px solid var(--ink); }
.bfa-grip::before, .bfa-grip::after { content: ""; position: absolute; top: 15px; border-style: solid; border-width: 6px 7px; border-color: transparent; }
.bfa-grip::before { left: 5px; border-right-color: var(--ink); }
.bfa-grip::after { right: 5px; border-left-color: var(--ink); }
.bfa[data-on] .bfa-range { display: block; position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: ew-resize; touch-action: pan-y; -webkit-appearance: none; appearance: none; background: none; }
/* the whole frame is the target, so the thumb is a sliver: a press lands the divider exactly where it was made */
.bfa-range::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 1px; height: 44px; }
.bfa-range::-moz-range-thumb { width: 1px; height: 44px; border: 0; }
.bfa[data-on] .bfa-frame:has(.bfa-range:focus-visible) .bfa-grip { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (hover: hover) and (pointer: fine) { .bfa[data-on] .bfa-frame:hover .bfa-grip { background: var(--alt); } }

/* picture points: with no script the points link to the numbered notes under the picture. Once the hotspots pattern
   sets data-on, a note is hidden until its point opens it: by its point from 768px, under the picture on a phone */
.ppt { margin: var(--s6) 0 0; max-width: 960px; }
/* the frame holds the picture (with its points) and the notes, so an open note is placed against the picture */
.ppt-frame { position: relative; }
.ppt-pic { position: relative; display: block; border: 1px solid var(--rule); background: var(--field); }
.ppt-img { display: block; width: 100%; height: auto; }
/* a point is a transparent 44px target holding a 28px square, so it covers little of the picture on a phone */
.ppt-dot { position: absolute; left: var(--x, 50%); top: var(--y, 50%); width: 44px; height: 44px; margin: -22px 0 0 -22px; display: flex; align-items: center; justify-content: center; background: transparent; color: var(--ink); text-decoration: none; }
.ppt-sq { position: relative; display: flex; align-items: center; justify-content: center; width: 28px; height: 28px; background: var(--field); border: 1px solid var(--ink); font-family: var(--font-mono); font-size: 11px; line-height: 1; transition: background-color var(--motion-hover) var(--motion-ease-out), color var(--motion-hover) var(--motion-ease-out); }
.ppt-marked .ppt-sq::before, .ppt-marked .ppt-sq::after { content: ""; position: absolute; left: 7px; top: 13px; width: 12px; height: 1px; background: currentColor; }
.ppt-marked .ppt-sq::after { transform: rotate(90deg); }
.ppt-dot[aria-expanded="true"] .ppt-sq { background: var(--ink); color: var(--field); }
/* the ring sits on the target, drawn in close around the square */
.ppt-dot:focus-visible { outline: 2px solid var(--accent); outline-offset: -6px; }
.ppt-notes { margin: var(--s4) 0 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: var(--s3); }
/* the note reads the brand's overlay tokens: plain on the field for harperOS, glass where a brand sets it */
.ppt-note { position: relative; display: flex; gap: var(--s3); align-items: flex-start; padding: var(--s4); border: 1px solid var(--note-rule); background: var(--note-surface); -webkit-backdrop-filter: blur(var(--note-blur)); backdrop-filter: blur(var(--note-blur)); }
.ppt-n { font-family: var(--font-mono); font-size: 12px; line-height: 22px; color: var(--note-ink-muted); }
.ppt-body { display: flex; flex-direction: column; gap: var(--s1); min-width: 0; }
.ppt-t { font-size: 15px; font-weight: 600; line-height: 22px; color: var(--note-ink); }
.ppt-x { font-size: 15px; line-height: 1.5; color: var(--note-ink-muted); }
.ppt-close { all: unset; box-sizing: border-box; flex: none; cursor: pointer; position: relative; width: 44px; height: 44px; margin: calc(-1 * var(--s3)) calc(-1 * var(--s3)) 0 auto; }
.ppt-close::before, .ppt-close::after { content: ""; position: absolute; left: 15px; top: 21px; width: 14px; height: 1px; background: var(--note-ink); transform: rotate(45deg); }
.ppt-close::after { transform: rotate(-45deg); }
.ppt-close:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.ppt[data-on] .ppt-note { display: none; }
.ppt[data-on] .ppt-note.open { display: flex; }
@media (hover: hover) and (pointer: fine) { .ppt-dot:hover .ppt-sq { background: var(--alt); } .ppt-dot[aria-expanded="true"]:hover .ppt-sq { background: var(--ink); } }
@media (min-width: 768px) {
  /* the note opens under its point, or over it in the lower part of the picture, held inside the frame's edges */
  .ppt[data-on] .ppt-notes { position: absolute; inset: 0; margin: 0; pointer-events: none; }
  .ppt[data-on] .ppt-note { z-index: 2; }
  .ppt[data-on] .ppt-note { position: absolute; width: 320px; left: clamp(0px, calc(var(--x, 50%) - 160px), calc(100% - 320px)); top: calc(var(--y, 50%) + 30px); pointer-events: auto; }
  .ppt[data-on] .ppt-note.start { left: clamp(0px, calc(var(--x, 50%) - 22px), calc(100% - 320px)); }
  .ppt[data-on] .ppt-note.end { left: clamp(0px, calc(var(--x, 50%) - 298px), calc(100% - 320px)); }
  .ppt[data-on] .ppt-note.up { top: auto; bottom: calc(100% - var(--y, 50%) + 30px); }
}

/* drawn line: the labels over their steps, the drawing under them at the frame's width. With no script, on the first
   screen and under reduced motion the path is drawn; once the draw pattern sets data-on it waits hidden and draws over
   --motion-layout, linear, when it comes into view; the end mark follows it */
.ld { margin: var(--s6) 0 0; max-width: 760px; }
.ld-art { position: relative; }
.ld-labels { position: relative; height: 22px; margin: 0 0 var(--s2); padding: 0; list-style: none; }
.ld-l { position: absolute; left: var(--lx, 0%); transform: translateX(-50%); white-space: nowrap; font-family: var(--font-mono); font-size: 12px; line-height: 22px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink); }
.ld-l.ld-start { transform: none; }
.ld-l.ld-end-l { transform: translateX(-100%); }
.ld-svg { display: block; width: 100%; height: auto; overflow: visible; }
.ld-path { fill: none; stroke: var(--ink); stroke-width: 1; vector-effect: non-scaling-stroke; }
.ld-node { fill: var(--field); stroke: var(--ink); stroke-width: 1; vector-effect: non-scaling-stroke; }
.ld-end { fill: var(--accent); }
.ld[data-on] .ld-path { stroke-dasharray: 1; stroke-dashoffset: 1; }
.ld[data-on] .ld-end { opacity: 0; }
.ld[data-on].drawn .ld-path { stroke-dashoffset: 0; transition: stroke-dashoffset var(--motion-layout) linear; }
.ld[data-on].drawn .ld-end { opacity: 1; transition: opacity var(--motion-hover) var(--motion-ease-out) var(--motion-layout); }
/* the loop (a brand may switch it off): the drawing erases and draws again without end, and stops for the Pause
   control, for focus inside it, while off screen (motion.js sets data-offscreen) and for reduced motion (WCAG 2.2.2) */
.ld-loop.drawn .ld-path { stroke-dasharray: 1; animation: ld-redraw 6s linear infinite; /* motion: allow ambient loop period, a drawing redrawn about every six seconds */ }
.ld-loop:focus-within .ld-path, .ld-loop[data-offscreen] .ld-path, .ld-loop:has(.ld-pause input:checked) .ld-path { animation-play-state: paused; }
@keyframes ld-redraw { 0%, 60% { stroke-dashoffset: 0; } 75% { stroke-dashoffset: -1; } 75.01% { stroke-dashoffset: 1; } 100% { stroke-dashoffset: 0; } }
.ld-pause { position: relative; display: inline-flex; align-items: center; min-height: 44px; min-width: 44px; margin-top: var(--s3); font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: .1em; color: var(--ink-muted); cursor: pointer; }
.ld-pause input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.ld-pause input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 2px; }
.ld-pause span::before { content: ""; display: inline-block; width: 8px; height: 8px; margin-right: 8px; border: 1px solid currentColor; vertical-align: 1px; }
.ld-pause input:checked + span::before { background: currentColor; }

@media (prefers-reduced-motion: reduce) {
  .xload-mark, .sst-n, .sst-t, .sst-x, .sst-shot, .sst-seg::before, a.bnt-cell, .bnt-arr, .ppt-sq { transition: none; }
  .ld-path, .ld-end { transition: none; animation: none; }
  .ld-pause { display: none; }
}
