/* ==========================================================================
   Rovik v3 — shared design system
   --------------------------------------------------------------------------
   Hand-written. No framework, no build step, no npm, no CDN, no preprocessor.

   HOW THEMING WORKS (G3)
   ----------------------
   1. `:root` below declares the COMPLETE light palette. Every colour token in
      the entire stylesheet is born there.
   2. `@media (prefers-color-scheme: dark)`, guarded as
      `:root:not([data-theme="light"])`, REDEFINES those same names for dark.
   3. `:root[data-theme="dark"]` REDEFINES them again, so an explicit toggle
      beats the operating system in both directions.

   RULE, NO EXCEPTIONS: no colour may exist only inside a media query or a
   [data-theme] block. Every token name in those blocks also appears in bare
   `:root`. Break this and a page renders one theme's text on the other
   theme's ground.

   RULE: alpha is for hairlines, washes and shadows ONLY — never for text.
   The v2 build set text as white-at-alpha over a dark ground; ten of those
   values silently drifted below WCAG AA (2.39:1 to 4.43:1). Every text token
   here is a SOLID hex, measured. Evidence: `_contrast-check.md`.

   FONTS — every page must carry these three tags in <head>:
     <link rel="preconnect" href="https://fonts.googleapis.com">
     <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
     <link href="https://fonts.googleapis.com/css2?family=Archivo:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">

   Calculator styles live in `css/calculator.css`, not here.
   ========================================================================== */


/* ==========================================================================
   1. TOKENS — LIGHT (source of truth; authored fresh, not inverted)
   ========================================================================== */

:root{

  /* -- 1.1 Colour-scheme hint for native controls (G4) ------------------- */
  --scheme:light;

  /* -- 1.2 Grounds ------------------------------------------------------- */
  --ground:#F7F4EE;        /* page background — warm off-white, never #FFF   */
  --ground-deep:#EFEAE0;   /* footer / recessed bands                        */
  --surface-1:#FDFBF7;     /* cards, panels — lifts above the ground         */
  --surface-2:#F1ECE1;     /* nested panels, table stripes, code blocks      */
  --surface-3:#E6E0D3;     /* input fills, hover washes — the DARKEST light
                              surface, so it sets the contrast worst case    */

  /* -- 1.3 Ink: four solid steps, never alpha ---------------------------- */
  --ink:#16120C;           /* headings, emphasis — deep warm charcoal        */
  --ink-body:#332B20;      /* paragraphs, default body text                  */
  --ink-muted:#544936;     /* secondary copy, captions, nav rest state       */
  --ink-faint:#645842;     /* quietest legal text — still clears 4.5:1       */

  /* -- 1.4 Accent: fill and text are DIFFERENT colours ------------------- */
  --accent:#E2701F;        /* FILL only — buttons, bars, marks               */
  --accent-hover:#F5883A;  /* FILL hover                                     */
  --accent-ink:#9E4306;    /* accent as TEXT — links, eyebrows, figures      */
  --on-accent:#16120C;     /* text that sits ON an accent fill               */
  --on-accent-muted:#2A1F12;

  /* -- 1.5 Semantic ------------------------------------------------------ */
  --loss:#B3261E;          /* money lost, errors                             */
  --gain:#0F5F39;          /* money recovered, success                       */
  --warn:#7A4F00;          /* cautions                                       */

  /* -- 1.6 Washes: translucent tints for badges and highlight rows ------- */
  --accent-wash:rgba(226,112,31,0.16);
  --gain-wash:rgba(15,95,57,0.14);
  --loss-wash:rgba(179,38,30,0.14);
  --warn-wash:rgba(122,79,0,0.14);
  --ink-wash:rgba(22,18,12,0.05);
  --ink-wash-strong:rgba(22,18,12,0.09);

  /* -- 1.7 Hairlines ----------------------------------------------------- */
  --line:rgba(22,18,12,0.12);
  --line-strong:rgba(22,18,12,0.22);
  --line-accent:rgba(226,112,31,0.40);
  /* High-contrast variants; consumed by the prefers-contrast block. */
  --line-hc:rgba(22,18,12,0.34);
  --line-strong-hc:rgba(22,18,12,0.52);

  /* Boundaries of INTERACTIVE controls. WCAG 1.4.11 wants 3:1 for these, so
     they are SOLID and measured — a translucent hairline is fine around a
     decorative card but leaves an empty text input invisible. */
  --field-border:#7D7462;   /* text inputs, selects, icon-only buttons       */
  --accent-edge:#9E4306;    /* rim on the primary button, so its shape reads
                               against a light ground                        */

  /* -- 1.8 Focus, selection, overlay ------------------------------------- */
  --focus:#9E4306;
  --select-bg:#E2701F;
  --select-ink:#16120C;
  --overlay:rgba(22,18,12,0.52);
  --tap-highlight:rgba(226,112,31,0.18);

  /* -- 1.9 Elevation ----------------------------------------------------- */
  --shadow-sm:0 1px 2px rgba(22,18,12,0.06), 0 2px 8px -4px rgba(22,18,12,0.10);
  --shadow-md:0 2px 6px rgba(22,18,12,0.06), 0 12px 28px -14px rgba(22,18,12,0.18);
  --shadow-lg:0 4px 12px rgba(22,18,12,0.07), 0 28px 60px -24px rgba(22,18,12,0.26);
  --glow-accent:0 12px 34px -14px rgba(226,112,31,0.55);
  --glow-accent-lg:0 18px 48px -16px rgba(226,112,31,0.65);

  /* -- 1.10 Depth: gradients that give the page dimension ----------------
     Decorative ONLY. These sit BEHIND content, never directly behind a
     paragraph, and their densest stop is capped low enough that text over
     them still clears 4.5:1 - measured in _contrast-check.md. Raising these
     alphas without re-running the check breaks contrast quietly, which is
     the exact failure this whole system exists to prevent.
     No new hues: the accent orb is the brand orange, the cool orb and the
     sheen are the theme's own ink. */
  --orb-accent:rgba(226,112,31,0.10);
  --orb-cool:rgba(22,18,12,0.05);
  --sheen:rgba(255,255,255,0.70);

  /* Composed gradients. Declared once - they resolve var() at use time, so
     they follow whichever theme is active with no duplication. */
  --grad-hero:radial-gradient(58% 68% at 12% 6%,var(--orb-accent) 0%,transparent 62%),radial-gradient(52% 62% at 88% 20%,var(--orb-cool) 0%,transparent 60%);
  --grad-orb:radial-gradient(circle at 50% 50%,var(--orb-accent) 0%,transparent 70%);
  --grad-sheen:linear-gradient(180deg,var(--sheen) 0%,transparent 58%);
  --grad-accent-bar:linear-gradient(90deg,var(--accent) 0%,var(--accent-hover) 100%);
  --grad-fade-line:linear-gradient(90deg,transparent,var(--line-strong) 18%,var(--line-strong) 82%,transparent);

  /* -- 1.11 Contrast band -------------------------------------------------
  A section that deliberately breaks the page ground, so the eye gets a
  rhythm instead of one flat colour from header to footer. In LIGHT mode
  it is a dark band; in DARK mode it is a LIFTED band, because a darker
  band on an already-dark page just reads as a hole.
  Every value here is measured - see _contrast-check.md. */
  --band-ground:#16120C;
  --band-surface:#231D14;
  --band-ink:#F7F3E9;
  --band-ink-body:#DCD5C6;
  --band-ink-muted:#B5AB97;
  --band-accent-ink:#F0A24A;
  --band-line:rgba(247,243,233,0.12);
  --band-line-strong:rgba(247,243,233,0.24);
  --band-field-border:#6A7684;


  /* ========================================================================
     2. TOKENS — NOT THEMED (identical in light and dark)
     ======================================================================== */

  /* -- 2.1 Type families ------------------------------------------------- */
  --sans:Archivo,"Helvetica Neue",Helvetica,Arial,sans-serif;
  --mono:"JetBrains Mono",ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;

  /* -- 2.2 Type scale ---------------------------------------------------- */
  --fs-display:clamp(40px,6vw,72px);
  --fs-h1:clamp(36px,5.2vw,62px);
  --fs-h2:clamp(29px,4vw,48px);
  --fs-h3:clamp(21px,2.2vw,27px);
  --fs-h4:19px;
  --fs-lede:clamp(17px,1.35vw,19px);
  --fs-body:16px;
  --fs-sm:14.5px;
  --fs-xs:13px;
  --fs-label:11.5px;

  /* -- 2.3 Line height and tracking -------------------------------------- */
  --lh-display:1.04;
  --lh-head:1.12;
  --lh-snug:1.4;
  --lh-body:1.62;
  --tr-display:-0.035em;
  --tr-head:-0.022em;
  --tr-body:-0.005em;
  --tr-label:0.15em;

  /* -- 2.4 Weight -------------------------------------------------------- */
  --fw-regular:400;
  --fw-medium:500;
  --fw-semibold:600;
  --fw-bold:700;
  --fw-black:800;

  /* -- 2.5 Spacing scale (4px base) -------------------------------------- */
  --sp-1:4px;   --sp-2:8px;   --sp-3:12px;  --sp-4:16px;
  --sp-5:20px;  --sp-6:24px;  --sp-8:32px;  --sp-10:40px;
  --sp-12:48px; --sp-16:64px; --sp-20:80px; --sp-24:96px;
  --sp-section:clamp(72px,9vw,132px);

  /* -- 2.6 Radius scale -------------------------------------------------- */
  --r-xs:6px; --r-sm:10px; --r-md:14px; --r-lg:20px; --r-xl:28px; --r-full:999px;

  /* -- 2.7 Layout -------------------------------------------------------- */
  --maxw:1280px;
  --maxw-prose:760px;
  --pad:clamp(18px,4vw,44px);
  --header-h:72px;

  /* -- 2.8 Motion -------------------------------------------------------- */
  --dur-fast:140ms;
  --dur:220ms;
  --dur-slow:420ms;
  --ease:cubic-bezier(0.4,0,0.2,1);
  --ease-out:cubic-bezier(0.16,1,0.3,1);
  /* Press feedback is faster than hover: a touch should feel instant. */
  --dur-press:100ms;

  /* -- 2.9 Focus ring geometry ------------------------------------------- */
  --focus-w:2px;
  --focus-gap:2px;

  /* -- 2.10 Mask stop. Not a colour anyone sees: CSS masks read the ALPHA
     channel, so this opaque value simply means "keep this part". Tokenised
     so the no-literals-outside-:root rule stays absolute. */
  --mask-opaque:#000000;
}


/* ==========================================================================
   3. TOKENS — DARK via system preference
   Guarded so an explicit light toggle wins. REDEFINES only; adds nothing.
   ========================================================================== */

