/* GENERATED by scripts/sync-design-system.mjs — do not edit by hand.
   Source: design/ (Claude Design project 90ac63ba). Edit there, then re-run. */

/* ==========================================================================
   tokens/fonts.css
   ========================================================================== */
/* Archivo (display + numerals) via Google Fonts. SUBSTITUTION: no font binaries were
   supplied with the brief; Archivo is loaded from Google's CDN. Swap for self-hosted
   files before production if the site must be fully self-contained. */
/* Self-hosted, latin + latin-ext subsets. Substituted for the design system's
   Google Fonts @import by scripts/sync-design-system.mjs — production makes no
   third-party requests. Licence: /assets/fonts/OFL.txt (SIL OFL 1.1). */
@font-face {
  font-family: "Archivo";
  src: url("/assets/fonts/archivo-latin.woff2") format("woff2");
  font-weight: 400 800;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Archivo";
  src: url("/assets/fonts/archivo-latin-ext.woff2") format("woff2");
  font-weight: 400 800;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}


:root{
  --font-display:'Archivo','Helvetica Neue',Helvetica,Arial,sans-serif;
  --font-body:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,'Noto Sans',sans-serif,'Apple Color Emoji','Segoe UI Emoji';
  --font-mono:ui-monospace,SFMono-Regular,'SF Mono',Menlo,Consolas,'Liberation Mono',monospace;
}

/* ==========================================================================
   tokens/colors.css
   ========================================================================== */
:root{
  /* Base palette — light */
  --blue-900:#012169;   /* Union blue */
  --blue-700:#0B3A9E;
  --blue-100:#E4EAF6;
  --red-600:#C8102E;    /* Union red */
  --red-100:#F8E3E6;
  --gold-400:#F0C14B;   /* achievement / progress */
  --gold-100:#FBF0D6;
  --paper:#F7F6F3;
  --white:#FFFFFF;
  --ink:#12161C;
  --muted:#4E5560;
  --hairline:#E1DFD9;
  --green-600:#1E7A45;  /* pass */
  --green-100:#E2F1E8;

  /* Semantic aliases — light theme is the default */
  --surface-page:var(--paper);
  --surface-card:var(--white);
  --surface-sunken:#EFEDE8;
  --surface-brand:var(--blue-900);
  --surface-accent-soft:var(--blue-100);
  --surface-gold-soft:var(--gold-100);

  --text-body:var(--ink);
  --text-muted:var(--muted);
  --text-brand:var(--blue-900);
  --text-accent:var(--red-600);
  --text-on-brand:#FFFFFF;
  --text-on-gold:#3A2B06;

  --border-hairline:var(--hairline);
  --border-strong:#C9C5BB;
  --border-brand:var(--blue-900);

  --brand-primary:var(--blue-900);
  --brand-accent:var(--red-600);
  --brand-gold:var(--gold-400);

  --state-pass:var(--green-600);
  --state-pass-soft:var(--green-100);
  --state-fail:var(--red-600);
  --state-fail-soft:var(--red-100);

  --focus-ring:var(--red-600);
  --focus-ring-offset:var(--surface-page);

  /* Guilloche / engraving hairline texture colour */
  --engrave-line:rgba(1,33,105,.10);
}

@media (prefers-color-scheme:dark){
  :root{
    --blue-900:#6E93E8;
    --blue-700:#8FAEF0;
    --blue-100:#1B2A4A;
    --red-600:#FF6B6B;
    --red-100:#3A1D22;
    --gold-400:#F0C14B;
    --gold-100:#332A12;
    --paper:#0A1020;
    --white:#111A2E;
    --ink:#E9EDF5;
    --muted:#9BA8BF;
    --hairline:#1E2A44;
    --green-600:#4CC38A;
    --green-100:#13301F;

    --surface-sunken:#0D1526;
    --surface-page:#0A1020;
    --surface-card:#111A2E;
    --surface-brand:#0F1B33;
    --text-on-brand:#E9EDF5;
    /* Dark flips --gold-100 from cream to a dark brown, so the text that sits on
       it has to flip too. Without this pair moving together the explanation
       panel renders #3A2B06 on #332A12 — a 1.06:1 contrast, i.e. invisible. */
    --text-on-gold:#FBF0D6;
    --border-strong:#2C3B5C;
    --engrave-line:rgba(110,147,232,.14);
  }
}

/* Forced themes — add data-theme="dark" | "light" on <html> to override the media query */
[data-theme=dark]{
  --blue-900:#6E93E8;--blue-700:#8FAEF0;--blue-100:#1B2A4A;--red-600:#FF6B6B;--red-100:#3A1D22;
  --gold-400:#F0C14B;--gold-100:#332A12;--paper:#0A1020;--white:#111A2E;--ink:#E9EDF5;--muted:#9BA8BF;
  --hairline:#1E2A44;--green-600:#4CC38A;--green-100:#13301F;--surface-sunken:#0D1526;
  --surface-page:#0A1020;--surface-card:#111A2E;--surface-brand:#0F1B33;--text-on-brand:#E9EDF5;
  --text-on-gold:#FBF0D6;--border-strong:#2C3B5C;--engrave-line:rgba(110,147,232,.14);
}
[data-theme=light]{
  --blue-900:#012169;--blue-700:#0B3A9E;--blue-100:#E4EAF6;--red-600:#C8102E;--red-100:#F8E3E6;
  --gold-400:#F0C14B;--gold-100:#FBF0D6;--paper:#F7F6F3;--white:#FFFFFF;--ink:#12161C;--muted:#4E5560;
  --hairline:#E1DFD9;--green-600:#1E7A45;--green-100:#E2F1E8;--surface-sunken:#EFEDE8;
  --surface-page:#F7F6F3;--surface-card:#FFFFFF;--surface-brand:#012169;--text-on-brand:#FFFFFF;
  --text-on-gold:#3A2B06;--border-strong:#C9C5BB;--engrave-line:rgba(1,33,105,.10);
}

/* ==========================================================================
   tokens/typography.css
   ========================================================================== */
:root{
  /* Sizes — mobile-first; --step-* are the fluid display sizes */
  --text-caption:12px;
  --text-small:14px;
  --text-body-size:16px;
  --text-lead:18px;
  --text-h4:20px;
  --text-h3:24px;
  --text-h2:clamp(26px,4vw,34px);
  --text-h1:clamp(32px,6vw,52px);
  --text-display:clamp(40px,8vw,72px);
  --text-numeral:clamp(34px,7vw,60px);

  --leading-tight:1.06;
  --leading-heading:1.16;
  --leading-body:1.6;
  --leading-loose:1.75;

  --weight-regular:400;
  --weight-medium:500;
  --weight-semibold:600;
  --weight-bold:700;
  --weight-black:800;

  --tracking-display:-0.02em;
  --tracking-heading:-0.01em;
  --tracking-body:0;
  --tracking-caps:0.09em;

  --numeral-features:"tnum" 1,"lnum" 1; /* @kind other */
}

