/* QuOracle Studios — quoracle.studio. Built by build.ts from site/styles.css + brand/tokens.css. */

/* Type (owner, 2026-08-20): Apercu is the UI and body face, Hipton Sans is display, UPPERCASE only.
   Apercu is three static cuts, not a variable range, so the weights the site asks for are mapped:
   100-450 Regular · 451-650 Medium (takes 500 and the workhorse 600) · 651-900 Bold (takes 700 and 800).
   That keeps 600 and 800 visibly apart, which one shared Bold would flatten. */
@font-face { font-family: "Apercu"; font-style: normal; font-weight: 100 450; font-display: swap; src: url("/assets/fonts/apercu-regular.woff2") format("woff2"); }
@font-face { font-family: "Apercu"; font-style: normal; font-weight: 451 650; font-display: swap; src: url("/assets/fonts/apercu-medium.woff2") format("woff2"); }
@font-face { font-family: "Apercu"; font-style: normal; font-weight: 651 900; font-display: swap; src: url("/assets/fonts/apercu-bold.woff2") format("woff2"); }
@font-face { font-family: "Hipton Sans"; font-style: normal; font-weight: 400; font-display: swap; src: url("/assets/fonts/hipton-sans.woff2") format("woff2"); }

/**
 * QuOracle Studios — brand tokens. The single source of truth.
 *
 * Two tiers, and the split is the whole point:
 *
 *   Tier 1  --quo-*      The brand. Five values, Chapter 02. These ARE QuOracle.
 *                        Every one is an oklch() literal so the artwork pipeline
 *                        can parse them out of this file. Nothing else is.
 *
 *   Tier 2  --background The roles. Every one resolves to a tier-1 value or steps
 *           --primary    off navy. A role may never introduce a new colour: if a
 *           --accent ... value is not derivable from tier 1, it does not belong
 *                        in the brand.
 *
 * Consumers:
 *   - the app, via packages/brand/src/brand.css (adds the Tailwind bridge)
 *   - the artwork pipeline, via packages/artwork/src/tokens.ts (parses tier 1)
 *
 * Change a tier-1 value here and the app, the 35-page brandbook and every social
 * graphic move together on the next build. That is the mechanism that has kept
 * this brand coherent; do not route around it by hand-keying a hex anywhere.
 */

:root {
  /* ---------------------------------------------------------------------
   * TIER 1 — THE BRAND
   * Three primaries, two secondaries. Chapter 02. Hexes are the verified
   * round-trip and are comments, not values: oklch is authoritative.
   * ------------------------------------------------------------------ */

  --quo-navy: oklch(0.1831 0.0309 263.4); /* #0b1220 — the field  */
  --quo-blue: oklch(0.62 0.2 255); /* #0c84fa — the lead   */
  --quo-gold: oklch(0.82 0.16 85); /* #f3ba25 — the call   */
  --quo-white: oklch(1 0 0); /* #ffffff — light+type */
  --quo-black: oklch(0 0 0); /* #000000 — ink        */

  /* ---------------------------------------------------------------------
   * TIER 2 — ROLES
   * ------------------------------------------------------------------ */

  /* Surfaces. Navy is the stage; elevated surfaces step UP from navy and
   * stay in navy's hue family (263.4). They are not neutral greys — Chapter
   * 02 forbids inventing off-palette greys, and a grey ramp under a navy
   * field is what makes an interface read as generic-dark rather than as
   * QuOracle. Chroma tapers slightly as lightness climbs so the steps read
   * as one material lit from above rather than four different blues. */
  --background: var(--quo-navy); /* #0b1220 */
  --card: oklch(0.2331 0.03 263.4); /* #161e2c */
  --muted: oklch(0.2631 0.0285 263.4); /* #1e2533 */
  --secondary: oklch(0.2931 0.027 263.4); /* #252c3a */
  --popover: oklch(0.2331 0.03 263.4); /* = card  */

  /* Type. White on navy is 18.7:1 — the default for everything. */
  --foreground: oklch(0.97 0.005 240);
  --card-foreground: oklch(0.97 0.005 240);
  --popover-foreground: oklch(0.97 0.005 240);
  --secondary-foreground: oklch(0.97 0.005 240);
  --muted-foreground: oklch(0.72 0.01 250); /* 7.6:1 on navy — AAA */

  /* Blue leads: action, links, active states, product tiles.
   * 5.1:1 on navy — AA at large sizes and for UI, never for body copy. */
  --primary: var(--quo-blue);
  --primary-foreground: oklch(0.99 0 0);

  /**
   * The button surface. Brand blue cannot carry a white label: white on
   * #0c84fa is 3.69:1, and a 14px/600 button label is normal text under WCAG
   * 1.4.3, so the bar is 4.5:1. ("Large" means 18.66px bold or 24px regular —
   * no button is.) The product ships that failure today, on the single
   * most-clicked element in every screen.
   *
   * So the SURFACE steps down, not the brand: same hue (255), one lightness
   * step, and the most chroma sRGB actually has at that lightness — which is
   * 0.185, not 0.20. The gamut narrows as blue darkens, and asking for 0.20
   * here silently clips the red channel to -0.0105 and hands back a lie.
   *
   * This introduces no new colour: it is the same derivation the surface ramp
   * uses on navy. --primary stays brand blue for links, large text, product
   * tiles and chart slot 1.
   */
  --primary-strong: oklch(0.56 0.185 255); /* #0072dd — white 4.72:1, AA */

  /* Gold is the call. Rare by rule: under ~15% of any surface, never a large
   * flat fill, and never on white (1.8:1 — it fails). Ink goes on gold. */
  --accent: var(--quo-gold);
  --accent-foreground: var(--quo-black); /* 11.9:1 — the CTA pairing */

  /* Destructive is functional, not brand. It is the one hue outside the
   * palette, and it earns that by never being decorative. */
  --destructive: oklch(0.65 0.22 25);
  --destructive-foreground: oklch(0.99 0 0);

  /** Same story as --primary-strong: white on --destructive is 3.58:1 and
   *  fails. The button surface steps down; the status colour does not move. */
  --destructive-strong: oklch(0.58 0.22 25); /* #df202e — white 4.79:1, AA */

  /* Hairlines. White at low alpha rather than a mixed grey, so they sit on
   * any surface in the ramp without being re-tuned per step. */
  --border: oklch(1 0 0 / 10%);
  --input: oklch(1 0 0 / 14%);
  --ring: oklch(0.62 0.2 255 / 70%);

  /* ---------------------------------------------------------------------
   * CHARTS — the functional palette (chapter 12)
   *
   * Identity and data are different jobs, and this is where chapter 00's "no
   * green/violet" stops applying. That rule governs the BRAND: what QuOracle
   * looks like. A chart has a different problem — six things must stay telling
   * apart, for everyone, and three hues cannot do that. So the categorical ramp
   * extends past the brand palette on purpose.
   *
   * Every slot is computed, not chosen by eye:
   *   - OKLCH L inside 0.48-0.67, the dark-mode categorical band
   *   - chroma >= 0.10 (below it a hue reads as grey and stops encoding)
   *   - strictly inside sRGB — no silent clipping
   *   - adjacent CVD separation dE 32.9 (target 12), tritan 47.3
   *   - all-pairs dE 13.3, also above target
   *   - every slot >= 3:1 against navy
   * Re-check with: bun test, or the dataviz validator against #0b1220.
   *
   * ASSIGN IN ORDER, NEVER CYCLED. Colour follows the entity, not its rank: a
   * filter that drops a series must not repaint the survivors. A 7th series is
   * not a new hue — it folds into "Other", or the chart becomes small multiples.
   *
   * Slots 1-2 are the brand's own two colours, and that is not a compromise:
   * blue-vs-amber measures dE 125.0, the highest separation of any pair here by
   * a distance. The brand gradient is also the most colourblind-safe pairing
   * available, so the common 2-series chart is maximally on-brand AND maximally
   * legible. Taste and the math agreed; that is rare, so it is worth writing down.
   * ------------------------------------------------------------------ */

  --chart-1: oklch(0.62 0.2 255); /* blue   #0c84fa — the brand lead */
  --chart-2: oklch(0.66 0.137 80); /* amber  #be8700 — gold's family */
  --chart-3: oklch(0.65 0.11 205); /* cyan   #08a2af */
  --chart-4: oklch(0.58 0.17 300); /* violet #8b5dce */
  --chart-5: oklch(0.66 0.16 150); /* green  #33ac5a */
  --chart-6: oklch(0.6 0.19 350); /* pink   #cd4290 */

  /**
   * Gold is NOT chart-2, and this is the one thing to understand here.
   *
   * Brand gold is #f3ba25 — OKLCH L 0.819, far above the 0.67 band ceiling. As a
   * series colour it would out-glare every other slot and break the ramp. But
   * that brightness is exactly why it works as the call: chapter 02 says gold is
   * rare and marks the one that matters, which is an EMPHASIS role, not an
   * identity one. So gold never identifies a series. It marks the one bar that
   * is the user's pick, the winning row, the consensus. chart-2 is amber: gold's
   * hue family, stepped down into the band, doing the identity job instead.
   */
  --chart-call: var(--quo-gold);

  /**
   * Reserved. Status is state, never identity — these ship with an icon and a
   * label, never colour alone, and never as "series 7".
   *
   * The product repo had --chart-4 set to oklch(0.65 0.22 25) = #f94144, which
   * is byte-identical to --destructive. Any chart with four series painted its
   * fourth in the error colour. The categorical ramp above contains no red at
   * all, which is what keeps this reserved rather than merely intended.
   */
  --status-critical: var(--destructive);

  /* ---------------------------------------------------------------------
   * GEOMETRY — Chapter 05's fixed measures, as tokens
   * ------------------------------------------------------------------ */

  --radius: 0.625rem;
  /* The tile ratio. Every QuOracle tile — app icon, favicon, mark, product
   * tile — is radius = 0.28 x size. It is a ratio, not a length, so it is
   * unitless here and multiplied at the callsite. */
  --radius-tile-ratio: 0.28;

  /* ---------------------------------------------------------------------
   * TYPE — Chapter 03
   * Inter is the UI and body face; Archivo Black is display, UPPERCASE only.
   * Both faces now run in the product, not just the artwork.
   * ------------------------------------------------------------------ */

  --font-sans: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-display: "Archivo Black", var(--font-sans);
  --tracking-wordmark: -0.02em; /* the QuOracle wordmark, Inter 800 */
  --tracking-eyebrow: 0.12em; /* gold eyebrows, Inter 800 */

  /* ---------------------------------------------------------------------
   * MOTION — Chapter 10
   *
   * Motion only ever does four things: something enters, exits, moves, or
   * celebrates. So there are four easings, one per verb, and a short duration
   * scale — the app should feel quick, not animated. "Simple beats clever"
   * (ch. 00) applies to time as much as to layout.
   *
   * The expressive end is rationed like gold. The spring, the overshoot, the
   * longer beat belong to the CALL — a win, the consensus landing, the reward —
   * and nowhere else. Everywhere else, motion is fast and quiet. Gold is rare;
   * the flourish is rare; it is the same rule, in a different dimension.
   * ------------------------------------------------------------------ */

  /* Durations. Short by design — see the scale, not just the values. */
  --motion-instant: 100ms; /* micro-feedback: a tint, a toggle. Barely there.  */
  --motion-quick: 160ms; /*   the workhorse: state, tabs, tooltips, hovers.     */
  --motion-base: 240ms; /*    enter/exit of larger things: a dialog, a sheet.   */
  --motion-call: 400ms; /*    the reward. Rare, like gold. The win, the call.   */

  /* Easing, one per verb. */
  --ease-enter: cubic-bezier(0.22, 1, 0.36, 1); /*    decisive in, gentle settle */
  --ease-exit: cubic-bezier(0.4, 0, 1, 1); /*         accelerate away, no linger  */
  --ease-move: cubic-bezier(0.4, 0, 0.2, 1); /*       reposition within the frame */
  --ease-call: cubic-bezier(0.34, 1.56, 0.64, 1); /*  the one spring: overshoot   */
}


