/* =========================================================================
   ARTICULANCE — the app's own light appearance, on the web
   -------------------------------------------------------------------------
   Every colour below is a token from `Palette.swift`, not an approximation of
   one. The app is a cool-neutral page carrying white cards, with hue reserved
   for destinations; this file is the same system.

     Color.Neutral       the page / card / well / ink ladder
     Color.appPrimaryAccent + appOnAccent      a door's fill, and its ink
     Color.appAccentOnSurface                  the interface tint (ink, never fill)
     FeatureAccent                             the seven destination hues

   ☠️ THE GRAMMAR, settled twice on Josh's own verdicts and enforced in the
   binary by `ExecutiveIdentityScanTests`:

        a coloured GLYPH WELL on a calm ground.
        a full accent GROUND is earned only by a DOOR.

   An identity card, a fact grid, a pricing row or a nav item is not a door.
   The App Store button and the download banner are. Do not paint a section
   background in an accent to make it feel designed — that verdict has already
   been taken ("accents, not backgrounds — colour the little icons").

   ☠️ THE INK ON THE ACCENT IS WHITE, and that is a reversal. It used to be
   obsidian, because the fill used to be gold (#D4AF37 carries white at 2.10:1
   and obsidian at 9.36:1). The fill is Keynote Sapphire #3A5CA0 now (re-keyed
   from cobalt #1A57C4 to match the icon arc); white on it clears 6.0:1.
   If the brand fill ever moves again, the ink moves with it — the rule is
   "the accent carries *its* ink", never a colour.
   ========================================================================= */

@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Nunito:wght@700;800&display=swap');

/* =========================================================================
   1 · TOKENS
   ========================================================================= */

:root {
  /* ---- The neutral spine (Color.Neutral, light) ---- */
  --page-top: #E7EAF0;
  --page-bottom: #DCE0E8;
  --card: #FFFFFF;
  --card-mid: #FBFCFE;
  --card-deep: #F5F7FA;
  --well: #DDE2EA;

  --ink: #0F172A;
  --ink-2: #55637A;   /* graded ≥ 4.5:1 on every stop of both ramps */
  /* ☠️ A CARD ink, and only a card ink. `#606E82` measures 5.28:1 on white and
     4.79 on the card's trailing stop, but **3.92 on the page's lower stop
     `#DCE0E8`** — under AA for the caption text it exists for. It was on the
     page in five places (the hero's price line, the pipeline sublabels, the
     policy meta, the footer and the contact notes) and all five moved to
     `--ink-2`, which clears 4.60 there. There is no third ink step available
     over this page; do not invent one by lightening this. */
  --ink-3: #606E82;

  /* ---- The brand: a fill, an ink, and they are different colours ---- */
  --accent-fill: #3A5CA0;      /* appPrimaryAccent (Keynote Sapphire) — doors only */
  --accent-fill-deep: #1B2F59;  /* FeatureAccent.cobalt.deepHex */
  --on-accent: #FFFFFF;        /* appOnAccent */
  --accent-ink: #2D4D8D;       /* FeatureAccent.cobalt.inkLightHex — links, kickers, glyphs */
  --accent-glow: #89A2D5;      /* FeatureAccent.cobalt.glowHex / Brand.azureOrb — cornflower */
  --accent-tint: #D6E4FF;      /* FeatureAccent.cobalt.tintHex */
  --accent-tint-dark: #263045; /* FeatureAccent.cobalt.tintDarkHex */

  /* ---- FeatureAccent: seven destinations. core / ink / glow / tint ---- */
  --fa-gold: #B69145;        --fa-gold-ink: #624A19;        --fa-gold-glow: #F2DAAA;        --fa-gold-tint: #F6E6C5;
  --fa-cobalt: #3A5CA0;      --fa-cobalt-ink: #2D4D8D;      --fa-cobalt-glow: #89A2D5;      --fa-cobalt-tint: #D6E4FF;
  --fa-amethyst: #6645C1;    --fa-amethyst-ink: #5737AD;    --fa-amethyst-glow: #AB95E9;    --fa-amethyst-tint: #E1D6FF;
  --fa-emerald: #36784F;     --fa-emerald-ink: #205E38;     --fa-emerald-glow: #79B791;     --fa-emerald-tint: #C7EFD6;
  --fa-cyan: #814585;        --fa-cyan-ink: #77347C;        --fa-cyan-glow: #C78ECB;        --fa-cyan-tint: #FBDAFD;
  --fa-rose: #A14463;        --fa-rose-ink: #8B2C4C;        --fa-rose-glow: #D98BA5;        --fa-rose-tint: #FFD6E4;
  --fa-graphite: #39435A;    --fa-graphite-ink: #444D64;    --fa-graphite-glow: #99A2B6;    --fa-graphite-tint: #E2E6EF;

  /* ---- Sovereign metal ramp (the app icon's material) ---- */
  --metal-ice: #F4F7FA;
  --metal-mist: #C9D3DD;
  --metal-steel: #8FA1B3;
  --metal-steel-deep: #5E7286;
  --metal-steel-shadow: #3C4A5A;
  --metal-gradient: linear-gradient(135deg, var(--metal-ice) 0%, var(--metal-steel) 55%, var(--metal-steel-deep) 100%);

  /* The wash a glyph well sits on: the accent's core at the app's own alpha. */
  --wash-alpha: 0.13;
  --wash-alpha-strong: 0.26;

  /* ---- Status. Deliberately not accent-adjacent. ---- */
  --success: #15803D;
  --warning: #E08A3C;
  --danger: #D4373E;
  --live: #D4373E;             /* Color.liveRed — the microphone is open, and nothing else */

  /* ---- Structure ---- */
  --hairline: rgba(15, 23, 42, 0.09);
  --hairline-strong: rgba(15, 23, 42, 0.16);
  --divider: rgba(15, 23, 42, 0.10);
  --chrome: rgba(255, 255, 255, 0.82);
  --chrome-solid: #FFFFFF;

  --shadow-card:
    0 1px 2px rgba(15, 23, 42, 0.05),
    0 10px 30px -14px rgba(15, 23, 42, 0.20);
  --shadow-lift:
    0 2px 4px rgba(15, 23, 42, 0.06),
    0 22px 48px -18px rgba(15, 23, 42, 0.28);
  --shadow-door: 0 10px 26px -10px rgba(58, 92, 160, 0.45);
  /* The float is for things that hover over the page — the hero callouts and
     the two fixed controls. One step above `--shadow-lift` so a floating
     object never reads as a card that merely lifted. */
  --shadow-float:
    0 4px 10px rgba(15, 23, 42, 0.07),
    0 30px 60px -22px rgba(15, 23, 42, 0.34);
  /* The primary door's hover sheen. A variable because the door inside
     `.banner` is white and needs a dark sweep instead of a light one. */
  --sheen: rgba(255, 255, 255, 0.30);

  /* The specular crest that makes a plate read as lit rather than as a
     rectangle. Asymmetric by appearance for a measured reason: white at 40 %
     is a crest on charcoal and nothing at all on white. */
  --crest: linear-gradient(160deg, #FFFFFF 0%, var(--card-mid) 46%, var(--card-deep) 100%);

  /* ---- Fixed-dark instrument surfaces ----
     The app's one non-adaptive family: a well that holds a *drawing*. A card
     is a sheet that carries prose; a well is the ground a waveform is drawn
     on, and it holds still so luminous ink stays graded against something. */
  --instrument: #12131A;
  --instrument-deep: #0A0B0E;
  --instrument-ink: #F5F7FA;
  --instrument-ink-2: #9BA0A8;
  --instrument-stroke: rgba(255, 255, 255, 0.10);
  --instrument-grid: rgba(255, 255, 255, 0.07);

  /* ---- Mesh orbs: light in the room, never a ground ---- */
  --orb-azure: #89A2D5;        /* Brand.azureOrb — cornflower */
  --orb-violet: #AAA3CA;       /* Brand.violetOrb — iris */
  --orb-warm: #F7B393;         /* Brand.warmOrb — peach/apricot */
  --orb-gold: #F2DAAA;
  --orb-opacity: 0.22;

  /* ---- Type ----
     ☠️ The app is SF Pro Rounded in 101 places and SF Pro Text everywhere
     else. `ui-rounded` resolves to SF Pro Rounded on Apple platforms, which is
     the platform this app ships on — so on a Mac or an iPhone the site is set
     in the app's own face, with no font downloaded at all. Nunito and Inter
     are the fallbacks elsewhere and are fetched only if they are actually
     used, which is what makes the pairing free on Apple hardware. */
  --font-display: ui-rounded, "SF Pro Rounded", -apple-system, "Nunito",
                  system-ui, "Segoe UI", sans-serif;
  --font-body: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Inter",
               system-ui, "Segoe UI", sans-serif;
  --font-mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, "JetBrains Mono",
               Consolas, monospace;

  /* ---- Rhythm ---- */
  --radius-sm: 10px;
  --radius: 16px;
  --radius-lg: 22px;
  --radius-xl: 28px;
  --gutter: clamp(1.15rem, 4vw, 2rem);
  --section-gap: clamp(4.5rem, 9vw, 8rem);
  --measure: 68ch;

  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);

  color-scheme: light;
}

/* -------------------------------------------------------------------------
   Dark appearance — the same tokens, the other half of every adaptive pair.
   The page is pitch black under charcoal cards, as in the app: that is what
   makes a card read as a plate rather than as a slightly different black.
   ------------------------------------------------------------------------- */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --page-top: #0B0C10;
    --page-bottom: #000000;
    --card: #1F1F23;
    --card-mid: #161619;
    --card-deep: #0F0F12;
    --well: #1C1C1F;

    --ink: #FFFFFF;
    --ink-2: #C2C4CA;
    --ink-3: #9BA0A8;

    --accent-ink: #89A2D5;
    --accent-fill: #3A5CA0;
    --accent-fill-deep: #1B2F59;

    --fa-gold-ink: #F2DAAA;        --fa-gold-tint: #3E3421;
    --fa-cobalt-ink: #89A2D5;      --fa-cobalt-tint: #263045;
    --fa-amethyst-ink: #AB95E9;    --fa-amethyst-tint: #342B4D;
    --fa-emerald-ink: #79B791;     --fa-emerald-tint: #1E3527;
    --fa-cyan-ink: #C78ECB;        --fa-cyan-tint: #3F2841;
    --fa-rose-ink: #D98BA5;        --fa-rose-tint: #462732;
    --fa-graphite-ink: #99A2B6;    --fa-graphite-tint: #2A2D34;

    --wash-alpha: 0.17;
    --wash-alpha-strong: 0.30;

    --success: #3FB98A;

    --hairline: rgba(255, 255, 255, 0.10);
    --hairline-strong: rgba(255, 255, 255, 0.18);
    --divider: rgba(255, 255, 255, 0.12);
    --chrome: rgba(11, 12, 16, 0.80);
    --chrome-solid: #0B0C10;

    --shadow-card: 0 1px 2px rgba(0, 0, 0, 0.55), 0 12px 30px -16px rgba(0, 0, 0, 0.85);
    --shadow-lift: 0 2px 6px rgba(0, 0, 0, 0.6), 0 26px 54px -20px rgba(0, 0, 0, 0.9);
    --shadow-door: 0 10px 28px -12px rgba(58, 92, 160, 0.65);
    --shadow-float: 0 4px 12px rgba(0, 0, 0, 0.55), 0 32px 60px -24px rgba(0, 0, 0, 0.92);

    --crest: linear-gradient(160deg, #23232A 0%, var(--card-mid) 48%, var(--card-deep) 100%);

    --instrument: #16161B;
    --instrument-deep: #08080B;
    --instrument-stroke: rgba(255, 255, 255, 0.09);

    --orb-opacity: 0.18;

    color-scheme: dark;
  }
}