/* Every figure, timer, score and count uses tabular lining numerals. */
.lu-num,[data-num]{font-variant-numeric:tabular-nums lining-nums;font-feature-settings:var(--numeral-features)}
.lu-eyebrow{font-family:var(--font-display);font-size:var(--text-caption);font-weight:var(--weight-bold);letter-spacing:var(--tracking-caps);text-transform:uppercase;color:var(--text-muted)}

/* ==========================================================================
   tokens/spacing.css
   ========================================================================== */
:root{
  --space-1:4px;
  --space-2:8px;
  --space-3:12px;
  --space-4:16px;
  --space-5:20px;
  --space-6:24px;
  --space-8:32px;
  --space-10:40px;
  --space-12:48px;
  --space-16:64px;
  --space-20:80px;
  --space-24:96px;

  --section-y:clamp(48px,9vw,96px); /* @kind spacing */
  --gutter:clamp(16px,5vw,32px); /* @kind spacing */
  --measure:64ch;
  --container:1120px;
  --container-narrow:720px;
}

/* ==========================================================================
   tokens/shape.css
   ========================================================================== */
:root{
  --radius-sm:8px;
  --radius-md:14px;
  --radius-lg:20px;
  --radius-pill:999px;

  --border-width:1px;
  --border-thick:2px;

  /* Shadows are quiet: paper lift, not material elevation */
  --shadow-none:none;
  --shadow-card:0 1px 2px rgba(18,22,28,.05),0 8px 24px -16px rgba(18,22,28,.24);
  --shadow-raised:0 2px 4px rgba(18,22,28,.06),0 18px 40px -22px rgba(18,22,28,.32);
  --shadow-press:inset 0 2px 4px rgba(1,33,105,.28);
  --shadow-focus:0 0 0 3px var(--surface-page),0 0 0 5px var(--focus-ring);

  /* Perforation divider — dotted, like a tear-off strip */
  --perforation:radial-gradient(circle,var(--border-hairline) 1.5px,transparent 1.6px) 0 50%/10px 3px repeat-x;
}
@media (prefers-color-scheme:dark){
  :root{
    --shadow-card:0 1px 2px rgba(0,0,0,.4),0 8px 24px -16px rgba(0,0,0,.7);
    --shadow-raised:0 2px 4px rgba(0,0,0,.5),0 18px 40px -22px rgba(0,0,0,.8);
    --shadow-press:inset 0 2px 4px rgba(0,0,0,.5);
  }
}

/* ==========================================================================
   tokens/motion.css
   ========================================================================== */
:root{
  --dur-fast:120ms; /* @kind other */
  --dur-base:200ms; /* @kind other */
  --dur-slow:380ms; /* @kind other */
  --dur-rise:520ms; /* @kind other */
  --ease-out:cubic-bezier(.2,.8,.2,1); /* @kind other */
  --ease-in-out:cubic-bezier(.4,0,.2,1); /* @kind other */
  --ease-stamp:cubic-bezier(.34,1.4,.64,1); /* @kind other */
  --rise-distance:14px;
}
@keyframes lu-rise{from{opacity:0;transform:translateY(var(--rise-distance))}to{opacity:1;transform:none}}
@keyframes lu-ring{from{stroke-dashoffset:var(--ring-length,314)}}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms !important;animation-iteration-count:1 !important;transition-duration:.001ms !important;scroll-behavior:auto !important}
}

/* ==========================================================================
   tokens/base.css
   ========================================================================== */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{margin:0;background:var(--surface-page);color:var(--text-body);font-family:var(--font-body);font-size:var(--text-body-size);line-height:var(--leading-body);text-wrap:pretty;-webkit-font-smoothing:antialiased}
h1,h2,h3,h4{font-family:var(--font-display);line-height:var(--leading-heading);letter-spacing:var(--tracking-heading);margin:0;color:var(--text-body);text-wrap:balance}
p{margin:0}
a{color:var(--text-brand);text-underline-offset:3px;text-decoration-thickness:1px}
a:hover{color:var(--text-accent)}
:focus-visible{outline:2px solid var(--focus-ring);outline-offset:2px;border-radius:2px}
img{max-width:100%;display:block}
button{font:inherit}

/* ==========================================================================
   site layer — src/assets/site.css
   ========================================================================== */
/* Site layer. The token layer (design/tokens/*.css, flattened into
   assets/styles.css by scripts/sync-design-system.mjs) is loaded first and owns
   every colour, size, radius, shadow and duration used below.

   These rules are a one-way port of the design kit's inline styles
   (ui_kits/website/{Chrome,Landing,Policies}.jsx). Where a number appears here
   it appears there too — if the two disagree, the kit wins. Nothing invents a
   value that is not already a token. */

/* The `hidden` attribute has to actually hide. The browser's default is
   `[hidden] { display: none }` in the UA sheet, which ANY author rule setting
   `display` outranks — so `.btn { display: inline-flex }` and
   `.mock__result { display: grid }` both left elements on screen while their
   `hidden` property read true. Every script in this file toggles visibility
   that way, so this rule is what makes the attribute mean what it says.
   `!important` is the standard remedy and is deliberate: an element asking to
   be hidden should beat a component's layout. */
[hidden] { display: none !important; }

/* --------------------------------------------------------------- lang offer */
/* Inserted by the root page's inline script when the browser asks for a
   language the site has. It sits above the masthead, in the offered language,
   and both of its controls are permanent decisions — take it, or never see it
   again. Nothing is hidden behind it and nothing moves without a click. */
.langbar { display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: var(--space-3) var(--space-5); padding: 10px var(--gutter);
  background: var(--surface-brand); color: var(--text-on-brand);
  font-size: var(--text-small); }
.langbar__go { color: var(--text-on-brand); font-weight: var(--weight-bold);
  text-underline-offset: 3px; }
.langbar__no { background: none; border: 0; padding: 0; cursor: pointer; font: inherit;
  color: color-mix(in srgb, var(--text-on-brand) 72%, transparent); text-decoration: underline;
  text-underline-offset: 3px; }
.langbar__no:hover { color: var(--text-on-brand); }

/* ------------------------------------------------------------------ layout */
.wrap { max-width: var(--container); margin-inline: auto; padding-inline: var(--gutter); }

.section { position: relative; }
.section > .wrap { padding-block: var(--section-y); }
.section--sunken { background: var(--surface-sunken); }
.section--brand { background: var(--surface-brand); }
.section--brand, .section--brand h2, .section--brand h3 { color: var(--text-on-brand); }
.section--brand .sec-head__lead { color: color-mix(in srgb, var(--text-on-brand) 80%, transparent); }