@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    --scheme:dark;

    --ground:#070B12;
    --ground-deep:#05080E;
    --surface-1:#0D131D;
    --surface-2:#141C28;
    --surface-3:#1A2331;

    --ink:#F7F3E9;
    --ink-body:#DCD5C6;
    --ink-muted:#B5AB97;
    --ink-faint:#A89E89;

    --accent:#E2701F;
    --accent-hover:#F5883A;
    --accent-ink:#F0A24A;
    --on-accent:#070B12;
    --on-accent-muted:#2A1F12;

    --loss:#FF7A6B;
    --gain:#4ADE9A;
    --warn:#F5A623;

    --accent-wash:rgba(226,112,31,0.16);
    --gain-wash:rgba(74,222,154,0.16);
    --loss-wash:rgba(255,122,107,0.16);
    --warn-wash:rgba(245,166,35,0.16);
    --ink-wash:rgba(247,243,233,0.04);
    --ink-wash-strong:rgba(247,243,233,0.08);

    --line:rgba(247,243,233,0.11);
    --line-strong:rgba(247,243,233,0.22);
    --line-accent:rgba(226,112,31,0.45);
    /* High-contrast variants; consumed by the prefers-contrast block. */
    --line-hc:rgba(247,243,233,0.30);
    --line-strong-hc:rgba(247,243,233,0.48);
    --field-border:#6A7684;
    --accent-edge:#E2701F;

    --focus:#F0A24A;
    --select-bg:#E2701F;
    --select-ink:#070B12;
    --overlay:rgba(3,5,9,0.72);
    --tap-highlight:rgba(240,162,74,0.20);

    --shadow-sm:0 1px 2px rgba(0,0,0,0.50), 0 2px 8px -4px rgba(0,0,0,0.60);
    --shadow-md:0 2px 6px rgba(0,0,0,0.50), 0 12px 28px -14px rgba(0,0,0,0.70);
    --shadow-lg:0 4px 12px rgba(0,0,0,0.55), 0 28px 60px -24px rgba(0,0,0,0.80);
    --glow-accent:0 12px 34px -14px rgba(226,112,31,0.75);
    --glow-accent-lg:0 18px 48px -16px rgba(226,112,31,0.85);

    /* -- 1.10 Depth: gradients that give the page dimension ----------------
    Decorative ONLY. These sit BEHIND content, never directly behind a
    paragraph, and their densest stop is capped low enough that text over
    them still clears 4.5:1 - measured in _contrast-check.md. Raising these
    alphas without re-running the check breaks contrast quietly, which is
    the exact failure this whole system exists to prevent.
    No new hues: the accent orb is the brand orange, the cool orb and the
    sheen are the theme's own ink. */
    --orb-accent:rgba(226,112,31,0.14);
    --orb-cool:rgba(247,243,233,0.05);
    --sheen:rgba(247,243,233,0.06);

    /* -- 1.11 Contrast band -------------------------------------------------
    A section that deliberately breaks the page ground, so the eye gets a
    rhythm instead of one flat colour from header to footer. In LIGHT mode
    it is a dark band; in DARK mode it is a LIFTED band, because a darker
    band on an already-dark page just reads as a hole.
    Every value here is measured - see _contrast-check.md. */
    --band-ground:#141C28;
    --band-surface:#1A2331;
    --band-ink:#F7F3E9;
    --band-ink-body:#DCD5C6;
    --band-ink-muted:#B5AB97;
    --band-accent-ink:#F0A24A;
    --band-line:rgba(247,243,233,0.12);
    --band-line-strong:rgba(247,243,233,0.24);
    --band-field-border:#6A7684;
  }
}


/* ==========================================================================
   4. TOKENS — DARK via explicit toggle (beats the OS)
   ========================================================================== */

:root[data-theme="dark"]{
  --scheme:dark;

  --ground:#070B12;
  --ground-deep:#05080E;
  --surface-1:#0D131D;
  --surface-2:#141C28;
  --surface-3:#1A2331;

  --ink:#F7F3E9;
  --ink-body:#DCD5C6;
  --ink-muted:#B5AB97;
  --ink-faint:#A89E89;

  --accent:#E2701F;
  --accent-hover:#F5883A;
  --accent-ink:#F0A24A;
  --on-accent:#070B12;
  --on-accent-muted:#2A1F12;

  --loss:#FF7A6B;
  --gain:#4ADE9A;
  --warn:#F5A623;

  --accent-wash:rgba(226,112,31,0.16);
  --gain-wash:rgba(74,222,154,0.16);
  --loss-wash:rgba(255,122,107,0.16);
  --warn-wash:rgba(245,166,35,0.16);
  --ink-wash:rgba(247,243,233,0.04);
  --ink-wash-strong:rgba(247,243,233,0.08);

  --line:rgba(247,243,233,0.11);
  --line-strong:rgba(247,243,233,0.22);
  --line-accent:rgba(226,112,31,0.45);
  /* High-contrast variants; consumed by the prefers-contrast block. */
  --line-hc:rgba(247,243,233,0.30);
  --line-strong-hc:rgba(247,243,233,0.48);
  --field-border:#6A7684;
  --accent-edge:#E2701F;

  --focus:#F0A24A;
  --select-bg:#E2701F;
  --select-ink:#070B12;
  --overlay:rgba(3,5,9,0.72);
  --tap-highlight:rgba(240,162,74,0.20);

  --shadow-sm:0 1px 2px rgba(0,0,0,0.50), 0 2px 8px -4px rgba(0,0,0,0.60);
  --shadow-md:0 2px 6px rgba(0,0,0,0.50), 0 12px 28px -14px rgba(0,0,0,0.70);
  --shadow-lg:0 4px 12px rgba(0,0,0,0.55), 0 28px 60px -24px rgba(0,0,0,0.80);
  --glow-accent:0 12px 34px -14px rgba(226,112,31,0.75);
  --glow-accent-lg:0 18px 48px -16px rgba(226,112,31,0.85);

  /* -- 1.10 Depth: gradients that give the page dimension ----------------
  Decorative ONLY. These sit BEHIND content, never directly behind a
  paragraph, and their densest stop is capped low enough that text over
  them still clears 4.5:1 - measured in _contrast-check.md. Raising these
  alphas without re-running the check breaks contrast quietly, which is
  the exact failure this whole system exists to prevent.
  No new hues: the accent orb is the brand orange, the cool orb and the
  sheen are the theme's own ink. */
  --orb-accent:rgba(226,112,31,0.14);
  --orb-cool:rgba(247,243,233,0.05);
  --sheen:rgba(247,243,233,0.06);

  /* -- 1.11 Contrast band -------------------------------------------------
  A section that deliberately breaks the page ground, so the eye gets a
  rhythm instead of one flat colour from header to footer. In LIGHT mode
  it is a dark band; in DARK mode it is a LIFTED band, because a darker
  band on an already-dark page just reads as a hole.
  Every value here is measured - see _contrast-check.md. */
  --band-ground:#141C28;
  --band-surface:#1A2331;
  --band-ink:#F7F3E9;
  --band-ink-body:#DCD5C6;
  --band-ink-muted:#B5AB97;
  --band-accent-ink:#F0A24A;
  --band-line:rgba(247,243,233,0.12);
  --band-line-strong:rgba(247,243,233,0.24);
  --band-field-border:#6A7684;
}


/* ==========================================================================
   5. TOKENS — LIGHT via explicit toggle (beats a dark OS preference)
   Same values as section 1. Restated so the toggle wins in BOTH directions.
   ========================================================================== */

:root[data-theme="light"]{
  --scheme:light;

  --ground:#F7F4EE;
  --ground-deep:#EFEAE0;
  --surface-1:#FDFBF7;
  --surface-2:#F1ECE1;
  --surface-3:#E6E0D3;

  --ink:#16120C;
  --ink-body:#332B20;
  --ink-muted:#544936;
  --ink-faint:#645842;

  --accent:#E2701F;
  --accent-hover:#F5883A;
  --accent-ink:#9E4306;
  --on-accent:#16120C;
  --on-accent-muted:#2A1F12;

  --loss:#B3261E;
  --gain:#0F5F39;
  --warn:#7A4F00;

  --accent-wash:rgba(226,112,31,0.16);
  --gain-wash:rgba(15,95,57,0.14);
  --loss-wash:rgba(179,38,30,0.14);
  --warn-wash:rgba(122,79,0,0.14);
  --ink-wash:rgba(22,18,12,0.05);
  --ink-wash-strong:rgba(22,18,12,0.09);

  --line:rgba(22,18,12,0.12);
  --line-strong:rgba(22,18,12,0.22);
  --line-accent:rgba(226,112,31,0.40);
  /* High-contrast variants; consumed by the prefers-contrast block. */
  --line-hc:rgba(22,18,12,0.34);
  --line-strong-hc:rgba(22,18,12,0.52);
  --field-border:#7D7462;
  --accent-edge:#9E4306;

  --focus:#9E4306;
  --select-bg:#E2701F;
  --select-ink:#16120C;
  --overlay:rgba(22,18,12,0.52);
  --tap-highlight:rgba(226,112,31,0.18);

  --shadow-sm:0 1px 2px rgba(22,18,12,0.06), 0 2px 8px -4px rgba(22,18,12,0.10);
  --shadow-md:0 2px 6px rgba(22,18,12,0.06), 0 12px 28px -14px rgba(22,18,12,0.18);
  --shadow-lg:0 4px 12px rgba(22,18,12,0.07), 0 28px 60px -24px rgba(22,18,12,0.26);
  --glow-accent:0 12px 34px -14px rgba(226,112,31,0.55);
  --glow-accent-lg:0 18px 48px -16px rgba(226,112,31,0.65);

  /* -- 1.10 Depth: gradients that give the page dimension ----------------
     Decorative ONLY. These sit BEHIND content, never directly behind a
     paragraph, and their densest stop is capped low enough that text over
     them still clears 4.5:1 - measured in _contrast-check.md. Raising these
     alphas without re-running the check breaks contrast quietly, which is
     the exact failure this whole system exists to prevent.
     No new hues: the accent orb is the brand orange, the cool orb and the
     sheen are the theme's own ink. */
  --orb-accent:rgba(226,112,31,0.10);
  --orb-cool:rgba(22,18,12,0.05);
  --sheen:rgba(255,255,255,0.70);

  /* -- 1.11 Contrast band -------------------------------------------------
  A section that deliberately breaks the page ground, so the eye gets a
  rhythm instead of one flat colour from header to footer. In LIGHT mode
  it is a dark band; in DARK mode it is a LIFTED band, because a darker
  band on an already-dark page just reads as a hole.
  Every value here is measured - see _contrast-check.md. */
  --band-ground:#16120C;
  --band-surface:#231D14;
  --band-ink:#F7F3E9;
  --band-ink-body:#DCD5C6;
  --band-ink-muted:#B5AB97;
  --band-accent-ink:#F0A24A;
  --band-line:rgba(247,243,233,0.12);
  --band-line-strong:rgba(247,243,233,0.24);
  --band-field-border:#6A7684;
}


/* ==========================================================================
   6. RESET AND BASE
   ========================================================================== */

*,*::before,*::after{box-sizing:border-box;}

html{
  color-scheme:var(--scheme);
  background:var(--ground);
  scroll-behavior:smooth;
  -webkit-text-size-adjust:100%;
  text-size-adjust:100%;
}

body{
  margin:0;
  background:var(--ground);
  color:var(--ink-body);
  font-family:var(--sans);
  font-optical-sizing:auto;
  font-size:var(--fs-body);
  font-weight:var(--fw-regular);
  line-height:var(--lh-body);
  letter-spacing:var(--tr-body);
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  overflow-x:hidden;
  touch-action:manipulation;
  -webkit-tap-highlight-color:var(--tap-highlight);
}

h1,h2,h3,h4,h5,h6{
  margin:0;
  color:var(--ink);
  font-weight:var(--fw-bold);
  line-height:var(--lh-head);
  letter-spacing:var(--tr-head);
  text-wrap:balance;
}
h1{font-size:var(--fs-h1);line-height:var(--lh-display);letter-spacing:var(--tr-display);}
h2{font-size:var(--fs-h2);letter-spacing:var(--tr-display);}
h3{font-size:var(--fs-h3);}
h4{font-size:var(--fs-h4);}

p{margin:0;}
strong,b{color:var(--ink);font-weight:var(--fw-semibold);}
small{font-size:var(--fs-xs);}

a{
  color:var(--accent-ink);
  text-decoration:none;
  transition:color var(--dur) var(--ease);
}
a:hover{color:var(--ink);}

hr{
  border:0;
  height:1px;
  background:var(--line);
  margin:var(--sp-10) 0;
}

img,svg,video,canvas{max-width:100%;display:block;}
img{height:auto;}

ul,ol{margin:0;padding-left:1.25em;}
li{margin:0 0 var(--sp-2);}

code,kbd,pre,samp{font-family:var(--mono);font-size:0.92em;}
code{
  background:var(--surface-2);
  border:1px solid var(--line);
  border-radius:var(--r-xs);
  padding:0.14em 0.4em;
  color:var(--ink);
}
pre{
  background:var(--surface-2);
  border:1px solid var(--line);
  border-radius:var(--r-md);
  padding:var(--sp-5);
  overflow-x:auto;
  margin:0 0 var(--sp-5);
  color:var(--ink-body);
}
pre code{background:none;border:0;padding:0;}