/* The explicit choice wins in both directions. */
:root[data-theme="dark"] {
  --page-top: #0B0C10;
  --page-bottom: #000000;
  --card: #1F1F23;
  --card-mid: #161619;
  --card-deep: #0F0F12;
  --well: #1C1C1F;
  --ink: #FFFFFF;
  --ink-2: #C2C4CA;
  --ink-3: #9BA0A8;
  --accent-ink: #89A2D5;
  --accent-fill: #3A5CA0;
  --accent-fill-deep: #1B2F59;
  --fa-gold-ink: #F2DAAA;        --fa-gold-tint: #3E3421;
  --fa-cobalt-ink: #89A2D5;      --fa-cobalt-tint: #263045;
  --fa-amethyst-ink: #AB95E9;    --fa-amethyst-tint: #342B4D;
  --fa-emerald-ink: #79B791;     --fa-emerald-tint: #1E3527;
  --fa-cyan-ink: #C78ECB;        --fa-cyan-tint: #3F2841;
  --fa-rose-ink: #D98BA5;        --fa-rose-tint: #462732;
  --fa-graphite-ink: #99A2B6;    --fa-graphite-tint: #2A2D34;
  --wash-alpha: 0.17;
  --wash-alpha-strong: 0.30;
  --success: #3FB98A;
  --hairline: rgba(255, 255, 255, 0.10);
  --hairline-strong: rgba(255, 255, 255, 0.18);
  --divider: rgba(255, 255, 255, 0.12);
  --chrome: rgba(11, 12, 16, 0.80);
  --chrome-solid: #0B0C10;
  --shadow-card: 0 1px 2px rgba(0, 0, 0, 0.55), 0 12px 30px -16px rgba(0, 0, 0, 0.85);
  --shadow-lift: 0 2px 6px rgba(0, 0, 0, 0.6), 0 26px 54px -20px rgba(0, 0, 0, 0.9);
  --shadow-door: 0 10px 28px -12px rgba(58, 92, 160, 0.65);
  --crest: linear-gradient(160deg, #23232A 0%, var(--card-mid) 48%, var(--card-deep) 100%);
  --instrument: #16161B;
  --instrument-deep: #08080B;
  --instrument-stroke: rgba(255, 255, 255, 0.09);
  --orb-opacity: 0.18;
  color-scheme: dark;
}

/* =========================================================================
   2 · RESET & BASE
   ========================================================================= */

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

html {
  font-size: 16px;
  scroll-behavior: smooth;
  overflow-x: clip;
  scroll-padding-top: 96px;
  background: var(--page-bottom);
  -webkit-text-size-adjust: 100%;
}

body {
  font-family: var(--font-body);
  color: var(--ink);
  /* ☠️ The page gradient lives on the fixed `.ambient-bg` layer, NOT here with
     `background-attachment: fixed`. On a long page that attachment makes the
     background a full-document paint on every scroll — measurably janky, and
     it made Chrome fail to rasterise this page at all past ~3,000 px. A solid
     stop stays here so the page is never transparent while that layer paints. */
  background: var(--page-bottom);
  line-height: 1.62;
  letter-spacing: -0.003em;
  overflow-x: clip;
  padding-top: 74px;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

body.mobile-menu-active { overflow: hidden; }

img, video, svg { max-width: 100%; display: block; }
img { height: auto; }

a { color: var(--accent-ink); text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 3px; }

:where(a, button, input, textarea, select, summary, label[role="button"]):focus-visible {
  outline: 2.5px solid var(--accent-fill);
  outline-offset: 3px;
  border-radius: 6px;
}

::selection { background: color-mix(in srgb, var(--accent-glow) 40%, transparent); color: var(--ink); }

.skip-link {
  position: absolute;
  left: 50%;
  top: 0;
  transform: translate(-50%, -120%);
  z-index: 300;
  background: var(--accent-fill);
  color: var(--on-accent);
  padding: 0.7rem 1.3rem;
  border-radius: 0 0 var(--radius) var(--radius);
  font-weight: 600;
  font-size: 0.92rem;
  transition: transform 0.2s var(--ease);
}
.skip-link:focus { transform: translate(-50%, 0); text-decoration: none; }

/* -------- Typography scale -------- */
h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 800;
  line-height: 1.08;
  letter-spacing: -0.028em;
  color: var(--ink);
  text-wrap: balance;
}
h3, h4 { font-weight: 700; letter-spacing: -0.02em; line-height: 1.25; }

p { text-wrap: pretty; }

code, kbd, samp {
  font-family: var(--font-mono);
  font-size: 0.88em;
  background: var(--well);
  padding: 0.12em 0.42em;
  border-radius: 6px;
  color: var(--ink);
}

/* =========================================================================
   3 · AMBIENT — the mesh behind the glass
   ☠️ Light in the room, never a surface. Two cool sources at low alpha are
   what stop a warm-neutral page reading as one tinted wash, which is the
   verdict this identity has already taken once ("monotone").
   ========================================================================= */

.ambient-bg {
  position: fixed;
  inset: 0;
  z-index: -2;
  overflow: hidden;
  pointer-events: none;
  background: linear-gradient(180deg, var(--page-top) 0%, var(--page-top) 22%, var(--page-bottom) 100%);
}

.orb {
  position: absolute;
  border-radius: 50%;
  filter: blur(120px);
  opacity: var(--orb-opacity);
  will-change: transform;
}
.orb-1 { width: 46vw; height: 46vw; min-width: 380px; min-height: 380px; top: -12vw; left: -8vw;  background: var(--orb-azure); }
.orb-2 { width: 40vw; height: 40vw; min-width: 320px; min-height: 320px; top: 42vh;  right: -10vw; background: var(--orb-violet); }
.orb-3 { width: 32vw; height: 32vw; min-width: 260px; min-height: 260px; top: 118vh; left: 18vw;  background: var(--orb-warm); opacity: calc(var(--orb-opacity) * 0.75); }

/* A whisper of grain, so a large flat field of near-white does not band. */
.noise-overlay {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: 0.22;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='0.30'/%3E%3C/svg%3E");
}

/* =========================================================================
   4 · LAYOUT
   ========================================================================= */

.container {
  width: min(1180px, 100% - var(--gutter) * 2);
  margin-inline: auto;
}

main > section { margin-top: var(--section-gap); }
main > section:first-child { margin-top: 0; }

.section-title-wrap {
  max-width: 720px;
  margin: 0 auto clamp(2.2rem, 4vw, 3.2rem);
  text-align: center;
}
.section-title { font-size: clamp(1.9rem, 4.4vw, 2.9rem); }
.section-subtitle {
  margin-top: 0.9rem;
  color: var(--ink-2);
  font-size: clamp(1rem, 1.6vw, 1.11rem);
  line-height: 1.6;
}

/* A kicker. Uppercase, tracked, in the interface tint — the app's own
   `Text(...).kicker()`, which is how a section names itself without a rule. */
.preview-eyebrow,
.promise-eyebrow,
.kicker {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--font-body);
  font-size: 0.735rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent-ink);
}

/* =========================================================================
   5 · SURFACES — the card, the well, the instrument
   ========================================================================= */

.glass-card,
.measure-card,
.persona-card,
.price-card,
.lab-card,
.faq-item,
.contact-card,
.receipt-card,
.promise-band,
.specs-table,
.policy-body {
  background: var(--crest);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
}

.glass-card {
  padding: clamp(1.5rem, 2.6vw, 2rem);
  transition: transform 0.35s var(--ease-out), box-shadow 0.35s var(--ease-out);
}

/* A recessed well — the thing you read *off*, not the thing that rises. */
.well {
  background: var(--well);
  border-radius: var(--radius);
  border: 1px solid var(--hairline);
}

/* ☠️ A fixed-dark instrument stage. Anything that DRAWS a measurement lives
   here, in both appearances, so its luminous ink is graded against one
   calibrated ground instead of two. Never use it for prose. */
.instrument {
  background: linear-gradient(165deg, var(--instrument) 0%, var(--instrument-deep) 100%);
  border: 1px solid var(--instrument-stroke);
  border-radius: var(--radius-lg);
  color: var(--instrument-ink);
  overflow: hidden;
}
.instrument .instrument-label {
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--instrument-ink-2);
}

/* -------- The glyph well: the whole colour grammar, in one rule --------
   A 44 px rounded square carrying the destination's core at 13 % alpha, with
   the glyph itself in that destination's ink. This is what "accents, not
   backgrounds" means in practice, and it is the only place hue is allowed on
   a card. */
.card-icon,
.glyph {
  --glyph: var(--fa-cobalt);
  --glyph-ink: var(--fa-cobalt-ink);
  --glyph-tint: var(--fa-cobalt-tint);
  display: inline-grid;
  place-items: center;
  width: 44px;
  height: 44px;
  flex: 0 0 44px;
  border-radius: 13px;
  background: var(--glyph-tint, color-mix(in srgb, var(--glyph) calc(var(--wash-alpha) * 100%), transparent));
  color: var(--glyph-ink);
  margin-bottom: 1.05rem;
}
.glyph { margin-bottom: 0; }
.card-icon svg, .glyph svg { width: 22px; height: 22px; }

.a-gold     { --glyph: var(--fa-gold);     --glyph-ink: var(--fa-gold-ink);     --glyph-tint: var(--fa-gold-tint); }
.a-cobalt   { --glyph: var(--fa-cobalt);   --glyph-ink: var(--fa-cobalt-ink);   --glyph-tint: var(--fa-cobalt-tint); }
.a-amethyst { --glyph: var(--fa-amethyst); --glyph-ink: var(--fa-amethyst-ink); --glyph-tint: var(--fa-amethyst-tint); }
.a-emerald  { --glyph: var(--fa-emerald);  --glyph-ink: var(--fa-emerald-ink);  --glyph-tint: var(--fa-emerald-tint); }
.a-cyan     { --glyph: var(--fa-cyan);     --glyph-ink: var(--fa-cyan-ink);     --glyph-tint: var(--fa-cyan-tint); }
.a-rose     { --glyph: var(--fa-rose);     --glyph-ink: var(--fa-rose-ink);     --glyph-tint: var(--fa-rose-tint); }
.a-graphite { --glyph: var(--fa-graphite); --glyph-ink: var(--fa-graphite-ink); --glyph-tint: var(--fa-graphite-tint); }

.card-title {
  font-family: var(--font-display);
  font-size: 1.16rem;
  font-weight: 700;
  letter-spacing: -0.018em;
  line-height: 1.28;
  margin-bottom: 0.6rem;
}
.card-desc { color: var(--ink-2); font-size: 0.965rem; line-height: 1.66; }

/* =========================================================================
   6 · HEADER, NAV, THEME TOGGLE
   ========================================================================= */

header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 120;
  border-bottom: 1px solid transparent;
  transition: border-color 0.3s var(--ease);
}
/* ☠️ The blur lives on a pseudo-element, NOT on `header` itself.
   `backdrop-filter` makes an element a CONTAINING BLOCK for every
   `position: fixed` descendant — so with it on the header, the nav drawer
   (which is `top: 0; bottom: 0`) resolved against a 74 px bar instead of the
   viewport and opened as a 128 px stub with one link in it. The same trap
   applies to `transform`, `filter` and `perspective`: do not put any of them
   on an ancestor of the drawer. */
header::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--chrome);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  transition: background 0.3s var(--ease);
}
/* ☠️ One hairline and nothing else. Every reference in the set draws a solid
   bar with a single rule across it; a second layer of glass double-blurs. */
header.scrolled { border-bottom-color: var(--divider); }

/* Scroll progress, drawn as the header's own bottom edge. `--scroll-progress`
   is a 0–1 number set on <html> by app.js' one rAF-throttled scroll listener —
   the same value drives the back-to-top ring. `transform` and not `width`, so
   the paint never re-lays-out the bar. */
header::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 2px;
  background: linear-gradient(90deg, var(--accent-fill), var(--fa-amethyst));
  transform: scaleX(var(--scroll-progress, 0));
  transform-origin: 0 50%;
  opacity: 0;
  transition: opacity 0.3s var(--ease);
  pointer-events: none;
}
header.scrolled::after { opacity: 1; }

.nav-container {
  width: min(1180px, 100% - var(--gutter) * 2);
  margin-inline: auto;
  height: 74px;
  display: flex;
  align-items: center;
  gap: 1rem;
}
/* Source order is logo → toggle → hamburger → nav so that the drawer's markup
   sits last; the visual order is set here instead, which keeps the appearance
   switch beside the menu button on a phone and after the links on a desktop. */