.stack { display: grid; gap: var(--space-8); }
.grid-auto { display: grid; gap: var(--space-4); grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.grid-auto--wide { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
.grid-auto--narrow { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }

/* Clipped rather than pushed off-screen. The usual `inset-inline-start:-9999px`
   trick flips to the RIGHT under dir="rtl" and drags the document's scroll
   width out with it, so Urdu got a horizontal scrollbar and clipped content. */
.skip-link { position: absolute; top: 0; inset-inline-start: 8px; z-index: 50;
  width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
  background: var(--surface-card); color: var(--text-brand); padding: 10px 14px;
  border-radius: var(--radius-sm); border: 1px solid var(--border-hairline); }
.skip-link:focus { width: auto; height: auto; overflow: visible; clip-path: none; top: 8px; }

.ic--inline { display: inline-block; vertical-align: -2px; margin-inline-start: 6px; }

/* ---------------------------------------------------------------- masthead */
.masthead { position: sticky; top: 0; z-index: 20;
  background: color-mix(in srgb, var(--surface-page) 88%, transparent);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  border-block-end: 1px solid var(--border-hairline); }
.masthead__inner { max-width: var(--container); margin-inline: auto;
  padding: 10px var(--gutter); display: flex; align-items: center; gap: var(--space-4); }
.masthead__actions { margin-inline-start: auto; display: flex; gap: var(--space-2); align-items: center; }
/* Scoped to beat `.btn { display: inline-flex }`, which is declared later in
   this file and would otherwise win on equal specificity — putting the desktop
   CTA back into the mobile masthead and squeezing the wordmark onto three
   lines. The matching reveal at 900px is scoped the same way. */
.masthead__actions .masthead__cta { display: none; }
.wordmark__text { white-space: nowrap; }

.wordmark { display: flex; align-items: center; gap: 10px; text-decoration: none; color: var(--text-body); }
.wordmark__mark { object-fit: contain; border-radius: 7px; }
.wordmark__text { font-family: var(--font-display); font-weight: var(--weight-black);
  font-size: 17px; letter-spacing: -0.01em; line-height: 1.1; }
.wordmark--lg .wordmark__text { font-size: 19px; }

.site-nav { display: none; margin-inline-start: auto; gap: var(--space-5); }
.site-nav a { font-size: 15px; font-weight: var(--weight-medium); text-decoration: none; color: var(--text-body); }
.site-nav a:hover { color: var(--text-accent); }

/* ------------------------------------------------------------------ drawer */
/* overflow:hidden is load-bearing, not tidiness: the closed panel sits at
   translateX(±100%), and without clipping it contributes its own width to the
   document's scroll width — a 340px phantom scrollbar on every page. */
.drawer { position: fixed; inset: 0; z-index: 40; visibility: hidden; overflow: hidden; }
.drawer[data-open] { visibility: visible; }
.drawer__scrim { position: absolute; inset: 0; background: rgba(10, 16, 32, .5); opacity: 0;
  transition: opacity var(--dur-base) var(--ease-out); }
.drawer[data-open] .drawer__scrim { opacity: 1; }
.drawer__panel { position: absolute; inset-block: 0; inset-inline-end: 0; width: min(88vw, 340px);
  background: var(--surface-page); border-inline-start: 1px solid var(--border-hairline);
  display: flex; flex-direction: column; gap: var(--space-2); padding: var(--space-4);
  transform: translateX(100%); transition: transform var(--dur-slow) var(--ease-out); }
[dir=rtl] .drawer__panel { transform: translateX(-100%); }
.drawer[data-open] .drawer__panel { transform: none; }
.drawer__head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); }
.drawer__nav { display: grid; margin-block-start: var(--space-4); }
.drawer__nav a { display: flex; align-items: center; padding: 14px 4px; text-decoration: none;
  color: var(--text-body); font-weight: var(--weight-medium);
  border-block-end: 1px solid var(--border-hairline); }
.drawer__chev { margin-inline-start: auto; color: var(--border-strong); }
[dir=rtl] .drawer__chev { transform: scaleX(-1); }
.drawer__foot { margin-block-start: auto; }

/* ------------------------------------------------------------------ button */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  font-family: var(--font-display); font-weight: var(--weight-bold); letter-spacing: -0.005em;
  border-radius: var(--radius-md); border: var(--border-width) solid transparent;
  cursor: pointer; text-decoration: none; text-align: center;
  transition: transform var(--dur-fast) var(--ease-stamp),
              background-color var(--dur-base) var(--ease-out),
              box-shadow var(--dur-base) var(--ease-out),
              color var(--dur-base) var(--ease-out); }