table{border-collapse:collapse;width:100%;}

summary{list-style:none;cursor:pointer;}
summary::-webkit-details-marker{display:none;}

::selection{background:var(--select-bg);color:var(--select-ink);}

::placeholder{color:var(--ink-muted);opacity:1;}

/* Fixed header offset for every in-page anchor target (G4). */
:target,[id]{scroll-margin-top:calc(var(--header-h) + var(--sp-6));}


/* ==========================================================================
   7. ACCESSIBILITY PRIMITIVES
   ========================================================================== */

/* Visible focus ring on every interactive element (G4). */
:focus-visible{
  outline:var(--focus-w) solid var(--focus);
  outline-offset:var(--focus-gap);
  border-radius:var(--r-xs);
}
/* Suppress the mouse-click ring only where :focus-visible is supported. */
:focus:not(:focus-visible){outline:none;}

/* Skip link — first focusable element on every page. */
.skip-link{
  position:absolute;
  top:var(--sp-2);
  left:var(--sp-2);
  z-index:200;
  transform:translateY(-160%);
  background:var(--surface-1);
  color:var(--ink);
  border:1px solid var(--line-strong);
  border-radius:var(--r-sm);
  padding:var(--sp-3) var(--sp-5);
  font-size:var(--fs-sm);
  font-weight:var(--fw-semibold);
  box-shadow:var(--shadow-md);
  transition:transform var(--dur) var(--ease);
}
.skip-link:focus{transform:translateY(0);color:var(--ink);}

/* Screen-reader-only text. */
.visually-hidden{
  position:absolute;
  width:1px;height:1px;
  padding:0;margin:-1px;
  overflow:hidden;
  clip:rect(0 0 0 0);
  clip-path:inset(50%);
  white-space:nowrap;
  border:0;
}

/* Reveal-on-scroll. Pure CSS transitions — no GSAP, no CDN (G7).
   js/rovik.js adds .is-revealed via IntersectionObserver. */
[data-reveal]{
  opacity:0;
  transform:translateY(18px);
  transition:opacity var(--dur-slow) var(--ease-out),
             transform var(--dur-slow) var(--ease-out);
}
[data-reveal].is-revealed{opacity:1;transform:none;}

@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto;}
  *,*::before,*::after{
    animation-duration:0.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:0.01ms !important;
    scroll-behavior:auto !important;
  }
  [data-reveal]{opacity:1 !important;transform:none !important;}
}


/* ==========================================================================
   8. LAYOUT HELPERS
   ========================================================================== */

.wrap{
  width:100%;
  max-width:var(--maxw);
  margin:0 auto;
  padding-left:var(--pad);
  padding-right:var(--pad);
}

.section{
  position:relative;
  border-top:1px solid var(--line);
  background:var(--ground);
}
.section--flush{border-top:0;}
.section-pad{padding-top:var(--sp-section);padding-bottom:var(--sp-section);}

.page-hero{
  max-width:var(--maxw);
  margin:0 auto;
  padding:clamp(132px,13vw,186px) var(--pad) clamp(48px,6vw,80px);
}

.stack{display:flex;flex-direction:column;}
.stack-2{gap:var(--sp-2);} .stack-3{gap:var(--sp-3);}
.stack-4{gap:var(--sp-4);} .stack-6{gap:var(--sp-6);}
.stack-8{gap:var(--sp-8);} .stack-12{gap:var(--sp-12);}

.row{display:flex;flex-wrap:wrap;align-items:center;gap:var(--sp-4);}

.grid{display:grid;gap:var(--sp-6);}
.grid-2{grid-template-columns:repeat(auto-fit,minmax(280px,1fr));}
.grid-3{grid-template-columns:repeat(auto-fit,minmax(260px,1fr));}
.grid-4{grid-template-columns:repeat(auto-fit,minmax(220px,1fr));}

.measure{max-width:var(--maxw-prose);}

/* Horizontal-scroll container for wide tables and diagrams.
   The page body must never scroll sideways. */
.scroll-x{
  overflow-x:auto;
  -webkit-overflow-scrolling:touch;
}


/* ==========================================================================
   9. TYPOGRAPHY PRIMITIVES
   ========================================================================== */

.eyebrow{
  display:block;
  font-family:var(--mono);
  font-size:var(--fs-label);
  font-weight:var(--fw-medium);
  letter-spacing:var(--tr-label);
  text-transform:uppercase;
  color:var(--accent-ink);
  margin:0 0 var(--sp-4);
}

.kicker{
  display:block;
  font-family:var(--mono);
  font-size:var(--fs-label);
  font-weight:var(--fw-medium);
  letter-spacing:var(--tr-label);
  text-transform:uppercase;
  color:var(--ink-muted);
}

.display{
  font-size:var(--fs-display);
  line-height:var(--lh-display);
  letter-spacing:var(--tr-display);
  color:var(--ink);
  font-weight:var(--fw-bold);
}

.lede{
  font-size:var(--fs-lede);
  line-height:var(--lh-body);
  color:var(--ink-body);
  max-width:640px;
  margin-top:var(--sp-5);
}

.muted{color:var(--ink-muted);}
.faint{color:var(--ink-faint);}
.strong-ink{color:var(--ink);}
.accent-ink{color:var(--accent-ink);}
.gain-ink{color:var(--gain);}
.loss-ink{color:var(--loss);}
.warn-ink{color:var(--warn);}

.mono{font-family:var(--mono);}

.microcopy{
  font-family:var(--mono);
  font-size:var(--fs-xs);
  color:var(--ink-muted);
  letter-spacing:0.02em;
}

/* Numeric display, e.g. prices and calculator figures. */
.figure{
  font-family:var(--mono);
  font-weight:var(--fw-semibold);
  font-variant-numeric:tabular-nums;
  letter-spacing:-0.02em;
  color:var(--ink);
}

/* Long-form content: legal pages, About, article bodies. */
.prose{max-width:var(--maxw-prose);color:var(--ink-body);}
.prose h2{font-size:26px;letter-spacing:var(--tr-head);margin:var(--sp-12) 0 var(--sp-4);}
.prose h2:first-child{margin-top:0;}
.prose h3{font-size:18px;letter-spacing:var(--tr-body);margin:var(--sp-8) 0 var(--sp-3);color:var(--ink);}
.prose p{margin:0 0 var(--sp-4);font-size:15.5px;line-height:1.68;color:var(--ink-body);}
.prose ul,.prose ol{margin:0 0 var(--sp-4);padding-left:var(--sp-5);font-size:15.5px;line-height:1.68;color:var(--ink-body);}
.prose li{margin-bottom:var(--sp-2);}
.prose li::marker{color:var(--accent-ink);}
.prose a{color:var(--accent-ink);text-decoration:underline;text-underline-offset:3px;text-decoration-thickness:1px;}
.prose a:hover{color:var(--ink);}
.prose strong{color:var(--ink);}
.prose blockquote{
  margin:0 0 var(--sp-5);
  padding:var(--sp-4) var(--sp-5);
  border-left:3px solid var(--accent);
  background:var(--surface-2);
  border-radius:0 var(--r-md) var(--r-md) 0;
  color:var(--ink-body);
}


/* ==========================================================================
   10. BUTTONS — .btn plus one variant plus one size
   Variants: .btn-primary | .btn-ghost | .btn-subtle
   Sizes:    .btn-sm | (default) | .btn-lg
   ========================================================================== */

.btn{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  gap:var(--sp-2);
  font-family:var(--sans);
  font-size:15.5px;
  font-weight:var(--fw-semibold);
  line-height:1.2;
  letter-spacing:-0.01em;
  padding:13px 22px;
  border-radius:var(--r-sm);
  border:1px solid transparent;
  background:none;
  cursor:pointer;
  white-space:nowrap;
  text-align:center;
  touch-action:manipulation;
  -webkit-tap-highlight-color:var(--tap-highlight);
  transition:background var(--dur) var(--ease),
             border-color var(--dur) var(--ease),
             color var(--dur) var(--ease),
             box-shadow var(--dur) var(--ease),
             transform var(--dur) var(--ease);
}
.btn:disabled,.btn[aria-disabled="true"]{
  opacity:0.5;
  cursor:not-allowed;
  transform:none !important;
}

.btn-sm{padding:10px 18px;font-size:14.5px;border-radius:var(--r-xs);}
.btn-lg{padding:16px 30px;font-size:17px;border-radius:var(--r-md);}

/* Primary — brand orange fill, dark label. Identical fill in both themes.
   The 1px --accent-edge rim is not decoration: #E2701F against the light
   ground measures 2.91:1, under the 3:1 WCAG 1.4.11 asks of a control
   boundary. The rim carries the shape instead, at 5.87:1. */
.btn-primary{
  background:var(--accent);
  color:var(--on-accent);
  border-color:var(--accent-edge);
  box-shadow:var(--glow-accent);
}
.btn-primary:hover{
  background:var(--accent-hover);
  color:var(--on-accent);
  border-color:var(--accent-edge);
  box-shadow:var(--glow-accent-lg);
  transform:translateY(-2px);
}
.btn-primary:active{transform:translateY(0) scale(0.97);transition-duration:var(--dur-press);}

/* Ghost — outlined, transparent. */
.btn-ghost{
  border-color:var(--line-strong);
  color:var(--ink);
  background:transparent;
}
.btn-ghost:hover{
  background:var(--ink-wash);
  border-color:var(--accent);
  color:var(--ink);
  transform:translateY(-2px);
}
.btn-ghost:active{transform:translateY(0) scale(0.97);transition-duration:var(--dur-press);}

/* Subtle — filled with a surface, no border emphasis. */
.btn-subtle{
  background:var(--surface-2);
  border-color:var(--line);
  color:var(--ink);
}
.btn-subtle:hover{
  background:var(--surface-3);
  border-color:var(--line-strong);
  color:var(--ink);
}

.btn-subtle:active{transform:scale(0.97);transition-duration:var(--dur-press);}

/* Full-width on request. */
.btn-block{width:100%;}


/* ==========================================================================
   11. CARDS AND SURFACES
   ========================================================================== */

.card{
  background:var(--surface-1);
  border:1px solid var(--line);
  border-radius:var(--r-lg);
  padding:var(--sp-8) var(--sp-6);
  color:var(--ink-body);
}
.card--flat{background:var(--surface-2);box-shadow:none;}
.card--raised{box-shadow:var(--shadow-md);}
.card--accent{
  border-color:var(--line-accent);
  background:var(--surface-1);
  box-shadow:var(--shadow-md);
}
.card--interactive{
  transition:border-color var(--dur) var(--ease),
             box-shadow var(--dur) var(--ease),
             transform var(--dur) var(--ease);
}
.card--interactive:hover,
.card--interactive:focus-within{
  border-color:var(--line-strong);
  box-shadow:var(--shadow-lg);
  transform:translateY(-3px);
}

.card h3{margin-bottom:var(--sp-3);}
.card p{color:var(--ink-body);}

/* Panel: a heavier container for tables and comparison blocks. */
.panel{
  background:var(--surface-1);
  border:1px solid var(--line);
  border-radius:var(--r-xl);
  overflow:hidden;
}

.divider{height:1px;background:var(--line);border:0;margin:var(--sp-6) 0;}


/* ==========================================================================
   12. BADGES AND TAGS
   ========================================================================== */

.badge{
  display:inline-flex;
  align-items:center;
  gap:var(--sp-2);
  font-family:var(--mono);
  font-size:var(--fs-label);
  font-weight:var(--fw-medium);
  letter-spacing:0.09em;
  text-transform:uppercase;
  padding:5px 11px;
  border-radius:var(--r-full);
  border:1px solid var(--line-accent);
  background:var(--accent-wash);
  color:var(--accent-ink);
  white-space:nowrap;
}
.badge--gain{
  background:var(--gain-wash);
  border-color:var(--gain);
  color:var(--gain);
}
.badge--loss{
  background:var(--loss-wash);
  border-color:var(--loss);
  color:var(--loss);
}
.badge--warn{
  background:var(--warn-wash);
  border-color:var(--warn);
  color:var(--warn);
}
.badge--neutral{
  background:var(--ink-wash);
  border-color:var(--line-strong);
  color:var(--ink-muted);
}