.logo { order: 1; }
nav { order: 2; }
.theme-toggle { order: 3; }
.nav-btn-download { order: 4; }
.hamburger { order: 5; }

.nav-btn-download {
  display: inline-flex;
  min-height: 38px;
  padding: 0.42rem 1.15rem;
  font-size: 0.88rem;
  font-weight: 650;
  border-radius: 999px;
}
/* ☠️ `.nav-container` is load-bearing, not tidiness. This element is
   `class="nav-btn-download btn btn-primary"`, and `.btn { display: inline-flex }`
   is declared in §7 — LATER in this file, at the same (0,1,0) specificity — so a
   bare `.nav-btn-download { display: none }` here loses the cascade and the
   button stayed on screen at every phone width. It cost the wordmark: at 390 px
   the logo had 107 px for 141 px of "Articulance" and the header read
   "Articulan". Measured, not guessed. Anything that hides a `.btn` from a rule
   placed above §7 needs the extra class. */
@media (max-width: 900px) {
  .nav-container .nav-btn-download { display: none; }
}

.logo {
  display: inline-flex;
  align-items: center;
  gap: 0.65rem;
  font-family: var(--font-display);
  font-size: 1.16rem;
  font-weight: 800;
  letter-spacing: -0.024em;
  color: var(--ink);
  margin-right: auto;
}
.logo:hover { text-decoration: none; }
.logo-icon { width: 34px; height: 34px; border-radius: 8.5px; }

nav ul {
  display: flex;
  align-items: center;
  gap: 0.15rem;
  list-style: none;
}
nav ul a {
  display: block;
  padding: 0.46rem 0.72rem;
  border-radius: 9px;
  font-size: 0.915rem;
  font-weight: 500;
  color: var(--ink-2);
  transition: color 0.2s, background 0.2s;
}
nav ul a:hover { color: var(--ink); background: var(--well); text-decoration: none; }
/* ☠️ Match ANY `aria-current`, not just "page". The markup ships
   `aria-current="page"` on Home and the scrollspy sets `aria-current="true"`
   on the section links — so a rule pinned to "page" styled the one value the
   script never writes, and the highlight sat on Home for the whole scroll
   while the spy ran correctly and invisibly underneath it. */
nav ul a[aria-current] { color: var(--accent-ink); font-weight: 600; }

.nav-drawer-header,
.nav-drawer-section,
.nav-drawer-footer { display: none; }

.theme-toggle {
  display: inline-grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: 11px;
  border: 1px solid var(--hairline);
  background: var(--card);
  color: var(--ink-2);
  cursor: pointer;
  transition: color 0.2s, border-color 0.2s, transform 0.2s var(--ease);
}
.theme-toggle:hover { color: var(--accent-ink); border-color: var(--hairline-strong); }
.theme-toggle:active { transform: scale(0.94); }
.theme-toggle svg { width: 18px; height: 18px; }
.theme-toggle .icon-moon { display: none; }
:root[data-theme="dark"] .theme-toggle .icon-moon { display: block; }
:root[data-theme="dark"] .theme-toggle .icon-sun { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-toggle .icon-moon { display: block; }
  :root:not([data-theme="light"]) .theme-toggle .icon-sun { display: none; }
}

.hamburger {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 40px;
  height: 40px;
  padding: 0 8px;
  border: 0;
  background: none;
  cursor: pointer;
  position: relative;
  z-index: 140;
}
.hamburger span {
  display: block;
  height: 2px;
  border-radius: 2px;
  background: var(--ink);
  transition: transform 0.28s var(--ease), opacity 0.2s;
}
.hamburger.active span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.hamburger.active span:nth-child(2) { opacity: 0; }
.hamburger.active span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

.nav-overlay {
  position: fixed;
  inset: 0;
  z-index: 110;
  background: rgba(15, 23, 42, 0.42);
  -webkit-backdrop-filter: blur(3px);
  backdrop-filter: blur(3px);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.3s var(--ease), visibility 0.3s;
}
.nav-overlay.active { opacity: 1; visibility: visible; }

@media (max-width: 900px) {
  .hamburger { display: flex; }
  nav {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    width: min(340px, 86vw);
    z-index: 130;
    background: var(--chrome-solid);
    border-left: 1px solid var(--divider);
    padding: 85px 1.4rem 2.2rem;
    transform: translateX(100%);
    transition: transform 0.34s var(--ease-out);
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
  }
  nav.active { transform: translateX(0); }
  nav ul { flex-direction: column; align-items: stretch; gap: 0.12rem; }
  nav ul a { padding: 0.72rem 0.8rem; font-size: 1rem; border-radius: var(--radius-sm); }

  .nav-drawer-header,
  .nav-drawer-section {
    display: block;
  }
  .nav-drawer-title {
    display: block;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ink-3);
    padding: 0.5rem 0.8rem 0.3rem;
  }
  .nav-drawer-section {
    margin-top: 0.8rem;
    padding-top: 0.8rem;
    border-top: 1px solid var(--divider);
  }
  .nav-secondary-list {
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 0.12rem;
  }
  .nav-secondary-list a {
    display: block;
    padding: 0.65rem 0.8rem;
    font-size: 0.94rem;
    color: var(--ink-2);
    border-radius: var(--radius-sm);
    transition: color 0.2s, background 0.2s;
  }
  .nav-secondary-list a:hover {
    color: var(--ink);
    background: var(--well);
    text-decoration: none;
  }

  .nav-drawer-footer {
    display: block;
    margin-top: auto;
    padding-top: 1.4rem;
    border-top: 1px solid var(--divider);
  }
  .nav-drawer-cta {
    display: block;
    padding: 0.84rem 1rem;
    text-align: center;
    font-weight: 650;
    font-size: 0.94rem;
    color: var(--on-accent);
    background: linear-gradient(175deg, #4468B0 0%, var(--accent-fill) 55%, var(--accent-fill-deep) 130%);
    border: 1px solid rgba(255, 255, 255, 0.22);
    border-radius: 999px;
    box-shadow: var(--shadow-door);
  }
  .nav-drawer-cta:hover { text-decoration: none; }
}

/* =========================================================================
   7 · BUTTONS — a door, and everything that is not one
   ========================================================================= */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  padding: 0.92rem 1.6rem;
  min-height: 52px;
  border: 1px solid transparent;
  border-radius: 999px;
  font-family: var(--font-body);
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  cursor: pointer;
  /* ☠️ Scale, not opacity. A control that fades under the thumb reads as
     disabling itself. */
  transition: transform 0.18s var(--ease), box-shadow 0.25s var(--ease),
              background 0.25s, border-color 0.25s, color 0.25s;
}
.btn:hover { text-decoration: none; }
.btn:active { transform: scale(0.975); }

/* A DOOR. The only kind of object that earns a full accent ground. */
.btn-primary {
  background: linear-gradient(175deg, #4468B0 0%, var(--accent-fill) 55%, var(--accent-fill-deep) 130%);
  color: var(--on-accent);
  box-shadow: var(--shadow-door);
  border: 1px solid rgba(255, 255, 255, 0.22);
  position: relative;
  overflow: hidden;
}
/* A light crossing the door once, on hover. `--sheen` because the door inside
   `.banner` is white and needs a dark sweep — see the override there. */
.btn-primary::after {
  content: "";
  position: absolute;
  inset: -1px;
  background: linear-gradient(105deg, transparent 38%, var(--sheen) 50%, transparent 62%);
  transform: translateX(-145%);
  transition: transform 0.75s var(--ease-out);
  pointer-events: none;
}
.btn-primary:hover::after { transform: translateX(145%); }
.btn-primary:hover {
  background: linear-gradient(175deg, #4C72BD 0%, #3D62AA 55%, #1B3260 130%);
  box-shadow: 0 14px 34px -10px rgba(58, 92, 160, 0.58);
}

/* The little round play badge on the hero's secondary door. */
.btn-play {
  display: inline-grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--accent-fill) 13%, transparent);
  color: var(--accent-ink);
  transition: background 0.25s, color 0.25s;
}
.btn-secondary:hover .btn-play { background: var(--accent-fill); color: var(--on-accent); }

.btn-secondary {
  background: var(--card);
  color: var(--ink);
  border-color: var(--hairline-strong);
  box-shadow: var(--shadow-card);
}
.btn-secondary:hover { border-color: var(--accent-ink); color: var(--accent-ink); }

.btn-group { display: flex; flex-wrap: wrap; gap: 0.85rem; }

.mini-link {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-weight: 600;
  font-size: 0.94rem;
  color: var(--accent-ink);
}

/* =========================================================================
   8 · HERO
   ========================================================================= */

.hero {
  display: grid;
  grid-template-columns: minmax(0, 1.22fr) minmax(0, 0.78fr);
  gap: clamp(2rem, 4vw, 3.4rem);
  align-items: center;
  padding-top: clamp(2.6rem, 6vw, 4.6rem);
}

.badge {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.42rem 0.95rem 0.42rem 0.7rem;
  border-radius: 999px;
  background: var(--card);
  border: 1px solid var(--hairline);
  box-shadow: var(--shadow-card);
  font-size: 0.83rem;
  font-weight: 550;
  color: var(--ink-2);
}
.badge-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--success);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--success) 20%, transparent);
}

.hero-title {
  margin-top: 1.35rem;
  font-size: clamp(2.35rem, 5vw, 3.55rem);
  line-height: 1.04;
  letter-spacing: -0.038em;
}
.hero-title span { color: var(--accent-ink); }
/* The headline's accent becomes a two-ink gradient. Wrapped in @supports so a
   browser without background-clip:text keeps the flat accent ink rather than
   `color: transparent` — the failure mode of the unguarded version is an
   invisible headline. */
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .hero-title .ink-gradient {
    background-image: linear-gradient(
      100deg,
      var(--accent-ink) 0%,
      color-mix(in srgb, var(--fa-amethyst-ink) 68%, var(--accent-ink)) 100%
    );
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    -webkit-text-fill-color: transparent;
  }
}

.hero-description {
  margin-top: 1.35rem;
  max-width: 56ch;
  font-size: clamp(1.03rem, 1.7vw, 1.17rem);
  line-height: 1.66;
  color: var(--ink-2);
}

.btn-group.animate-up { margin-top: 2rem; }

/* What the purchase actually guarantees, as chips — the app's own three
   claims, and one platform fact, each with a glyph. Replaces a run-on
   sentence that read as fine print under the buttons. */
.hero-trust {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 0.55rem;
  margin-top: 1.5rem;
  list-style: none;
}
.hero-trust li {
  display: inline-flex;
  align-items: center;
  gap: 0.42rem;
  padding: 0.4rem 0.82rem;
  border-radius: 999px;
  background: var(--card);
  border: 1px solid var(--hairline);
  box-shadow: var(--shadow-card);
  font-size: 0.82rem;
  font-weight: 550;
  color: var(--ink-2);
}
.hero-trust svg { width: 15px; height: 15px; flex: none; color: var(--accent-ink); }

.hero-screens-link { margin-top: 1.15rem; font-size: 0.93rem; }
.hero-screens-link a { display: inline-flex; align-items: center; gap: 0.35rem; font-weight: 600; }
.hero-screens-link a span { transition: transform 0.25s var(--ease); }
.hero-screens-link a:hover span { transform: translateX(3px); }

/* -------- The device -------- */
.hero-visual {
  position: relative;
  display: grid;
  place-items: center;
  min-height: 520px;
}

/* A soft cobalt light behind the phone. Pseudo-element and `filter: blur`, not
   a box-shadow: a shadow on a transparent-asset container would draw a
   rectangle. The rings and the device paint after it in DOM order. */
.hero-visual::before {
  content: "";
  position: absolute;
  width: min(560px, 88vw);
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(
    circle,
    color-mix(in srgb, var(--accent-glow) 30%, transparent) 0%,
    transparent 64%
  );
  filter: blur(28px);
  pointer-events: none;
}

/* Concentric rings — the app's own resting record halo, not decoration for
   its own sake: it is the one shape the product opens on. */
.td-rings { position: absolute; inset: 0; display: grid; place-items: center; pointer-events: none; }
.td-ring {
  position: absolute;
  border-radius: 50%;
  border: 1px solid var(--hairline-strong);
  opacity: 0.5;
}
.td-ring:nth-child(1) { width: 330px; height: 330px; }
.td-ring:nth-child(2) { width: 450px; height: 450px; opacity: 0.32; }
.td-ring:nth-child(3) { width: 570px; height: 570px; opacity: 0.18; }

