/* ============================================================
   soshctrl — marketing site
   ------------------------------------------------------------
   Liquid-glass design system. Three colours only: brand yellow
   (#FFDF00), black and white, with a neutral grey ramp derived
   from black. Surfaces are translucent and blurred over a soft
   ambient field, so depth comes from light rather than from
   borders.

   Everything lives in this file: the deployed site ships a
   strict CSP (`style-src 'self'`), so there are no inline
   styles and no <style> blocks anywhere.
   ============================================================ */

/* ── Fonts ─────────────────────────────────────────────────
   Geist (SIL OFL 1.1), self-hosted so no visitor's browser calls
   Google before consent. One variable file per script covers every
   weight from 100 to 900. The arrows file holds just ← and →.
   The fallback stack sits in --font / --font-head below. */
@font-face {
  font-family: "Geist";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("assets/fonts/geist-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Geist";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("assets/fonts/geist-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Geist";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("assets/fonts/geist-arrows.woff2") format("woff2");
  unicode-range: U+2190, U+2192;
}

:root {
  /* Marketing site is light-only. Opt out of forced OS dark rendering. */
  color-scheme: only light;

  /* ── Brand ─────────────────────────────────────────────── */
  --brand: #ffdf00;
  --brand-hi: #ffe94d;          /* lighter end of yellow gradients */
  --brand-lo: #f0ce00;          /* hover / pressed */
  --brand-deep: #d4b600;        /* focus rings, hairlines on yellow */
  --brand-mute-hi: #e8d664;     /* slightly dulled yellow — primary button hover */
  --brand-mute: #dfc93a;
  --brand-glow: rgba(255, 223, 0, .55);
  --brand-wash: rgba(255, 223, 0, .16);
  --brand-ink: #0a0a0b;         /* text that sits on yellow */

  /* Hand-drawn marker stroke used for inline link underlines.
     Tapered at both ends, lifts slightly to the right, stretched
     to the link width (preserveAspectRatio='none'). */
  --pen-brand: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 11' preserveAspectRatio='none'%3E%3Cpath fill='%23ffdf00' d='M1.5 8.3C13 6.6 35 5.2 58 4.5c23-.7 45-.9 60.5-.6.4 1.1-.3 2.3-1.7 2.9-15.8-.4-34.8-.2-54.8.4-21 .7-43 2-54.8 3.3C4.2 10.9 1.1 9.7 1.5 8.3Z'/%3E%3Cpath fill='%23ffdf00' fill-opacity='.5' d='M107 6.7c4-.2 8-.2 12.4 0-2.4.8-6.4 1.2-9.8 1Z'/%3E%3C/svg%3E");
  --pen-ink: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 11' preserveAspectRatio='none'%3E%3Cpath fill='%230a0a0b' d='M1.5 8.3C13 6.6 35 5.2 58 4.5c23-.7 45-.9 60.5-.6.4 1.1-.3 2.3-1.7 2.9-15.8-.4-34.8-.2-54.8.4-21 .7-43 2-54.8 3.3C4.2 10.9 1.1 9.7 1.5 8.3Z'/%3E%3Cpath fill='%230a0a0b' fill-opacity='.5' d='M107 6.7c4-.2 8-.2 12.4 0-2.4.8-6.4 1.2-9.8 1Z'/%3E%3C/svg%3E");

  /* ── Neutral ramp (pure, derived from black) ───────────── */
  --black: #000000;
  --ink: #0a0a0b;
  --ink-soft: #17171a;
  --text: #0a0a0b;
  --text-2: #3a3a3f;
  --muted: #6a6a72;
  --faint: #9a9aa3;

  --page: #f4f4f6;
  --surface: #ffffff;
  --surface-muted: #ededf0;
  --surface-sunken: #f7f7f9;

  --hairline: rgba(0, 0, 0, .07);
  --hairline-mid: rgba(0, 0, 0, .1);
  --hairline-strong: rgba(0, 0, 0, .16);
  --border: var(--hairline);
  --border-strong: var(--hairline-mid);

  /* ── Glass ─────────────────────────────────────────────── */
  --glass: rgba(255, 255, 255, .62);
  --glass-hi: rgba(255, 255, 255, .78);
  --glass-lo: rgba(255, 255, 255, .42);
  --glass-edge: rgba(255, 255, 255, .72);
  --blur: saturate(180%) blur(24px);
  --blur-lg: saturate(190%) blur(36px);
  --blur-glass: saturate(210%) blur(30px);

  /* Glass on black */
  --glass-d: rgba(255, 255, 255, .055);
  --glass-d-hi: rgba(255, 255, 255, .09);
  --glass-d-edge: rgba(255, 255, 255, .1);

  /* ── Elevation ─────────────────────────────────────────── */
  --ring: 0 0 0 1px rgba(0, 0, 0, .05);
  --edge: inset 0 1px 0 rgba(255, 255, 255, .85);
  --edge-d: inset 0 1px 0 rgba(255, 255, 255, .08);

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, .04), 0 4px 12px -6px rgba(0, 0, 0, .08);
  --shadow-md: 0 2px 6px -2px rgba(0, 0, 0, .05), 0 14px 32px -14px rgba(0, 0, 0, .18);
  --shadow-lg: 0 8px 20px -10px rgba(0, 0, 0, .1), 0 40px 80px -32px rgba(0, 0, 0, .3);

  /* ── Type ──────────────────────────────────────────────── */
  --font: "Geist", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-head: "Geist", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

  /* ── Weight ────────────────────────────────────────────────
     Three voices, deliberately far apart. Geist is loaded as a
     variable face across 100..900, so the gaps below are real
     steps rather than the browser's synthetic bolding.

       --w-display  headlines — h1, h2, the hero, page heroes.
                    The loudest thing on any screen.
       --w-title    sub-titles — h3..h6, card and column heads,
                    labels, table heads. Reads as a heading at a
                    glance without competing with the display.
       --w-body     running copy. Light on purpose: against 800
                    headlines the contrast is what carries the
                    hierarchy, not size alone. 300 rather than the
                    200 this started at — 200 held up in a display
                    screenshot and then thinned out to nothing in a
                    long paragraph, which is where most of the copy
                    on this site actually lives.
       --w-body-em  inline emphasis inside that light copy. It has
                    to jump several steps to register at all.

     Interactive chrome — buttons, nav links, chips, tags — keeps
     its own weights further down. Those are targets, not prose,
     and they stop reading as pressable when they go thin.
     ──────────────────────────────────────────────────────── */
  --w-display: 800;
  --w-title: 600;
  --w-body: 300;
  --w-body-em: 600;

  /* ── Geometry ──────────────────────────────────────────── */
  --r-panel: clamp(26px, 3.2vw, 44px);
  --r-xl: 28px;
  --r-lg: 22px;
  --r-md: 16px;
  --r-sm: 11px;
  --radius-lg: var(--r-lg);
  --radius-md: var(--r-md);
  --radius-sm: var(--r-sm);
  --radius-pill: 999px;
  --r-pill: 999px;
  --topbar-h: 52px;
  /* The corner of the card that ribbon and open panel form together — the
     ribbon's top corners and the sheet's bottom ones are the same card, so
     they are the same number. It has to stay well under half the ribbon's
     height: at 26px the arc consumes the bar's full height, leaving no flat
     top edge at all, and the ribbon reads as a dome with the wordmark and the
     CTA pressed up against the curve. */
  --r-menu: 18px;

  /* ── Motion ────────────────────────────────────────────── */

  /* One duration scale for the whole site. Anything that moves picks the step
     that matches how far it travels — a 6px hover tint and a 300px panel
     cannot share a number and both look right. Exits run roughly two-thirds
     of their entrance: leaving should feel like getting out of the way. */
  --t-1: 140ms;   /* tints, text colour, small state flips */
  --t-2: 220ms;   /* buttons, chips, links lifting */
  --t-3: 320ms;   /* cards, the ribbon changing character */
  --t-4: 460ms;   /* the mega-menu unfurl — the longest move on the site */

  /* --ease was cubic-bezier(.16, 1, .3, 1): an expo-out that spends ~80% of
     its travel in the first quarter of its time. On a 4px hover that is
     crisp; on anything that actually moves a distance it reads as a snap
     followed by a crawl, which is exactly what made the mega menu feel
     broken. This curve keeps the decisive start and lands without the drag. */
  --ease: cubic-bezier(.25, .8, .25, 1);
  --ease-out: cubic-bezier(.22, .61, .36, 1);
  /* For surfaces that change size. Slower off the mark than --ease, so the
     first frames read as the panel taking hold rather than jumping. */
  --ease-smooth: cubic-bezier(.32, .72, 0, 1);
}

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

html {
  color-scheme: only light;
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
  scrollbar-gutter: stable;
  background-color: var(--page);
  scroll-padding-top: 92px;
}

html, body {
  margin: 0;
  padding: 0;
  color: var(--text);
  /* Ranged left. Centring is an opt-in, not the ground state: the few
     blocks that earn it — the heroes, the claim band, the CTA band —
     say so themselves, and they are collected under
     "Centred where it earns it" further down. */
  text-align: left;
  font-family: var(--font);
  font-size: 17px;
  font-weight: var(--w-body);
  line-height: 1.55;
  letter-spacing: -0.012em;
  /* A long address or link that can't fit a phone's line breaks inside
     itself instead of running off the side. Ordinary words are unaffected. */
  overflow-wrap: break-word;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

body.site {
  position: relative;
  overflow-x: hidden;
}

/* ── Ambient field ───────────────────────────────────────────
   A fixed wash of yellow and neutral light behind the whole
   document. Without something to refract, glass reads as flat
   grey — this is what the blurred surfaces are blurring.
   ────────────────────────────────────────────────────────── */

body.site::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(52vw 46vw at 8% -6%, rgba(255, 223, 0, .22), transparent 62%),
    radial-gradient(44vw 40vw at 96% 4%, rgba(255, 223, 0, .12), transparent 64%),
    radial-gradient(60vw 50vw at 76% 88%, rgba(255, 223, 0, .12), transparent 66%),
    radial-gradient(50vw 44vw at 14% 62%, rgba(0, 0, 0, .05), transparent 64%),
    linear-gradient(180deg, #ffffff 0%, var(--page) 46%, #efeff2 100%);
}

/* Fine grain, so large flat areas don't band. */
body.site::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 2000;
  pointer-events: none;
  opacity: .035;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* Keep the marketing site light even under Chrome/Samsung auto-dark. */
@media (prefers-color-scheme: dark) {
  html:has(body.site) { color-scheme: only light !important; background-color: #f4f4f6 !important; }
  body.site {
    color-scheme: only light !important;
    background-color: transparent !important;
    color: #0a0a0b !important;
  }
}

a { color: inherit; text-decoration: none; }
img { max-width: 100%; display: block; }
ul, ol { margin: 0; padding: 0; }

/* Form controls don't inherit type from body by default — opt them in so
   every control renders in Geist alongside the rest of the page. Weight is
   opted in too, so what someone types into a field matches the prose around
   it; .btn re-asserts its own heavier step below. */
button, input, select, textarea { font-family: inherit; font-weight: inherit; }
/* Browsers default these to monospace; the site is Geist only, so they
   follow the text around them too. */
code, pre, kbd, samp, tt, var, optgroup, svg text { font-family: inherit; font-size: inherit; }

h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-head);
  font-weight: var(--w-title);
  letter-spacing: -0.038em;
  margin: 0;
  text-wrap: balance;
}

/* h1 and h2 are the page's voice — they carry the display weight. h3 and
   below are sub-titles and stay on --w-title, above. At 800 the tighter
   tracking earns itself: heavy glyphs need less air between them than the
   600 step did. */
h1, h2 {
  font-weight: var(--w-display);
  letter-spacing: -0.045em;
}

/* Emphasis has to clear 200-weight copy by a wide margin to read as
   emphasis at all — the old 650-against-400 gap no longer applies. */
strong, b { font-weight: var(--w-body-em); }

::selection { background: var(--brand); color: var(--brand-ink); }

:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
  border-radius: 6px;
}
.band-dark :focus-visible { outline-color: var(--brand); }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.container { width: min(1120px, calc(100% - 44px)); margin: 0 auto; }
.container--narrow { width: min(820px, calc(100% - 44px)); }

/* ── Top bar — a floating glass island ───────────────────── */

.topbar {
  position: sticky;
  top: 0;
  z-index: 40;
  padding: 10px 0 8px;
  background: transparent;
  border: 0;
}

/* The glass is built entirely from a gradient fill plus inset shadows:
   inset shadows paint above the background but below the content, so the
   specular rim and inner glow never wash over the nav. Pseudo-elements are
   avoided deliberately — this is a grid container.

   The white fill stays thin on purpose. Much past ~.5 it stops being glass:
   the backdrop-filter is still running, but nothing of the page behind it
   survives to be seen, so over a coloured band (.claim-band) the pill read as
   a flat white lozenge while the dark state — white at .07–.18 — looked like
   real glass. These alphas let the blurred, saturated backdrop through in
   both cases. */
.topbar-inner {
  /* The rim alpha per ribbon state. A token rather than four full shadow
     lists: the open state has to restyle the rim without knowing whether the
     scrolled or the dark list is the one currently winning, which is exactly
     what border-color used to do for free. box-shadow still transitions, so
     the rim still cross-fades between states. */
  --ribbon-rim: rgba(255, 255, 255, .55);
  height: var(--topbar-h);
  display: grid;
  /* Equal side tracks so the links sit on the page centre, lined up with
     centred hero content, whatever the brand and tools each measure. */
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 16px;
  padding: 0 8px 0 20px;
  /* Half the height, which is what --r-pill resolved to here anyway — the
     browser clamps any larger radius down to this. Written out because the
     clamp is applied to the *used* value while a transition interpolates the
     *specified* one: morphing to the open state from 999px stayed pinned at
     pill shape for almost the whole duration and then snapped over the last
     few percent. From 26px it actually interpolates. */
  border-radius: calc(var(--topbar-h) / 2);
  background:
    linear-gradient(180deg,
      rgba(255, 255, 255, .5) 0%,
      rgba(255, 255, 255, .28) 46%,
      rgba(255, 255, 255, .38) 100%);
  -webkit-backdrop-filter: var(--blur-glass);
  backdrop-filter: var(--blur-glass);
  /* The rim is an inset ring rather than a real border, and that is load
     bearing rather than stylistic: .nav-flyout is positioned against this
     element, and an absolute box resolves against the *padding* box. With a
     border here the ribbon's outer edge came from the border painter while the
     sheet's came from the layout engine, one pixel apart, and no offset could
     reconcile them — at fractional device pixel ratios the two paths round in
     opposite directions, so a −1px correction that was exact at 1x and 2x hung
     a device pixel past the ribbon at 1.75x and 2.5x. With no border the
     padding box *is* the border box: the sheet inherits the ribbon's own edge
     and there is only one number left to round. It is also how the sheet has
     always drawn its own rim, so the two now match layer for layer.

     Listed above the other insets because that is where a border painted —
     over the inset shadows, under the content. */
  box-shadow:
    0 0 0 1px rgba(0, 0, 0, .045),
    0 2px 6px -3px rgba(0, 0, 0, .08),
    0 12px 32px -16px rgba(0, 0, 0, .3),
    inset 0 0 0 1px var(--ribbon-rim),
    inset 0 1px 0 rgba(255, 255, 255, 1),
    inset 0 9px 18px -12px rgba(255, 255, 255, .95),
    inset 0 -7px 16px -12px rgba(255, 255, 255, .6);
  /* The radius lands ahead of the fill on purpose: the seam between ribbon and
     sheet wants to be square by the time the sheet is far enough out to meet
     it, and a corner still rounding under an arriving panel reads as a gap. */
  transition: background var(--t-3) var(--ease), box-shadow var(--t-3) var(--ease),
              border-radius var(--t-2) var(--ease-smooth),
              width var(--t-4) var(--ease-smooth);
}

/* Resting at the very top the ribbon is not a pill at all: no fill, no rim,
   no frost, just the brand, links and buttons sitting on the page — and a
   little wider than the container. Scrolling away (initTopbar drops .is-top)
   draws it in to container width and the glass fades up, which is the
   compacting move. Class-gated rather than the default so that without
   JavaScript the ribbon keeps its glass and never loses its edge mid-page.

   The shadow list keeps the same shape as the glass one with every alpha at
   zero, so box-shadow interpolates instead of snapping. Width alone ignores
   .is-menuOpen: a panel opened at the top should hang off the wide ribbon
   rather than yank it narrow underneath the pointer. */
.topbar.is-top .topbar-inner { width: min(1240px, calc(100% - 24px)); }
.topbar.is-top:not(.is-menuOpen):not(.is-onDark) .topbar-inner {
  --ribbon-rim: rgba(255, 255, 255, 0);
  background: transparent;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  box-shadow:
    0 0 0 1px rgba(0, 0, 0, 0),
    0 2px 6px -3px rgba(0, 0, 0, 0),
    0 12px 32px -16px rgba(0, 0, 0, 0),
    inset 0 0 0 1px var(--ribbon-rim),
    inset 0 1px 0 rgba(255, 255, 255, 0),
    inset 0 9px 18px -12px rgba(255, 255, 255, 0),
    inset 0 -7px 16px -12px rgba(255, 255, 255, 0);
}

.topbar.is-scrolled .topbar-inner {
  --ribbon-rim: rgba(255, 255, 255, .7);
  background:
    linear-gradient(180deg,
      rgba(255, 255, 255, .6) 0%,
      rgba(255, 255, 255, .4) 46%,
      rgba(255, 255, 255, .5) 100%);
  box-shadow:
    0 0 0 1px rgba(0, 0, 0, .055),
    0 2px 6px -3px rgba(0, 0, 0, .1),
    0 18px 44px -20px rgba(0, 0, 0, .36),
    inset 0 0 0 1px var(--ribbon-rim),
    inset 0 1px 0 rgba(255, 255, 255, 1),
    inset 0 9px 18px -12px rgba(255, 255, 255, .95),
    inset 0 -7px 16px -12px rgba(255, 255, 255, .6);
}

/* Adaptive tint. White glass over a black panel resolves to mid-grey, which
   buries dark nav text and the black wordmark — so when the ribbon is
   travelling over a dark section it inverts to dark glass instead. Toggled by
   initTopbar() in js/site.js; without JavaScript the ribbon simply stays
   light, exactly as it is at the top of every page. */
.topbar.is-onDark .topbar-inner {
  --ribbon-rim: rgba(255, 255, 255, .2);
  background:
    linear-gradient(180deg,
      rgba(255, 255, 255, .18) 0%,
      rgba(255, 255, 255, .07) 46%,
      rgba(255, 255, 255, .13) 100%);
  box-shadow:
    0 0 0 1px rgba(0, 0, 0, .45),
    0 2px 6px -3px rgba(0, 0, 0, .3),
    0 18px 44px -20px rgba(0, 0, 0, .75),
    inset 0 0 0 1px var(--ribbon-rim),
    inset 0 1px 0 rgba(255, 255, 255, .4),
    inset 0 9px 18px -12px rgba(255, 255, 255, .3),
    inset 0 -7px 16px -12px rgba(255, 255, 255, .16);
}
/* Same three-step scale as the light ribbon, run the other way: over a dark
   band "darkest" is pure white, so that is what the current page gets and
   hover stops one step short of it. */
.topbar.is-onDark .nav-link { color: rgba(255, 255, 255, .62); }
.topbar.is-onDark .nav-link:hover { color: rgba(255, 255, 255, .86); }
.topbar.is-onDark .nav-link[aria-current="page"] { color: #fff; font-weight: 700; }
.topbar.is-onDark .menu-toggle {
  color: #fff;
  background: rgba(255, 255, 255, .1);
  border-color: rgba(255, 255, 255, .2);
}
.topbar.is-onDark .menu-toggle:hover { background: rgba(255, 255, 255, .18); }
/* the wordmark is solid black on transparent, so inverting yields clean white */
.topbar.is-onDark .brand-mark { filter: invert(1); }

.brand { display: inline-flex; align-items: center; justify-self: start; }
.brand-mark { height: 16px; width: auto; flex: none; display: block; }

.nav-links {
  display: flex;
  gap: 2px;
  justify-content: center;
  list-style: none;
}
.nav-link {
  color: var(--muted);
  font-weight: 600;
  white-space: nowrap;
  font-size: clamp(13px, 1.9vw, 14px);
  padding: 7px 14px;
  border-radius: var(--r-pill);
  transition: color var(--t-2) var(--ease-out);
}

/* No pill behind the text, in any state. The ribbon is glass sitting over
   whatever the page happens to be showing, and a translucent black panel
   behind a single word read as a smudge stuck to the nav rather than a
   highlight — and any state that outlived the pointer left it there. Weight
   is carried by colour alone, on a three-step scale so that each step means
   one thing: muted at rest, a mid grey for the transient states (hover, and
   the item whose panel is open), and full black for the page you are on.

   Hover used to land on the same full black as the current page, which left
   the two indistinguishable — you could not tell where you were from where
   the pointer happened to be. Backing hover off one step is what makes the
   current page legible, so the darkest word in the ribbon is always the
   page under you. It also carries the extra weight, for the same reason and
   for anyone who cannot separate the two greys. */
.nav-link:hover { color: var(--text-2); }
.topbar .nav-link[aria-current="page"] { color: var(--ink); font-weight: 700; }

.topbar-tools { display: flex; align-items: center; gap: 10px; justify-self: end; }

.menu-toggle {
  display: none;
  width: 36px; height: 36px;
  align-items: center; justify-content: center;
  border: 1px solid var(--hairline-mid);
  background: rgba(255, 255, 255, .7);
  border-radius: var(--r-pill);
  cursor: pointer;
  color: var(--text);
  transition: background .2s var(--ease-out), transform .2s var(--ease-out);
}
.menu-toggle:hover { background: #fff; }
.menu-toggle:active { transform: scale(.94); }
.menu-toggle svg { width: 18px; height: 18px; }

/* ── Mega menu — the flyout under the ribbon ─────────────── */

/* The trigger is wrapped so the hover target is a box rather than the text.
   Without it the pointer falls out of the menu in the 2px between two items
   and the panel flickers shut. */
.nav-item { display: flex; }

/* The pill keeps its own layer above both the scrim and the sheet, so it stays
   crisp while everything behind it is dimmed. */
.topbar-inner { position: relative; z-index: 2; }

/* Opaque while a panel is open: the ribbon can be sitting over a black band,
   and the adaptive dark tint is suppressed for the duration (see initMegaMenu),
   so the glass has to stop relying on what is behind it. */
.topbar.is-menuOpen .topbar-inner {
  background: #fff;
  --ribbon-rim: rgba(255, 255, 255, .9);
  /* While a panel is out the ribbon stops being a pill and becomes the top of
     a card: square along the bottom, where it meets the sheet, and carrying
     the card's own corner on top. Leaving --r-pill here is what broke it —
     with the bottom pair at 0 there is nothing to share the height with, so
     the clamp hands the top corner the whole 52px and the arc cuts across the
     wordmark and the CTA. Half the height (26px) stops the cutting but is
     still a perfect semicircle, which is the dome the corner was stuck in.

     The radius is the fastest thing in the sequence on purpose: the bottom
     corners have to be square before the sheet has grown far enough to meet
     them, or the seam opens as two rounded shoulders with a notch between. */
  border-radius: var(--r-menu) var(--r-menu) 0 0;
  transition: background var(--t-3) var(--ease), box-shadow var(--t-3) var(--ease),
              border-radius var(--t-1) var(--ease-out);
}
/* An open panel is a transient state, so it reads at the hover step, not the
   current-page step. The :not() keeps it from stealing the black off the item
   you are actually on when you open that same item's panel — without it this
   rule ties on specificity, comes later in the file, and wins. */
.topbar .nav-link[aria-expanded="true"]:not([aria-current="page"]) { color: var(--text-2); }

/* Dims the page under an open panel. It lives inside .topbar because that is
   the only element stacked above the page, and sits below the pill and sheet. */
.nav-scrim {
  position: fixed;
  inset: 0;
  z-index: 0;
  background: rgba(10, 10, 11, .28);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--t-4) var(--ease-out);
}
.nav-scrim[hidden] { display: none; }
.topbar.is-menuOpen .nav-scrim { opacity: 1; pointer-events: auto; }

/* Positioned against .topbar-inner, the only positioned ancestor, so every
   panel is exactly as wide as the ribbon whichever item opened it, and hangs
   straight off its bottom edge. Nothing separates trigger from sheet, so the
   pointer can never fall through to the scrim on the way down.

   left/right: 0 is only exact because the ribbon has no border — see the note
   on .topbar-inner. While it had one, these resolved against the padding box
   and the sheet came out 2px narrow, a visible step in the vertical edge at
   the seam; and correcting that with −1px traded it for a worse bug, because a
   layout offset and a border round to device pixels independently, so the two
   edges disagreed at 1.75x and 2.5x even though they matched at 1x and 2x.
   Both edges are now the same edge, which is the only version that has no
   rounding left to get wrong. Verified 0px apart on both sides at 1x–3x.

   top: 100% is that same shared edge, so the sheet's outer ring lands on the
   ribbon's last row rather than below it — which is what keeps the seam a
   single hairline instead of two stacked rings. */
.nav-flyout {
  position: absolute;
  /* Tucked 1px up under the ribbon: at 125% and 175% display scaling the two
     edges rounded to different device pixels and left a faint grey row. The
     sheet is the same white and its top ring is clipped, so the overlap is
     invisible. */
  top: calc(100% - 1px);
  left: 0;
  right: 0;
  z-index: 1;
  opacity: 0;
  /* The sheet has to be opaque well before it has finished growing, or the
     page shows through its leading edge — so the fade is short and the size
     change is what you actually watch. */
  transition: opacity 200ms var(--ease-out);
}
.nav-flyout[hidden] { display: none; }
.nav-flyout.is-open { opacity: 1; transition-duration: 180ms; }

/* The unfurl is a 0fr → 1fr grid row, not a measured pixel height: the
   deployed CSP is `style-src 'self'`, so JavaScript cannot set an inline
   height. A browser that will not interpolate fr units just snaps open.

   Close is quicker than open, and both sit on --ease-smooth rather than the
   site's general curve: a surface this size needs a couple of frames of
   wind-up to look like it is taking hold instead of being flicked out. */
.nav-flyout__clip {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 300ms var(--ease-smooth);
}
.nav-flyout.is-open .nav-flyout__clip {
  grid-template-rows: 1fr;
  transition-duration: var(--t-4);
}

/* The contents travel with the sheet rather than sitting still while an edge
   wipes down over them — that wipe was the whole reason the panel read as a
   blind being pulled rather than a surface arriving. They start a little high
   and a little transparent, and settle a touch behind the sheet's own growth,
   which is what gives the unfurl its weight.

   On the way out they go first and go fast: content that is still fading when
   the edge reaches it gets guillotined mid-line. */
.nav-panel {
  padding: clamp(22px, 2.6vw, 32px) clamp(24px, 3vw, 38px);
  opacity: 0;
  transform: translateY(-14px);
  transition: opacity 150ms var(--ease-out),
              transform 200ms var(--ease-out);
}
.nav-flyout.is-open .nav-panel {
  opacity: 1;
  transform: none;
  transition: opacity 300ms var(--ease-out) 80ms,
              transform 520ms var(--ease-smooth) 40ms;
}

/* Swapping straight from one open panel to another. The sheet is already the
   right surface in the right place, so only the contents change hands: the
   two panels crossfade where they stand instead of one collapsing and the
   next unfurling into the hole it left.

   `no-anim` suppresses the height animation *only* — the contents still
   arrive under their own steam. Killing every transition on the flyout, as
   this used to, turned a swap into a hard cut. */
.nav-flyout.no-anim .nav-flyout__clip { transition: none; }

/* The outgoing panel holds its full height while it fades, so the incoming
   one — which paints above it — is never briefly laid over a collapsing box. */
.nav-flyout.is-leaving {
  z-index: 0;
  pointer-events: none;
  transition-duration: 200ms;
}
.nav-flyout.is-leaving .nav-flyout__clip {
  grid-template-rows: 1fr;
  transition: none;
}

/* The ring is an inset shadow rather than a border — a border would keep two
   pixels of height when the row collapses to 0fr and flash on close. */
.nav-flyout__sheet {
  overflow: hidden;
  min-height: 0;
  /* The other two corners of the same card as the ribbon's — same number. */
  border-radius: 0 0 var(--r-menu) var(--r-menu);
  /* Solid, unlike the rest of the glass on this site. The sheet sits over
     whatever the page happens to be showing — a black 64px headline bleeding
     through at even a couple of per cent reads as a smudge — and it has to
     land on exactly the same white as the ribbon above it, which no amount of
     translucency will do when the two are filtering different backdrops. */
  background: #fff;
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, .8),
    0 0 0 1px rgba(0, 0, 0, .05),
    0 2px 8px -4px rgba(0, 0, 0, .1),
    0 28px 64px -28px rgba(0, 0, 0, .42);
  /* No seam: clip the ring and shadows above the sheet's top edge so ribbon and
     sheet read as one surface. The sides and drop shadow stay. The clip sits
     1px inside the sheet, in the part tucked under the ribbon: exactly on the
     edge it anti-aliased at fractional scaling and let a sliver of ring through. */
  clip-path: inset(1px -120px -120px -120px);
}

.nav-panel__cols {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 22px clamp(28px, 5vw, 72px);
}

.nav-lead, .nav-col { display: flex; flex-direction: column; min-width: 0; }

.nav-col__h {
  font-family: var(--font-head);
  font-size: 12.5px;
  font-weight: var(--w-title);
  letter-spacing: -0.01em;
  color: var(--faint);
  margin: 0 0 12px;
}

/* The first column carries the weight, the way Apple's does: big links you
   read at a glance, with the rest of the panel in a quieter register. */
.nav-lead__l {
  display: flex;
  align-items: baseline;
  gap: 10px;
  font-family: var(--font-head);
  font-size: clamp(18px, 1.9vw, 23px);
  font-weight: var(--w-title);
  letter-spacing: -0.024em;
  line-height: 1.3;
  color: var(--text);
  margin-inline: -12px;
  padding: 5px 12px;
  border-radius: var(--r-md);
  transition: background .18s var(--ease-out), color .18s var(--ease-out);
}
.nav-lead__l:hover { color: var(--brand); }
.nav-lead__l:hover .nav-lead__meta { color: var(--brand); }

.nav-lead__meta {
  font-family: var(--font);
  font-size: 12.5px;
  font-weight: var(--w-title);
  letter-spacing: -0.005em;
  color: var(--muted);
  white-space: nowrap;
  transition: color .18s var(--ease-out);
}

.nav-col__l {
  display: block;
  font-size: 14.5px;
  font-weight: 500;
  color: var(--text-2);
  margin-inline: -10px;
  padding: 6px 10px;
  border-radius: var(--r-sm);
  transition: background .18s var(--ease-out), color .18s var(--ease-out);
}
.nav-col__l:hover { color: var(--brand); }

/* ── Mobile drawer ───────────────────────────────────────── */

.site-drawer { position: fixed; inset: 0; z-index: 60; }
.site-drawer[hidden] { display: none; }

.site-drawer__backdrop {
  position: absolute; inset: 0; border: 0; padding: 0;
  background: rgba(10, 10, 11, .34);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  cursor: pointer;
  animation: fade-in .3s var(--ease) both;
}

.site-drawer__panel {
  position: absolute;
  top: 12px; right: 12px; bottom: 12px;
  width: min(330px, calc(100vw - 24px));
  background: rgba(255, 255, 255, .78);
  -webkit-backdrop-filter: var(--blur-lg);
  backdrop-filter: var(--blur-lg);
  border: 1px solid var(--glass-edge);
  border-radius: var(--r-xl);
  padding: 26px 22px;
  box-shadow: var(--shadow-lg), var(--edge);
  display: flex; flex-direction: column; gap: 4px;
  animation: drawer-in .42s var(--ease) both;
}

@keyframes fade-in { from { opacity: 0 } to { opacity: 1 } }
@keyframes drawer-in {
  from { opacity: 0; transform: translateX(16px) scale(.98); }
  to   { opacity: 1; transform: none; }
}

/* The panel covers the menu button, so it carries its own way out, drawn
   the same and sitting in the same corner. */
.site-drawer__close {
  align-self: flex-end;
  flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px;
  margin: -14px -10px 4px 0;
  padding: 0;
  border: 1px solid var(--hairline-mid);
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .7);
  color: var(--text);
  cursor: pointer;
  transition: background .2s var(--ease-out), transform .2s var(--ease-out);
}
.site-drawer__close:hover { background: #fff; }
.site-drawer__close:active { transform: scale(.94); }
.site-drawer__close svg { width: 18px; height: 18px; }

.site-drawer__nav { display: flex; flex-direction: column; gap: 2px; }
.site-drawer__nav a {
  padding: 13px 14px;
  font-size: 16.5px;
  font-weight: 600;
  border-radius: var(--r-md);
  border-bottom: 0;
  transition: color .2s var(--ease-out);
}

/* No chip behind any row. The current page is marked by black, heavier text;
   a hovered row turns brand yellow. */
.site-drawer__nav a { color: var(--muted); background: none; }
.site-drawer__nav a:hover,
.site-drawer__nav a:focus-visible { color: var(--brand); background: none; }
.site-drawer__nav a[aria-current="page"] {
  color: var(--ink);
  font-weight: 800;
  background: none;
}
.site-drawer__cta { margin-top: 20px; }
.site-drawer__login { margin-top: 8px; }
body.drawer-open { overflow: hidden; }

/* ── Log-in dialog ───────────────────────────────────────── */

/* The ribbon's secondary button is white glass; over a dark band it takes the
   same ghost treatment as the menu toggle so it does not glow. */
.topbar.is-onDark .topbar-login {
  color: #fff;
  background: rgba(255, 255, 255, .1);
  border-color: rgba(255, 255, 255, .2);
  box-shadow: none;
}
.topbar.is-onDark .topbar-login:hover { background: rgba(255, 255, 255, .18); }

/* ── Buttons ─────────────────────────────────────────────── */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 43px; padding: 0 21px;
  border-radius: var(--r-pill);
  font-family: var(--font);
  font-size: 14.5px;
  font-weight: 650;
  letter-spacing: -0.015em;
  border: 1px solid transparent;
  cursor: pointer;
  text-align: center;
  transition: transform .22s var(--ease), background .22s var(--ease-out),
              border-color .22s var(--ease-out), color .22s var(--ease-out),
              box-shadow .22s var(--ease-out);
}
.btn:active { transform: translateY(0) scale(.98); }

.btn-primary {
  background: linear-gradient(180deg, var(--brand-hi), var(--brand));
  color: var(--brand-ink);
  border-color: rgba(0, 0, 0, .08);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .08),
              0 12px 26px -14px var(--brand-glow),
              inset 0 1px 0 rgba(255, 255, 255, .65);
}
.btn-primary:hover {
  background: linear-gradient(180deg, var(--brand), var(--brand-lo));
  border-color: rgba(0, 0, 0, .1);
}

.btn-secondary {
  background: rgba(255, 255, 255, .6);
  -webkit-backdrop-filter: var(--blur);
  backdrop-filter: var(--blur);
  color: var(--text);
  border-color: var(--hairline-mid);
  box-shadow: var(--shadow-sm), var(--edge);
}
.btn-secondary:hover {
  background: rgba(226, 226, 230, .95);
  border-color: var(--hairline-strong);
  box-shadow: var(--shadow-sm), var(--edge);
}

.btn-dark {
  background: var(--ink);
  color: #fff;
  border-color: var(--ink);
  box-shadow: 0 12px 26px -16px rgba(0, 0, 0, .7);
}
.btn-dark:hover { background: #33333a; border-color: #33333a; }

.btn-onDark { background: #fff; color: var(--ink); border-color: #fff; }
.btn-onDark:hover { background: #d9d9de; border-color: #d9d9de; }

.btn-ghostOnDark {
  background: rgba(255, 255, 255, .07);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  color: #fff;
  border-color: rgba(255, 255, 255, .16);
  box-shadow: var(--edge-d);
}
.btn-ghostOnDark:hover {
  background: rgba(255, 255, 255, .22);
  border-color: rgba(255, 255, 255, .34);
}

.btn-sm { min-height: 33px; padding: 0 15px; font-size: 13px; }
.btn-block { width: 100%; }
.btn-row { display: flex; flex-wrap: wrap; gap: 12px; }
/* Centred on the button's height and still on hover. */
.btn__icon {
  display: block;
  width: 16px; height: 16px; flex: none;
  align-self: center;
}
.btn-sm .btn__icon { width: 14px; height: 14px; }

/* ── Section furniture ───────────────────────────────────── */

.section { padding: clamp(58px, 7.4vw, 104px) 0; position: relative; }
.section--tight { padding: clamp(48px, 6vw, 80px) 0; }
/* Two sections that carry on the same thought sit closer together:
   --join tightens its own top and the bottom of the section above it,
   so the pair reads as one run rather than two separated blocks. */
.section--join { padding-top: clamp(28px, 3.2vw, 46px); }
.section:has(+ .section--join) { padding-bottom: clamp(28px, 3.2vw, 46px); }

/* Floating panels: sunken, dark and claim bands are inset cards
   rather than full-bleed stripes. */
.section--sunken,
.section.band-dark,
.claim-band {
  width: min(1280px, calc(100% - 28px));
  margin-inline: auto;
  margin-block: clamp(16px, 2.2vw, 30px);
  border-radius: var(--r-panel);
  position: relative;
  overflow: hidden;
  isolation: isolate;
}

.section--sunken {
  background: linear-gradient(180deg, rgba(255, 255, 255, .72), rgba(255, 255, 255, .34));
  -webkit-backdrop-filter: var(--blur);
  backdrop-filter: var(--blur);
  border: 1px solid var(--glass-edge);
  box-shadow: var(--ring), 0 20px 48px -34px rgba(0, 0, 0, .3), var(--edge);
}

/* A section heading stands on its own — no subtitle line under it — so
   the heading itself carries the gap down to the content. */
.section h2 {
  font-size: clamp(1.85rem, 3.5vw, 2.9rem);
  line-height: 1.06;
  margin: 0 0 clamp(26px, 3.4vw, 42px);
  letter-spacing: -0.042em;
}

/* Prose that is a section's own body, not a description of its heading. */
.section-copy {
  margin: 0 0 18px;
  font-size: clamp(1rem, 1.5vw, 1.08rem);
  line-height: 1.66;
  max-width: 44em;
}

.section-copy:last-child { margin-bottom: 0; }

/* Same grey and size the cap-lists use, for prose that replaced a bullet list. */
.section-copy--muted {
  color: var(--muted);
  font-size: .97rem;
  line-height: 1.58;
}

.rule { border: 0; border-top: 1px solid var(--hairline); margin: 0; }

.kicker {
  font-family: var(--font-head);
  font-size: 13px;
  font-weight: var(--w-title);
  letter-spacing: -0.01em;
  color: var(--text);
  margin: 0 0 14px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 14px 6px 11px;
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .6);
  border: 1px solid var(--glass-edge);
  box-shadow: var(--ring), var(--edge);
}
.kicker::before {
  content: "";
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--brand);
  box-shadow: 0 0 0 3px var(--brand-wash);
  flex: none;
}
.band-dark .kicker {
  color: #fff;
  background: var(--glass-d);
  border-color: var(--glass-d-edge);
  box-shadow: var(--edge-d);
}

/* ── Hero ────────────────────────────────────────────────── */

.hero-shell {
  padding: clamp(36px, 6vw, 76px) 0 clamp(34px, 5vw, 64px);
  position: relative;
  /* Clip sideways only. `overflow: hidden` would also cut the aurora below
     flat against the top edge of the section, drawing a hard yellow line
     directly under the ribbon — and another under the short page heroes.
     `clip` keeps the over-wide glow off the horizontal axis while letting
     it bleed vertically, which is the whole point of an ambient glow. */
  overflow: visible;
  overflow-x: clip;
}

/* The homepage hero is a full first screen: viewport height less the
   ribbon it sits under, with the content optically centred. min-height,
   not height — on a short window or a phone the content still grows the
   section rather than being clipped.

   It has no surface of its own. The hero sits straight on the page ground
   and the aurora below is its background, so the first screen is the site's
   own light rather than a panel laid over it — every framed thing here (the
   kicker, the buttons, the orbit) is glass floating on that ground. */
.hero-shell:has(.hero) {
  display: flex;
  align-items: center;
  min-height: calc(100vh - 70px);
  min-height: calc(100svh - 70px);
  padding-top: clamp(24px, 3vw, 40px);
  padding-bottom: clamp(24px, 3vw, 40px);
}

/* Aurora behind the headline. */
.hero-shell::before {
  content: "";
  position: absolute;
  top: -34vh; left: 50%;
  width: min(1500px, 140vw); height: min(1100px, 130vh);
  transform: translateX(-50%);
  /* Behind everything, not just the hero: now that it is free to bleed past
     the section it paints over whatever follows a short page hero unless it
     is pushed below the content layer. It still lands above the body wash,
     which is also at -1 but earlier in tree order. */
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(38% 36% at 26% 42%, rgba(255, 223, 0, .34), transparent 70%),
    radial-gradient(34% 32% at 74% 32%, rgba(255, 223, 0, .18), transparent 72%),
    radial-gradient(30% 30% at 52% 66%, rgba(255, 255, 255, .85), transparent 70%);
  filter: blur(18px);
}

.hero-shell > .container { position: relative; z-index: 1; }

.hero {
  display: grid;
  gap: clamp(38px, 5vw, 60px);
  align-items: center;
  grid-template-columns: 1fr;
}
.hero-copy { min-width: 0; }

.hero h1 {
  font-size: clamp(2.6rem, 5.4vw, 4.35rem);
  line-height: 1;
  letter-spacing: -0.058em;
  margin: 0 0 22px;
  font-weight: var(--w-display);
  color: var(--text);
}

.hero-lead {
  margin: 0 0 34px;
  font-size: clamp(1.02rem, 1.5vw, 1.16rem);
  line-height: 1.55;
  color: var(--text-2);
  max-width: 27em;
}

/* ── Hero mock: the orbit ────────────────────────────────────
   The first screen does not show a screenshot. It shows the
   product's shape: the soshctrl "o" at the centre, the four
   accounts it publishes to placed around it, and your approval
   sitting on the ring between them. No words — the headline
   already said it.

   Geometry lives in one 400×400 SVG so the rings, the spokes
   and the travelling sweep stay exactly concentric at every
   size. Everything that has to be a real element — the glass
   core, the account chips, the gate — is HTML laid over it at
   percentages taken from the same viewBox:

       outer track   r 156  →  39% of the stage
       dashed ring   r 118  →  29.5%
       core disc     r  84  →  21%   (inset 29%)

   Diagonal placement is 39% × cos45° = 27.58% off centre.
   ────────────────────────────────────────────────────────── */

.hero-mock { min-width: 0; }

.orbit {
  position: relative;
  width: min(100%, 520px);
  aspect-ratio: 1;
  margin-inline: auto;
}

/* The light the whole thing sits in. Larger than the stage on purpose —
   it reads as the hero's own aurora gathering at the mark rather than as
   a glow bolted onto a graphic. */
.orbit__glow {
  position: absolute;
  inset: -14%;
  border-radius: 50%;
  pointer-events: none;
  background:
    radial-gradient(closest-side, rgba(255, 223, 0, .34), rgba(255, 223, 0, .08) 58%, transparent 74%),
    radial-gradient(closest-side at 50% 58%, rgba(255, 255, 255, .9), transparent 62%);
  filter: blur(6px);
}

.orbit__geo {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  overflow: visible;
}

.orbit__rim   { stroke: rgba(0, 0, 0, .05); stroke-width: 1; }
.orbit__track { stroke: rgba(0, 0, 0, .1);  stroke-width: 1; }

/* Counter-rotating tick ring. Slow enough that you notice it only after the
   sweep — two speeds in the same picture is what stops it reading as a logo. */
.orbit__dash {
  stroke: rgba(0, 0, 0, .16);
  stroke-width: 1;
  stroke-dasharray: 2 9;
  stroke-linecap: round;
  transform-box: view-box;
  transform-origin: 200px 200px;
  animation: orbit-spin 64s linear infinite reverse;
}

.orbit__spokes path {
  stroke: rgba(0, 0, 0, .13);
  stroke-width: 1;
  stroke-linecap: round;
}

/* The run itself: one bright arc travelling the track, with the live pip on
   its leading edge. Circumference at r156 is 980, so 150 on / 830 off is a
   55° arc — long enough to read as motion, short enough not to become a ring.
   Both share the one animation, so the pip never drifts off the arc. */
.orbit__sweep {
  stroke: var(--brand);
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-dasharray: 150 830;
  filter: drop-shadow(0 0 7px var(--brand-glow));
  transform-box: view-box;
  transform-origin: 200px 200px;
  animation: orbit-spin 11s linear infinite;
}

.orbit__pip {
  fill: var(--brand);
  stroke: var(--brand-deep);
  stroke-width: 1;
  filter: drop-shadow(0 0 9px var(--brand-glow));
  transform-box: view-box;
  transform-origin: 200px 200px;
  animation: orbit-spin 11s linear infinite;
}

@keyframes orbit-spin {
  to { transform: rotate(360deg); }
}

/* ── The core: the mark, under glass ─────────────────────── */

.orbit__core {
  position: absolute;
  inset: 29%;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background:
    radial-gradient(115% 115% at 30% 18%, rgba(255, 255, 255, .95), rgba(255, 255, 255, .58) 62%),
    var(--brand-wash);
  -webkit-backdrop-filter: var(--blur-lg);
  backdrop-filter: var(--blur-lg);
  border: 1px solid rgba(255, 255, 255, .85);
  box-shadow:
    0 0 0 1px rgba(0, 0, 0, .05),
    0 10px 24px -14px rgba(0, 0, 0, .18),
    0 44px 80px -38px rgba(0, 0, 0, .42),
    inset 0 1px 0 rgba(255, 255, 255, .95);
  animation: orbit-breathe 9s ease-in-out infinite;
}

.orbit__mark {
  width: 44%;
  height: auto;
  display: block;
  /* The glyph is optically heavy at the foot — nudging it up centres the
     counter, not the bounding box. */
  transform: translateY(-1.5%);
}

@keyframes orbit-breathe {
  0%, 100% { transform: translateY(0)    scale(1);     }
  50%      { transform: translateY(-7px) scale(1.018); }
}

/* ── The gate: your approval, sitting on the track ───────── */

.orbit__gate {
  position: absolute;
  top: 11%; left: 50%;
  transform: translate(-50%, -50%);
  display: grid;
  place-items: center;
  width: clamp(30px, 7.4%, 40px);
  aspect-ratio: 1;
  border-radius: 50%;
  color: var(--brand-ink);
  background: linear-gradient(180deg, var(--brand-hi), var(--brand));
  border: 1px solid rgba(0, 0, 0, .08);
  box-shadow:
    0 8px 18px -8px var(--brand-glow),
    0 0 0 6px rgba(255, 255, 255, .6),
    inset 0 1px 0 rgba(255, 255, 255, .65);
}
.orbit__gate svg { width: 52%; height: 52%; }

/* ── The accounts ────────────────────────────────────────── */

.orbit__node {
  position: absolute;
  display: grid;
  place-items: center;
  width: clamp(46px, 11.5%, 60px);
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  color: var(--ink);
  background: rgba(255, 255, 255, .72);
  -webkit-backdrop-filter: var(--blur);
  backdrop-filter: var(--blur);
  border: 1px solid rgba(255, 255, 255, .9);
  box-shadow:
    0 0 0 1px rgba(0, 0, 0, .045),
    0 10px 22px -14px rgba(0, 0, 0, .3),
    inset 0 1px 0 rgba(255, 255, 255, .95);
}
.orbit__node svg { width: 46%; height: 46%; }

.orbit__node--yt { left: 77.58%; top: 22.42%; }
.orbit__node--ig { left: 22.42%; top: 22.42%; }
.orbit__node--tt { left: 22.42%; top: 77.58%; }
.orbit__node--fb { left: 77.58%; top: 77.58%; }

/* A post landing. Each account pings on its own beat, so the four of them
   read as one publish fanning out rather than as a synchronised blink. */
.orbit__node::after {
  content: "";
  position: absolute;
  inset: -1px;
  border-radius: 50%;
  border: 1.5px solid var(--brand);
  opacity: 0;
  animation: orbit-ping 11s var(--ease-out) infinite;
}
.orbit__node--tt::after { animation-delay: 2.15s; }
.orbit__node--ig::after { animation-delay: 4.9s; }
.orbit__node--yt::after { animation-delay: 7.65s; }
.orbit__node--fb::after { animation-delay: 10.4s; }

@keyframes orbit-ping {
  0%       { opacity: 0;   transform: scale(1);    }
  4%       { opacity: .85; transform: scale(1);    }
  16%      { opacity: 0;   transform: scale(1.42); }
  100%     { opacity: 0;   transform: scale(1.42); }
}

/* ── Claim band — the yellow statement panel ─────────────── */

.claim-band {
  padding: clamp(54px, 6vw, 84px) 0;
  text-align: center;
  color: var(--brand-ink);
  background: linear-gradient(150deg, var(--brand-hi) 0%, var(--brand) 52%, #f7d000 100%);
  border: 1px solid rgba(0, 0, 0, .08);
  box-shadow:
    0 0 0 1px rgba(255, 255, 255, .5) inset,
    0 30px 70px -40px var(--brand-glow);
}
.claim-band::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    radial-gradient(60% 70% at 18% 8%, rgba(255, 255, 255, .6), transparent 66%),
    radial-gradient(50% 60% at 88% 96%, rgba(0, 0, 0, .07), transparent 68%);
}
.claim-band__inner { position: relative; }

.claim-band__kicker {
  font-family: var(--font-head);
  font-size: 13px;
  font-weight: var(--w-title);
  color: rgba(10, 10, 11, .6);
  margin: 0 0 16px;
}

.claim-band h2 {
  margin: 0 auto 18px;
  max-width: 18em;
  font-size: clamp(1.9rem, 4vw, 3.15rem);
  line-height: 1.04;
  letter-spacing: -0.045em;
  color: var(--brand-ink);
}
/* The band is the headline alone unless something is set under it — that
   trailing 18px would otherwise sit inside the panel as uneven padding. */
.claim-band h2:last-child { margin-bottom: 0; }

/* A chip that takes a whole line of its own (Security). The ink box is
   taller than the glyphs it wraps, so at 1.04 leading it closes over the
   descenders of the line above; this gives the line box room for it. The
   homepage keeps the tighter setting — its chip ends a line under one that
   has no descenders. */
.claim-band--stack h2 { line-height: 1.24; }

.claim-band p {
  margin: 0 auto;
  max-width: 34em;
  font-size: clamp(1rem, 1.8vw, 1.14rem);
  line-height: 1.58;
  color: rgba(10, 10, 11, .66);
}

/* ── Dashboard shot — the app's home screen, set in the yellow band ──
   Built in markup rather than a PNG so it stays sharp and needs no
   real account name: the user is shown as "user". Everything inside
   is ranged left like the app itself; only the caption is centred. */

.dash-shot {
  margin: clamp(30px, 4vw, 48px) auto 0;
  max-width: 1040px;
}
/* The caption closes the band, so the band's generous bottom padding would
   sit as dead yellow under one line of text — trim it here. */
.claim-band:has(.dash-shot) { padding-bottom: clamp(26px, 3vw, 38px); }
.dash-shot figcaption {
  margin: 18px auto 0;
  max-width: none;
  text-wrap: balance;
  font-size: clamp(.95rem, 1.6vw, 1.06rem);
  line-height: 1.5;
  color: rgba(10, 10, 11, .66);
}

.dash {
  display: grid;
  grid-template-columns: 222px minmax(0, 1fr);
  gap: 8px;
  padding: 8px 8px 8px 0;
  text-align: left;
  font-size: 13px;
  line-height: 1.35;
  font-weight: 400;
  color: var(--ink);
  background: #f6f6f7;
  border-radius: 20px;
  border: 1px solid rgba(0, 0, 0, .1);
  box-shadow: 0 2px 6px -2px rgba(0, 0, 0, .08), 0 40px 80px -40px rgba(0, 0, 0, .35);
  overflow: hidden;
}
.dash svg { width: 14px; height: 14px; flex: none; }
.dash b { font-weight: 500; }

/* Sidebar */
.dash__side {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 14px 10px 6px 14px;
}
.dash__brand {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 2px 16px 4px;
  color: #8a8a92;
}
.dash__brand img { height: 20px; width: auto; }
.dash__actions { display: flex; gap: 6px; margin-bottom: 18px; }
.dash__label { padding: 0 8px 6px; font-size: 11.5px; color: #6a6a72; }

.dash-btn {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 6px 9px;
  font-size: 12px;
  white-space: nowrap;
  color: var(--ink);
  background: #fff;
  border: 1px solid rgba(0, 0, 0, .1);
  border-radius: 9px;
}
.dash-btn svg { width: 12px; height: 12px; }
.dash-btn--brand { background: var(--brand); border-color: rgba(0, 0, 0, .04); }
.dash__side .dash-btn--brand svg { fill: currentColor; }
.dash-btn--sm { padding: 4px 9px; font-size: 11.5px; border-radius: 999px; }

.dash-nav {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 7px 8px;
  border-radius: 9px;
}
.dash-nav.is-open { background: #ececef; }
.dash-nav__chev { margin-left: auto; color: #8a8a92; width: 12px !important; height: 12px !important; }
.dash-sub {
  display: flex;
  flex-direction: column;
  margin: 2px 0 2px 16px;
  padding-left: 8px;
  border-left: 1px solid rgba(0, 0, 0, .08);
}
.dash-sub span { padding: 5px 8px; border-radius: 8px; }
.dash-sub .is-current { background: #ececef; }

.dash-user {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: auto;
  padding: 18px 6px 4px;
}
.dash-user svg { margin-left: auto; color: #8a8a92; width: 12px; height: 12px; }
.dash-user__avatar {
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  font-size: 11px;
  border-radius: 50%;
  background: var(--brand);
}

/* Main panel */
.dash__main {
  display: flex;
  flex-direction: column;
  min-width: 0;
  background: #fff;
  border-radius: 14px;
  border: 1px solid rgba(0, 0, 0, .06);
  overflow: hidden;
}
.dash__strip {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 7px 12px;
  font-size: 11.5px;
  color: #6a6a72;
  background: #f4f4f5;
  border-bottom: 1px solid rgba(0, 0, 0, .06);
}
.dash__close { margin-left: auto; }
.dash__crumbs {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 11px 20px;
  color: #6a6a72;
  border-bottom: 1px solid rgba(0, 0, 0, .06);
}
.dash__trail { display: inline-flex; align-items: center; gap: 7px; }
.dash__trail svg { width: 11px; height: 11px; }
.dash__trail b { font-weight: 400; color: var(--ink); }
.dash__tools { display: inline-flex; gap: 14px; }

.dash__body {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 20px;
}
.dash-card {
  border: 1px solid rgba(0, 0, 0, .08);
  border-radius: 14px;
}
.dash-card--hello,
.dash-card__row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
}
.dash-card--hello { padding: 14px 14px 14px 16px; }
.dash-card__title { display: block; font-size: 14px; font-weight: 500; }
.dash-card__title--lg { font-size: 17px; }
.dash-card__sub { display: block; margin-top: 4px; color: #6a6a72; }
.dash-card__btns { display: flex; gap: 6px; }
.dash-card__head { padding: 14px 16px 12px; }

.dash-step {
  display: grid;
  grid-template-columns: 14px minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  padding: 9px 14px 9px 16px;
  border-top: 1px solid rgba(0, 0, 0, .07);
}
.dash-step > svg { align-self: start; margin-top: 2px; color: #6a6a72; }
.dash-step__copy b { display: block; font-weight: 400; }
.dash-step__copy span { display: block; margin-top: 2px; font-size: 11.5px; color: #6a6a72; }

.dash-card--perf { padding: 14px 14px 0 16px; }
.dash-range {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 3px;
  font-size: 12px;
  color: #6a6a72;
  background: #f4f4f5;
  border-radius: 999px;
}
.dash-range span { padding: 3px 9px; border-radius: 999px; }
.dash-range .is-on { color: var(--ink); background: #fff; box-shadow: 0 1px 2px rgba(0, 0, 0, .08); }
.dash-range svg { margin: 0 6px 0 4px; width: 12px; height: 12px; }
.dash-empty {
  padding: 34px 12px 38px;
  text-align: center;
  color: #6a6a72;
}
.dash-empty b { display: block; margin-bottom: 4px; font-weight: 400; color: var(--ink); }

/* A narrow screen drops the sidebar and the extras — except for a shot the
   script scales as a whole (.is-fit), which keeps its full desktop layout. */
@media (max-width: 860px) {
  .dash:not(.is-fit) { grid-template-columns: minmax(0, 1fr); padding: 6px; }
  .dash:not(.is-fit) .dash__side { display: none; }
  .dash:not(.is-fit) :where(.dash-card--hello .dash-btn:first-child,
  .dash-step__copy span) { display: none; }
}
@media (max-width: 520px) {
  .dash:not(.is-fit) .dash__body { padding: 12px; }
  .dash:not(.is-fit) :where(.dash-card__btns,
  .dash-step .dash-btn,
  .dash-range,
  .dash-card--perf .dash-card__sub) { display: none; }
}
/* The home dashboard on a phone: laid out at desktop width and zoomed down
   to the column (the script sets the width and the zoom), so it reads as a
   picture of the real app rather than a cut-down version of it. */
.dash.is-fit { max-width: none; }

/* ── Pipelines page shot — the app's All Pipelines screen, under the
   product page's pipeline box. Built in markup like the home dashboard.
   The caption sits on its left on wide screens, above it on narrow ones. */

.pipes-shot { margin: clamp(48px, 6vw, 84px) 0 0; max-width: none; }
.pipes-shot figcaption {
  margin: 0 0 clamp(18px, 2.4vw, 26px);
  max-width: 40em;
  font-size: clamp(1rem, 1.5vw, 1.08rem);
  line-height: 1.66;
  color: var(--text);
  text-wrap: pretty;
}
/* The section's copy is one short paragraph, set like the caption below,
   sitting close under its heading. */
#pipelines :is(.split__copy, .pipes-shot figcaption) h2 { margin-bottom: clamp(14px, 1.6vw, 20px); }
#pipelines :is(.split__copy, .pipes-shot figcaption) .section-copy { max-width: 30em; text-wrap: pretty; }
@media (min-width: 1100px) {
  .pipes-shot {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 2.4fr);
    gap: clamp(30px, 4vw, 60px);
    align-items: center;
  }
  .pipes-shot figcaption { margin: 0; }
  /* Let the app shot run past the container's right edge, into the
     page margin, but never closer than 24px to the window edge. */
  .pipes-shot .dash { width: calc(100% + clamp(0px, (100vw - 1120px) / 2 - 24px, 140px)); max-width: none; }
}
.pipes-shot .dash__body { gap: 12px; }
.pipes-head { margin-bottom: 6px; }
.pipes-head .dash-card__btns { align-items: center; }
.pipes-count {
  padding: 3px 9px;
  font-size: 11.5px;
  white-space: nowrap;
  color: #6a6a72;
  background: #f4f4f5;
  border-radius: 999px;
}
.pipe-card { display: grid; gap: 8px; padding: 12px 14px 12px 16px; }
.pipe-card__top,
.pipe-card__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.pipe-health {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 8px;
  font-size: 11.5px;
  color: #1f9d5c;
  background: #e8f6ee;
  border-radius: 999px;
}
.pipe-health::before { content: ""; width: 5px; height: 5px; border-radius: 50%; background: currentColor; }
.pipe-card__type { display: inline-flex; align-items: center; gap: 10px; font-size: 11.5px; color: #6a6a72; }
.pipe-card__name { display: inline-flex; align-items: center; gap: 8px; font-size: 14px; font-weight: 500; }
.pipe-card__name svg { color: #8a8a92; font-weight: 400; }
.pipe-card__foot > span:first-child { color: #6a6a72; font-size: 12px; }

@media (max-width: 520px) {
  .pipes-head .dash-card__sub,
  .pipes-count { display: none; }
  .pipes-head .dash-card__btns,
  .pipe-card .dash-card__btns { display: flex; }
  .pipe-card .dash-btn--sm:not(.dash-btn--brand) { display: none; }
}

/* Black marker chip inside the yellow headline. */
.claim-hl {
  color: var(--brand);
  background: var(--ink);
  padding: .04em .28em .1em;
  border-radius: .26em;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}

/* ── Dark bands ──────────────────────────────────────────── */

.band-dark {
  background:
    radial-gradient(120% 130% at 50% -24%, #1d1d20 0%, #0b0b0c 54%, #050505 100%);
  color: #fafafa;
  border: 1px solid rgba(255, 255, 255, .08);
  box-shadow: 0 30px 70px -44px rgba(0, 0, 0, .8);
}
.band-dark::before {
  content: "";
  position: absolute;
  inset: -40% 0 auto;
  height: 90%;
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(42% 46% at 50% 50%, rgba(255, 223, 0, .16), transparent 70%);
}
.band-dark h2 { color: #fff; }
.band-dark .section-copy { color: rgba(250, 250, 250, .78); }

/* Light-on-dark blooms: the same stem that reads as light-and-crisp in black
   on white reads as frail in white on black. One step up on the dark panels
   only — enough to hold the strokes together without turning the copy into a
   different voice. */
.band-dark {
  --w-body: 400;
  /* Redefining the token is not enough on its own: descendants inherit the
     resolved weight from body, not the variable, so the property has to be
     re-declared here for the new value to reach them. */
  font-weight: var(--w-body);
}

/* ── Feature grid ────────────────────────────────────────── */

.feature-grid { display: grid; gap: 14px; grid-template-columns: 1fr; }

.feature-card {
  padding: clamp(24px, 2.6vw, 32px);
  border-radius: var(--r-lg);
  background: rgba(255, 255, 255, .58);
  -webkit-backdrop-filter: var(--blur);
  backdrop-filter: var(--blur);
  border: 1px solid var(--glass-edge);
  box-shadow: var(--ring), var(--shadow-sm), var(--edge);
  transition: transform .4s var(--ease), box-shadow .4s var(--ease), background .4s var(--ease);
}
.feature-card:hover {
  transform: translateY(-4px);
  background: rgba(255, 255, 255, .74);
  box-shadow: var(--ring), var(--shadow-md), var(--edge);
}
.feature-card h3 { margin: 0 0 9px; font-size: 1.18rem; letter-spacing: -0.032em; }
.feature-card p { margin: 0; color: var(--muted); line-height: 1.62; font-size: .97rem; }

/* No box: icon, title and a line straight on the section. */
.feature-card--flat,
.feature-card--flat:hover {
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  box-shadow: none;
  transform: none;
}

.band-dark .feature-card {
  background: var(--glass-d);
  -webkit-backdrop-filter: blur(20px);
  backdrop-filter: blur(20px);
  border-color: var(--glass-d-edge);
  box-shadow: var(--edge-d);
}
.band-dark .feature-card:hover {
  background: var(--glass-d-hi);
  border-color: rgba(255, 255, 255, .16);
  box-shadow: var(--edge-d), 0 24px 50px -30px rgba(0, 0, 0, .9);
}
.band-dark .feature-card h3 { color: #fff; }
.band-dark .feature-card p { color: rgba(250, 250, 250, .66); }

.feature-icon {
  width: 46px; height: 46px;
  display: grid; place-items: center;
  border-radius: 15px;
  margin-bottom: 20px;
  background: linear-gradient(180deg, var(--brand-hi), var(--brand));
  color: var(--brand-ink);
  border: 1px solid rgba(0, 0, 0, .07);
  box-shadow: 0 10px 22px -12px var(--brand-glow), inset 0 1px 0 rgba(255, 255, 255, .65);
}
.band-dark .feature-icon { border-color: rgba(0, 0, 0, .2); }
.feature-icon svg { width: 21px; height: 21px; }

/* No tile: the icon stands on its own, in text colour. */
.feature-icon--bare,
.band-dark .feature-icon--bare {
  width: auto; height: auto;
  display: block;
  border-radius: 0;
  margin-bottom: 16px;
  background: none;
  color: var(--text);
  border: 0;
  box-shadow: none;
}
.band-dark .feature-icon--bare { color: #fff; }
.feature-icon--bare svg { width: 28px; height: 28px; }

/* ── Use cases ───────────────────────────────────────────── */
/* Homepage. Seven jobs strung along a wave: an icon, its label beneath it,
   each one sitting a little above or below its neighbours (`--wave`), with
   one line threaded through every icon. initUseCases draws the line from
   where the icons actually land, so it follows whichever layout the width
   gives: one row, two rows, or a single column. Without the script the
   section still reads, just without the thread. */

#use-cases {
  margin-top: clamp(48px, 6vw, 96px);
  /* The heading sits higher in the panel than a section's usual top pad,
     and `.usecases` takes the space back below it, so the wave itself
     stays where it was. */
  padding-top: clamp(26px, 3.1vw, 42px);
  padding-bottom: clamp(44px, 4.6vw, 64px);
}
#use-cases h2 { text-align: center; }

.usecases {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  justify-items: center;
  gap: 26px 0;
  margin-top: clamp(38px, 4.5vw, 58px);
}

.usecases__line {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
  z-index: 0;
}
.usecases__line path {
  fill: none;
  stroke: var(--hairline-strong);
  stroke-width: 1.25;
  stroke-linecap: round;
}

.usecase {
  position: relative;
  z-index: 1;
  display: grid;
  justify-items: center;
  gap: 12px;
  max-width: 15em;
  text-align: center;
  /* The wave. Each item is nudged off the row by its own offset below. */
  transform: translate(var(--wave-x, 0px), var(--wave-y, 0px));
}

.usecase__icon {
  width: 48px;
  height: 48px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: #fff;
  color: var(--text);
  box-shadow: var(--ring), var(--shadow-sm), var(--edge);
  transition: background .3s var(--ease), transform .3s var(--ease);
}
.usecase__icon svg { width: 22px; height: 22px; }
.usecase:hover .usecase__icon { background: var(--brand); color: var(--brand-ink); }

.usecase h3 {
  margin: 0;
  font-size: 1.04rem;
  line-height: 1.32;
  letter-spacing: -0.03em;
  text-wrap: balance;
}

@media (prefers-reduced-motion: no-preference) {
  .usecase:hover .usecase__icon { transform: translateY(-2px); }
}

/* One column: the wave runs down the page, each item leaning off centre. */
@media (max-width: 699px) {
  .usecases { gap: 22px 0; }
  .usecase:nth-child(odd) { --wave-x: clamp(-52px, -7vw, -22px); }
  .usecase:nth-child(even) { --wave-x: clamp(22px, 7vw, 52px); }
}

/* Two rows of four and three: the labels stay readable, the wave rolls
   across each row. The twelve-column track is what splits 4 / 3 evenly. */
@media (min-width: 700px) {
  .usecases {
    grid-template-columns: repeat(12, minmax(0, 1fr));
    column-gap: clamp(8px, 1.4vw, 20px);
    row-gap: clamp(30px, 4vw, 46px);
    align-items: start;
    /* Each label wraps inside its own column, so a long one never runs
       under its neighbour. */
    justify-items: stretch;
  }
  .usecase { max-width: none; }
  .usecase:nth-child(-n+5) { grid-column: span 3; } /* the <svg> counts too */
  .usecase:nth-child(n+6) { grid-column: span 4; }
  .usecase:nth-child(odd) { --wave-y: -15px; }
  .usecase:nth-child(even) { --wave-y: 15px; }
}

/* Wide: all seven on one line, a full wave through them. */
@media (min-width: 1040px) {
  .usecases {
    grid-template-columns: repeat(7, minmax(0, 1fr));
    column-gap: clamp(4px, 1vw, 14px);
    padding: 30px 0 14px;
  }
  .usecase:nth-child(n) { grid-column: auto; }
  .usecase { max-width: none; }
  .usecase h3 { font-size: .99rem; }

  /* A sine through the seven icons: level, down, level, up, level, down,
     level. The line the script draws joins the dots, so this is the wave. */
  .usecase:nth-child(2) { --wave-y: 0px; }
  .usecase:nth-child(3) { --wave-y: 30px; }
  .usecase:nth-child(4) { --wave-y: 0px; }
  .usecase:nth-child(5) { --wave-y: -30px; }
  .usecase:nth-child(6) { --wave-y: 0px; }
  .usecase:nth-child(7) { --wave-y: 30px; }
  .usecase:nth-child(8) { --wave-y: 0px; }
}

/* ── Play tiles ──────────────────────────────────────────── */
/* The homepage's pipeline claim, with a working toy beside it. Built for
   the dark band only. `.play-demo` ships `hidden`; initPlay unhides it. */

.play-grid { display: grid; gap: 14px; grid-template-columns: minmax(0, 1fr); }

.play-tile {
  display: flex;
  flex-direction: column;
  gap: 22px;
  padding: clamp(22px, 2.6vw, 32px);
  border-radius: var(--r-lg);
  background: var(--glass-d);
  border: 1px solid var(--glass-d-edge);
  box-shadow: var(--edge-d);
  transition: border-color .4s var(--ease), background .4s var(--ease);
}
.play-tile:hover { background: rgba(255, 255, 255, .07); border-color: rgba(255, 255, 255, .15); }
.play-copy h3 { margin: 0 0 8px; font-size: 1.18rem; letter-spacing: -0.032em; color: #fff; }
.play-copy p { margin: 0; max-width: 46ch; color: rgba(250, 250, 250, .66); line-height: 1.62; font-size: .97rem; }

.play-demo { display: flex; flex-direction: column; gap: 14px; margin-top: auto; }
.play-demo[hidden] { display: none; }

.play-label {
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: .02em;
  color: rgba(250, 250, 250, .48);
}

.play-status {
  margin: 0;
  min-height: 1.5em;
  font-size: 13.5px;
  color: rgba(250, 250, 250, .62);
  font-variant-numeric: tabular-nums;
}
.play-status b { color: var(--brand); font-weight: 500; }

.play-btn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-height: 36px;
  padding: 0 14px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, .13);
  background: rgba(255, 255, 255, .06);
  color: #fff;
  font: 500 13.5px/1 var(--font);
  cursor: pointer;
  transition: background .2s var(--ease), border-color .2s var(--ease), transform .2s var(--ease), opacity .2s var(--ease);
}
.play-btn svg { width: 16px; height: 16px; flex: none; }
.play-btn:hover { background: rgba(255, 255, 255, .12); border-color: rgba(255, 255, 255, .22); }
.play-btn:active { transform: scale(.97); }
.play-btn:disabled { opacity: .35; cursor: not-allowed; transform: none; }
.play-btn[hidden] { display: none; }
.play-btn--brand {
  background: var(--brand);
  border-color: var(--brand);
  color: var(--brand-ink);
}
.play-btn--brand:hover { background: var(--brand-hi); border-color: var(--brand-hi); }
.play-btn--quiet { background: transparent; border-color: transparent; color: rgba(250, 250, 250, .66); }
.play-btn--quiet:hover { background: rgba(255, 255, 255, .06); border-color: transparent; color: #fff; }
.play-btn__cost {
  padding: 3px 7px;
  border-radius: 999px;
  background: rgba(255, 255, 255, .1);
  font-size: 11.5px;
  font-variant-numeric: tabular-nums;
  color: rgba(250, 250, 250, .8);
}

/* One pipeline: tap accounts on or off, then post to all of them at once. */
.play-tile--fan .play-demo { align-items: flex-start; gap: 18px; }
.chips { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 8px; }
.chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 40px;
  padding: 0 14px 0 12px;
  border-radius: 999px;
  border: 1px dashed rgba(255, 255, 255, .18);
  background: transparent;
  color: rgba(250, 250, 250, .45);
  font: 500 14px/1 var(--font);
  cursor: pointer;
  transition: background .25s var(--ease), border-color .25s var(--ease), color .25s var(--ease), transform .2s var(--ease);
}
.chip svg { width: 18px; height: 18px; flex: none; }
.chip:hover { border-color: rgba(255, 255, 255, .32); color: rgba(250, 250, 250, .8); }
.chip:active { transform: scale(.97); }
.chip.is-on {
  border-style: solid;
  border-color: rgba(255, 255, 255, .14);
  background: rgba(255, 255, 255, .07);
  color: #fff;
}
.chip.is-posted { border-color: rgba(255, 223, 0, .5); background: rgba(255, 223, 0, .1); color: var(--brand); }

@media (min-width: 960px) {
  .play-tile--fan {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    gap: clamp(28px, 4vw, 64px);
    align-items: center;
  }
  .play-tile--fan .play-demo { margin-top: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .play-btn, .chip { transition: none; }
}

/* ── Steps ───────────────────────────────────────────────── */


/* ── A run, beside the steps it describes ────────────────────
   The six steps on the left are the explanation; the console on
   the right is the same six steps happening. It sticks while
   you read down them, so the row that is live in the console is
   always next to whatever step you are on.

   Light glass, like the stills: it sits in the section rather than
   punching a hole in it. Yellow marks state as fills and spines;
   text on it stays ink, because yellow text is unreadable on white.
   ────────────────────────────────────────────────────────── */

.runview { display: grid; gap: clamp(26px, 3vw, 38px); }

/* Stacked, the console leads — you see the thing before you read the
   six paragraphs about it. */
.runview__side { order: -1; min-width: 0; }

.console {
  position: relative;
  overflow: hidden;
  border-radius: var(--r-lg);
  color: var(--text);
  background:
    radial-gradient(120% 86% at 84% -12%, rgba(255, 223, 0, .16), transparent 56%),
    rgba(255, 255, 255, .62);
  -webkit-backdrop-filter: var(--blur);
  backdrop-filter: var(--blur);
  border: 1px solid var(--glass-edge);
  box-shadow: var(--ring), var(--shadow-md), var(--edge);
}

/* ── Header ──────────────────────────────────────────────── */

.console__bar {
  display: flex; align-items: center; gap: 10px;
  padding: 15px 18px;
  border-bottom: 1px solid var(--hairline);
}

/* The mark, in ink — the glyph is solid black on transparent, so it masks
   cleanly to any colour. */
.console__mark {
  flex: none;
  width: 15px; height: 18px;
  background: var(--ink);
  -webkit-mask: url("assets/mark-dark.png") no-repeat center / contain;
  mask: url("assets/mark-dark.png") no-repeat center / contain;
}

.console__name {
  font-family: var(--font);
  font-size: 12.5px;
  letter-spacing: -0.01em;
  color: var(--text);
}

.console__id {
  margin-right: auto;
  font-family: var(--font);
  font-size: 11px;
  color: var(--faint);
  font-variant-numeric: tabular-nums;
}

.console__state {
  flex: none;
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 11px; font-weight: 600;
  letter-spacing: .04em; text-transform: uppercase;
  padding: 5px 11px 5px 9px;
  border-radius: var(--r-pill);
  color: var(--text);
  background: rgba(255, 223, 0, .34);
  border: 1px solid rgba(212, 182, 0, .5);
}

.console__pulse {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--ink);
  box-shadow: 0 0 0 0 var(--brand-glow);
  animation: console-pulse 2.4s var(--ease-out) infinite;
}

@keyframes console-pulse {
  0%       { box-shadow: 0 0 0 0 rgba(255, 223, 0, .55); }
  70%, 100% { box-shadow: 0 0 0 7px rgba(255, 223, 0, 0); }
}

/* ── Progress: six segments, one per step ────────────────── */

.console__gauge {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 4px;
  padding: 14px 18px 4px;
}

.console__seg {
  height: 3px;
  border-radius: 2px;
  background: rgba(0, 0, 0, .08);
}
.console__seg.is-on { background: var(--brand-deep); }
.console__seg.is-live {
  background: var(--brand);
  box-shadow: 0 0 10px -1px var(--brand-glow);
  animation: console-breathe 2.4s var(--ease-out) infinite;
}

@keyframes console-breathe {
  0%, 100% { opacity: 1; }
  50%      { opacity: .45; }
}

/* ── The rail ────────────────────────────────────────────────
   A spine down the left edge of each row rather than a dot per
   step: solid yellow behind what has run, lit behind the row
   that is live, bare behind what has not started.
   ────────────────────────────────────────────────────────── */

.console__rail { list-style: none; margin: 0; padding: 10px 0 6px; }

.console__rail li {
  position: relative;
  display: flex; align-items: center; gap: 14px;
  padding: 10px 18px 10px 22px;
  font-size: 13.5px;
}

.console__rail li::before {
  content: "";
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 2px;
  background: rgba(0, 0, 0, .08);
}
.console__rail li.is-done::before { background: var(--brand-deep); }
.console__rail li.is-now::before {
  background: var(--brand);
  box-shadow: 0 0 14px 1px var(--brand-glow);
}

.console__rail li.is-now {
  background: linear-gradient(90deg, rgba(255, 223, 0, .24), rgba(255, 223, 0, 0) 70%);
}

.console__i {
  flex: none;
  font-family: var(--font);
  font-size: 11px;
  letter-spacing: .05em;
  color: var(--faint);
  font-variant-numeric: tabular-nums;
}

.console__label {
  margin-right: auto;
  font-weight: 500;
  color: var(--text-2);
  letter-spacing: -0.012em;
}

.console__meta {
  flex: none;
  font-family: var(--font);
  font-size: 11px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.console__rail li.is-done .console__i    { color: var(--muted); }
.console__rail li.is-now  .console__i    { color: var(--text); }
.console__rail li.is-now  .console__label { color: var(--text); font-weight: 600; }
.console__rail li.is-now  .console__meta  { color: var(--text); font-weight: 600; }
.console__rail li.is-next .console__i,
.console__rail li.is-next .console__label,
.console__rail li.is-next .console__meta { color: var(--faint); }

/* ── The three ways out ──────────────────────────────────── */

.console__foot {
  display: flex; gap: 8px;
  padding: 14px 16px 16px;
  border-top: 1px solid var(--hairline);
}

.console__act {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--font);
  font-size: 12.5px; font-weight: 600;
  letter-spacing: -0.012em;
  line-height: 1.2;
  padding: 9px 15px;
  border-radius: var(--r-pill);
  color: var(--text-2);
  background: rgba(0, 0, 0, .035);
  border: 1px solid rgba(0, 0, 0, .1);
  transition: background .25s var(--ease), color .25s var(--ease), opacity .3s var(--ease), transform .25s var(--ease), box-shadow .25s var(--ease);
}
.console__act svg { width: 14px; height: 14px; margin-left: -3px; }
.console__act--go {
  color: var(--brand-ink);
  background: linear-gradient(180deg, var(--brand-hi), var(--brand));
  border-color: rgba(0, 0, 0, .1);
  box-shadow: 0 10px 22px -12px var(--brand-glow), inset 0 1px 0 rgba(255, 255, 255, .6);
}

.console__cap {
  margin: 14px 2px 0;
  font-size: .85rem;
  color: var(--muted);
}

/* ── What the selected step produced ─────────────────────── */

.console__detail {
  position: relative;
  padding: 14px 18px 16px;
  border-top: 1px solid var(--hairline);
  background: rgba(0, 0, 0, .015);
}

.run-panel { display: grid; gap: 10px; align-content: start; }
.run-panel[hidden] { display: none; }

.run-panel__k {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 11px; font-weight: 600;
  letter-spacing: .04em; text-transform: uppercase;
  color: var(--text);
}
.run-panel__k svg { width: 14px; height: 14px; }
.run-panel__k--stop { color: var(--muted); }

.run-panel__title {
  margin: 0;
  font-size: 15px; font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--text);
  line-height: 1.35;
}

.run-panel__quote,
.run-panel__caption {
  margin: 0;
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--text-2);
}

.run-panel__caption {
  padding: 10px 12px;
  border-radius: 12px;
  background: rgba(0, 0, 0, .035);
  border: 1px solid rgba(0, 0, 0, .08);
  transition: border-color .25s var(--ease), background .25s var(--ease), box-shadow .25s var(--ease);
}
.run-panel__caption[contenteditable="true"] {
  outline: none;
  color: var(--text);
  background: #fff;
  border-color: var(--brand-deep);
  box-shadow: 0 0 0 3px rgba(255, 223, 0, .3);
  cursor: text;
}

.run-panel__more { font-size: 11.5px; color: var(--muted); }

.run-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.run-chip {
  font-size: 11.5px; font-weight: 500;
  padding: 4px 10px;
  border-radius: var(--r-pill);
  color: var(--text-2);
  background: rgba(0, 0, 0, .05);
  border: 1px solid rgba(0, 0, 0, .08);
}
.run-chip--mute { color: var(--muted); background: none; }

.run-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.run-list li {
  display: flex; align-items: baseline; gap: 12px;
  padding: 5px 0;
  font-size: 13px;
  color: var(--text-2);
}
.run-list span { margin-right: auto; }
.run-list em { font-style: normal; font-size: 11.5px; color: var(--muted); }

.run-media { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.run-media__tile {
  display: grid; gap: 2px;
  padding: 11px 12px;
  border-radius: 12px;
  background: linear-gradient(160deg, rgba(255, 223, 0, .26), rgba(255, 255, 255, .5) 60%);
  border: 1px solid rgba(0, 0, 0, .08);
}
.run-media__tile svg { width: 18px; height: 18px; margin-bottom: 6px; color: var(--ink); }
.run-media__tile b { font-size: 12.5px; font-weight: 600; color: var(--text); }
.run-media__tile em { font-style: normal; font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums; }

.run-cap { display: flex; align-items: center; gap: 12px; margin-top: 2px; }
.run-cap__bar {
  flex: 1;
  height: 4px;
  border-radius: 2px;
  background: rgba(0, 0, 0, .08);
  overflow: hidden;
}
.run-cap__fill {
  display: block;
  width: 1.56%;
  min-width: 4px;
  height: 100%;
  border-radius: inherit;
  background: var(--brand-deep);
}
.run-cap__txt { flex: none; font-size: 11.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
.run-cap__txt b { color: var(--text); font-weight: 600; }

.run-accts { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px; }
.run-accts li {
  display: flex; align-items: center; gap: 9px;
  padding: 8px 10px;
  border-radius: 10px;
  font-size: 12.5px; font-weight: 500;
  color: var(--text);
  background: rgba(0, 0, 0, .03);
  border: 1px solid rgba(0, 0, 0, .07);
}
.run-accts svg { flex: none; width: 16px; height: 16px; }
.run-accts span { margin-right: auto; }
.run-accts em { font-style: normal; font-size: 11px; font-weight: 600; color: var(--text); }

/* ── Live: site.js drives the console from the steps ─────── */

.console__replay {
  display: none;
  margin-left: auto;
  align-items: center; gap: 6px;
  font-family: var(--font);
  font-size: 12px; font-weight: 500;
  padding: 8px 10px;
  border: 0;
  border-radius: var(--r-pill);
  color: var(--muted);
  background: none;
  cursor: pointer;
  transition: color .2s var(--ease), background .2s var(--ease);
}
.console__replay svg { width: 15px; height: 15px; transition: transform .5s var(--ease); }
.console__replay:hover { color: var(--text); background: rgba(0, 0, 0, .05); }
.console__replay:hover svg { transform: rotate(-180deg); }
.is-live .console__replay:not([hidden]) { display: inline-flex; }
.console__replay:focus-visible,
.console__act:focus-visible { outline: 2px solid var(--brand-deep); outline-offset: 2px; }

.is-live .console__act { cursor: pointer; }
.is-live .console__act:disabled { cursor: default; opacity: .32; box-shadow: none; }
.is-live .console__act:not(:disabled):not(.console__act--go):hover { color: var(--text); background: rgba(0, 0, 0, .07); }
.is-live .console__act--go:not(:disabled):hover {
  transform: translateY(-1px);
  box-shadow: 0 14px 26px -12px var(--brand-glow), inset 0 1px 0 rgba(255, 255, 255, .6);
}
.is-live .console__act--go:not(:disabled) { animation: run-call 2.4s var(--ease-out) infinite; }
.console__act[aria-pressed="true"] { color: #fff; background: var(--ink); border-color: var(--ink); }

@keyframes run-call {
  0%        { box-shadow: 0 0 0 0 rgba(255, 223, 0, .5), 0 10px 22px -12px var(--brand-glow); }
  70%, 100% { box-shadow: 0 0 0 9px rgba(255, 223, 0, 0), 0 10px 22px -12px var(--brand-glow); }
}

.is-live .console__detail { min-height: 146px; }
.run-panel.is-entering { animation: run-in .45s var(--ease-smooth) both; }
@keyframes run-in {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}

/* The four accounts land one after another once you approve. */
.is-live .run-accts li { transition: opacity .4s var(--ease), transform .4s var(--ease), border-color .4s var(--ease); }
.is-live .run-accts em { transition: opacity .3s var(--ease); }
.is-live .run-panel:not(.is-posted) .run-accts li { opacity: .4; transform: translateY(3px); }
.is-live .run-panel:not(.is-posted) .run-accts em { opacity: 0; }
.run-panel.is-posted .run-accts li { border-color: rgba(212, 182, 0, .5); background: rgba(255, 223, 0, .16); }
.run-panel.is-posted .run-accts li:nth-child(2),
.run-panel.is-posted .run-accts li:nth-child(2) em { transition-delay: .12s; }
.run-panel.is-posted .run-accts li:nth-child(3),
.run-panel.is-posted .run-accts li:nth-child(3) em { transition-delay: .24s; }
.run-panel.is-posted .run-accts li:nth-child(4),
.run-panel.is-posted .run-accts li:nth-child(4) em { transition-delay: .36s; }

.is-live .console__rail li { cursor: pointer; transition: background .25s var(--ease); }
.is-live .console__rail li:hover { background: rgba(0, 0, 0, .03); }
.is-live .console__rail li.is-now:hover { background: linear-gradient(90deg, rgba(255, 223, 0, .32), rgba(255, 223, 0, 0) 70%); }
.console__rail li::before { transition: background .35s var(--ease), box-shadow .35s var(--ease); }
.console__rail li.is-stop::before { background: var(--ink); }
.console__rail li.is-stop .console__i,
.console__rail li.is-stop .console__meta { color: var(--text-2); }
.console__rail li.is-stop .console__label { color: var(--text); font-weight: 600; }

.console__seg { position: relative; overflow: hidden; transition: background .35s var(--ease); }
.console__seg.is-stop { background: var(--ink); }
/* While the run plays, the live segment fills over the time the step is
   shown; its animationend is what moves the run on. */
.console__seg.is-timing { animation: none; background: rgba(255, 223, 0, .3); }
.console__seg.is-timing::after {
  content: "";
  position: absolute; inset: 0;
  background: var(--brand);
  transform-origin: left center;
  animation: run-fill 1.9s linear both;
}
@keyframes run-fill {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

.console__state { transition: color .3s var(--ease), background .3s var(--ease), border-color .3s var(--ease); }
.console__state.is-done { color: var(--brand-ink); background: var(--brand); border-color: var(--brand); }
.console__state.is-stop { color: #fff; background: var(--ink); border-color: var(--ink); }
.console__state.is-done .console__pulse,
.console__state.is-stop .console__pulse { animation: none; background: currentColor; }

/* The steps, as controls. Each whole row is the button's hit area; the
   selected one lifts onto a glass card and its number turns yellow. */
.step__go {
  font: inherit;
  letter-spacing: inherit;
  color: inherit;
  text-align: left;
  padding: 0;
  margin: 0;
  border: 0;
  background: none;
}

.runview.is-live .step,
.runview.is-live .step:first-child,
.runview.is-live .step:last-child {
  position: relative;
  isolation: isolate;
  padding-block: 13px;
  cursor: pointer;
}
.runview.is-live .step::before {
  content: "";
  position: absolute;
  inset: 0 -18px;
  z-index: -1;
  border-radius: 18px;
  background: rgba(255, 255, 255, .9);
  box-shadow: var(--ring), var(--shadow-md), var(--edge);
  opacity: 0;
  transform: scale(.985);
  transition: opacity .35s var(--ease), transform .35s var(--ease);
}
.runview.is-live .step__go { cursor: pointer; }
.runview.is-live .step__go::after { content: ""; position: absolute; inset: 0 -18px; border-radius: 18px; }
.runview.is-live .step__go:focus-visible { outline: none; }
.runview.is-live .step__go:focus-visible::after { outline: 2px solid var(--ink); outline-offset: 2px; }

.runview.is-live .step:hover::before { opacity: .45; transform: none; }
.runview.is-live .step.is-current::before { opacity: 1; transform: none; }
.runview.is-live .step.is-current,
.runview.is-live .step.is-current + .step { border-top-color: transparent; }

.runview.is-live .step h3 { color: var(--text-2); transition: color .3s var(--ease); }
.runview.is-live .step.is-current h3 { color: var(--ink); }
.runview.is-live .step p { transition: color .3s var(--ease); }
.runview.is-live .step.is-current p { color: var(--text-2); }

/* Thin rows: the number is plain text on the heading's line, no chip. */
.runview .step { grid-template-columns: auto minmax(0, 1fr); gap: 14px; align-items: baseline; }
.runview .step h3 { margin: 0 0 3px; font-size: 1.02rem; }
.runview .step p { font-size: .92rem; line-height: 1.5; }
.runview .step__n {
  width: auto; height: auto;
  min-width: 1.4em;
  display: block;
  border-radius: 0;
  background: none;
  box-shadow: none;
  color: var(--faint);
  font-size: .92rem;
  font-variant-numeric: tabular-nums;
  transition: color .3s var(--ease);
}
.runview.is-live .step.is-done .step__n { color: var(--muted); }
.runview.is-live .step.is-current .step__n { color: var(--ink); }

@media (prefers-reduced-motion: reduce) {
  .run-panel.is-entering,
  .is-live .console__act--go:not(:disabled) { animation: none; }
}

@media (max-width: 600px) {
  .runview.is-live .step::before,
  .runview.is-live .step__go::after { inset: 0 -12px; }
  .run-media { grid-template-columns: minmax(0, 1fr); }
  .run-accts { grid-template-columns: minmax(0, 1fr); }
  .run-media__tile { grid-template-columns: auto 1fr auto; align-items: center; gap: 10px; }
  .run-media__tile svg { margin: 0; }
}
.steps { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }

.step {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 18px;
  align-items: start;
  padding: clamp(20px, 2.2vw, 26px) clamp(20px, 2.4vw, 28px);
  border-radius: var(--r-lg);
  border: 1px solid var(--glass-edge);
  background: rgba(255, 255, 255, .62);
  box-shadow: var(--ring), var(--shadow-sm), var(--edge);
  transition: transform .4s var(--ease), background .4s var(--ease), box-shadow .4s var(--ease);
}
.step:hover {
  transform: translateY(-3px);
  background: rgba(255, 255, 255, .78);
  box-shadow: var(--ring), var(--shadow-md), var(--edge);
}
.step:last-child { border-bottom: 1px solid var(--glass-edge); }

.step__n {
  flex: none;
  width: 36px; height: 36px;
  display: grid; place-items: center;
  border-radius: 12px;
  background: var(--ink);
  color: var(--brand);
  font-family: var(--font-head);
  font-weight: var(--w-title);
  font-size: .92rem;
  box-shadow: 0 8px 18px -10px rgba(0, 0, 0, .6);
}

.step h3 { margin: 5px 0 7px; font-size: 1.1rem; letter-spacing: -0.032em; }
.step p { margin: 0; color: var(--muted); line-height: 1.62; font-size: .97rem; max-width: 46em; }

.section--sunken .step { background: rgba(255, 255, 255, .6); }
.band-dark .step {
  background: var(--glass-d);
  border-color: var(--glass-d-edge);
  box-shadow: var(--edge-d);
}
.band-dark .step h3 { color: #fff; }
.band-dark .step p { color: rgba(250, 250, 250, .66); }
.band-dark .step__n { background: var(--brand); color: var(--brand-ink); }

/* ── The run, step by step (homepage #how) ───────────────────
   Six steps down the left, the matching still on the right.
   Pressing a step opens its note under the heading and brings
   its still forward.

   The stage overlaps every still in one grid cell and crossfades
   between them on `is-current` alone, so it never resizes as you
   move down the list and the whole interaction needs no timers —
   `visibility` is what takes the hidden ones out of the tab order
   and out of the accessibility tree.

   Nothing here is load-bearing: without `is-flow` — no script —
   every note and every still is simply on the page, in order.
   ────────────────────────────────────────────────────────── */

.flow { display: grid; gap: clamp(22px, 3vw, 30px); align-items: start; }

.flow__rail { display: grid; }

.flow__row {
  display: grid;
  grid-template-rows: auto auto;
  padding: clamp(16px, 2vw, 22px) 0;
  border-top: 1px solid var(--hairline-strong);
}
.flow__row:first-child { border-top: 0; padding-top: 0; }

.flow__head { margin: 0; }

.flow__trigger {
  display: block;
  width: 100%;
  margin: 0; padding: 0;
  border: 0; background: none;
  text-align: left;
  font-family: var(--font-head);
  font-size: clamp(1.12rem, 1.7vw, 1.36rem);
  font-weight: 500;
  letter-spacing: -0.03em;
  line-height: 1.2;
  color: var(--text);
  cursor: default;
}
.flow.is-flow .flow__trigger {
  cursor: pointer;
  color: var(--text-2);
  transition: color var(--t-2) var(--ease);
}
.flow.is-flow .flow__trigger:hover { color: var(--text); }
.flow.is-flow .flow__row.is-open .flow__trigger { color: var(--text); font-weight: 700; }
.flow__trigger:focus-visible {
  outline: 2px solid var(--brand-deep);
  outline-offset: 4px;
  border-radius: 6px;
}

.flow__note {
  margin: 0;
  padding-top: 10px;
  color: var(--muted);
  line-height: 1.62;
  font-size: .97rem;
  max-width: 42em;
}

/* Collapsed: the note's row is given no height at all and the box
   clips its own padding, so a shut step is exactly its heading. */
.flow.is-flow .flow__row {
  grid-template-rows: auto 0fr;
  transition: grid-template-rows var(--t-3) var(--ease-smooth);
}
.flow.is-flow .flow__row.is-open { grid-template-rows: auto 1fr; }
.flow.is-flow .flow__note {
  min-height: 0;
  overflow: hidden;
  opacity: 0;
  transition: opacity var(--t-2) var(--ease);
}
.flow.is-flow .flow__row.is-open .flow__note { opacity: 1; }

.flow__stage { display: grid; gap: 16px; }

.flow.is-flow .flow__stage { gap: 0; }
.flow.is-flow .flow__stage > .shot {
  grid-area: 1 / 1;
  align-self: start;
  opacity: 0;
  visibility: hidden;
  transform: translateY(12px) scale(.985);
  transition:
    opacity var(--t-3) var(--ease),
    transform 420ms var(--ease-smooth),
    visibility 0s linear var(--t-3);
}
.flow.is-flow .flow__stage > .shot.is-current {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition:
    opacity var(--t-3) var(--ease),
    transform 420ms var(--ease-smooth),
    visibility 0s;
}

@media (min-width: 900px) {
  .flow {
    grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
    gap: clamp(36px, 5vw, 68px);
  }

  /* Side by side, the still runs the full height of the six steps:
     the stage stretches to the rail, every still fills the stage,
     rows take up the slack to a point, and the totals sit at the foot. */
  .flow.is-flow { align-items: stretch; }
  .flow.is-flow .flow__stage { grid-template-rows: minmax(0, 1fr); }
  .flow.is-flow .flow__stage > .shot {
    align-self: stretch;
    display: flex;
    flex-direction: column;
  }
  .flow.is-flow .shot__body {
    flex: 1;
    display: flex;
    flex-direction: column;
    padding-top: 12px;
    padding-bottom: 22px;
  }
  .flow.is-flow .shot-row { flex: 1 1 auto; max-height: 68px; }
  .flow.is-flow .shot-stats,
  .flow.is-flow .shot-cap { margin-top: auto; }
  .flow.is-flow .shot-stats { padding-top: 20px; }
}

/* ── The stills ──────────────────────────────────────────────
   Mock-ups, not screenshots, drawn the way the app draws a run:
   a header with a title, a quiet meta line and a status pill,
   then full-width rows split by hairlines — a status disc, the
   step, its value and a chevron — with the last row sunk into a
   grey foot. The card itself is light glass. Every colour is a
   --shot-* token, so the palette lives in one place. Each <figure>
   carries the one sentence it
   is worth to a reader who cannot see it, and nothing inside is
   announced. To put a real screenshot in, replace a figure's
   contents with an <img> and keep the figure's class and label.
   ────────────────────────────────────────────────────────── */

.shot {
  --shot-bg:
    radial-gradient(120% 70% at 88% -10%, rgba(255, 223, 0, .09), transparent 60%),
    rgba(255, 255, 255, .66);
  --shot-border: var(--glass-edge);
  --shot-shadow: var(--ring), var(--shadow-md), var(--edge);
  --shot-ink: var(--text);
  --shot-ink-2: var(--text-2);
  --shot-ink-3: var(--muted);
  --shot-ink-4: var(--faint);
  --shot-line: rgba(0, 0, 0, .07);
  --shot-edge: rgba(0, 0, 0, .08);
  --shot-fill: rgba(0, 0, 0, .04);
  --shot-fill-2: rgba(0, 0, 0, .08);
  --shot-foot: rgba(0, 0, 0, .028);
  --shot-done: #3dba7e;
  --shot-active: #f29d12;
  --shot-active-ink: #d9780a;
  --shot-live: #2b9be8;
  --shot-live-bg: rgba(43, 155, 232, .11);
  --shot-ok-ink: #22955e;
  --shot-ok-bg: rgba(61, 186, 126, .13);
  --shot-play: var(--ink);

  margin: 0;
  position: relative;
  overflow: hidden;
  border-radius: var(--r-lg);
  color: var(--shot-ink);
  background: var(--shot-bg);
  -webkit-backdrop-filter: var(--blur);
  backdrop-filter: var(--blur);
  border: 1px solid var(--shot-border);
  box-shadow: var(--shot-shadow);
  text-align: left;
}

/* Header: title over a meta line, status pill on the right. */
.shot__bar {
  display: flex; align-items: center; gap: 14px;
  padding: 16px 20px 15px;
  border-bottom: 1px solid var(--shot-line);
}
.shot__head { display: grid; gap: 3px; min-width: 0; margin-right: auto; }
.shot__title {
  font-size: 16px;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--shot-ink);
}
.shot__meta {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12.5px;
  color: var(--shot-ink-3);
}
.shot__meta svg { width: 14px; height: 14px; flex: none; }

.shot__tag {
  flex: none;
  font-size: 13px; font-weight: 500;
  letter-spacing: -0.01em;
  padding: 5px 12px;
  border-radius: var(--r-pill);
  color: var(--shot-ink-3);
  background: var(--shot-fill);
}
.shot__tag--live { color: var(--shot-live); background: var(--shot-live-bg); }
.shot__tag--ok { color: var(--shot-ok-ink); background: var(--shot-ok-bg); }

/* Something wider than a row — a score, a chart — above the rows. */
.shot__section {
  padding: 4px 20px 18px;
  border-bottom: 1px solid var(--shot-line);
}

/* The steps. The column is capped at the card's width: left to size
   itself, it grows to fit the rows' unwrapped text, and on a phone the
   values and chevrons are cut off by the card's edge instead of ending
   in an ellipsis. */
.shot__rows { display: grid; grid-template-columns: minmax(0, 1fr); }

.shot-row {
  display: flex; align-items: center; gap: 12px;
  min-height: 54px;
  padding: 10px 16px 10px 20px;
  font-size: 14.5px;
}
.shot-row + .shot-row { border-top: 1px solid var(--shot-line); }

.shot-ico {
  flex: none;
  display: grid; place-items: center;
  width: 26px; height: 26px;
  border-radius: 50%;
  color: var(--shot-ink-3);
  background: var(--shot-fill);
}
.shot-ico svg { width: 14px; height: 14px; }

.shot-row__k {
  flex: none;
  max-width: 62%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 500;
  letter-spacing: -0.015em;
  color: var(--shot-ink);
}
.shot-row__v {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  text-align: right;
  font-size: 13.5px;
  color: var(--shot-ink-3);
  font-variant-numeric: tabular-nums;
}
.shot-chev {
  flex: none;
  width: 16px; height: 16px;
  margin-left: -4px;
  color: var(--shot-ink-4);
}

/* Done: a green disc with a tick. */
.shot-row.is-done .shot-ico { color: #fff; background: var(--shot-done); }
.shot-row.is-done .shot-ico svg { stroke-width: 3; }

/* Working on it: an amber disc with a turning ring, the value in amber. */
.shot-row.is-active .shot-ico { color: #fff; background: var(--shot-active); }
.shot-row.is-active .shot-ico svg { stroke-width: 3; }
.shot-row.is-active .shot-row__v { color: var(--shot-active-ink); }

/* A suggestion: amber, but still. */
.shot-row.is-tip .shot-ico { color: #fff; background: var(--shot-active); }
.shot-row.is-tip .shot-ico svg { stroke-width: 2.4; }
.shot-row.is-tip .shot-row__v { color: var(--shot-active-ink); }

/* Not yet, or not yours: grey disc, quieter label. */
.shot-row.is-todo .shot-row__k { color: var(--shot-ink-3); font-weight: 400; }

/* The pick: yellow disc, value in ink. */
.shot-row.is-pick .shot-ico { color: var(--brand-ink); background: var(--brand); }
.shot-row.is-pick .shot-row__v { color: var(--shot-ink); font-weight: 500; }

/* The last row sinks into the foot, with anything opened under it. */
.shot-row.is-foot,
.shot-row.is-foot + .shot-panel { background: var(--shot-foot); }

.shot-panel { display: grid; gap: 12px; padding: 2px 20px 18px 58px; }

.shot-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.shot-chip {
  font-size: 12.5px;
  padding: 5px 11px;
  border-radius: var(--r-pill);
  color: var(--shot-ink-2);
  background: rgba(255, 255, 255, .7);
  border: 1px solid var(--shot-edge);
}

.shot-tiles {
  display: grid;
  grid-template-columns: 1.15fr 1fr 1fr;
  gap: 8px;
}
.shot-tile {
  position: relative;
  height: 96px;
  border-radius: 12px;
  border: 1px solid var(--shot-edge);
  background:
    linear-gradient(150deg, rgba(255, 223, 0, .2), transparent 58%),
    var(--shot-fill);
}
.shot-tile:nth-child(3) {
  background:
    linear-gradient(150deg, var(--shot-fill-2), transparent 62%),
    var(--shot-fill);
}
/* The first one is the video: a play head sits in the middle of it. */
.shot-tile--video::after {
  content: "";
  position: absolute; inset: 0; margin: auto;
  width: 0; height: 0;
  border-left: 11px solid var(--shot-play);
  border-top: 7px solid transparent;
  border-bottom: 7px solid transparent;
  transform: translateX(2px);
}

.shot-meter {
  height: 6px;
  border-radius: 3px;
  background: var(--shot-fill-2);
  overflow: hidden;
}
.shot-meter__fill {
  display: block;
  height: 100%;
  border-radius: 3px;
  background: var(--shot-done);
}
.shot-meter__fill--78 { width: 78%; }

.shot-score {
  display: flex;
  align-items: flex-end;
  gap: 14px;
  padding: 14px 0 14px;
}
.shot-score__n {
  font-family: var(--font-head);
  font-weight: var(--w-title);
  font-size: 46px;
  line-height: .9;
  letter-spacing: -0.05em;
  color: var(--shot-ink);
  font-variant-numeric: tabular-nums;
}
.shot-score__n small {
  margin-left: 3px;
  font-size: 15px;
  letter-spacing: -0.02em;
  color: var(--shot-ink-4);
}
.shot-score__l {
  margin-bottom: 3px;
  font-size: 13px;
  color: var(--shot-ink-3);
}

.shot-bars {
  display: flex;
  align-items: flex-end;
  gap: 7px;
  height: 104px;
  margin-top: 14px;
}
.shot-bars span {
  flex: 1;
  border-radius: 6px 6px 2px 2px;
  background: var(--shot-fill-2);
}
.shot-bars span:nth-child(1) { height: 38%; }
.shot-bars span:nth-child(2) { height: 52%; }
.shot-bars span:nth-child(3) { height: 44%; }
.shot-bars span:nth-child(4) { height: 66%; }
.shot-bars span:nth-child(5) { height: 94%; }
.shot-bars span:nth-child(6) { height: 58%; }
.shot-bars span:nth-child(7) { height: 72%; }
.shot-bars span.is-top {
  background: linear-gradient(180deg, var(--brand-hi), var(--brand));
  box-shadow: 0 8px 18px -10px var(--brand-glow);
}

@media (prefers-reduced-motion: no-preference) {
  .shot-row.is-active .shot-ico svg { animation: shot-spin 1.1s linear infinite; }
}
@keyframes shot-spin { to { transform: rotate(360deg); } }

@media (max-width: 460px) {
  .shot__bar { padding: 14px 16px 13px; }
  .shot__section { padding-left: 16px; padding-right: 16px; }
  .shot-row { padding-left: 16px; padding-right: 12px; font-size: 14px; }
  .shot-panel { padding-left: 16px; padding-right: 16px; }

  /* A phone is too narrow for a step and its value side by side: both got
     cut down to a letter or two. The value drops under its step instead,
     with the disc and the chevron centred on the pair. */
  .shot-row {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    column-gap: 12px;
    row-gap: 1px;
  }
  .shot-ico { grid-column: 1; grid-row: 1 / span 2; }
  .shot-row__k,
  .shot-row__v { white-space: normal; line-height: 1.35; }
  .shot-row__k { grid-column: 2; grid-row: 1; max-width: none; }
  .shot-row__v { grid-column: 2; grid-row: 2; text-align: left; font-size: 12.5px; }
  .shot-chev { grid-column: 3; grid-row: 1 / span 2; margin-left: 0; }
}

/* ── Capability cards ────────────────────────────────────── */

.cap-grid { display: grid; gap: 14px; grid-template-columns: 1fr; }

.cap-card {
  padding: clamp(26px, 3vw, 36px);
  border-radius: var(--r-xl);
  background: rgba(255, 255, 255, .62);
  -webkit-backdrop-filter: var(--blur);
  backdrop-filter: var(--blur);
  border: 1px solid var(--glass-edge);
  box-shadow: var(--ring), var(--shadow-sm), var(--edge);
}

.cap-card--accent {
  background: linear-gradient(170deg, rgba(255, 223, 0, .3), rgba(255, 223, 0, .1));
  border-color: rgba(212, 182, 0, .34);
  box-shadow: 0 0 0 1px rgba(212, 182, 0, .12),
              0 20px 44px -30px var(--brand-glow),
              inset 0 1px 0 rgba(255, 255, 255, .8);
}

.cap-card h3 { margin: 0 0 20px; font-size: 1.28rem; letter-spacing: -0.036em; }

.cap-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 13px; }

/* Markers are absolutely positioned rather than grid cells: these list
   items contain inline <b>, which a grid container would promote to a
   second grid item and break the sentence across rows. */
.cap-list li {
  position: relative;
  padding-left: 26px;
  color: var(--muted);
  font-size: .97rem;
  line-height: 1.58;
}
/* Centred on the first line: half the line box, less half the dot. */
.cap-list li::before {
  content: "";
  position: absolute;
  left: 2px; top: calc(.79em - 5px);
  width: 10px; height: 10px;
  border-radius: 50%;
  background: var(--brand);
}
.cap-list--plain li { padding-left: 26px; }
.cap-list--plain li::before {
  content: "";
  left: 4px; top: .52em;
  width: 7px; height: 7px;
  background: var(--ink);
  opacity: .32;
  box-shadow: none;
}
.cap-list li b { color: var(--text); font-weight: inherit; }
/* Lead-in stays the same grey as the rest of the sentence. */
.cap-list--muted li b { color: inherit; }

.band-dark .cap-card {
  background: var(--glass-d);
  border-color: var(--glass-d-edge);
  box-shadow: var(--edge-d);
}
.band-dark .cap-card h3 { color: #fff; }
.band-dark .cap-list li { color: rgba(250, 250, 250, .66); }
.band-dark .cap-list li b { color: #fff; }
.band-dark .cap-list--plain li::before { border-color: rgba(255, 255, 255, .22); }

/* ── Posture tiles (security #posture) ───────────────────── */

/* One claim per tile: the two long lists used to sit in a pair of tall
   boxes, which buried the individual promises. */
.posture-set + .posture-set { margin-top: clamp(28px, 3.2vw, 42px); }

/* These two headings are centred on the page, like #use-cases. */
#posture h2 { text-align: center; }

.posture-label {
  margin: 0 0 clamp(16px, 1.8vw, 22px);
  font-size: clamp(1.6rem, 2.9vw, 2.15rem);
  line-height: 1.12;
  letter-spacing: -0.04em;
  text-align: center;
}

/* One row that scrolls sideways, snapping tile by tile. The block padding
   is the room the hover lift and its shadow need: a horizontal scroller
   clips whatever leaves the box on the cross axis. */
.posture-grid {
  list-style: none;
  margin: -10px 0 0;
  padding: 10px 0 16px;
  display: flex;
  gap: 12px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
}

/* The native bar is as wide as the strip, whatever it is styled with, so it
   is hidden and a short one drawn underneath instead. js/site.js sizes and
   moves the thumb; without the script the strips still scroll. */
.posture-grid { scrollbar-width: none; }
.posture-grid::-webkit-scrollbar { display: none; }

.posture-bar {
  width: 96px;
  height: 4px;
  margin: 2px auto 0;
  border-radius: 99px;
  background: rgba(10, 10, 11, .12);
  overflow: hidden;
}
.posture-bar__thumb {
  display: block;
  width: 42%;
  height: 100%;
  border-radius: inherit;
  background: var(--ink);
}
/* Nothing to scroll: no bar. */
.posture-set.is-static .posture-bar { display: none; }

/* Whole tiles only: each one is an exact share of the strip, so a rest
   position never leaves a tile sliced at the edge. One across on a phone,
   two from 720, three from 960. */
.posture-tile {
  flex: 0 0 100%;
  scroll-snap-align: start;
  display: flex;
  flex-direction: column;
  gap: 13px;
  padding: 18px 18px 20px;
  border-radius: var(--r-md);
  background: rgba(255, 255, 255, .62);
  border: 1px solid var(--glass-edge);
  box-shadow: var(--ring), var(--edge);
  transition: transform .35s var(--ease), background .35s var(--ease), box-shadow .35s var(--ease);
}
.posture-tile:hover {
  transform: translateY(-5px);
  background: rgba(255, 255, 255, .86);
  box-shadow: var(--ring), var(--shadow-md), var(--edge);
}

.posture-tile__ico {
  display: inline-flex;
  align-items: center; justify-content: center;
  width: 34px; height: 34px;
  border-radius: 11px;
  background: rgba(255, 255, 255, .8);
  border: 1px solid var(--glass-edge);
  color: var(--ink);
}
.posture-tile__ico svg { width: 18px; height: 18px; }

.posture-tile p {
  margin: 0;
  color: var(--text);
  font-size: .95rem;
  line-height: 1.55;
}

.posture-tile--muted .posture-tile__ico { color: var(--muted); }
.posture-tile--muted p { color: var(--muted); }

@media (min-width: 720px) {
  .posture-tile { flex-basis: calc((100% - 12px) / 2); }
}
@media (min-width: 960px) {
  .posture-tile { flex-basis: calc((100% - 24px) / 3); }
}

@media (prefers-reduced-motion: reduce) {
  .posture-tile, .posture-tile:hover { transition: none; transform: none; }
}

/* ── Info cards ──────────────────────────────────────────── */

.info-grid { display: grid; gap: 14px; grid-template-columns: 1fr; }

.info-card {
  padding: clamp(22px, 2.4vw, 28px);
  border-radius: var(--r-lg);
  background: rgba(255, 255, 255, .55);
  border: 1px solid var(--glass-edge);
  box-shadow: var(--ring), var(--edge);
  transition: transform .4s var(--ease), background .4s var(--ease), box-shadow .4s var(--ease);
}
.info-card:hover {
  transform: translateY(-3px);
  background: rgba(255, 255, 255, .8);
  box-shadow: var(--ring), var(--shadow-md), var(--edge);
}
.info-card h3 { margin: 0 0 9px; font-size: 1.04rem; letter-spacing: -0.03em; }
.info-card p { margin: 0; color: var(--muted); font-size: .94rem; line-height: 1.6; }

.info-card__kicker {
  display: inline-block;
  margin: 0 0 10px;
  font-size: 12px;
  font-weight: var(--w-title);
  color: var(--muted);
}

.section--sunken .info-card { background: rgba(255, 255, 255, .64); }
.band-dark .info-card {
  background: var(--glass-d);
  border-color: var(--glass-d-edge);
  box-shadow: var(--edge-d);
}
.band-dark .info-card h3 { color: #fff; }
.band-dark .info-card p { color: rgba(250, 250, 250, .66); }

/* ── Payment exhibits (pricing #billing) ─────────────────── */

/* The panel ends on a one-line note, so the full section padding below it
   reads as empty space; close it up. */
#billing { padding-top: clamp(36px, 4.2vw, 56px); padding-bottom: clamp(16px, 1.8vw, 22px); }
#billing .lead-out { margin-top: clamp(40px, 4.6vw, 60px); font-size: .82rem; }
#billing h2 { text-align: center; }

/* Three grey cards, each with a small slice of the checkout drawn above
   its caption, then a row of plain facts set large. The middle card is lit
   in brand yellow. The drawings are aria-hidden; the captions carry the
   facts. No amounts anywhere, only what the terms say. */
.pay-cards { display: grid; gap: 14px; grid-template-columns: 1fr; }

.pay-card {
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  padding: 0 clamp(20px, 2.2vw, 26px) clamp(22px, 2.4vw, 28px);
  border-radius: var(--r-lg);
  background:
    radial-gradient(120% 70% at 50% 108%, rgba(255, 223, 0, .16), transparent 70%),
    var(--surface-muted);
}
.pay-card h3 { margin: 0 0 7px; font-size: 1.22rem; line-height: 1.2; letter-spacing: -0.034em; }
.pay-card p { margin: 0; color: var(--muted); font-size: .94rem; line-height: 1.55; }

/* The stage the slips sit on, bleeding off the right edge. */
.pay-card__stage {
  position: relative;
  height: 196px;
  margin: 0 calc(-1 * clamp(20px, 2.2vw, 26px)) 18px;
}

.pay-slip {
  position: absolute;
  border-radius: var(--r-md);
  background: var(--surface);
  box-shadow: var(--ring), var(--shadow-sm);
  transition: translate .4s var(--ease);
}
.pay-slip--main { z-index: 1; top: 26px; left: clamp(20px, 2.2vw, 26px); right: clamp(20px, 2.2vw, 26px); padding: 16px 18px; }
.pay-slip--back {
  top: 132px; left: 56px; right: 24px;
  display: grid; gap: 8px;
  padding: 26px 16px 16px;
  background: rgba(255, 255, 255, .6);
}
.pay-slip--list { top: 22px; padding: 6px 18px; }
/* Sits centred in its stage instead of bleeding off the right. */
.pay-slip--center {
  top: 50%; left: 50%; right: auto;
  width: min(272px, calc(100% - 2 * clamp(20px, 2.2vw, 26px)));
  transform: translate(-50%, -50%);
}

.pay-card:hover .pay-slip--main { translate: 0 -4px; }
.pay-card:hover .pay-slip--back { translate: 0 3px; }

.pay-slip__head { display: flex; align-items: center; gap: 8px; margin-bottom: 14px; }
.pay-slip__icon { flex: none; width: 18px; height: 18px; color: var(--ink); }
.pay-slip__label { font-size: 12.5px; font-weight: var(--w-title); color: var(--muted); }
.pay-slip__title { margin: 0; font-size: 1.12rem; font-weight: var(--w-title); letter-spacing: -0.03em; color: var(--ink); white-space: nowrap; }
.pay-slip__sub { margin: 3px 0 0; font-size: 13px; color: var(--muted); }

.pay-chip {
  margin-left: auto;
  padding: 3px 9px;
  border-radius: var(--r-pill);
  background: var(--brand);
  color: var(--brand-ink);
  font-size: 11px;
  font-weight: var(--w-title);
  white-space: nowrap;
}
.pay-chip--soft { background: var(--surface-muted); color: var(--text-2); }

.pay-bar { display: block; height: 7px; border-radius: var(--r-pill); background: var(--surface-muted); }
.pay-bar--short { width: 42%; }

/* A payment-method list and a plan list share one row shape. */
.pay-opt,
.pay-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 0;
  font-size: 14px;
  font-weight: var(--w-title);
  color: var(--ink);
  white-space: nowrap;
  border-top: 1px solid var(--hairline);
}
.pay-opt:first-child,
.pay-row:first-child { border-top: 0; }
.pay-row { padding: 13px 0; }
.pay-opt:not(.is-on) { color: var(--text-2); }

.pay-radio {
  flex: none;
  width: 14px; height: 14px;
  border-radius: 50%;
  border: 1.5px solid var(--hairline-strong);
}
.pay-opt.is-on .pay-radio { border: 4px solid var(--ink); }

/* Official payment marks, right-aligned in each option row. */
.pay-logos { display: flex; align-items: center; gap: 6px; margin-left: auto; }
.pay-logo { display: block; flex: none; height: 16px; width: auto; }
.pay-logo--visa { height: 11px; }
.pay-logo--mc { height: 18px; }
.pay-logo--bank { height: 18px; color: var(--ink); }

/* Facts, set large under the cards. */
.pay-facts {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 28px 24px;
  margin: clamp(38px, 4.6vw, 60px) 0 0;
}
.pay-fact { margin: 0; text-align: center; }
/* Three facts in two columns: the last one spans the row so it stays centred. */
.pay-fact:last-child { grid-column: 1 / -1; }
.pay-fact__value {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin: 0 0 8px;
  font-size: clamp(1.2rem, 2.1vw, 1.75rem);
  font-weight: var(--w-display);
  line-height: 1;
  letter-spacing: -0.045em;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.pay-facts + .lead-out { margin-inline: auto; text-align: center; }
.pay-fact__icon { flex: none; width: .8em; height: .8em; stroke-width: 2.4; }
.pay-fact dd { margin: 0 auto; max-width: 17em; color: var(--muted); font-size: .86rem; line-height: 1.55; }

@media (min-width: 900px) {
  .pay-cards { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  /* Equal columns, so each centred fact sits in the middle of its own third. */
  .pay-facts { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .pay-fact:last-child { grid-column: auto; }
}

/* The smallest phones: a row and its chip need a little more room than the
   slip leaves, so the slip moves out to the card's edges and sets smaller. */
@media (max-width: 379px) {
  .pay-slip--main:not(.pay-slip--center) { left: 14px; right: 14px; }
  .pay-slip--list { padding-inline: 14px; }
  .pay-slip--center { width: calc(100% - 28px); }
  .pay-opt, .pay-row { gap: 8px; font-size: 13px; }
}

@media (prefers-reduced-motion: reduce) {
  .pay-slip { transition: none; }
  .pay-card:hover .pay-slip { translate: none; }
}

/* ── What's next ─────────────────────────────────────────── */

/* Three upcoming features in a row, each hung off a hairline. No boxes. */
.next-list {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: 28px; grid-template-columns: 1fr;
}
.next-item { padding-top: 20px; border-top: 1px solid var(--hairline-strong); }
.next-item__head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 18px;
}
.next-item__icon { display: inline-flex; color: var(--ink, currentColor); }
.next-item__icon svg { width: 22px; height: 22px; }
.next-item__status {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 12px; font-weight: 600; color: var(--muted);
}
.next-item__status::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%;
  background: var(--brand);
  box-shadow: 0 0 0 3px rgba(255, 223, 0, .18);
}
.next-item h3 { margin: 0 0 8px; font-size: 1.04rem; letter-spacing: -0.03em; }
.next-item p { margin: 0; color: var(--muted); font-size: .94rem; line-height: 1.6; }

.band-dark .next-item { border-top-color: rgba(255, 255, 255, .16); }
.band-dark .next-item__icon,
.band-dark .next-item h3 { color: #fff; }
.band-dark .next-item__status,
.band-dark .next-item p { color: rgba(250, 250, 250, .66); }

@media (min-width: 720px) {
  .next-list { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(28px, 4vw, 56px); }
}

/* ── Integration fan ─────────────────────────────────────── */

/* Integrations: every platform and source is a narrow, lightly glazed card,
   dealt out in one half circle that spans the full width of the screen.
   Each card sits on an offset --o from the centre of the fan; the offset
   drives the spread, the drop along the arc and the tilt. Hovering a card
   lifts it. */
.fan-stage {
  /* A full-screen band: an anchor jump should land on its top edge, not
     92px below it, so cancel the document scroll-padding. */
  scroll-margin-top: -92px;
  background: #070708;
  overflow: clip;
  isolation: isolate;
  container-type: inline-size;
  /* The stage fills a whole screen; the note sits close to its bottom edge. */
  min-height: 100svh;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  padding-bottom: clamp(20px, 2.2vw, 32px);
}
.fan-stage > .container:last-child { margin-top: auto; }
.fan-stage::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(55% 45% at 50% 80%, rgba(255, 223, 0, .12), transparent 70%),
    radial-gradient(35% 40% at 16% 62%, rgba(255, 255, 255, .05), transparent 70%),
    radial-gradient(35% 40% at 84% 62%, rgba(255, 255, 255, .05), transparent 70%);
}
.fan-stage h2 { color: #fff; }
.fan-stage .note { color: rgba(250, 250, 250, .62); }
.fan-stage .note a { color: #fff; }

.fan {
  --count: 12;
  --w: min(11.5cqi, 220px);
  --ratio: 1.45;
  --drop: .34cqi;
  --tilt: 2.5deg;
  /* Room for the outermost cards: their drop (5.5² × --drop) plus the corner
     their tilt swings down, so they don't spill onto the note below. */
  --arc: 12cqi;
  --lift-room: 34px;
  --gutter: 2cqi;
  --pad: clamp(12px, 1.1cqi, 20px);
  --step: calc((100cqi - var(--w) - 2 * var(--gutter)) / (var(--count) - 1));
  position: relative;
  list-style: none;
  margin: clamp(4px, 1vw, 16px) 0 clamp(32px, 4vw, 64px);
  padding: 0;
  height: calc(var(--w) * var(--ratio) + var(--arc) + var(--lift-room));
}

.fan > :nth-child(1)  { --o: -5.5; }
.fan > :nth-child(2)  { --o: -4.5; }
.fan > :nth-child(3)  { --o: -3.5; }
.fan > :nth-child(4)  { --o: -2.5; }
.fan > :nth-child(5)  { --o: -1.5; }
.fan > :nth-child(6)  { --o: -.5; }
.fan > :nth-child(7)  { --o: .5; }
.fan > :nth-child(8)  { --o: 1.5; }
.fan > :nth-child(9)  { --o: 2.5; }
.fan > :nth-child(10) { --o: 3.5; }
.fan > :nth-child(11) { --o: 4.5; }
.fan > :nth-child(12) { --o: 5.5; }

.fan__card {
  --glow: #ffffff;
  position: absolute;
  top: var(--lift-room);
  left: 50%;
  width: var(--w);
  aspect-ratio: 1 / var(--ratio);
  margin-left: calc(var(--w) / -2);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  padding: var(--pad);
  border-radius: clamp(14px, 1.4cqi, 24px);
  border: 1px solid rgba(255, 255, 255, .09);
  background: linear-gradient(165deg, rgba(38, 38, 42, .9), rgba(18, 18, 20, .92) 55%);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .14),
    0 26px 50px -22px rgba(0, 0, 0, .9);
  transform-origin: 50% 100%;
  transform:
    translateX(calc(var(--o) * var(--step)))
    translateY(calc(var(--o) * var(--o) * var(--drop)))
    rotate(calc(var(--o) * var(--tilt)));
  /* Cards keep their place in the stack at all times: a hovered card only
     rises, so nothing ever pops in front of anything on the way up or down. */
  --fan-ease: cubic-bezier(.22, 1, .36, 1);
  transition:
    translate .6s var(--fan-ease),
    box-shadow .6s var(--fan-ease);
}
/* The logo's own colour, lit softly inside the card. On hover it also
   reaches below the card to cover the gap the lift opens, so a pointer near
   the bottom edge doesn't lose the card and set it bouncing. */
.fan__card::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: radial-gradient(75% 45% at 50% 36%, color-mix(in srgb, var(--glow) 22%, transparent), transparent 72%) top / 100% 100% no-repeat;
  opacity: .7;
  transition: opacity .6s var(--fan-ease);
}
/* A faint rim of light on the top-left edge — a hint of glass, no more. */
.fan__card::after {
  content: "";
  position: absolute;
  inset: 0;
  padding: 1px;
  border-radius: inherit;
  pointer-events: none;
  background: linear-gradient(140deg, rgba(255, 255, 255, .28), transparent 35%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
}
.fan__card:hover {
  translate: 0 -24px;
  transition:
    translate .5s var(--fan-ease),
    box-shadow .5s var(--fan-ease);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .2),
    0 36px 64px -24px rgba(0, 0, 0, .95);
}
.fan__card:hover::before {
  bottom: -24px;
  background-size: 100% calc(100% - 24px);
  opacity: 1;
}

.fan__logo {
  flex: 1;
  width: 100%;
  display: grid;
  place-items: center;
  color: #fff;
}
.fan__logo svg {
  width: 38%;
  height: auto;
  max-height: 50%;
  filter:
    drop-shadow(0 0 2px color-mix(in srgb, var(--glow) 55%, transparent))
    drop-shadow(0 0 16px color-mix(in srgb, var(--glow) 45%, transparent));
}
/* Names wrap inside the strip the next card leaves uncovered. */
.fan__meta { display: block; max-width: calc(var(--step) - var(--pad)); }
.fan__name {
  display: block;
  font-family: var(--font-head);
  font-weight: var(--w-title);
  letter-spacing: -0.02em;
  line-height: 1.2;
  font-size: clamp(12px, 1.05cqi, 17px);
  color: #fff;
}
.fan__card .tag { font-size: clamp(11px, .85cqi, 13px); color: rgba(250, 250, 250, .6); }
.fan__card .tag--live { color: #4ade80; }
.fan__card .tag--live::before { content: none; }

#pub-x .fan__logo path { fill: #fff; }

#pub-youtube   { --glow: #ff0000; }
#pub-instagram { --glow: #e4337c; }
#pub-tiktok    { --glow: #25f4ee; }
#pub-facebook  { --glow: #0866ff; }
#pub-linkedin  { --glow: #0a66c2; }
#pub-pinterest { --glow: #e60023; }
#ctx-drive     { --glow: #1fa463; }
#ctx-dropbox   { --glow: #0061ff; }
#ctx-onedrive  { --glow: #0078d4; }
#ctx-upload    { --glow: #ffdf00; }

/* Too narrow for twelve cards in one fan: deal them into a grid instead. */
@media (max-width: 1099px) {
  .fan {
    height: auto;
    width: calc(100% - 44px);
    margin-inline: auto;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
    gap: 10px;
  }
  .fan__card {
    position: relative;
    top: auto; left: auto;
    width: auto;
    margin: 0;
    aspect-ratio: 1 / 1.25;
    --pad: 12px;
    border-radius: 16px;
    transform: none;
  }
  .fan__meta { max-width: none; }
  .fan__card:hover { translate: 0 -6px; }
  .fan__name { font-size: 13px; }
  .fan__card .tag { font-size: 11px; }
}
@media (prefers-reduced-motion: reduce) {
  .fan__card, .fan__card::before { transition: none; }
}

/* Status reads as plain text, not a pill. */
.tag {
  flex: none;
  display: inline-flex; align-items: center;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: -0.005em;
  color: var(--muted);
  white-space: nowrap;
}
.tag--live { color: var(--ink); gap: 7px; }
.tag--live::before {
  content: "";
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--brand);
}
.tag--soon { color: var(--faint); }

/* ── Pricing ─────────────────────────────────────────────── */

/* The plan switch. Individual and Business hold different cards, not the
   same cards at different prices, so this swaps panels rather than numbers.
   Both panels are plain content until initPlanTabs marks the wrapper
   .is-tabbed — with no JavaScript the page keeps every plan on it. */

.plan-switch { display: none; }
.plan-tabs.is-tabbed .plan-switch {
  display: flex;
  position: relative;
  gap: 4px;
  width: min(100%, 520px);
  margin: 0 auto clamp(24px, 3vw, 36px);
  padding: 5px;
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .6);
  -webkit-backdrop-filter: var(--blur);
  backdrop-filter: var(--blur);
  border: 1px solid var(--glass-edge);
  box-shadow: var(--ring), var(--shadow-sm), var(--edge);
}

/* The dark pill is drawn once, behind both options, and slides between them
   rather than being repainted on whichever one is active. --plan-thumb is the
   index of the selected option, set by initPlanTabs; with no JavaScript the
   switch is display:none and this never shows. The two options are flex: 1 1 0
   inside a 5px padding and a 4px gap, so each is exactly half the padding box
   less 7px — which is what the width below says, and a step of its own width
   plus the gap lands the pill on the second one. */
.plan-tabs.is-tabbed .plan-switch::before {
  content: "";
  position: absolute;
  z-index: 0;
  top: 5px; bottom: 5px; left: 5px;
  width: calc(50% - 7px);
  border-radius: var(--r-pill);
  background: var(--ink);
  box-shadow: 0 10px 22px -16px rgba(0, 0, 0, .75), inset 0 1px 0 rgba(255, 255, 255, .1);
  transform: translateX(calc((100% + 4px) * var(--plan-thumb, 0)));
  transition: transform var(--t-3) var(--ease-smooth);
}

.plan-switch__opt {
  flex: 1 1 0;
  min-width: 0;
  position: relative;
  z-index: 1;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 44px;
  padding: 0 14px;
  border: 1px solid transparent;
  border-radius: var(--r-pill);
  background: transparent;
  font-family: var(--font);
  font-size: 14.5px;
  font-weight: 650;
  letter-spacing: -0.015em;
  color: var(--muted);
  white-space: nowrap;
  cursor: pointer;
  transition: color var(--t-2) var(--ease-out);
}
.plan-switch__opt:hover { color: var(--text); }
/* Only the text colour: the dark ground behind it is the sliding pill. The
   label turns white a little before the pill has finished arriving, which
   reads as the pill catching up to it rather than the two moving as one. */
.plan-switch__opt.is-active { color: #fff; }
.plan-switch__icon { width: 16px; height: 16px; flex: none; }

/* Only the no-JavaScript reading needs these headings: with the switch up,
   the selected tab already says which set of plans is on screen. */
.plan-panel + .plan-panel { margin-top: clamp(30px, 3.6vw, 48px); }
.plan-panel__title { margin: 0 0 18px; font-size: 1.5rem; }
.plan-panel[hidden] { display: none; }
.plan-tabs.is-tabbed .plan-panel__title { display: none; }
.plan-tabs.is-tabbed .plan-panel + .plan-panel { margin-top: 0; }

/* The swap. Four cards and two cards are nowhere near the same height, so
   the deck carries the change itself: initPlanTabs pins its height, takes
   the outgoing panel out of the flow, and lets the box ease down to the
   incoming one while the two crossfade. Every piece of it is driven by a
   class the script adds, so the resting state stays plain layout. */
.plan-deck.is-swapping {
  position: relative;
  overflow: hidden;
  transition: height .42s var(--ease-smooth);
}
/* The incoming panel waits out most of the outgoing one's fade before it
   starts: two sets of cards at half opacity over each other read as a
   mess, and these two sets do not even share a column count. */
.plan-tabs.is-tabbed .plan-panel {
  transition: opacity .26s var(--ease-out) .12s, transform .36s var(--ease-smooth) .12s;
}
.plan-tabs.is-tabbed .plan-panel.is-entering { opacity: 0; transform: translateY(10px); }
/* Out of the flow so it cannot push the deck around on its way out, under
   the incoming panel rather than over it, and quicker to go than the other
   is to arrive. */
.plan-tabs.is-tabbed .plan-panel.is-leaving {
  position: absolute;
  top: 0; left: 0; right: 0;
  z-index: 0;
  opacity: 0;
  transform: translateY(-6px);
  pointer-events: none;
  transition: opacity .16s var(--ease-out), transform .3s var(--ease-smooth);
}
.plan-tabs.is-tabbed .plan-panel:not(.is-leaving) { position: relative; z-index: 1; }

.price-grid { display: grid; gap: 14px; grid-template-columns: 1fr; align-items: stretch; }
/* Two cards, not four — hold them to a readable width instead of letting
   them stretch across the whole grid. */
.price-grid--duo { max-width: 760px; margin-inline: auto; }

.price-card {
  display: flex;
  flex-direction: column;
  padding: clamp(24px, 2.6vw, 30px);
  border-radius: var(--r-xl);
  background: rgba(255, 255, 255, .6);
  -webkit-backdrop-filter: var(--blur);
  backdrop-filter: var(--blur);
  border: 1px solid var(--glass-edge);
  box-shadow: var(--ring), var(--shadow-sm), var(--edge);
  transition: translate .4s var(--ease), box-shadow .4s var(--ease);
}
/* The lift is on `translate`, not `transform`: the scroll reveal pins
   transform once a card is in, and would cancel it. */
.price-card:hover { translate: 0 -4px; box-shadow: var(--ring), var(--shadow-md), var(--edge); }

/* Same white card as the others; the yellow outline is what sets it apart. */
.price-card--featured {
  border: 2px solid var(--brand);
  box-shadow: var(--shadow-sm), 0 0 36px -18px var(--brand-glow), var(--edge);
}
.price-card--featured:hover {
  box-shadow: var(--shadow-md), 0 0 44px -18px var(--brand-glow), var(--edge);
}

.price-card__head {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  margin-bottom: 8px;
  min-height: 26px;
}
.price-card__head h3 { margin: 0; font-size: 1.08rem; letter-spacing: -0.034em; }

.price-card__flag {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: -0.005em;
  padding: 5px 11px;
  border-radius: var(--r-pill);
  background: var(--brand);
  color: var(--brand-ink);
  white-space: nowrap;
  box-shadow: 0 6px 14px -8px var(--brand-glow);
}
/* A label, not a selling point — the free plan says "No card" without
   the yellow shouting it. */
.price-card__flag--soft {
  background: var(--surface-muted);
  color: var(--muted);
  box-shadow: none;
}

.price-card__tagline {
  margin: 0 0 20px;
  color: var(--muted);
  font-size: .88rem;
  line-height: 1.5;
  min-height: 2.6em;
}

.price-amount {
  margin: 0;
  font-family: var(--font-head);
  font-size: clamp(2.1rem, 3.2vw, 2.6rem);
  font-weight: var(--w-display);
  letter-spacing: -0.055em;
  line-height: 1;
  color: var(--text);
}
.price-amount small {
  font-family: var(--font);
  font-size: .88rem;
  font-weight: var(--w-body);
  color: var(--muted);
  letter-spacing: -0.01em;
}

.price-annual { margin: 10px 0 18px; font-size: .79rem; color: var(--muted); }

.price-card .btn { margin-bottom: 20px; }

.price-feats {
  list-style: none; margin: 0; padding: 20px 0 0;
  /* Rows start at the top, so a shorter list keeps the same line spacing and
     leaves the rest of the card empty instead of spreading out. */
  display: grid; gap: 11px; align-content: start;
  border-top: 1px solid var(--hairline);
}

.price-feats li {
  position: relative;
  padding-left: 22px;
  color: var(--muted);
  font-size: .88rem;
  line-height: 1.5;
}
.price-feats li::before {
  content: "";
  position: absolute;
  left: 3px; top: .3em;
  width: 5px; height: 9px;
  border-right: 2.5px solid var(--brand);
  border-bottom: 2.5px solid var(--brand);
  border-radius: 0 0 1px 0;
  transform: rotate(42deg);
}
.price-feats li b { color: var(--text); font-weight: var(--w-body-em); }

/* ── Tables ──────────────────────────────────────────────── */

.table-wrap {
  overflow-x: auto;
  border: 1px solid var(--glass-edge);
  border-radius: var(--r-lg);
  background: rgba(255, 255, 255, .6);
  -webkit-backdrop-filter: var(--blur);
  backdrop-filter: var(--blur);
  box-shadow: var(--ring), var(--edge);
}
table.data { width: 100%; border-collapse: collapse; font-size: .91rem; min-width: 560px; }
table.data th, table.data td {
  text-align: left;
  padding: 14px 18px;
  border-bottom: 1px solid rgba(0, 0, 0, .055);
  vertical-align: top;
}
table.data thead th {
  font-family: var(--font-head);
  font-weight: var(--w-title);
  font-size: .82rem;
  letter-spacing: -0.015em;
  color: var(--text);
  background: rgba(0, 0, 0, .035);
  border-bottom-color: rgba(0, 0, 0, .08);
}
table.data tbody tr { transition: background .25s var(--ease-out); }
table.data tbody tr:hover { background: rgba(255, 255, 255, .6); }
table.data tbody tr:last-child td { border-bottom: 0; }
table.data td { color: var(--muted); }
table.data td:first-child { color: var(--text); font-weight: var(--w-title); }

/* ── FAQ ─────────────────────────────────────────────────── */

.faq-list { display: grid; gap: 8px; }

.faq-item {
  border-top: 0;
  border: 1px solid var(--glass-edge);
  border-radius: var(--r-lg);
  background: rgba(255, 255, 255, .52);
  box-shadow: var(--ring), var(--edge);
  overflow: hidden;
  transition: background .3s var(--ease), box-shadow .3s var(--ease);
}
.faq-list .faq-item:last-child { border-bottom: 1px solid var(--glass-edge); }
.faq-item:hover { background: rgba(255, 255, 255, .76); }
.faq-item[open] {
  background: rgba(255, 255, 255, .8);
  box-shadow: var(--ring), var(--shadow-sm), var(--edge);
}
.section--sunken .faq-item { background: rgba(255, 255, 255, .62); }

.faq-item summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  /* Question on the left, chevron on the right edge of the row it opens. */
  justify-content: space-between;
  gap: 18px;
  padding: 19px clamp(18px, 2vw, 24px);
  font-family: var(--font-head);
  font-weight: var(--w-title);
  font-size: 1.02rem;
  letter-spacing: -0.028em;
  color: var(--text);
}
.faq-item summary::-webkit-details-marker { display: none; }

.faq-item summary::after {
  content: "";
  flex: none;
  width: 26px; height: 26px;
  border-radius: 50%;
  background: rgba(0, 0, 0, .05);
  background-image:
    linear-gradient(var(--ink), var(--ink)),
    linear-gradient(var(--ink), var(--ink));
  background-size: 10px 1.6px, 1.6px 10px;
  background-position: center, center;
  background-repeat: no-repeat;
  transition: transform .35s var(--ease), background-color .25s var(--ease-out);
}
.faq-item[open] summary::after { transform: rotate(135deg); margin-top: 0; }
/* A closing panel is still [open] while its height animates shut, so the
   marker would otherwise turn back a beat after the answer had gone. The
   class lands the moment the collapse starts and the two travel together. */
.faq-item.is-closing summary::after { transform: none; }

.faq-body { padding: 0 clamp(18px, 2vw, 24px) 22px; }
.faq-body p { margin: 0 0 10px; color: var(--muted); line-height: 1.65; font-size: .96rem; }
.faq-body p:last-child { margin-bottom: 0; }
.faq-body ul { margin: 10px 0 0; padding-left: 1.2em; color: var(--muted); }
.faq-body li { margin: 6px 0; line-height: 1.6; font-size: .96rem; }

.faq-group {
  font-family: var(--font-head);
  font-size: 1rem !important;
  font-weight: var(--w-title);
  letter-spacing: -0.02em;
  color: var(--text);
  margin: 0 0 12px !important;
  display: flex;
  align-items: center;
  gap: 10px;
}
.faq-group.mt-lg { margin-top: 50px !important; }

/* ── CTA band ────────────────────────────────────────────── */

.cta-band { text-align: center; }
/* The CTA band is a closing statement: it carries more vertical padding
   than .section--tight gives it. */
.section.cta-band { padding: clamp(64px, 7.5vw, 112px) 0; }
.cta-band h2 { margin: 0 auto 10px; max-width: 16em; }
.cta-band p { margin: 0 auto 22px; max-width: 34em; color: rgba(250, 250, 250, .66); font-size: 1.04rem; line-height: 1.6; }
.cta-band .btn-row { justify-content: center; }
/* The closing band, the homepage market band and What's next run edge to
   edge: no inset, no rounded corners, and no side borders to draw a line
   against the viewport edge. Three selectors deep so they outrank the inset
   panel rule and its narrow-screen override. */
.section.band-dark.cta-band,
.section.band-dark#market,
.section.band-dark#competitors,
.section.band-dark#next {
  width: 100%;
  border-radius: 0;
  border-inline: 0;
}
/* The market band ends on a one-line footnote, so the full section padding
   under it reads as dead space. */
.section.band-dark#market,
.section.band-dark#competitors { padding-bottom: clamp(32px, 3.6vw, 52px); }
/* The headline sits midway between the band's top edge and the first chart
   card: the space under it matches the band's top padding. */
.section.band-dark#market,
.section.band-dark#competitors { padding-top: clamp(36px, 4.4vw, 60px); }
.section.band-dark#market > .container > h2,
.section.band-dark#competitors > .container > h2 { margin-bottom: clamp(36px, 4.4vw, 60px); }
/* Product #insights: the headline is centred over the shots
   (a statement heading). */
#insights > .container > h2 { text-align: center; }
/* The brand S stands in for the "o" — sized to the x-height so it sits on
   the baseline like any other lowercase letter. The letter itself stays in
   the text, inked out, and the mark is painted over it: that way the "o"
   selects, copies and takes the page's yellow ::selection like every other
   letter, instead of showing the browser's grey tint for a picture. The
   filter makes the mark its own stacking context, so it lands on top of the
   selection band. */
.glyph-o {
  color: transparent;
  /* The letter is wider than the mark; pull the rest of the word back so the
     word keeps exactly the advance the picture had. No margin on the left:
     a margin is dead space the selection band doesn't paint, which would
     show as a white sliver in front of the mark. */
  margin-right: -.042em;
}
/* The page's ::selection paints selected text in ink, which would bring the
   hidden letter back under the mark. It stays out of sight either way. */
/* The mark is an inline-block, and a line may break on either side of one,
   so a narrow screen could split "soshials" around it. The word it sits in
   is kept whole. */
.glyph-word { white-space: nowrap; }
.glyph-o::selection { color: transparent; }
.glyph-o::-moz-selection { color: transparent; }
.glyph-o::before {
  content: "";
  display: inline-block;
  height: 1.1ex;
  /* 493 x 600 is the mark's own size, so it keeps its shape at any type size. */
  width: calc(1.1ex * 493 / 600);
  /* .05em evens the mark's gaps to the heading's own, and the pull-back cancels
     the mark's whole advance, so the letter underneath still starts here and
     its selection band runs straight through. */
  margin-left: .05em;
  margin-right: calc(-1.1ex * 493 / 600 - .05em);
  vertical-align: -.03em;
  background: url(assets/sosh-glyph-bold.png) 0 0 / 100% 100% no-repeat;
  filter: brightness(0) invert(1);
}
.cta-fine { margin: 22px auto 0 !important; font-size: .85rem !important; color: rgba(250, 250, 250, .45) !important; }

/* ── Forms ───────────────────────────────────────────────── */

.form-card {
  padding: clamp(24px, 3.2vw, 38px);
  border-radius: var(--r-xl);
  background: rgba(255, 255, 255, .66);
  -webkit-backdrop-filter: var(--blur-lg);
  backdrop-filter: var(--blur-lg);
  border: 1px solid var(--glass-edge);
  box-shadow: var(--ring), var(--shadow-md), var(--edge);
}

/* The contact form sits under a centred hero, so it centres with it —
   and so does the privacy note beneath it. The pricing note under the
   plan cards centres the same way. Doubled class so it outranks the
   base .note margin defined further down. */
.form-card.narrow-block { margin-inline: auto; }
.note.note-centred {
  margin-inline: auto;
  text-align: center;
}

.field { margin: 0 0 18px; }
.field label {
  display: block;
  margin-bottom: 8px;
  font-family: var(--font-head);
  font-size: 13.5px;
  font-weight: var(--w-title);
  letter-spacing: -0.02em;
  color: var(--text);
  text-transform: none;
}
.field input, .field textarea, .field select {
  width: 100%;
  min-height: 50px;
  padding: 13px 16px;
  font: inherit;
  font-size: 15.5px;
  color: var(--text);
  background: rgba(255, 255, 255, .72);
  border: 1px solid var(--hairline-mid);
  border-radius: var(--r-md);
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, .03);
  transition: border-color .2s var(--ease-out), box-shadow .2s var(--ease-out), background .2s var(--ease-out);
}
.field input::placeholder, .field textarea::placeholder { color: var(--faint); }
.field textarea { resize: vertical; min-height: 130px; line-height: 1.55; }
.field input:focus, .field textarea:focus, .field select:focus {
  outline: none;
  background: #fff;
  border-color: var(--brand-deep);
  box-shadow: 0 0 0 4px var(--brand-wash);
}

.field-hint { margin: 8px 0 0; font-size: .82rem; color: var(--faint); line-height: 1.5; }

/* Contact form: the spam trap is off-screen rather than display:none, which
   some bots skip; the status line only ever holds fixed text from site.js. */
.form-trap { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }
.form-check { margin: 0 0 18px; min-height: 65px; }
.form-status { margin: 14px 0 0; font-size: .9rem; line-height: 1.5; color: var(--text); }
.form-status[data-state="error"] { color: #b42318; }

/* Category dropdown. The native select keeps the platform's own open
   behaviour (and its keyboard handling); only the closed state is restyled,
   with our own caret because the OS one can't be recoloured. */
.field--select { position: relative; }
.field--select select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 46px;
  cursor: pointer;
}
/* Nothing chosen yet: read as a placeholder, not as an answer. */
.field--select select:invalid { color: var(--faint); }
.field--select select option { color: var(--text); }
.field--select select option[value=""] { color: var(--faint); }
.field__caret {
  position: absolute;
  right: 16px;
  top: 25px;
  margin-top: -10px;
  width: 20px; height: 20px;
  color: var(--muted);
  pointer-events: none;
}

/* Live character count. Turns ink once the message is long enough to send. */
.field-count {
  margin: 8px 0 0;
  font-size: .78rem;
  color: var(--faint);
  font-variant-numeric: tabular-nums;
}
.field-count[data-state="ok"] { color: var(--muted); }
.field-count[data-state="over"] { color: #b42318; }

/* The card owns the error tint so the whole form reads as rejected, not
   just the line of text under the button. */
.form-card.is-error {
  border-color: #d92d20;
  box-shadow: var(--ring), var(--shadow-md), var(--edge), 0 0 0 3px rgba(217, 45, 32, .12);
}

.form-consent { display: flex; gap: 12px; align-items: flex-start; margin: 0 0 22px; }
.form-consent input {
  width: 18px; height: 18px; margin-top: 3px; flex: none;
  accent-color: var(--brand-deep);
}
.form-consent label {
  font-family: var(--font);
  font-size: .87rem;
  color: var(--muted);
  line-height: 1.55;
  text-transform: none;
  letter-spacing: 0;
  font-weight: var(--w-body);
  margin: 0;
}

/* ── Contact form: sending, sent, failed ─────────────────────
   One glyph carries all three states. It spins in the button while the
   message is in flight, flies up out of the card on success (the panel
   below lands in the middle of the page), and shakes in place on failure.
   Every state is a class on an element — the deployed CSP is
   `style-src 'self'`, so nothing here can be set from script as an inline
   style except the two custom properties the flight path needs. */

.contact-send { position: relative; }
.contact-send__spinner { display: none; }

.contact-send.is-sending,
.contact-send.is-failed { pointer-events: none; }

/* Sending: the label goes, the glyph is all that is left in the button. */
.contact-send.is-sending .contact-send__label,
.contact-send.is-failed .contact-send__label { visibility: hidden; }
.contact-send.is-sending .contact-send__spinner,
.contact-send.is-failed .contact-send__spinner {
  display: block;
  position: absolute;
  top: 50%; left: 50%;
  width: 21px; height: 26px;
  margin: -13px 0 0 -10px;
  background: var(--brand-ink);
  -webkit-mask: url("assets/sosh-glyph-bold.png") no-repeat center / contain;
  mask: url("assets/sosh-glyph-bold.png") no-repeat center / contain;
}
/* A turn, then a beat, then another turn — not a constant whirl. */
.contact-send.is-sending .contact-send__spinner { animation: sosh-spin 1.5s var(--ease) infinite; }
.contact-send.is-failed .contact-send__spinner { animation: sosh-shake .5s var(--ease) 1; }

@keyframes sosh-spin {
  0%   { transform: rotate(0deg); }
  60%  { transform: rotate(360deg); }
  100% { transform: rotate(360deg); }
}
@keyframes sosh-shake {
  0%, 100% { transform: translateX(0) rotate(0deg); }
  15% { transform: translateX(-5px) rotate(-7deg); }
  35% { transform: translateX(5px) rotate(7deg); }
  55% { transform: translateX(-4px) rotate(-5deg); }
  75% { transform: translateX(3px) rotate(4deg); }
}

/* The flight. --fly-x / --fly-y are the button's own position, the only
   two values script sets, so the glyph leaves from where it was spinning
   and travels straight up past the card and off the top of the page. */
.contact-fly {
  position: fixed;
  left: var(--fly-x, 50%); top: var(--fly-y, 70%);
  z-index: 1200;
  width: 21px; height: 26px;
  margin: -13px 0 0 -10px;
  background: var(--brand-ink);
  -webkit-mask: url("assets/sosh-glyph-bold.png") no-repeat center / contain;
  mask: url("assets/sosh-glyph-bold.png") no-repeat center / contain;
  pointer-events: none;
  animation: sosh-fly .85s var(--ease-smooth) forwards;
}
@keyframes sosh-fly {
  0%   { transform: translateY(0) rotate(0deg) scale(1); opacity: 1; }
  25%  { transform: translateY(-14vh) rotate(220deg) scale(1.5); opacity: 1; }
  100% { transform: translateY(-120vh) rotate(900deg) scale(2.3); opacity: 0; }
}

/* Sent. Centred on the page, over a scrim, because the message leaving is
   the whole point of the page — it should not read as a footnote under a
   button. */
/* Both carry the hidden attribute when they're not in play, and both set a
   display of their own — which outranks the browser's rule for [hidden], so
   each has to opt out again or it shows in every state. */
.contact-fly[hidden],
.contact-done[hidden] { display: none; }

.contact-done {
  position: fixed;
  inset: 0;
  z-index: 1300;
  display: grid;
  place-items: center;
  padding: 24px;
  background: rgba(10, 10, 11, .34);
  -webkit-backdrop-filter: saturate(140%) blur(6px);
  backdrop-filter: saturate(140%) blur(6px);
  animation: sosh-done-in .32s var(--ease-out) both;
}
/* The panel covers the page, and during the cooldown its main button is
   disabled — so there has always to be a way out: this, Escape, or a click
   on the scrim. */
.contact-done__close {
  position: absolute;
  top: 12px; right: 12px;
  width: 34px; height: 34px;
  display: grid; place-items: center;
  border: 0; border-radius: var(--r-pill);
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  transition: background .18s var(--ease-out), color .18s var(--ease-out);
}
.contact-done__close:hover { background: rgba(0, 0, 0, .05); color: var(--ink); }
.contact-done__close svg { width: 17px; height: 17px; }

.contact-done__card {
  position: relative;
  width: min(420px, 100%);
  padding: clamp(28px, 4vw, 40px);
  text-align: center;
  background: rgba(255, 255, 255, .92);
  -webkit-backdrop-filter: var(--blur-lg);
  backdrop-filter: var(--blur-lg);
  border: 1px solid var(--glass-edge);
  border-radius: var(--r-xl);
  box-shadow: var(--ring), var(--shadow-lg), var(--edge);
  animation: sosh-done-card .42s var(--ease-smooth) both;
}
.contact-done__tick { width: 62px; height: 62px; display: block; margin: 0 auto 18px; }
.contact-done__tick-ring {
  stroke: #129d5f;
  stroke-width: 2.5;
  opacity: .28;
}
.contact-done__tick-mark {
  stroke: #129d5f;
  stroke-width: 4;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 44;
  stroke-dashoffset: 44;
  animation: sosh-tick .5s var(--ease-out) .18s forwards;
}
.contact-done__title {
  margin: 0 0 8px;
  font-family: var(--font-head);
  font-size: 1.45rem;
  font-weight: var(--w-display);
  letter-spacing: -0.04em;
  color: var(--text);
}
.contact-done__copy { margin: 0 0 22px; color: var(--muted); font-size: .92rem; line-height: 1.55; }
.contact-done__again { width: 100%; }
.contact-done__again[disabled] { opacity: .55; cursor: not-allowed; }

@keyframes sosh-done-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes sosh-done-card {
  from { opacity: 0; transform: translateY(14px) scale(.96); }
  to   { opacity: 1; transform: none; }
}
@keyframes sosh-tick { to { stroke-dashoffset: 0; } }

/* Restored from a previous visit rather than just animated: no entrance,
   no flight — the page simply opens in the state it was left in. */
.contact-done.is-restored,
.contact-done.is-restored .contact-done__card { animation: none; }
.contact-done.is-restored .contact-done__tick-mark { stroke-dashoffset: 0; animation: none; }

@media (prefers-reduced-motion: reduce) {
  .contact-send.is-sending .contact-send__spinner { animation: sosh-spin 3s linear infinite; }
  .contact-send.is-failed .contact-send__spinner { animation: none; }
  .contact-fly { display: none; }
  .contact-done,
  .contact-done__card { animation: none; }
  .contact-done__tick-mark { stroke-dashoffset: 0; animation: none; }
}

/* ── Contact list ────────────────────────────────────────── */

.contact-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.contact-row {
  display: grid;
  grid-template-columns: 1fr;
  gap: 5px;
  padding: 18px 20px;
  border-top: 0;
  border: 1px solid var(--glass-edge);
  border-radius: var(--r-lg);
  background: rgba(255, 255, 255, .58);
  box-shadow: var(--ring), var(--edge);
  transition: background .3s var(--ease), transform .3s var(--ease);
}
.contact-row:hover { background: rgba(255, 255, 255, .82); transform: translateY(-2px); }
.contact-list .contact-row:last-child { border-bottom: 1px solid var(--glass-edge); }
.contact-row dt {
  font-family: var(--font-head);
  font-weight: var(--w-title);
  font-size: .96rem;
  letter-spacing: -0.028em;
  color: var(--text);
}
.contact-row dd { margin: 0; color: var(--muted); font-size: .93rem; line-height: 1.55; }
.contact-row a {
  color: var(--text);
  font-weight: 600;
}

/* ── Contact page ────────────────────────────────────────── */

/* Headline and buttons on the left, the form as a card on the right.
   Ranged left — this is not one of the centred compositions. */
.contact-hero {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(36px, 5vw, 64px);
  align-items: center;
  padding: clamp(8px, 1.2vw, 16px) 0 clamp(16px, 3vw, 32px);
}
@media (min-width: 900px) {
  .contact-hero { grid-template-columns: minmax(0, 1.15fr) minmax(0, 430px); }
  /* Grow the card rightward into the page margin, keeping its left edge put */
  .contact-card { margin-right: calc(-1 * min(80px, max(0px, (100vw - 1120px) / 2 - 24px))); }
}
.contact-hero__copy h1 {
  font-size: clamp(2.6rem, 5.8vw, 4.4rem);
  line-height: 1.02;
  letter-spacing: -0.056em;
  font-weight: var(--w-display);
  margin: 0 0 24px;
  max-width: 9em;
}
.contact-hero__copy p {
  margin: 0;
  max-width: 34em;
  color: var(--muted);
  font-size: clamp(1rem, 1.5vw, 1.1rem);
  line-height: 1.6;
}
.contact-hero__copy .btn-row { margin-top: 34px; }

.contact-card { padding: clamp(22px, 2.3vw, 28px); }
.contact-card h2 {
  font-size: clamp(1.45rem, 2.1vw, 1.7rem);
  letter-spacing: -0.04em;
  margin: 0 0 6px;
}
.contact-card__lead { margin: 0 0 22px; color: var(--muted); font-size: .95rem; }
.contact-card .field { margin-bottom: 12px; }
.contact-card .field input,
.contact-card .field textarea {
  min-height: 46px;
  padding: 11px 14px;
  font-size: 14.5px;
  border-radius: var(--r-sm);
  background: var(--surface-muted);
  border-color: transparent;
  box-shadow: none;
}
.contact-card .field textarea { min-height: 104px; }
.contact-card .form-consent { margin: 16px 0 20px; }
.contact-card .form-consent label { font-size: .8rem; }

/* The whole card belongs on the first screen, so the page gives up the usual
   hero headroom and, on shorter windows, the card packs a little tighter. */
.hero-shell:has(.contact-hero) { padding-top: clamp(20px, 3.2vh, 40px); }
@media (min-width: 900px) {
  /* Centred in the first screen below the ribbon, like the homepage hero */
  .hero-shell:has(.contact-hero) {
    display: flex;
    align-items: center;
    min-height: calc(100vh - 70px);
    min-height: calc(100svh - 70px);
    padding-block: clamp(20px, 3vh, 40px);
  }
  .contact-hero { padding: 0; }
}
@media (min-width: 900px) and (max-height: 860px) {
  .contact-card { padding-block: 24px; }
  .contact-card h2 { margin-bottom: 2px; }
  .contact-card__lead { margin-bottom: 16px; }
  .contact-card .field { margin-bottom: 10px; }
  .contact-card .field textarea { min-height: clamp(72px, 100vh - 610px, 104px); }
  .contact-card .form-consent { margin: 12px 0 16px; }
}

/* ── Identity card (legal notice) ────────────────────────── */

.idcard {
  padding: clamp(20px, 2.6vw, 30px);
  border-radius: var(--r-xl);
  background: rgba(255, 255, 255, .62);
  -webkit-backdrop-filter: var(--blur);
  backdrop-filter: var(--blur);
  border: 1px solid var(--glass-edge);
  box-shadow: var(--ring), var(--shadow-sm), var(--edge);
  margin: 0 0 30px;
}
.idrow {
  display: flex; gap: 16px;
  padding: 14px 0;
  border-bottom: 1px solid rgba(0, 0, 0, .055);
  flex-wrap: wrap;
}
.idrow:last-child { border-bottom: none; }
.idrow .k {
  width: 190px; flex: none;
  font-size: 14px;
  font-weight: var(--w-title);
  color: var(--muted);
  letter-spacing: -0.015em;
}
.idrow .v { flex: 1; min-width: 210px; font-size: 15.5px; font-weight: var(--w-title); color: var(--text); }
.idrow .v .sub { display: block; font-weight: var(--w-body); color: var(--muted); font-size: 14px; margin-top: 3px; }

/* The Xctrl wordmark sits above the rows, over the same hairline the rows
   use, so the card reads as one stack rather than a logo dropped on a box. */
#team .idcard { display: flex; flex-direction: column; }

.idcard__logo {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 10px 0 26px;
  border-bottom: 1px solid rgba(0, 0, 0, .055);
}
.idcard__logo img { display: block; width: auto; height: clamp(56px, 6.5vw, 96px); }

/* Founder and designer share the bottom of the card, side by side. They drop
   to one column when the card gets too narrow to hold two names cleanly. */
.idpeople {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 22px 24px;
  padding: 18px 0 2px;
}
.idperson .k {
  font-size: 14px;
  font-weight: var(--w-title);
  color: var(--muted);
  letter-spacing: -0.015em;
}
.idperson .v {
  margin-top: 6px;
  font-size: 15.5px;
  font-weight: var(--w-title);
  color: var(--text);
}
.idperson .v .sub { display: block; font-weight: var(--w-body); color: var(--muted); font-size: 14px; margin-top: 3px; }

/* ── No boxes inside panels ──────────────────────────────── */

/* A sunken or dark section is already a floating card, so whatever sits
   in it lays its text straight onto the panel. An open section has no
   panel at all and lays its text straight onto the page ground: grids separate by space,
   lists by a hairline. Must stay below every card rule it overrides. */
.section--sunken :is(.cap-card, .info-card, .feature-card, .step, .plat-row, .contact-row, .idcard, .table-wrap),
.section--open :is(.cap-card, .info-card, .feature-card),
.section.band-dark :is(.cap-card, .info-card, .feature-card, .step, .plat-row, .contact-row, .idcard, .table-wrap),
.section--sunken :is(.cap-card, .info-card, .feature-card, .step, .plat-row, .contact-row):hover,
.section--open :is(.cap-card, .info-card, .feature-card):hover,
.section.band-dark :is(.cap-card, .info-card, .feature-card, .step, .plat-row, .contact-row):hover {
  background: none;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  transform: none;
}

.section--sunken :is(.cap-card, .info-card, .feature-card, .idcard),
.section--open :is(.cap-card, .info-card, .feature-card),
.section.band-dark :is(.cap-card, .info-card, .feature-card, .idcard) { padding: 0; }

.section--sunken :is(.cap-grid, .info-grid, .feature-grid),
.section--open :is(.cap-grid, .info-grid, .feature-grid),
.section.band-dark :is(.cap-grid, .info-grid, .feature-grid) { gap: clamp(30px, 3.6vw, 44px) clamp(28px, 4.4vw, 64px); }

.section--sunken :is(.steps, .plat-list, .contact-list),
.section.band-dark :is(.steps, .plat-list, .contact-list) { gap: 0; }

.section--sunken :is(.step, .plat-row, .contact-row),
.section.band-dark :is(.step, .plat-row, .contact-row) {
  padding-inline: 0;
  border-top: 1px solid var(--hairline);
}
.section--sunken :is(.step, .plat-row, .contact-row):first-child,
.section.band-dark :is(.step, .plat-row, .contact-row):first-child { border-top: 0; padding-top: 0; }
.section--sunken :is(.step, .plat-row, .contact-row):last-child,
.section.band-dark :is(.step, .plat-row, .contact-row):last-child { padding-bottom: 0; border-bottom: 0; }
.section.band-dark :is(.step, .plat-row, .contact-row) { border-top-color: var(--glass-d-edge); }

/* Feature grid on a dark band: a spec sheet, not icon tiles. Each entry
   stands on a hairline whose first stretch is lit in brand yellow, with
   its index above the title. The hairline is a background layer because
   the rules above clear border and background on hover; the yellow is
   ::after, so no transition sits on the card to fight the reveal fade.
   Hover runs the yellow the full width and lights the index. */
.section.band-dark .feature-grid {
  counter-reset: feature;
  row-gap: clamp(40px, 4.6vw, 60px);
}
.section.band-dark .feature-card,
.section.band-dark .feature-card:hover {
  counter-increment: feature;
  position: relative;
  padding-top: 22px;
  background: linear-gradient(rgba(255, 255, 255, .13), rgba(255, 255, 255, .13)) 0 0 / 100% 1px no-repeat;
}
.section.band-dark .feature-card::after {
  content: "";
  position: absolute;
  top: 0; left: 0;
  width: 40px; height: 2px;
  background: var(--brand);
  box-shadow: 0 0 10px var(--brand-glow);
  transition: width .7s var(--ease);
}
.section.band-dark .feature-card:hover::after { width: 100%; }
.section.band-dark .feature-card::before {
  content: counter(feature, decimal-leading-zero);
  display: block;
  margin-bottom: 16px;
  font-size: .8rem;
  font-weight: var(--w-title);
  letter-spacing: .06em;
  font-variant-numeric: tabular-nums;
  color: rgba(255, 223, 0, .62);
  transition: color .4s var(--ease);
}
.section.band-dark .feature-card:hover::before { color: var(--brand); }
.section.band-dark .feature-card h3 { font-size: clamp(1.2rem, 1.5vw, 1.36rem); margin-bottom: 10px; }
.section.band-dark .feature-card p { max-width: 34ch; }
@media (prefers-reduced-motion: reduce) {
  .section.band-dark .feature-card::after,
  .section.band-dark .feature-card::before { transition: none; }
}

/* The same spec sheet as one sideways row (Product, #market): a native
   horizontal scroller moved by a swipe, shift + wheel or the arrows under
   it. The edge that still has entries beyond it fades out; js/site.js
   sets is-scrolled / is-end and wires the arrows. */
.section.band-dark .feature-grid.feature-grid--rail {
  display: flex;
  gap: clamp(24px, 3vw, 44px);
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x proximity;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
  /* Room for the lit hairline's glow — the scroller clips. */
  padding: 12px 0 8px;
  outline: none;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 var(--rail-fade-l, 0px), #000 calc(100% - var(--rail-fade-r, 64px)), transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 var(--rail-fade-l, 0px), #000 calc(100% - var(--rail-fade-r, 64px)), transparent 100%);
}
.feature-grid--rail::-webkit-scrollbar { display: none; }
.rail.is-scrolled .feature-grid--rail { --rail-fade-l: 64px; }
.rail.is-end .feature-grid--rail { --rail-fade-r: 0px; }
.feature-grid--rail:focus-visible { outline: 2px solid var(--brand); outline-offset: 4px; }
.section.band-dark .feature-grid--rail .feature-card {
  flex: 0 0 clamp(240px, 22vw, 290px);
  scroll-snap-align: start;
}

.rail__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-top: 24px;
}
.rail__foot .note { margin: 0; }
.rail__nav { display: flex; gap: 8px; flex: none; }
.rail__btn {
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  padding: 0;
  border: 1px solid rgba(255, 255, 255, .16);
  border-radius: 50%;
  background: transparent;
  color: #fafafa;
  cursor: pointer;
  transition: border-color .3s var(--ease), color .3s var(--ease), opacity .3s var(--ease);
}
.rail__btn:hover:not(:disabled) { border-color: var(--brand); color: var(--brand); }
.rail__btn:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.rail__btn:disabled { opacity: .3; cursor: default; }
@media (prefers-reduced-motion: reduce) {
  .rail__btn { transition: none; }
}

/* ── Market globe (Product, #market) ─────────────────────────
   The six things it analyses, set around a dot-matrix globe drawn straight
   on the page ground, no panel: three down each side on wide screens, the
   globe on top and the entries below it on narrow ones. The dotted orbit
   and its six nodes are SVG, so they stand without script; js/site.js draws
   the globe on the canvas (colours from the --globe-* tokens), turns it to
   the entry under the pointer and links that point to its node. At rest it
   holds still. Entries are a plain title and line: no rules, no index. */
.globe-map {
  --globe-dot: #0a0a0b;
  --globe-spot: #ffdf00;
  --globe-spot-edge: #b89e00;
  --globe-link: #b89e00;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 22px clamp(24px, 3vw, 44px);
  margin-top: clamp(24px, 3vw, 36px);
}
.globe {
  position: relative;
  width: min(100%, 340px);
  aspect-ratio: 1;
  margin: 0 auto;
}
.globe::before {
  content: "";
  position: absolute;
  inset: 10%;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(255, 223, 0, .13), rgba(255, 223, 0, .04) 70%, transparent);
  pointer-events: none;
}
.globe__dots,
.globe__orbit {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.globe__orbit { overflow: visible; }
.globe__ring {
  stroke: rgba(10, 10, 11, .28);
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-dasharray: 0 7;
}
.globe__node {
  fill: #fff;
  stroke: var(--brand-deep);
  stroke-width: 1.5;
  transform-box: fill-box;
  transform-origin: center;
  transition: fill .7s var(--ease), stroke .7s var(--ease), transform .7s var(--ease), filter .7s var(--ease);
}
.globe__node.is-active {
  fill: var(--brand);
  stroke: var(--globe-spot-edge);
  transform: scale(1.35);
  filter: drop-shadow(0 0 6px var(--brand-glow));
}

.globe-map .feature-card { cursor: default; }
.globe-map .feature-card h3 { font-size: clamp(1.08rem, 1.3vw, 1.2rem); margin-bottom: 6px; }
.globe-map .feature-card p { max-width: 32ch; font-size: .94rem; line-height: 1.55; }

/* Phones and tablets have no hover, so the entries become a swipe strip
   under the globe: the card snapped to the middle is the active one and
   turns the globe to its continent. A tap on a card slides it in. */
@media (max-width: 959px) {
  .globe-map { gap: 8px; }
  .globe { width: min(100%, 320px); }
  .globe-map__list {
    position: relative;
    display: flex;
    gap: 12px;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
    overscroll-behavior-x: contain;
    margin-inline: -22px;
    padding: 6px 22px 24px;
    scroll-padding-inline: 22px;
  }
  .globe-map__list::-webkit-scrollbar { display: none; }
  .globe-map .globe-map__list > .feature-card,
  .globe-map .globe-map__list > .feature-card:hover {
    flex: 0 0 min(76%, 300px);
    scroll-snap-align: center;
    padding: 20px 20px 22px;
    border-radius: var(--r-lg);
    background: rgba(255, 255, 255, .62);
    -webkit-backdrop-filter: var(--blur);
    backdrop-filter: var(--blur);
    border: 1px solid var(--glass-edge);
    box-shadow: var(--ring), var(--shadow-sm), var(--edge);
    cursor: pointer;
    text-align: left;
    /* Opacity and transform belong to .reveal, so keep its timings. */
    transition: opacity .5s var(--ease-out), transform .68s var(--ease-smooth),
                box-shadow .5s var(--ease), border-color .5s var(--ease);
  }
  .globe-map .globe-map__list > .feature-card :is(h3, p) { transition: color .5s var(--ease); }
  .globe-map .globe-map__list > .feature-card:not(.is-active) h3 { color: var(--muted); }
  .globe-map .globe-map__list > .feature-card:not(.is-active) p { color: rgba(10, 10, 11, .32); }
  .globe-map .globe-map__list > .feature-card.is-active {
    border-color: rgba(184, 158, 0, .45);
    box-shadow: var(--ring), var(--shadow-md), var(--edge), inset 0 2px 0 var(--brand);
  }
}
@media (min-width: 960px) {
  .globe-map__list { display: contents; }
  .globe-map {
    grid-template-columns: minmax(0, 1fr) minmax(300px, 360px) minmax(0, 1fr);
    grid-template-rows: repeat(3, auto);
    align-items: center;
    row-gap: 14px;
  }
  .globe { grid-column: 2; grid-row: 1 / 4; width: 100%; }
  .globe-map .feature-card:nth-of-type(1) { grid-column: 1; grid-row: 1; }
  .globe-map .feature-card:nth-of-type(2) { grid-column: 1; grid-row: 2; }
  .globe-map .feature-card:nth-of-type(3) { grid-column: 1; grid-row: 3; }
  .globe-map .feature-card:nth-of-type(4) { grid-column: 3; grid-row: 1; }
  .globe-map .feature-card:nth-of-type(5) { grid-column: 3; grid-row: 2; }
  .globe-map .feature-card:nth-of-type(6) { grid-column: 3; grid-row: 3; }
}
@media (prefers-reduced-motion: reduce) {
  .globe__node { transition: none; }
}

/* ── Market charts (Home, #market) ───────────────────────────
   One wide area chart on top (tabs + hover tooltip), then three small
   charts, each a different form: horizontal bars, a ring, columns. Sizes
   live here, not in style="", because the CSP allows no inline styles;
   js/site.js only moves things on hover and on a tab or chip click. */

.chart-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 16px;
}
@media (min-width: 720px) {
  .chart-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .chart-card--wide, .chart-grid > .chart-card:last-child { grid-column: 1 / -1; }
}
@media (min-width: 1000px) {
  .chart-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .chart-grid > .chart-card:last-child { grid-column: auto; }
  .chart-card--wide { grid-column: 1 / -1; }
}

.chart-card {
  display: flex;
  flex-direction: column;
  padding: 24px;
  border-radius: var(--r-xl);
  background: rgba(255, 255, 255, .045);
  border: 1px solid rgba(255, 255, 255, .08);
  box-shadow: var(--edge-d);
}
.chart-card h3 { margin: 0; font-size: 1.2rem; color: #fff; }
.chart-card p { margin: 8px 0 0; font-size: .95rem; line-height: 1.5; color: rgba(250, 250, 250, .6); }
/* The three small cards under the wide one run compact. */
.chart-card:not(.chart-card--wide) { padding: 18px 20px; }
.chart-card:not(.chart-card--wide) h3 { font-size: 1.05rem; }
.chart-card:not(.chart-card--wide) p { margin-top: 4px; font-size: .85rem; }

.chart-card__head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px 24px;
}

/* Segmented tabs and chips share one look. */
.chart-tabs {
  display: inline-flex;
  padding: 3px;
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .06);
  border: 1px solid rgba(255, 255, 255, .08);
}
.chart-tabs button,
.chart-chips button {
  font: inherit;
  font-size: .85rem;
  font-weight: 500;
  color: rgba(250, 250, 250, .62);
  background: transparent;
  border: 0;
  border-radius: var(--r-pill);
  padding: 6px 14px;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color .2s, color .2s;
}
/* A small phone: the two tabs keep one line each. */
@media (max-width: 379px) {
  .chart-tabs button { padding-inline: 11px; }
}
.chart-tabs button:hover,
.chart-chips button:hover { color: #fff; }
.chart-tabs button[aria-selected="true"] { background: rgba(255, 255, 255, .12); color: #fff; }

.chart-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.chart-chips button { border: 1px solid rgba(255, 255, 255, .1); padding: 5px 12px; }
.chart-chips button[aria-pressed="true"] { background: var(--brand); border-color: var(--brand); color: var(--brand-ink); }

.chart-card__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px 24px;
  margin-top: 18px;
  font-size: .9rem;
}
.chart-card__insight { display: inline-flex; align-items: center; gap: 8px; color: #fff; }
.chart-card__insight svg { width: 18px; height: 18px; flex: none; color: var(--brand); }

.chart-legend { display: inline-flex; gap: 16px; color: rgba(250, 250, 250, .6); }
.chart-legend > span { display: inline-flex; align-items: center; gap: 6px; }
.chart-legend i,
.area-chart__tip i { width: 9px; height: 9px; border-radius: 3px; background: var(--brand); flex: none; }
.chart-legend i.is-rival,
.area-chart__tip i.is-rival { background: rgba(255, 255, 255, .55); }

/* Area chart */
.area-chart { margin-top: 26px; }
.area-chart__plot {
  position: relative;
  height: clamp(180px, 22vw, 240px);
  border-bottom: 1px solid rgba(255, 255, 255, .14);
  touch-action: pan-y;
}
.area-chart__grid {
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(to bottom, rgba(255, 255, 255, .08) 0 1px, transparent 1px 25%);
  -webkit-mask-image: repeating-linear-gradient(to right, #000 0 4px, transparent 4px 8px);
  mask-image: repeating-linear-gradient(to right, #000 0 4px, transparent 4px 8px);
}
.area-chart svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.area-chart__fill, .area-chart__line { transition: d .5s cubic-bezier(.2, .7, .2, 1); }
.area-chart__fill--you { fill: url(#mk-fill-you); }
.area-chart__fill--rival { fill: url(#mk-fill-rival); }
.area-chart__line { fill: none; stroke-width: 1.5; vector-effect: non-scaling-stroke; }
.area-chart__line--you { stroke: var(--brand); }
.area-chart__line--rival { stroke: rgba(255, 255, 255, .55); stroke-dasharray: 5 4; }

.area-chart__cursor,
.area-chart__dot,
.area-chart__tip { position: absolute; opacity: 0; pointer-events: none; transition: opacity .15s; }
.area-chart__plot.is-active :is(.area-chart__cursor, .area-chart__dot, .area-chart__tip) { opacity: 1; }
.area-chart__cursor { top: 0; bottom: 0; width: 1px; background: rgba(255, 255, 255, .22); }
.area-chart__dot {
  width: 10px; height: 10px;
  margin: -5px 0 0 -5px;
  border-radius: 50%;
  border: 2px solid #0b0b0c;
  background: var(--brand);
}
.area-chart__dot--rival { background: #c9c9cc; }
.area-chart__tip {
  top: 8px;
  min-width: 170px;
  margin-left: 12px;
  display: grid;
  gap: 6px;
  padding: 10px 12px;
  border-radius: var(--r-sm);
  background: rgba(20, 20, 22, .94);
  border: 1px solid rgba(255, 255, 255, .12);
  box-shadow: 0 12px 30px -12px rgba(0, 0, 0, .8);
  font-size: .8rem;
  color: rgba(250, 250, 250, .66);
}
.area-chart__tip { transform: translateX(calc(-100% - 24px)); }
.area-chart__tip.is-right { transform: none; }
.area-chart__tip-label { color: #fff; font-weight: 600; }
.area-chart__tip-row { display: flex; align-items: center; gap: 8px; }
.area-chart__tip-row b { margin-left: auto; color: #fff; font-weight: 600; font-variant-numeric: tabular-nums; }
.area-chart__x { display: flex; justify-content: space-between; margin-top: 10px; font-size: .8rem; color: rgba(250, 250, 250, .5); }

/* Horizontal bars */
.hbar-chart { display: grid; gap: 6px; margin-top: auto; padding-top: 16px; }
.hbar {
  position: relative;
  display: flex;
  align-items: center;
  height: 24px;
  padding: 0 10px;
  font-size: .78rem;
}
.hbar__fill {
  position: absolute;
  inset: 0 auto 0 0;
  width: calc((100% - 3.5ch) * var(--w)); /* leaves a column for the value */
  border-radius: 6px;
  background: var(--brand);
  transition: opacity .2s;
}
.hbar__k { position: relative; color: var(--brand-ink); font-weight: 600; }
.hbar__v { position: relative; margin-left: auto; color: rgba(250, 250, 250, .66); font-variant-numeric: tabular-nums; }
.hbar-chart:hover .hbar:not(:hover) .hbar__fill { opacity: .35; }
.hbar:nth-child(1) { --w: .94; }
.hbar:nth-child(2) { --w: .76; }
.hbar:nth-child(3) { --w: .60; }
.hbar:nth-child(4) { --w: .40; }
.hbar:nth-child(5) { --w: .28; }

/* Ring */
.ring-chart { display: grid; justify-items: center; gap: 14px; margin-top: auto; padding-top: 16px; }
.ring-chart__dial { position: relative; width: 112px; aspect-ratio: 1; }
.ring-chart svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.ring-chart circle { fill: none; stroke-width: 12; }
.ring-chart__track { stroke: rgba(255, 255, 255, .08); }
.ring-chart__value { stroke: var(--brand); stroke-linecap: round; transition: stroke-dashoffset .6s cubic-bezier(.2, .7, .2, 1); }
.ring-chart__label { position: absolute; inset: 0; display: grid; place-content: center; text-align: center; }
.ring-chart__label b { font-size: 1.5rem; font-weight: 700; line-height: 1; color: #fff; font-variant-numeric: tabular-nums; }
.ring-chart__label small { margin-top: 2px; font-size: .72rem; color: rgba(250, 250, 250, .55); }
.ring-chart .chart-chips { justify-content: center; gap: 4px; }
.ring-chart .chart-chips button { padding: 3px 10px; font-size: .75rem; }

/* Columns */
.col-chart { display: flex; gap: 8px; height: 150px; margin-top: auto; padding-top: 18px; }
.col { flex: 1; min-width: 0; display: grid; grid-template-rows: minmax(0, 1fr) auto; }
.col__bar {
  position: relative;
  align-self: end;
  justify-self: center;
  width: 70%;
  height: calc(100% * var(--h));
  border-radius: 6px 6px 2px 2px;
  background: rgba(255, 255, 255, .14);
  transition: background-color .2s;
}
.col:hover .col__bar { background: rgba(255, 255, 255, .28); }
.col.is-you .col__bar { background: var(--brand); }
.col__bar em {
  position: absolute;
  bottom: calc(100% + 6px);
  left: 50%;
  transform: translateX(-50%);
  font-style: normal;
  font-size: .75rem;
  font-weight: 600;
  color: var(--brand);
}
.col small {
  margin-top: 8px;
  text-align: center;
  font-size: .72rem;
  color: rgba(250, 250, 250, .5);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.col.is-you small { color: #fff; }
.col:nth-child(1) { --h: .94; }
.col:nth-child(2) { --h: .78; }
.col:nth-child(3) { --h: .58; }
.col:nth-child(4) { --h: .44; }
.col:nth-child(5) { --h: .30; }

@media (prefers-reduced-motion: reduce) {
  .area-chart__fill, .area-chart__line, .ring-chart__value, .hbar__fill { transition: none; }
}

/* ── Legal documents ─────────────────────────────────────── */

.legal-hero { padding: clamp(46px, 7vh, 78px) 0 8px; }
.legal-hero h1 {
  font-size: clamp(2.1rem, 5.2vw, 3.1rem);
  line-height: 1.02;
  letter-spacing: -0.045em;
  margin: 0 0 12px;
}
.legal-hero .legal-meta { margin: 0; font-size: 14.5px; color: var(--faint); }

.back-to {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 13.5px; font-weight: 600;
  color: var(--muted);
  margin-bottom: 28px;
  padding: 8px 15px 8px 12px;
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .6);
  border: 1px solid var(--glass-edge);
  box-shadow: var(--ring), var(--edge);
  transition: background .25s var(--ease-out), color .25s var(--ease-out), transform .25s var(--ease-out);
}
.back-to:hover { color: var(--text); background: #fff; transform: translateX(-2px); }

.legal-doc { padding: 10px 0 48px; overflow-wrap: break-word; }
.legal-doc > p:first-child { margin-top: 0; }
.legal-doc h2 {
  font-size: 1.32rem;
  letter-spacing: -0.036em;
  margin: 2.2em 0 .55em;
  padding-top: 1.5em;
  border-top: 1px solid var(--hairline);
  color: var(--text);
}
.legal-doc h2:first-of-type { border-top: 0; padding-top: 0; margin-top: 1.6em; }
.legal-doc h3 { margin: 1.7em 0 .45em; font-size: 1rem; font-weight: var(--w-title); letter-spacing: -0.026em; }
.legal-doc p, .legal-doc li { color: var(--muted); font-size: 16px; line-height: 1.7; }
.legal-doc p { margin: .75em 0; }
.legal-doc ul, .legal-doc ol { margin: .6em 0 1.1em; padding-left: 1.4em; }
.legal-doc li { margin: .42em 0; }
.legal-doc strong { color: var(--text); font-weight: var(--w-body-em); }
.legal-doc a {
  color: var(--text);
  font-weight: 500;
}
.legal-doc .table-wrap { margin: 1.3em 0 1.7em; }

.callout {
  padding: clamp(20px, 2.4vw, 26px);
  border-radius: var(--r-lg);
  background: linear-gradient(170deg, rgba(255, 223, 0, .3), rgba(255, 223, 0, .12));
  border: 1px solid rgba(212, 182, 0, .32);
  box-shadow: 0 0 0 1px rgba(212, 182, 0, .1),
              0 18px 40px -30px var(--brand-glow),
              inset 0 1px 0 rgba(255, 255, 255, .8);
  color: var(--text-2);
  margin: 1.4em 0;
}
.callout--slim { padding-block: clamp(11px, 1.1vw, 14px); }
.callout strong { color: var(--ink); font-weight: var(--w-body-em); }
.callout p { color: inherit; font-size: inherit; margin: .55em 0; line-height: 1.65; }
.callout p:first-child { margin-top: 0; }
.callout p:last-child { margin-bottom: 0; }
.callout ul { margin: .6em 0 .2em; }
.callout li { color: inherit; font-size: inherit; }

.summary-box {
  padding: clamp(20px, 2.4vw, 26px);
  border-radius: var(--r-lg);
  background: rgba(255, 255, 255, .62);
  border: 1px solid var(--glass-edge);
  box-shadow: var(--ring), var(--edge);
  margin: 1.4em 0;
}
.summary-box h2 {
  border: 0 !important;
  padding-top: 0 !important;
  margin: 0 0 12px !important;
  font-size: 1rem !important;
  letter-spacing: -0.02em;
  color: var(--text) !important;
}
.summary-box ul { margin: 0; padding-left: 1.25em; }
.summary-box li { margin: 8px 0; font-size: 15.5px; }

.legal-index { list-style: none; margin: 1.2em 0; padding: 0; display: grid; gap: 8px; }
/* These are cards, not running prose — drop the document link underline. */
.legal-doc .legal-index a { text-decoration: none; font-weight: inherit; }
.legal-doc .legal-index a:hover { background: none; }
.legal-index li { border-top: 0; }
.legal-index li:last-child { border-bottom: 0; }
.legal-index a {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 16px;
  align-items: center;
  padding: 20px 22px;
  border-radius: var(--r-lg);
  border: 1px solid var(--glass-edge);
  background: rgba(255, 255, 255, .58);
  box-shadow: var(--ring), var(--edge);
  transition: background .3s var(--ease), transform .3s var(--ease), box-shadow .3s var(--ease);
}
.legal-index a:hover {
  background: rgba(255, 255, 255, .86);
  transform: translateY(-2px);
  box-shadow: var(--ring), var(--shadow-md), var(--edge);
}
.legal-index strong {
  display: block;
  font-family: var(--font-head);
  font-size: 1.04rem;
  font-weight: var(--w-title);
  letter-spacing: -0.032em;
  color: var(--text);
}
.legal-index span { display: block; }
.legal-index a > span > span {
  margin-top: 5px;
  color: var(--muted);
  font-size: .9rem;
  line-height: 1.55;
  font-weight: var(--w-body);
}
.legal-index .arrow {
  width: 34px; height: 34px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--brand);
  color: var(--brand-ink);
  font-size: 15px;
  line-height: 1;
  transition: transform .3s var(--ease);
  box-shadow: 0 8px 18px -10px var(--brand-glow), inset 0 1px 0 rgba(255, 255, 255, .5);
}
.legal-index a:hover .arrow { transform: translateX(3px); }

/* ── Footer ──────────────────────────────────────────────── */

/* Every other section on the site is an inset floating panel. The footer is
   the exception on purpose: it runs the full width with no edge at all and
   dissolves out of the page ground into flat brand yellow, so the page ends
   in the brand rather than in another card. Nothing here is glass — ink on
   yellow all the way down, which is also why the ribbon must NOT invert over
   it (see initTopbar) and why its focus rings stay ink. */
.site-footer {
  width: 100%;
  margin: clamp(12px, 2vw, 28px) 0 0;
  /* the top padding is where the fade happens — the columns must not start
     until the yellow has had room to come up out of the page */
  padding: clamp(44px, 4.5vw, 68px) 0 0;
  color: var(--brand-ink);
  background:
    radial-gradient(72% 42% at 50% 97%, var(--brand-hi) 0%, rgba(255, 233, 77, 0) 74%),
    linear-gradient(180deg,
      rgba(255, 223, 0, 0) 0%,
      rgba(255, 223, 0, .14) 24%,
      rgba(255, 223, 0, .50) 50%,
      rgba(255, 223, 0, .88) 72%,
      var(--brand) 88%,
      var(--brand) 100%);
  position: relative;
  overflow: hidden;
  isolation: isolate;
}

.footer-top {
  display: grid;
  gap: 38px;
  padding-bottom: 36px;
  border-bottom: 1px solid rgba(0, 0, 0, .12);
}
.footer-brand { max-width: 34em; min-width: 0; }
.footer-appicon {
  display: inline-block;
  line-height: 0;
}
.footer-appicon img {
  display: block;
  height: 38px;
  width: auto;
}

/* The marks under the brand are the four platforms soshctrl posts to, not
   our own social accounts — we do not run any, and a row of dead icons
   would be worse than none. Each one deep-links to its section and wears
   the platform's official mark in ink, centred in a hairline ring. The
   chip has no fill of its own: whatever the footer background is at that
   spot shows straight through, so it never reads as a grey disc. */
.footer-plat {
  list-style: none;
  margin: 20px 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}
.fplat {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  line-height: 0;
  color: var(--ink);
  background: transparent;
  box-shadow: inset 0 0 0 1px rgba(10, 10, 11, .14);
  transition: box-shadow .22s var(--ease-out);
}
.fplat svg { width: 16px; height: 16px; display: block; }
.fplat .fplat-cut { display: none; }
/* Stays put on hover — the ring just darkens; the inside stays clear. */
.fplat:hover,
.fplat:focus-visible {
  background: transparent;
  box-shadow: inset 0 0 0 1px rgba(10, 10, 11, .32);
}

.footer-cols { display: grid; gap: 30px; grid-template-columns: repeat(2, minmax(0, 1fr)); }

.fcol-h {
  font-family: var(--font-head);
  font-size: 13px;
  font-weight: var(--w-title);
  letter-spacing: -0.02em;
  color: var(--ink);
  margin: 0 0 14px;
}
.fcol-l {
  display: block;
  font-size: 14px;
  color: rgba(10, 10, 11, .62);
  padding: 6px 0;
  transition: color .2s var(--ease-out), transform .2s var(--ease-out);
}
/* yellow-on-yellow is no hover at all down here — go to ink instead */
.fcol-l:hover { color: var(--ink); transform: translateX(2px); }

.footer-bottom { padding: 0 0 clamp(8px, 1vw, 13px); display: grid; gap: 10px; }
.footer-bottom p { margin: 0; font-size: 12.5px; line-height: 1.6; color: rgba(10, 10, 11, .56); }
.footer-bottom .owner { color: rgba(10, 10, 11, .74); }
.footer-bottom a { color: rgba(10, 10, 11, .74); text-decoration: underline; text-underline-offset: 3px; }
.footer-bottom a:hover { color: var(--ink); }

/* ── The oversized wordmark ──────────────────────────────────
   The name at page width, sitting whole on the yellow — every
   letter finishes, with the copyright line tucked under the baseline.
   It is the wordmark used as an alpha mask over flat soft ink
   rather than a recoloured image, so
   it stays crisp at any size — and it is
   the same file the top bar loads, so it costs no new request.
   Purely ornamental, and hidden outright where masks are not
   supported — the fallback would be a plain ink slab.
   ────────────────────────────────────────────────────────── */

.footer-wordmark { display: none; }

@supports ((-webkit-mask-image: linear-gradient(#000, #000)) or (mask-image: linear-gradient(#000, #000))) {
  .footer-wordmark {
    display: block;
    /* Capped, or on a 2560px display the name alone would be 500px tall. */
    width: min(100% - clamp(36px, 9vw, 160px), 1520px);
    /* Air over it so it clears the column rule, and enough under the baseline
       for the copyright line that closes the page. */
    margin: clamp(26px, 3.2vw, 44px) auto clamp(14px, 1.6vw, 22px);
    aspect-ratio: 1780 / 392;
    pointer-events: none;
    position: relative;
    /* A mask clips everything drawn on its own element, shadows included, so
       the letters live on ::before and the shadow sits out here, where it is
       cast from the already-masked shape: a tight contact shade plus a softer
       drop, both falling straight down onto the yellow. */
    filter:
      drop-shadow(0 clamp(2px, .25vw, 4px) clamp(1px, .12vw, 2px) rgba(10, 10, 11, .22))
      drop-shadow(0 clamp(8px, 1vw, 16px) clamp(8px, 1vw, 16px) rgba(10, 10, 11, .20));
  }
  .footer-wordmark::before {
    content: "";
    position: absolute;
    inset: 0;
    /* Solid ink through the x-height, then easing into the footer's own yellow
       at the baseline, so the name settles into the colour it sits on. Mixed
       toward the brand yellow rather than faded to transparent, which would
       only turn the bottom a muddy olive. The base is --ink-soft, a step off
       pure black, so the name reads heavy without going to dead flat black. */
    background: linear-gradient(180deg,
      var(--ink-soft) 0%,
      var(--ink-soft) 60%,
      color-mix(in srgb, var(--ink-soft) 84%, var(--brand)) 80%,
      color-mix(in srgb, var(--ink-soft) 62%, var(--brand)) 100%);
    -webkit-mask: url("assets/wordmark.png") no-repeat center / 100% 100%;
    mask: url("assets/wordmark.png") no-repeat center / 100% 100%;
  }

  /* The closing line sits under the wordmark, so it measures itself against
     the wordmark rather than the page container: the same width, so the
     copyright starts where the "s" starts and the meta ends where the "l"
     ends. The glyphs run edge to edge in the file, so matching the box is
     enough — no optical nudge needed. */
  .footer-wordmark + .container { width: min(100% - clamp(36px, 9vw, 160px), 1520px); }
}

/* ── Page hero (interior pages) ──────────────────────────── */

.page-hero { padding: clamp(40px, 5.4vw, 70px) 0 clamp(26px, 4vw, 42px); max-width: 820px; }
.hero-shell:has(.page-hero) { padding-bottom: 0; }

/* An interior hero that opens on a full first screen: the headline holds the
   viewport on its own and the first section only arrives once you scroll.
   Unlike the homepage hero this one is top-aligned — the copy keeps the
   position it has on every other interior page and the screen is filled out
   underneath it, rather than the headline dropping to the middle. min-height,
   not height, so a short window or a phone grows the section rather than
   clipping it. The two-class selector is deliberate: it has to outrank the
   padding rule above. */
.hero-shell.hero-shell--full {
  display: flex;
  align-items: flex-start;
  min-height: calc(100vh - 70px);
  min-height: calc(100svh - 70px);
  padding-bottom: 0;
}

/* Whatever follows a full-screen hero starts at the fold. The hero's own
   empty lower half is already all the breathing room the next section needs,
   so it drops its standard ~100px of top padding instead of stacking more
   air on top of it. */
.hero-shell--full + .section { padding-top: clamp(12px, 1.6vw, 22px); }

/* A full-screen hero that gives the whole first screen to the headline
   itself: the copy is optically centred in the viewport and set at display
   size, and everything else on the page starts below the fold. Layered on
   top of --full, which supplies the height; --cover only re-centres and
   evens out the padding so the block sits in the middle of the screen
   rather than under its top edge. Used on Integrations. */
.hero-shell.hero-shell--cover {
  align-items: center;
  padding-top: clamp(24px, 3vw, 40px);
  padding-bottom: clamp(24px, 3vw, 40px);
}
/* The shell owns the vertical rhythm here, so the hero block drops the
   interior-page padding it would otherwise centre around. */
.hero-shell--cover .page-hero { padding: 0; }
/* A faint grid across the whole hero: hairlines in the text colour at low
   alpha, one continuous lattice revealed only in soft patches, under the
   headline and scattered around the screen, so it surfaces here and there
   and never draws a hard edge. Behind the copy, above the aurora. The
   Pricing display hero and the About hero (--grid) share the lattice with
   their own patches (below). */
.hero-shell.hero-shell--cover::after,
.hero-shell:has(.page-hero--display)::after,
.hero-shell.hero-shell--grid::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-image:
    linear-gradient(color-mix(in srgb, var(--text) 9%, transparent) 1px, transparent 1px),
    linear-gradient(90deg, color-mix(in srgb, var(--text) 9%, transparent) 1px, transparent 1px);
  background-size: 24px 24px;
  background-position: center center;
  --grid-mask:
    radial-gradient(ellipse 22% 16% at 50% 64%, #000, transparent),
    radial-gradient(ellipse 14% 20% at 12% 24%, #000, transparent),
    radial-gradient(ellipse 12% 16% at 86% 18%, rgba(0, 0, 0, .8), transparent),
    radial-gradient(ellipse 16% 18% at 80% 78%, #000, transparent),
    radial-gradient(ellipse 10% 14% at 20% 84%, rgba(0, 0, 0, .7), transparent),
    radial-gradient(ellipse 8% 12% at 36% 12%, rgba(0, 0, 0, .6), transparent);
  -webkit-mask-image: var(--grid-mask);
  mask-image: var(--grid-mask);
}

/* ── Model ribbon ────────────────────────────────────────────
   The AI providers behind the gateway, drifting past in their own
   colours directly under the Integrations hero. The hero gives up the
   ribbon's height so both land on the first screen. Each logo is drawn
   once as a <symbol>; a group repeats the set twice so it outruns
   even a wide screen at a tight gap. Three identical groups slide one full
   group width and loop without a seam; every copy but the first set is
   aria-hidden. */
.model-ribbon {
  --ribbon-gap: clamp(30px, 3vw, 44px);
  --ribbon-h: 92px;
  position: relative;
  height: var(--ribbon-h);
  display: flex;
  align-items: center;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
}
.model-ribbon__defs { position: absolute; width: 0; height: 0; overflow: hidden; }
.hero-shell.hero-shell--cover:has(+ .model-ribbon) {
  min-height: calc(100vh - 70px - 92px);
  min-height: calc(100svh - 70px - 92px);
}
.hero-shell--full + .model-ribbon + .section { padding-top: clamp(40px, 5vw, 72px); }

.model-ribbon__track {
  display: flex;
  gap: var(--ribbon-gap);
}
.model-ribbon__group {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: var(--ribbon-gap);
  list-style: none;
}
.model-ribbon__item {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  white-space: nowrap;
  font-size: .95rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--text);
}
.model-ribbon__logo { width: 16px; height: 16px; flex: none; }

@media (prefers-reduced-motion: no-preference) {
  .model-ribbon__group { animation: model-ribbon 60s linear infinite; }
}
@keyframes model-ribbon {
  to { transform: translateX(calc(-100% - var(--ribbon-gap))); }
}
/* Standing still, one set is enough: wrap it and drop the copy. */
@media (prefers-reduced-motion: reduce) {
  .model-ribbon { height: auto; min-height: var(--ribbon-h); padding-block: 20px; -webkit-mask-image: none; mask-image: none; }
  .model-ribbon__track, .model-ribbon__group { width: 100%; min-width: 0; flex-wrap: wrap; justify-content: center; row-gap: 18px; }
  .model-ribbon__group[aria-hidden="true"],
  .model-ribbon__item[aria-hidden="true"] { display: none; }
}
@media (max-width: 640px) {
  .model-ribbon { --ribbon-h: 72px; }
  .hero-shell.hero-shell--cover:has(+ .model-ribbon) {
    min-height: calc(100vh - 70px - 72px);
    min-height: calc(100svh - 70px - 72px);
  }
  .model-ribbon__item { font-size: .88rem; gap: 6px; }
  .model-ribbon__logo { width: 14px; height: 14px; }
}

/* ── Feature wall (product #everything) ──────────────────────
   The features that come as standard, as icon-and-name tiles papered
   across the full width in three rows that drift right to left. Each icon
   is drawn once as a <symbol>. A row holds the set twice and slides one
   set width, so it loops without a seam; rows start at different
   features and run at different speeds so the wall never lines up.
   Hovering the wall pauses it. Only the first set is read out. */
.feature-wall-section { overflow: hidden; padding-bottom: 36px; }
.feature-wall__defs { position: absolute; width: 0; height: 0; overflow: hidden; }
.section h2.feature-wall__title { text-align: center; }

.feature-wall {
  --wall-gap: 14px;
  display: grid;
  gap: var(--wall-gap);
  max-width: 1920px;
  margin-inline: auto;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent);
}
.feature-wall__row {
  display: flex;
  gap: var(--wall-gap);
  width: max-content;
}
.feature-wall__row:nth-child(2) { margin-left: -120px; }
.feature-wall__row:nth-child(3) { margin-left: -60px; }
.feature-wall__group {
  flex-shrink: 0;
  display: flex;
  gap: var(--wall-gap);
  margin: 0;
  padding: 0;
  list-style: none;
}
.feature-wall__tile {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  padding: 18px 26px 18px 20px;
  border-radius: var(--r-lg);
  background: rgba(255, 255, 255, .55);
  border: 1px solid var(--glass-edge);
  box-shadow: var(--ring), var(--edge);
  white-space: nowrap;
  font-size: 1rem;
  font-weight: var(--w-title);
  letter-spacing: -0.02em;
  color: var(--text);
  transition: background .4s var(--ease), box-shadow .4s var(--ease);
}
.feature-wall__tile:hover {
  background: rgba(255, 255, 255, .85);
  box-shadow: var(--ring), var(--shadow-sm), var(--edge);
}
.feature-wall__tile svg { width: 22px; height: 22px; flex: none; }

@media (prefers-reduced-motion: no-preference) {
  .feature-wall__group { animation: feature-wall 72s linear infinite; }
  .feature-wall__row:nth-child(2) .feature-wall__group { animation-duration: 88s; }
  .feature-wall__row:nth-child(3) .feature-wall__group { animation-duration: 80s; }
}
@keyframes feature-wall {
  to { transform: translateX(calc(-100% - var(--wall-gap))); }
}
/* Standing still, one set is enough: wrap it in the container and drop the copies. */
@media (prefers-reduced-motion: reduce) {
  .feature-wall { max-width: 1100px; padding-inline: 16px; -webkit-mask-image: none; mask-image: none; }
  .feature-wall__row, .feature-wall__group { width: 100%; margin-left: 0; flex-wrap: wrap; justify-content: center; }
  .feature-wall__row[aria-hidden="true"],
  .feature-wall__group[aria-hidden="true"] { display: none; }
}
@media (max-width: 640px) {
  .feature-wall { --wall-gap: 10px; }
  .feature-wall__tile { padding: 13px 18px 13px 15px; gap: 10px; font-size: .9rem; border-radius: var(--r-md); }
  .feature-wall__tile svg { width: 18px; height: 18px; }
}

.page-hero h1 {
  font-size: clamp(2.2rem, 5.4vw, 3.6rem);
  line-height: 1.02;
  letter-spacing: -0.052em;
  margin: 0 0 18px;
  font-weight: var(--w-display);
}
.page-hero p {
  margin: 0;
  color: var(--text-2);
  font-size: clamp(1.02rem, 1.7vw, 1.18rem);
  line-height: 1.6;
  max-width: 40em;
}
.page-hero .btn-row { margin-top: 30px; }
/* Small print under a headline: the logos mean "we use their models", not a sponsorship. */
.page-hero p.page-hero__disclaimer {
  margin: 0 auto;
  font-size: .8rem;
  line-height: 1.5;
  color: var(--muted);
  max-width: 44em;
}

/* ── Product hero: the yellow sky ────────────────────────────
   A full first screen washed in brand yellow, running up behind the
   ribbon (70px: 10 + --topbar-h + 8), with the app icon, the black
   wordmark as the headline, one line and a black button centred on
   it. The button is dark because the yellow primary vanishes on a
   yellow ground. The wash fades into the page at the bottom edge
   instead of stopping on a hard line.

   The sky is still: nothing in it follows the pointer. Little soshctrl
   S marks (::after) show only where a "current" strikes. js/site.js
   (initSunHero) fires strikes of one to five marks at free positions
   (runs, zigzags, arcs, forks, scatters) at random places and uneven
   gaps, the pulse stuttering along each one. With no script or reduced
   motion the marks stay hidden. */
.hero-shell.hero-sun {
  align-items: center;
  padding-top: clamp(24px, 3vw, 40px);
  padding-bottom: clamp(48px, 6vw, 80px);
}
.hero-shell.hero-sun::before {
  top: -70px; left: 0; bottom: 0;
  width: 100%; height: auto;
  transform: none;
  filter: none;
  background:
    radial-gradient(circle 120px at 50% 44%, rgba(255, 255, 255, .3), rgba(255, 255, 255, .08) 45%, transparent 72%),
    radial-gradient(circle 520px at 84% 42%, rgba(247, 186, 0, .55), transparent 70%),
    radial-gradient(34% 44% at 16% 30%, rgba(255, 255, 255, .7), transparent 70%),
    radial-gradient(26% 30% at 34% 78%, rgba(255, 255, 255, .45), transparent 70%),
    radial-gradient(40% 56% at 84% 42%, rgba(247, 190, 0, .6), transparent 72%),
    radial-gradient(30% 36% at 64% 12%, rgba(255, 244, 170, .9), transparent 70%),
    linear-gradient(160deg, #fff6b8 0%, var(--brand-hi) 34%, var(--brand) 62%, #f5c800 100%);
  -webkit-mask-image: linear-gradient(180deg, #000 82%, transparent);
  mask-image: linear-gradient(180deg, #000 82%, transparent);
}
/* The script writes one background layer per lit mark (--cur-img at
   --cur-pos), one mask layer for its brightness or a torn slice
   (--cur-mask), and the flicker (--cur-a). A mark is the S glyph at
   15.2 x 18.5px, the size the old tiled pattern drew it. Until the script
   runs the layer is invisible. */
.hero-shell.hero-sun::after {
  content: "";
  position: absolute;
  top: -70px; left: 0; right: 0; bottom: 0;
  z-index: -1;
  pointer-events: none;
  background-image: var(--cur-img, none);
  background-position: var(--cur-pos, 0 0);
  background-size: 15.2px 18.5px;
  background-repeat: no-repeat;
  opacity: var(--cur-a, 0);
  -webkit-mask-image: var(--cur-mask, none);
  mask-image: var(--cur-mask, none);
}
.hero-sun .page-hero { padding: 0; }

/* The first section after the sun hero sits a little lower. */
#pipelines { padding-top: clamp(96px, 11vw, 160px); }

.sun-hero__icon {
  width: clamp(72px, 7vw, 92px);
  height: auto;
  margin: 0 auto clamp(26px, 3.4vw, 40px);
  border-radius: 22%;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .12), 0 18px 36px -18px rgba(0, 0, 0, .45);
}
.page-hero h1.sun-hero__logo { margin: 0 0 clamp(20px, 2.6vw, 30px); line-height: 0; }
.sun-hero__logo img {
  width: clamp(220px, 34vw, 440px);
  height: auto;
  margin-inline: auto;
}
.hero-sun .page-hero p {
  color: var(--brand-ink);
  font-size: clamp(.92rem, 1.4vw, 1.02rem);
}
/* Tagline and button share one line, the tagline on the left. */
.sun-hero__cta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 12px 18px;
}
.page-hero .sun-hero__cta p { margin: 0; }
.page-hero .sun-hero__cta .btn-row { margin-top: 0; }

/* ── Centred where it earns it ───────────────────────────────
   The page is ranged left. Three compositions are centred on
   purpose, and each one says so on its own selector rather than
   taking it from the document: the interior page hero (here),
   the homepage hero (under "The centred column") and the two
   statement panels, .claim-band and .cta-band, which carry their
   own text-align where they are defined.

   What is collected here is the layout work centring needs that
   `text-align` cannot reach — a measure block has to take
   `margin-inline: auto` to sit in the middle, and a flex row has
   to be told where to put its own items, because text-align
   stops at a flex container.

   This replaced a site-wide rule that centred every heading,
   list, table cell and form field on the page. `tools/build.py`
   no longer sets the old `.page-center` class either; a stale
   one on a built page is inert.
   ────────────────────────────────────────────────────────── */

/* The interior page hero: a headline and one line under it, sitting in the
   middle of the screen it has been given. */
.page-hero {
  max-width: 880px;
  margin-inline: auto;
  text-align: center;
}
.page-hero p { margin-inline: auto; }
.page-hero .btn-row { justify-content: center; }

/* The homepage FAQ, centred as a composition: the heading, the column of
   questions and the link out all sit on the middle of the page. The
   questions keep their own ranged-left setting — a row with a chevron on
   its right edge reads from the left, and so does an opened answer. */
.faq-centred { text-align: center; }
.section.faq-centred { padding-bottom: clamp(24px, 2.8vw, 40px); }
.faq-centred .faq-list {
  margin-inline: auto;
  text-align: left;
}

/* The FAQ page: each group's column of questions sits on the middle of the
   page, and each group heading is centred over it a step larger than the
   default. Questions and answers keep their ranged-left setting. The
   heading's margins are !important in its base rule, so centring the box
   needs !important here too. */
.faq-page .narrow-block { margin-inline: auto; }
.faq-page .faq-group {
  justify-content: center;
  text-align: center;
  font-size: 1.5rem !important;
  margin-inline: auto !important;
  margin-bottom: 16px !important;
  /* The same hand-drawn yellow stroke every body link carries, so the
     group titles read as part of the same hand. The box shrinks to its
     words (width: max-content) so the stroke stops with the text
     instead of running the full 780px column. */
  width: max-content;
  max-width: 100%;
  background-image: var(--pen-brand);
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 100% .34em;
  padding-bottom: .2em;
}

/* A section whose headline and closing note sit on the middle of the page
   (Integrations' publishing list, Pricing's credits). The rows and cards
   between them keep their own ranged-left setting. */
.section-centred > .container > h2 { text-align: center; }
.section-centred .narrow-block { margin-inline: auto; }
.section-centred .section-copy {
  margin-inline: auto;
  text-align: center;
}
.section-centred .note {
  margin-inline: auto;
  text-align: center;
}

/* The CTA band's fine print — the band itself is centred where it is
   defined, and this is the one measure block inside it. */
.cta-fine { margin-inline: auto; }

/* ── The display hero ────────────────────────────────────────
   One word carrying the page, with the promise in a single line
   under it and nothing else. Used on Pricing.

   It sits closer under the ribbon than a normal page hero: with
   no button row under it, the standard rhythm leaves the
   title stranded in the middle of the first screen.
   ────────────────────────────────────────────────────────── */

.hero-shell:has(.page-hero--display) { padding-top: clamp(44px, 6.2vw, 88px); }
.page-hero--display {
  padding-top: clamp(14px, 2.4vw, 34px);
  padding-bottom: clamp(18px, 2.6vw, 30px);
}
.page-hero--display h1 {
  margin-bottom: clamp(14px, 1.8vw, 20px);
}
.page-hero--display p {
  font-size: clamp(.9rem, 1.3vw, .98rem);
}
/* Pricing takes the Integrations grid exactly: the same patches, sized to the
   Integrations hero's height (full screen less header and ribbon) and centred
   on the short band, so the lattice shows at the same size and strength
   instead of being stretched into bigger, stronger patches. The patches are
   drawn a touch larger (110% wide, 125% tall) for a little more grid.
   The first layer keeps the grid off the copy: a clear ellipse over the title
   and lead (their block ends 30px above the band's bottom edge), intersected
   with the six patches underneath, so no line runs through the text. */
.hero-shell:has(.page-hero--display)::after {
  /* The upper left and upper right are drawn stronger than the rest, as a
     mirrored pair. A mask can only take
     alpha away, so the lines go to 16% here and every other patch is
     scaled by 9/16 to stay exactly as faint as the shared lattice; the
     two upper patches keep full strength and are drawn a little larger.
     The top layer fades the whole lattice in over the band's first 120px,
     so no patch is cut off flat against the top edge. */
  background-image:
    linear-gradient(color-mix(in srgb, var(--text) 16%, transparent) 1px, transparent 1px),
    linear-gradient(90deg, color-mix(in srgb, var(--text) 16%, transparent) 1px, transparent 1px);
  --grid-mask:
    radial-gradient(ellipse 22% 16% at 50% 64%, rgba(0, 0, 0, .56), transparent),
    radial-gradient(ellipse 18% 22% at 16% 32%, #000, transparent),
    radial-gradient(ellipse 18% 22% at 84% 32%, #000, transparent),
    radial-gradient(ellipse 16% 18% at 80% 78%, rgba(0, 0, 0, .56), transparent),
    radial-gradient(ellipse 10% 14% at 20% 84%, rgba(0, 0, 0, .39), transparent),
    radial-gradient(ellipse 8% 12% at 36% 12%, rgba(0, 0, 0, .34), transparent);
  -webkit-mask-image: linear-gradient(transparent, #000 120px), radial-gradient(ellipse 480px 150px at 50% calc(100% - 95px), transparent 80%, #000), var(--grid-mask);
  mask-image: linear-gradient(transparent, #000 120px), radial-gradient(ellipse 480px 150px at 50% calc(100% - 95px), transparent 80%, #000), var(--grid-mask);
  -webkit-mask-composite: source-in, source-in, source-over, source-over, source-over, source-over, source-over, source-over;
  mask-composite: intersect, intersect, add, add, add, add, add, add;
  -webkit-mask-size: 100% 100%, 100% 100%, 110% calc((100vh - 162px) * 1.25), 110% calc((100vh - 162px) * 1.25), 110% calc((100vh - 162px) * 1.25), 110% calc((100vh - 162px) * 1.25), 110% calc((100vh - 162px) * 1.25), 110% calc((100vh - 162px) * 1.25);
  mask-size: 100% 100%, 100% 100%, 110% calc((100svh - 162px) * 1.25), 110% calc((100svh - 162px) * 1.25), 110% calc((100svh - 162px) * 1.25), 110% calc((100svh - 162px) * 1.25), 110% calc((100svh - 162px) * 1.25), 110% calc((100svh - 162px) * 1.25);
  -webkit-mask-position: center;
  mask-position: center;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
}

/* The Integrations grid, re-patched for a short band (About): one patch under the
   title, the rest out to the sides where the copy doesn't reach. The ellipses
   are taller in percent because the section is so much shorter. */
.hero-shell.hero-shell--grid::after {
  --grid-mask:
    radial-gradient(ellipse 20% 34% at 50% 40%, #000, transparent),
    radial-gradient(ellipse 12% 42% at 12% 36%, #000, transparent),
    radial-gradient(ellipse 11% 36% at 88% 30%, rgba(0, 0, 0, .8), transparent),
    radial-gradient(ellipse 10% 34% at 80% 82%, rgba(0, 0, 0, .7), transparent),
    radial-gradient(ellipse 8% 30% at 24% 86%, rgba(0, 0, 0, .6), transparent);
}

/* A cover hero without the lattice (About): the aurora stays, the grid goes. */
.hero-shell.hero-shell--plain::after { content: none; }

/* ── Utilities ───────────────────────────────────────────── */

.mt-lg { margin-top: 30px; }
.mt-md { margin-top: 18px; }

.note {
  margin: 24px 0 0;
  font-size: .87rem;
  color: var(--faint);
  line-height: 1.6;
  max-width: 46em;
}
.note a { color: var(--muted); }
.note a:hover { color: var(--text); }

.lead-out { margin: 28px 0 0; color: var(--muted); font-size: .97rem; line-height: 1.65; max-width: 46em; }
.lead-out a {
  color: var(--text);
}

.band-dark .note { color: rgba(250, 250, 250, .48); }
.band-dark .note a { color: rgba(250, 250, 250, .7); }
.band-dark .lead-out { color: rgba(250, 250, 250, .62); }
.band-dark .lead-out a { color: #fff; }
/* On a black ground the hover must stay white: the plain .note hover
   above would otherwise pull the word back to dark ink. */
.band-dark .note a:hover,
.band-dark .lead-out a:hover,
.fan-stage .note a:hover,
.fan-stage .lead-out a:hover { color: #fff; }

.link-inline {
  color: var(--text);
  font-weight: 500;
}

/* ── Pen underline ───────────────────────────────────────────
   Every plain-text link in the page body carries a hand-drawn
   yellow marker stroke instead of a ruled text-decoration.
   Negative margins let the stroke overshoot the word on both
   sides without shifting the text.

   Written with :where() so the whole block has zero specificity:
   any component that styles its own links — the legal index
   cards, .note, .link-inline — keeps winning on colour and
   weight without having to re-state the stroke. The opt-out
   below covers links shaped like a button or a card, which is
   the only thing :where() cannot decide for itself. */
:where(main a) {
  text-decoration: none;
  background-image: var(--pen-brand);
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 100% .5em;
  padding: 0 .18em .22em;
  margin: 0 -.18em;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}
/* One hover for every marker link, everywhere on the site: a soft
   yellow wash lifts behind the word — the padding above already holds
   it a little clear of the glyphs — and the stroke is drawn again with
   more weight, as if the pen were pressed harder. No component swaps
   it for a black stroke or leaves the wash off any more: a link that
   reads one way at rest should not change character under the pointer
   just because of where it sits. */
:where(main a:hover) {
  background-size: 100% .58em;
  background-color: var(--brand-wash);
  border-radius: 3px;
}

@media (prefers-reduced-motion: no-preference) {
  :where(main a) { transition: background-size .18s ease, background-color .18s ease; }
}

/* Not plain text: CTAs, the back-to-legal pill, the legal index
   cards. They bring their own padding and background. */
:where(main .btn, main .back-to, main .legal-index a) {
  background-image: none;
  background-size: auto;
  margin: 0;
}
/* …and the hover wash is for running text, not for a shape that already
   carries a fill of its own. Zero specificity here too, so any component
   with its own hover background still wins. */
:where(main .btn:hover, main .back-to:hover, main .legal-index a:hover) {
  background-color: transparent;
}

.list-wide { max-width: 44em; }
.narrow-block { max-width: 780px; }
.measure { max-width: 62ch; }

.hero-shell + .section--tight { padding-top: clamp(30px, 4vw, 48px); }

/* ── Entrance ────────────────────────────────────────────────
   Above-the-fold copy rises on load. Pure CSS, so it never
   depends on JavaScript having run.
   ────────────────────────────────────────────────────────── */

@keyframes rise {
  from { opacity: 0; transform: translateY(22px); }
  to   { opacity: 1; transform: none; }
}

.hero-copy > *,
.page-hero > *,
.legal-hero > * { animation: rise .9s var(--ease) both; }

.hero-copy > *:nth-child(2), .page-hero > *:nth-child(2), .legal-hero > *:nth-child(2) { animation-delay: .07s; }
.hero-copy > *:nth-child(3), .page-hero > *:nth-child(3) { animation-delay: .14s; }
.hero-copy > *:nth-child(4), .page-hero > *:nth-child(4) { animation-delay: .21s; }
.hero-copy > *:nth-child(5), .page-hero > *:nth-child(5) { animation-delay: .28s; }

.hero-mock { animation: rise 1s var(--ease) both; animation-delay: .16s; }

/* ── Setup rail (Product, #setup) ────────────────────────────
   The six setup decisions as one row of tall glass cards in a
   native horizontal scroller: a sideways touchpad swipe, a touch
   swipe or shift + wheel moves it, and vertical scrolling passes
   straight through to the page. js/site.js marks the card nearest
   the scroll position active and keeps the counter in step.

   The heading is centred: this is a composition built around the
   middle of the screen, like the heroes and the statement bands.
   ────────────────────────────────────────────────────────── */

.setup { padding-bottom: clamp(40px, 5vw, 72px); }
.setup .setup__title {
  text-align: center;
  margin: 0 auto clamp(22px, 3vw, 36px);
}

.setup__viewport {
  --setup-gutter: max(22px, calc((100% - 1120px) / 2));
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x proximity;
  /* A sideways swipe that hits either end must not become browser back/forward. */
  overscroll-behavior-x: contain;
  scroll-padding-inline: var(--setup-gutter);
  scrollbar-width: none;
  outline: none;
}
/* Glass reads as flat grey with nothing behind it: two soft yellow pools
   sit under the row for the cards to blur. */
.setup__viewport {
  background:
    radial-gradient(34% 46% at 28% 58%, rgba(255, 223, 0, .2), transparent 70%),
    radial-gradient(30% 42% at 74% 44%, rgba(255, 223, 0, .14), transparent 70%);
}
.setup__viewport::-webkit-scrollbar { display: none; }
.setup__viewport:focus-visible .setup__track { outline: 2px solid var(--brand-deep); outline-offset: 4px; border-radius: 34px; }

.setup__track {
  display: flex;
  gap: clamp(12px, 1.4vw, 18px);
  width: max-content;
  list-style: none;
  margin: 0;
  /* Room for the cards' lift and soft shadow — the viewport clips. */
  padding: 20px var(--setup-gutter) 56px;
}
.setup__viewport + .setup__foot { margin-top: -24px; }

.setup-card {
  position: relative;
  flex: 0 0 auto;
  width: clamp(248px, 23vw, 292px);
  height: clamp(264px, 23vw, 300px);
  display: flex;
  flex-direction: column;
  padding: clamp(22px, 2.2vw, 28px);
  border-radius: 30px;
  isolation: isolate;
  /* Liquid glass, on the ribbon's recipe: a thin white fill so the blurred
     backdrop survives, a specular rim drawn with inset shadows, and a soft
     sheen across the top third (::before). */
  background:
    linear-gradient(180deg,
      rgba(255, 255, 255, .56) 0%,
      rgba(255, 255, 255, .26) 48%,
      rgba(255, 255, 255, .4) 100%);
  -webkit-backdrop-filter: var(--blur-glass);
  backdrop-filter: var(--blur-glass);
  border: 0;
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, .6),
    inset 0 1.5px 0 rgba(255, 255, 255, .95),
    inset 0 -1px 0 rgba(255, 255, 255, .35),
    inset 0 0 26px rgba(255, 255, 255, .28),
    0 0 0 1px rgba(0, 0, 0, .035),
    0 22px 44px -30px rgba(0, 0, 0, .3);
  scroll-snap-align: start;
  cursor: default;
  transition:
    transform var(--t-3) var(--ease),
    box-shadow var(--t-3) var(--ease);
}
.setup-card::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  pointer-events: none;
  background:
    radial-gradient(120% 60% at 20% -8%, rgba(255, 255, 255, .75), transparent 58%),
    linear-gradient(115deg, transparent 38%, rgba(255, 255, 255, .22) 50%, transparent 62%);
  transition: opacity var(--t-3) var(--ease);
}
/* The same card with a yellow tint and glow — .is-active fades it in. */
.setup-card::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0;
  background:
    radial-gradient(90% 55% at 50% 110%, rgba(255, 223, 0, .3), transparent 70%),
    linear-gradient(180deg, rgba(255, 255, 255, .34), rgba(255, 255, 255, .1));
  transition: opacity var(--t-3) var(--ease);
}

.setup-card__icon {
  display: block;
  color: var(--ink);
}
.setup-card__icon svg { display: block; width: 30px; height: 30px; }

.setup-card__body { margin-top: auto; }
.setup-card h3 {
  margin: 0 0 10px;
  font-size: clamp(1.18rem, 1.5vw, 1.34rem);
  letter-spacing: -0.034em;
  line-height: 1.18;
}
.setup-card p {
  margin: 0;
  color: var(--muted);
  font-size: .94rem;
  line-height: 1.58;
  transition: color var(--t-3) var(--ease);
}

/* The card in hand. */
.setup-card.is-active {
  transform: translateY(-8px);
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, .8),
    inset 0 1.5px 0 #fff,
    inset 0 -1px 0 rgba(255, 223, 0, .45),
    inset 0 0 30px rgba(255, 255, 255, .4),
    0 0 0 1px rgba(212, 182, 0, .28),
    0 26px 56px -26px rgba(212, 182, 0, .55),
    0 18px 40px -28px rgba(0, 0, 0, .22);
}
.setup-card.is-active::after { opacity: 1; }
.setup-card.is-active p { color: var(--text-2); }

.setup__foot {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
}
.setup__count {
  font-family: var(--font);
  font-size: 12px;
  letter-spacing: .04em;
  color: var(--faint);
  font-variant-numeric: tabular-nums;
}
.setup__count b { color: var(--text); font-weight: 600; }
.setup__bar {
  position: relative;
  width: 140px;
  height: 3px;
  border-radius: 3px;
  background: var(--hairline-mid);
  overflow: hidden;
}
.setup__fill {
  position: absolute;
  inset: 0;
  background: var(--ink);
  transform: scaleX(0);
  transform-origin: left center;
}

.setup-card { cursor: pointer; }
.setup-card:not(.is-active):hover { transform: translateY(-3px); }

/* ── Scroll reveal ───────────────────────────────────────────
   js/site.js adds `.reveal` only when IntersectionObserver and
   motion are both available, so with no JS everything renders
   in its final state.
   ────────────────────────────────────────────────────────── */

/* 22px over .8s on an expo curve meant a block sat nearly still for the last
   half-second of its own entrance — arriving late and looking like lag rather
   than poise. Shorter travel, shorter time, and the fade lands before the
   movement does, so the text is readable while it is still settling. */
.reveal {
  opacity: 0;
  transform: translateY(15px);
  will-change: opacity, transform;
}
.reveal.is-in {
  opacity: 1;
  transform: none;
  transition: opacity .5s var(--ease-out), transform .68s var(--ease-smooth);
}
/* The stagger delay is set inline by js/site.js in page order. */

/* A revealed price card keeps its hover easing alongside the entrance, and
   only the entrance is staggered, so the lift answers the pointer at once.
   These positional delays only cover a plan switch settling a panel by hand. */
.price-card.reveal.is-in {
  transition: opacity .5s var(--ease-out), transform .68s var(--ease-smooth),
              translate .4s var(--ease), box-shadow .4s var(--ease);
}
.price-card.reveal.is-in:nth-child(2) { transition-delay: .055s, .055s, 0s, 0s; }
.price-card.reveal.is-in:nth-child(3) { transition-delay: .11s, .11s, 0s, 0s; }
.price-card.reveal.is-in:nth-child(4) { transition-delay: .165s, .165s, 0s, 0s; }

/* ── Responsive ──────────────────────────────────────────── */

@media (max-width: 900px) {
  .nav-links { display: none; }
  .nav-flyout, .nav-scrim { display: none !important; }
  .menu-toggle { display: inline-flex; }
  .topbar-tools .btn { display: none; }
  .topbar-inner { grid-template-columns: auto 1fr; padding-right: 10px; }
  .topbar-tools { justify-self: end; }
}

@media (min-width: 720px) {
  .feature-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; }
  .cap-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .info-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .price-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .price-grid--duo { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* Cards side by side share one set of rows, so a tagline that wraps to an
     extra line doesn't push that card's price below its neighbours'. */
  .price-card {
    display: grid;
    grid-row: span 6;
    grid-template-rows: subgrid;
    row-gap: 0;
  }
  /* Label in its own track, detail beside it. */
  .contact-row { grid-template-columns: 210px minmax(0, 1fr); gap: 7px 20px; align-items: baseline; }
  /* Brand beside the link columns, two by two. At 1040 all four share a row. */
  .footer-top {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.25fr);
    grid-template-areas: "brand links";
    column-gap: 48px;
    align-items: start;
  }
  /* Sits on the rule rather than floating at the top of the taller columns. */
  .footer-brand { grid-area: brand; align-self: end; }
  .footer-cols { grid-area: links; }
  /* The closing two lines share one row: owner on the left, meta pushed to
     the right edge. They wrap back to a stack if the row runs out of room. */
  .footer-bottom {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: baseline;
    gap: 6px 32px;
  }
  .footer-bottom .meta { margin-left: auto; }
}

/* The homepage hero owns a whole screen on a tall window — open the
   rhythm up so the block sits in that space rather than floating in it. */
@media (min-width: 960px) and (min-height: 800px) {
  .hero h1 { margin-bottom: 26px; }
  .hero-lead { margin-bottom: 42px; font-size: 1.2rem; }
}

@media (min-width: 960px) {
  .hero { grid-template-columns: minmax(0, 1.04fr) minmax(0, .96fr); gap: 60px; }
  .info-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .price-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .price-grid--duo { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Four cards in the 1120px column run narrow, so on wide screens the deck
   reaches past the column by up to 60px a side, never closer than 22px to
   the viewport edge. The breakout sits on the deck, not the grid, so the
   swap's overflow clip is just as wide. */
@media (min-width: 1180px) {
  .plan-deck { --deck-out: clamp(0px, (100vw - 1180px) / 2, 60px); margin-inline: calc(-1 * var(--deck-out)); }
  .plan-panel__title { padding-inline: var(--deck-out); }
}

@media (min-width: 1040px) {
  /* Reading order again: the steps are the text, the console is the exhibit
     pinned alongside them. The sticky offset clears the ribbon plus air. */
  .runview {
    grid-template-columns: minmax(0, 1.12fr) minmax(0, .88fr);
    column-gap: clamp(28px, 3.2vw, 46px);
    align-items: start;
  }
  .runview__side { order: 0; position: sticky; top: 96px; }

  .footer-top {
    grid-template-columns: minmax(0, 1fr) minmax(0, 2.3fr);
    column-gap: clamp(34px, 3.6vw, 64px);
  }
  .footer-cols { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

@media (max-width: 600px) {
  .section--sunken,
  .section.band-dark,
  .claim-band { width: min(1280px, calc(100% - 16px)); }
}

@media (max-width: 460px) {
  html, body { font-size: 16px; }
  .idrow .k { width: 100%; }
  .btn { width: 100%; }
  .btn-row { flex-direction: column; }
  .topbar-tools .btn { width: auto; }
  .site-drawer__cta { width: 100%; }
  .console__foot { flex-wrap: wrap; }
  .step { grid-template-columns: 1fr; gap: 12px; }
  /* No room for a third track — the status tag drops under the copy it
     belongs to rather than squeezing the description to nothing. */
  .plat-row { grid-template-columns: auto minmax(0, 1fr); gap: 12px; }
  .plat-row .tag { grid-column: 2; justify-self: start; }
  /* "Business & Enterprise" has to fit half a phone — the icons go first,
     and the label is allowed a second line rather than pushing out of
     the pill on the narrowest screens. */
  .plan-switch__icon { display: none; }
  .plan-switch__opt {
    padding: 8px 10px;
    font-size: 13px;
    line-height: 1.25;
    white-space: normal;
  }
}

/* ── Homepage stage — the first screen ───────────────────────
   Full-bleed on the page ground, no panel or frame, the ribbon
   floating over its top. A centred column of type, then the spin:
   posts soshctrl published and the app screens that made them,
   turning on one slow ring. Its only colour is brand light — a
   pool of yellow under the ring and two faint washes in the top
   corners.

   The ribbon is sticky, so it occupies 70px of flow (10 +
   --topbar-h + 8). The stage is pulled up under it and pays it
   back as padding, so nothing lands under the pill.
   ────────────────────────────────────────────────────────── */

.hero-shell.hero-stage {
  width: 100%;
  margin: calc(-10px - var(--topbar-h)) 0 0;
  padding-top: calc(10px + var(--topbar-h) + clamp(22px, 4.6vh, 50px));
  padding-bottom: clamp(24px, 4vh, 40px);
  min-height: 100vh;
  min-height: 100svh;
  flex-direction: column;
  align-items: stretch;
  justify-content: center;
  /* No frame: the hero sits straight on the page ground. The ring is wider
     than the window on purpose, so clip sideways only. */
  overflow: visible;
  overflow-x: clip;
}
/* The brand light, laid on the ground rather than inside a panel. It fades
   out before the section's bottom edge so no band line shows. */
.hero-shell.hero-stage::before {
  top: 0; left: 0; right: 0; bottom: 0;
  width: auto; height: auto;
  transform: none;
  filter: none;
  background:
    radial-gradient(58% 46% at 50% 100%, rgba(255, 223, 0, .34), transparent 72%),
    radial-gradient(34% 30% at 8% 4%, rgba(255, 223, 0, .13), transparent 70%),
    radial-gradient(30% 28% at 94% 10%, rgba(255, 223, 0, .1), transparent 70%);
  -webkit-mask-image: linear-gradient(to bottom, #000 70%, transparent);
          mask-image: linear-gradient(to bottom, #000 70%, transparent);
}

.hero-kicker { margin-bottom: 18px; }

/* ── The centred column ──────────────────────────────────── */

.hero.hero--center {
  grid-template-columns: minmax(0, 1fr);
  justify-items: center;
  text-align: center;
  gap: 0;
}
.hero--center .hero-copy { max-width: 940px; }
.hero--center .btn-row { justify-content: center; margin-top: clamp(38px, 4.4vw, 56px); }
.hero--center .btn-row .btn { min-height: 42px; padding: 0 22px; font-size: 14.5px; }
.hero--center .btn-row .btn__icon { width: 15px; height: 15px; }

.hero-stage .hero h1 {
  font-size: clamp(2.4rem, 5.1vw, 4.15rem);
  line-height: .98;
  letter-spacing: -0.055em;
}
.hero--center .hero-lead {
  margin-inline: auto;
  margin-bottom: 26px;
  max-width: 38em;
  text-wrap: balance;
}

/* The second line carries the brand the way the rest of the page does — the
   same hand-drawn marker stroke every body link is underlined with, drawn at
   headline weight. */
.hero-hl {
  color: var(--text);
  background-image: var(--pen-brand);
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 100% .28em;
  padding: 0 .06em .06em;
  margin: 0 -.06em;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}

/* ── The spin ────────────────────────────────────────────────
   Thirty-six cards on a ring, 10° apart — the eighteen
   designs twice, the second lap offset by half a set. One width drives the
   whole thing: the card height, the ring radius and the type
   inside every card are all multiples of --c-w, so the ring
   keeps its shape at any size without a breakpoint.

   Radius: 7.16w puts the circumference at 45w, so each of
   the 36 cards gets its own width plus a quarter of one in air.

   The ring is pushed back by its own radius and the cards face
   out, so the card straight ahead sits at its natural size and
   the ones towards either edge turn away and recede. The camera
   is close (perspective 11.6w), which is what gives the edges their
   lean. Cards turned away are dropped by their backface. No edge
   fade — the cards run clean off both sides.
   ────────────────────────────────────────────────────────── */

.spin {
  --c-w: clamp(101px, 10.9vw, 175px);
  --c-h: calc(var(--c-w) * 1.32);
  --R: calc(var(--c-w) * 7.16);

  position: relative;
  height: calc(var(--c-h) * 1.3);
  margin-top: clamp(18px, 3.6vh, 40px);
  perspective: calc(var(--c-w) * 11.63);
  perspective-origin: 50% 50%;
}
.spin__scene {
  position: absolute;
  left: 50%; top: 50%;
  width: var(--c-w);
  height: var(--c-h);
  margin: calc(var(--c-h) / -2) 0 0 calc(var(--c-w) / -2);
  transform-style: preserve-3d;
}
.spin__ring {
  position: absolute;
  inset: 0;
  margin: 0;
  padding: 0;
  list-style: none;
  transform-style: preserve-3d;
  transform: translateZ(calc(var(--R) * -1)) rotateY(0deg);
  animation: spin-turn 90s linear infinite;
}
@keyframes spin-turn {
  from { transform: translateZ(calc(var(--R) * -1)) rotateY(0deg); }
  to   { transform: translateZ(calc(var(--R) * -1)) rotateY(-360deg); }
}

.spin__item {
  --i: 0;
  position: absolute;
  inset: 0;
  transform: rotateY(calc(var(--i) * 10deg)) translateZ(var(--R));
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
}
.spin__item:nth-child(2) { --i: 1; }
.spin__item:nth-child(3) { --i: 2; }
.spin__item:nth-child(4) { --i: 3; }
.spin__item:nth-child(5) { --i: 4; }
.spin__item:nth-child(6) { --i: 5; }
.spin__item:nth-child(7) { --i: 6; }
.spin__item:nth-child(8) { --i: 7; }
.spin__item:nth-child(9) { --i: 8; }
.spin__item:nth-child(10) { --i: 9; }
.spin__item:nth-child(11) { --i: 10; }
.spin__item:nth-child(12) { --i: 11; }
.spin__item:nth-child(13) { --i: 12; }
.spin__item:nth-child(14) { --i: 13; }
.spin__item:nth-child(15) { --i: 14; }
.spin__item:nth-child(16) { --i: 15; }
.spin__item:nth-child(17) { --i: 16; }
.spin__item:nth-child(18) { --i: 17; }
.spin__item:nth-child(19) { --i: 18; }
.spin__item:nth-child(20) { --i: 19; }
.spin__item:nth-child(21) { --i: 20; }
.spin__item:nth-child(22) { --i: 21; }
.spin__item:nth-child(23) { --i: 22; }
.spin__item:nth-child(24) { --i: 23; }
.spin__item:nth-child(25) { --i: 24; }
.spin__item:nth-child(26) { --i: 25; }
.spin__item:nth-child(27) { --i: 26; }
.spin__item:nth-child(28) { --i: 27; }
.spin__item:nth-child(29) { --i: 28; }
.spin__item:nth-child(30) { --i: 29; }
.spin__item:nth-child(31) { --i: 30; }
.spin__item:nth-child(32) { --i: 31; }
.spin__item:nth-child(33) { --i: 32; }
.spin__item:nth-child(34) { --i: 33; }
.spin__item:nth-child(35) { --i: 34; }
.spin__item:nth-child(36) { --i: 35; }
/* Every card sits on the same centre line, so the arc reads as one clean band. */

/* Everything inside a card is sized in em off this, so a card is one
   drawing scaled rather than a layout reflowing. */
.spin-card {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
  border-radius: calc(var(--c-w) * .1);
  background: #fff;
  border: 1px solid rgba(0, 0, 0, .06);
  box-shadow: 0 1px 1px rgba(0, 0, 0, .04), 0 22px 44px -22px rgba(0, 0, 0, .34);
  font-size: calc(var(--c-w) * .062);
  line-height: 1.3;
  letter-spacing: -0.01em;
  color: var(--ink);
  text-align: left;
}
.spin-card svg { width: 1.15em; height: 1.15em; flex: none; }

/* A published post. No border and no dark backing, so no dark rim shows
   at the rounded edge. */
.spin-post {
  background: transparent;
  border: 0;
}
.spin-post__img {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  border-radius: inherit;
}
.spin-post__meta {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  display: grid;
  gap: .45em;
  padding: 2.8em .9em .85em;
  background: linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, .74));
  color: #fff;
}
.spin-post__title { font-size: 1.08em; font-weight: 650; line-height: 1.18; }
.spin-post__stats {
  display: flex;
  gap: .9em;
  font-size: .9em;
  font-variant-numeric: tabular-nums;
  color: rgba(255, 255, 255, .84);
}
.spin-post__stats > span { display: inline-flex; align-items: center; gap: .3em; }

/* A screen of the app. */
.spin-app {
  display: flex;
  flex-direction: column;
  gap: .6em;
  padding: .95em;
}
.spin-app__head {
  display: flex;
  align-items: center;
  gap: .45em;
  font-weight: 600;
  font-size: .95em;
}
.spin-app__dot {
  width: .6em; height: .6em;
  flex: none;
  border-radius: 50%;
  background: var(--brand);
  box-shadow: 0 0 0 .22em var(--brand-wash);
}
.spin-app__tag {
  margin-left: auto;
  padding: .15em .55em;
  border-radius: var(--r-pill);
  background: var(--brand-wash);
  font-size: .82em;
}
.spin-app__thumb {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: .7em;
}
.spin-app__doc { font-size: 1.05em; font-weight: 650; line-height: 1.2; }
.spin-app__acts { display: flex; gap: .4em; margin-top: auto; }
.spin-app__acts span {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .3em;
  min-width: 2.3em;
  height: 2.3em;
  padding: 0 .6em;
  border-radius: var(--r-pill);
  background: #f1f1f4;
  font-weight: 650;
}
.spin-app__acts .is-go { flex: 1; background: var(--brand); }
.spin-app__big {
  display: flex;
  align-items: center;
  gap: .4em;
  font-size: 1.25em;
  font-weight: 700;
  letter-spacing: -0.025em;
}
.spin-app__days { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: .25em; }
.spin-app__days span {
  display: grid;
  place-items: center;
  aspect-ratio: 1;
  border-radius: .45em;
  background: #f1f1f4;
  font-size: .8em;
  font-weight: 600;
  color: var(--muted);
}
.spin-app__days .is-on { background: var(--brand); color: var(--ink); }
.spin-app__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .5em;
  padding-top: .5em;
  border-top: 1px solid var(--hairline-mid);
  font-size: .9em;
}
.spin-app__row > span { display: inline-flex; align-items: center; gap: .35em; color: var(--muted); }
.spin-app__row b { font-weight: 600; font-variant-numeric: tabular-nums; }
.spin-app__row.is-dim { opacity: .5; }
.spin-app__num {
  font-size: 2.3em;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.045em;
  font-variant-numeric: tabular-nums;
}
.spin-app__sub { margin-top: -.3em; font-size: .88em; color: var(--muted); }
.spin-app__meter { height: .5em; border-radius: var(--r-pill); background: #ececf0; overflow: hidden; }
.spin-app__meter span { display: block; width: 8%; height: 100%; border-radius: inherit; background: var(--brand); }
.spin-app__bars {
  display: flex;
  align-items: flex-end;
  gap: .35em;
  height: 5.2em;
  margin-top: auto;
}
.spin-app__bars span { flex: 1; height: 40%; border-radius: .3em .3em .15em .15em; background: #e6e6ea; }
.spin-app__bars span:nth-child(2) { height: 55%; }
.spin-app__bars span:nth-child(3) { height: 35%; }
.spin-app__bars span:nth-child(4) { height: 68%; }
.spin-app__bars span:nth-child(5) { height: 60%; }
.spin-app__bars span:nth-child(6) { height: 82%; }
.spin-app__bars span:nth-child(7) { height: 100%; background: var(--brand); }
.spin-app__wave { display: flex; align-items: center; gap: .24em; height: 3.4em; }
.spin-app__wave span { flex: 1; height: 30%; border-radius: var(--r-pill); background: var(--ink); }
.spin-app__wave span:nth-child(3n)   { height: 70%; }
.spin-app__wave span:nth-child(4n+1) { height: 50%; }
.spin-app__wave span:nth-child(5n)   { height: 95%; background: var(--brand-deep); }

.spin-app--dark { background: var(--ink); border-color: var(--ink); color: #fff; }
.spin-app--dark .spin-app__row { border-top-color: rgba(255, 255, 255, .12); }
.spin-app--dark .spin-app__row > span,
.spin-app--dark .spin-app__sub { color: rgba(255, 255, 255, .6); }
.spin-app--dark .spin-app__meter { background: rgba(255, 255, 255, .14); }
.spin-app--dark .spin-app__num { color: var(--brand); }

.spin-app--brand { background: linear-gradient(160deg, var(--brand-hi), var(--brand)); border-color: rgba(0, 0, 0, .08); }
.spin-app--brand .spin-app__dot { background: var(--ink); box-shadow: none; }
.spin-app--brand .spin-app__row { border-top-color: rgba(0, 0, 0, .1); }
.spin-app--brand .spin-app__row > span { color: rgba(10, 10, 11, .62); }

/* ── Why soshctrl — the statement and its four tiles ─────────
   The heading is a statement, so it is centred like the other
   statement panels; the tiles under it are ranged left.
   ────────────────────────────────────────────────────────── */

.intro__head {
  max-width: 920px;
  margin: 0 auto clamp(34px, 4.4vw, 56px);
  text-align: center;
}
.intro .intro__title {
  margin: 0;
  font-size: clamp(2rem, 4.4vw, 3.35rem);
  line-height: 1.08;
  letter-spacing: -0.045em;
}
.intro__mute { color: var(--faint); }
.intro__badge {
  display: inline-grid;
  place-items: center;
  width: .9em; height: .9em;
  border-radius: 50%;
  vertical-align: -.1em;
  background: var(--ink);
  color: var(--brand);
}
.intro__badge svg { width: .5em; height: .5em; stroke-width: 2.4; }
.intro__badge--brand { background: var(--brand); color: var(--ink); }

.bento {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 16px;
}
.bento__stack { display: grid; gap: 16px; grid-template-rows: 1fr auto; }

.bento__card {
  position: relative;
  display: flex;
  flex-direction: column;
  min-height: 210px;
  padding: 22px 24px;
  overflow: hidden;
  border-radius: var(--r-xl);
  text-align: left;
}
.bento__label {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 14px;
  font-size: 14px;
  font-weight: var(--w-title);
  letter-spacing: -0.01em;
  color: var(--text-2);
}
.bento__label svg { width: 18px; height: 18px; color: var(--brand); }
.bento__num {
  display: block;
  font-size: clamp(2.5rem, 4.2vw, 3.3rem);
  font-weight: var(--w-title);
  line-height: 1;
  letter-spacing: -0.05em;
  font-variant-numeric: tabular-nums;
}
.bento__card p { margin: 0; font-size: 14.5px; line-height: 1.5; }

.bento__card--photo {
  min-height: 400px;
  padding: 14px;
  justify-content: flex-end;
  background: var(--surface-muted);
}
.bento__photo {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: 50% 26%;
}
.bento__chip {
  position: absolute;
  top: 14px; right: 14px;
  display: grid;
  place-items: center;
  width: 40px; height: 40px;
  border-radius: 12px;
  background: #fff;
  color: var(--ink);
  box-shadow: var(--shadow-sm);
}
.bento__chip svg { width: 20px; height: 20px; }
.bento__inset {
  position: relative;
  padding: 18px 20px 20px;
  border-radius: 18px;
  background: #fff;
  box-shadow: var(--shadow-md);
}
.bento__inset p { margin-top: 8px; color: var(--text-2); }

.bento__card--grey { background: var(--surface-muted); }
.bento__foot { margin-top: auto; padding-top: 30px; }
.bento__acts { display: flex; margin-bottom: 12px; }
.bento__acts span {
  display: grid;
  place-items: center;
  width: 40px; height: 40px;
  border-radius: 50%;
  border: 2px solid var(--surface-muted);
  background: #fff;
}
.bento__acts span + span { margin-left: -9px; }
.bento__acts svg { width: 18px; height: 18px; }
.bento__acts .is-go { background: var(--brand); }
.bento__card--grey p { color: var(--text-2); }

.bento__card--brand {
  background: linear-gradient(150deg, var(--brand-hi), var(--brand) 60%, #f7d000);
  color: var(--brand-ink);
}
.bento__card--brand .bento__label { color: rgba(10, 10, 11, .66); }
.bento__card--brand p { margin-top: auto; padding-top: 18px; color: rgba(10, 10, 11, .74); }

.bento__card--dark {
  min-height: 0;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  background: var(--ink);
  color: #fff;
}
.bento__card--dark .bento__label { margin: 0; color: rgba(255, 255, 255, .72); }
.bento__card--dark .bento__num { font-size: clamp(2rem, 3vw, 2.6rem); }

@media (min-width: 720px) {
  .bento { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .bento__stack { grid-column: 1 / -1; grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-rows: none; }
}
@media (min-width: 1000px) {
  .bento { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .bento__stack { grid-column: auto; grid-template-columns: minmax(0, 1fr); grid-template-rows: 1fr auto; }
}

/* ── Motion & print ──────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  .orbit__core,
  .orbit__dash,
  .orbit__sweep,
  .orbit__pip,
  .orbit__node::after,
  .spin__ring,
  .console__pulse,
  .console__seg.is-live { animation: none; }
  .orbit__node::after { opacity: 0; }
  .reveal { opacity: 1; transform: none; }
  /* The panel's contents start hidden and are transitioned in, so with every
     duration flattened they need their end state stated outright. */
  .nav-flyout.is-open .nav-panel { opacity: 1; transform: none; }
}

@media print {
  .topbar, .site-footer, .back-to, .site-drawer { display: none !important; }
  .spin { display: none !important; }
  .nav-flyout, .nav-scrim { display: none !important; }
  body.site::before, body.site::after { display: none !important; }
  .legal-doc p, .legal-doc li { color: #000; }
  .idcard, .callout, .summary-box { box-shadow: none; border-color: #ccc; }
}

/* ── Feature splits (Home, Product) ──────────────────────────
   One feature per section: the claim and its points on one side,
   an example of what it looks like on the other. Stacked on a
   phone with the copy first; side by side from 960px, where
   --flip puts the example on the left so a run of these zigzags.
   The example figures are .shot mock-ups marked "Example" — swap
   their contents for real product screenshots when they exist.
   ────────────────────────────────────────────────────────── */

.split {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(30px, 4vw, 60px);
  align-items: center;
}
.split__copy { min-width: 0; }
/* "you" in the Learns-you heading: one soft gold-to-yellow gradient,
   clipped to the letters, that flows steadily left to right. Nothing
   else on top: no lines, hatching or glints. The gradient repeats
   seamlessly (same gold at both ends) and each loop moves exactly one
   tile, so it never jumps. Still under reduced motion.
   initial-value must be font-independent (px, not em) or the browser
   drops the registration and the position jumps instead of gliding. */
@property --tg-base { syntax: '<length>'; inherits: false; initial-value: 0px; }
.text-grad-yellow {
  --tg-base: 0em;
  background-image: linear-gradient(100deg,
    #b09400 0%, var(--brand-deep) 25%, var(--brand) 50%,
    var(--brand-deep) 75%, #b09400 100%);
  background-size: 2.4em 100%;
  background-repeat: repeat-x;
  background-position: var(--tg-base) 50%;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: var(--brand-deep);
  padding-bottom: .08em;
}
@media (prefers-reduced-motion: no-preference) {
  .text-grad-yellow { animation: text-grad-drift 8s linear infinite; }
}
@keyframes text-grad-drift {
  from { --tg-base: 0em; }
  to   { --tg-base: 2.4em; }
}
/* A real screenshot of the app. On a phone it keeps a readable width
   and scrolls sideways inside its rounded frame. */
.app-shot {
  margin: 0;
  min-width: 0;
  border-radius: 20px;
  overflow: hidden;
  overflow-x: auto;
  scrollbar-width: thin;
  background: #fff;
  box-shadow: var(--ring), var(--shadow-md), var(--edge);
}
.app-shot img { display: block; width: 100%; min-width: 760px; height: auto; }

/* Reliability card (Product #analytics): a run-outcome donut beside
   its counts. Arcs are circles of circumference 100, so each
   dasharray is the share in percent. */
.rely { --rely-fail: #dc2f2f; --rely-stop: #8a8a91; }
.rely__body {
  display: grid;
  grid-template-columns: 132px minmax(0, 1fr);
  align-items: center;
  gap: 24px;
  padding: 18px 20px 16px;
}
.rely__donut { position: relative; width: 132px; aspect-ratio: 1; }
.rely__donut svg { display: block; width: 100%; height: 100%; transform: scaleY(-1); }
.rely__arc { fill: none; stroke-width: 5.4; }
.rely__arc--done { stroke: var(--shot-done); }
.rely__arc--part { stroke: var(--shot-active); }
.rely__arc--fail { stroke: var(--rely-fail); }
.rely__arc--stop { stroke: var(--rely-stop); }
.rely__rate {
  position: absolute; inset: 0;
  display: grid; place-content: center; justify-items: center;
  font-size: 12px;
  color: var(--shot-ink-3);
}
.rely__rate b {
  font-size: 22px; font-weight: 600;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
  color: var(--shot-active-ink);
}
.rely__rows { margin: 0; display: grid; font-size: 14px; }
.rely__rows > div {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 3ch 4.5ch;
  gap: 14px;
  align-items: center;
  padding: 8px 0;
}
.rely__rows > div + div { border-top: 1px solid var(--shot-line); }
.rely__rows dt { display: flex; align-items: center; gap: 9px; min-width: 0; color: var(--shot-ink-2); }
.rely__rows dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; }
.rely__rows dd:last-child { font-size: 12.5px; color: var(--shot-ink-3); }
.rely__dot { flex: none; width: 8px; height: 8px; border-radius: 50%; }
.rely__dot--done { background: var(--shot-done); }
.rely__dot--part { background: var(--shot-active); }
.rely__dot--fail { background: var(--rely-fail); }
.rely__dot--stop { background: var(--rely-stop); }
.rely__rows > .rely__total { border-top-color: var(--shot-edge); }
.rely__total dt { padding-left: 17px; color: var(--shot-ink); font-weight: 500; }
.rely__total dd:nth-of-type(1) { font-weight: 500; }

@media (max-width: 440px) {
  .rely__body { grid-template-columns: minmax(0, 1fr); justify-items: center; gap: 16px; }
  .rely__rows { width: 100%; }
}

/* Wide screens: screenshot left, copy right, in a wider band than the
   usual container so the screenshot keeps most of its size. */
@media (min-width: 1100px) {
  .container.split--wide {
    width: min(1440px, calc(100% - 64px));
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
  }
  .container.split--wide > .split__copy { order: 2; }
}
.split .cap-list { max-width: 34em; }
.split__foot {
  margin: 26px 0 0;
  color: var(--muted);
  font-size: .97rem;
  line-height: 1.6;
}
.split__foot a { color: var(--text); font-weight: 500; }

@media (min-width: 960px) {
  .split { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .split--flip > .split__copy { order: 2; }
  /* A wide app screenshot stacks under the copy until there is room to sit
     beside it at a legible size. */
  .split--wide { grid-template-columns: minmax(0, 1fr); }
  .split--wide > .split__copy { order: 0; }
  /* Copy starts level with the top of the visual instead of centring on it. */
  .split--top { align-items: start; }
}

.mt-xl { margin-top: clamp(40px, 5vw, 64px); }

/* Four across on a wide screen, two on a tablet — so four use cases
   never leave one card stranded on a row of its own. */
@media (min-width: 720px) {
  .feature-grid--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1040px) {
  .feature-grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* The logo glyph standing in for the "o", in ink on the light hero. */
.glyph-o--ink::before { filter: brightness(0); }

/* Platform marks under a feature-grid entry. */
.mini-logos {
  list-style: none;
  margin: 14px 0 0;
  padding: 0;
  display: flex;
  gap: 12px;
  color: var(--text);
}
.mini-logos svg { width: 20px; height: 20px; display: block; }

/* Status text on a dark panel: dark text would vanish. */
.band-dark .tag--live { color: #fafafa; }
.band-dark .tag--soon { color: rgba(250, 250, 250, .66); }

/* What's next cards: the status sits in a small grey pill, lifted a
   little clear of the heading under it. */
#next .info-card .tag {
  padding: 4px 12px;
  border-radius: 999px;
  margin-bottom: 8px;
  /* Pull back by the padding so the words line up with the heading. */
  margin-left: -12px;
  background: rgba(0, 0, 0, .06);
  line-height: 1.4;
}
.band-dark#next .info-card .tag { background: rgba(255, 255, 255, .1); }

/* ── Cloner (Product) ────────────────────────────────────────
   Beside the copy, "Cloner" set straight on the section's measuring grid
   in solid ink, with a mirrored copy stacked exactly on top. On a slow
   loop the two crossfade through a light blur: as one softens out the
   other sharpens in, so the word is always on screen and never moves.
   ────────────────────────────────────────────────────────── */

/* The Cloner section runs edge to edge, with the measuring grid showing
   through in scattered patches rather than as an even sheet. */
#you:has(.cloner) {
  padding-block: clamp(36px, 4.4vw, 60px);
  /* A breath of blank space between the panels above and below. */
  margin-block: clamp(26px, 3vw, 44px);
  isolation: isolate;
  overflow: hidden;
  /* No edge lines: the wash and the grid both fade in from the section
     above and back out into the one below. */
  background: linear-gradient(180deg, transparent, rgba(255, 255, 255, .5) 30%, rgba(255, 255, 255, .22) 70%, transparent);
}
/* The band's own padding, margin and fading wash already separate it from
   what follows, so the next section starts closer than a full section top. */
#you:has(.cloner) + .section { padding-top: clamp(30px, 3.4vw, 48px); }
#you:has(.cloner)::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-image:
    linear-gradient(rgba(10, 10, 11, .06) 1px, transparent 1px),
    linear-gradient(90deg, rgba(10, 10, 11, .06) 1px, transparent 1px);
  background-size: 22px 22px;
  background-position: center top;
  -webkit-mask-image:
    linear-gradient(180deg, transparent, #000 32%, #000 68%, transparent),
    radial-gradient(22% 38% at 6% 18%, #000, transparent),
    radial-gradient(18% 30% at 38% 92%, #000, transparent),
    radial-gradient(16% 34% at 57% 8%, #000, transparent),
    radial-gradient(24% 40% at 94% 72%, #000, transparent),
    radial-gradient(12% 22% at 78% 22%, #000, transparent),
    radial-gradient(26% 46% at 27% 50%, #000 20%, transparent);
  mask-image:
    linear-gradient(180deg, transparent, #000 32%, #000 68%, transparent),
    radial-gradient(22% 38% at 6% 18%, #000, transparent),
    radial-gradient(18% 30% at 38% 92%, #000, transparent),
    radial-gradient(16% 34% at 57% 8%, #000, transparent),
    radial-gradient(24% 40% at 94% 72%, #000, transparent),
    radial-gradient(12% 22% at 78% 22%, #000, transparent),
    radial-gradient(26% 46% at 27% 50%, #000 20%, transparent);
  /* The top layer fades the patches out towards the top and bottom edges. */
  -webkit-mask-composite: source-in, source-over, source-over, source-over, source-over, source-over, source-over;
  mask-composite: intersect, add, add, add, add, add, add;
}

.cloner {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: .1em;
  margin: 0;
  padding: clamp(22px, 3.4vw, 40px);
  font-family: var(--font-head);
  font-weight: 900;
  font-size: clamp(46px, 6.2vw, 84px);
  line-height: 1;
  letter-spacing: -0.035em;
}

/* Stacked over the copy, the word lines up with the heading under it:
   the padding only earns its keep beside the copy. */
@media (max-width: 959px) {
  .cloner { padding: 0; }
}

.cloner__pair { display: block; position: relative; }

.cloner__word {
  display: block;
  position: relative;
  padding-bottom: .04em;
  color: var(--ink);
}

/* The mirror sits exactly over the original, hidden at rest. */
.cloner__word--mirror {
  position: absolute;
  inset: 0;
  transform: scaleX(-1);
  opacity: 0;
}

@media (prefers-reduced-motion: no-preference) {
  .cloner__word {
    animation: cloner-swap 8s cubic-bezier(.45, 0, .55, 1) infinite;
    will-change: filter, opacity;
  }
  /* Half a loop behind, so it sharpens exactly while the original softens. */
  .cloner__word--mirror { animation-delay: -4s; }
}

/* Sharp · soften out · hidden while the other rests · sharpen back in. */
@keyframes cloner-swap {
  0%, 27.5% { filter: blur(0); opacity: 1; }
  50%, 77.5% { filter: blur(5px); opacity: 0; }
  100% { filter: blur(0); opacity: 1; }
}


/* ── Studio (Product, #studio) ───────────────────────────────
   What it makes, one type at a time: the six types listed on the
   left, an example of the open one on the right. On a wide, tall
   window the pair pins under the ribbon while the page scrolls
   through a track the script sizes, and each stretch of that
   scroll opens the next type; the hairline over the open row
   fills as you go. Clicking a type scrolls to its stretch. On a
   phone nothing pins and a tap switches. Without the script
   every note and every example is simply on the page, in order.
   ────────────────────────────────────────────────────────── */

.studio { --studio-h: clamp(420px, calc(100svh - var(--topbar-h) - 240px), 580px); }

.studio__pin {
  display: grid;
  gap: clamp(26px, 4vw, 40px);
}

/* The heading rides inside the pin, so it stays in view the whole
   time the types scroll through. */
.section .studio__title { grid-column: 1 / -1; margin: 0; }

.studio__rail { list-style: none; display: grid; align-content: center; }

.studio__row {
  position: relative;
  display: grid;
  grid-template-rows: auto auto;
  padding: clamp(15px, 1.8vw, 20px) 0;
  border-top: 1px solid var(--hairline-mid);
}

.studio__head { margin: 0; font-size: inherit; }

.studio__trigger {
  display: block;
  width: 100%;
  margin: 0; padding: 0;
  border: 0; background: none;
  text-align: left;
  font: inherit;
  font-family: var(--font-head);
  font-size: clamp(1.1rem, 1.6vw, 1.3rem);
  font-weight: var(--w-title);
  letter-spacing: -0.03em;
  line-height: 1.2;
  color: var(--text);
  cursor: default;
}
.studio__trigger:focus-visible {
  outline: 2px solid var(--brand-deep);
  outline-offset: 4px;
  border-radius: 6px;
}

.studio__note {
  margin: 0;
  padding-top: 8px;
  color: var(--muted);
  font-size: .97rem;
  line-height: 1.6;
  max-width: 34em;
}

/* Live: shut rows are their heading alone, in grey. */
.studio.is-live .studio__trigger {
  cursor: pointer;
  color: var(--faint);
  transition: color var(--t-2) var(--ease);
}
.studio.is-live .studio__trigger:hover { color: var(--text-2); }
.studio.is-live .studio__row.is-open .studio__trigger { color: var(--text); }

.studio.is-live .studio__row {
  grid-template-rows: auto 0fr;
  transition: grid-template-rows var(--t-3) var(--ease-smooth);
}
.studio.is-live .studio__row.is-open { grid-template-rows: auto 1fr; }
.studio.is-live .studio__note {
  min-height: 0;
  overflow: hidden;
  opacity: 0;
  transition: opacity var(--t-2) var(--ease);
}
.studio.is-live .studio__row.is-open .studio__note { opacity: 1; }

/* The open row's hairline: an ink segment that fills with --p. */
.studio.is-live .studio__row::before {
  content: "";
  position: absolute;
  left: 0; right: 0; top: -1px;
  height: 2px;
  background: var(--ink);
  transform-origin: left center;
  transform: scaleX(0);
  opacity: 0;
  transition: opacity var(--t-2) var(--ease);
}
.studio.is-live .studio__row.is-open::before {
  opacity: 1;
  transform: scaleX(calc(.1 + var(--p, 0) * .9));
}

/* Stacked (a phone): the script wraps each row's note and its example in
   one .studio__drop, and the row opens and shuts that like it did the note.
   The stage below the list is left empty, so it goes. The side padding
   gives the card's shadow room inside the clip. */
.studio.is-inline .studio__stage { display: none; }
/* No scroll to fill against here, so the open row's hairline runs the
   full width. */
.studio.is-inline .studio__row::before {
  transition: opacity var(--t-2) var(--ease), transform var(--t-3) var(--ease-smooth);
}
.studio.is-inline .studio__row.is-open::before { transform: scaleX(1); }
.studio__drop {
  display: grid;
  min-height: 0;
  overflow: hidden;
  margin-inline: -16px;
  padding-inline: 16px;
}
.studio.is-inline .studio__note { overflow: visible; }
.studio.is-inline .studio__drop > .studio-shot { grid-area: auto; margin: 16px 0 14px; }
/* On a phone each picture is a little shorter, so an open example stays
   close to the size of the screen. */
@media (max-width: 599px) {
  .studio.is-inline .studio-frame--tall { aspect-ratio: 1 / 1; }
  .studio.is-inline .studio-frame--wide { aspect-ratio: 2 / 1; }
  .studio.is-inline .studio-ad__img { aspect-ratio: 1 / 1; }
  .studio.is-inline .studio-images { aspect-ratio: 16 / 10; }
  .studio.is-inline .studio-design__post { min-height: 0; aspect-ratio: 16 / 9; }
}

/* The examples: stacked in one cell, crossfading. */
.studio__stage { display: grid; gap: 16px; min-width: 0; }
.studio.is-live .studio__stage { gap: 0; }
.studio.is-live .studio-shot {
  grid-area: 1 / 1;
  opacity: 0;
  visibility: hidden;
  transform: translateY(10px) scale(.985);
  transition:
    opacity var(--t-3) var(--ease),
    transform 420ms var(--ease-smooth),
    visibility 0s linear var(--t-3);
}
.studio.is-live .studio-shot.is-current {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition:
    opacity var(--t-3) var(--ease),
    transform 420ms var(--ease-smooth),
    visibility 0s;
}

.studio-shot { display: flex; flex-direction: column; min-width: 0; }
.studio-shot__body {
  flex: 1;
  min-height: 0;
  padding: 16px;
}

/* A picture in a rounded frame, with small labels laid over it. */
.studio-frame {
  position: relative;
  overflow: hidden;
  min-height: 0;
  border-radius: 14px;
  background: var(--shot-fill-2);
  box-shadow: inset 0 0 0 1px var(--shot-edge);
}
.studio-frame > img {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}
/* Videos get a dark fade at the foot, so the white caption reads on a light shot. */
.studio-frame--tall::after,
.studio-frame--wide::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 45%;
  background: linear-gradient(180deg, transparent, rgba(10, 10, 11, .55));
  pointer-events: none;
}
.studio-frame > span { z-index: 1; }
.studio-frame__chip {
  position: absolute;
  left: 10px; top: 10px;
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 9px;
  border-radius: var(--r-pill);
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: #fff;
  background: rgba(10, 10, 11, .55);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
}
.studio-frame__chip svg { width: 13px; height: 13px; }
.studio-frame__sub {
  position: absolute;
  left: 12px; right: 12px; bottom: 44px;
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: -0.015em;
  text-align: center;
  color: #fff;
  text-shadow: 0 1px 10px rgba(0, 0, 0, .55);
  text-wrap: balance;
}
.studio-frame__scrub {
  position: absolute;
  left: 12px; right: 12px; bottom: 14px;
  display: flex; align-items: center; gap: 9px;
  color: #fff;
}
.studio-frame__scrub svg { width: 14px; height: 14px; fill: currentColor; flex: none; }
.studio-frame__bar {
  flex: 1;
  height: 3px;
  border-radius: 3px;
  background: rgba(255, 255, 255, .35);
  overflow: hidden;
}
.studio-frame__bar > span { display: block; width: 38%; height: 100%; background: var(--brand); }

/* 1 · UGC: a small vertical clip on the left, what went into it on the right. */
.studio-ugc {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
  gap: 16px;
  align-items: center;
}
.studio-frame--tall { aspect-ratio: 4 / 5; }
.studio-frame--tall > img { object-position: 60% 30%; }
.studio-ugc__rows .shot-row { min-height: 44px; padding: 8px 4px; font-size: 14px; }
.studio-ugc__rows .shot-ico { width: 22px; height: 22px; }
.studio-ugc__rows .shot-ico svg { width: 12px; height: 12px; }

/* 2 · Product: the open scene over the cut. */
.studio-product { display: grid; grid-template-rows: minmax(0, 1fr) auto; gap: 12px; }
.studio-frame--wide { aspect-ratio: 16 / 9; background: #fff3a8; }
.studio-frame--wide > img { object-position: 50% 45%; }
.studio-frame--wide .studio-frame__sub { bottom: 16px; }
.studio-scenes {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 8px;
}
.studio-scenes li {
  display: grid;
  gap: 6px;
  min-width: 0;
  font-size: 12px;
  color: var(--shot-ink-3);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.studio-scenes li.is-on { color: var(--shot-ink); font-weight: 500; }
.studio-scenes__img {
  position: relative;
  display: block;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border-radius: 9px;
  background: #fff3a8;
  box-shadow: inset 0 0 0 1px var(--shot-edge);
}
.studio-scenes li.is-on .studio-scenes__img { outline: 2px solid var(--ink); outline-offset: -2px; }
.studio-scenes__img img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.studio-scenes__img--b img { transform: scale(1.9); object-position: 30% 60%; }
.studio-scenes__img--c img { transform: scale(1.35) rotate(-6deg); }
.studio-scenes__img--d img { transform: scale(.8); }

/* 3 · Ads: three angles side by side, the strongest marked. */
.studio-ads {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
  align-content: start;
}
.studio-ad {
  display: grid;
  gap: 4px;
  align-content: start;
  min-width: 0;
  padding: 6px 6px 12px;
  border-radius: 14px;
  background: rgba(255, 255, 255, .6);
  box-shadow: inset 0 0 0 1px var(--shot-edge);
}
.studio-ad.is-pick { box-shadow: inset 0 0 0 2px var(--ink); }
.studio-ad__img {
  position: relative;
  display: block;
  aspect-ratio: 4 / 5;
  overflow: hidden;
  border-radius: 10px;
  margin-bottom: 6px;
  background: var(--shot-fill-2);
}
.studio-ad__img img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.studio-ad__angle {
  padding: 0 4px;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--shot-ink-3);
}
.studio-ad.is-pick .studio-ad__angle { color: var(--shot-ink); }
.studio-ad__hook {
  padding: 0 4px;
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: -0.015em;
  color: var(--shot-ink);
  text-wrap: balance;
}

/* 4 · Images: a carousel, two posts and a thumbnail. */
.studio-images {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr) minmax(0, 1fr);
  grid-template-rows: minmax(0, 1fr) minmax(0, 1fr);
  gap: 10px;
  aspect-ratio: 16 / 11;
}
.studio-images__main { grid-row: 1 / 3; }
.studio-images__thumb { grid-column: 2 / 4; }
.studio-images__thumb > img { object-position: 50% 30%; }
.studio-images__title {
  position: absolute;
  left: 14px; bottom: 12px;
  font-size: clamp(15px, 1.8vw, 20px);
  font-weight: 800;
  letter-spacing: -0.04em;
  color: #fff;
  text-shadow: 0 1px 12px rgba(0, 0, 0, .6);
}
.studio-dots {
  position: absolute;
  left: 0; right: 0; bottom: 12px;
  display: flex; justify-content: center; gap: 5px;
}
.studio-dots i {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: rgba(255, 255, 255, .5);
}
.studio-dots i.is-on { background: #fff; }

/* 5 · Copy: the script as labelled lines, then the caption. */
.studio-copy { display: grid; gap: 16px; align-content: start; }
.studio-script { margin: 0; display: grid; }
.studio-script > div {
  display: grid;
  grid-template-columns: 64px minmax(0, 1fr);
  gap: 12px;
  align-items: baseline;
  padding: 10px 4px;
}
.studio-script > div + div { border-top: 1px solid var(--shot-line); }
.studio-script dt {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--shot-ink-3);
}
.studio-script dd {
  margin: 0;
  font-size: 14.5px;
  line-height: 1.45;
  letter-spacing: -0.01em;
  color: var(--shot-ink);
}
.studio-caption {
  display: grid;
  gap: 10px;
  padding: 14px;
  border-radius: 14px;
  background: var(--shot-foot);
  box-shadow: inset 0 0 0 1px var(--shot-line);
}
.studio-caption__label {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--shot-ink-3);
}
.studio-caption p { margin: 0; font-size: 14.5px; line-height: 1.5; color: var(--shot-ink); }
.studio-caret {
  display: inline-block;
  width: 2px; height: 1.05em;
  margin-left: 2px;
  vertical-align: -0.15em;
  background: var(--brand-deep);
}

/* 6 · Design: the kit on one side, a post wearing it on the other. */
.studio-design {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 16px;
}
.studio-kit { display: grid; gap: 10px; align-content: start; }
.studio-kit__group {
  display: grid;
  gap: 8px;
  justify-items: start;
  padding: 12px;
  border-radius: 14px;
  background: rgba(255, 255, 255, .6);
  box-shadow: inset 0 0 0 1px var(--shot-edge);
}
.studio-kit__label {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--shot-ink-3);
}
.studio-kit__logo {
  display: grid;
  place-items: center;
  flex: none;
  width: 40px; height: 40px;
  border-radius: 11px;
  color: var(--brand);
  background: var(--ink);
}
.studio-kit__logo svg { width: 22px; height: 22px; }
.studio-kit__logo--sm { width: 26px; height: 26px; border-radius: 8px; }
.studio-kit__logo--sm svg { width: 15px; height: 15px; }
.studio-swatches { display: flex; gap: 6px; }
.studio-swatches i {
  width: 30px; height: 30px;
  border-radius: 9px;
  box-shadow: inset 0 0 0 1px var(--shot-edge);
}
.studio-swatch--brand { background: var(--brand); }
.studio-swatch--ink { background: var(--ink); }
.studio-swatch--paper { background: #fff; }
.studio-swatch--grey { background: var(--muted); }
.studio-cast { display: flex; flex-wrap: wrap; gap: 12px; }
.studio-cast__one {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 13px;
  color: var(--shot-ink-2);
}
.studio-cast__one img {
  width: 30px; height: 30px;
  border-radius: 50%;
  object-fit: cover;
  box-shadow: 0 0 0 2px #fff, 0 0 0 3px var(--shot-edge);
}
.studio-design__post { min-height: 220px; }
.studio-design__post > img { object-position: 50% 35%; }
.studio-design__band {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  display: flex; align-items: center; gap: 9px;
  padding: 10px 12px;
  font-size: 13.5px;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--brand-ink);
  background: var(--brand);
}

@media (max-width: 520px) {
  .studio-ads { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .studio-ads .studio-ad:last-child { display: none; }
  .studio-design { grid-template-columns: minmax(0, 1fr); }
  .studio-design__post { min-height: 0; aspect-ratio: 4 / 3; }
  .studio-scenes li { font-size: 11px; }
}

/* Narrow: the clip is small, so its labels shrink, and each row puts its
   value under its label so the text column still fits. */
@media (max-width: 599px) {
  .studio.is-inline .studio-ugc .studio-frame--tall { aspect-ratio: 3 / 4; }
  .studio-ugc { gap: 12px; }
  .studio-ugc .studio-frame__chip { left: 6px; top: 6px; padding: 3px 7px; font-size: 10.5px; }
  .studio-ugc .studio-frame__sub { left: 8px; right: 8px; bottom: 30px; font-size: 11px; }
  .studio-ugc .studio-frame__scrub { left: 8px; right: 8px; bottom: 10px; gap: 6px; }
  .studio-ugc__rows .shot-row {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    column-gap: 10px;
    min-height: 0;
    padding: 7px 2px;
  }
  .studio-ugc__rows .shot-ico { grid-row: 1 / 3; }
  .studio-ugc__rows .shot-row__k { max-width: none; font-size: 13.5px; }
  .studio-ugc__rows .shot-row__v { text-align: left; font-size: 12.5px; }
}

/* Side by side. */
@media (min-width: 960px) {
  .studio__pin {
    grid-template-columns: minmax(0, .82fr) minmax(0, 1.18fr);
    gap: clamp(26px, 3.4vw, 42px) clamp(40px, 5vw, 72px);
    align-items: center;
  }
  .studio.is-live .studio__stage { height: var(--studio-h); }
  .studio.is-live .studio-shot { height: 100%; }

  /* Every example fills the stage, its picture taking the slack. */
  .studio.is-live .studio-ugc { align-items: center; align-content: center; height: 100%; }
  .studio.is-live .studio-ugc__rows { align-content: center; }
  .studio.is-live .studio-frame--wide { aspect-ratio: auto; }
  .studio.is-live .studio-images { aspect-ratio: auto; }
  .studio.is-live .studio-design__post { min-height: 0; }
  .studio.is-live :is(.studio-ads, .studio-copy, .studio-kit) { align-content: center; }
}

/* Pinned: the script gives the track its height and measures the pin
   (heading included, --studio-pin-h); the whole block holds still in
   the middle of the window below the ribbon. */
.studio.is-pinned .studio__pin {
  position: sticky;
  top: max(calc(var(--topbar-h) + 56px), calc((100svh - var(--studio-pin-h, var(--studio-h))) / 2 + var(--topbar-h) / 2));
}

@media (prefers-reduced-motion: reduce) {
  .studio.is-live .studio__row,
  .studio.is-live .studio__note,
  .studio.is-live .studio-shot,
  .studio.is-live .studio-shot.is-current { transition: none; }
  .studio.is-live .studio-shot { transform: none; }
}

/* Insight cards with a small video still above the copy (product #insights). */
.info-grid--shots { gap: 28px 18px !important; }
.info-grid--shots .info-card p { font-size: .84rem; line-height: 1.55; }
.info-shot {
  position: relative;
  /* The stills are 4:5 portrait, so the frame is too - a landscape crop cut
     the subject down to a head and shoulders. Matching the source means
     nothing is cropped at any width. */
  aspect-ratio: 4 / 5;
  margin: 0 0 14px;
  overflow: hidden;
  border-radius: var(--r-md);
  background: #111;
  box-shadow: var(--ring);
}
.info-shot img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: 50% 50%; }
.info-shot__play {
  position: absolute; left: 10px; top: 10px;
  display: grid; place-items: center;
  width: 30px; height: 30px; border-radius: 50%;
  background: rgba(10, 10, 10, .55); color: #fff;
  backdrop-filter: blur(6px);
}
.info-shot__play svg { width: 14px; height: 14px; }
.info-shot__bar {
  position: absolute; left: 10px; right: 10px; bottom: 9px;
  height: 3px; border-radius: 3px; background: rgba(255, 255, 255, .35); overflow: hidden;
}
.info-shot__bar i { display: block; height: 100%; width: 40%; background: var(--brand); }
.info-card:nth-child(1) .info-shot__bar i { width: 62%; }
.info-card:nth-child(2) .info-shot__bar i { width: 38%; }
.info-card:nth-child(3) .info-shot__bar i { width: 81%; }
.info-card:nth-child(4) .info-shot__bar i { width: 24%; }
@media (min-width: 1100px) {
  /* The row runs a little past the text column so the four stills sit on one
     line, but not so far that each frame turns into a slab. */
  .info-grid--shots {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    margin-inline: calc((100% - min(1160px, 100vw - 60px)) / 2);
  }
  /* Four across, each caption sits on one line. */
  .info-grid--shots .info-card p { font-size: .76rem; }
}
/* Hover reads as "play": the still lifts and zooms and the button turns
   brand yellow. The progress bar holds still - it never moves on hover. */
.info-shot { transition: translate .4s var(--ease), box-shadow .4s var(--ease); }
.info-shot img { transition: scale .9s var(--ease-smooth), filter .4s var(--ease); }
.info-shot__play { transition: background .25s var(--ease), color .25s var(--ease), scale .3s var(--ease); }
@media (hover: hover) {
  .info-card:hover .info-shot { translate: 0 -4px; box-shadow: var(--ring), var(--shadow-md); }
  .info-card:hover .info-shot img { scale: 1.06; filter: saturate(1.08) contrast(1.04); }
  .info-card:hover .info-shot__play { background: var(--brand); color: #0a0a0a; scale: 1.12; }
}
@media (prefers-reduced-motion: reduce) {
  .info-shot, .info-shot img, .info-shot__play { transition: none; }
  .info-card:hover .info-shot { translate: none; }
  .info-card:hover .info-shot img { scale: none; }
}
@media (max-width: 719px) {
  .info-grid--shots { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 22px 14px !important; }
  .info-grid--shots .info-shot { margin-bottom: 10px; border-radius: var(--r-sm); }
  .info-grid--shots .info-shot__play { width: 24px; height: 24px; left: 7px; top: 7px; }
  .info-grid--shots .info-shot__play svg { width: 11px; height: 11px; }
  .info-grid--shots .info-card__kicker { margin-bottom: 6px; }
  .info-grid--shots h3 { font-size: .9rem; margin-bottom: 5px; }
  .info-grid--shots .info-card p { font-size: .8rem; line-height: 1.5; }
}

/* ── About ───────────────────────────────────────────────────
   A heading on the left and its body on the right from 900px,
   stacked below that. Numbered rows are ranged left with a small
   ink label; no icons, no photos, no cards inside the panels.
   ────────────────────────────────────────────────────────── */

/* Hero: a full-width cream sky that runs up behind the floating
   top bar (its 70px is pulled back with a negative margin). Built in CSS, no
   photo: a warm gradient that lightens through the middle and comes back to
   cream along the bottom before it fades into the page. The yellow is there at
   rest — the hero reads warm with the pointer nowhere near it — but it stays a
   tint the ink sits comfortably on, not a wash; the cursor pool is what makes
   it properly yellow. A soft sun glow; faint white cloud wisps from an SVG
   noise filter. The headline sits in ink, centred. */
.about-hero {
  position: relative;
  margin-top: -70px;
  padding-top: 70px;
  overflow: hidden;
  isolation: isolate;
}
/* The sky drifts on its own, slowly but visibly: the glows wander across a
   good part of the hero and brighten and fade, the cloud layers slide and
   swell. Mismatched periods so the loop never visibly repeats. Registered
   properties let the gradient centres animate smoothly; without @property
   support the sky simply rests at these values. */
@property --sky-sun-x  { syntax: "<percentage>"; inherits: false; initial-value: 78%; }
@property --sky-sun-y  { syntax: "<percentage>"; inherits: false; initial-value: 18%; }
@property --sky-sun-a  { syntax: "<number>";     inherits: false; initial-value: .9; }
@property --sky-warm-x { syntax: "<percentage>"; inherits: false; initial-value: 20%; }
@property --sky-warm-y { syntax: "<percentage>"; inherits: false; initial-value: 8%; }
@property --sky-warm-a { syntax: "<number>";     inherits: false; initial-value: .38; }
@property --sky-low-x  { syntax: "<percentage>"; inherits: false; initial-value: 72%; }
@property --sky-low2-x { syntax: "<percentage>"; inherits: false; initial-value: 18%; }
@keyframes about-sky-sun {
  0%   { --sky-sun-x: 82%; --sky-sun-y: 14%; --sky-sun-a: 1; }
  50%  { --sky-sun-x: 58%; --sky-sun-y: 32%; --sky-sun-a: .6; }
  100% { --sky-sun-x: 72%; --sky-sun-y: 6%;  --sky-sun-a: .95; }
}
@keyframes about-sky-warm {
  0%   { --sky-warm-x: 12%; --sky-warm-y: 4%;  --sky-warm-a: .3; }
  50%  { --sky-warm-x: 38%; --sky-warm-y: 20%; --sky-warm-a: .6; }
  100% { --sky-warm-x: 22%; --sky-warm-y: 10%; --sky-warm-a: .42; }
}
@keyframes about-sky-low {
  0%   { --sky-low-x: 80%; --sky-low2-x: 10%; }
  100% { --sky-low-x: 50%; --sky-low2-x: 38%; }
}
@keyframes about-sky-wisps {
  0%   { transform: translate3d(-5%, 1.5%, 0) scale(1.14); }
  100% { transform: translate3d(5%, -2%, 0) scale(1.22); }
}
@keyframes about-sky-banks {
  0%   { transform: translate3d(4.5%, 2%, 0) scale(1.2); }
  100% { transform: translate3d(-4.5%, -2%, 0) scale(1.13); }
}
.about-hero__sky {
  --sky-sun-x: 78%; --sky-sun-y: 18%; --sky-sun-a: .9;
  --sky-warm-x: 20%; --sky-warm-y: 8%; --sky-warm-a: .38;
  --sky-low-x: 72%; --sky-low2-x: 18%;
  /* Cursor glow (site.js, initAboutWind): a pool of yellow that follows the
     pointer across the hero and fades out when it leaves. It sits on top of
     the sky's own layers, so the sky keeps its shape and only warms. */
  --glow-x: 50%; --glow-y: 50%; --glow-a: 0;
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(720px 600px at var(--glow-x) var(--glow-y), rgba(255, 214, 0, calc(var(--glow-a) * .5)), rgba(255, 219, 0, calc(var(--glow-a) * .24)) 45%, rgba(255, 219, 0, 0) 72%),
    radial-gradient(60% 55% at var(--sky-sun-x) var(--sky-sun-y), rgba(255, 255, 255, calc(var(--sky-sun-a) * .72)), transparent 70%),
    radial-gradient(70% 40% at var(--sky-warm-x) var(--sky-warm-y), rgba(255, 226, 0, calc(var(--sky-warm-a) * .4)), transparent 72%),
    radial-gradient(60% 26% at var(--sky-low-x) 90%, rgba(255, 228, 0, .11), transparent 72%),
    radial-gradient(50% 22% at var(--sky-low2-x) 94%, rgba(255, 228, 0, .085), transparent 72%),
    linear-gradient(180deg, #fff6cf 0%, #fff9e2 30%, #fffbec 52%, #fffae6 68%, #fff8dd 88%, #fff8dc 100%);
  /* Dissolve into whatever the page ground is doing below, so no seam. */
  -webkit-mask-image: linear-gradient(180deg, #000 84%, transparent);
  mask-image: linear-gradient(180deg, #000 84%, transparent);
}
.about-hero__sky::before,
.about-hero__sky::after {
  content: "";
  position: absolute;
  inset: 0;
  background-repeat: no-repeat;
  background-size: 100% 100%;
}
/* Long, thin wisps. */
.about-hero__sky::before {
  opacity: .6;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1600' height='900' preserveAspectRatio='none'%3E%3Cfilter id='c' x='0' y='0' width='100%25' height='100%25'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.0016 .0062' numOctaves='5' seed='11'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 2.6 0 0 0 -1.25'/%3E%3C/filter%3E%3Crect width='1600' height='900' filter='url(%23c)'/%3E%3C/svg%3E");
  -webkit-mask-image: linear-gradient(180deg, #000 0%, #000 55%, transparent 88%);
  mask-image: linear-gradient(180deg, #000 0%, #000 55%, transparent 88%);
}
/* Softer, rounder cloud banks. */
.about-hero__sky::after {
  opacity: .6;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1600' height='900' preserveAspectRatio='none'%3E%3Cfilter id='c' x='0' y='0' width='100%25' height='100%25'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.0024 .0036' numOctaves='4' seed='3'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 3.2 0 0 0 -1.7'/%3E%3CfeGaussianBlur stdDeviation='6'/%3E%3C/filter%3E%3Crect width='1600' height='900' filter='url(%23c)'/%3E%3C/svg%3E");
  -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 30%, #000 50%, rgba(0, 0, 0, .35) 66%, #000 86%, transparent 100%);
  mask-image: linear-gradient(180deg, transparent 0%, #000 30%, #000 50%, rgba(0, 0, 0, .35) 66%, #000 86%, transparent 100%);
}
/* Big soft lights that sweep across the sky: a deep yellow, a white and a
   warmer amber, each a wide ellipse fading to nothing at its edge. They carry
   the visible motion; the glows and clouds above add slower drift on top. */
.about-hero__light {
  position: absolute;
  border-radius: 50%;
  will-change: transform;
}
.about-hero__light--a {
  left: -22%;
  top: -35%;
  width: 78%;
  height: 105%;
  background: radial-gradient(closest-side, rgba(255, 219, 0, .22), rgba(255, 219, 0, .095) 55%, transparent);
}
.about-hero__light--b {
  right: -18%;
  top: -12%;
  width: 62%;
  height: 90%;
  background: radial-gradient(closest-side, rgba(255, 255, 255, .82), rgba(255, 255, 255, .44) 50%, transparent);
}
.about-hero__light--c {
  left: 28%;
  bottom: -45%;
  width: 72%;
  height: 85%;
  background: radial-gradient(closest-side, rgba(255, 212, 0, .17), rgba(255, 216, 0, .07) 55%, transparent);
}
/* Cursor wind (site.js, initAboutWind): the lights and clouds lean a few px
   with the pointer via `translate`, which stacks on their animated transform.
   Both values rest at zero. */
.about-hero__light { translate: calc(var(--push-x, 0px) * 1.2) calc(var(--push-y, 0px) * 1.2); }
.about-hero__sky::before { translate: calc(var(--push-x, 0px) * .7) calc(var(--push-y, 0px) * .7); }
.about-hero__sky::after { translate: var(--push-x, 0px) var(--push-y, 0px); }
@keyframes about-light-a {
  0%   { transform: translate3d(0, 0, 0) scale(1); }
  50%  { transform: translate3d(48%, 22%, 0) scale(1.18); }
  100% { transform: translate3d(18%, 38%, 0) scale(.92); }
}
@keyframes about-light-b {
  0%   { transform: translate3d(0, 0, 0) scale(1); }
  50%  { transform: translate3d(-55%, 30%, 0) scale(.9); }
  100% { transform: translate3d(-25%, -8%, 0) scale(1.15); }
}
@keyframes about-light-c {
  0%   { transform: translate3d(0, 0, 0) scale(1); }
  50%  { transform: translate3d(-48%, -18%, 0) scale(1.2); }
  100% { transform: translate3d(22%, -30%, 0) scale(.95); }
}
/* Now and then the sky drifts out of focus and slowly back: in each 40s cycle
   it stays sharp for most of the time, softens over about six seconds, holds,
   and comes back into focus. One inherited value blurs the lights and clouds
   together (the gradients underneath are already soft, and blurring the sky
   box itself would fade its edges). */
@property --sky-blur { syntax: "<length>"; inherits: true; initial-value: 0px; }
@keyframes about-sky-focus {
  0%, 42% { --sky-blur: 0px; animation-timing-function: ease-in-out; }
  58%, 70% { --sky-blur: 28px; animation-timing-function: ease-in-out; }
  88%, 100% { --sky-blur: 0px; }
}
.about-hero__light,
.about-hero__sky::before,
.about-hero__sky::after { filter: blur(var(--sky-blur, 0px)); }
@media (prefers-reduced-motion: no-preference) {
  .about-hero__light--a { animation: about-light-a 16s ease-in-out infinite alternate; }
  .about-hero__light--b { animation: about-light-b 19s ease-in-out -6s infinite alternate; }
  .about-hero__light--c { animation: about-light-c 23s ease-in-out -11s infinite alternate; }
  .about-hero__sky {
    animation:
      about-sky-sun 22s ease-in-out infinite alternate,
      about-sky-warm 28s ease-in-out -9s infinite alternate,
      about-sky-low 34s ease-in-out -14s infinite alternate,
      about-sky-focus 40s linear -8s infinite;
  }
  /* Scaled up a touch at rest so the slide never shows an edge. */
  .about-hero__sky::before {
    transform: scale(1.14);
    animation: about-sky-wisps 24s ease-in-out infinite alternate;
    will-change: transform;
  }
  .about-hero__sky::after {
    transform: scale(1.2);
    animation: about-sky-banks 31s ease-in-out -11s infinite alternate;
    will-change: transform;
  }
}
.about-hero__panel {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: max(520px, calc(100vh - 70px));
  min-height: max(520px, calc(100svh - 70px));
}
.about-hero__copy {
  padding: clamp(40px, 6vw, 80px) 0;
  max-width: 860px;
  margin: 0 auto;
  text-align: center;
}
.about-hero__copy h1 {
  margin: 0 0 18px;
  font-size: clamp(2.2rem, 5.4vw, 3.6rem);
  line-height: 1.02;
  letter-spacing: -0.052em;
  font-weight: var(--w-display);
  color: var(--ink);
}
.about-hero__copy p {
  margin: 0 auto;
  max-width: 38em;
  font-size: clamp(1rem, 1.6vw, 1.14rem);
  line-height: 1.6;
  color: var(--text-2);
}

/* Who we are: a centred statement between two wavy ribbons of S marks; big
   stats underneath. The ribbons bleed to the viewport edges, each with its own
   wave, and show their real colours at all times — there is no hover state.
   Both ribbons drift in a slow loop, the top one leftward and the bottom one
   rightward (initAboutRibbons in js/site.js). The wave below stays put: the
   marks glide along it from place to place, so it keeps exactly this shape. */
/* The ribbon follows straight on from the hero, so the run-in above it is
   shorter than a normal section top. */
.about-who { overflow: hidden; overflow: clip; padding-top: clamp(36px, 4.4vw, 64px); }
.about-who__stage { padding: clamp(8px, 2vw, 24px) 0; }
.about-ribbon {
  --mark: clamp(16px, 1.7vw, 26px);
  --mark-gap: clamp(6px, .9vw, 14px);
  position: relative;
  left: 50%;
  width: 100vw;
  transform: translateX(-50%);
  display: flex;
  justify-content: center;
  gap: var(--mark-gap);
  padding: calc(var(--mark) * 1.7) 0;
  pointer-events: none;
}
.about-ribbon--top { margin-bottom: clamp(2px, .9vw, 14px); }
.about-ribbon--bottom { margin-top: clamp(22px, 3.1vw, 42px); }
.about-ribbon img {
  flex: none;
  box-sizing: content-box;
  width: var(--mark);
  height: auto;
  padding-inline: calc(var(--mark-gap) / 2 + 1px);
  margin-inline: calc(var(--mark-gap) / -2 - 1px);
  user-select: none;
  -webkit-user-drag: none;
  opacity: 1;
}
.about-ribbon img[src$="mark-white.png"] { filter: drop-shadow(0 2px 5px rgba(20, 20, 30, .3)); }
.about-ribbon--top    img:nth-child(1) { transform: translateY(0.0%); }
.about-ribbon--bottom img:nth-child(1) { transform: translateY(60.4%); }
.about-ribbon--top    img:nth-child(2) { transform: translateY(31.2%); }
.about-ribbon--bottom img:nth-child(2) { transform: translateY(52.2%); }
.about-ribbon--top    img:nth-child(3) { transform: translateY(59.6%); }
.about-ribbon--bottom img:nth-child(3) { transform: translateY(39.4%); }
.about-ribbon--top    img:nth-child(4) { transform: translateY(83.0%); }
.about-ribbon--bottom img:nth-child(4) { transform: translateY(23.8%); }
.about-ribbon--top    img:nth-child(5) { transform: translateY(99.8%); }
.about-ribbon--bottom img:nth-child(5) { transform: translateY(7.3%); }
.about-ribbon--top    img:nth-child(6) { transform: translateY(109.6%); }
.about-ribbon--bottom img:nth-child(6) { transform: translateY(-8.0%); }
.about-ribbon--top    img:nth-child(7) { transform: translateY(112.9%); }
.about-ribbon--bottom img:nth-child(7) { transform: translateY(-20.3%); }
.about-ribbon--top    img:nth-child(8) { transform: translateY(111.2%); }
.about-ribbon--bottom img:nth-child(8) { transform: translateY(-27.9%); }
.about-ribbon--top    img:nth-child(9) { transform: translateY(106.3%); }
.about-ribbon--bottom img:nth-child(9) { transform: translateY(-29.8%); }
.about-ribbon--top    img:nth-child(10) { transform: translateY(100.2%); }
.about-ribbon--bottom img:nth-child(10) { transform: translateY(-25.4%); }
.about-ribbon--top    img:nth-child(11) { transform: translateY(94.6%); }
.about-ribbon--bottom img:nth-child(11) { transform: translateY(-14.8%); }
.about-ribbon--top    img:nth-child(12) { transform: translateY(90.4%); }
.about-ribbon--bottom img:nth-child(12) { transform: translateY(1.3%); }
.about-ribbon--top    img:nth-child(13) { transform: translateY(87.7%); }
.about-ribbon--bottom img:nth-child(13) { transform: translateY(21.6%); }
.about-ribbon--top    img:nth-child(14) { transform: translateY(85.8%); }
.about-ribbon--bottom img:nth-child(14) { transform: translateY(44.6%); }
.about-ribbon--top    img:nth-child(15) { transform: translateY(83.2%); }
.about-ribbon--bottom img:nth-child(15) { transform: translateY(68.1%); }
.about-ribbon--top    img:nth-child(16) { transform: translateY(78.2%); }
.about-ribbon--bottom img:nth-child(16) { transform: translateY(90.0%); }
.about-ribbon--top    img:nth-child(17) { transform: translateY(68.9%); }
.about-ribbon--bottom img:nth-child(17) { transform: translateY(108.6%); }
.about-ribbon--top    img:nth-child(18) { transform: translateY(54.4%); }
.about-ribbon--bottom img:nth-child(18) { transform: translateY(121.9%); }
.about-ribbon--top    img:nth-child(19) { transform: translateY(34.0%); }
.about-ribbon--bottom img:nth-child(19) { transform: translateY(128.9%); }
.about-ribbon--top    img:nth-child(20) { transform: translateY(8.6%); }
.about-ribbon--bottom img:nth-child(20) { transform: translateY(128.8%); }
.about-ribbon--top    img:nth-child(21) { transform: translateY(-20.4%); }
.about-ribbon--bottom img:nth-child(21) { transform: translateY(121.6%); }
.about-ribbon--top    img:nth-child(22) { transform: translateY(-50.5%); }
.about-ribbon--bottom img:nth-child(22) { transform: translateY(107.9%); }
.about-ribbon--top    img:nth-child(23) { transform: translateY(-79.0%); }
.about-ribbon--bottom img:nth-child(23) { transform: translateY(88.9%); }
.about-ribbon--top    img:nth-child(24) { transform: translateY(-103.4%); }
.about-ribbon--bottom img:nth-child(24) { transform: translateY(66.2%); }
.about-ribbon--top    img:nth-child(25) { transform: translateY(-121.3%); }
.about-ribbon--bottom img:nth-child(25) { transform: translateY(41.8%); }
.about-ribbon--top    img:nth-child(26) { transform: translateY(-131.6%); }
.about-ribbon--bottom img:nth-child(26) { transform: translateY(17.8%); }
.about-ribbon--top    img:nth-child(27) { transform: translateY(-134.0%); }
.about-ribbon--bottom img:nth-child(27) { transform: translateY(-3.8%); }
.about-ribbon--top    img:nth-child(28) { transform: translateY(-129.2%); }
.about-ribbon--bottom img:nth-child(28) { transform: translateY(-21.4%); }
.about-ribbon--top    img:nth-child(29) { transform: translateY(-119.0%); }
.about-ribbon--bottom img:nth-child(29) { transform: translateY(-33.4%); }
.about-ribbon--top    img:nth-child(30) { transform: translateY(-105.5%); }
.about-ribbon--bottom img:nth-child(30) { transform: translateY(-39.3%); }
.about-ribbon--top    img:nth-child(31) { transform: translateY(-91.0%); }
.about-ribbon--bottom img:nth-child(31) { transform: translateY(-38.7%); }
.about-ribbon--top    img:nth-child(32) { transform: translateY(-77.3%); }
.about-ribbon--bottom img:nth-child(32) { transform: translateY(-32.2%); }
.about-ribbon--top    img:nth-child(33) { transform: translateY(-65.5%); }
.about-ribbon--bottom img:nth-child(33) { transform: translateY(-20.9%); }
.about-ribbon--top    img:nth-child(34) { transform: translateY(-55.9%); }
.about-ribbon--bottom img:nth-child(34) { transform: translateY(-6.1%); }
.about-ribbon--top    img:nth-child(35) { transform: translateY(-47.9%); }
.about-ribbon--bottom img:nth-child(35) { transform: translateY(10.0%); }
.about-ribbon--top    img:nth-child(36) { transform: translateY(-40.3%); }
.about-ribbon--bottom img:nth-child(36) { transform: translateY(25.7%); }
.about-ribbon--top    img:nth-child(37) { transform: translateY(-31.3%); }
.about-ribbon--bottom img:nth-child(37) { transform: translateY(38.9%); }
.about-ribbon--top    img:nth-child(38) { transform: translateY(-19.4%); }
.about-ribbon--bottom img:nth-child(38) { transform: translateY(47.8%); }
.about-ribbon--top    img:nth-child(39) { transform: translateY(-3.5%); }
.about-ribbon--bottom img:nth-child(39) { transform: translateY(51.2%); }
.about-ribbon--top    img:nth-child(40) { transform: translateY(16.7%); }
.about-ribbon--bottom img:nth-child(40) { transform: translateY(48.3%); }
.about-ribbon--top    img:nth-child(41) { transform: translateY(40.5%); }
.about-ribbon--bottom img:nth-child(41) { transform: translateY(38.9%); }
.about-ribbon--top    img:nth-child(42) { transform: translateY(66.4%); }
.about-ribbon--bottom img:nth-child(42) { transform: translateY(23.5%); }
.about-ribbon--top    img:nth-child(43) { transform: translateY(92.0%); }
.about-ribbon--bottom img:nth-child(43) { transform: translateY(3.1%); }
.about-ribbon--top    img:nth-child(44) { transform: translateY(114.7%); }
.about-ribbon--bottom img:nth-child(44) { transform: translateY(-20.7%); }
.about-ribbon--top    img:nth-child(45) { transform: translateY(132.0%); }
.about-ribbon--bottom img:nth-child(45) { transform: translateY(-46.0%); }
.about-ribbon--top    img:nth-child(46) { transform: translateY(142.2%); }
.about-ribbon--bottom img:nth-child(46) { transform: translateY(-70.8%); }
.about-ribbon--top    img:nth-child(47) { transform: translateY(144.0%); }
.about-ribbon--bottom img:nth-child(47) { transform: translateY(-92.9%); }
.about-ribbon--top    img:nth-child(48) { transform: translateY(137.5%); }
.about-ribbon--bottom img:nth-child(48) { transform: translateY(-110.6%); }
.about-ribbon--top    img:nth-child(49) { transform: translateY(124.0%); }
.about-ribbon--bottom img:nth-child(49) { transform: translateY(-122.3%); }
.about-ribbon--top    img:nth-child(50) { transform: translateY(105.2%); }
.about-ribbon--bottom img:nth-child(50) { transform: translateY(-127.3%); }
.about-ribbon--top    img:nth-child(51) { transform: translateY(83.6%); }
.about-ribbon--bottom img:nth-child(51) { transform: translateY(-125.1%); }
.about-ribbon--top    img:nth-child(52) { transform: translateY(61.8%); }
.about-ribbon--bottom img:nth-child(52) { transform: translateY(-116.1%); }
.about-ribbon--top    img:nth-child(53) { transform: translateY(41.6%); }
.about-ribbon--bottom img:nth-child(53) { transform: translateY(-101.2%); }
.about-ribbon--top    img:nth-child(54) { transform: translateY(24.4%); }
.about-ribbon--bottom img:nth-child(54) { transform: translateY(-81.9%); }
.about-ribbon--top    img:nth-child(55) { transform: translateY(10.6%); }
.about-ribbon--bottom img:nth-child(55) { transform: translateY(-60.0%); }
.about-ribbon--top    img:nth-child(56) { transform: translateY(-0.4%); }
.about-ribbon--bottom img:nth-child(56) { transform: translateY(-37.6%); }
.about-ribbon--top    img:nth-child(57) { transform: translateY(-9.7%); }
.about-ribbon--bottom img:nth-child(57) { transform: translateY(-16.7%); }
.about-ribbon--top    img:nth-child(58) { transform: translateY(-19.1%); }
.about-ribbon--bottom img:nth-child(58) { transform: translateY(0.9%); }
.about-ribbon--top    img:nth-child(59) { transform: translateY(-30.0%); }
.about-ribbon--bottom img:nth-child(59) { transform: translateY(13.6%); }
.about-ribbon--top    img:nth-child(60) { transform: translateY(-43.6%); }
.about-ribbon--bottom img:nth-child(60) { transform: translateY(20.4%); }
.about-ribbon--top    img:nth-child(61) { transform: translateY(-60.1%); }
.about-ribbon--bottom img:nth-child(61) { transform: translateY(20.9%); }
.about-ribbon--top    img:nth-child(62) { transform: translateY(-78.9%); }
.about-ribbon--bottom img:nth-child(62) { transform: translateY(15.4%); }
.about-ribbon--top    img:nth-child(63) { transform: translateY(-98.6%); }
.about-ribbon--bottom img:nth-child(63) { transform: translateY(4.7%); }
.about-ribbon--top    img:nth-child(64) { transform: translateY(-117.0%); }
.about-ribbon--bottom img:nth-child(64) { transform: translateY(-9.8%); }

.about-who__copy { max-width: 40rem; margin: 0 auto; text-align: center; }
.section .about-who__copy h2 { margin-bottom: 20px; }
.about-who__copy .section-copy {
  margin: 0 auto 14px;
  font-size: clamp(.9rem, 1.1vw, .96rem);
  line-height: 1.7;
  text-wrap: pretty;
}
.about-who__copy .section-copy:last-child { margin-bottom: 0; }

.about-split {
  display: grid;
  gap: 0;
  align-items: start;
}
@media (min-width: 900px) {
  .about-split {
    grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
    gap: clamp(40px, 6vw, 96px);
  }
  .section .about-split > h2 { margin-bottom: 0; max-width: 11em; }
  .section .about-split > div > h2 { margin-bottom: 18px; max-width: 11em; }
}

.about-num {
  display: inline-block;
  font-size: 13px;
  font-weight: var(--w-title);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0;
  line-height: 1;
  padding: 6px 9px;
  border-radius: var(--r-pill);
  background: var(--brand);
  color: var(--brand-ink);
}

.about-steps { list-style: none; margin: 0; padding: 0; display: grid; }

.about-steps {
  margin-top: clamp(44px, 6vw, 80px);
  gap: 0 clamp(28px, 4vw, 56px);
}
.about-steps li {
  padding: 24px 0;
  border-top: 1px solid var(--hairline-mid);
}
.about-steps h3 { margin: 16px 0 8px; font-size: 1.15rem; letter-spacing: -0.03em; }
.about-steps p { margin: 0; color: var(--muted); font-size: .96rem; line-height: 1.6; max-width: 26em; }
@media (min-width: 760px) {
  .about-steps { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}


/* What we are not building (About, #not-building): the heading centred
   above the list, each title marked with a yellow dot and its
   line under it. A line opens as its row reaches the middle of the screen
   and closes again as you scroll past; js/site.js sets is-live on the list
   and is-open on the row. Without it (or with reduced motion) every line
   stays open. */
.section .about-stack > h2 {
  text-align: center;
  margin: 0 auto clamp(32px, 4vw, 56px);
  max-width: 18em;
  text-wrap: balance;
}
.section .about-stack > .about-nots { max-width: 720px; margin: 0 auto; }
.about-nots { margin: 0; }
.about-nots > div {
  padding: 20px 0 20px 26px;
  border-top: 1px solid var(--hairline-mid);
}
.about-nots > div:last-child { border-bottom: 1px solid var(--hairline-mid); }
.about-nots dt::before {
  content: "";
  position: absolute;
  left: -24px;
  top: calc(.65em - 5px);
  width: 10px; height: 10px;
  border-radius: 50%;
  background: var(--brand);
}
.about-nots dt {
  position: relative;
  font-size: clamp(1.05rem, 1.6vw, 1.2rem);
  font-weight: var(--w-title);
  line-height: 1.3;
  letter-spacing: -0.025em;
  color: var(--text);
}
.about-nots dd {
  display: grid;
  grid-template-rows: 1fr;
  margin: 6px 0 0;
  color: var(--muted);
  line-height: 1.55;
}
.about-nots dd > span { min-height: 0; overflow: hidden; }

.about-nots.is-live dt { color: var(--muted); transition: color .3s ease; }
.about-nots.is-live dd {
  grid-template-rows: 0fr;
  margin-top: 0;
  opacity: 0;
  transition: grid-template-rows .45s var(--ease-smooth), margin-top .45s var(--ease-smooth), opacity .3s ease;
}
.about-nots.is-live dt { cursor: pointer; }
.about-nots.is-live dt:hover { color: var(--text); }
.about-nots.is-live dt:focus-visible { outline: 2px solid var(--brand); outline-offset: 4px; border-radius: 4px; }
.about-nots.is-live > .is-open dt { color: var(--text); }
.about-nots.is-live > .is-open dd { grid-template-rows: 1fr; margin-top: 6px; opacity: 1; }
/* The legal-details line closes the identity card. It is set apart by space
   alone — no hairline, so the names above it are the card's last ruled row. */
#team .idcard .note {
  margin: 34px auto 0;
  max-width: 100%;
  padding-top: 0;
  text-align: center;
  font-size: .82rem;
}

/* Who is behind soshctrl: a statement band. The words sit centred in the
   middle of the page and the identity card sits under them, centred on the
   same axis, instead of the two standing side by side. */
#team .about-who__copy { max-width: 34rem; }
#team .idcard {
  max-width: 44rem;
  margin: clamp(22px, 2.4vw, 30px) auto 0;
  text-align: left;
}
/* The card no longer has a column to stretch into, so the wordmark takes its
   own height rather than the slack above the rows. */
#team .idcard__logo { flex: 0 0 auto; padding: 2px 0 20px; border-bottom: none; }

/* The band carries only a heading, a paragraph and the card, so it does not
   need a full section's worth of air above and below. */
#team.section { padding: clamp(40px, 4.4vw, 62px) 0; }
/* The legal-details line is the card's closing footnote, so it sits near the
   panel's bottom edge rather than centred in a full section's worth of air. */
#team.section { padding-bottom: clamp(20px, 2vw, 28px); }

/* Founder and designer sit as a centred pair under the wordmark, on the same
   axis as the heading, rather than spread to the edges of the card. */
#team .idpeople {
  grid-template-columns: repeat(2, minmax(0, max-content));
  justify-content: center;
  gap: 20px clamp(44px, 6.5vw, 92px);
  padding: clamp(38px, 5vw, 64px) 0 0;
  text-align: center;
}
@media (max-width: 560px) {
  #team .idpeople { grid-template-columns: minmax(0, max-content); }
}

/* ── Keys around the word (Security hero) ────────────────────
   Four small grey keys scattered off the corners of "keys." in
   the Security headline. They are decoration, not content, so
   they are aria-hidden and sit in absolute positions hung off
   the word itself — the headline's own layout never moves.

   Every measurement is in em, so the whole cluster tracks the
   clamped h1 size from a phone up to the widest window.

   They pop in once, on load, after the headline has risen into
   place: a short scale-up with a little overshoot, staggered
   outward. No idle loop — once landed they hold still, and the
   rotation each key rests at is carried in --kr so the pop
   never straightens it out.
   ────────────────────────────────────────────────────────── */

.keys-word { position: relative; white-space: nowrap; }

/* The two keys under the word need somewhere to land. The stock 18px between
   a hero headline and its line of copy is not enough for one to sit in with
   air on both sides, so the headline that carries them keeps a wider gap. */
.page-hero h1:has(.keys-word) { margin-bottom: clamp(30px, 2.8vw, 46px); }

/* The security headline runs a size under the other interior heroes: it is a
   long line, and the keys around the word need room without the whole thing
   filling the screen. The keys are sized in em, so they follow it down. */
.page-hero h1:has(.keys-word) { font-size: clamp(2rem, 4.75vw, 3.15rem); }
.page-hero:has(.keys-word) p { font-size: clamp(.95rem, 1.35vw, 1.05rem); }

.keys-word__k {
  position: absolute;
  display: block;
  pointer-events: none;
  color: var(--faint);
  animation: key-pop .72s var(--ease) both;
}
.keys-word__k svg { display: block; width: 100%; height: auto; }

/* Above the word, left and right of centre. `bottom: 100%` hangs each one off
   the top edge of the word's own box, clear of the cap height. */
.keys-word__k--a {
  width: .54em; --kr: -24deg;
  color: var(--muted);
  left: 0; margin-left: .30em;
  bottom: 100%; margin-bottom: -.02em;
  animation-delay: .52s;
}
.keys-word__k--c {
  width: .47em; --kr: 20deg;
  color: var(--muted);
  left: 100%; margin-left: .10em;
  bottom: 100%; margin-bottom: -.02em;
  animation-delay: .60s;
}

/* Below the baseline, further out and a size smaller, so the cluster thins
   as it spreads rather than ringing the word evenly. */
.keys-word__k--b {
  width: .37em; --kr: 15deg;
  left: 0; margin-left: .40em;
  top: 100%; margin-top: -.14em;
  animation-delay: .68s;
}
.keys-word__k--d {
  width: .33em; --kr: -13deg;
  left: 100%; margin-left: .30em;
  top: 100%; margin-top: -.16em;
  animation-delay: .76s;
}

@keyframes key-pop {
  from { opacity: 0; transform: translateY(.14em) rotate(0deg) scale(.4); }
  60%  { opacity: 1; transform: translateY(-.04em) rotate(calc(var(--kr) * 1.18)) scale(1.1); }
  to   { opacity: 1; transform: translateY(0) rotate(var(--kr)) scale(1); }
}

/* Narrow windows: the headline wraps and "keys." starts the second line,
   right under the first, where the top pair would sit on the letters above.
   The keys keep the same four places as on a wide screen; instead the word's
   line drops a little, opening a gap between the lines for the top pair. */
@media (max-width: 660px) {
  .keys-word { display: inline-block; margin-top: .8em; }
}

/* No entrance for anyone who asked for stillness — the keys are simply there. */
@media (prefers-reduced-motion: reduce) {
  .keys-word__k { animation: none; transform: rotate(var(--kr)); }
}

/* ── Account isolation (Security, #isolation) ─────────────── */

/* This band is a full-bleed stripe rather than one of the floating
   panels, so the black runs to both page edges: no side margin, no
   radius, no side borders. */
.section.band-dark.band-dark--bleed {
  width: 100%;
  margin-inline: 0;
  border-radius: 0;
  border-inline: 0;
}

/* The heading starts higher in the band than a full section's top padding
   would put it, so the statement meets the eye before the diagram. */
#isolation.section {
  /* The notes' column gap, shared with the diagram so it can line its two
     accounts up over the outer notes. */
  --iso-gap: clamp(28px, 4.4vw, 60px);
  padding-top: clamp(44px, 4.6vw, 66px);
  padding-bottom: clamp(64px, 7vw, 100px);
}

/* The heading is the band's whole statement, so it stands on the page's
   centre line with the diagram directly under it. */
/* `.section h2` would otherwise reset the side margins to 0 and leave the
   box on the left, so the selector has to outrank it. */
.section .isolation__title {
  text-align: center;
  max-width: 34ch;
  margin-inline: auto;
  /* The heading sits high in the band with a wide gap under it, so the
     diagram stands on its own below the statement. */
  margin-bottom: clamp(72px, 8.6vw, 118px);
}

/* Two accounts joined by a plain straight hairline, with a crossed-out eye
   sitting on it halfway: the picture says what the heading says. The line is
   drawn as a segment either side of the badge — with no gap, so it reads as
   one unbroken line running into the eye — rather than one line with a disc
   laid over it, which would have to be painted opaque to match the band's
   gradient. */
.iso-diagram {
  /* The eye sits inside its badge at 48% of it. The person is drawn half again
     that size — at the eye's exact size it read as a speck, because the eye
     fills its box across while the figure uses only the middle of its own. */
  --iso-badge: clamp(52px, 5.6vw, 68px);
  --iso-ico: calc(var(--iso-badge) * .72);
  /* Tabler draws the person 12 units wide inside its 24-unit box, so this is
     how wide the figure actually is — what the line has to stop at, since the
     box itself reaches well past the shoulders. */
  --iso-ico-draw: calc(var(--iso-ico) * .5);
  /* Breathing space between the figure and the end of the line, so the line
     stops beside it rather than growing out of its shoulder. */
  --iso-line-gap: clamp(7px, .8vw, 11px);
  /* Both side columns are this wide — a set width, not `auto`: the two
     labels are different lengths, and a content-sized side column would
     shift the eye off the page's centre line by the difference. Wide
     enough to hold the longer label on one line. */
  --iso-node-w: clamp(142px, 13.6vw, 170px);
  display: grid;
  grid-template-columns: var(--iso-node-w) minmax(0, 1fr) var(--iso-node-w);
  align-items: start;
  gap: 0;
  max-width: 780px;
  margin: 0 auto clamp(44px, 5.4vw, 76px);
}

.iso-node {
  display: grid;
  justify-items: center;
  gap: 12px;
  text-align: center;
}
/* Just the person: no disc behind it, and no ring drawn around it either. */
.iso-node__ico {
  width: var(--iso-ico);
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  color: #fff;
}
/* Thinned in step with the box, so the figure keeps the eye's stroke weight
   instead of growing a heavier outline than everything around it. */
.iso-node__ico svg {
  width: 100%;
  height: 100%;
  stroke-width: 1.33;
}
.iso-node__label {
  font-size: 1rem;
  line-height: 1.45;
  color: rgba(250, 250, 250, .66);
  max-width: 100%;
}

/* The line runs through the centres of the two icons, not through the
   centre of the whole node (icon plus label): the row is held to zero
   height and dropped half an icon down, and `align-content: center` puts
   the row's own middle — the line — on that mark, with the taller badge
   overflowing evenly above and below it. */
.iso-link {
  display: grid;
  grid-template-columns: minmax(10px, 1fr) auto minmax(10px, 1fr);
  align-items: center;
  align-content: center;
  gap: 0;
  height: 0;
  margin-top: calc(var(--iso-ico) / 2);
  /* The line reaches the glyphs: the row is pulled out of its own column and
     into each side column by the space left beside the figure there, less the
     gap, so each end stops just clear of the figure instead of far out from it
     — or across it. */
  margin-inline: calc((var(--iso-ico-draw) - var(--iso-node-w)) / 2 + var(--iso-line-gap));
}
.iso-link::before,
.iso-link::after {
  content: "";
  height: 1px;
  background: rgba(255, 255, 255, .34);
}
.iso-link__badge {
  width: var(--iso-badge);
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  border-radius: 50%;
  color: var(--brand);
  background: rgba(255, 223, 0, .07);
  border: 1px solid rgba(255, 223, 0, .32);
  box-shadow: 0 0 26px -10px var(--brand-glow);
}
.iso-link__badge svg { width: 48%; height: 48%; }

/* Three plain notes under the diagram: a heading and a line of text, on
   the same centre axis, with no rule and no step number. Three across at
   every width, phones included, so the section reads the same everywhere. */
.iso-notes {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(26px, 3.4vw, 40px) var(--iso-gap);
  max-width: 1000px;
  margin-inline: auto;
}
/* Each account stands over its own note and the eye over the middle one:
   the diagram is sized so its side columns centre on the notes' outer
   columns. Notes run W wide in three columns of C, so their outer centres
   are W − C apart; the diagram adds one node column to that span. */
.iso-diagram {
  --iso-w: min(1000px, 100%);
  --iso-col: calc((var(--iso-w) - 2 * var(--iso-gap)) / 3);
  max-width: none;
  width: calc(var(--iso-w) - var(--iso-col) + var(--iso-node-w));
}

/* Phone: the same horizontal run, scaled down. The side columns shrink to
   one note column each, so the diagram spans exactly the notes' width and
   the labels wrap inside their column instead of pushing past the edge. */
@media (max-width: 620px) {
  #isolation.section { --iso-gap: 12px; }
  .iso-diagram {
    --iso-badge: 44px;
    --iso-line-gap: 5px;
    --iso-node-w: var(--iso-col);
  }
  .iso-node { gap: 8px; }
  .iso-node__label { font-size: .8rem; line-height: 1.35; }
  .iso-note h3 { font-size: .86rem; margin-bottom: 6px; }
  .iso-note p { font-size: .74rem; line-height: 1.5; }
}
.iso-note { text-align: center; }
.iso-note h3 {
  margin: 0 0 10px;
  color: #fff;
  font-size: clamp(1.02rem, 1.25vw, 1.14rem);
  letter-spacing: -0.032em;
}
.iso-note p {
  margin: 0 auto;
  max-width: 34ch;
  color: rgba(250, 250, 250, .66);
  line-height: 1.62;
  font-size: .9rem;
}

/* ── Data rights (security #rights) ─────────── */
/* The four rights are square cards side by side, four across on a wide
   screen, two on a tablet and one under the other on a phone. Each card
   keeps the Tabler icon that acts out its verb on hover — the copy pulls a
   second sheet off, the bin lifts its lid, the clock sweeps a full minute
   round, the helper steps in. */
#rights h2 { text-align: center; }

.rights-grid {
  list-style: none;
  margin: clamp(30px, 4vw, 48px) 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(14px, 1.6vw, 20px);
}

/* Square card, text ranged left, icon at the top and the words at the foot.
   The square is a floor, not a cage: a card whose words need more room
   grows, and the grid row keeps its neighbours the same height. */
.rights-card {
  display: flex;
  flex-direction: column;
  aspect-ratio: 1 / 1;
  /* aspect-ratio opts out of the row's stretch; this puts it back. */
  height: 100%;
  padding: clamp(22px, 2.4vw, 28px);
  border: 1px solid var(--hairline-mid);
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--shadow-md);
}

@media (max-width: 959px) {
  .rights-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
/* One column: a full-width square would be mostly empty, so the card sizes
   to its words instead. */
@media (max-width: 559px) {
  .rights-grid { grid-template-columns: minmax(0, 1fr); }
  .rights-card { aspect-ratio: auto; min-height: 200px; }
}

.rights-card h3 {
  margin: 0 0 10px;
  font-size: 1.18rem;
  letter-spacing: -0.03em;
}
.rights-card p {
  margin: 0;
  color: var(--muted);
  font-size: .94rem;
  line-height: 1.6;
}

/* Bare icon, no tile — a box round it would be the only box left here. */
.rights-card__ico {
  display: block;
  margin: 0 0 auto;
  color: var(--ink);
  transition: color .42s var(--ease);
}
.rights-card__ico svg { width: 30px; height: 30px; overflow: visible; }
.rights-card:hover .rights-card__ico,
.rights-card:focus-within .rights-card__ico { color: var(--brand); }

/* Each moving part translates or rotates only — no stroke is redrawn, so the
   icon keeps its shape at every point in the transition. */
.rights-ico__front,
.rights-ico__back,
.rights-ico__lid,
.rights-ico__min,
.rights-ico__hour,
.rights-ico__mate {
  /* Origins below are viewBox coordinates, so pin the box the transform is
     measured from — the default fill-box would offset every rotation. */
  transform-box: view-box;
  transition: transform .42s var(--ease);
}
.rights-ico__lid { transform-origin: 4px 7px; }
.rights-ico__min,
.rights-ico__hour { transform-origin: 12px 12px; }

.rights-card:hover .rights-ico__front,
.rights-card:focus-within .rights-ico__front { transform: translate(1.6px, 1.6px); }
.rights-card:hover .rights-ico__back,
.rights-card:focus-within .rights-ico__back { transform: translate(-1.6px, -1.6px); }

.rights-card:hover .rights-ico__lid,
.rights-card:focus-within .rights-ico__lid { transform: translate(.5px, -2.6px) rotate(-11deg); }

.rights-card:hover .rights-ico__min,
.rights-card:focus-within .rights-ico__min { transform: rotate(360deg); }
.rights-card:hover .rights-ico__hour,
.rights-card:focus-within .rights-ico__hour { transform: rotate(30deg); }

.rights-card:hover .rights-ico__mate,
.rights-card:focus-within .rights-ico__mate { transform: translateX(-1px); }

@media (prefers-reduced-motion: reduce) {
  :is(.rights-card, .rights-card:hover, .rights-card:focus-within)
  :is(.rights-ico__front, .rights-ico__back, .rights-ico__lid,
      .rights-ico__min, .rights-ico__hour, .rights-ico__mate) {
    transition: none; transform: none;
  }
}

/* ── 404 ─────────────────────────────────────────────────────
   A bare dark screen: tools/build.py leaves out the header and
   footer on this page. Black ground with a soft white glow; the
   "404" is a dot matrix of the small S marks the Product hero
   lights up, drawn as one inline SVG. js/notfound.js paints the
   hover field on the canvas behind it, on the same lattice.
   ────────────────────────────────────────────────────────── */

/* No reserved scrollbar gutter: this screen never scrolls, and the empty
   light track would draw a pale strip down the right edge. */
html:has(body.site--404) { background: #050506; scrollbar-gutter: auto; }
body.site.site--404 { background: #050506; color: #fff; }
/* Opaque base layer, so the light-site auto-dark override behind it never shows. */
body.site--404::before {
  background:
    radial-gradient(64vw 44vw at 50% 110%, rgba(255, 255, 255, .13), transparent 70%),
    radial-gradient(40vw 32vw at 10% -10%, rgba(255, 255, 255, .08), transparent 68%),
    radial-gradient(34vw 28vw at 94% 2%, rgba(255, 255, 255, .06), transparent 70%),
    radial-gradient(30vw 22vw at 50% 42%, rgba(255, 223, 0, .05), transparent 72%),
    #050506;
}

.nf {
  position: relative;
  display: flex;
  align-items: center;
  min-height: 100vh;
  min-height: 100svh;
  padding: 48px 0;
}
.nf__field {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}
.nf > .container { position: relative; z-index: 1; }
.nf__inner { text-align: center; }
/* An image link, so none of the marker-stroke link treatment. */
.nf__logo {
  display: inline-block;
  margin-bottom: clamp(30px, 4.4vw, 52px);
  padding: 0;
  background: none;
}
.nf__logo:hover { background: none; }
.nf__logo img { width: clamp(118px, 12vw, 150px); height: auto; }
.nf__code {
  display: block;
  width: min(540px, 84vw);
  height: auto;
  margin: 0 auto;
  filter: drop-shadow(0 0 12px rgba(255, 223, 0, .26));
}
.nf__title {
  margin: clamp(24px, 3.2vw, 36px) 0 0;
  color: #fff;
  font-size: clamp(1.5rem, 3vw, 2rem);
  font-weight: 400;
  letter-spacing: -0.03em;
  line-height: 1.1;
}
.nf .btn-row {
  justify-content: center;
  gap: 10px;
  margin-top: clamp(18px, 2.4vw, 26px);
}
/* A step down from the standard button, a step up from .btn-sm. */
.nf .btn { min-height: 38px; padding: 0 18px; font-size: 13.5px; gap: 7px; }