.tag{
  font-family:var(--mono);
  font-size:var(--fs-label);
  letter-spacing:0.12em;
  text-transform:uppercase;
  color:var(--ink-muted);
}


/* ==========================================================================
   13. FORM CONTROLS
   ========================================================================== */

.field{display:flex;flex-direction:column;gap:var(--sp-2);}

.label{
  font-size:var(--fs-sm);
  font-weight:var(--fw-semibold);
  color:var(--ink);
}
.label .req{color:var(--loss);margin-left:2px;}

.hint{font-size:var(--fs-xs);color:var(--ink-muted);}

.input,
.textarea,
.select{
  width:100%;
  font-family:var(--sans);
  font-size:var(--fs-body);
  line-height:1.5;
  color:var(--ink);
  background:var(--surface-2);
  /* Solid, measured border — an empty input must be findable. */
  border:1px solid var(--field-border);
  border-radius:var(--r-sm);
  padding:12px 14px;
  transition:border-color var(--dur) var(--ease),
             background var(--dur) var(--ease),
             box-shadow var(--dur) var(--ease);
  -webkit-tap-highlight-color:var(--tap-highlight);
}
.textarea{min-height:140px;resize:vertical;}

.select{
  appearance:none;
  -webkit-appearance:none;
  padding-right:38px;
  cursor:pointer;
  /* Caret drawn as a border triangle on .select-wrap::after — no image, no CDN. */
}
.select-wrap{position:relative;display:block;}
.select-wrap::after{
  content:"";
  position:absolute;
  right:15px;
  top:50%;
  width:7px;height:7px;
  border-right:2px solid var(--ink-muted);
  border-bottom:2px solid var(--ink-muted);
  transform:translateY(-70%) rotate(45deg);
  pointer-events:none;
}

.input:hover,.textarea:hover,.select:hover{border-color:var(--ink-muted);background:var(--surface-3);}

.input:focus,.textarea:focus,.select:focus{
  outline:none;
  border-color:var(--accent);
  background:var(--surface-1);
  box-shadow:0 0 0 3px var(--accent-wash);
}
.input:focus-visible,.textarea:focus-visible,.select:focus-visible{
  outline:var(--focus-w) solid var(--focus);
  outline-offset:var(--focus-gap);
}

.input[aria-invalid="true"],
.textarea[aria-invalid="true"],
.select[aria-invalid="true"]{
  border-color:var(--loss);
  box-shadow:0 0 0 3px var(--loss-wash);
}

.error-text{font-size:var(--fs-xs);color:var(--loss);font-weight:var(--fw-medium);}

/* Checkbox and radio */
.check{display:flex;align-items:flex-start;gap:var(--sp-3);cursor:pointer;}
.check input[type="checkbox"],
.check input[type="radio"]{
  width:18px;height:18px;
  margin:2px 0 0;
  accent-color:var(--accent);
  cursor:pointer;
  flex:0 0 auto;
}
.check span{font-size:var(--fs-sm);color:var(--ink-body);}

/* Range slider */
.range{
  width:100%;
  height:26px;
  background:transparent;
  accent-color:var(--accent);
  cursor:pointer;
}

/* Status region for async form results (aria-live target). */
.form-status{
  font-size:var(--fs-sm);
  border-radius:var(--r-sm);
  padding:var(--sp-3) var(--sp-4);
  border:1px solid transparent;
}
.form-status:empty{display:none;}
.form-status--ok{background:var(--gain-wash);border-color:var(--gain);color:var(--gain);}
.form-status--err{background:var(--loss-wash);border-color:var(--loss);color:var(--loss);}


/* ==========================================================================
   14. THEME TOGGLE
   Logic and markup contract: js/theme.js. Task 2 writes the markup.
   ========================================================================== */

.theme-toggle{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width:38px;
  height:38px;
  flex:0 0 auto;
  padding:0;
  /* Icon-only control: no visible text label carries its identity, so the
     boundary is measured, not a decorative hairline. */
  border:1px solid var(--field-border);
  border-radius:var(--r-sm);
  background:transparent;
  color:var(--ink-muted);
  cursor:pointer;
  touch-action:manipulation;
  -webkit-tap-highlight-color:var(--tap-highlight);
  transition:color var(--dur) var(--ease),
             border-color var(--dur) var(--ease),
             background var(--dur) var(--ease);
}
.theme-toggle:hover{
  color:var(--ink);
  border-color:var(--accent);
  background:var(--ink-wash);
}
.theme-toggle svg{width:18px;height:18px;display:block;}

/* Exactly one icon is visible at a time. The theme.js contract requires both
   icons to exist in the markup at all times; CSS decides which one shows. */
.theme-toggle .icon-sun{display:none;}
.theme-toggle .icon-moon{display:block;}

@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]) .theme-toggle .icon-sun{display:block;}
  :root:not([data-theme="light"]) .theme-toggle .icon-moon{display:none;}
}
:root[data-theme="dark"] .theme-toggle .icon-sun{display:block;}
:root[data-theme="dark"] .theme-toggle .icon-moon{display:none;}
:root[data-theme="light"] .theme-toggle .icon-sun{display:none;}
:root[data-theme="light"] .theme-toggle .icon-moon{display:block;}


/* ==========================================================================
   15. TABLES
   ========================================================================== */

.table{
  width:100%;
  border-collapse:collapse;
  font-size:var(--fs-sm);
  color:var(--ink-body);
}
.table th,.table td{
  text-align:left;
  padding:var(--sp-4) var(--sp-5);
  border-bottom:1px solid var(--line);
  vertical-align:top;
}
.table thead th{
  font-family:var(--mono);
  font-size:var(--fs-label);
  font-weight:var(--fw-medium);
  letter-spacing:var(--tr-label);
  text-transform:uppercase;
  color:var(--ink-muted);
  background:var(--surface-2);
  border-bottom:1px solid var(--line-strong);
}
.table tbody tr:last-child td{border-bottom:0;}
.table tbody tr:hover{background:var(--ink-wash);}
.table .cell-yes{color:var(--gain);font-weight:var(--fw-semibold);}
.table .cell-no{color:var(--ink-faint);}
.table caption{
  caption-side:top;
  text-align:left;
  padding:0 var(--sp-5) var(--sp-4);
  font-size:var(--fs-sm);
  color:var(--ink-muted);
}


/* ==========================================================================
   16. LISTS WITH MARKS
   ========================================================================== */

.list-check{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:var(--sp-3);}
.list-check li{
  position:relative;
  padding-left:26px;
  margin:0;
  font-size:var(--fs-sm);
  color:var(--ink-body);
}
.list-check li::before{
  content:"";
  position:absolute;
  left:2px;
  top:6px;
  width:6px;height:11px;
  border-right:2px solid var(--gain);
  border-bottom:2px solid var(--gain);
  transform:rotate(45deg);
}

.list-num{list-style:none;padding:0;margin:0;counter-reset:rovik-step;}
.list-num li{
  counter-increment:rovik-step;
  position:relative;
  padding-left:44px;
  margin:0 0 var(--sp-5);
}
.list-num li::before{
  content:counter(rovik-step,decimal-leading-zero);
  position:absolute;
  left:0;top:1px;
  font-family:var(--mono);
  font-size:var(--fs-xs);
  font-weight:var(--fw-semibold);
  color:var(--accent-ink);
  letter-spacing:0.08em;
}


/* ==========================================================================
   17. DETAILS / ACCORDION (FAQ)
   No hover-only content anywhere — everything opens on click and on focus.
   ========================================================================== */

.faq{border-top:1px solid var(--line);}
.faq-item{border-bottom:1px solid var(--line);}
.faq-item summary{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:var(--sp-4);
  padding:var(--sp-5) 0;
  font-size:var(--fs-h4);
  font-weight:var(--fw-semibold);
  color:var(--ink);
}
.faq-item summary:hover{color:var(--accent-ink);}
.faq-item summary::after{
  content:"";
  flex:0 0 auto;
  width:9px;height:9px;
  border-right:2px solid var(--ink-muted);
  border-bottom:2px solid var(--ink-muted);
  transform:rotate(45deg);
  transition:transform var(--dur) var(--ease);
}
.faq-item[open] summary::after{transform:rotate(-135deg);}
.faq-answer{padding:0 0 var(--sp-6);color:var(--ink-body);font-size:var(--fs-sm);line-height:1.68;max-width:var(--maxw-prose);}


/* ==========================================================================
   17b. DEPTH - dimensional gradients
   These are the "3D" layer: soft orange glow bleeding behind a hero, a light
   sheen along the top edge of a card, a gradient rule. All pure CSS, so no
   library and no build step (G7).

   Two rules, both non-negotiable:
   1. An atmosphere layer is DECORATIVE. It is aria-hidden, it never receives
      pointer events, and no text is ever placed directly on its densest
      point without re-running the contrast check.
   2. It must be readable in BOTH themes. A glow tuned for the dark ground
      turns to mud on the light one, which is why --orb-accent is a different
      strength per theme.
   ========================================================================== */

/* Container for an atmosphere layer. */
.has-depth{position:relative;isolation:isolate;}

/* The layer itself. Markup: <div class="atmosphere" aria-hidden="true"></div>
   as the FIRST child of a .has-depth element. */
.atmosphere{
  position:absolute;
  inset:0;
  z-index:-1;
  pointer-events:none;
  background-image:var(--grad-hero);
  background-repeat:no-repeat;
}
.atmosphere--orb{background-image:var(--grad-orb);}

/* Everything the atmosphere sits behind must establish its own stacking
   context, or the negative z-index drops it behind the page background. */
.has-depth > *:not(.atmosphere){position:relative;}

/* A card with a lit top edge. This is what reads as dimensional. */
.card--dimensional{position:relative;overflow:hidden;box-shadow:var(--shadow-md);}
.card--dimensional::before{
  content:"";
  position:absolute;
  inset:0 0 auto 0;
  height:60%;
  background-image:var(--grad-sheen);
  pointer-events:none;
  z-index:0;
}
.card--dimensional > *{position:relative;z-index:1;}

/* Gradient accent bar - a 3px rule above a heading, or a progress fill. */
.accent-bar{
  display:block;
  height:3px;
  width:56px;
  border-radius:var(--r-full);
  background-image:var(--grad-accent-bar);
}

/* Hairline that fades out at both ends, instead of stopping dead. */
.fade-line{
  height:1px;
  border:0;
  background-image:var(--grad-fade-line);
}

@media (prefers-reduced-motion:reduce){
  .atmosphere{transition:none;}
}


/* ==========================================================================
   17c. SECTION RHYTHM - stopping the page being one flat colour
   Five treatments. Alternate them down a page so the eye gets a beat.
   All colour comes from tokens, so every variant works in both themes.
   ========================================================================== */

.section--alt{background:var(--ground-deep);}
.section--tint{background:var(--surface-2);}

/* The contrast band. In light mode a dark block; in dark mode a lifted one.
   It rebinds the ink tokens locally, so EVERY primitive inside it - buttons,
   cards, eyebrows, links, inputs - adapts automatically with no extra
   classes and no risk of dark text landing on a dark band. */
.section--band{
  background:var(--band-ground);
  --ground:var(--band-ground);
  --ground-deep:var(--band-ground);
  --surface-1:var(--band-surface);
  --surface-2:var(--band-surface);
  --surface-3:var(--band-surface);
  --ink:var(--band-ink);
  --ink-body:var(--band-ink-body);
  --ink-muted:var(--band-ink-muted);
  --ink-faint:var(--band-ink-muted);
  --accent-ink:var(--band-accent-ink);
  --line:var(--band-line);
  --line-strong:var(--band-line-strong);
  --field-border:var(--band-field-border);
  --focus:var(--band-accent-ink);
  color:var(--band-ink-body);
}