/* ☠️ The bezel is IN the asset — this element draws no device of its own.
   It used to: a rounded rectangle with a border, a card background and a
   box-shadow, with the screenshot cropped into it by `object-fit: cover`. That
   is a phone nobody makes — no button, no antenna line, no camera, and a corner
   radius picked by eye — and the crop quietly ate the bottom of every capture.
   Adding a border or a background back here puts a fake bezel around a real one.

   ⚠️ The width grew 288 -> 312 px because the frame is wider than the screen it
   holds (1320 of 1428 px, 92.4 %). At the old width the *screen* would have
   rendered smaller than it did before, which reads as the site shrinking its own
   screenshots to make room for decoration. 312 x 0.924 = 288: the app is exactly
   the size it always was, and the device is new around it.

   `filter: drop-shadow` and not `box-shadow`, because the asset is transparent
   outside the device: drop-shadow follows the silhouette, including the rounded
   corners and the button nubs, where box-shadow would draw a rectangle. */
.td-hero-device {
  position: relative;
  width: min(312px, 78vw);
  aspect-ratio: 1428 / 2959;
  filter: drop-shadow(0 24px 38px rgba(15, 23, 42, 0.22))
          drop-shadow(0 5px 11px rgba(15, 23, 42, 0.14));
}
/* ☠️ The arriving frame rises OVER a still-opaque outgoing one, and the outgoing
   only snaps away once it has finished. The obvious crossfade — and the one this
   element used to run — takes the leaving frame to zero BEFORE the arriving one
   starts. That was correct while an opaque card sat behind the stack: the dead
   window in the middle showed a blank phone. Against a transparent framed asset
   there is nothing behind, so the same 380 ms window deleted the whole device
   and left a hole in the page with the shadow still under it.

   ⚠️ A plain overlapping crossfade does not fix it either. Two layers at 50 %
   compose to 75 % alpha, not 100 %, so the device would still go momentarily
   see-through. Holding the bottom layer fully opaque is what keeps the silhouette
   solid — which also keeps `drop-shadow` on the parent from pulsing.

   ⚠️ And the 1.012 scale is gone. Two identical bezels crossfading at slightly
   different scales double every edge; on a bare screenshot nobody could see it,
   on a photographed device it reads as a focus problem. */
.placeholder-device {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: top center;
  opacity: 0;
  z-index: 1;
  /* leaving: hold, then snap once the arriving frame is fully there */
  transition: opacity 0s linear 0.55s;
}
.placeholder-device.active {
  opacity: 1;
  z-index: 2;
  transition: opacity 0.55s var(--ease);
}

:root[data-theme="dark"] .td-hero-device {
  filter: drop-shadow(0 20px 30px rgba(0, 0, 0, 0.62))
          drop-shadow(0 4px 9px rgba(0, 0, 0, 0.5));
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .td-hero-device {
    filter: drop-shadow(0 20px 30px rgba(0, 0, 0, 0.62))
            drop-shadow(0 4px 9px rgba(0, 0, 0, 0.5));
  }
}

/* -------- The two floating callouts --------
   UI from the shipping app, echoed in full by the receipt section and the
   gallery. Decorative (aria-hidden) and never the only place a claim lives.
   Hidden below 1160 px: at tablet widths they would overlap the device. */
.hero-float {
  position: absolute;
  z-index: 3;
  display: flex;
  flex-direction: column;
  gap: 0.32rem;
  padding: 0.8rem 0.9rem;
  border-radius: var(--radius);
  background: var(--crest);
  border: 1px solid var(--hairline);
  box-shadow: var(--shadow-float);
  animation: floaty 5.5s ease-in-out infinite alternate;
}
.hero-float--receipt {
  top: 9%;
  right: max(-8px, -1vw);
  width: min(228px, 62%);
  animation-delay: -1.6s;
}
.hero-float--metric {
  bottom: 12%;
  left: max(-10px, -1.4vw);
  width: 162px;
}
.hero-float-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.665rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--accent-ink);
}
.hero-float-title {
  font-family: var(--font-display);
  font-size: 0.9rem;
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: -0.015em;
}
.hero-float-meta { display: inline-flex; align-items: center; gap: 0.4rem; }
.hero-float-play {
  display: inline-grid;
  place-items: center;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--accent-fill);
  color: var(--on-accent);
  flex: none;
}
.hero-float-time { font-family: var(--font-mono); font-size: 0.74rem; color: var(--ink-2); }
.hero-float-label {
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-2);
}
.hero-float-value {
  font-family: var(--font-display);
  font-size: 1.75rem;
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.hero-float-value span {
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0;
  color: var(--ink-2);
  margin-left: 0.22rem;
}
.hero-float-meta--quiet { font-size: 0.72rem; color: var(--ink-2); }
@keyframes floaty {
  from { transform: translateY(-5px); }
  to { transform: translateY(6px); }
}
@media (max-width: 1160px) { .hero-float { display: none; } }

@media (max-width: 900px) {
  .hero { grid-template-columns: 1fr; text-align: center; }
  .hero-description { margin-inline: auto; }
  .btn-group.animate-up { justify-content: center; }
  .hero-trust { justify-content: center; }
  .hero-visual { min-height: 480px; }
  .td-ring:nth-child(3) { display: none; }
}

/* =========================================================================
   9 · THE PROMISE BAND
   ========================================================================= */

.promise-band {
  padding: clamp(2.1rem, 4.4vw, 3.4rem);
  text-align: center;
}
.promise-title {
  margin-top: 1rem;
  font-size: clamp(1.6rem, 3.6vw, 2.4rem);
  line-height: 1.16;
}
.promise-title span { color: var(--accent-ink); }
.promise-desc {
  margin: 1.15rem auto 0;
  max-width: 68ch;
  color: var(--ink-2);
  font-size: 1.005rem;
}
.promise-list {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.6rem;
  margin-top: 1.7rem;
  list-style: none;
}
.promise-list li {
  padding: 0.42rem 0.95rem;
  border-radius: 999px;
  background: var(--well);
  border: 1px solid var(--hairline);
  font-size: 0.865rem;
  font-weight: 550;
  color: var(--ink-2);
}

/* =========================================================================
   10 · THE DELIVERY STRIP — one rehearsal, drawn the way the app draws it
   ☠️ This replaced a row of twelve bouncing bars. A decorative equaliser on
   the site of an app whose whole argument is *it only draws what it measured*
   is the one piece of ornament this product cannot afford: it looks like a
   measurement and is not one. What is here instead is the real grammar —
   pitch columns over a speech rail whose gaps are pauses, findings marked
   beneath — captioned so it reads as an explanation of the drawing rather
   than a claim about anybody's voice. The shape is a fixed function of the
   column index, never random, so it is the same drawing in every build.
   ========================================================================= */

.strip-header {
  text-align: center;
  margin-bottom: 1.1rem;
}

.strip-stage {
  padding: 1.5rem clamp(1rem, 3vw, 2rem) 1.25rem;
  border-radius: var(--radius-lg);
  background: linear-gradient(165deg, var(--instrument) 0%, var(--instrument-deep) 100%);
  border: 1px solid var(--instrument-stroke);
  overflow: hidden;
}

.strip-cols {
  display: flex;
  align-items: flex-end;
  gap: clamp(2px, 0.45vw, 5px);
  height: clamp(70px, 9vw, 108px);
}
.strip-cols span {
  flex: 1 1 0;
  min-width: 2px;
  height: calc(var(--h, 0.3) * 100%);
  border-radius: 2px 2px 0 0;
  background: linear-gradient(180deg, var(--fa-cobalt-glow) 0%, var(--fa-cobalt) 100%);
  opacity: 0.92;
  cursor: pointer;
  transition: transform 0.15s var(--ease), background 0.15s;
}
.strip-cols span:hover {
  transform: scaleY(1.08);
  background: linear-gradient(180deg, #FFFFFF 0%, var(--fa-cobalt-glow) 100%);
}
/* A pause is drawn as nothing, because nothing was measured there. */
.strip-cols span.silent { height: 2px; background: var(--instrument-grid); border-radius: 1px; }

.strip-rail { position: relative; height: 3px; margin-top: 9px; }
.strip-rail i {
  position: absolute;
  top: 0;
  left: var(--a);
  right: calc(100% - var(--b));
  height: 3px;
  border-radius: 2px;
  background: var(--fa-graphite-glow);
  opacity: 0.8;
}

.strip-marks { position: relative; height: 12px; margin-top: 7px; }
.strip-marks b {
  position: absolute;
  left: var(--x);
  width: 3px;
  height: 12px;
  border-radius: 2px;
  transform: translateX(-1.5px);
}
.strip-marks .m-gold     { background: var(--fa-gold-glow); }
.strip-marks .m-amethyst { background: var(--fa-amethyst-glow); }
.strip-marks .m-cyan     { background: var(--fa-cyan-glow); }
.strip-marks .m-rose     { background: var(--fa-rose-glow); }
.strip-marks .m-emerald  { background: var(--fa-emerald-glow); }

.strip-hover-info {
  margin-top: 0.9rem;
  padding: 0.45rem 0.8rem;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid var(--instrument-stroke);
  color: var(--instrument-ink-2);
  font-size: 0.82rem;
  font-family: var(--font-mono);
  text-align: center;
  transition: color 0.2s, border-color 0.2s, background 0.2s;
}
.strip-hover-info.active-info {
  color: var(--instrument-ink);
  background: rgba(91, 155, 255, 0.12);
  border-color: rgba(91, 155, 255, 0.35);
}

.strip-legend {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem clamp(1rem, 3vw, 2rem);
  margin-top: 1.05rem;
  font-size: 0.86rem;
  color: var(--ink-2);
}
.strip-legend span { display: inline-flex; align-items: center; gap: 0.45rem; }
.strip-legend b { color: var(--ink); font-weight: 650; }
.strip-legend em { display: inline-block; border-radius: 2px; flex: none; }
.strip-legend .k-col  { width: 3px;  height: 13px; background: var(--fa-cobalt); }
.strip-legend .k-rail { width: 15px; height: 3px;  background: var(--fa-graphite); }
.strip-legend .k-mark { width: 3px;  height: 13px; background: var(--fa-rose); }

/* =========================================================================
   11 · PIPELINE
   ========================================================================= */

.pipeline-flow {
  display: flex;
  align-items: flex-start;
  justify-content: center;
  gap: clamp(0.5rem, 2.4vw, 2rem);
  flex-wrap: wrap;
}
.pipe-stage {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.55rem;
  width: min(230px, 40vw);
  text-align: center;
  opacity: 0.42;
  transform: translateY(8px);
  transition: opacity 0.6s var(--ease), transform 0.6s var(--ease-out);
}
.pipe-stage.active { opacity: 1; transform: none; }

.pipe-dot {
  display: grid;
  place-items: center;
  width: 68px;
  height: 68px;
  border-radius: 21px;
  background: var(--crest);
  border: 1px solid var(--hairline);
  box-shadow: var(--shadow-card);
  color: var(--fa-cobalt-ink);
}
.pipe-dot svg { width: 28px; height: 28px; fill: none; stroke: currentColor; stroke-width: 1.7; }
.pipe-dot.gold      { color: var(--fa-cobalt-ink); }
.pipe-dot.champagne { color: var(--fa-emerald-ink); }
.pipe-dot.white     { color: var(--fa-amethyst-ink); }

.pipe-label {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.04rem;
  letter-spacing: -0.016em;
}
.pipe-sublabel { color: var(--ink-2); font-size: 0.845rem; line-height: 1.45; }

.pipe-arrow {
  align-self: center;
  margin-top: 12px;
  font-size: 1.35rem;
  color: var(--hairline-strong);
  opacity: 0;
  transform: translateX(-6px);
  transition: opacity 0.5s var(--ease), transform 0.5s var(--ease-out), color 0.5s;
}
.pipe-arrow.lit { opacity: 1; transform: none; color: var(--accent-ink); }
@media (max-width: 860px) {
  .pipeline-flow { flex-direction: column; align-items: center; gap: 0.5rem; }
  .pipe-stage { width: min(320px, 100%); }
  .pipe-arrow { margin: 0; transform: rotate(90deg) translateX(-6px); }
  .pipe-arrow.lit { transform: rotate(90deg); }
}

/* =========================================================================
   12 · BENTO GRID
   ========================================================================= */

.bento-grid {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: clamp(0.9rem, 1.8vw, 1.35rem);
}
.bento-4 { grid-column: span 4; }
.bento-6 { grid-column: span 6; }
.bento-8 { grid-column: span 8; }
@media (max-width: 1000px) { .bento-4, .bento-6, .bento-8 { grid-column: span 6; } }
@media (max-width: 700px)  { .bento-4, .bento-6, .bento-8 { grid-column: span 12; } }

.flex-card-content {
  display: flex;
  align-items: center;
  gap: clamp(1.2rem, 3vw, 2.2rem);
}
.flex-card-text { flex: 1 1 55%; min-width: 0; }
.flex-card-visual { flex: 0 1 42%; min-width: 0; }
@media (max-width: 780px) {
  .flex-card-content { flex-direction: column; align-items: stretch; }
  .flex-card-visual { order: 2; }
}

.pro-tag {
  display: inline-block;
  font-size: 0.65rem;
  font-weight: 750;
  letter-spacing: 0.06em;
  padding: 0.16rem 0.48rem;
  border-radius: 6px;
  background: var(--accent-fill);
  color: var(--on-accent);
  vertical-align: middle;
  margin-left: 0.4rem;
}
.mini-pro {
  display: inline-block;
  font-size: 0.6rem;
  font-weight: 750;
  padding: 0.1rem 0.38rem;
  border-radius: 4px;
  background: var(--accent-fill);
  color: var(--on-accent);
  margin-left: 0.35rem;
  letter-spacing: 0.04em;
}

/* A miniature instrument stage inside a bento card. */
.card-stage {
  display: grid;
  place-items: center;
  padding: 1.1rem;
  border-radius: var(--radius);
  background: linear-gradient(165deg, var(--instrument) 0%, var(--instrument-deep) 100%);
  border: 1px solid var(--instrument-stroke);
}

/* =========================================================================
   13 · THE RECEIPT (INTERACTIVE)
   ========================================================================= */

.receipt-section { }
.receipt-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.92fr);
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
}
@media (max-width: 900px) { .receipt-layout { grid-template-columns: 1fr; } }