/* The faces above replace the design system's Inter + Archivo Black (owner, 2026-08-20).
   Overridden here because brand/tokens.css is vendored verbatim; the design system needs
   the same change to stay the source of truth. */
:root { --font-sans: "Apercu", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
        --font-display: "Hipton Sans", var(--font-sans); }

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--background);
  color: var(--foreground);
  font-family: var(--font-sans);
  font-size: 1rem;
  line-height: 1.5;
  font-feature-settings: "cv11", "ss01";
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* Spatial scale: 4 8 12 16 24 32 48 64 96 128 */
:root {
  --s1: 4px; --s2: 8px; --s3: 12px; --s4: 16px; --s5: 24px; --s6: 32px;
  --s7: 48px; --s8: 64px; --s9: 96px; --s10: 128px;
  --measure: 62ch;
  --page-max: 1200px;
  --gutter: clamp(20px, 5vw, 64px);
}

a { color: inherit; text-decoration: none; }
a:focus-visible, button:focus-visible, [tabindex]:focus-visible {
  outline: 2px solid var(--ring); outline-offset: 3px; border-radius: 4px;
}
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
p { margin: 0; }
h1, h2, h3, h4 { margin: 0; font-weight: inherit; }
ul { margin: 0; padding: 0; list-style: none; }
img, svg { display: block; max-width: 100%; }

/* ---- Type roles (ch. 03) ---- */
.eyebrow {
  font-weight: 800; font-size: 0.75rem; letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase; color: var(--quo-gold);
}
.subline { font-weight: 600; font-size: clamp(1.0625rem, 1.5vw, 1.25rem); line-height: 1.4; }
.body { font-weight: 400; max-width: var(--measure); }
.muted { color: var(--muted-foreground); }
.caption { font-weight: 600; font-size: 0.8125rem; color: var(--muted-foreground); }
.wordmark { font-weight: 800; letter-spacing: var(--tracking-wordmark); }
.tnum { font-variant-numeric: tabular-nums; }


/* ---- Marks (ch. 01, 07) ---- */
.mark { display: inline-grid; place-items: center; flex-shrink: 0; }
.mark svg { width: 66%; height: 66%; }
.lockup { display: inline-flex; align-items: center; gap: 10px; }
.lockup .name { display: flex; flex-direction: column; line-height: 1; }
.lockup .name .wordmark { font-size: 1.125rem; }
.lockup .name .studios { font-size: 0.6875rem; opacity: 0.7; letter-spacing: 0.02em; margin-top: 3px; }
.product-lockup { display: inline-flex; align-items: center; gap: 10px; font-weight: 600; letter-spacing: -0.01em; }
.product-lockup .name { display: flex; flex-direction: column; line-height: 1.1; }
.product-lockup .byline { font-size: 0.75rem; font-weight: 400; opacity: 0.65; letter-spacing: 0.01em; }

/* ---- Buttons (ch. 09): ink on gold = the call; white on --primary-strong = default ---- */
.pill {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s2);
  height: 44px; padding: 0 var(--s5); border-radius: 999px;
  font-weight: 800; font-size: 0.875rem; letter-spacing: 0.06em; text-transform: uppercase;
  white-space: nowrap; transition: transform var(--motion-instant) var(--ease-move), background-color var(--motion-instant) linear;
}
.pill.gold { background: var(--accent); color: var(--accent-foreground); }
.pill.gold:hover { background: oklch(0.85 0.16 85); }
.pill.blue { background: var(--primary-strong); color: var(--primary-foreground); }
.pill.blue:hover { background: oklch(0.6 0.185 255); }
.pill.ghost { color: var(--foreground); box-shadow: inset 0 0 0 1.5px var(--input); }
.pill.ghost:hover { box-shadow: inset 0 0 0 1.5px oklch(1 0 0 / 30%); }
.pill:active { transform: scale(0.98); }
.pill.sm { height: 36px; padding: 0 var(--s4); font-size: 0.75rem; }
.link { color: var(--quo-blue); font-weight: 600; }
.link:hover { text-decoration: underline; text-underline-offset: 3px; }