/* A band with the glow behind it - the most "alive" treatment. Use sparingly:
   once on the home page, at most once elsewhere. */
.section--depth{position:relative;isolation:isolate;overflow:hidden;}
.section--depth > .atmosphere{z-index:-1;}

/* Hairline that fades at the ends, for a softer section join. */
.section--soft-edge{border-top:0;}
.section--soft-edge::before{
  content:"";
  display:block;
  height:1px;
  background-image:var(--grad-fade-line);
}


/* ==========================================================================
   17d. MOTION - restrained, and entirely optional
   Every animation here is switched off by the prefers-reduced-motion block
   in section 7. Nothing below is required to understand the page: motion
   draws attention, it never carries meaning.
   ========================================================================== */

/* -- Reveal variants. js/rovik.js adds .is-revealed on scroll. ----------- */
[data-reveal="fade"]{transform:none;}
[data-reveal="left"]{transform:translateX(-24px);}
[data-reveal="right"]{transform:translateX(24px);}
[data-reveal="scale"]{transform:scale(0.965);}
[data-reveal].is-revealed{opacity:1;transform:none;}

/* Stagger. Put data-reveal-delay="1".."6" on successive cards in a grid so
   they arrive in sequence instead of all at once. */
[data-reveal-delay="1"]{transition-delay:60ms;}
[data-reveal-delay="2"]{transition-delay:120ms;}
[data-reveal-delay="3"]{transition-delay:180ms;}
[data-reveal-delay="4"]{transition-delay:240ms;}
[data-reveal-delay="5"]{transition-delay:300ms;}
[data-reveal-delay="6"]{transition-delay:360ms;}

/* -- Hover lift. Also fires on :focus-within, so keyboard users get it. -- */
.hover-lift{
  transition:transform var(--dur) var(--ease-out),
             box-shadow var(--dur) var(--ease-out),
             border-color var(--dur) var(--ease);
}
.hover-lift:hover,.hover-lift:focus-within{
  transform:translateY(-4px);
  box-shadow:var(--shadow-lg);
  border-color:var(--line-strong);
}

/* -- Link underline that grows from the left. --------------------------- */
.link-grow{position:relative;}
.link-grow::after{
  content:"";
  position:absolute;
  left:0;bottom:-3px;
  height:2px;width:100%;
  background:var(--accent-ink);
  transform:scaleX(0);
  transform-origin:left;
  transition:transform var(--dur) var(--ease-out);
}
.link-grow:hover::after,.link-grow:focus-visible::after{transform:scaleX(1);}

/* -- Ambient drift on an atmosphere layer. Slow enough to be felt, not
      watched. Pauses for reduced-motion. --------------------------------- */
@keyframes rovik-drift{
  0%{transform:translate3d(0,0,0) scale(1);}
  100%{transform:translate3d(2%,-2%,0) scale(1.06);}
}
.atmosphere--drift{
  animation:rovik-drift 22s var(--ease) infinite alternate;
  will-change:transform;
}

/* -- "Live" pulse, for a status dot next to "answering calls right now". - */
@keyframes rovik-pulse{
  0%,100%{opacity:0.35;transform:scale(1);}
  50%{opacity:1;transform:scale(1.5);}
}
.pulse-dot{
  display:inline-block;
  width:8px;height:8px;
  border-radius:var(--r-full);
  background:var(--gain);
  position:relative;
  flex:0 0 auto;
}
.pulse-dot::after{
  content:"";
  position:absolute;
  inset:0;
  border-radius:inherit;
  background:inherit;
  animation:rovik-pulse 2.4s var(--ease) infinite;
}

/* -- Sweep across the accent bar. --------------------------------------- */
@keyframes rovik-sweep{
  0%{background-position:0% 50%;}
  100%{background-position:200% 50%;}
}
.accent-bar--live{
  background-size:200% 100%;
  animation:rovik-sweep 3.5s linear infinite;
}

/* -- Any auto-advancing element must pause on hover AND focus (G4). ------
   js/rovik.js also pauses its timer; this is the CSS half. */
[data-autoplay]:hover,
[data-autoplay]:focus-within{animation-play-state:paused;}
[data-autoplay]:hover *,
[data-autoplay]:focus-within *{animation-play-state:paused;}


/* ==========================================================================
   17e. PRODUCT MOCKUPS - the "images" on this site
   --------------------------------------------------------------------------
   There is no photography here, deliberately. A stock photo of a smiling
   contractor implies a customer that does not exist yet, which is the same
   fabrication G1 bans in written form. Instead the site shows the MECHANISM:
   a call arriving, a transcript, a booking, a confirmation, a record.

   These are built from CSS and tokens - no image files, no CDN, nothing to
   optimise later. They adapt to both themes for free, stay sharp on any
   display, and cost no bandwidth.

   G2: every example must stay location-agnostic. Use a masked number
   (+.. ... ... ..82) or "unknown number". Never a real national format.
   ========================================================================== */

/* -- The window chrome every mockup sits in ----------------------------- */
.ui-panel{
  background:var(--surface-1);
  border:1px solid var(--line-strong);
  border-radius:var(--r-lg);
  overflow:hidden;
  box-shadow:var(--shadow-lg);
}
.ui-panel__bar{
  display:flex;
  align-items:center;
  gap:var(--sp-3);
  padding:var(--sp-3) var(--sp-4);
  background:var(--surface-2);
  border-bottom:1px solid var(--line);
  font-family:var(--mono);
  font-size:var(--fs-label);
  letter-spacing:var(--tr-label);
  text-transform:uppercase;
  color:var(--ink-muted);
}
.ui-panel__body{padding:var(--sp-5);}
.ui-panel__foot{
  padding:var(--sp-3) var(--sp-5);
  border-top:1px solid var(--line);
  background:var(--surface-2);
  font-size:var(--fs-xs);
  color:var(--ink-muted);
}

/* -- Live call header ---------------------------------------------------- */
.ui-call{display:flex;align-items:center;gap:var(--sp-4);}
.ui-call__num{
  font-family:var(--mono);
  font-size:var(--fs-h4);
  color:var(--ink);
  letter-spacing:0.04em;
}
.ui-call__meta{font-size:var(--fs-xs);color:var(--ink-muted);}
.ui-call__timer{
  margin-left:auto;
  font-family:var(--mono);
  font-size:var(--fs-sm);
  color:var(--gain);
  font-variant-numeric:tabular-nums;
}

/* -- Transcript ---------------------------------------------------------- */
.ui-transcript{display:flex;flex-direction:column;gap:var(--sp-3);}
.ui-turn{
  max-width:82%;
  padding:var(--sp-3) var(--sp-4);
  border-radius:var(--r-md);
  font-size:var(--fs-sm);
  line-height:1.55;
}
.ui-turn__who{
  display:block;
  font-family:var(--mono);
  font-size:var(--fs-label);
  letter-spacing:var(--tr-label);
  text-transform:uppercase;
  margin-bottom:var(--sp-1);
}
.ui-turn--system{
  align-self:flex-start;
  background:var(--surface-2);
  border:1px solid var(--line);
  color:var(--ink-body);
}
.ui-turn--system .ui-turn__who{color:var(--accent-ink);}
.ui-turn--caller{
  align-self:flex-end;
  background:var(--surface-3);
  border:1px solid var(--line);
  color:var(--ink-body);
}
.ui-turn--caller .ui-turn__who{color:var(--ink-muted);}

/* -- Waveform. Pure CSS bars; no audio, purely indicative. --------------- */
.ui-wave{display:flex;align-items:center;gap:3px;height:26px;}
.ui-wave span{
  display:block;
  width:3px;
  border-radius:var(--r-full);
  background:var(--accent);
  height:35%;
}
.ui-wave span:nth-child(3n){height:80%;}
.ui-wave span:nth-child(4n){height:55%;}
.ui-wave span:nth-child(5n){height:100%;}
.ui-wave span:nth-child(7n){height:20%;}

@keyframes rovik-wave{0%,100%{transform:scaleY(0.45);}50%{transform:scaleY(1);}}
.ui-wave--live span{
  animation:rovik-wave 1.1s var(--ease) infinite;
  transform-origin:center;
}
.ui-wave--live span:nth-child(2n){animation-delay:0.12s;}
.ui-wave--live span:nth-child(3n){animation-delay:0.24s;}
.ui-wave--live span:nth-child(5n){animation-delay:0.36s;}

/* -- Qualification / CRM record ------------------------------------------ */
.ui-record{display:flex;flex-direction:column;}
.ui-field{
  display:flex;
  gap:var(--sp-4);
  padding:var(--sp-3) 0;
  border-bottom:1px solid var(--line);
  font-size:var(--fs-sm);
}
.ui-field:last-child{border-bottom:0;}
.ui-field__k{
  flex:0 0 40%;
  font-family:var(--mono);
  font-size:var(--fs-xs);
  letter-spacing:0.08em;
  text-transform:uppercase;
  color:var(--ink-muted);
}
.ui-field__v{flex:1;color:var(--ink);font-weight:var(--fw-medium);}

/* -- Calendar slots ------------------------------------------------------ */
.ui-slots{display:grid;grid-template-columns:repeat(auto-fit,minmax(92px,1fr));gap:var(--sp-2);}
.ui-slot{
  padding:var(--sp-3) var(--sp-2);
  border:1px solid var(--line-strong);
  border-radius:var(--r-sm);
  text-align:center;
  font-family:var(--mono);
  font-size:var(--fs-sm);
  color:var(--ink-body);
  background:var(--surface-2);
}
.ui-slot--taken{
  color:var(--ink-faint);
  background:transparent;
  text-decoration:line-through;
}
.ui-slot--picked{
  background:var(--accent);
  border-color:var(--accent-edge);
  color:var(--on-accent);
  font-weight:var(--fw-semibold);
}

/* -- SMS confirmation ---------------------------------------------------- */
.ui-sms{
  max-width:300px;
  padding:var(--sp-4);
  border-radius:var(--r-lg) var(--r-lg) var(--r-xs) var(--r-lg);
  background:var(--accent);
  color:var(--on-accent);
  font-size:var(--fs-sm);
  line-height:1.5;
  border:1px solid var(--accent-edge);
}
.ui-sms__meta{
  display:block;
  margin-top:var(--sp-2);
  font-family:var(--mono);
  font-size:var(--fs-label);
  color:var(--on-accent-muted);
}

/* -- Stat tile ----------------------------------------------------------- */
.stat-tile{
  padding:var(--sp-5);
  border:1px solid var(--line);
  border-radius:var(--r-md);
  background:var(--surface-1);
}
.stat-tile__k{
  display:block;
  font-family:var(--mono);
  font-size:var(--fs-label);
  letter-spacing:var(--tr-label);
  text-transform:uppercase;
  color:var(--ink-muted);
  margin-bottom:var(--sp-2);
}
.stat-tile__v{
  display:block;
  font-family:var(--mono);
  font-size:28px;
  font-weight:var(--fw-semibold);
  font-variant-numeric:tabular-nums;
  color:var(--ink);
  letter-spacing:-0.02em;
}

/* -- Brand surface patterns. CSS gradients, not images. ------------------ */
.pattern-grid{
  background-image:
    linear-gradient(var(--line) 1px,transparent 1px),
    linear-gradient(90deg,var(--line) 1px,transparent 1px);
  background-size:44px 44px;
}
.pattern-dots{
  background-image:radial-gradient(var(--line-strong) 1px,transparent 1px);
  background-size:22px 22px;
}
.pattern-mask{
  -webkit-mask-image:radial-gradient(70% 60% at 50% 0%,var(--mask-opaque) 0%,transparent 75%);
  mask-image:radial-gradient(70% 60% at 50% 0%,var(--mask-opaque) 0%,transparent 75%);
}


/* ==========================================================================
   18. UTILITIES
   ========================================================================== */