.receipt-heading {
  margin: 1rem 0 1.3rem;
  font-size: clamp(1.9rem, 4.2vw, 2.85rem);
}
.text-accent { color: var(--accent-ink); }
.receipt-copy p { color: var(--ink-2); margin-bottom: 1rem; max-width: 58ch; }
.receipt-copy p:last-child { margin-bottom: 0; }

.receipt-card {
  position: relative;
  padding: 1.5rem 1.5rem 1.35rem;
  overflow: hidden;
}
.receipt-card::before {
  content: "";
  position: absolute;
  inset: 14px auto 14px 0;
  width: 4px;
  border-radius: 0 3px 3px 0;
  background: var(--fa-amethyst);
}

.receipt-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.3rem 0.72rem;
  border-radius: 999px;
  background: color-mix(in srgb, var(--fa-cobalt) calc(var(--wash-alpha) * 100%), transparent);
  color: var(--fa-cobalt-ink);
  font-size: 0.755rem;
  font-weight: 700;
  letter-spacing: 0.04em;
}

.receipt-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  margin: 0.95rem 0 0.55rem;
}
.receipt-title {
  font-family: var(--font-display);
  font-size: 1.1rem;
  font-weight: 700;
  letter-spacing: -0.016em;
  line-height: 1.3;
}
.receipt-time {
  flex: none;
  font-family: var(--font-mono);
  font-size: 0.82rem;
  font-variant-numeric: tabular-nums;
  padding: 0.24rem 0.55rem;
  border-radius: 8px;
  background: var(--well);
  color: var(--ink-2);
  transition: color 0.2s, background 0.2s;
}
.receipt-time.playing {
  background: var(--accent-fill);
  color: var(--on-accent);
}
.receipt-body { color: var(--ink-2); font-size: 0.945rem; }

.receipt-quote {
  margin: 1rem 0;
  padding: 0.85rem 1rem;
  border-radius: var(--radius);
  background: var(--well);
  border: 1px solid transparent;
  font-style: italic;
  font-size: 0.965rem;
  color: var(--ink);
  transition: background 0.3s var(--ease), border-color 0.3s var(--ease);
}
.receipt-quote.playing-highlight {
  background: color-mix(in srgb, var(--fa-cobalt) 12%, transparent);
  border-color: color-mix(in srgb, var(--fa-cobalt) 32%, transparent);
}
.receipt-quote em { font-style: normal; font-size: 0.8rem; color: var(--ink-2); }

.receipt-measured {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 1rem;
}
.receipt-measured span {
  padding: 0.34rem 0.7rem;
  border-radius: 9px;
  background: var(--card-deep);
  border: 1px solid var(--hairline);
  font-size: 0.8rem;
  color: var(--ink-2);
}
.receipt-measured b { color: var(--ink); font-variant-numeric: tabular-nums; }

/* Interactive Simulated Hear This Player */
.hear-this-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.52rem 1.15rem;
  border-radius: 999px;
  background: color-mix(in srgb, var(--fa-cobalt) calc(var(--wash-alpha) * 100%), transparent);
  color: var(--fa-cobalt-ink);
  border: 1px solid color-mix(in srgb, var(--fa-cobalt) 25%, transparent);
  font-size: 0.88rem;
  font-weight: 650;
  cursor: pointer;
  transition: all 0.22s var(--ease);
}
.hear-this-btn:hover {
  background: color-mix(in srgb, var(--fa-cobalt) 22%, transparent);
  transform: translateY(-1px);
}
.hear-this-btn.playing {
  background: var(--accent-fill);
  color: var(--on-accent);
  border-color: var(--accent-fill);
  box-shadow: 0 4px 14px -3px rgba(26, 87, 196, 0.55);
}
.hear-this-btn .play-icon {
  display: flex;
  align-items: center;
  justify-content: center;
}
.hear-this-btn .audio-waves {
  display: inline-flex;
  align-items: center;
  gap: 2.5px;
  height: 14px;
}
.hear-this-btn .audio-waves i {
  display: block;
  width: 2.5px;
  height: 4px;
  border-radius: 1px;
  background: currentColor;
  opacity: 0.7;
}
.hear-this-btn.playing .audio-waves i {
  animation: wave-bounce 0.7s ease-in-out infinite alternate;
}
.hear-this-btn.playing .audio-waves i:nth-child(1) { animation-delay: 0.0s; }
.hear-this-btn.playing .audio-waves i:nth-child(2) { animation-delay: 0.22s; }
.hear-this-btn.playing .audio-waves i:nth-child(3) { animation-delay: 0.44s; }
.hear-this-btn.playing .audio-waves i:nth-child(4) { animation-delay: 0.12s; }

@keyframes wave-bounce {
  0% { height: 3px; }
  100% { height: 14px; }
}

.receipt-foot {
  margin-top: 1rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--divider);
  font-size: 0.83rem;
  color: var(--ink-3);
}

/* =========================================================================
   13b · THE FILM
   ☠️ The frame here is a WELL, not a bezel. The device mockups draw their own
   bezels in the asset (README § "The device mockups"); a video cannot, so it is
   presented as a screen on an instrument ground instead of a fake phone that
   would have a corner radius picked by eye and no buttons. The CSS is:
   a fixed-dark well, a soft cobalt light, and the screen itself at its own
   aspect ratio (620 / 1344, the file's, not a guess).
   ========================================================================= */

.film-layout {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.78fr);
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
}
@media (max-width: 900px) { .film-layout { grid-template-columns: 1fr; gap: 2.6rem; } }

.film-copy .kicker { margin-bottom: 0.55rem; }
.film-heading { font-size: clamp(1.9rem, 4.2vw, 2.85rem); }
.film-lede {
  margin: 1.1rem 0 1.25rem;
  max-width: 54ch;
  color: var(--ink-2);
  font-size: 1.005rem;
}
.film-points { list-style: none; display: grid; gap: 0.62rem; margin-bottom: 1.8rem; }
.film-points li {
  position: relative;
  padding-left: 1.55rem;
  color: var(--ink-2);
  font-size: 0.94rem;
  line-height: 1.5;
}
.film-points li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.52em;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--accent-fill);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent-fill) 13%, transparent);
}

.film-stage { margin: 0; }
.film-frame {
  position: relative;
  display: grid;
  place-items: center;
  padding: clamp(0.9rem, 2.2vw, 1.5rem);
  border-radius: var(--radius-xl);
  background: linear-gradient(165deg, var(--instrument) 0%, var(--instrument-deep) 100%);
  border: 1px solid var(--instrument-stroke);
  box-shadow: var(--shadow-lift);
  overflow: hidden;
}
.film-frame::before {
  content: "";
  position: absolute;
  width: 72%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(
    circle,
    color-mix(in srgb, var(--accent-glow) 32%, transparent) 0%,
    transparent 66%
  );
  filter: blur(30px);
  pointer-events: none;
}
.film-video {
  position: relative;
  z-index: 1;
  width: min(302px, 74vw);
  height: auto;
  /* ⚠️ A <video> carrying width/height attributes renders at its attribute
     height unless `height: auto` + an aspect-ratio override it — the old
     `.film` section shipped once at 1344 px inside a 300 px column. */
  aspect-ratio: 620 / 1344;
  border-radius: 26px;
  background: #000;
  box-shadow: 0 18px 44px -18px rgba(0, 0, 0, 0.72);
}
.film-play {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: grid;
  place-items: center;
  border: 0;
  padding: 0;
  background: transparent;
  cursor: pointer;
  opacity: 1;
  transition: opacity 0.35s var(--ease), visibility 0.35s;
}
.film-play.is-hidden {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}
.film-play-disc {
  display: grid;
  place-items: center;
  width: clamp(66px, 9vw, 80px);
  height: clamp(66px, 9vw, 80px);
  padding-left: 4px;   /* optical centring of the triangle */
  border-radius: 50%;
  background: color-mix(in srgb, var(--card) 92%, transparent);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  border: 1px solid var(--hairline-strong);
  box-shadow: var(--shadow-lift);
  color: var(--accent-ink);
  transition: transform 0.25s var(--ease), background 0.25s, color 0.25s;
}
.film-play:hover .film-play-disc {
  transform: scale(1.07);
  background: var(--accent-fill);
  color: var(--on-accent);
}
.film-play:focus-visible { outline: none; }
.film-play:focus-visible .film-play-disc {
  outline: 2.5px solid var(--accent-fill);
  outline-offset: 4px;
}
.film-caption {
  margin-top: 0.95rem;
  text-align: center;
  color: var(--ink-2);
  font-size: 0.85rem;
}

/* =========================================================================
   14 · INTERACTIVE SCREENS SHOWCASE
   ========================================================================= */

.screens-section { margin-top: var(--section-gap); }

.showcase-tabs-wrap {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.45rem;
  margin: 0 auto 2.4rem;
  padding: 0.35rem;
  background: var(--well);
  border: 1px solid var(--hairline);
  border-radius: 999px;
  width: fit-content;
  max-width: 100%;
}

.showcase-tab {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.6rem 1.15rem;
  border-radius: 999px;
  border: 0;
  background: transparent;
  color: var(--ink-2);
  font-family: var(--font-body);
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.22s var(--ease);
}
.showcase-tab svg { width: 16px; height: 16px; flex: none; }
.showcase-tab:hover { color: var(--ink); background: color-mix(in srgb, var(--card) 60%, transparent); }
.showcase-tab.active {
  background: var(--card);
  color: var(--accent-ink);
  box-shadow: var(--shadow-card);
}

.showcase-panel {
  display: none;
  animation: panel-fade 0.35s var(--ease-out) forwards;
}
.showcase-panel.active { display: block; }
@keyframes panel-fade {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: none; }
}

.carousel-container {
  position: relative;
  width: 100%;
  padding-inline: 0.2rem;
}