/* ---- The page (F) ---- */
  /* ---- Ink and the call. Paper ground, navy ink, one grid, gold only where there is something to do. ---- */
  :root {
    --paper: oklch(0.985 0.003 263.4);            /* white with a whisper of navy */
    --ink: var(--quo-navy);
    --ink-2: oklch(0.45 0.022 263.4);             /* labels + captions only, 6.9:1 on paper */
    --rule: oklch(0.1831 0.0309 263.4 / 16%);     /* the hairline: navy at 16% */
    --lead: var(--quo-blue);                      /* display-size colour only (3.7:1) */
    --lead-text: var(--primary-strong);           /* links at text size (4.7:1) */
    --lead-deep: oklch(0.48 0.19 255);            /* the hover step for things already blue */
    --gx: clamp(20px, 3vw, 40px);
    --col-gap: clamp(24px, 4vw, 56px);
    --col-gap-wide: clamp(32px, 5.5vw, 80px);
  }
  /* Smooth anchors. Overflow and scroll-behavior live on the same element (html) so the viewport takes both from it. */
  html { overflow-x: clip; scroll-behavior: smooth; }
  @media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
  body { background: var(--paper); color: var(--ink); overflow-x: visible; }
  ::selection { background: var(--quo-gold); color: var(--quo-black); }
  .g { width: min(100% - 2 * var(--gx), 1400px); margin-inline: auto; }

  /* Type scale: 12 · 14 · 16 · 20 · 28 · 44 · poster */
  .t12 { font-size: 0.75rem; }  .t14 { font-size: 0.875rem; }  .t20 { font-size: 1.25rem; line-height: 1.4; }
  .t28 { font-size: 1.75rem; line-height: 1.25; }
  .lab { font-size: 0.75rem; font-weight: 800; letter-spacing: var(--tracking-eyebrow); text-transform: uppercase; color: var(--ink); }
  .lab.soft { color: var(--ink-2); }
  .poster { font-family: var(--font-display); font-weight: 400; text-transform: uppercase; line-height: 0.95; letter-spacing: -0.01em; text-wrap: balance; }
  .poster.h { font-size: clamp(3.25rem, 12.5vw, 10.5rem); }
  .poster.p { font-size: clamp(2.75rem, 9vw, 7.5rem); }
  .dot { display: inline-block; width: 0.16em; height: 0.16em; border-radius: 50%; background: var(--quo-gold); margin-left: 0.05em; vertical-align: 0; transform-origin: center; }
  @media (prefers-reduced-motion: no-preference) { .dot { animation: land var(--motion-call) var(--ease-call) 120ms both; } }
  @keyframes land { from { transform: scale(0); } to { transform: scale(1); } }
  /* Anything clickable: no underline, ever; it turns blue on hover, like the header. */
  a { transition: color var(--motion-instant) linear; }
  a:hover, a:focus-visible { text-decoration: none; }
  .lnk { color: var(--lead-text); font-weight: 600; }
  .lnk:hover, .lnk:focus-visible { color: var(--lead-deep); }
  .status { display: inline-flex; align-items: center; gap: 8px; font-weight: 600; color: var(--ink-2); white-space: nowrap; }
  .status::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--ink-2); }
  .status.live::before { background: oklch(0.66 0.16 150); }    /* leaf green: the brand's computed green (chart-5) */
  .status.early::before { background: oklch(0.7 0.17 55); }     /* orange: early access */
  .status.soon::before { background: var(--quo-blue); }         /* blue: between tournaments, next version coming */
  /* The CTA pill (ch. 04/05): the blue pill with an offset gold ring behind it. On hover the pill settles toward the ring. */
  .pill.call { position: relative; isolation: isolate; background: transparent; }
  .pill.call::after { content: ""; position: absolute; inset: 0; border-radius: 999px; background: var(--primary-strong); z-index: -1; transition: background-color var(--motion-instant) linear; }
  .pill.call::before { content: ""; position: absolute; inset: 0; border-radius: 999px; box-shadow: inset 0 0 0 1.5px var(--quo-gold); transform: translate(6px, 6px); z-index: -2; transition: transform var(--motion-quick) var(--ease-move); }
  .pill.call:hover::after, .pill.call:focus-visible::after { background: oklch(0.6 0.185 255); }
  .pill.call:hover::before, .pill.call:focus-visible::before { transform: translate(4px, 4px); }
  /* Secondary pill: no fill, blue outline; deepens on hover like every other clickable. */
  .pill.outline { color: var(--lead-text); background: transparent; box-shadow: inset 0 0 0 1.5px var(--lead-text); }
  .pill.outline:hover, .pill.outline:focus-visible { color: var(--lead-deep); box-shadow: inset 0 0 0 1.5px var(--lead-deep); }

  /* Masthead: a floating navy island (owner, 2026-08-19, after a reference with a floating pill header; sized down the
     same day: it hugs its content, 52px tall, no CTA). Sticky at --island-top; on the home page the hero runs
     underneath it (negative margin), elsewhere the page starts below. Hairline + soft shadow so it holds on the navy
     artwork and on paper alike; no blur. */
  :root { --island-top: 20px; --island-h: 52px; --island-rest: 48px; }   /* --island-rest: where it sits before you scroll (well inside the hero image); it sticks at --island-top */
  /* Liquid-glass navy (owner, 2026-08-19): translucent navy over a backdrop blur, a light edge on top, so what passes
     underneath shows through softly. Solid navy where backdrop-filter is unsupported. */
  .mast { position: sticky; top: var(--island-top); z-index: 10; width: fit-content; max-width: calc(100% - 2 * var(--gx)); margin: var(--island-top) auto 0; height: var(--island-h); border-radius: 999px; background: var(--ink); color: var(--quo-white); box-shadow: inset 0 1px 0 oklch(1 0 0 / 22%), inset 0 0 0 1px oklch(1 0 0 / 12%), 0 12px 32px -14px oklch(0.1831 0.0309 263.4 / 55%); }
  @supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
    .mast { background: linear-gradient(180deg, oklch(1 0 0 / 7%), oklch(1 0 0 / 0%) 45%), oklch(0.1831 0.0309 263.4 / 72%); -webkit-backdrop-filter: blur(16px) saturate(150%); backdrop-filter: blur(16px) saturate(150%); }
  }
  body[data-home] .mast { margin-top: var(--island-rest); margin-bottom: calc(-1 * (var(--island-rest) + var(--island-h))); }
  .mast .mast-in { height: var(--island-h); padding: 0 26px 0 12px; display: flex; align-items: center; gap: 36px; }
  .mast .mark svg { width: 86%; height: 86%; }
  .mast .lockup .name .wordmark { font-size: 1rem; }
  .mast .lockup .name .studios { font-size: 0.625rem; margin-top: 2px; }
  .mast nav ul { display: flex; gap: 32px; font-size: 0.875rem; font-weight: 600; }
  .mast nav a { color: var(--quo-white); padding-block: 8px; transition: color var(--motion-instant) linear; }
  .mast nav a:hover, .mast nav a:focus-visible { color: var(--quo-blue); }   /* brand blue on navy: 5.1:1 */
  @media (max-width: 720px) { .mast .mast-in { gap: 22px; padding-inline: 10px 20px; } .mast nav ul { gap: 18px; font-size: 0.8125rem; } }
  @media (max-width: 520px) { .mast .lockup .name { display: none; } .mast .mast-in { gap: 14px; padding-inline: 10px 16px; } .mast nav ul { gap: 14px; } }

  /* ---------- The island on a phone (owner, 2026-09-07) ----------
     Five links on one row need 375px of content, and the pill can only be `100% - 40px`, so it fits from a 415px
     viewport up. Below that the right padding goes first and then the last word crosses the pill's edge: -22px at
     393, -25px at 390, -40px at 375, -55px at 360, -95px at 320. So under 420px the island SPLITS: the lockup keeps
     a pill of its own at the left gutter, the button takes a 52px circle at the right, and the five links become a
     panel that drops from the button. The wordmark comes BACK here; it is hidden under 520px above only because the
     five links needed the room, and a circle costs 52px.
     ⚠ This block must stay BELOW the 520px one: `.mast .lockup .name` has the same specificity in both and both
     match on a phone, so with it above, the wordmark stays hidden.
     ⚠ `.mast` gives its navy, blur and shadow to the two children rather than keeping them. That is what lets the
     panel be a plain `left: 0; right: 0` inside a gutter-to-gutter row. Leaving the blur on `.mast` would also make
     it the containing block for any fixed descendant, which is the trap the joined version had to work around. */
  .mburg, .mscrim { display: none; }
  @media (max-width: 420px) {
    .mast { width: calc(100% - 2 * var(--gx)); max-width: none; background: none; box-shadow: none;
            border-radius: 0; -webkit-backdrop-filter: none; backdrop-filter: none; }
    .mast .mast-in { padding: 0; gap: 12px; justify-content: space-between; }
    .mast .lockup .name { display: flex; }

    #lockup, .mburg {
      height: var(--island-h); border-radius: 999px; background: var(--ink);
      box-shadow: inset 0 1px 0 oklch(1 0 0 / 22%), inset 0 0 0 1px oklch(1 0 0 / 12%),
                  0 12px 32px -14px oklch(0.1831 0.0309 263.4 / 55%);
    }
    @supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
      #lockup, .mburg { background: linear-gradient(180deg, oklch(1 0 0 / 7%), oklch(1 0 0 / 0%) 45%), oklch(0.1831 0.0309 263.4 / 72%);
                        -webkit-backdrop-filter: blur(16px) saturate(150%); backdrop-filter: blur(16px) saturate(150%); }
    }
    #lockup { display: flex; align-items: center; padding: 0 22px 0 12px; }

    /* The button. A circle, so its width tracks --island-h and never the glyph inside it. */
    .mburg { display: grid; place-items: center; flex: none; width: var(--island-h); cursor: pointer;
             color: var(--quo-white); transition: transform var(--motion-quick) var(--ease-move); }
    .mburg:active { transform: scale(0.94); }
    .mburg .bars { position: relative; display: block; width: 20px; height: 16px; }
    .mburg i { position: absolute; left: 0; top: calc(50% - 1px); width: 20px; height: 2px; border-radius: 2px;
               background: currentColor; transform: translateY(var(--y)); }
    .mburg i:nth-child(1) { --y: -6px; }
    .mburg i:nth-child(2) { --y: 0px; }
    .mburg i:nth-child(3) { --y: 6px; }

    /* The five links leave the row and become the panel. Same <nav>, same <a>s: nothing is duplicated, so the
       same-anchor handler in app.js and every href keep working. */
    .mast nav {
      position: absolute; top: calc(100% + 10px); left: 0; right: 0; padding: 6px; border-radius: 22px;
      background: linear-gradient(180deg, oklch(1 0 0 / 7%), oklch(1 0 0 / 0%) 45%), oklch(0.1831 0.0309 263.4 / 86%);
      -webkit-backdrop-filter: blur(18px) saturate(150%); backdrop-filter: blur(18px) saturate(150%);
      box-shadow: inset 0 1px 0 oklch(1 0 0 / 22%), inset 0 0 0 1px oklch(1 0 0 / 12%),
                  0 26px 50px -22px oklch(0.1831 0.0309 263.4 / 65%);
      transform-origin: 100% 0; transform: translateY(-8px) scale(0.96); opacity: 0;
      visibility: hidden; pointer-events: none;
      transition: transform var(--motion-base) var(--ease-enter), opacity var(--motion-quick) linear,
                  visibility 0s linear var(--motion-base);
    }
    body.nav-open .mast nav { transform: none; opacity: 1; visibility: visible; pointer-events: auto;
                              transition-delay: 0s, 0s, 0s; }
    .mast nav ul { display: block; font-size: 1rem; }
    .mast nav li { position: relative; }
    .mast nav li + li::before { content: ""; position: absolute; left: 14px; right: 14px; top: 0; height: 1px;
                                background: oklch(1 0 0 / 12%); }
    .mast nav a { display: block; padding: 14px; border-radius: 16px; font-weight: 600;
                  opacity: 0; transform: translateY(-6px);
                  transition: opacity var(--motion-quick) linear, transform var(--motion-base) var(--ease-enter),
                              color var(--motion-instant) linear, background-color var(--motion-instant) linear; }
    .mast nav a:active { background: oklch(1 0 0 / 10%); }
    /* The stagger is nth-child rather than a JS-written --i: the panel is static HTML and should not need script
       to look right. */
    .mast nav li:nth-child(1) { --i: 0; } .mast nav li:nth-child(2) { --i: 1; } .mast nav li:nth-child(3) { --i: 2; }
    .mast nav li:nth-child(4) { --i: 3; } .mast nav li:nth-child(5) { --i: 4; }
    body.nav-open .mast nav a { opacity: 1; transform: none;
                                transition-delay: calc(60ms + var(--i) * 34ms), calc(60ms + var(--i) * 34ms), 0s, 0s; }

    /* The scrim sits under the island, so the two pills and the panel stay lit. */
    .mscrim { display: block; position: fixed; inset: 0; z-index: 8;
              background: oklch(0.1831 0.0309 263.4 / 34%); opacity: 0; visibility: hidden;
              transition: opacity var(--motion-base) linear, visibility 0s linear var(--motion-base); }
    body.nav-open .mscrim { opacity: 1; visibility: visible; transition-delay: 0s, 0s; }

    /* Squash and spring (owner, 2026-09-07, chosen from six treatments in explorations/island.ts): the bars close
       up to the middle with no rotation, then the cross springs past 45 degrees (to 48.9) and settles back on it.
       Timing is per keyframe, accelerating into the squash and springing out of it, so --ease-call is written out:
       a custom property cannot be read from inside a keyframe block. `closing` runs the same keyframes backwards. */
    body.nav-open .mburg i:nth-child(1) { animation: sqTop 440ms forwards; }
    body.nav-open .mburg i:nth-child(2) { animation: sqMid 440ms forwards; }
    body.nav-open .mburg i:nth-child(3) { animation: sqBot 440ms forwards; }
    body.nav-closing .mburg i:nth-child(1) { animation: sqTop 380ms reverse forwards; }
    body.nav-closing .mburg i:nth-child(2) { animation: sqMid 380ms reverse forwards; }
    body.nav-closing .mburg i:nth-child(3) { animation: sqBot 380ms reverse forwards; }
  }
  @keyframes sqTop {
    0%   { transform: translateY(-6px); animation-timing-function: cubic-bezier(0.4, 0, 1, 1); }
    32%  { transform: translateY(-1px); animation-timing-function: cubic-bezier(0.34, 1.56, 0.64, 1); }
    100% { transform: translateY(0) rotate(45deg); }
  }
  @keyframes sqBot {
    0%   { transform: translateY(6px); animation-timing-function: cubic-bezier(0.4, 0, 1, 1); }
    32%  { transform: translateY(1px); animation-timing-function: cubic-bezier(0.34, 1.56, 0.64, 1); }
    100% { transform: translateY(0) rotate(-45deg); }
  }
  @keyframes sqMid {
    0%   { opacity: 1; transform: scaleX(1); }
    32%  { opacity: 1; transform: scaleX(1); }
    62%  { opacity: 0; transform: scaleX(0.1); }
    100% { opacity: 0; transform: scaleX(0.1); }
  }
  @media (prefers-reduced-motion: reduce) {
    .mburg i, .mast nav, .mast nav a, .mscrim { transition-duration: 1ms !important; animation-duration: 1ms !important; }
  }

  /* Hero: the bloom artwork as an inset navy panel filling the first screen (owner reference, 2026-08-19); the
     headline centred in white with its gold full stop, the studio line, one CTA. The artwork is positioned by JS
     (placeBloom) so its radiant call sits exactly on GAME's full stop; without JS it simply covers, centred. */
  .hero-panel { position: relative; isolation: isolate; margin: var(--inset) var(--inset) 0; min-height: calc(100svh - 2 * var(--inset)); border-radius: 22px; overflow: hidden; background: var(--ink); color: var(--quo-white); display: grid; place-items: center; padding: calc(var(--island-top) + var(--island-h) + 40px) var(--gx) 72px; scroll-margin-top: 0; }
  .hero-art { position: absolute; left: 0; top: 0; width: 100%; height: 100%; max-width: none; object-fit: cover; z-index: 0; pointer-events: none; user-select: none; overflow: visible; }   /* overflow: the ribbons run past the artwork's own box, so they reach the panel edge (which clips) and come in from off-screen */
  /* Three voices under the artwork: the poster, the sub-title ("and it's meant to be played with others."), then the
     studio line; one CTA. The sub-title and line fade up as the full stop lands (static under reduced motion / no JS). */
  .hero-stack { position: relative; z-index: 1; display: grid; justify-items: center; text-align: center; gap: clamp(14px, 1.8vw, 20px); max-width: 1100px; }
  .hero-panel .poster.h { color: var(--quo-white); text-shadow: 0 2px 24px oklch(0.1831 0.0309 263.4 / 50%); margin-bottom: clamp(6px, 1.2vw, 14px); }
  .hero-panel .poster.typed .ch.cur::after { background: var(--quo-white); }
  .hero-sub { font-size: clamp(1.25rem, 2.4vw, 2rem); line-height: 1.25; font-weight: 600; letter-spacing: -0.01em; color: var(--quo-white); text-wrap: balance; text-shadow: 0 1px 12px oklch(0.1831 0.0309 263.4 / 45%); }
  .hero-line { font-size: clamp(1rem, 1.35vw, 1.1875rem); line-height: 1.5; font-weight: 500; max-width: 46ch; color: oklch(0.87 0.01 250); text-wrap: balance; }
  .js .hero-stack :is(.hero-sub, .hero-line), .hero-panel.playing .hero-stack :is(.hero-sub, .hero-line) { opacity: 0; transform: translateY(8px); }
  /* The landing sequence (app.js playBloom): before JS takes over, the moving parts of the artwork are held back;
     the field, vignette and blue glow are always there. Reduced motion / no JS: everything simply shows. */
  .js .hero-art :is(.ribbon, .ray, .ring, .glow-gold, .crowd) { opacity: 0; }
  .hero-art :is(.ring, .glow-gold) { transform-box: fill-box; transform-origin: center; }
  .hero-panel.playing.landed .hero-stack :is(.hero-sub, .hero-line) { opacity: 1; transform: none; transition: opacity 560ms var(--ease-move), transform 560ms var(--ease-move); }
  .hero-panel.playing.landed .hero-line { transition-delay: 90ms; }
  .hero-panel.playing.landed .pill { transition-delay: 180ms; }
  .cols { display: grid; gap: 40px var(--col-gap); }
  .cols.c3 { column-gap: var(--col-gap-wide); }
  .cols.c3 { grid-template-columns: repeat(3, 1fr); }
  .cols.c4 { grid-template-columns: repeat(4, 1fr); }
  @media (max-width: 860px) { .cols.c3, .cols.c4 { grid-template-columns: repeat(2, 1fr); } }
  @media (max-width: 520px) { .cols.c3, .cols.c4 { grid-template-columns: 1fr; } }
  .col { position: relative; display: grid; gap: 12px; align-content: start; }
  .col p { max-width: 38ch; }
  .statement { font-size: 1.25rem; line-height: 1.4; font-weight: 600; }
  .col h3 { font-size: 1.25rem; font-weight: 600; line-height: 1.3; }
  .col .txt { font-size: 0.9375rem; line-height: 1.5; }

  /* Sections: no rules anywhere (owner, 2026-08-19: "too many horizontal lines"). The Games section is the model:
     a small label, then the content across the full width; sections separate by air. (Until then each section had a
     solid ink rule and every column a hairline; the labels sat in a side column before that.) */
  /* Sections are inset panels (owner picked this of six treatments, 2026-08-19): the same inset and 22px radius as the
     hero, tinted a few percent toward navy, one below the other with the inset as the gap. Content inside is centred
     and capped at the page width. */
  :root { --inset: clamp(10px, 1.2vw, 16px); --panel: oklch(0.1831 0.0309 263.4 / 4%); }
  .g.sec { position: relative; width: calc(100% - 2 * var(--inset)); max-width: none; margin: 0 var(--inset) var(--inset); padding: clamp(32px, 4.5vw, 64px) var(--gx); background: var(--panel); border-radius: 22px; display: grid; grid-template-columns: minmax(0, 1fr); justify-items: center; gap: 24px; }
  .g.sec > * { width: min(100%, 1400px); }
  .sec > .sec-body { display: grid; gap: 40px; }
  @media (max-width: 860px) { .g.sec { gap: 18px; } }
  .hero-panel + .sec, .phero + .sec { margin-top: var(--inset); }

  /* Games as ruled rows. Columns pack left and align across rows (subgrid); only the action sits at the right edge. */
  .rows { display: grid; grid-template-columns: max-content max-content max-content 1fr; column-gap: var(--col-gap); }
  .row { grid-column: 1 / -1; display: grid; grid-template-columns: subgrid; align-items: center; padding-block: 16px; }
  .row .name { color: var(--ink); }
  .row .pitch { display: grid; gap: 4px; }
  .row .pitch .t14 { color: var(--ink-2); }
  .row .actions { justify-self: end; display: flex; gap: 10px; align-items: center; }
  @media (max-width: 860px) { .rows { grid-template-columns: 1fr 1fr; } .row { row-gap: 12px; } .row .pitch { grid-column: 1 / -1; } .row .status { justify-self: start; } .row .actions { justify-self: end; } }

  .row .product-lockup > .name > span:first-child { transition: color var(--motion-instant) linear; }
  .row .name:hover .product-lockup > .name > span:first-child, .row .name:focus-visible .product-lockup > .name > span:first-child { color: var(--lead-text); }

  /* ---- Games: two product tiles (ch. 07: blue tile = product level). The tile on top carries real screens in
     device frames and the name as a poster; the text sits on paper below. Container units size the devices to the
     tile, so the composition holds at every width. ---- */
  .games { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--col-gap); }
  @media (max-width: 860px) { .games { grid-template-columns: 1fr; } }
  .gcard { display: grid; grid-template-rows: auto 1fr; border: 1px solid var(--rule); border-radius: 12px; overflow: hidden; background: var(--paper); }
  .gvis { position: relative; aspect-ratio: 5 / 3; background: var(--quo-blue); overflow: hidden; isolation: isolate; container-type: inline-size; }
  /* The name sits in a translucent dark pill (owner, 2026-08-19: legibility over the screens). No blur. */
  .gname { position: absolute; left: 3.6cqw; bottom: 3.4cqw; z-index: 3; color: var(--quo-white); font-size: 6.2cqw; line-height: 1; letter-spacing: -0.005em; padding: 0.34em 0.62em 0.3em; border-radius: 999px; background: oklch(0.2 0.02 263.4 / 62%); box-shadow: inset 0 0 0 1px oklch(1 0 0 / 8%); }
  .gname .dot { animation: none; }
  .devs { position: absolute; inset: 0; z-index: 1; }
  .devs figure { position: absolute; margin: 0; }
  .devs img { display: block; width: 100%; height: auto; }
  /* Phones: dark frame, a screen, the island. Both lean the same way, the front one more. */
  .phone { width: 43cqw; padding: 1.9cqw; background: #05070d; border-radius: 8.6cqw; box-shadow: inset 0 0 0 1px oklch(1 0 0 / 16%), 0 12cqw 16cqw -10cqw oklch(0 0 0 / 55%); }
  .phone::before { content: ""; position: absolute; top: 3.5cqw; left: 50%; transform: translateX(-50%); width: 11.5cqw; height: 3.2cqw; border-radius: 999px; background: #000; z-index: 2; }
  .phone img { border-radius: 6.9cqw; }
  .phone.back { left: 7cqw; top: 2cqw; transform: rotate(7deg); z-index: 1; }
  .phone.front { left: 47cqw; top: -12cqw; transform: rotate(14deg); z-index: 2; }
  /* Windows: a navy browser frame with three dots. The front one is the live match; the back one sits up-left. */
  .win { background: var(--quo-navy); border-radius: 1.6cqw; overflow: hidden; box-shadow: 0 0 0 1px oklch(1 0 0 / 18%), 0 12cqw 16cqw -10cqw oklch(0 0 0 / 55%); }
  .win .bar { display: flex; align-items: center; gap: 0.9cqw; height: 3.6cqw; padding-inline: 1.6cqw; background: oklch(0.2331 0.03 263.4); border-bottom: 1px solid oklch(1 0 0 / 8%); }
  .win .bar i { width: 1.25cqw; height: 1.25cqw; border-radius: 50%; background: oklch(1 0 0 / 24%); }
  .win.back { left: -4cqw; top: 0; width: 62cqw; z-index: 1; }
  .win.front { left: 42cqw; top: 14cqw; width: 78cqw; z-index: 2; }
  /* Text on paper: kicker, the line, the pitch, four things you do, status + actions. */
  /* Three across once there is a tool beside the two games; two, then one, as it narrows.
     Higher specificity than the plain .games rules, so both breakpoints have to be restated. */
  .games.three { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  @media (max-width: 1180px) { .games.three { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
  @media (max-width: 860px) { .games.three { grid-template-columns: 1fr; } }

  /* Blueline's own chrome, drawn rather than captured: on the brand blue there is no page behind
     the rail to photograph. Sized in cqw off the tile like the device frames above, from the real
     values in quoracle-blueline/toolbar/src (panel 320, rail 52, buttons 40, radii 20/22/12).
     The surfaces are rgba(255,255,255,0.97), blueline's own no-backdrop-filter fallback: a flat
     ground gives the blur nothing to sample, so a translucent panel there is a wash, not glass. */
  .blv { position: absolute; inset: 0; z-index: 1; color: var(--quo-navy); }
  .blv .bl-panel, .blv .bl-rail { position: absolute; background: oklch(1 0 0 / 97%);
    box-shadow: inset 0 1px 0 oklch(1 0 0 / 95%), inset 0 0 0 1px oklch(0.1831 0.0309 263.4 / 10%),
                0 4.2cqw 10.2cqw -4.2cqw oklch(0.1831 0.0309 263.4 / 55%); }
  .blv .bl-panel { left: 5.35cqw; top: 3.5cqw; width: 74.42cqw; border-radius: 4.65cqw; overflow: hidden; }
  .blv .bl-head { display: flex; align-items: baseline; gap: 1.86cqw; padding: 2.56cqw 3.72cqw 1.4cqw;
    font-family: var(--font-display); text-transform: uppercase; font-size: 2.44cqw; letter-spacing: 0.09em; }
  .blv .bl-path { color: oklch(0.1831 0.0309 263.4 / 45%); }
  .blv .bl-rows { padding: 0 1.86cqw 0.93cqw; }
  .blv .bl-row { display: flex; align-items: flex-start; gap: 2.56cqw; padding: 1.86cqw 2.33cqw; border-radius: 2.79cqw; }
  .blv .bl-row.on { background: oklch(0.62 0.2 255 / 8%); }
  .blv .bl-chip { flex: none; width: 4.88cqw; height: 4.88cqw; margin-top: 0.23cqw; border-radius: 999px;
    display: grid; place-items: center; color: #fff; font-size: 2.56cqw; font-weight: 600;
    font-variant-numeric: tabular-nums; background: var(--quo-blue);
    box-shadow: 0 0.47cqw 1.4cqw -0.47cqw oklch(0.1831 0.0309 263.4 / 50%); }
  .blv .bl-txt { min-width: 0; }
  .blv .bl-el { display: block; margin-bottom: 0.7cqw; font-family: var(--font-display); text-transform: uppercase;
    font-size: 2.33cqw; letter-spacing: 0.08em; color: oklch(0.1831 0.0309 263.4 / 50%);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .blv .bl-cm { display: block; font-size: 3.02cqw; line-height: 1.42; }
  /* Bottom-anchored, and short enough that its top corners are inside the frame. */
  .blv .bl-rail { right: 5.35cqw; bottom: 3.72cqw; width: 12.09cqw; border-radius: 5.12cqw; padding: 1.4cqw;
    display: flex; flex-direction: column; align-items: center; gap: 0.47cqw; }
  .blv .bl-btn { width: 9.3cqw; height: 9.3cqw; border-radius: 2.79cqw; display: grid; place-items: center;
    color: oklch(0.1831 0.0309 263.4 / 72%); }
  .blv .bl-btn svg { width: 4.19cqw; height: 4.19cqw; }
  .blv .bl-btn.on { color: #fff; background: var(--quo-navy); }
  .blv .bl-btn.send { color: #fff; background: var(--quo-blue); box-shadow: 0 0 0 0.47cqw var(--quo-gold); }

  .gtxt { padding: 24px 28px 22px; display: flex; flex-direction: column; gap: 10px; }
  .gline { font-size: 1.375rem; line-height: 1.25; font-weight: 600; letter-spacing: -0.01em; text-wrap: balance; }
  .gdesc { font-size: 0.9375rem; line-height: 1.5; max-width: 48ch; }
  .chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 4px; margin-bottom: 14px; }
  .chips li { font-size: 0.75rem; font-weight: 600; line-height: 1; color: var(--ink-2); border: 1px solid var(--rule); border-radius: 999px; padding: 6px 10px; white-space: nowrap; }
  .gfoot { margin-top: auto; padding-top: 16px; border-top: 1px solid var(--rule); display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
  .gfoot .actions { display: flex; gap: 10px; align-items: center; }
  @media (max-width: 480px) { .gtxt { padding: 18px 18px 16px; } .gline { font-size: 1.25rem; } }

  /* Steps as numbered rows (a real sequence). */
  .seq-row { display: grid; grid-template-columns: 3rem minmax(120px, 2fr) 7fr; gap: var(--col-gap); align-items: baseline; padding-block: 14px; }
  .seq-row .k { font-weight: 800; font-size: 1.125rem; line-height: 1; color: var(--lead-text); font-variant-numeric: tabular-nums; }
  .seq-row h3 { font-size: 1.125rem; font-weight: 600; }
  @media (max-width: 520px) { .seq-row { grid-template-columns: 3rem 1fr; } .seq-row p { grid-column: 2; } }

  .two { display: grid; grid-template-columns: 1fr 1fr; gap: 40px var(--col-gap-wide); }
  @media (max-width: 720px) { .two { grid-template-columns: 1fr; } }
  .sec { scroll-margin-top: calc(var(--island-top) + var(--island-h) + 16px); }

  /* Founders: photo frame + name, role, snippet. Two across. */
  .founders { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 40px var(--col-gap-wide); }
  @media (max-width: 720px) { .founders { grid-template-columns: 1fr; } }
  .founder { position: relative; display: grid; grid-template-columns: 168px 1fr; gap: 24px; align-items: start; }
  @media (max-width: 480px) { .founder { grid-template-columns: 1fr; } }
  .founder .photo { aspect-ratio: 1; border-radius: 50%; background: oklch(0.1831 0.0309 263.4 / 5%); border: 1px solid var(--rule); display: grid; place-items: center; overflow: hidden; }
  .founder .photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
  .founder .photo .init { font-weight: 800; letter-spacing: 0.06em; color: var(--ink-2); font-size: 1.25rem; }
  .founder .who { display: grid; gap: 6px; }
  .founder h3 { font-size: 1.25rem; font-weight: 600; line-height: 1.3; }
  .founder .role { color: var(--ink-2); font-size: 0.875rem; font-weight: 600; }
  .founder .bio { font-size: 0.9375rem; line-height: 1.5; margin-top: 6px; max-width: 34ch; }
  .founder .mail { color: var(--lead-text); font-weight: 600; width: fit-content; margin-top: 4px; }
  .founder .mail:hover, .founder .mail:focus-visible { color: var(--lead-deep); }

  /* Contact: its own section, one line each. */
  .contact { display: grid; gap: 10px; }
  .contact .email { font-size: 1.25rem; font-weight: 600; color: var(--lead-text); width: fit-content; }
  .contact .links { display: flex; gap: 32px; flex-wrap: wrap; }
  .contact .links a { color: var(--ink); font-weight: 600; display: inline-flex; align-items: center; gap: 8px; }
  .contact .links svg { flex-shrink: 0; }
  .contact .links a:hover, .contact .links a:focus-visible { color: var(--lead-text); }
  .contact .email:hover, .contact .email:focus-visible { color: var(--lead-deep); }

  /* Product page */
  .back { color: var(--ink-2); font-size: 0.875rem; font-weight: 600; }
  .back:hover, .back:focus-visible { color: var(--lead-text); }
  .phero { padding-block: clamp(32px, 5vw, 56px) clamp(48px, 6vw, 88px); display: grid; gap: clamp(32px, 5vw, 56px); }
  .phero .lede { display: grid; grid-template-columns: repeat(12, 1fr); gap: var(--col-gap); align-items: end; }
  .phero .lede p { grid-column: 1 / span 7; }
  .phero .lede .act { grid-column: 9 / -1; display: flex; gap: 16px; align-items: center; justify-content: flex-end; flex-wrap: wrap; }
  /* With no action to take (a tool has nothing to sign up to) the block is a status line, not a
     call: it belongs under the paragraph, not stranded in the right-hand column. */
  .phero .lede .act.bare { grid-column: 1 / -1; justify-content: flex-start; margin-top: 4px; }
  @media (max-width: 860px) { .phero .lede p, .phero .lede .act { grid-column: 1 / -1; } .phero .lede .act { justify-content: flex-start; } }

  /* Footer */
  .foot { padding-block: 32px 56px; display: flex; align-items: center; justify-content: space-between; gap: 24px; flex-wrap: wrap; }
  .foot .legal { display: flex; gap: 20px; flex-wrap: wrap; font-size: 0.875rem; color: var(--ink-2); }
  .foot .legal a:hover, .foot .legal a:focus-visible { color: var(--lead-text); }
  .foot .tick { width: 48px; }

  /* Beliefs: a lead line, then four ruled columns, each with its brandbook shape and a poster-size title. */
  .belief { gap: 14px; }
  .belief .shape { display: block; width: 40px; height: 40px; margin-bottom: 4px; color: var(--ink); }
  .belief .shape.blue { color: var(--quo-blue); }
  .belief .shape.gold { color: var(--quo-gold); }
  .belief .shape.violet { color: oklch(0.58 0.17 300); }  /* the brand's violet (chart-4) */
  .belief .shape.green { color: oklch(0.55 0.13 150); }   /* evergreen */
  .belief .shape svg { width: 100%; height: 100%; }
  .belief h3.poster.b { font-size: clamp(1.25rem, 1.75vw, 1.625rem); line-height: 1.02; letter-spacing: -0.01em; text-wrap: balance; }
  .belief .txt { max-width: 30ch; }

  /* Beliefs (2026-08-19): Mission and Vision as two statements, then the four beliefs as numbered rows. No icons, no lines. */
  .cols.c2 { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--col-gap-wide); }
  @media (max-width: 720px) { .cols.c2 { grid-template-columns: 1fr; } }
  .statement.lg { font-size: clamp(1.375rem, 2vw, 1.75rem); line-height: 1.3; max-width: 26ch; }
  .creed { display: grid; gap: clamp(14px, 2vw, 22px); }
  #beliefs .sec-body { gap: clamp(48px, 5.5vw, 80px); }   /* more air between Mission/Vision and the values (owner) */
  #beliefs .creed { grid-auto-rows: 1fr; row-gap: clamp(8px, 1.4vw, 16px); }   /* the four values sit at even intervals whatever wraps */
  #beliefs .creed-row p { max-width: 44ch; }
  .creed-row { display: grid; grid-template-columns: 3.5rem minmax(140px, 2fr) 7fr; gap: var(--col-gap); align-items: baseline; }
  .creed-row .k { font-weight: 800; font-size: 1.125rem; line-height: 1; color: var(--lead-text); font-variant-numeric: tabular-nums; }
  .creed-row .k.when { font-size: 0.75rem; letter-spacing: var(--tracking-eyebrow); text-transform: uppercase; color: var(--ink-2); line-height: 1.4; }
  .creed-row h3 { font-size: 1.25rem; font-weight: 600; line-height: 1.3; }
  .creed-row p { font-size: 0.9375rem; line-height: 1.5; max-width: 52ch; }
  .mile .creed-row { grid-template-columns: 6.5rem minmax(150px, 1.7fr) 2.6fr; }
  .mile .creed-row h3 { font-size: 1.125rem; }
  @media (max-width: 640px) { .creed-row { grid-template-columns: 3.5rem 1fr; } .creed-row p { grid-column: 2; } .mile .creed-row { grid-template-columns: 6.5rem 1fr; } .mile .creed-row p { grid-column: 2; } }

  /* Numbers: big figures in the display face, a small label under each; the home strip is four across. */
  .fig { display: grid; gap: 6px; align-content: start; }
  .num { font-family: var(--font-display); font-size: clamp(2.5rem, 4.6vw, 4.25rem); line-height: 0.95; letter-spacing: -0.01em; color: var(--ink); font-variant-numeric: tabular-nums; }
  .fig-d { font-size: 0.875rem; line-height: 1.45; color: var(--ink-2); max-width: 30ch; }
  /* ---- The arc: three panels of Footie Predict's first tournament (owner, 2026-08-20). The charts are
     server-rendered SVG, so the drawn state IS the page. JS only adds the reveal and, on /numbers, the
     scrub. Everything below degrades to the finished picture when either is missing. ---- */
  .arc { display: grid; gap: 22px; }
  .arc-head { display: grid; gap: 8px; max-width: 68ch; }
  .arc-row { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--col-gap); }
  /* The three panels share their row tracks, so a title that wraps to two lines in one panel cannot
     push its figure and chart out of line with the other two. Without subgrid they simply sit as they
     fall, which is the old behaviour rather than a broken one. */
  @supports (grid-template-rows: subgrid) {
    .arc-row { grid-template-rows: repeat(7, auto); }
    .acard { grid-row: span 7; grid-template-rows: subgrid; }
  }
  .acard { display: grid; gap: 8px; align-content: start; padding: 22px 24px 24px; background: var(--quo-white); border: 1px solid var(--rule); border-radius: 12px; }
  .acard h4 { font-weight: 600; }
  .acard-n { display: flex; align-items: baseline; gap: 8px; }
  .acard .num { font-size: clamp(1.75rem, 2.8vw, 2.5rem); }
  .acard figcaption { line-height: 1.55; }
  /* One insight per chart, set above the supporting caption and marked with the gold call. */
  .aha { font-weight: 600; line-height: 1.45; padding-left: 14px; border-left: 3px solid var(--quo-gold); }
  .abig .aha { max-width: 62ch; margin-top: 4px; }
  /* The inner box is inset so the gold end marker, which always lands on the top right corner of a
     cumulative series, sits inside the panel instead of hanging off it. */
  .ac-plot { height: 98px; margin: 6px 0 4px; padding: 6px 7px 0 0; }
  /* Every chart stands on a baseline, so a line or a bar has a floor instead of floating. */
  .ac-inner { position: relative; display: block; height: 100%; border-bottom: 1px solid var(--rule); }
  .ac-axis { display: flex; justify-content: space-between; margin-top: 2px; }
  .ac-svg { width: 100%; height: 100%; overflow: visible; }
  .ac-line { fill: none; stroke: var(--quo-blue); stroke-width: 2; vector-effect: non-scaling-stroke; stroke-linejoin: round; stroke-linecap: round; }
  .ac-area { fill: var(--quo-blue); opacity: 0.10; }
  .ac-dot { position: absolute; width: 9px; height: 9px; margin: -4.5px 0 0 -4.5px; border-radius: 50%; background: var(--quo-gold); }
  .ac-bar { fill: var(--quo-blue); opacity: 0.85; }
  .arc-soon { padding: 16px 18px; border: 1px dashed var(--rule); border-radius: 12px; max-width: 62ch; }
  @media (max-width: 900px) { .arc-row { grid-template-columns: 1fr; } }

  /* The reveal. app.js marks the cards itself rather than leaning on html.js, which only exists on the
     home page and clears itself after 2.5s. The panels sit well below the fold, so marking them from
     script is invisible in practice, and a browser without JS simply never hides them. Panels stagger
     left to right, the order the story is read in. */
  @media (prefers-reduced-motion: no-preference) {
    .acard.pre { opacity: 0; transform: translateY(12px); }
    .acard.pre.in { opacity: 1; transform: none; transition: opacity 520ms var(--ease-call) calc(var(--i) * 140ms), transform 520ms var(--ease-call) calc(var(--i) * 140ms); }
    .acard.pre .ac-svg.line { clip-path: inset(0 100% 0 0); }
    .acard.pre.in .ac-svg.line { clip-path: inset(0 0 0 0); transition: clip-path 1100ms cubic-bezier(0.33, 1, 0.68, 1) calc(var(--i) * 140ms + 180ms); }
    .acard.pre .ac-dot { opacity: 0; }
    .acard.pre.in .ac-dot { opacity: 1; transition: opacity 320ms var(--ease-call) calc(var(--i) * 140ms + 1150ms); }
    .acard.pre .ac-bar { transform: scaleY(0); transform-origin: 50% 100%; }
    .acard.pre.in .ac-bar { transform: none; transition: transform 520ms var(--ease-call) calc(var(--i) * 140ms + var(--bi, 0) * 55ms); }
  }

  /* /numbers: the same three series, drawn large, one block each, with a scrub. */
  .abigs { display: grid; gap: 28px; }
  .abig { display: grid; gap: 10px; padding: 26px 28px 28px; background: var(--quo-white); border: 1px solid var(--rule); border-radius: 12px; }
  .abig-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px 16px; }
  .abig-head h3 { font-weight: 600; margin-right: auto; }
  .abig-n { display: flex; align-items: baseline; gap: 8px; }
  .abig .num { font-size: clamp(2rem, 3.4vw, 3rem); }
  .abig-plot { height: 220px; padding: 8px 8px 0 0; }
  .abig-plot:focus-visible { outline: 2px solid var(--quo-blue); outline-offset: 6px; border-radius: 6px; }
  .abig-axis { display: flex; justify-content: space-between; }
  .abig-read { min-height: 1.5em; font-weight: 600; }
  .abig figcaption { max-width: 70ch; line-height: 1.55; }
  @media (max-width: 700px) { .abig { padding: 20px 18px 22px; } .abig-plot { height: 170px; } }

  /* The scrub guide and the milestone pins ride on top of the stretched plot, so both are plain
     elements positioned by percentage rather than anything drawn inside the SVG. */
  .ab-guide { position: absolute; top: 0; bottom: 0; width: 1px; background: var(--quo-blue); opacity: 0.45; pointer-events: none; }
  .ab-guide::after { content: ""; position: absolute; left: 50%; width: 9px; height: 9px; margin: -4.5px 0 0 -4.5px; border-radius: 50%; background: var(--quo-blue); top: var(--gy, 0%); }
  .ab-mark { position: absolute; top: 0; bottom: 0; width: 0; border-left: 1px dashed color-mix(in srgb, var(--ink) 38%, transparent); pointer-events: none; }
  /* The labels sit in their own band above the plot. Inside the chart only the dashed line survives, so
     a label can never print over a bar. Each label is a row lower than the one before it. */
  .ab-marks { position: relative; height: calc(var(--rows, 1) * 22px); }
  .ab-marks .ab-mark-t { position: absolute; top: calc(var(--mi, 0) * 22px); }
  /* Two milestones four days apart would print their labels on top of each other, so each sits a row
     lower than the last, and one near the right edge hangs its label to the left of its pin. */
  .ab-mark-t { white-space: nowrap; font-weight: 600; color: var(--ink-2); padding-left: 7px; border-left: 1px dashed color-mix(in srgb, var(--ink) 38%, transparent); }
  .ab-mark-t.flip { transform: translateX(-100%); padding: 0 7px 0 0; border-left: 0; border-right: 1px dashed color-mix(in srgb, var(--ink) 38%, transparent); }
  @media (max-width: 700px) { .ab-mark-t { display: none; } }

  .strip { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 32px var(--col-gap); }
  @media (max-width: 860px) { .strip { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
  .figs { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 36px var(--col-gap); }
  @media (max-width: 860px) { .figs { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
  @media (max-width: 480px) { .figs { grid-template-columns: 1fr; } .strip { gap: 24px 20px; } }
  .more { font-size: 1rem; }
  .lnk.arrow::after { content: " →"; }
  .tag { display: inline-block; margin-left: 10px; padding: 3px 8px; border-radius: 999px; font-size: 0.6875rem; letter-spacing: 0.06em; color: var(--ink-2); box-shadow: inset 0 0 0 1px var(--rule); vertical-align: middle; }
  .nlead { display: grid; gap: 16px; }
  .nlead .t20 { max-width: 56ch; }
  .mile, .learn { display: grid; gap: 18px; align-content: start; }
  .insights { display: grid; gap: 20px; }
  .insight { display: grid; gap: 6px; }
  .insight h3 { font-size: 1.25rem; font-weight: 600; line-height: 1.3; }
  .insight p { font-size: 0.9375rem; line-height: 1.5; max-width: 48ch; }
  .phero > .lab + .poster { margin-top: -8px; }

  /* Founder cards: the Profile button; founder pages: big circular photo beside the name. */
  .founder .factions { margin-top: 10px; }
  .fhead { display: grid; grid-template-columns: clamp(160px, 18vw, 240px) minmax(0, 1fr); gap: var(--col-gap-wide); align-items: center; }
  .fhead .photo.lg { aspect-ratio: 1; border-radius: 50%; overflow: hidden; border: 1px solid var(--rule); background: oklch(0.1831 0.0309 263.4 / 5%); }
  .fhead .photo.lg img { width: 100%; height: 100%; object-fit: cover; display: block; }
  .fhead .stack { display: grid; gap: 24px; }
  .fhead .act { display: flex; gap: 12px; flex-wrap: wrap; }
  @media (max-width: 720px) { .fhead { grid-template-columns: 1fr; } .fhead .photo.lg { width: 160px; } }
  .phero .fhead .poster.p { font-size: clamp(2.5rem, 7.5vw, 6rem); }

  /* Founder pages: dated rows (experience, football, education) share the creed grid; a wider date column. Rows are
     evenly spaced and a rail with rounded tips runs down the logo column between them: a timeline (owner, 2026-08-19). */
  .frows { --rowgap: 30px; gap: var(--rowgap); }
  .frows .creed-row { grid-template-columns: 7rem minmax(180px, 1.4fr) 3fr; align-items: start; position: relative; }
  .frows:has(.has-logo) .frow:not(:last-child)::after { content: ""; position: absolute; left: calc(7rem + var(--col-gap) + 22px - 1.5px); top: 52px; bottom: calc(-1 * var(--rowgap) + 8px); width: 3px; border-radius: 999px; background: oklch(0.1831 0.0309 263.4 / 16%); }
  .frows .fr { display: grid; gap: 2px; }
  .frows .has-logo .fr { grid-template-columns: 44px minmax(0, 1fr); gap: 12px; align-items: start; }
  .frows .flogo { width: 44px; height: 44px; border-radius: 10px; background: var(--quo-white); box-shadow: inset 0 0 0 1px var(--rule); display: grid; place-items: center; overflow: hidden; }
  .frows .flogo img { width: 34px; height: 34px; object-fit: contain; display: block; }
  .frows .flogo.navy { background: var(--ink); box-shadow: none; }
  /* A list can mix rows that carry a logo with rows that do not (Quentin's, until his logos arrive).
     The ones without keep the 44px slot empty so every title starts on the same left edge, and the
     rail above runs past them instead of stopping. */
  .frows:has(.has-logo) .frow:not(.has-logo) .fr { padding-left: 56px; }
  .frows .frt { display: grid; gap: 2px; }
  .frows .fr h3 { font-size: 1.125rem; }
  .frows .where { font-size: 0.875rem; color: var(--ink-2); font-weight: 600; }
  .frows p { max-width: 62ch; }
  /* The awards badge wall (owner, 2026-09-04). The one place on a founder page that uses cards, and it earns them:
     each badge is a single link to that award's public record, so it has to read as one object you can press. Cards
     stretch to a common height (the grid stretches, the card is a column, the credit takes the leftover space with
     margin-top: auto) so the credited role sits on one line across a row however the categories wrap. No hairline
     inside the card: the credit is separated by space and colour, the way the rest of the site separates things. */
  .badges { list-style: none; display: grid; grid-template-columns: repeat(auto-fit, minmax(196px, 1fr)); gap: clamp(12px, 1.4vw, 18px); }
  .badge { height: 100%; display: flex; flex-direction: column; gap: 5px; padding: 20px; border-radius: 16px; background: var(--quo-white); box-shadow: inset 0 0 0 1px var(--rule); transition: box-shadow var(--motion-instant) linear; }
  .badge:hover { box-shadow: inset 0 0 0 1px oklch(0.62 0.2 255 / 45%); }
  .bmark { width: 56px; height: 56px; border-radius: 12px; display: grid; place-items: center; margin-bottom: 9px; }
  .bmark.navy { background: var(--ink); }
  .bmark img { width: 44px; height: 44px; object-fit: contain; display: block; }
  .brank { font-size: 1.125rem; font-weight: 600; line-height: 1.25; color: var(--ink); }
  .badge:hover .brank { color: var(--quo-blue); }
  .bwhat { font-size: 0.875rem; font-weight: 600; line-height: 1.35; color: var(--ink); }
  .bcat { font-size: 0.8125rem; line-height: 1.45; color: var(--ink-2); }
  .bcred { margin-top: auto; padding-top: 16px; font-size: 0.75rem; font-weight: 800; letter-spacing: var(--tracking-eyebrow); text-transform: uppercase; color: var(--ink-2); }
  /* On a narrow wall the badges must stay two across (owner, 2026-09-04). `auto-fit` with a 196px minimum silently
     drops to ONE column under ~404px, which stacked all six badges into a 1405px column on a phone. Keyed off the
     CONTAINER, not the viewport: a section is not always viewport-wide (a paired section is half of it), so the
     column count has to follow the space the wall actually has. Six badges make three rows of two. */
  #awards .sec-body { container-type: inline-size; }
  @container (max-width: 620px) {
    .badges { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
    .badge { padding: 14px; gap: 4px; border-radius: 14px; }
    .bmark { width: 38px; height: 38px; border-radius: 9px; margin-bottom: 6px; }
    .bmark img { width: 30px; height: 30px; }
    .brank { font-size: 1rem; }
    .bwhat { font-size: 0.8125rem; }
    .bcat { font-size: 0.75rem; line-height: 1.4; }
    .bcred { padding-top: 12px; font-size: 0.6875rem; }
  }
  /* The creed at the head of "How X works" (owner, 2026-09-04). The statement and the mission sit side by side, the
     mission larger because it is the point and the statement is the run-up; the five values then take the full width
     as the section's one display moment, uppercase in the display face. Separated from the strengths below by space
     only: no rule, and no gold, because nothing here is something to do. */
  .creed-top { display: grid; gap: clamp(30px, 4vw, 52px); margin-bottom: clamp(38px, 5vw, 68px); }
  .ctop { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); gap: clamp(24px, 3vw, var(--col-gap-wide)); align-items: start; }
  .cstate p { font-size: clamp(1.0625rem, 1.5vw, 1.25rem); line-height: 1.55; max-width: 54ch; }
  .csrc { margin-top: 12px; font-size: 0.8125rem; line-height: 1.5; color: var(--ink-2); }
  .cmiss .lab, .cvals .lab { display: block; margin-bottom: clamp(10px, 1.2vw, 16px); }
  .cmiss p { font-size: clamp(1.25rem, 2.1vw, 1.75rem); line-height: 1.25; font-weight: 600; letter-spacing: -0.01em; text-wrap: balance; max-width: 26ch; }
  /* The five values span the row, edge to edge. Sized off the CONTAINER, not the viewport: the glyphs of these five
     words measure 22.7x the font size, so 3.4cqw keeps them at about 77% of the width and `space-between` hands the
     remaining 23% to the four gaps. Sizing this in vw instead put a fixed 54px gap against a shrinking row and broke
     it into three ragged lines by 1200px. One line holds down to ~450px; below that it wraps, and the gaps go even. */
  .cvals { container-type: inline-size; }
  .cvals ul { list-style: none; display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: clamp(10px, 1.2vw, 18px) clamp(14px, 1.6vw, 28px); font-family: var(--font-display); font-weight: 400; text-transform: uppercase; font-size: clamp(1.125rem, 3.4cqw, 2.875rem); line-height: 1; letter-spacing: -0.01em; color: var(--ink); }
  @media (max-width: 860px) { .ctop { grid-template-columns: 1fr; } }
  @media (max-width: 560px) { .cvals ul { justify-content: flex-start; } }
  /* A section of experience is two columns: the timeline (with its explanation below it) and, beside it, the mosaic of
     every picture from that section. On hover the explanation swaps to the row under the pointer; it starts on the most
     recent role, so it is never empty and nothing shifts. Narrow screens put the mosaic under the list and the notes
     back inline (there is no hover there). */
  .expwrap { display: grid; grid-template-columns: minmax(0, 49%) minmax(0, 1fr); gap: clamp(20px, 2.6vw, 40px); align-items: start; }
  .rowswrap { display: grid; gap: clamp(20px, 2.4vw, 32px); }
  .expwrap .frows { --datew: 7.25rem; --rowgapx: 18px; }   /* month ranges break onto two lines by design */
  .expwrap .frows .creed-row { grid-template-columns: var(--datew) minmax(0, 1fr); column-gap: var(--rowgapx); }
  .expwrap .frows:has(.has-logo) .frow:not(:last-child)::after { left: calc(var(--datew) + var(--rowgapx) + 22px - 1.5px); }
  .rowswrap.has-stage .frows .creed-row > p { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip-path: inset(50%); }
  .frow.on .frt h3 { color: var(--lead-text); }
  .hstage p { font-size: 0.9375rem; line-height: 1.6; color: var(--ink); background: var(--quo-white); border-radius: 16px; padding: 18px 20px 18px 22px; box-shadow: inset 0 0 0 1px var(--rule), inset 3px 0 0 0 oklch(0.62 0.2 255 / 55%); }
  @media (max-width: 1000px) {
    .expwrap { grid-template-columns: 1fr; }
    .hstage { display: none; }
    /* Narrow the date column by moving --datew, never grid-template-columns on its own: the rail's
       left is calculated from the same variable, and changing one without the other is what put the
       rail through the paragraph. */
    .expwrap .frows { --datew: 7rem; }
    .rowswrap.has-stage .frows .creed-row > p { position: static; width: auto; height: auto; margin: 0; clip-path: none; }
  }
  @media (max-width: 640px) {
    /* On a phone the date column was taking 40% of the width and squeezing the copy to about thirty
       characters a line. The row stacks instead: date as a label, then the logo and title, then the
       text across the full width. The connecting rail goes with it, because once the rows are a single
       column there is no left-hand column for it to join up, and its offset was the thing that broke. */
    /* Every founder list stacks here, including the ones with no mosaic beside them: a list without
       media (Quentin's) kept the three columns and pushed the page 70px wider than the phone. The
       .sec on the front is what carries the weight, because the .expwrap rule further up is more
       specific than a bare .frows and would otherwise keep its columns. */
    .sec .frows .creed-row { grid-template-columns: 1fr; row-gap: 10px; }
    .sec .frows .creed-row > p { grid-column: 1; max-width: none; }
    .frows:has(.has-logo) .frow:not(:last-child)::after { display: none; }
    .frows .k.when br { display: none; }
    .frows .creed-row .k.when { line-height: 1.3; }
    /* app.js marks a row foldable and adds the button, so a browser without script simply shows the
       text as it always did rather than hiding it behind a control that cannot open. */
    .frow.foldable > p { display: none; }
    .frow.foldable.open > p { display: block; }
    .fold-btn { justify-self: start; font-size: 0.8125rem; font-weight: 600; color: var(--lead-text); background: none; border: 0; padding: 2px 0; cursor: pointer; display: inline-flex; align-items: center; gap: 6px; }
    .fold-btn::after { content: ""; width: 7px; height: 7px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: rotate(45deg) translate(-1px, -1px); }
    .frow.open .fold-btn::after { transform: rotate(-135deg) translate(-2px, -2px); }
  }
  .fold-btn { display: none; }
  @media (max-width: 640px) { .frow.foldable .fold-btn { display: inline-flex; } }

  /* The mosaic: masonry columns, so each picture keeps its own shape and none is cropped. */
  .bento { columns: 3; column-gap: 8px; }
  .bento figure { break-inside: avoid; margin: 0 0 8px; border-radius: 10px; overflow: hidden; background: var(--quo-white); box-shadow: inset 0 0 0 1px var(--rule); position: relative; }
  .bento :is(img, video) { width: 100%; height: auto; display: block; }
  .bento .bplay { display: block; width: 100%; padding: 0; cursor: pointer; }
  .bento .play { position: absolute; left: 50%; top: 50%; width: 44px; height: 44px; margin: -22px 0 0 -22px; border-radius: 50%; background: var(--primary-strong); color: var(--quo-white); display: grid; place-items: center; box-shadow: 0 10px 24px -10px oklch(0 0 0 / 55%); transition: transform var(--motion-quick) var(--ease-move); }
  .bento .play svg { width: 20px; height: 20px; margin-left: 2px; }
  .bento .bplay:hover .play, .bento .bplay:focus-visible .play { transform: scale(1.08); }
  .bento .bzoom { display: block; width: 100%; padding: 0; cursor: zoom-in; }
  .bento.wide { columns: 2; column-gap: 14px; }                     /* app screens are wide: two per row */
  .bento.wide figure { margin-bottom: 14px; border-radius: 12px; }
  @media (max-width: 720px) { .bento.wide { columns: 1; } }
  @media (max-width: 1000px) { .bento { columns: 4; } }

  /* Click a picture to see it whole (the redrawn diagram needs it, the team photos benefit). */
  .lightbox { position: fixed; inset: 0; z-index: 50; display: grid; place-items: center; padding: clamp(16px, 4vw, 48px); background: oklch(0.1831 0.0309 263.4 / 88%); cursor: zoom-out; }
  .lightbox[hidden] { display: none; }
  .lightbox :is(img, video) { max-width: min(1200px, 92vw); max-height: 88vh; width: auto; height: auto; border-radius: 12px; background: var(--quo-white); box-shadow: 0 40px 80px -30px oklch(0 0 0 / 70%); }
  .lightbox .close { position: absolute; top: clamp(12px, 2vw, 24px); right: clamp(12px, 2vw, 24px); width: 44px; height: 44px; border-radius: 50%; background: oklch(1 0 0 / 12%); color: var(--quo-white); display: grid; place-items: center; font-size: 1.25rem; cursor: pointer; }
  .lightbox .close:hover { background: oklch(1 0 0 / 22%); }
  @media (max-width: 640px) { .bento { columns: 2; } }

  .sec .src { color: var(--ink-2); }
  .fhead .tagline { display: block; margin-top: 6px; color: var(--ink-2); }

  /* On-page index under a founder's hero: the sections below, one click away. */
  /* margin-inline stays auto: .g centres with it, and a plain `margin` shorthand would kill that. The bottom
     margin is the index's own, because the .phero + .sec rule that gives the first panel its air stopped
     matching once this nav was placed between the two. */
  .jump { display: grid; gap: 10px; margin: clamp(10px, 1.6vw, 18px) auto clamp(16px, 2vw, 24px); }
  .jump ul { display: flex; flex-wrap: wrap; gap: 10px 32px; }
  .jump a.on { color: var(--lead-text); }
  /* These three sit ABOVE the phone block on purpose. They match `.jump a` and `.jump a::before` at the
     same specificity as the rules inside it, so whichever comes last in the file wins: with them below,
     the phone's 8px ink dot silently rendered as this 6px gold one. */
  .jump a { font-size: 0.9375rem; font-weight: 600; color: var(--ink); display: inline-flex; align-items: center; gap: 8px; }
  .jump a::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--quo-gold); }
  .jump a:hover, .jump a:focus-visible { color: var(--lead-text); }
  /* On a phone the index leaves the flow entirely and becomes dots up the right edge (owner,
     2026-09-04, chosen from six treatments in explorations/jump.ts). The dot you are in is gold and its
     NAME rides out beside it while the page is moving, folding back to a bare dot a beat after you stop,
     so a still page is only dots and the sections keep the whole screen. It replaced a sticky strip of
     seven chips that scrolled sideways: about 900px of pills in a 358px viewport, clipped at both edges,
     stacked under the island. Above 700px it stays exactly the quiet list it was. */
  @media (max-width: 700px) {
    .jump { position: fixed; right: 0; top: 50%; transform: translateY(-50%); width: auto; max-width: 70vw;
            margin: 0; z-index: 9;
            transition: opacity var(--motion-base) var(--ease-enter), visibility var(--motion-base) linear; }
    /* The rail is not there when you land: the hero is the whole first screen and dots up its edge only
       clutter it. `at-hero` is set by app.js while the hero still holds the top of the screen and comes
       off on the same line the scrollspy marks on, so the rail fades in already carrying its gold dot,
       and fades back out if you return to the top. Without script the class is never set and the rail is
       simply always there, as it was. `:focus-within` keeps it reachable by keyboard from the hero. */
    body.at-hero .jump:not(:focus-within) { opacity: 0; visibility: hidden; }
    .jump ul { flex-direction: column; align-items: flex-end; gap: 10px; padding: 0 9px 0 0; }
    /* ⚠ The li is a flex container so the link stops being an inline box: as one it sat on a text
       baseline and the li kept the inherited line-height under it, another 6px of air per dot that no
       rule here asked for. */
    .jump li { flex: 0 0 auto; display: flex; justify-content: flex-end; }
    .jump a { position: relative; gap: 0; padding: 3px; border-radius: 999px;
              transition: gap var(--motion-quick) var(--ease-move), padding var(--motion-quick) var(--ease-move),
                          background-color var(--motion-instant) linear, box-shadow var(--motion-instant) linear; }
    /* The dot is 7px but the thing you tap is 28 by 29, which is what this transparent box is for. Its
       height is exactly the pitch (18px row + 10px gap), so the targets tile the rail without overlapping. */
    .jump a::after { content: ""; position: absolute; inset: -5px -7px; }
    .jump a::before { width: 7px; height: 7px; background: var(--ink); opacity: 0.26; transition: opacity var(--motion-instant) linear; }
    .jump a.on::before { background: var(--quo-gold); opacity: 1; }
    /* ⚠ `line-height: 1`. The name is clipped to no width but it still sets the row's height, and at the
       inherited line-height that is an 18px line box holding a 7px dot: the rail was as tall as its names
       whether or not one was showing, which is what made the dots sit so far apart. The names are
       uppercase, so a 1 line box has nothing to clip. */
    .jump a .n { max-width: 0; opacity: 0; overflow: hidden; white-space: nowrap; line-height: 1;
                 font-size: 0.75rem; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase;
                 transition: max-width var(--motion-quick) var(--ease-move), opacity var(--motion-instant) linear; }
    body.moving .jump a.on { gap: 7px; padding: 6px 11px 6px 10px; color: var(--ink);
                             background: color-mix(in srgb, var(--quo-white) 78%, transparent); backdrop-filter: blur(10px);
                             box-shadow: inset 0 0 0 1px var(--rule), 0 8px 20px -12px oklch(0.1831 0.0309 263.4 / 55%); }
    @supports not (backdrop-filter: blur(10px)) { body.moving .jump a.on { background: var(--quo-white); } }
    body.moving .jump a.on .n { max-width: 62vw; opacity: 1; }
    @media (prefers-reduced-motion: reduce) { .jump, .jump :is(a, a .n) { transition-duration: 1ms; } }
  }
  /* Founder work: tiles (cover 16:10, kicker, title, a line, one action), the click-to-load player, the mood board. */
  .wtiles { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--col-gap); }
  .wtiles.two { grid-template-columns: repeat(2, minmax(0, 1fr)); }   /* four films sit two by two, no orphan row */
  .wtiles.two .wtxt { padding: 20px 24px 22px; }
  .wtiles.two .wtxt h3 { font-size: 1.25rem; }
  .wtiles.two .wtxt p { max-width: 62ch; }
  @media (max-width: 1000px) { .wtiles { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
  @media (max-width: 600px) { .wtiles, .wtiles.two { grid-template-columns: 1fr; } }
  .wtile { display: grid; grid-template-rows: auto 1fr; background: var(--quo-white); border: 1px solid var(--rule); border-radius: 12px; overflow: hidden; }
  .wmedia { position: relative; display: block; aspect-ratio: 16 / 9; background: var(--ink); overflow: hidden; padding: 0; width: 100%; }
  .wmedia img, .wmedia iframe { width: 100%; height: 100%; object-fit: cover; display: block; border: 0; }
  .wmedia .play { position: absolute; left: 50%; top: 50%; width: 64px; height: 64px; margin: -32px 0 0 -32px; border-radius: 50%; background: var(--primary-strong); color: var(--quo-white); display: grid; place-items: center; box-shadow: 0 12px 28px -10px oklch(0 0 0 / 50%); transition: transform var(--motion-quick) var(--ease-move); }
  .wmedia .play svg { width: 28px; height: 28px; margin-left: 3px; }
  .wmedia.vplay { cursor: pointer; }
  .wmedia.vplay:hover .play, .wmedia.vplay:focus-visible .play { transform: scale(1.06); }
  .wtxt { padding: 18px 20px 20px; display: flex; flex-direction: column; gap: 8px; }
  /* The role sits bottom right of the tile, under the description (owner, 2026-08-20). It takes the free
     space, so where a CTA follows the pill keeps its own gap instead of splitting the space with it. */
  .wrole { font-size: 0.8125rem; font-weight: 600; color: var(--ink-2); margin-top: auto; align-self: end; text-align: right; }
  .wcta { align-self: end; margin-top: 18px; }
  .wtxt > .wcta:not(:first-child) { margin-top: auto; }
  .wtxt > .wrole + .wcta { margin-top: 18px; }
  .wtxt h3 { font-size: 1.125rem; font-weight: 600; line-height: 1.3; }
  .wtxt p { font-size: 0.9375rem; line-height: 1.5; }
  .wtxt .lnk { width: fit-content; margin-top: 2px; }
  .mood { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); grid-auto-rows: clamp(120px, 15vw, 210px); grid-auto-flow: dense; gap: 12px; }
  .mood figure { margin: 0; border-radius: 12px; overflow: hidden; background: var(--panel); }
  .mood figure img { width: 100%; height: 100%; object-fit: cover; display: block; }
  .mood .s22 { grid-column: span 2; grid-row: span 2; }
  .mood .s21 { grid-column: span 2; }
  .mood .s12 { grid-row: span 2; }
  @media (max-width: 640px) { .mood { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
  /* Stickers: seven tall strips in a row (they wrap on narrower screens), each with its city, country and a line. */
  .wlead { max-width: 60ch; }
  .cwork { display: grid; gap: 16px; }
  .cdesc { font-size: 1.0625rem; line-height: 1.6; max-width: 74ch; }
  .stickers { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 28px clamp(14px, 2vw, 28px); }
  @media (max-width: 1100px) { .stickers { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
  .sticker { margin: 0; display: grid; gap: 12px; align-content: start; }
  .sticker img { width: 100%; height: auto; aspect-ratio: 620 / 1600; object-fit: cover; border-radius: 10px; box-shadow: inset 0 0 0 1px var(--rule); display: block; }
  .sticker figcaption { display: grid; gap: 2px; }
  .sticker .city { font-weight: 600; font-size: 1rem; line-height: 1.3; }
  .sticker .country { font-size: 0.75rem; font-weight: 800; letter-spacing: var(--tracking-eyebrow); text-transform: uppercase; color: var(--ink-2); }
  .sticker p { font-size: 0.8125rem; line-height: 1.45; margin-top: 6px; color: var(--ink); }
  @media (max-width: 480px) { .stickers { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
  .slides { display: grid; gap: 20px; max-width: 1100px; }
  .slide { margin: 0; border-radius: 12px; overflow: hidden; border: 1px solid var(--rule); background: var(--quo-white); }
  .slide img { width: 100%; height: auto; display: block; }

  /* Two short sections can share a row, so the page is not one endless column (owner, 2026-08-19). */
  .pair { display: grid; grid-template-columns: 1fr 1fr; gap: var(--inset); margin: 0 var(--inset) var(--inset); }
  .pair > .g.sec { width: 100%; margin: 0; align-content: start; }
  .pair :is(.sec-body, .creed, .creed-row) { align-content: start; }
  .pair .frows .creed-row { row-gap: 0; }
  .pair .cols.c4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pair .frows .creed-row { grid-template-columns: 7rem minmax(0, 1fr); column-gap: 18px; }
  .pair .frows .creed-row > p { grid-column: 2; margin-top: 8px; }
  .pair .frows:has(.has-logo) .frow:not(:last-child)::after { left: calc(7rem + 18px + 22px - 1.5px); }
  @media (max-width: 900px) { .pair { grid-template-columns: 1fr; } .pair .frows .creed-row { grid-template-columns: 7rem minmax(180px, 1.4fr) 3fr; } .pair .frows .creed-row > p { grid-column: auto; margin-top: 0; } }
  @media (max-width: 640px) { .pair .frows .creed-row { grid-template-columns: 7rem 1fr; } .pair .frows .creed-row > p { grid-column: 2; } }

  /* Legal pages */
  .prose { display: grid; gap: 14px; max-width: 66ch; line-height: 1.6; }
  .prose h3 { font-size: 1.125rem; font-weight: 600; line-height: 1.3; margin-top: 14px; }
  .prose strong { font-weight: 600; }

  /* No flash of the finished mark or headline before the sequences take over (app.js hands off; a fallback timer in the head un-hides). */
  .js .poster.typed .ch { visibility: hidden; }
  .js .poster.typed .dot { animation: none; transform: scale(0); }

  /* Typewriter: each character is a span (layout is fixed from the start); the caret rides the last visible one. */
  .poster.typed .ch { position: relative; }
  .poster.typed .ch.cur::after { content: ""; position: absolute; left: 100%; top: 0.14em; width: 0.05em; height: 0.72em; margin-left: 0.04em; background: var(--ink); }