.text-center{text-align:center;}
.center{margin-left:auto;margin-right:auto;}
.nowrap{white-space:nowrap;}
.full{width:100%;}
.mt-0{margin-top:0;} .mt-4{margin-top:var(--sp-4);} .mt-6{margin-top:var(--sp-6);}
.mt-8{margin-top:var(--sp-8);} .mt-12{margin-top:var(--sp-12);}
.mb-0{margin-bottom:0;} .mb-4{margin-bottom:var(--sp-4);} .mb-6{margin-bottom:var(--sp-6);}
.mb-8{margin-bottom:var(--sp-8);} .mb-12{margin-bottom:var(--sp-12);}

/* Print: force the light palette, drop decoration. */
@media print{
  .skip-link,.theme-toggle{display:none !important;}
  body{background:var(--ground);color:var(--ink);}
  .card,.panel{box-shadow:none;}
}


/* ==========================================================================
   19. SHELL - header, nav, mobile menu, footer
   Merged from css/shell.css. Kept as one stylesheet per G7.
   ========================================================================== */

/* ==========================================================================
   Rovik v3 — SHARED SHELL (header, mobile navigation, footer)
   --------------------------------------------------------------------------
   Loaded by EVERY page, immediately after css/rovik.css:

     <link rel="stylesheet" href="css/rovik.css">
     <link rel="stylesheet" href="css/shell.css">

   WHY THIS IS A SEPARATE FILE
   ---------------------------
   Task 1 shipped css/rovik.css as the token + primitive layer and Task 2 was
   instructed not to edit it. Shell layout therefore lives here, following the
   same convention rovik.css already documents for css/calculator.css.

   RULES THIS FILE OBEYS
   ---------------------
   - Not one colour literal. Every colour is a var() from rovik.css. The
     contrast script parses rovik.css only, so a raw hex here would be
     unmeasured and unverifiable.
   - No hover-only content (G4). Anything a hover reveals also reveals on
     :focus-within and is visible by default on small screens.
   - The mobile menu is a real disclosure, not display:none. See section 3.
   ========================================================================== */


/* ==========================================================================
   1. HEADER SHELL
   --------------------------------------------------------------------------
   Fixed, full-bleed, transparent at the top of the page and solid once the
   reader scrolls. js/rovik.js adds .is-solid; the page still reads correctly
   with JS off because the resting state sits directly on --ground.
   ========================================================================== */

.site-header{
  position:fixed;
  top:0;left:0;right:0;
  z-index:100;
  height:var(--header-h);
  display:flex;
  align-items:center;
  background:transparent;
  border-bottom:1px solid transparent;
  transition:background var(--dur) var(--ease),
             border-color var(--dur) var(--ease),
             box-shadow var(--dur) var(--ease);
}
.site-header.is-solid{
  background:var(--ground);
  border-bottom-color:var(--line);
  box-shadow:var(--shadow-sm);
}

/* While the menu is open the header must be opaque whatever the scroll
   position, or the panel shows through it. */
.nav-open .site-header{
  background:var(--ground);
  border-bottom-color:var(--line);
}

.site-header__inner{
  display:flex;
  align-items:center;
  gap:var(--sp-6);
  width:100%;
}

/* The 1px probe js/rovik.js watches to decide .is-solid. Zero height, zero
   cost, and it means no scroll handler runs on every frame. */
.header-sentinel{
  position:absolute;
  top:0;left:0;
  width:1px;height:1px;
  pointer-events:none;
}


/* -- 1.1 Brand ----------------------------------------------------------- */

.brand{
  display:inline-flex;
  align-items:center;
  gap:var(--sp-3);
  flex:0 0 auto;
  color:var(--ink);
  font-weight:var(--fw-bold);
  font-size:19px;
  letter-spacing:-0.03em;
  line-height:1;
}
.brand:hover{color:var(--ink);}
.brand img{
  width:30px;height:30px;
  border-radius:var(--r-xs);
  flex:0 0 auto;
}
.brand__dot{color:var(--accent-ink);}


/* -- 1.2 Desktop navigation ---------------------------------------------- */

.site-nav{margin-left:auto;}

.site-nav__list{
  display:flex;
  align-items:center;
  gap:var(--sp-1);
  list-style:none;
  margin:0;padding:0;
}
.site-nav__list li{margin:0;}

.site-nav__link{
  position:relative;
  display:inline-block;
  padding:9px 13px;
  border-radius:var(--r-xs);
  font-size:14.5px;
  font-weight:var(--fw-medium);
  color:var(--ink-muted);
  white-space:nowrap;
  transition:color var(--dur) var(--ease),
             background var(--dur) var(--ease);
}
.site-nav__link:hover{color:var(--ink);background:var(--ink-wash);}
.site-nav__link[aria-current="page"]{color:var(--ink);}
.site-nav__link[aria-current="page"]::after{
  content:"";
  position:absolute;
  left:13px;right:13px;
  bottom:2px;
  height:2px;
  border-radius:var(--r-full);
  background:var(--accent);
}


/* -- 1.3 Header actions -------------------------------------------------- */

.site-header__actions{
  display:flex;
  align-items:center;
  gap:var(--sp-3);
  flex:0 0 auto;
}
.site-header__cta{flex:0 0 auto;}


/* ==========================================================================
   2. THE MENU BUTTON
   --------------------------------------------------------------------------
   Hidden on wide screens, shown at and below the nav breakpoint. It is a
   button, not a link, it carries aria-expanded and aria-controls, and its
   accessible name is real text in a .visually-hidden span so js/rovik.js can
   rewrite it between "Open menu" and "Close menu".
   ========================================================================== */

.nav-toggle{
  display:none;
  align-items:center;
  justify-content:center;
  width:38px;height:38px;
  flex:0 0 auto;
  padding:0;
  border:1px solid var(--field-border);
  border-radius:var(--r-sm);
  background:transparent;
  color:var(--ink);
  cursor:pointer;
  touch-action:manipulation;
  -webkit-tap-highlight-color:var(--tap-highlight);
  transition:color var(--dur) var(--ease),
             border-color var(--dur) var(--ease),
             background var(--dur) var(--ease);
}
.nav-toggle:hover{border-color:var(--accent);background:var(--ink-wash);}

.nav-toggle__bars{
  position:relative;
  display:block;
  width:18px;height:12px;
}
.nav-toggle__bars span{
  position:absolute;
  left:0;right:0;
  height:2px;
  border-radius:var(--r-full);
  background:currentColor;
  transition:transform var(--dur) var(--ease),
             opacity var(--dur-fast) var(--ease);
}
.nav-toggle__bars span:nth-child(1){top:0;}
.nav-toggle__bars span:nth-child(2){top:5px;}
.nav-toggle__bars span:nth-child(3){top:10px;}

.nav-toggle[aria-expanded="true"] .nav-toggle__bars span:nth-child(1){transform:translateY(5px) rotate(45deg);}
.nav-toggle[aria-expanded="true"] .nav-toggle__bars span:nth-child(2){opacity:0;}
.nav-toggle[aria-expanded="true"] .nav-toggle__bars span:nth-child(3){transform:translateY(-5px) rotate(-45deg);}


/* ==========================================================================
   3. THE MOBILE MENU PANEL
   --------------------------------------------------------------------------
   The v2 build shipped `@media (max-width:920px){[data-navlinks]{display:none}}`
   with nothing in its place: on every phone the whole navigation vanished and
   an interior page had no route back into the site. This is the replacement.

   It sits BELOW the header rather than over it, so the brand, the theme
   toggle and the close button stay visible and operable while it is open.
   ========================================================================== */

.mobile-menu{
  position:fixed;
  top:var(--header-h);
  left:0;right:0;bottom:0;
  z-index:99;
  background:var(--ground);
  border-top:1px solid var(--line);
  overflow-y:auto;
  overscroll-behavior:contain;              /* scrolling it never scrolls the page */
  -webkit-overflow-scrolling:touch;
  padding:var(--sp-6) 0 var(--sp-16);
  opacity:0;
  transform:translateY(-8px);
  transition:opacity var(--dur) var(--ease),
             transform var(--dur) var(--ease);
}
.mobile-menu[hidden]{display:none;}
.mobile-menu.is-open{opacity:1;transform:none;}
.mobile-menu:focus{outline:none;}

/* Page scroll lock while the panel is open. Applied to <html>. */
.nav-open,
.nav-open body{overflow:hidden;}

.mobile-menu__list{
  list-style:none;
  margin:0 0 var(--sp-6);
  padding:0;
  border-top:1px solid var(--line);
}
.mobile-menu__list li{margin:0;}

.mobile-menu__link{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:var(--sp-4);
  min-height:56px;                          /* comfortable touch target */
  padding:var(--sp-4) var(--sp-1);
  border-bottom:1px solid var(--line);
  font-size:19px;
  font-weight:var(--fw-semibold);
  letter-spacing:-0.02em;
  color:var(--ink);
}
.mobile-menu__link:hover{color:var(--accent-ink);}
.mobile-menu__link[aria-current="page"]{color:var(--accent-ink);}
.mobile-menu__link::after{
  content:"";
  flex:0 0 auto;
  width:8px;height:8px;
  border-top:2px solid var(--ink-faint);
  border-right:2px solid var(--ink-faint);
  transform:rotate(45deg);
}

.mobile-menu__cta{margin-bottom:var(--sp-6);}

.mobile-menu__meta{
  display:flex;
  flex-direction:column;
  gap:var(--sp-2);
  padding-top:var(--sp-5);
  border-top:1px solid var(--line);
}
.mobile-menu__meta a{
  font-size:var(--fs-sm);
  color:var(--ink-muted);
}
.mobile-menu__meta a:hover{color:var(--accent-ink);}


/* ==========================================================================
   4. THE NAVIGATION BREAKPOINT
   --------------------------------------------------------------------------
   Swaps at 1024px, not 920px. Between 920 and 1024 the five nav items plus
   the full-length CTA crowd each other, and a crowded header is the reason
   the previous build reached for display:none in the first place. The
   requirement — a reachable menu button below 920px — is satisfied by a
   wider band, not a narrower one.
   ========================================================================== */

@media (max-width:1024px){
  .site-nav{display:none;}
  .site-header__cta{display:none;}
  .nav-toggle{display:inline-flex;}
  .site-header__actions{margin-left:auto;}
}

@media (min-width:1025px){
  .mobile-menu{display:none;}
}


/* ==========================================================================
   5. FOOTER
   --------------------------------------------------------------------------
   Four columns. No geography, no phone number, no address (G2, G8). The
   contact column carries the email and the booking link and nothing else.
   ========================================================================== */

.site-footer{
  background:var(--ground-deep);
  border-top:1px solid var(--line);
}

.site-footer__grid{
  display:grid;
  grid-template-columns:1.6fr 1fr 1fr 1.2fr;
  gap:var(--sp-10) var(--sp-8);
  padding-top:var(--sp-16);
  padding-bottom:var(--sp-12);
}
@media (max-width:900px){
  .site-footer__grid{grid-template-columns:repeat(2,minmax(0,1fr));}
}
@media (max-width:520px){
  .site-footer__grid{grid-template-columns:1fr;}
}

.site-footer__blurb{
  margin-top:var(--sp-4);
  max-width:34ch;
  font-size:var(--fs-sm);
  line-height:1.6;
  color:var(--ink-muted);
}

.site-footer__head{
  font-family:var(--mono);
  font-size:var(--fs-label);
  font-weight:var(--fw-medium);
  letter-spacing:var(--tr-label);
  text-transform:uppercase;
  color:var(--ink-faint);
  margin-bottom:var(--sp-4);
}

.site-footer__col ul{
  list-style:none;
  margin:0;padding:0;
  display:flex;
  flex-direction:column;
  gap:var(--sp-3);
}
.site-footer__col li{margin:0;}
.site-footer__col a{
  font-size:var(--fs-sm);
  color:var(--ink-muted);
}
.site-footer__col a:hover{color:var(--accent-ink);}
.site-footer__col a[aria-current="page"]{color:var(--ink);}