.carousel-track {
  display: flex;
  gap: clamp(1rem, 2.2vw, 1.5rem);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  -webkit-overflow-scrolling: touch;
  padding: 0.75rem 0.25rem 1.4rem;
  scrollbar-width: none;
}
.carousel-track::-webkit-scrollbar {
  display: none;
}
/* The arrows are hidden below 840 px, so the track itself is the only pointer-
   free way through the cards. It carries `tabindex="0"`, and a focusable thing
   has to show that it is focused. */
.carousel-track:focus-visible {
  outline: 2.5px solid var(--accent-fill);
  outline-offset: 2px;
  border-radius: var(--radius-lg);
}

.carousel-track .showcase-card {
  flex: 0 0 clamp(280px, 30.5%, 335px);
  scroll-snap-align: start;
  user-select: none;
}

@media (max-width: 960px) {
  .carousel-track .showcase-card {
    flex: 0 0 clamp(260px, 78vw, 320px);
  }
}

.carousel-arrow {
  position: absolute;
  top: 42%;
  transform: translateY(-50%);
  z-index: 10;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--card);
  border: 1px solid var(--hairline-strong);
  color: var(--ink);
  display: grid;
  place-items: center;
  box-shadow: var(--shadow-lift);
  cursor: pointer;
  transition: transform 0.2s var(--ease), background 0.2s, color 0.2s, box-shadow 0.2s;
}
.carousel-arrow:hover {
  background: var(--accent-fill);
  color: var(--on-accent);
  border-color: var(--accent-fill);
  transform: translateY(-50%) scale(1.06);
}
.carousel-arrow:active {
  transform: translateY(-50%) scale(0.96);
}
/* Do not offer what cannot happen: at an end the arrow is disabled, so its
   appearance and its behaviour agree. */
.carousel-arrow:disabled {
  opacity: 0.3;
  cursor: default;
  box-shadow: var(--shadow-card);
}
.carousel-arrow:disabled:hover {
  background: var(--card);
  color: var(--ink);
  border-color: var(--hairline-strong);
  transform: translateY(-50%);
}
.carousel-arrow.prev { left: -20px; }
.carousel-arrow.next { right: -20px; }

@media (max-width: 840px) {
  .carousel-arrow { display: none; }
}

.carousel-dots {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 0.35rem;
  margin-top: 0.2rem;
  padding-bottom: 0.5rem;
}
/* ☠️ `[hidden]` is a UA rule and `display: flex` is an author one, so the
   author rule wins and the attribute does nothing. Any element this file gives
   a `display` to needs its own hidden case, or JS setting `.hidden` is inert. */
.carousel-dots[hidden] { display: none; }
.carousel-dot[hidden] { display: none; }

/* The dot the eye sees is 8 px; the dot the finger hits is 24. Drawing the
   pill on a pseudo-element is what lets those two be different numbers —
   an 8 px control is a quarter of the 24 px minimum, and shrinking the gap
   to buy the padding would have put the hit areas on top of each other. */
.carousel-dot {
  width: 24px;
  height: 24px;
  padding: 0;
  border: 0;
  background: none;
  display: grid;
  place-items: center;
  cursor: pointer;
  border-radius: 999px;
  transition: width 0.25s var(--ease);
}
.carousel-dot::before {
  content: "";
  display: block;
  width: 8px;
  height: 8px;
  border-radius: 999px;
  background: var(--hairline-strong);
  transition: width 0.25s var(--ease), background 0.25s;
}
.carousel-dot.active { width: 42px; }
.carousel-dot.active::before {
  width: 26px;
  background: var(--accent-ink);
}

.showcase-card {
  background: var(--crest);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  transition: transform 0.35s var(--ease-out), box-shadow 0.35s var(--ease-out), border-color 0.35s;
}
.showcase-card:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-lift);
  border-color: var(--hairline-strong);
}

.showcase-img-wrap {
  width: 100%;
  aspect-ratio: 1206 / 1850;
  overflow: hidden;
  background: var(--well);
  border-bottom: 1px solid var(--hairline);
}
.showcase-img-wrap img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top center;
  transition: transform 0.5s var(--ease-out);
}
.showcase-card:hover .showcase-img-wrap img {
  transform: scale(1.025);
}

/* -------- The framed variant of a gallery thumbnail --------
   The flat treatment above crops a bare screenshot flush to the card edges. The
   framed asset is a whole device on a transparent ground, so it gets air on
   three sides and runs off the bottom of the card instead: a phone standing on
   the panel rather than a rectangle jammed into a hole.

   ☠️ `object-fit` is NOT used here. The device is `height: auto` at full width
   of the padded box, so it overflows the card's fixed aspect ratio and the
   wrap's own `aspect-ratio` + `overflow: hidden` are what cut it off — a real
   crop at a real place. `object-fit: cover` on a transparent PNG would letterbox it against
   `--well` and then crop the bezel off the bottom AND the sides. */
.showcase-img-wrap.is-framed {
  display: flex;
  justify-content: center;
  align-items: flex-start;
  padding: 1.15rem 1.15rem 0;
  background: linear-gradient(170deg, var(--card-mid) 0%, var(--well) 100%);
}
.showcase-img-wrap.is-framed img {
  width: 100%;
  height: auto;
  filter: drop-shadow(0 10px 18px rgba(15, 23, 42, 0.18));
  transform-origin: top center;
}
:root[data-theme="dark"] .showcase-img-wrap.is-framed img {
  filter: drop-shadow(0 10px 18px rgba(0, 0, 0, 0.55));
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .showcase-img-wrap.is-framed img {
    filter: drop-shadow(0 10px 18px rgba(0, 0, 0, 0.55));
  }
}

.showcase-card-body {
  padding: 1.2rem 1.25rem 1.4rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  flex: 1;
}
.showcase-badge {
  display: inline-flex;
  align-items: center;
  align-self: flex-start;
  font-size: 0.73rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  padding: 0.2rem 0.55rem;
  border-radius: 6px;
  background: var(--glyph-tint, color-mix(in srgb, var(--glyph) calc(var(--wash-alpha) * 100%), transparent));
  color: var(--glyph-ink);
}
.showcase-card-body h3 {
  font-size: 1.08rem;
  letter-spacing: -0.018em;
  margin-top: 0.1rem;
}
.showcase-card-body p {
  color: var(--ink-2);
  font-size: 0.905rem;
  line-height: 1.55;
}
.showcase-card-body .lab-card-tags {
  margin-top: auto;
  padding-top: 0.5rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
}
.lab-tag {
  padding: 0.2rem 0.55rem;
  border-radius: 7px;
  background: var(--well);
  font-size: 0.735rem;
  font-weight: 550;
  color: var(--ink-2);
}

@media (max-width: 760px) {
  .showcase-tabs-wrap { border-radius: var(--radius); width: 100%; }
  .showcase-tab { flex: 1 1 45%; justify-content: center; }
}

/* =========================================================================
   14b · ON IPAD
   ========================================================================= */
/* Three iPads in a row, on the page's own ground. No card and no well: the
   assets are transparent outside the device, so the band reads as three tablets
   lying on the page rather than three pictures of tablets in three boxes. */

.ipad-band { margin-top: var(--section-gap); }

.ipad-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(1rem, 2.6vw, 2.1rem);
  align-items: start;
}
.ipad-shot { margin: 0; }
.ipad-shot img {
  width: 100%;
  height: auto;
  display: block;
  filter: drop-shadow(0 18px 30px rgba(15, 23, 42, 0.20))
          drop-shadow(0 4px 9px rgba(15, 23, 42, 0.12));
}
.ipad-shot figcaption {
  margin-top: 1rem;
  color: var(--ink-2);
  font-size: 0.9rem;
  line-height: 1.5;
  text-align: center;
  text-wrap: balance;
}
:root[data-theme="dark"] .ipad-shot img {
  filter: drop-shadow(0 18px 28px rgba(0, 0, 0, 0.6))
          drop-shadow(0 4px 9px rgba(0, 0, 0, 0.45));
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .ipad-shot img {
    filter: drop-shadow(0 18px 28px rgba(0, 0, 0, 0.6))
            drop-shadow(0 4px 9px rgba(0, 0, 0, 0.45));
  }
}

/* One iPad at a time below the tablet breakpoint. Three across a phone renders
   each at ~100 px, where the split layout the band exists to show is gone. */
@media (max-width: 860px) {
  .ipad-row {
    grid-template-columns: 1fr;
    gap: 2.4rem;
    max-width: 460px;
    margin-inline: auto;
  }
}

/* =========================================================================
   15 · MEASURES + SPEC TABLE
   ========================================================================= */

.measure-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: clamp(0.8rem, 1.6vw, 1.15rem);
  counter-reset: measure;
}
.measure-card { position: relative; padding: 1.25rem 1.3rem; counter-increment: measure; }
/* An editorial index, drawn by CSS so the ten cards cannot fall out of step
   with their number. `--ink-3` is legal here: these cards are white/card ink. */
.measure-card::after {
  content: counter(measure, decimal-leading-zero);
  position: absolute;
  top: 1.1rem;
  right: 1.2rem;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.05em;
  color: var(--ink-3);
}
.measure-card h4 {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 1rem;
  margin-bottom: 0.5rem;
}
.measure-card h4::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 3px;
  background: var(--fa-cobalt);
  flex: none;
}
.measure-card:nth-child(7n+2) h4::before { background: var(--fa-amethyst); }
.measure-card:nth-child(7n+3) h4::before { background: var(--fa-cyan); }
.measure-card:nth-child(7n+4) h4::before { background: var(--fa-emerald); }
.measure-card:nth-child(7n+5) h4::before { background: var(--fa-rose); }
.measure-card:nth-child(7n+6) h4::before { background: var(--fa-gold); }
.measure-card:nth-child(7n+7) h4::before { background: var(--fa-graphite); }
.measure-card p { color: var(--ink-2); font-size: 0.9rem; line-height: 1.58; }

.tech-specs-details {
  border-radius: var(--radius-lg);
  background: var(--crest);
  border: 1px solid var(--hairline);
  box-shadow: var(--shadow-card);
  overflow: hidden;
  transition: border-color 0.2s;
}
.tech-specs-details[open] {
  border-color: var(--hairline-strong);
}
.tech-specs-summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1.1rem 1.4rem;
  font-size: 0.94rem;
  font-weight: 650;
  color: var(--ink);
  cursor: pointer;
  user-select: none;
  list-style: none;
}
.tech-specs-summary::-webkit-details-marker { display: none; }
.tech-specs-summary svg {
  transition: transform 0.25s var(--ease);
  color: var(--ink-2);
}
.tech-specs-details[open] .tech-specs-summary svg {
  transform: rotate(180deg);
  color: var(--accent-ink);
}
.tech-specs-body {
  border-top: 1px solid var(--divider);
  padding: 0.4rem 0.4rem;
}

.specs-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  overflow: hidden;
  font-size: 0.92rem;
}
.specs-table td { padding: 0.85rem 1.15rem; vertical-align: top; }
.specs-table tr + tr td { border-top: 1px solid var(--divider); }
.specs-table td:first-child {
  width: 34%;
  font-weight: 600;
  color: var(--ink);
  white-space: nowrap;
}
.specs-table td:last-child { color: var(--ink-2); }
@media (max-width: 640px) {
  .specs-table td { display: block; padding: 0.5rem 1rem; }
  .specs-table td:first-child { width: auto; padding-bottom: 0.1rem; white-space: normal; }
  .specs-table td:last-child { padding-top: 0; }
  .specs-table tr + tr td:first-child { border-top: 1px solid var(--divider); padding-top: 0.85rem; }
  .specs-table tr + tr td:last-child { border-top: 0; }
}

/* =========================================================================
   16 · PERSONAS
   ========================================================================= */

.persona-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: clamp(0.9rem, 1.8vw, 1.35rem);
}
.persona-card { padding: 1.6rem 1.5rem; }
.persona-title {
  margin: 0 0 0.9rem;
  font-size: 1.16rem;
}
.persona-list { list-style: none; display: grid; gap: 0.6rem; }
.persona-list li {
  position: relative;
  padding-left: 1.5rem;
  color: var(--ink-2);
  font-size: 0.93rem;
  line-height: 1.5;
}
.persona-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.56em;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent-ink);
  opacity: 0.55;
}