.btn:active { transform: translateY(1px) scale(.985); }
.btn--sm { font-size: var(--text-small); padding: 8px 14px; min-height: 36px; }
.btn--md { font-size: var(--text-body-size); padding: 12px 20px; min-height: 44px; }
.btn--lg { font-size: var(--text-lead); padding: 16px 28px; min-height: 52px; }
.btn--block { width: 100%; }
.btn--primary { background: var(--brand-primary); color: var(--text-on-brand); box-shadow: var(--shadow-card); }
.btn--primary:hover { color: var(--text-on-brand); background: var(--blue-700); }
.btn--primary:active { box-shadow: var(--shadow-press); }
.btn--accent { background: var(--brand-accent); color: #fff; box-shadow: var(--shadow-card); }
.btn--accent:hover { color: #fff; }
.btn--secondary { background: var(--surface-card); color: var(--text-brand); border-color: var(--border-brand); }
.btn--ghost { background: transparent; color: var(--text-brand); }

.icon-btn { width: 44px; height: 44px; border-radius: var(--radius-pill);
  border: 1px solid var(--border-hairline); background: var(--surface-card);
  color: var(--text-brand); display: grid; place-items: center; cursor: pointer;
  transition: background-color var(--dur-base) var(--ease-out); }
.icon-btn:hover { background: var(--surface-accent-soft); }

/* -------------------------------------------------------------------- card */
.card { position: relative; overflow: hidden; isolation: isolate; }
.card--r-lg { border-radius: var(--radius-lg); }
.card--r-md { border-radius: var(--radius-md); }
.card--r-sm { border-radius: var(--radius-sm); }
.card--p-none { padding: 0; }
.card--p-sm { padding: var(--space-4); }
.card--p-md { padding: var(--space-6); }
.card--p-lg { padding: var(--space-8); }
.card--paper { background: var(--surface-card); color: var(--text-body); border: 1px solid var(--border-hairline); }
.card--brand { background: var(--surface-brand); color: var(--text-on-brand); border: 1px solid transparent; }
.card--soft { background: var(--surface-accent-soft); color: var(--text-body); border: 1px solid transparent; }
.card--gold { background: var(--surface-gold-soft); color: var(--text-body); border: 1px solid var(--brand-gold); }
.card--elevated { box-shadow: var(--shadow-card); }
.card__engrave { position: absolute; inset: 0; pointer-events: none; opacity: .9; z-index: -1;
  background: repeating-linear-gradient(115deg, var(--engrave-line) 0 1px, transparent 1px 7px);
  -webkit-mask-image: radial-gradient(120% 90% at 100% 0%, #000 0%, transparent 70%);
  mask-image: radial-gradient(120% 90% at 100% 0%, #000 0%, transparent 70%); }
.card--brand .card__engrave { background: repeating-linear-gradient(115deg, rgba(255,255,255,.10) 0 1px, transparent 1px 7px); }

/* ------------------------------------------------------------------- badge */
.badge { display: inline-flex; align-items: center; gap: 6px; font-family: var(--font-display);
  font-size: var(--text-caption); font-weight: var(--weight-bold); letter-spacing: var(--tracking-caps);
  text-transform: uppercase; padding: 5px 11px; border-radius: var(--radius-pill);
  border: 1px solid transparent; width: fit-content; }
.badge--brand { background: var(--surface-accent-soft); color: var(--text-brand); border-color: color-mix(in srgb, var(--brand-primary) 22%, transparent); }
.badge--neutral { background: var(--surface-card); color: var(--text-muted); border-color: var(--border-hairline); }
.badge--pass { background: var(--state-pass-soft); color: var(--state-pass); border-color: color-mix(in srgb, var(--state-pass) 30%, transparent); }
.badge--gold { background: var(--surface-gold-soft); color: var(--text-on-gold); border-color: var(--brand-gold); }

/* ----------------------------------------------------------------- divider */
.divider { border: 0; height: 1px; background: var(--border-hairline); margin: 0; }
.divider--perf { height: 3px; background: var(--perforation); }

/* --------------------------------------------------------- section heading */
.sec-head { display: grid; gap: var(--space-3); max-width: var(--measure); }
.sec-head__title { font-size: var(--text-h2); font-weight: var(--weight-black); letter-spacing: var(--tracking-display); }
.sec-head__lead { font-size: var(--text-lead); color: var(--text-muted); }

/* -------------------------------------------------------------------- hero */
.hero { position: relative; overflow: hidden; }
.hero__engrave { position: absolute; inset: 0; pointer-events: none;
  background: repeating-linear-gradient(115deg, var(--engrave-line) 0 1px, transparent 1px 8px);
  -webkit-mask-image: radial-gradient(90% 70% at 80% 0%, #000, transparent 70%);
  mask-image: radial-gradient(90% 70% at 80% 0%, #000, transparent 70%); }
.hero__inner { position: relative; max-width: var(--container); margin-inline: auto;
  padding: var(--section-y) var(--gutter); display: grid; gap: var(--space-12);
  grid-template-columns: minmax(0, 1fr); }
/* 38ch, not the kit's 32ch: the kit's StoreBadge is a placeholder slot, while
   the real Apple and Google badges need ~410px to sit side by side as designed.
   Any narrower and they stack, which reads as two competing CTAs. */
.hero__copy { display: grid; gap: var(--space-5); align-content: center; max-width: 38ch; }
.hero__title { font-size: var(--text-h1); font-weight: var(--weight-black);
  letter-spacing: var(--tracking-display); line-height: var(--leading-tight); }
.hero__lead { font-size: var(--text-lead); color: var(--text-muted); max-width: 46ch; }
.hero__rating { display: inline-flex; align-items: center; gap: var(--space-2); font-size: var(--text-body); font-weight: var(--weight-bold); margin-block: var(--space-1); }
.hero__rating-score { font-size: 1.15rem; font-weight: var(--weight-black); color: var(--text); }
.hero__rating-stars { color: #F59E0B; letter-spacing: 1.5px; font-size: 1.1rem; }
.hero__rating-count { color: var(--text-muted); font-weight: var(--weight-regular); font-size: var(--text-small); }
.hero__note { font-size: var(--text-small); color: var(--text-muted); }
/* One screen, centred, with the app icon overlapping its top-left corner the
   way a store listing pairs them. `--tilt-x/y` are written by site.js from the
   pointer; they stay at 0 when nothing writes them, which is also the state a
   reduced-motion reader keeps. */
.hero__stage { position: relative; display: grid; justify-items: center;
  perspective: 1200px; }
.hero__frame { position: relative; transform-style: preserve-3d;
  transform: translate3d(0, calc(var(--par, 0) * 1px), 0)
             rotateX(calc(var(--tilt-y, 0) * -6deg)) rotateY(calc(var(--tilt-x, 0) * 6deg));
  transition: transform var(--dur-base) var(--ease-out); }
.hero__icon { position: absolute; z-index: 1; inset-block-start: -18px; inset-inline-start: -22px;
  width: 76px; height: 76px; border-radius: 18px; box-shadow: var(--shadow-raised);
  background: var(--paper); transform: translateZ(60px) rotate(-6deg); }

/* The wash behind the hero. Two offset radial tints drifting across each other
   — cheap, GPU-composited, and it never touches layout. */
.hero__glow { position: absolute; inset: -20% -10% auto; height: 130%; pointer-events: none;
  background:
    radial-gradient(38% 42% at 22% 18%, color-mix(in srgb, var(--brand-primary) 26%, transparent), transparent 70%),
    radial-gradient(34% 38% at 78% 8%, color-mix(in srgb, var(--brand-gold) 22%, transparent), transparent 72%);
  filter: blur(6px); opacity: .85; animation: lu-drift 24s var(--ease-in-out) infinite alternate; }

@keyframes lu-drift {
  from { transform: translate3d(-3%, -2%, 0) scale(1); }
  to   { transform: translate3d(4%, 3%, 0) scale(1.08); }
}

/* ---------------------------------------------------------- number/explain */
.figure-card { display: grid; gap: 4px; }
.figure-card__n { font-family: var(--font-display); font-size: 44px; font-weight: var(--weight-black);
  color: var(--text-brand); line-height: 1; }
.figure-card__l { color: var(--text-muted); }

/* ------------------------------------------------------------------- stats */
.stat { display: grid; gap: var(--space-2); }
.stat__value { font-family: var(--font-display); font-size: var(--text-numeral);
  font-weight: var(--weight-black); line-height: 1; letter-spacing: var(--tracking-display);
  color: var(--text-on-brand); }
.stat--gold .stat__value { color: var(--brand-gold); }
.stat__label { font-size: var(--text-small); color: color-mix(in srgb, var(--text-on-brand) 78%, transparent); }

/* ------------------------------------------------------------------- modes */
.mode { display: grid; gap: var(--space-3); align-content: start; padding: var(--space-6);
  background: var(--surface-card); border: 1px solid var(--border-hairline);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-card); }
.mode__icon { width: 40px; height: 40px; display: grid; place-items: center; border-radius: var(--radius-md);
  background: var(--surface-accent-soft); color: var(--text-brand); }
.mode__title { font-size: var(--text-h4); font-weight: var(--weight-bold); }
.mode__desc { color: var(--text-muted); }
.mode__meta { font-size: var(--text-small); color: var(--text-brand); font-weight: var(--weight-semibold); }

/* --------------------------------------------------------------------- faq */
.faq { border-block-end: 1px solid var(--border-hairline); }
.faq__q { display: flex; align-items: center; gap: var(--space-4); cursor: pointer; list-style: none;
  padding: var(--space-5) 0; font-family: var(--font-display); font-weight: var(--weight-bold);
  font-size: var(--text-h4); }
.faq__q::-webkit-details-marker { display: none; }
.faq__chev { margin-inline-start: auto; flex: none; color: var(--text-brand);
  transition: transform var(--dur-base) var(--ease-out); }
.faq[open] .faq__chev { transform: rotate(180deg); }
.faq__a { padding-block-end: var(--space-5); color: var(--text-muted); max-width: var(--measure);
  display: grid; gap: var(--space-3); }

/* ------------------------------------------------------------------- chips */
.chip { display: grid; gap: 2px; padding: var(--space-4); border-radius: var(--radius-md);
  background: var(--surface-card); border: 1px solid var(--border-hairline);
  text-decoration: none; color: var(--text-body);
  transition: border-color var(--dur-base) var(--ease-out), transform var(--dur-fast) var(--ease-out); }
a.chip:hover { border-color: var(--border-brand); transform: translateY(-1px); color: var(--text-body); }
.chip--current { border-color: var(--border-brand); background: var(--surface-accent-soft); }
.chip__native { font-family: var(--font-display); font-weight: var(--weight-bold); font-size: var(--text-lead); }
.chip__name { font-size: var(--text-small); color: var(--text-muted); }

/* ------------------------------------------------------------ store badges */
.stores { display: flex; gap: var(--space-3); flex-wrap: wrap; }
.store { display: inline-flex; align-items: center; gap: 10px; padding: 9px 16px 9px 14px;
  border-radius: var(--radius-md); background: var(--ink); color: var(--paper);
  text-decoration: none; border: 1px solid var(--ink); box-shadow: var(--shadow-card);
  transition: transform var(--dur-fast) var(--ease-stamp); }
.store:hover { color: var(--paper); transform: translateY(-1px); }
.store:active { transform: translateY(1px) scale(.985); }
.store__glyph { flex: none; }
.store__text { display: grid; line-height: 1.15; }
.store__sub { font-size: 10px; letter-spacing: var(--tracking-caps); text-transform: uppercase; opacity: .8; }
.store__name { font-family: var(--font-display); font-size: 16px; font-weight: var(--weight-bold); }
.section--brand .store { background: var(--paper); color: var(--ink); border-color: var(--paper); }
.section--brand .store:hover { color: var(--ink); }

/* ------------------------------------------------------------ phone frames */
.phone { margin: 0; display: grid; gap: var(--space-3); flex: none; width: var(--phone-w); }
.phone__body { position: relative; border-radius: 26px; padding: 7px; background: var(--ink);
  box-shadow: var(--shadow-raised); transform: rotate(var(--phone-tilt)); }
/* 1206 × 2622 is the real capture size of the shipped screenshots
   (scripts/import-screenshots.sh). Reserving the exact ratio means the hero
   does not reflow when the images decode. */
/* `height: auto` is required, not tidiness. The width/height attributes on the
   <img> are presentational hints that map to CSS width/height, so without this
   the attribute height (1044px) beats aspect-ratio and every screenshot renders
   as a tall vertical smear. */
.phone__shot, .phone__slot { display: block; width: 100%; height: auto;
  aspect-ratio: 1206 / 2622;
  border-radius: 20px; background: var(--surface-sunken); object-fit: cover; }
.phone__slot { background: repeating-linear-gradient(135deg, var(--surface-sunken) 0 10px, var(--surface-card) 10px 20px); }
.phone__cap { font-size: var(--text-caption); color: var(--text-muted); line-height: 1.4; }

/* ----------------------------------------------------------- question card */
.qc { display: grid; gap: var(--space-3); padding: var(--space-5); border-radius: var(--radius-lg);
  background: var(--surface-card); border: 1px solid var(--border-hairline); box-shadow: var(--shadow-card); }
.qc__head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-4); }
.qc__chapter { font-family: var(--font-display); font-size: var(--text-caption);
  font-weight: var(--weight-bold); letter-spacing: var(--tracking-caps);
  text-transform: uppercase; color: var(--text-brand); }
.qc__counter { font-size: var(--text-caption); color: var(--text-muted); }
.qc__history { font-size: var(--text-caption); color: var(--text-muted); }
.qc__q { font-family: var(--font-display); font-weight: var(--weight-bold); font-size: var(--text-h4); }
.qc__q-t { color: var(--text-muted); font-size: var(--text-small); }
.qc__opts { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-2); }
.qc__opt { display: flex; gap: var(--space-3); align-items: flex-start; padding: 10px 12px;
  border-radius: var(--radius-sm); border: 1px solid var(--border-hairline); background: var(--surface-page); }
.qc__opt.is-right { border-color: var(--state-pass); background: var(--state-pass-soft); }
.qc__opt.is-wrong { border-color: var(--state-fail); background: var(--state-fail-soft); }
.qc__opt.is-sel { border-color: var(--border-brand); }
.qc__marker { flex: none; width: 22px; height: 22px; border-radius: var(--radius-pill);
  display: grid; place-items: center; font-family: var(--font-display); font-size: 12px;
  font-weight: var(--weight-bold); background: var(--surface-card); border: 1px solid var(--border-hairline); }
.qc__opt.is-right .qc__marker { background: var(--state-pass); color: #fff; border-color: var(--state-pass); }
.qc__opt.is-wrong .qc__marker { background: var(--state-fail); color: #fff; border-color: var(--state-fail); }
.qc__opt-text { display: grid; gap: 1px; }
.qc__opt-t { color: var(--text-muted); font-size: var(--text-small); }
.qc__exp { display: grid; gap: 2px; padding: var(--space-3); border-radius: var(--radius-sm);
  background: var(--surface-gold-soft); border: 1px solid var(--brand-gold); color: var(--text-on-gold);
  font-size: var(--text-small); }
.qc__exp-t { opacity: .85; }

/* ---------------------------------------------------------- progress bars */
.pbar { display: grid; gap: 6px; }
.pbar__row { display: flex; justify-content: space-between; gap: var(--space-4); align-items: baseline; }
.pbar__label { font-size: var(--text-small); font-weight: var(--weight-medium); }
.pbar__meta { font-size: var(--text-caption); color: var(--text-muted); }
.pbar__track { height: 8px; border-radius: var(--radius-pill); background: var(--surface-sunken);
  overflow: hidden; border: 1px solid var(--border-hairline); }
.pbar__fill { display: block; height: 100%; border-radius: var(--radius-pill); background: var(--brand-primary); }
.pbar__fill--gold { background: var(--brand-gold); }

/* ---------------------------------------------------------- progress ring */
.ring { position: relative; width: var(--ring-size); height: var(--ring-size); flex: none;
  display: grid; place-items: center; }
.ring svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.ring circle { fill: none; stroke-width: 10; stroke-linecap: round; }
.ring__track { stroke: var(--surface-sunken); }
.ring__val { stroke: var(--brand-primary); animation: lu-ring var(--dur-rise) var(--ease-out) both; }
.ring--gold .ring__val { stroke: var(--brand-gold); }
.ring__mid { position: absolute; display: grid; justify-items: center; gap: 0; }
.ring__num { font-family: var(--font-display); font-size: 26px; font-weight: var(--weight-black); line-height: 1; }
.ring__sub { font-size: var(--text-caption); color: var(--text-muted); }

/* -------------------------------------------------------------- stamp seal */
.seal { display: grid; justify-items: center; gap: 0; width: 92px; height: 92px;
  border-radius: var(--radius-pill); place-content: center; text-align: center;
  transform: rotate(var(--seal-angle)); font-family: var(--font-display);
  border: 2px dashed var(--brand-gold); color: var(--brand-gold);
  background: color-mix(in srgb, var(--brand-gold) 12%, transparent); }
.seal__label { font-size: 20px; font-weight: var(--weight-black); letter-spacing: -0.01em; }
.seal__sub { font-size: 10px; letter-spacing: var(--tracking-caps); text-transform: uppercase; opacity: .9; }
/* In the kit the seal is absolutely positioned into the download band's top
   right. Below 900px there is no room beside the heading, so it returns to the
   flow above it rather than overlapping the text. */
.seal--float { position: static; margin-inline: auto; }
@media (min-width: 900px) {
  .seal--float { position: absolute; inset-inline-end: 0; top: -18px; margin-inline: 0; }
}

.stores--center { justify-content: center; }

/* ------------------------------------------------------- language switcher */
.langs { position: relative; }
.langs__btn { width: auto; padding-inline: 12px; gap: 7px; display: inline-flex; align-items: center;
  list-style: none; white-space: nowrap; }
.langs__btn::-webkit-details-marker { display: none; }
.langs__cur { display: none; font-size: var(--text-small); font-weight: var(--weight-semibold); }
.langs__menu { position: absolute; inset-inline-end: 0; top: calc(100% + 8px); z-index: 30;
  min-width: 232px; max-height: 62vh; overflow-y: auto; padding: var(--space-2);
  display: grid; gap: 1px; background: var(--surface-card); border: 1px solid var(--border-hairline);
  border-radius: var(--radius-md); box-shadow: var(--shadow-raised); }
.langs__item { display: flex; align-items: baseline; gap: var(--space-3); padding: 9px 10px;
  border-radius: var(--radius-sm); text-decoration: none; color: var(--text-body); }
.langs__item:hover { background: var(--surface-accent-soft); color: var(--text-body); }
.langs__item.is-current { background: var(--surface-accent-soft); font-weight: var(--weight-semibold); }
.langs__en { margin-inline-start: auto; font-size: var(--text-caption); color: var(--text-muted); }

/* ------------------------------------------------------------------ footer */
.site-footer { border-block-start: 1px solid var(--border-hairline); background: var(--surface-sunken); }
.site-footer > .wrap { padding-block: var(--space-12); display: grid; gap: var(--space-8); }
.site-footer__grid { display: grid; gap: var(--space-8); grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }
.site-footer__tagline { margin-block-start: var(--space-3); color: var(--text-muted); font-size: var(--text-small); max-width: 34ch; }
.site-footer h3 { font-size: var(--text-caption); font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-caps); text-transform: uppercase; color: var(--text-muted);
  margin-block-end: var(--space-3); }
.site-footer ul { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-2); }
.site-footer a { color: var(--text-body); text-decoration: none; font-size: var(--text-small); }
.site-footer a:hover { color: var(--text-accent); text-decoration: underline; }
.site-footer__disclaimer { font-size: var(--text-small); color: var(--text-body); max-width: 86ch; }
.site-footer__source { font-size: var(--text-small); color: var(--text-muted); max-width: 86ch; }
.site-footer__legal { display: flex; flex-wrap: wrap; gap: var(--space-4); align-items: center;
  font-size: var(--text-caption); color: var(--text-muted);
  border-block-start: 1px solid var(--border-hairline); padding-block-start: var(--space-6); }

/* --------------------------------------------------------------- documents */
/* Privacy, Terms and Support share this shell — the kit's Doc component. */
.doc { max-width: var(--container-narrow); margin-inline: auto;
  padding: var(--section-y) var(--gutter); display: grid; gap: var(--space-6); }
.doc__head { display: grid; gap: var(--space-3); }
.doc__title { font-size: var(--text-h1); font-weight: var(--weight-black); letter-spacing: var(--tracking-display); }
.doc__updated { color: var(--text-muted); font-size: var(--text-small); }
.doc__lead { font-size: var(--text-lead); color: var(--text-muted); }
.doc__body { display: grid; gap: var(--space-6); max-width: var(--measure); }
.doc__body h2 { font-size: var(--text-h3); font-weight: var(--weight-bold); margin-block-start: var(--space-4); }
.doc__body h3 { font-size: var(--text-h4); font-weight: var(--weight-bold); margin-block-start: var(--space-3); }
.doc__body p { margin-block-start: var(--space-3); }
.doc__body ul { display: grid; gap: var(--space-2); padding-inline-start: 1.1em; margin-block-start: var(--space-3); }
.doc__body section > :first-child { margin-block-start: 0; }
.doc__toc { display: grid; gap: var(--space-2); padding: var(--space-5); border-radius: var(--radius-md);
  background: var(--surface-card); border: 1px solid var(--border-hairline); }
.doc__toc ol { margin: 0; padding-inline-start: 1.2em; display: grid; gap: 6px; font-size: var(--text-small); }
/* The kit's visible TODO block. Nothing shipped uses it — scripts/check.mjs
   fails the build if one reaches dist/ — but the style stays so that a draft
   left in a content file is impossible to miss during review. */
.doc__todo { display: flex; gap: var(--space-2); align-items: flex-start;
  background: var(--surface-gold-soft); border: 1px solid var(--brand-gold);
  color: var(--text-on-gold); border-radius: var(--radius-sm); padding: 10px 12px;
  font-size: var(--text-small); }
.doc__todo strong { letter-spacing: .08em; }

/* ------------------------------------------------------------ guide tables */
.factlist { display: grid; gap: 0; border: 1px solid var(--border-hairline);
  border-radius: var(--radius-md); overflow: hidden; background: var(--surface-card); }
.factlist__row { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-4);
  justify-content: space-between; padding: var(--space-4) var(--space-5);
  border-block-end: 1px solid var(--border-hairline); }
.factlist__row:last-child { border-block-end: 0; }
.factlist__k { color: var(--text-muted); font-size: var(--text-small); }
.factlist__v { font-family: var(--font-display); font-weight: var(--weight-bold); }

/* ------------------------------------------------------------ app screens */
/* Six frames, so the column count is written out rather than left to auto-fit:
   at this width auto-fit resolves to five and strands the sixth on its own row,
   the same way it stranded the fourth `why` card. 1 / 2 / 3 divides six evenly
   at every step. */
.screens { display: grid; gap: var(--space-6) var(--space-5); grid-template-columns: 1fr;
  justify-items: center; }
@media (min-width: 640px) { .screens { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 900px) { .screens { grid-template-columns: repeat(3, 1fr); } }
.screens .phone__cap { text-align: center; max-width: 30ch; }

/* -------------------------------------------------------------- mock test */
/* `is-idle` is only ever set by site.js, so with no JS the whole paper is
   simply there, answered and explained — the same bargain the quiz makes. */
.mock { display: grid; gap: var(--space-5); }
.mock__bar { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-4) var(--space-6); }
.mock__bar > p { margin: 0; }
.mock__clock { font-family: var(--font-display); font-weight: var(--weight-black);
  font-size: var(--text-h4); font-variant-numeric: tabular-nums; }
.mock__clock-l { font-family: var(--font-body); font-size: var(--text-caption);
  font-weight: var(--weight-medium); color: var(--text-muted); text-transform: uppercase;
  letter-spacing: var(--tracking-caps); }
.mock__count { color: var(--text-muted); font-size: var(--text-small); }

/* All 24 cards are always in the markup — that is what a crawler and a no-JS
   reader get. `is-stepped` is set by site.js once the paper is running, and
   from then on exactly one card is on screen. */
.mock__paper { display: grid; gap: var(--space-5);
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
.mock.is-stepped .mock__paper { grid-template-columns: minmax(0, 640px); justify-content: center; }
.mock.is-stepped .mock__paper > .qc { display: none; }
.mock.is-stepped .mock__paper > .qc[data-current] { display: grid; }

.mock__nav { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3);
  justify-content: space-between; max-width: 640px; margin-inline: auto; width: 100%; }
.mock__nav [data-mock-back][disabled] { opacity: .4; cursor: default; }

/* Before Start: the paper is out of reach but still on the page for anyone
   reading rather than sitting it. Not `display:none` — that would drop it from
   the accessibility tree and from find-in-page for no benefit. */
.mock.is-live.is-idle .mock__paper { opacity: .35; pointer-events: none; filter: saturate(.4); }
.mock.is-live.is-idle .qc__opt-btn { cursor: default; }

.mock__result { display: grid; gap: var(--space-2); justify-items: start;
  padding: var(--space-5); border-radius: var(--radius-md);
  border: var(--border-width) solid var(--border-strong); background: var(--surface-card); }
.mock__result[data-passed="yes"] { border-color: var(--state-pass); background: var(--state-pass-soft); }
.mock__result[data-passed="no"] { border-color: var(--state-fail); background: var(--state-fail-soft); }
.mock__verdict { font-family: var(--font-display); font-weight: var(--weight-black);
  font-size: var(--text-h3); }
.mock__score { font-size: var(--text-lead); }
.mock__needed:empty { display: none; }

/* The store links inside the result. Separated by a rule rather than a colour
   block: the panel is already tinted pass-green or fail-red, and a second
   surface inside it would read as a different component. */
.mock__get { display: grid; gap: var(--space-3); justify-items: start;
  margin-block-start: var(--space-3); padding-block-start: var(--space-4);
  border-block-start: 1px solid var(--border-hairline); width: 100%; }
.mock__get-title { font-family: var(--font-display); font-weight: var(--weight-bold);
  font-size: var(--text-lead); line-height: var(--leading-tight); max-width: 28ch; }
.mock__get-lead { color: var(--text-muted); font-size: var(--text-small); max-width: var(--measure); }

/* -------------------------------------------------------------------- quiz */
/* Keyed on [data-quiz], not on a class. `.quiz` was the ten-question block's
   own class, so when /mock-test/ arrived with `.mock` these rules silently
   stopped applying and every explanation — which states the answer in prose —
   was on screen before the reader had chosen anything. The attribute is what
   site.js binds to, so it is what the styling must bind to as well.

   Only `.is-live`, set by site.js once it has taken the answers away, hides
   anything. Without JS none of this applies and the cards stay exactly as the
   server wrote them: answered, explained, and readable. */
.quiz { display: grid; gap: var(--space-5); }
.quiz__bar { font-family: var(--font-display); font-weight: var(--weight-bold);
  font-size: var(--text-lead); color: var(--text-brand); }
[data-quiz].is-live .qc__exp { display: none; }
[data-quiz].is-live .qc[data-answered] .qc__exp { display: grid; }
.qc__verdict { font-size: var(--text-small); font-weight: var(--weight-medium); }
.qc[data-answered="right"] .qc__verdict { color: var(--state-pass); }
.qc[data-answered="wrong"] .qc__verdict { color: var(--state-fail); }

/* The <button> site.js wraps each option in. It inherits the row's own layout
   so the markup change is invisible: same box, same alignment, now focusable. */
.qc__opt-btn { display: flex; gap: var(--space-3); align-items: flex-start; width: 100%;
  padding: 0; margin: 0; border: 0; background: none; color: inherit; font: inherit;
  text-align: start; cursor: pointer; }
[data-quiz].is-live .qc[data-answered] .qc__opt-btn { cursor: default; }
.qc__opt-btn:focus-visible { outline: 2px solid var(--brand-primary); outline-offset: 3px;
  border-radius: var(--radius-sm); }
[data-quiz].is-live .qc:not([data-answered]) .qc__opt { transition: border-color var(--dur-fast) var(--ease-out),
  background-color var(--dur-fast) var(--ease-out); }
[data-quiz].is-live .qc:not([data-answered]) .qc__opt:hover { border-color: var(--border-brand);
  background: var(--surface-sunken); }

/* -------------------------------------------------------------- why cards */
/* Fixed two-up rather than the auto-fit grid the other sections use. There are
   exactly four of these and auto-fit resolved to three columns at desktop,
   leaving one card alone on a second row — which reads as a mistake rather than
   a layout. Four items want 2×2 or a single column, nothing in between. */
.why__grid { display: grid; gap: var(--space-5); grid-template-columns: 1fr; }
@media (min-width: 640px) { .why__grid { grid-template-columns: 1fr 1fr; } }

.why__card { display: grid; gap: var(--space-3); align-content: start;
  transition: transform var(--dur-base) var(--ease-out), box-shadow var(--dur-base) var(--ease-out); }
.why__card:hover { transform: translateY(-4px); box-shadow: var(--shadow-raised); }
.why__icon { display: inline-flex; align-items: center; justify-content: center;
  width: 42px; height: 42px; border-radius: var(--radius-md);
  background: var(--surface-sunken); color: var(--text-brand); }
.why__title { font-family: var(--font-display); font-size: var(--text-lead);
  font-weight: var(--weight-bold); line-height: var(--leading-tight); }
.why__body { color: var(--text-muted); }
.why__note { font-size: var(--text-small); color: var(--text-muted); max-width: var(--measure); }

/* ------------------------------------------------------------------ motion */
/* Everything here is decorative and additive: with site.js removed, or with
   reduced motion asked for, every element is already in its final state. The
   attributes are written by the markup; the classes below only animate the
   transition into a position the element occupies anyway. */
[data-rise] { animation: lu-rise var(--dur-rise) var(--ease-out) both; }

/* Hero entrance. `data-hero` is the stagger index. The delays are written out
   per index rather than computed from the attribute: typed attr() in calc() is
   still too new to depend on, and there are only five. */
.js [data-hero] { opacity: 0; transform: translateY(14px); }
.js .hero[data-lit] [data-hero] { animation: lu-rise var(--dur-rise) var(--ease-out) both; }
.js .hero[data-lit] [data-hero="0"] { animation-delay: 0ms; }
.js .hero[data-lit] [data-hero="1"] { animation-delay: 90ms; }
.js .hero[data-lit] [data-hero="2"] { animation-delay: 180ms; }
.js .hero[data-lit] [data-hero="3"] { animation-delay: 270ms; }
.js .hero[data-lit] [data-hero="4"] { animation-delay: 360ms; }

/* Scroll reveal. Held down only while JS is present and the observer has not
   reached the element yet — `.js` is set by site.js itself, so a reader with no
   JS never sees a hidden section. */
.js [data-reveal]:not([data-rise]) { opacity: 0; transform: translateY(18px); }

/* Parallax. site.js writes `--par` — a pixel offset derived from the element's
   distance to the viewport centre — and nothing else. It deliberately does NOT
   set a transform: several of these elements already have one of their own
   (a tilt, a rotation), and a blanket `[data-parallax] { transform: … }` would
   silently win or lose against them depending on rule order. Each participant
   composes `--par` into its own transform instead, so the two never fight. */
[data-parallax] { will-change: transform; }
.hero__engrave { transform: translate3d(0, calc(var(--par, 0) * 1px), 0); }
.seal--float { transform: rotate(var(--seal-angle)) translate3d(0, calc(var(--par, 0) * 1px), 0); }

/* Counters and bars animate by writing a custom property, never by rewriting
   layout — the number's box is reserved by the final value at build time. */
.lu-num { font-variant-numeric: tabular-nums; }
.pbar__fill { transition: width var(--dur-rise) var(--ease-out); }

@media (prefers-reduced-motion: reduce) {
  .js [data-hero], .js [data-reveal]:not([data-rise]) { opacity: 1; transform: none; }
  .hero__glow { animation: none; }
  .hero__frame, .hero__engrave { transform: none; }
  .seal--float { transform: rotate(var(--seal-angle)); }
}

/* ----------------------------------------------------------------- reviews */
.reviews__summary { display: flex; align-items: center; justify-content: center; gap: var(--space-2); font-size: var(--text-lead); font-weight: var(--weight-bold); margin-block-end: var(--space-2); }
.reviews__stars { color: #F59E0B; letter-spacing: 2px; }
.reviews__score { font-weight: var(--weight-black); }
.reviews__dot { color: var(--text-muted); }
.reviews__stores { color: var(--text-muted); font-size: var(--text-body); font-weight: var(--weight-regular); }

.reviews__grid { display: grid; gap: var(--space-4); grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); }

.review-card { display: flex; flex-direction: column; justify-content: space-between; gap: var(--space-4); background: var(--paper); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: var(--space-5); box-shadow: var(--shadow-sm); transition: transform var(--dur-base) var(--ease-out), box-shadow var(--dur-base) var(--ease-out); }
.review-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-raised); }

.review-card__head { display: flex; align-items: center; gap: var(--space-3); }
.review-card__avatar { width: 42px; height: 42px; border-radius: 50%; color: #ffffff; display: flex; align-items: center; justify-content: center; font-weight: var(--weight-bold); font-size: var(--text-body); flex-shrink: 0; }
.review-card__who { display: flex; flex-direction: column; gap: 2px; flex-grow: 1; min-width: 0; }
.review-card__name { font-weight: var(--weight-bold); font-size: var(--text-body); color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.review-card__city { font-size: var(--text-small); color: var(--text-muted); }
.review-card__stars { color: #F59E0B; letter-spacing: 1px; font-size: 0.95rem; flex-shrink: 0; }

.review-card__text { font-size: var(--text-body); line-height: var(--leading-normal); color: var(--text); margin: 0; flex-grow: 1; }

.review-card__verified { display: flex; align-items: center; gap: 6px; font-size: var(--text-small); color: #10B981; font-weight: var(--weight-medium); }
.review-card__verified-icon { color: #10B981; }

/* -------------------------------------------------------------- breakpoint */
/* The kit's single breakpoint: burger out, inline nav and store CTA in, hero
   goes side by side. */
@media (min-width: 900px) {
  .burger { display: none; }
  .site-nav { display: flex; }
  .masthead__actions .masthead__cta { display: inline-flex; }
  .langs__cur { display: inline; }
  .hero__inner { grid-template-columns: 1fr 1.05fr; align-items: center; }
}

@media (min-width: 640px) {
  .site-footer__grid { grid-template-columns: 1.4fr 1fr 1fr; }
}