.site-footer__bottom{
  display:flex;
  flex-wrap:wrap;
  align-items:center;
  justify-content:space-between;
  gap:var(--sp-4);
  padding-top:var(--sp-6);
  padding-bottom:var(--sp-8);
  border-top:1px solid var(--line);
  font-size:var(--fs-xs);
  color:var(--ink-faint);
}


/* ==========================================================================
   20. HOME PAGE
   Merged from css/home.css. Kept as one stylesheet per G7.
   ========================================================================== */

/* ==========================================================================
   Rovik v3 — HOMEPAGE ONLY
   --------------------------------------------------------------------------
   Loaded by index.html alone, after css/rovik.css and css/shell.css.
   Same rule as shell.css: not one colour literal, every colour a var().
   ========================================================================== */


/* ==========================================================================
   1. HERO
   --------------------------------------------------------------------------
   One ambient gradient on the page, and it lives here. Nothing else on the
   homepage glows, blurs or floats — the restraint is the point.
   ========================================================================== */

.hero{
  position:relative;
  overflow:hidden;
  padding:calc(var(--header-h) + clamp(44px,6vw,84px)) 0 clamp(56px,8vw,104px);
}

.hero__glow{
  position:absolute;
  top:-38%;
  right:-16%;
  width:min(940px,110vw);
  height:min(940px,110vw);
  pointer-events:none;
  border-radius:50%;
  background:radial-gradient(circle at 50% 50%,
             var(--accent-wash) 0%,
             var(--ink-wash) 38%,
             transparent 68%);
}

.hero__inner{position:relative;z-index:1;}

.hero__grid{
  display:grid;
  grid-template-columns:minmax(0,1.02fr) minmax(0,1fr);
  gap:clamp(44px,5vw,76px);
  align-items:center;
}
@media (max-width:980px){
  .hero__grid{grid-template-columns:minmax(0,1fr);gap:var(--sp-12);}
}

/* .badge supplies the pill; these three overrides make it hold a full
   sentence. .badge is nowrap and uppercase by default, which would push a
   28-word eyebrow off the side of the page. */
.hero__eyebrow{
  display:inline-flex;
  align-items:center;
  gap:var(--sp-2);
  max-width:100%;
  text-transform:none;
  white-space:normal;
  letter-spacing:0.06em;
  font-size:var(--fs-xs);
  line-height:1.5;
  padding:6px 13px;
}
.hero__eyebrow .dot{
  width:6px;height:6px;
  border-radius:50%;
  background:var(--accent);
  flex:0 0 auto;
  animation:rovik-pulse 2.4s var(--ease) infinite;
}
@keyframes rovik-pulse{
  0%,100%{opacity:1;transform:scale(1);}
  50%{opacity:0.45;transform:scale(0.72);}
}

.hero h1{margin-top:var(--sp-6);font-size:var(--fs-display);}
.hero__lede{max-width:33em;}

.hero__actions{
  display:flex;
  flex-wrap:wrap;
  gap:var(--sp-3);
  margin-top:var(--sp-8);
}

.hero__micro{margin-top:var(--sp-5);}


/* ==========================================================================
   2. THE INTAKE SEQUENCE CARD STACK
   --------------------------------------------------------------------------
   Five cards, one highlighted at a time, connected by a vertical hairline.
   js/rovik.js advances the highlight. It PAUSES on hover and on focus, stops
   when the tab is hidden, and never starts at all under prefers-reduced-
   motion — the v2 build ran a bare setInterval with no pause of any kind,
   which fails WCAG 2.2.2.

   The stack is figure + figcaption, and the caption says plainly that it is
   an illustration. No reader should mistake it for a customer record (G1).
   ========================================================================== */

.seq{
  position:relative;
  margin:0;
  padding-left:var(--sp-10);
}
.seq:focus{outline:none;}

.seq__rail{
  position:absolute;
  left:13px;
  top:22px;bottom:34px;
  width:1px;
  background:linear-gradient(180deg,
             transparent 0%,
             var(--line-accent) 18%,
             var(--line-accent) 82%,
             transparent 100%);
  pointer-events:none;
}

.seq__card{
  position:relative;
  margin-bottom:var(--sp-3);
  padding:var(--sp-4) var(--sp-5);
  background:var(--surface-1);
  border:1px solid var(--line);
  border-radius:var(--r-md);
  transition:border-color var(--dur-slow) var(--ease),
             box-shadow var(--dur-slow) var(--ease),
             transform var(--dur-slow) var(--ease-out);
}
.seq__card:last-child{margin-bottom:0;}

/* The node on the rail. */
.seq__card::before{
  content:"";
  position:absolute;
  left:calc(-1 * var(--sp-10) + 9px);
  top:22px;
  width:9px;height:9px;
  border-radius:50%;
  background:var(--surface-3);
  border:1px solid var(--line-strong);
  transition:background var(--dur-slow) var(--ease),
             border-color var(--dur-slow) var(--ease),
             transform var(--dur-slow) var(--ease-out);
}

.seq__card.is-active{
  border-color:var(--line-accent);
  box-shadow:var(--shadow-md);
  transform:translateX(6px);
}
/* The card slides 6px right when active; the node must not, or it walks off
   the rail. Counter-translate it by the same amount. */
.seq__card.is-active::before{
  background:var(--accent);
  border-color:var(--accent-edge);
  transform:translateX(-6px);
}

.seq__head{
  display:flex;
  align-items:flex-start;
  justify-content:space-between;
  gap:var(--sp-4);
}
.seq__title{
  font-size:15px;
  font-weight:var(--fw-semibold);
  color:var(--ink);
  letter-spacing:-0.015em;
  line-height:1.35;
}
.seq__sub{
  margin-top:3px;
  font-size:var(--fs-xs);
  color:var(--ink-muted);
  line-height:1.45;
}
.seq__stage{
  flex:0 0 auto;
  font-family:var(--mono);
  font-size:10px;
  font-weight:var(--fw-medium);
  letter-spacing:0.16em;
  text-transform:uppercase;
  color:var(--ink-faint);
  padding-top:2px;
}

/* Qualification chips. */
/* Four chips, so a fixed 2x2. auto-fit gave 3 + 1 on a wide card, which
   reads as a layout accident rather than a set of four answers. */
.seq__chips{
  display:grid;
  grid-template-columns:repeat(2,minmax(0,1fr));
  gap:var(--sp-2);
  margin-top:var(--sp-3);
}
@media (max-width:620px){
  .seq__chips{grid-template-columns:minmax(0,1fr);}
}
.seq__chip{
  border:1px solid var(--line);
  border-radius:var(--r-sm);
  padding:8px 10px;
  background:var(--surface-2);
}
.seq__chip .k{
  display:block;
  font-family:var(--mono);
  font-size:9.5px;
  letter-spacing:0.14em;
  text-transform:uppercase;
  color:var(--ink-faint);
}
.seq__chip .v{
  display:block;
  margin-top:3px;
  font-size:12.5px;
  line-height:1.35;
  color:var(--ink);
}

/* Booking strip. */
.seq__slots{
  display:grid;
  grid-template-columns:repeat(5,minmax(0,1fr));
  gap:6px;
  margin-top:var(--sp-3);
}
.seq__slot{
  border:1px solid var(--line);
  border-radius:var(--r-xs);
  padding:8px 4px;
  text-align:center;
  background:var(--surface-2);
}
.seq__slot .d{
  display:block;
  font-family:var(--mono);
  font-size:9.5px;
  letter-spacing:0.1em;
  color:var(--ink-faint);
}
.seq__slot .t{
  display:block;
  margin-top:3px;
  font-family:var(--mono);
  font-size:11.5px;
  font-weight:var(--fw-semibold);
  color:var(--ink-muted);
}
.seq__slot--taken{
  border-color:var(--line-accent);
  background:var(--accent-wash);
}
.seq__slot--taken .d{color:var(--accent-ink);}
.seq__slot--taken .t{color:var(--ink);}

/* SMS bubble. */
.seq__sms{
  display:inline-block;
  max-width:30em;
  margin-top:var(--sp-3);
  padding:9px 12px;
  border:1px solid var(--line-accent);
  background:var(--accent-wash);
  border-radius:var(--r-md) var(--r-md) var(--r-md) 4px;
  font-size:13px;
  line-height:1.45;
  color:var(--ink);
}

.seq__caption{
  margin-top:var(--sp-5);
  padding-left:2px;
  font-family:var(--mono);
  font-size:var(--fs-xs);
  letter-spacing:0.02em;
  color:var(--ink-faint);
}


/* ==========================================================================
   3. THE PROBLEM CHAIN — 01 to 04
   --------------------------------------------------------------------------
   Numbered steps joined by a connective hairline that runs across the row on
   wide screens and down the left edge on narrow ones.
   ========================================================================== */

.chain{
  display:grid;
  grid-template-columns:repeat(4,minmax(0,1fr));
  gap:var(--sp-6);
  margin:var(--sp-12) 0 0;
  padding:0;                                 /* it is an <ol> — reset both */
  list-style:none;
}

.chain__step{
  position:relative;
  margin:0;                                  /* rovik.css li margin */
  padding-top:var(--sp-8);
}
.chain__step::before{
  content:"";
  position:absolute;
  top:6px;
  left:0;
  right:calc(-1 * var(--sp-6));
  height:1px;
  background:var(--line);
}
.chain__step:last-child::before{right:0;}
.chain__step::after{
  content:"";
  position:absolute;
  top:2px;left:0;
  width:9px;height:9px;
  border-radius:50%;
  background:var(--accent);
}

.chain__n{
  display:block;
  font-family:var(--mono);
  font-size:var(--fs-xs);
  font-weight:var(--fw-semibold);
  letter-spacing:0.14em;
  color:var(--accent-ink);
  margin-bottom:var(--sp-2);
}
.chain__step h3{font-size:19px;letter-spacing:-0.02em;}
.chain__step p{
  margin-top:var(--sp-2);
  font-size:var(--fs-sm);
  line-height:1.6;
  color:var(--ink-muted);
}

@media (max-width:900px){
  .chain{grid-template-columns:repeat(2,minmax(0,1fr));}
  .chain__step:nth-child(2n)::before{right:0;}
}
@media (max-width:560px){
  .chain{grid-template-columns:minmax(0,1fr);gap:var(--sp-8);}
  .chain__step::before{right:0;}
}


/* ==========================================================================
   4. CAPABILITY BENTO — six panels
   --------------------------------------------------------------------------
   Rhythm 2 / 3 / 1 on a six-column grid. Collapses to two columns, then one.
   Nothing is hidden behind hover; the lift is the only hover effect and it
   also fires on :focus-within.
   ========================================================================== */

.bento{
  display:grid;
  grid-template-columns:repeat(6,minmax(0,1fr));
  gap:var(--sp-4);
  margin-top:var(--sp-12);
}
.bento__item{grid-column:span 2;}
.bento__item--half{grid-column:span 3;}
.bento__item--full{grid-column:span 6;}

@media (max-width:900px){
  .bento{grid-template-columns:repeat(2,minmax(0,1fr));}
  .bento__item,
  .bento__item--half,
  .bento__item--full{grid-column:span 1;}
  .bento__item--full{grid-column:span 2;}
}
@media (max-width:560px){
  .bento{grid-template-columns:minmax(0,1fr);}
  .bento__item,
  .bento__item--half,
  .bento__item--full{grid-column:span 1;}
}

.bento__item{
  position:relative;
  overflow:hidden;
  padding:var(--sp-6);
}
.bento__rule{
  position:absolute;
  top:0;left:0;right:0;
  height:2px;
  background:var(--accent);
  transform:scaleX(0);
  transform-origin:left center;
  transition:transform var(--dur-slow) var(--ease-out);
}
.bento__item:hover .bento__rule,
.bento__item:focus-within .bento__rule{transform:scaleX(1);}