/* =========================================================================
   17 · PRICING
   ========================================================================= */

.pricing-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(270px, 1fr));
  gap: clamp(0.9rem, 1.8vw, 1.35rem);
  align-items: start;
}
.price-card { position: relative; padding: 1.75rem 1.5rem 1.6rem; }

/* ⚠️ The featured card is NOT an accent ground — it is the same white plate,
   lifted and outlined. A price row is not a door. */
.price-card.featured {
  border-color: color-mix(in srgb, var(--accent-fill) 42%, transparent);
  box-shadow: var(--shadow-lift);
}
.price-flag {
  position: absolute;
  top: -12px;
  left: 1.5rem;
  padding: 0.28rem 0.8rem;
  border-radius: 999px;
  background: var(--accent-fill);
  color: var(--on-accent);
  font-size: 0.735rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  box-shadow: var(--shadow-door);
}
.price-name { font-size: 1.08rem; color: var(--ink-2); font-weight: 700; }
.price-amount {
  margin-top: 0.4rem;
  font-family: var(--font-display);
  font-size: clamp(2.2rem, 5vw, 2.8rem);
  font-weight: 800;
  letter-spacing: -0.035em;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.price-period { color: var(--ink-3); font-size: 0.895rem; margin-top: 0.3rem; }
.price-list { list-style: none; display: grid; gap: 0.7rem; margin: 1.4rem 0; }
.price-list li { display: flex; align-items: flex-start; gap: 0.6rem; font-size: 0.925rem; color: var(--ink-2); line-height: 1.45; }
.price-list li svg { flex: none; margin-top: 3px; }
.price-list strong { color: var(--ink); font-weight: 650; }
.price-note {
  padding-top: 0.95rem;
  border-top: 1px solid var(--divider);
  font-size: 0.815rem;
  color: var(--ink-3);
  line-height: 1.5;
}

/* The three purchase guarantees as chips. They used to be a mid-sentence list
   inside `.section-subtitle`; the same fact twice on one screen was the echo
   defect the app side calls out (AP), so the prose states the price question
   and these state the terms. */
.pricing-promises {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem;
  margin-top: 1.35rem;
  list-style: none;
}
.pricing-promises li {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.38rem 0.85rem;
  border-radius: 999px;
  background: var(--card);
  border: 1px solid var(--hairline);
  box-shadow: var(--shadow-card);
  font-size: 0.83rem;
  font-weight: 550;
  color: var(--ink-2);
}
.pricing-promises svg { width: 15px; height: 15px; flex: none; }

.pricing-foot {
  max-width: 74ch;
  margin: 1.8rem auto 0;
  padding: 1.1rem 1.35rem;
  border-radius: var(--radius);
  background: var(--card-deep);
  border: 1px solid var(--hairline);
  color: var(--ink-2);
  font-size: 0.9rem;
  line-height: 1.6;
  text-align: center;
}
.pricing-foot strong { color: var(--ink); font-weight: 650; }
.pricing-foot span { display: block; margin-top: 0.55rem; font-size: 0.82rem; color: var(--ink-3); }

/* Four tiers need a tighter floor than three did. */
.pricing-grid { grid-template-columns: repeat(auto-fit, minmax(232px, 1fr)); }
@media (min-width: 1040px) { .price-card { padding: 1.7rem 1.3rem 1.5rem; } }

/* =========================================================================
   18 · FAQ
   ========================================================================= */

.faq-list { display: grid; gap: 0.7rem; max-width: 880px; margin-inline: auto; }
.faq-item { overflow: hidden; }
/* The checkbox is the control and it is invisible, so `:focus-visible` on it
   draws nothing a keyboard user can find. The ring goes on the label it
   operates. */
.faq-toggle { position: absolute; opacity: 0; pointer-events: none; }
.faq-toggle:focus-visible + .faq-label {
  outline: 2.5px solid var(--accent-fill);
  outline-offset: 3px;
}
.faq-label {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.1rem 1.3rem;
  cursor: pointer;
  user-select: none;
}
.faq-title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.02rem;
  letter-spacing: -0.014em;
  line-height: 1.35;
}
.faq-icon { flex: none; width: 20px; height: 20px; color: var(--ink-3); transition: transform 0.3s var(--ease), color 0.3s; }
.faq-toggle:checked + .faq-label .faq-icon { transform: rotate(180deg); color: var(--accent-ink); }
.faq-toggle:focus-visible + .faq-label { outline: 2.5px solid var(--accent-fill); outline-offset: -2px; border-radius: var(--radius-lg); }

/* ☠️ The cap is a clipping hazard and has already truncated all seven answers
   once. Add a longer answer and RE-MEASURE rather than assuming. */
.faq-content {
  max-height: 0;
  overflow: hidden;
  padding: 0 1.3rem;
  color: var(--ink-2);
  font-size: 0.945rem;
  line-height: 1.65;
  transition: max-height 0.4s var(--ease), padding 0.4s var(--ease);
}
.faq-toggle:checked ~ .faq-content { max-height: 1400px; padding: 0 1.3rem 1.25rem; }

/* =========================================================================
   19 · BANNER / CTA
   ========================================================================= */

.banner {
  padding: clamp(2.2rem, 5vw, 3.6rem);
  border-radius: var(--radius-xl);
  text-align: center;
  /* A DOOR. This one earns its ground. */
  background:
    radial-gradient(120% 140% at 22% 0%, color-mix(in srgb, var(--accent-glow) 34%, transparent) 0%, transparent 58%),
    linear-gradient(165deg, var(--accent-fill) 0%, var(--accent-fill-deep) 130%);
  color: var(--on-accent);
  box-shadow: var(--shadow-door);
  overflow: hidden;
}
.banner-title { font-size: clamp(1.75rem, 4.2vw, 2.6rem); color: var(--on-accent); }
.banner-desc {
  margin: 0.9rem auto 1.8rem;
  max-width: 56ch;
  /* ☠️ FULL `--on-accent`, and the 88 % it replaced is the reason. This ground
     is not one colour: the radial glow lifts the cobalt to #306ED8 at its
     brightest, and 88 % white composited over THAT measures 4.11:1 — under AA
     for body copy, on the page's loudest door. Undiluted white measures 4.83:1
     on the same stop. The title clears either way because it is large text
     (3.0), which is exactly why this went unseen: the two lines are graded
     against different bars. An ink on a gradient is graded at the gradient's
     worst stop, never at its nominal colour. */
  color: var(--on-accent);
  font-size: 1.02rem;
}
.banner-action { display: flex; flex-wrap: wrap; gap: 0.8rem; justify-content: center; }
.banner .btn-primary {
  background: var(--on-accent);
  color: var(--accent-fill-deep);
  box-shadow: 0 10px 26px -10px rgba(0, 0, 0, 0.4);
  --sheen: rgba(15, 23, 42, 0.10);
}
.banner .btn-secondary {
  background: transparent;
  border-color: color-mix(in srgb, var(--on-accent) 45%, transparent);
  color: var(--on-accent);
  box-shadow: none;
}
.banner .btn-secondary:hover { background: color-mix(in srgb, var(--on-accent) 14%, transparent); color: var(--on-accent); border-color: var(--on-accent); }

/* The quieter sibling: a bridge, not a door. */
.banner.banner-quiet {
  background: var(--crest);
  border: 1px solid var(--hairline);
  color: var(--ink);
  box-shadow: var(--shadow-card);
}
.banner.banner-quiet .banner-title { color: var(--ink); }
.banner.banner-quiet .banner-desc { color: var(--ink-2); }
.banner.banner-quiet .btn-primary {
  background: linear-gradient(165deg, var(--accent-fill), var(--accent-fill-deep) 140%);
  color: var(--on-accent);
  box-shadow: var(--shadow-door);
}

/* =========================================================================
   21 · FOOTER
   ========================================================================= */

footer {
  margin-top: var(--section-gap);
  border-top: 1px solid var(--divider);
  background: color-mix(in srgb, var(--card) 55%, transparent);
}
.footer-content {
  width: min(1180px, 100% - var(--gutter) * 2);
  margin-inline: auto;
  padding: clamp(2.4rem, 5vw, 3.4rem) 0 1.6rem;
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  gap: clamp(1.6rem, 4vw, 3rem);
}
@media (max-width: 760px) { .footer-content { grid-template-columns: 1fr; } }

.footer-brand {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-family: var(--font-display);
  font-size: 1.1rem;
  font-weight: 800;
  letter-spacing: -0.022em;
  color: var(--ink);
  margin-bottom: 0.7rem;
}
.footer-brand:hover { text-decoration: none; }
.footer-brand img { width: 30px; height: 30px; border-radius: 7.5px; }
.footer-desc { color: var(--ink-2); font-size: 0.92rem; max-width: 46ch; }

.footer-links { display: flex; flex-wrap: wrap; gap: 0.5rem 1.4rem; align-content: start; }
.footer-links a { color: var(--ink-2); font-size: 0.92rem; }
.footer-links a:hover { color: var(--accent-ink); }

.footer-bottom {
  width: min(1180px, 100% - var(--gutter) * 2);
  margin-inline: auto;
  padding: 1.2rem 0 2.2rem;
  border-top: 1px solid var(--divider);
  color: var(--ink-2);
  font-size: 0.845rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem 1.2rem;
  justify-content: space-between;
}

/* =========================================================================
   22 · POLICY / SUPPORT PAGES
   ========================================================================= */

.policy-page {
  width: min(820px, 100% - var(--gutter) * 2);
  margin: clamp(2.4rem, 6vw, 4rem) auto 0;
}
.policy-title { font-size: clamp(2rem, 5vw, 3rem); }
.policy-meta { margin-top: 0.7rem; color: var(--ink-2); font-size: 0.9rem; }
.policy-body {
  margin-top: 2rem;
  padding: clamp(1.6rem, 4vw, 2.6rem);
}
.policy-body h2 {
  font-size: 1.28rem;
  margin: 2rem 0 0.8rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--divider);
}
.policy-body > h2:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
.policy-body h3 { font-size: 1.05rem; margin: 1.4rem 0 0.5rem; }
.policy-body p, .policy-body li { color: var(--ink-2); font-size: 0.97rem; line-height: 1.68; }
.policy-body p { margin-bottom: 1rem; }
.policy-body ul, .policy-body ol { margin: 0 0 1.1rem 1.2rem; display: grid; gap: 0.45rem; }
.policy-body strong { color: var(--ink); font-weight: 650; }
.policy-body a { font-weight: 550; }
.policy-body hr { border: 0; border-top: 1px solid var(--divider); margin: 1.6rem 0; }
.policy-body table { width: 100%; border-collapse: collapse; margin-bottom: 1.2rem; font-size: 0.93rem; }
.policy-body th, .policy-body td { text-align: left; padding: 0.6rem 0.7rem; border-bottom: 1px solid var(--divider); color: var(--ink-2); }
.policy-body th { color: var(--ink); font-weight: 650; }

/* =========================================================================
   23 · CONTACT
   ========================================================================= */

.contact-hero { text-align: center; max-width: 640px; margin: clamp(2.4rem, 6vw, 4rem) auto 0; }
.contact-card {
  max-width: 640px;
  margin: 2rem auto 0;
  padding: clamp(1.5rem, 4vw, 2.4rem);
}
.contact-extra { max-width: 640px; margin: 1.6rem auto 0; text-align: center; color: var(--ink-2); font-size: 0.9rem; }

.form-group { display: grid; gap: 0.4rem; margin-bottom: 1.05rem; }
.form-group label { font-size: 0.88rem; font-weight: 600; color: var(--ink); }
.form-control {
  width: 100%;
  padding: 0.8rem 0.95rem;
  border-radius: var(--radius-sm);
  border: 1px solid var(--hairline-strong);
  /* ⚠️ A field SINKS into the page where a card rises off it. */
  background: var(--well);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 1rem;
  transition: border-color 0.2s, box-shadow 0.2s;
}
.form-control::placeholder { color: var(--ink-2); }
.form-control:focus {
  outline: none;
  border-color: var(--accent-fill);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent-fill) 20%, transparent);
}
textarea.form-control { min-height: 150px; resize: vertical; }

.hp-field { position: absolute; left: -9999px; opacity: 0; pointer-events: none; }

.btn-submit {
  width: 100%;
  justify-content: center;
  background: linear-gradient(165deg, var(--accent-fill), var(--accent-fill-deep) 140%);
  color: var(--on-accent);
  box-shadow: var(--shadow-door);
  border: 0;
}
.btn-submit[disabled] { opacity: 0.55; cursor: not-allowed; }
.btn-spinner {
  width: 17px;
  height: 17px;
  border: 2px solid color-mix(in srgb, var(--on-accent) 40%, transparent);
  border-top-color: var(--on-accent);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ⚠️ `display: none` by default and shown by a state class — the status region
   is present in the DOM from first paint so a screen reader's live region has
   something to attach to before the first submit. */
.form-message {
  display: none;
  margin-bottom: 1.2rem;
  padding: 0.85rem 1.1rem;
  border-radius: var(--radius-sm);
  font-size: 0.92rem;
  text-align: center;
  line-height: 1.5;
}
.form-message.success {
  display: block;
  background: color-mix(in srgb, var(--success) 13%, transparent);
  border: 1px solid color-mix(in srgb, var(--success) 34%, transparent);
  color: var(--success);
}
.form-message.error {
  display: block;
  background: color-mix(in srgb, var(--danger) 13%, transparent);
  border: 1px solid color-mix(in srgb, var(--danger) 34%, transparent);
  color: var(--danger);
}

/* -------- Slide to verify --------
   ⚠️ No third-party CAPTCHA and no tracking pixel, on purpose: a privacy page
   that loads someone else's script to prove you are human has undone itself.
   The visible track is `.unlock-container`; the control is a transparent range
   input laid over it, so it is keyboard-operable and announces as a slider. */
.unlock-container {
  position: relative;
  height: 60px;
  margin: 1.6rem 0 1.4rem;
  padding: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  background: var(--well);
  border: 1px solid var(--hairline-strong);
  overflow: hidden;
  touch-action: none;
  transition: border-color 0.3s, box-shadow 0.3s;
}
.unlock-container.unlocked {
  border-color: color-mix(in srgb, var(--success) 55%, transparent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--success) 16%, transparent);
}

.unlock-bg {
  position: absolute;
  left: 0;
  top: 0;
  height: 100%;
  width: 0;
  z-index: 1;
  border-radius: 999px;
  pointer-events: none;
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--accent-fill) 16%, transparent),
    color-mix(in srgb, var(--accent-fill) 30%, transparent));
  transition: width 0.08s linear;
}

.unlock-label {
  position: relative;
  z-index: 2;
  font-size: 0.9rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--ink-2);
  pointer-events: none;
  user-select: none;
  transition: opacity 0.25s, color 0.25s;
}

.unlock-handle {
  position: absolute;
  left: 4px;
  top: 4px;
  z-index: 3;
  /* 52 px exactly fills the 60 px track inside its 4 px padding; the inline
     script positions it with `calc(100% - 56px)` at rest, which is this
     width plus that padding. Move one and you must move the other. */
  width: 52px;
  height: 52px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: linear-gradient(165deg, var(--accent-fill), var(--accent-fill-deep) 150%);
  box-shadow: var(--shadow-door);
  pointer-events: none;
  transition: background 0.3s, box-shadow 0.3s, transform 0.2s var(--ease);
}
.unlock-handle svg { width: 20px; height: 20px; fill: none; stroke: var(--on-accent); stroke-width: 2; }
.unlock-container.unlocked .unlock-handle {
  background: var(--success);
  box-shadow: 0 8px 20px -8px color-mix(in srgb, var(--success) 70%, transparent);
}

/* The real control, invisible over the track. */
.unlock-slider {
  position: absolute;
  inset: 0;
  z-index: 10;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
  touch-action: none;
  -webkit-appearance: none;
  appearance: none;
  background: transparent;
}
.unlock-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 52px; height: 52px;
  border-radius: 50%;
  background: transparent;
  cursor: grab;
}
.unlock-slider::-moz-range-thumb {
  width: 52px; height: 52px;
  border: 0;
  border-radius: 50%;
  background: transparent;
  cursor: grab;
}
.unlock-slider:focus-visible + .unlock-handle,
.unlock-container:focus-within { outline: 2.5px solid var(--accent-fill); outline-offset: 2px; }

.qr-wrap { display: flex; flex-direction: column; align-items: center; gap: 0.9rem; }
.qr-wrap img { border-radius: 22px; }
.qr-box {
  padding: 10px;
  border-radius: var(--radius);
  background: #FFFFFF;
  box-shadow: var(--shadow-card);
}
.qr-box img { width: 144px; height: 144px; border-radius: 8px; }

.contact-extra { display: flex; flex-direction: column; gap: 1.25rem; text-align: left; }
.contact-extra .glass-card { padding: 1.7rem; }
.contact-extra .card-title { font-size: 1.16rem; }

@media (max-width: 640px) {
  .contact-card { padding: 1.5rem 1.2rem; }
}

/* =========================================================================
   23b · CARD SPOTLIGHT — the cursor as a light
   -------------------------------------------------------------------------
   The radial is painted as a BACKGROUND layer, not as an overlay: a layer
   above the card content would tint the card's own text, and this repo grades
   ink against its ground (website/README § Checks). The alpha rides on
   `--spot-a` so there is no glow at rest, and `--spot-x/--spot-y` are written
   by one pointermove listener in app.js. The whole block sits after the card
   rules on purpose — `.showcase-card` re-declares `background` and would
   otherwise win the cascade. No transition on the alpha: `transition` on a
   custom property needs `@property`, and a snap this subtle does not earn a
   global registration for every browser.
   ========================================================================= */

.glass-card,
.measure-card,
.persona-card,
.price-card,
.receipt-card,
.showcase-card {
  background-image:
    radial-gradient(
      300px circle at var(--spot-x, 50%) var(--spot-y, 50%),
      color-mix(in srgb, var(--accent-glow) calc(var(--spot-a, 0) * 17%), transparent),
      transparent 72%
    ),
    var(--crest);
}
@media (hover: hover) and (pointer: fine) {
  .glass-card:hover,
  .measure-card:hover,
  .persona-card:hover,
  .price-card:hover,
  .receipt-card:hover,
  .showcase-card:hover { --spot-a: 1; }
}

/* =========================================================================
   23c · FLOATING CONTROLS — the phone's door, and the way back up
   -------------------------------------------------------------------------
   Both are script-shown: `visibility: hidden` keeps the hidden one out of the
   tab order, which `aria-hidden` on a focusable link would not. Without
   JavaScript neither ever shows, and the page loses nothing: the hero CTA is
   the door, and `#top` is a one-anchor jump.
   ========================================================================= */

.mobile-cta {
  position: fixed;
  left: 50%;
  bottom: max(0.75rem, env(safe-area-inset-bottom));
  z-index: 116;
  display: flex;
  align-items: center;
  gap: 0.6rem;
  width: min(560px, calc(100% - 1.6rem));
  padding: 0.62rem 0.9rem;
  border-radius: 999px;
  background: var(--chrome-solid);
  border: 1px solid var(--hairline-strong);
  box-shadow: var(--shadow-lift);
  color: var(--ink);
  visibility: hidden;
  transform: translate(-50%, calc(100% + 1.6rem));
  transition: transform 0.4s var(--ease-out), visibility 0.4s;
}
.mobile-cta.show { visibility: visible; transform: translate(-50%, 0); }
.mobile-cta:hover { text-decoration: none; }
.mobile-cta > svg { flex: none; color: var(--accent-ink); }
.mobile-cta-text {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 0.83rem;
  color: var(--ink-2);
}
.mobile-cta-text strong { color: var(--ink); font-weight: 700; }
.mobile-cta-get {
  margin-left: auto;
  flex: none;
  padding: 0.42rem 0.9rem;
  border-radius: 999px;
  background: linear-gradient(175deg, #4468B0 0%, var(--accent-fill) 55%, var(--accent-fill-deep) 130%);
  color: var(--on-accent);
  font-size: 0.83rem;
  font-weight: 650;
}
@media (min-width: 901px) { .mobile-cta { display: none !important; } }

.to-top {
  position: fixed;
  right: clamp(0.9rem, 2.5vw, 1.5rem);
  bottom: clamp(1rem, 3vw, 1.6rem);
  z-index: 117;
  width: 52px;
  height: 52px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--card);
  border: 1px solid var(--hairline-strong);
  box-shadow: var(--shadow-lift);
  color: var(--ink);
  opacity: 0;
  visibility: hidden;
  transform: translateY(10px) scale(0.94);
  transition: opacity 0.3s var(--ease), transform 0.3s var(--ease-out),
              visibility 0.3s, color 0.2s, border-color 0.2s;
}
.to-top.show { opacity: 1; visibility: visible; transform: none; }
.to-top:hover { color: var(--accent-ink); border-color: var(--accent-ink); text-decoration: none; }
.to-top-arrow { width: 19px; height: 19px; }
/* r = 21, so the circumference is 131.95 — the 132 dash is the whole ring. */
.to-top-ring {
  position: absolute;
  inset: 3px;
  width: calc(100% - 6px);
  height: calc(100% - 6px);
  transform: rotate(-90deg);
  pointer-events: none;
}
.to-top-ring circle {
  fill: none;
  stroke: var(--accent-ink);
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-dasharray: 132;
  stroke-dashoffset: calc(132 * (1 - var(--scroll-progress, 0)));
  transition: stroke-dashoffset 0.1s linear;
}
/* On a phone the download bar owns the bottom edge; the arrow sits above it. */
@media (max-width: 900px) {
  body.mobile-cta-active .to-top {
    bottom: calc(max(0.75rem, env(safe-area-inset-bottom)) + 68px);
  }
}

/* ☠️ The nav overlay is z 110 and the drawer 130; these two are 116 and 117,
   so with the drawer open they would float ON TOP of the dimmed backdrop.
   The drawer is modal — everything under it goes away. */
body.mobile-menu-active .mobile-cta,
body.mobile-menu-active .to-top {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

/* =========================================================================
   24 · MOTION
   ========================================================================= */

.animate-up { opacity: 0; transform: translateY(18px); animation: rise 0.85s var(--ease-out) forwards; }
.delay-1 { animation-delay: 0.05s; }
.delay-2 { animation-delay: 0.14s; }
.delay-3 { animation-delay: 0.23s; }
.delay-4 { animation-delay: 0.32s; }
@keyframes rise { to { opacity: 1; transform: none; } }

.scroll-reveal {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.75s var(--ease-out), transform 0.75s var(--ease-out);
}
.scroll-reveal.visible { opacity: 1; transform: none; }
.scroll-reveal-group > .scroll-reveal:nth-child(2) { transition-delay: 0.07s; }
.scroll-reveal-group > .scroll-reveal:nth-child(3) { transition-delay: 0.14s; }
.scroll-reveal-group > .scroll-reveal:nth-child(4) { transition-delay: 0.21s; }
.scroll-reveal-group > .scroll-reveal:nth-child(5) { transition-delay: 0.28s; }
.scroll-reveal-group > .scroll-reveal:nth-child(6) { transition-delay: 0.35s; }

/* ⚠️ Reduce Motion is a design variant, not a switch that turns the page off:
   everything still arrives, it simply arrives without travelling. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  /* The page was covered and this scroller was not — `scroll-behavior` is
     per-scroll-container, so a rule on `html` says nothing about the carousel
     the arrows and dots drive. */
  .carousel-track { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  .animate-up, .scroll-reveal { opacity: 1; transform: none; }
  .pipe-stage { opacity: 1; transform: none; }
  .pipe-arrow { opacity: 1; transform: none; }
}

/* =========================================================================
   25 · UTILITIES
   ========================================================================= */

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}
.text-muted { color: var(--ink-2); }
.center { text-align: center; }
.stack-sm > * + * { margin-top: 0.6rem; }

@media print {
  header, footer, .ambient-bg, .noise-overlay, .btn, .delivery-strip,
  .to-top, .mobile-cta, .hero-float { display: none !important; }
  body { padding-top: 0; background: #fff; color: #000; }
  .policy-body, .glass-card { box-shadow: none; border-color: #ccc; }
}