.bento__n{
  display:block;
  font-family:var(--mono);
  font-size:var(--fs-xs);
  font-weight:var(--fw-semibold);
  letter-spacing:0.14em;
  color:var(--ink-faint);
  margin-bottom:var(--sp-4);
}
.bento__item h3{font-size:19px;letter-spacing:-0.02em;margin-bottom:var(--sp-2);}
.bento__item p{
  font-size:var(--fs-sm);
  line-height:1.6;
  color:var(--ink-muted);
}


/* ==========================================================================
   5. WHY ROVIK
   ========================================================================== */

.why{
  display:grid;
  grid-template-columns:minmax(0,0.85fr) minmax(0,1fr);
  gap:clamp(32px,5vw,72px);
  align-items:start;
}
@media (max-width:880px){
  .why{grid-template-columns:minmax(0,1fr);gap:var(--sp-8);}
}

.why__body{
  font-size:var(--fs-lede);
  line-height:var(--lh-body);
  color:var(--ink-body);
}

/* Where a larger company would put a logo wall. It says what is true
   instead: the programme is open and there are three places (G1). */
.founding{
  margin-top:var(--sp-8);
  padding:var(--sp-6);
  border:1px solid var(--line-accent);
  border-radius:var(--r-lg);
  background:var(--surface-1);
}
.founding p{
  margin-top:var(--sp-3);
  font-size:var(--fs-sm);
  line-height:1.6;
  color:var(--ink-muted);
}
.founding a{
  text-decoration:underline;
  text-underline-offset:3px;
  text-decoration-thickness:1px;
}


/* ==========================================================================
   6. CALCULATOR TEASER
   --------------------------------------------------------------------------
   Shows the shape of the arithmetic and not one number. Every figure on the
   calculator belongs to the reader; inventing an example here would be the
   borrowed statistic the page exists to refuse.
   ========================================================================== */

.calc-teaser{
  display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,0.9fr);
  gap:clamp(32px,5vw,64px);
  align-items:center;
  padding:clamp(32px,4vw,52px);
}
@media (max-width:880px){
  .calc-teaser{grid-template-columns:minmax(0,1fr);gap:var(--sp-8);}
}

.calc-teaser__actions{margin-top:var(--sp-8);}

.calc-chain{
  list-style:none;
  margin:0;padding:0;
  border:1px solid var(--line);
  border-radius:var(--r-md);
  background:var(--surface-2);
  overflow:hidden;
}
.calc-chain li{
  display:flex;
  align-items:baseline;
  gap:var(--sp-4);
  margin:0;
  padding:11px var(--sp-5);
  border-bottom:1px solid var(--line);
  font-size:var(--fs-sm);
  color:var(--ink-body);
}
.calc-chain li:last-child{border-bottom:0;}
.calc-chain .n{
  flex:0 0 auto;
  font-family:var(--mono);
  font-size:10.5px;
  letter-spacing:0.12em;
  color:var(--ink-faint);
}
.calc-chain .blank{
  margin-left:auto;
  font-family:var(--mono);
  font-size:12px;
  letter-spacing:0.1em;
  color:var(--ink-faint);
}


/* ==========================================================================
   7. CLOSING CALL TO ACTION
   ========================================================================== */

.closing{
  max-width:760px;
  margin-left:auto;
  margin-right:auto;
  text-align:center;
}
.closing .lede{margin-left:auto;margin-right:auto;}
.closing__actions{
  display:flex;
  flex-wrap:wrap;
  justify-content:center;
  gap:var(--sp-3);
  margin-top:var(--sp-8);
}


/* ==========================================================================
   8. SHARED SECTION FURNITURE
   ========================================================================== */

.section-head{max-width:760px;}
.section-head .lede{margin-top:var(--sp-4);}


/* ==========================================================================
   21. PRICING PAGE
   --------------------------------------------------------------------------
   Three tier cards, one setup line, one full feature-comparison table, the
   founding-partner block, the FAQ.

   THE ARGUMENT THIS LAYOUT HAS TO CARRY
   -------------------------------------
   Plans differ by call VOLUME and PARTNERSHIP DEPTH. They never differ by
   capability: every tier answers every call, 24/7. The comparison table is
   therefore mostly a wall of ticks, and that is the point, not a defect. Do
   not gate a capability to make the table look more interesting - it would
   contradict the headline and the sub in the same screenful.

   Every colour is a var() from section 1. No literals: check_contrast.py's
   S3 check fails the whole run on a single stray hex.
   ========================================================================== */

/* -- 21.1 Tier cards ----------------------------------------------------- */

.tiers{
  display:grid;
  grid-template-columns:repeat(auto-fit,minmax(288px,1fr));
  gap:var(--sp-6);
  align-items:stretch;
}

.tier{
  display:flex;
  flex-direction:column;
  position:relative;
  padding:var(--sp-8) var(--sp-6) var(--sp-6);
}

/* The chosen tier. A border and a shadow, not a scale transform - a card
   that grows changes the height of the row on a phone and pushes the other
   two prices below the fold. */
.tier--featured{
  border-color:var(--line-accent);
  box-shadow:var(--shadow-lg);
}

.tier__flag{
  position:absolute;
  top:calc(-1 * var(--sp-3));
  left:var(--sp-6);
  font-family:var(--mono);
  font-size:var(--fs-label);
  font-weight:var(--fw-semibold);
  letter-spacing:var(--tr-label);
  text-transform:uppercase;
  padding:5px 12px;
  border-radius:var(--r-full);
  background:var(--accent);
  border:1px solid var(--accent-edge);
  color:var(--on-accent);
  white-space:nowrap;
}

.tier__name{
  font-family:var(--mono);
  font-size:var(--fs-label);
  font-weight:var(--fw-medium);
  letter-spacing:var(--tr-label);
  text-transform:uppercase;
  color:var(--ink-muted);
  margin:0 0 var(--sp-4);
}

.tier__price{
  display:flex;
  align-items:baseline;
  flex-wrap:wrap;
  gap:var(--sp-2);
  margin-bottom:var(--sp-2);
}
.tier__amount{
  font-family:var(--mono);
  font-size:42px;
  font-weight:var(--fw-bold);
  font-variant-numeric:tabular-nums;
  letter-spacing:-0.03em;
  line-height:1;
  color:var(--ink);
}
.tier__unit{
  font-family:var(--mono);
  font-size:var(--fs-sm);
  color:var(--ink-muted);
}

/* "Rate locked for 12 months. Cancel anytime." - identical on all three
   cards and everywhere else on the site. G5 is explicit that the old site's
   "No long-term contracts" beside a 12-month lock must not recur. */
.tier__contract{
  font-size:var(--fs-xs);
  color:var(--ink-muted);
  margin-bottom:var(--sp-5);
}

.tier__volume{
  display:flex;
  flex-direction:column;
  gap:var(--sp-1);
  padding:var(--sp-4);
  margin-bottom:var(--sp-5);
  background:var(--surface-2);
  border:1px solid var(--line);
  border-radius:var(--r-md);
}
.tier__volume span{
  font-family:var(--mono);
  font-size:var(--fs-sm);
  color:var(--ink);
}

.tier .list-check{flex:1 1 auto;margin-bottom:var(--sp-6);}
.tier__cta{margin-top:auto;}

/* -- 21.2 Setup line ----------------------------------------------------- */

.setup-note{
  margin-top:var(--sp-8);
  padding:var(--sp-5) var(--sp-6);
  border:1px solid var(--line-accent);
  border-radius:var(--r-md);
  background:var(--accent-wash);
  text-align:center;
}
.setup-note strong{
  display:block;
  font-family:var(--mono);
  font-size:var(--fs-body);
  color:var(--ink);
  margin-bottom:var(--sp-2);
}
.setup-note p{font-size:var(--fs-sm);color:var(--ink-body);margin:0;}

/* -- 21.3 Comparison table ----------------------------------------------- */

.cmp{min-width:660px;}
.cmp th[scope="row"]{
  font-weight:var(--fw-regular);
  color:var(--ink-body);
  font-size:var(--fs-sm);
}
.cmp td{text-align:center;font-variant-numeric:tabular-nums;}
.cmp thead th:not(:first-child){text-align:center;}
.cmp thead .cmp__tier{
  font-family:var(--sans);
  font-size:var(--fs-sm);
  font-weight:var(--fw-semibold);
  letter-spacing:var(--tr-body);
  text-transform:none;
  color:var(--ink);
}

/* Row-group header. A full-width band inside the table so "Intake",
   "Booking", "Records" and "Partnership" read as sections rather than as
   another feature row. */
.cmp__group th{
  background:var(--surface-2);
  font-family:var(--mono);
  font-size:var(--fs-label);
  font-weight:var(--fw-semibold);
  letter-spacing:var(--tr-label);
  text-transform:uppercase;
  color:var(--accent-ink);
  border-bottom:1px solid var(--line-strong);
  padding-top:var(--sp-5);
  padding-bottom:var(--sp-3);
}
.cmp__group:hover th{background:var(--surface-2);}

/* The tick. Drawn from borders rather than a glyph so it renders identically
   whatever font resolves, and paired with visually-hidden text so a screen
   reader hears "Included" rather than silence. */
.tick{
  display:inline-block;
  width:7px;height:13px;
  border-right:2px solid var(--gain);
  border-bottom:2px solid var(--gain);
  transform:rotate(45deg);
  margin-bottom:3px;
}
.dash{
  display:inline-block;
  width:12px;height:2px;
  background:var(--ink-faint);
  vertical-align:middle;
}

.cmp__note{
  margin-top:var(--sp-5);
  font-size:var(--fs-sm);
  color:var(--ink-muted);
  max-width:var(--maxw-prose);
}

/* -- 21.4 Founding partner block ----------------------------------------- */

.founding-block{
  display:grid;
  grid-template-columns:repeat(auto-fit,minmax(300px,1fr));
  gap:var(--sp-10);
  align-items:start;
}
.founding-block h3{margin-bottom:var(--sp-4);}
.founding-block p{margin-bottom:var(--sp-4);}
.founding-block p:last-child{margin-bottom:0;}

.trade-list{
  list-style:none;
  padding:0;
  margin:0 0 var(--sp-5);
  border-top:1px solid var(--line);
}
.trade-list li{
  display:flex;
  align-items:baseline;
  gap:var(--sp-4);
  margin:0;
  padding:var(--sp-4) 0;
  border-bottom:1px solid var(--line);
  color:var(--ink);
  font-size:var(--fs-sm);
}
.trade-list .n{
  font-family:var(--mono);
  font-size:var(--fs-xs);
  letter-spacing:0.08em;
  color:var(--accent-ink);
  flex:0 0 auto;
}

.upfront{
  padding:var(--sp-5);
  border:1px solid var(--line-strong);
  border-radius:var(--r-md);
  background:var(--surface-1);
}
.upfront__k{
  display:block;
  font-family:var(--mono);
  font-size:var(--fs-label);
  letter-spacing:var(--tr-label);
  text-transform:uppercase;
  color:var(--ink-muted);
  margin-bottom:var(--sp-2);
}
.upfront__v{
  display:block;
  font-family:var(--mono);
  font-size:30px;
  font-weight:var(--fw-semibold);
  font-variant-numeric:tabular-nums;
  letter-spacing:-0.02em;
  color:var(--ink);
  margin-bottom:var(--sp-2);
}
.upfront__d{font-size:var(--fs-xs);color:var(--ink-muted);}

/* -- 21.5 FAQ width ------------------------------------------------------ */

.faq--pricing{max-width:860px;}

@media (max-width:560px){
  .tier__amount{font-size:36px;}
  .tier__flag{left:var(--sp-5);}
}


/* ==========================================================================
   22. HIGH CONTRAST — prefers-contrast: more
   The layout leans on low-alpha hairlines to separate surfaces. A reader who
   has asked the OS for more contrast loses those first. Redefines the two
   line tokens and widens the focus ring. REDEFINES only; adds no new token.
   ========================================================================== */

@media (prefers-contrast:more){
  :root{
    --line:var(--line-hc);
    --line-strong:var(--line-strong-hc);
    --focus-w:3px;
  }
}
