/* ======================================================================
 * GOLDTRAP EA — STYLESHEET
 * ======================================================================
 * Structure of this file:
 *
 *   1.  Design tokens (custom properties)
 *   2.  Reset & base
 *   3.  Layout primitives (containers, sections, rules)
 *   4.  Typography primitives (eyebrow, headings, lead)
 *   5.  Component primitives (buttons, pills, cards, icon discs,
 *       feature lists, copy fields)
 *   6.  Scroll reveal
 *   7.  Site chrome (top action bar, header, nav, language selector)
 *   8.  Section 1  — Hero
 *   9.  Section 2  — Quick Benefits
 *   10. Section 3  — How GoldTrap Works
 *   11. Section 4  — Live Results
 *   12. Section 5  — Get GoldTrap EA (pricing)
 *   13. Section 6  — Source Code
 *   14. Section 7  — Free Access
 *   15. Section 8  — Download
 *   16. Section 9  — FAQ
 *   17. Section 10 — Footer
 *   18. Live chat widget
 *   19. Dialogs
 *   20. Google Translate overrides
 *
 * NOTE ON RESPONSIVE SCOPE
 * This is the DESKTOP implementation (phase 1 of the three-phase workflow
 * in CLAUDE.md). Values are fluid across the desktop range (~1024px and up)
 * so the design holds from 1024 to ultra-wide, but the dedicated mobile and
 * tablet layouts are deliberately NOT implemented yet.
 * ====================================================================== */


/* ======================================================================
 * 1. DESIGN TOKENS
 * ======================================================================
 * Every colour below was sampled directly from the supplied mockups.
 * Change a token here and it propagates across the whole site.
 * ====================================================================== */

:root {
    /*
     * THEME COLOURS
     * The eight --site-* properties below are written by main.js from its
     * SITE COLORS block, so the palette is editable from one place without
     * touching CSS. Each var() carries the same value as a fallback, so the
     * page is correctly coloured before JavaScript runs and if it fails.
     */

    /* --- Surfaces: the page alternates between these near-black bands --- */
    --bg-black: var(--site-background, #050505);  /* hero, works, free+download, footer */
    --bg-zinc: #09090B;           /* quick benefits, pricing, FAQ                   */
    --bg-hero: #0B0A07;           /* hero base, under the gold glow                 */
    --bg-warm: #0D0C08;           /* live results band                              */

    --surface: var(--site-surface, #111113);      /* neutral card, dark buttons     */
    --surface-warm: #14120F;      /* warm card (pricing, source code)               */
    --surface-2: #1A1A1D;         /* inactive pills, secondary buttons              */
    --surface-3: #202023;         /* hover state for dark surfaces                  */

    /* --- Lines --- */
    --rule: #222223;              /* neutral 1px section hairline                   */
    --rule-warm: #292312;         /* warm hairline (live results band)              */
    --border-subtle: var(--site-border, #232019); /* default card border            */
    --border-gold: #4A3F21;       /* emphasised card border                         */
    --border-gold-solid: var(--site-primary-accent, #DDB954); /* hover borders + icons */

    /* --- Gold ramp: the brand spine --- */
    --gold-100: #F1D998;          /* button gradient, top stop                      */
    --gold-200: #E8D59B;          /* display heading gradient, light stop           */
    --gold-300: #E8C97A;          /* eyebrows and gold body text                    */
    --gold-400: var(--site-primary-accent, #DDB954);  /* primary gold accent        */
    --gold-500: #C9A94E;          /* button gradient, bottom stop                   */
    --gold-600: #C4AC60;          /* display heading gradient, dark stop            */

    /* --- Accents --- */
    --green-dot: var(--site-success, #00D492);    /* live / online indicators       */
    --green-btn: #2BC18A;         /* Free Access call to action                     */
    --green-text: #05A974;        /* the word "FREE" on the free plan               */
    --blue: #51B3E7;              /* View Live Results button (single use)          */
    --danger-bg: #261613;         /* free-plan warning strip                        */
    --danger-text: #F87171;

    /* --- Text --- */
    --text: var(--site-text, #FFFFFF);
    --text-muted: var(--site-muted-text, #AFAEB1);/* body paragraphs                */
    --text-dim: #9F9FA9;          /* idle nav links, top bar, meta                  */
    --text-faint: #8A8A93;        /* footer tier — see note below                   */
    --on-gold: var(--site-primary-accent-hover, #09090B); /* text on gold/green     */

    /*
     * ACCESSIBILITY DEVIATION (the only one in this build).
     * The mockup footer uses #52525C, which measures 2.64:1 against #050505
     * and fails WCAG AA (4.5:1 needed at this text size). --text-faint is
     * lightened to #8A8A93 (5.96:1). CLAUDE.md permits departing from the
     * mockup where accessibility requires it. To match the mockup exactly
     * instead, set this to #52525C.
     */

    /* --- Signature gradients, reused site-wide --- */
    --grad-gold: linear-gradient(180deg, var(--gold-100) 0%, var(--gold-500) 100%);
    --grad-gold-text: linear-gradient(180deg, var(--gold-200) 0%, var(--gold-600) 100%);
    --grad-green: linear-gradient(180deg, #34D39B 0%, #16A97A 100%);
    --grad-blue: linear-gradient(180deg, #1F6FA8 0%, #175687 100%);

    /*
     * --- Containers ---
     * Measured on the live reference site at 1920px. Each section is a
     * full-bleed band; the content inside it is a centred max-width
     * container with a fixed 32px edge padding. The visible side gutter is
     * therefore NOT a fixed value — it is (viewport - container) / 2 plus
     * the padding, so it breathes with the viewport and collapses to the
     * 32px padding once the viewport reaches container + 64px.
     *
     * At 1920px this yields: wide 320px gutters, mid 384px, narrow 448px,
     * footer 576px.
     */
    --container-wide: 1280px;     /* header, hero, benefits, how it works,
                                     live results, pricing, free access     */
    --container-mid: 1152px;      /* source-code card                       */
    --container-narrow: 1024px;   /* download, FAQ, the full FAQ page       */
    --container-footer: 768px;    /* footer content                         */
    --gutter: 32px;               /* edge safety padding, never the gutter  */

    --header-height: 80px;        /* measured on the reference site         */

    /*
     * The announcement bar's vertical padding, as ONE value used for both
     * sides. Declaring it once is the point: a shorthand that sets only
     * padding-top, or a later rule overriding one side, is how a bar ends
     * up with its text sitting flush against the bottom edge. The bar's
     * height comes from this padding, never from a fixed height, so it
     * grows correctly when the announcement wraps to two or three lines.
     */
    --action-bar-padding-block: 10px;   /* measured on the reference bar */

    /*
     * How much fixed/sticky chrome sits at the top of the viewport. Written
     * by main.js from the REAL measured heights, because the announcement
     * bar is dismissible — assuming a value leaves deep links and the FAQ
     * category rail off by the bar's height once it is closed.
     *
     * Used for the FAQ rail's `top` and for `scroll-margin-top` on anything
     * scrolled to, so the two can never disagree.
     */
    --sticky-offset: 0px;

    /*
     * The same figure plus the FAQ page's category rail. Written by
     * main.js; the fallback keeps the site chrome offset on pages without
     * a rail, and before the script runs.
     */
    --faq-sticky-offset: var(--sticky-offset);

    /* --- Radii --- */
    --radius-pill: 999px;
    --radius-sm: 12px;            /* inner rows: dialog rows, licence field         */
    --radius-md: 16px;            /* standard cards                                 */
    --radius-lg: 24px;            /* large cards: pricing, source code, chart panel */

    /* --- Type --- */
    /*
     * TWO TYPEFACES PLUS ONE UTILITY FACE, each with a defined role:
     *
     *   --font-display  Montserrat — headings only, always with the
     *                   -0.02em tracking set on the h1–h4 rule below.
     *   --font-body     Roboto — everything else. Set once on the root so
     *                   it cascades; individual components never restate it.
     *   --font-mono     Roboto Mono — ONLY machine-copyable technical
     *                   strings: the wallet address, the download file
     *                   name and the MetaTrader whitelist URL. Countdown
     *                   timers deliberately do NOT use it; they use Roboto
     *                   with tabular figures so the digits stay fixed-width
     *                   without changing typeface.
     *
     * Both faces are loaded from Google Fonts in the <head> of each page at
     * the exact weights used here (Montserrat 700/900, Roboto
     * 400/500/600/700/900, Roboto Mono 400/500/600). If a weight is missing
     * the browser synthesises it, which renders at a different width and
     * looks like a size change — so keep the link and this list in step.
     */
    --font-display: "Montserrat", "Roboto", ui-sans-serif, system-ui, sans-serif;
    --font-body: "Roboto", ui-sans-serif, system-ui, sans-serif;
    --font-mono: "Roboto Mono", ui-monospace, "SFMono-Regular", Consolas, monospace;

    /*
     * TYPE SCALE
     * Fixed pixel values read off the computed styles of the live
     * reference site at 1920px. They are deliberately not fluid: the
     * reference site steps between fixed sizes at its breakpoints rather
     * than scaling continuously, and the mobile pass will do the same.
     *
     * Every font-size in this file should reference one of these. If a
     * component seems to need a size that is not here, it is almost always
     * the wrong size rather than a missing token.
     */
    --fs-h1: 72px;                /* hero H1                                */
    --fs-h2: 48px;                /* primary section headings               */
    --fs-h2-sm: 36px;             /* secondary section headings             */
    --fs-h3-lg: 30px;             /* source-code title, big money figures   */
    --fs-h3: 20px;                /* card titles, plan names, dialog titles */
    --fs-h4: 18px;                /* download platform titles               */

    --fs-lead: 20px;              /* hero lead paragraph                    */
    --fs-subhead: 18px;           /* gold subhead, section intros           */
    --fs-body: 16px;              /* base                                   */
    --fs-sm: 14px;                /* card copy, nav, buttons, eyebrows      */
    --fs-xs: 12px;                /* captions, chips, fine print            */
    --fs-2xs: 11px;               /* stat labels, footer, badges            */
    --fs-3xs: 10px;               /* timer caption                          */

    --fs-stat: 30px;              /* live-results numbers                   */
    --fs-price: 48px;             /* plan prices                            */
    --fs-timer: 18px;             /* countdown digits                       */

    /* Line heights. The reference site uses 1.625 for every run of body
       copy, so it is a token rather than a repeated magic number. */
    --lh-h1: 0.95;
    --lh-h2: 1;
    --lh-h2-sm: 1.1111;           /* 40 / 36 */
    --lh-h3-lg: 1.2;              /* 36 / 30 */
    --lh-h3: 1.4;                 /* 28 / 20 */
    --lh-h4: 1.5556;              /* 28 / 18 */
    --lh-body: 1.625;
    --lh-tight: 1.5;

    /* Tracking. -0.02em on headings is a fixed requirement of the design. */
    --ls-heading: -0.02em;
    --ls-eyebrow: 0.05em;         /* uppercase kicker labels                */

    /* --- Motion --- */
    --transition: 200ms ease;
    --reveal-duration: 600ms;
    --reveal-distance: 30px;
    --reveal-stagger: 100ms;
}


/* ======================================================================
 * 2. RESET & BASE
 * ====================================================================== */

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

/*
 * The `hidden` attribute must always win.
 *
 * Browsers implement it as `[hidden] { display: none }` in the user-agent
 * stylesheet, which is only specificity (0,1,0) — so ANY class rule that
 * sets `display` silently defeats it. That is not theoretical: four FAQ
 * components (.faq-no-results, .faq-page__toolbar,
 * .faq-sticky-search-button and .faq-search__clear) each set a display
 * value, and every one of them kept rendering while its `hidden` property
 * was true. That is why the FAQ page showed "No answers found" underneath
 * perfectly good search results.
 *
 * Two components had already been patched individually further down this
 * file (.action-bar[hidden], .lang-select__panel[hidden]). Per-component
 * opt-outs are the fragile pattern that let this through, so one
 * authoritative rule closes the trap for every component, present and
 * future.
 */
[hidden] {
    display: none !important;
}

html {
    -webkit-text-size-adjust: 100%;
    scroll-behavior: smooth;
}

/*
 * The body typeface and its rendering hints are declared ONCE, here, and
 * inherited by everything. Only headings override the family (see the
 * h1–h4 rule below); no component restates the stack.
 */
html {
    font-family: var(--font-body);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
}

body {
    margin: 0;
    background-color: var(--bg-black);
    color: var(--text);
    font-family: inherit;
    font-size: var(--fs-body);
    line-height: var(--lh-body);
}

/*
 * Glows are large box-shadows and the hero glow is a positioned pseudo
 * element. Clipping on a wrapper (never on body, which would break
 * position: sticky) keeps them from creating horizontal scroll.
 */
.page-wrapper {
    position: relative;
    overflow-x: clip;
    background-color: var(--bg-black);
}

/*
 * Defensive backstop, NOT the fix. Google Translate appends its UI to
 * <body>, outside .page-wrapper above, so the wrapper's clip cannot reach
 * it; the actual offender is constrained in section 20. This is here so
 * that anything else Google decides to inject at body level can never turn
 * into a horizontal scrollbar either.
 *
 * clip rather than hidden: `overflow-x: hidden` would make the page a
 * horizontally scrollable container that merely hides its scrollbar (and
 * would still scroll under a swipe on iOS), whereas `clip` refuses the
 * scroll outright. On the root element the value propagates to the
 * viewport, so overflow-y stays scrollable and no new scroll container is
 * created — position: sticky and position: fixed are unaffected.
 */
html {
    overflow-x: clip;
}

/*
 * The ONLY place the display face and its tracking are applied. Every
 * heading in the site is an h1–h4 element, so nothing else needs to
 * restate them; each heading class below sets only its size and its own
 * line-height.
 */
h1, h2, h3, h4 {
    margin: 0;
    font-family: var(--font-display);
    font-weight: 900;
    line-height: var(--lh-h3);
    letter-spacing: var(--ls-heading);
}

p {
    margin: 0;
}

ul, ol {
    margin: 0;
    padding: 0;
    list-style: none;
}

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

a {
    color: inherit;
    text-decoration: none;
    transition: color var(--transition);
}

button {
    font: inherit;
    color: inherit;
    background: none;
    border: none;
    cursor: pointer;
}

/* A single, consistent, always-visible focus ring (CLAUDE.md §22). */
:focus-visible {
    outline: 2px solid var(--gold-400);
    outline-offset: 3px;
    border-radius: 4px;
}

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

.skip-link {
    position: absolute;
    top: -100px;
    left: 16px;
    z-index: 100;
    padding: 12px 20px;
    background: var(--gold-400);
    color: var(--on-gold);
    font-weight: 700;
    border-radius: 0 0 var(--radius-sm) var(--radius-sm);
    transition: top var(--transition);
}

.skip-link:focus {
    top: 0;
}


/* ======================================================================
 * 3. LAYOUT PRIMITIVES
 * ====================================================================== */

/*
 * A centred max-width container plus a fixed edge padding. The side gutter
 * a visitor sees is the leftover space either side, so it scales with the
 * viewport by itself and bottoms out at --gutter once the viewport is
 * narrower than the container plus its padding. Never hard-code a gutter.
 */
.container {
    width: 100%;
    max-width: calc(var(--container-wide) + var(--gutter) * 2);
    margin-inline: auto;
    padding-inline: var(--gutter);
}

/* The source-code card reads slightly narrower than the pricing grid. */
.container--mid {
    max-width: calc(var(--container-mid) + var(--gutter) * 2);
}

/* Download and FAQ: reading-heavy, so the measure is deliberately shorter. */
.container--narrow {
    max-width: calc(var(--container-narrow) + var(--gutter) * 2);
}

.container--footer {
    max-width: calc(var(--container-footer) + var(--gutter) * 2);
}

/*
 * Sections carry their own background band and a 1px hairline separator,
 * reproducing the alternating rhythm measured in the mockup.
 */
.section {
    position: relative;
    border-bottom: 1px solid var(--rule);
}

.section--black { background-color: var(--bg-black); }
.section--zinc  { background-color: var(--bg-zinc); }
.section--warm  { background-color: var(--bg-warm); border-bottom-color: var(--rule-warm); }

.section__inner {
    /* 105px top / 101px bottom at 1920, matching the mockup's section rhythm. */
    padding-block: clamp(64px, 5.5vw, 105px) clamp(60px, 5.3vw, 101px);
}


/* ======================================================================
 * 4. TYPOGRAPHY PRIMITIVES
 * ====================================================================== */

.eyebrow {
    display: block;
    margin: 0 0 18px;
    color: var(--gold-300);
    font-size: var(--fs-sm);
    font-weight: 900;
    letter-spacing: var(--ls-eyebrow);
    text-transform: uppercase;
    line-height: 1.4286;
}

/* Eyebrow variant rendered as an outlined or filled pill. */
.eyebrow-pill {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin: 0 0 20px;
    padding: 8px 16px;
    border-radius: var(--radius-pill);
    background: rgba(221, 185, 84, 0.08);
    border: 1px solid var(--border-gold);
    color: var(--gold-300);
    font-size: var(--fs-xs);
    font-weight: 900;
    letter-spacing: var(--ls-eyebrow);
    text-transform: uppercase;
}

.eyebrow-pill--solid {
    background: var(--grad-gold);
    border-color: transparent;
    color: var(--on-gold);
}

.section-heading {
    font-size: var(--fs-h2);
    /*
     * line-height and letter-spacing are deliberately NOT set here: these
     * headings inherit 1.05 / -0.02em from the h1–h4 base rule, which is
     * what they used before the typeface pass. 800px is the measure that
     * reproduces the mockup's line breaks at this size.
     */
    max-width: 800px;
    line-height: var(--lh-h2);
}

/*
 * The mockup runs two heading tiers: 65px for most sections, and a smaller
 * ~48px for the Download and FAQ headings.
 */
.section-heading--sm {
    font-size: var(--fs-h2-sm);
    line-height: var(--lh-h2-sm);
}

.section-heading--center {
    margin-inline: auto;
    text-align: center;
    max-width: 800px;
}

/* Two-tone headings, e.g. "Get the <gold>Source Code</gold>".
   Not scoped to .section-heading — the source-code title uses it too. */
.accent {
    color: var(--gold-300);
}

.section-lead {
    margin-top: 20px;
    color: var(--text-muted);
    font-size: var(--fs-subhead);
    line-height: var(--lh-body);
    max-width: 62ch;
}

.section-lead--center {
    margin-inline: auto;
    text-align: center;
}

.text-gold { color: var(--gold-300); }
.text-muted { color: var(--text-muted); }
.mono { font-family: var(--font-mono); }


/* ======================================================================
 * 5. COMPONENT PRIMITIVES
 * ====================================================================== */

/* --- 5.1 Buttons -----------------------------------------------------
 * One base class, five fills. Every button lightens subtly on hover and
 * gold/green fills take #09090B text, per CLAUDE.md §11.1 and §23.
 * ------------------------------------------------------------------- */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 16px 28px;
    border-radius: var(--radius-pill);
    font-size: var(--fs-sm);
    font-weight: 900;
    text-align: center;
    white-space: nowrap;
    cursor: pointer;
    transition: background var(--transition), border-color var(--transition),
                color var(--transition), box-shadow var(--transition),
                filter var(--transition);
}

.btn svg {
    flex-shrink: 0;
}

.btn--gold {
    background: var(--grad-gold);
    color: var(--on-gold);
}

/*
 * §11.1: the orange-ish (gold) buttons invert to #09090B on hover, while
 * every button lightens subtly. Gold buttons therefore flip to a dark fill
 * with gold text and a gold border, keeping contrast well above AA.
 */
.btn--gold:hover,
.btn--gold:focus-visible {
    background: var(--site-primary-accent-hover, #09090B);
    color: var(--gold-300);
    box-shadow: inset 0 0 0 1px var(--gold-400);
}

.btn--green {
    background: var(--grad-green);
    color: var(--on-gold);
}

.btn--green:hover,
.btn--green:focus-visible {
    filter: brightness(1.12);
}

/*
 * Worn by exactly one control, the "View Live Results" link. The label is
 * white and the inline icon strokes with currentColor, so the icon follows
 * the label rather than needing a rule of its own.
 */
.btn--blue {
    background: var(--grad-blue);
    color: var(--text);
    box-shadow: 0 12px 40px -12px rgba(81, 179, 231, 0.65);
}

/* Subtle lift on hover, the same brightness step every other button uses. */
.btn--blue:hover,
.btn--blue:focus-visible {
    filter: brightness(1.12);
}

.btn--dark {
    background: var(--surface);
    color: var(--text);
}

.btn--dark:hover,
.btn--dark:focus-visible {
    background: var(--surface-3);
}

.btn--outline {
    background: var(--surface-2);
    color: var(--text);
    box-shadow: inset 0 0 0 1px var(--border-subtle);
}

.btn--outline:hover,
.btn--outline:focus-visible {
    background: var(--surface-3);
}

.btn--block {
    width: 100%;
}

.btn--lg {
    padding: 18px 32px;
    font-size: var(--fs-sm);
}

/* Coloured haloes behind the emphasised calls to action. */
.btn--glow-gold { box-shadow: 0 16px 48px -16px rgba(221, 185, 84, 0.55); }
.btn--glow-green { box-shadow: 0 16px 48px -14px rgba(43, 193, 138, 0.55); }


/* --- 5.2 Pills & badges --------------------------------------------- */

.status-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--green-dot);
    flex-shrink: 0;
}

/* Continuously pulsing live-activity indicator (colour set from main.js). */
.pulsing-dot {
    position: relative;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--gold-400);
    flex-shrink: 0;
}

.pulsing-dot::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: 50%;
    background: inherit;
    animation: pulse-ring 2s ease-out infinite;
}

@keyframes pulse-ring {
    0%   { transform: scale(1);   opacity: 0.7; }
    70%  { transform: scale(2.8); opacity: 0; }
    100% { transform: scale(2.8); opacity: 0; }
}

.badge-hot {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 5px 10px;
    border-radius: var(--radius-pill);
    background: var(--grad-gold);
    color: var(--on-gold);
    font-size: var(--fs-2xs);
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}


/* --- 5.3 Cards ------------------------------------------------------- */

.card {
    background: var(--surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    transition: border-color var(--transition), background var(--transition),
                color var(--transition);
}

.card--warm {
    background: var(--surface-warm);
}

.card--lg {
    border-radius: var(--radius-lg);
}

.card--gold {
    border-color: var(--border-gold);
}


/* --- 5.4 Icon discs -------------------------------------------------- */

.icon-disc {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: rgba(221, 185, 84, 0.12);
    color: var(--gold-300);
    font-size: var(--fs-sm);
    font-weight: 900;
}

.icon-disc--solid {
    background: var(--grad-gold);
    color: var(--on-gold);
}

.icon-disc--sm {
    width: 28px;
    height: 28px;
    font-size: var(--fs-xs);
}

.icon-disc--green {
    background: rgba(43, 193, 138, 0.14);
    color: var(--green-btn);
}


/* --- 5.5 Feature lists ----------------------------------------------- */

.feature-list {
    display: grid;
    gap: 14px;
}

.feature-list--2col {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: 48px;
}

.feature-list li {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    font-size: var(--fs-sm);
}

.feature-list .check {
    flex-shrink: 0;
    margin-top: 3px;
    color: var(--gold-300);
}


/* --- 5.6 Copy field --------------------------------------------------
 * Shared by the download whitelist chip and the dialog wallet row.
 * ------------------------------------------------------------------- */

.copy-btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 7px 12px;
    border-radius: 8px;
    background: var(--surface-2);
    border: 1px solid var(--border-subtle);
    color: var(--text-muted);
    font-size: var(--fs-2xs);
    font-weight: 600;
    transition: color var(--transition), border-color var(--transition),
                background var(--transition);
}

.copy-btn:hover,
.copy-btn:focus-visible {
    color: var(--border-gold-solid);
    border-color: var(--border-gold-solid);
}

/* Confirmed state: the icon swaps to a green check for 5 seconds. */
.copy-btn.is-copied,
.copy-btn.is-copied:hover {
    color: var(--green-dot);
    border-color: var(--green-dot);
}

.copy-btn .icon-copy,
.copy-btn .icon-check {
    flex-shrink: 0;
}

.copy-btn .icon-check { display: none; }
.copy-btn.is-copied .icon-copy { display: none; }
.copy-btn.is-copied .icon-check { display: block; }


/* ======================================================================
 * 6. SCROLL REVEAL
 * ======================================================================
 * Elements marked .scroll-reveal start faded and nudged down, then settle
 * when they enter the viewport. main.js adds .is-visible.
 *
 * TUNING
 *   distance → --reveal-distance   (default 30px)
 *   duration → --reveal-duration   (default 600ms)
 *   easing   → the transition-timing-function below (default ease-out)
 *   stagger  → --reveal-stagger    (default 100ms per index)
 *   threshold→ REVEAL_THRESHOLD in main.js (default 0.15)
 *
 * Stagger is driven by a single --reveal-index custom property set from JS,
 * so groups of cards cascade without needing one CSS rule per child.
 * ====================================================================== */

/*
 * The hidden starting state is applied ONLY where scripting is available,
 * so a visitor with JavaScript disabled or broken sees every section at
 * full opacity instead of a blank page. Browsers that do not support the
 * `scripting` media feature also fall through to the visible default.
 */
@media (scripting: enabled) {
    .scroll-reveal {
        opacity: 0;
        transform: translateY(var(--reveal-distance));
        transition:
            opacity var(--reveal-duration) ease-out,
            transform var(--reveal-duration) ease-out;
        transition-delay: calc(var(--reveal-index, 0) * var(--reveal-stagger));
    }
}

.scroll-reveal.is-visible {
    opacity: 1;
    transform: translateY(0);
}

/*
 * Reduced motion: content appears immediately, with no movement anywhere.
 * This also disables the pulsing dot and smooth scrolling.
 */
@media (prefers-reduced-motion: reduce) {
    html {
        scroll-behavior: auto;
    }

    .scroll-reveal {
        opacity: 1;
        transform: none;
        transition: none;
    }

    .pulsing-dot::after {
        animation: none;
    }

    /* No perpetual animation, and no static gold ring left behind either.
       The launcher, its photo and its green online dot stay fully visible.
       Restated after the .chat-widget rules further down, where it wins. */
    .chat-widget__pulse,
    .chat-widget__pulse.is-js-timed.is-pulsing {
        animation: none;
        opacity: 0;
    }

    *,
    *::before,
    *::after {
        animation-duration: 0.001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.001ms !important;
    }
}


/* ======================================================================
 * 7. SITE CHROME
 * ====================================================================== */

/* --- FAQ per-question copy link --------------------------------------
 * A sibling of the accordion trigger, not a child of it. Three states:
 * muted at rest, white on hover, green with a check when copied. The icon
 * swap and the aria-live announcement carry the meaning — colour only
 * reinforces it, so the control still works for a colourblind visitor.
 * ------------------------------------------------------------------- */

.faq-copy-link {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* 44px of touch target without a 44px visual footprint. */
    width: 44px;
    height: 44px;
    margin-inline-start: 4px;
    padding: 0;
    border-radius: 50%;
    color: var(--text-dim);
    transition: color var(--transition), background var(--transition);
}

.faq-copy-link:hover {
    color: var(--text);
    background: rgba(255, 255, 255, 0.06);
}

.faq-copy-link:focus-visible {
    color: var(--text);
}

.faq-copy-link.is-copied {
    color: var(--green-dot);
}

.faq-copy-link.is-failed {
    color: var(--danger-text);
}

/* The two icons occupy the same cell; exactly one is shown. */
.faq-copy-link__icon {
    display: inline-flex;
}

.faq-copy-link__icon--done,
.faq-copy-link.is-copied .faq-copy-link__icon--link,
.faq-copy-link.is-failed .faq-copy-link__icon--link {
    display: none;
}

.faq-copy-link.is-copied .faq-copy-link__icon--done,
.faq-copy-link.is-failed .faq-copy-link__icon--done {
    display: inline-flex;
}

/*
 * Anything scrolled to lands below the sticky chrome. One property, shared
 * with the rail's `top`, rather than a magic number in the scroll call.
 *
 * The FAQ page pins a second bar — the category rail — under the site
 * chrome, so its content clears --faq-sticky-offset (site chrome + rail),
 * which main.js measures at runtime. The homepage has no rail, so
 * --faq-sticky-offset falls back to --sticky-offset there.
 */
.faq-item {
    scroll-margin-top: calc(var(--sticky-offset) + 16px);
}

.faq-question,
.faq-group {
    scroll-margin-top: calc(var(--faq-sticky-offset, var(--sticky-offset)) + 16px);
}


/* --- 7.1 Top action bar ---------------------------------------------- */

.action-bar {
    position: relative;
    background: var(--bg-black);
    border-bottom: 1px solid var(--rule-warm);
}

.action-bar[hidden] {
    display: none;
}

/*
 * Symmetric padding, single source. See --action-bar-padding-block.
 * min-height is deliberately `auto`: a min-height would centre the text in
 * a fixed box and mask a broken padding value instead of exposing it.
 *
 * Measured against the reference bar at 1440 / 768 / 390. There the row is
 * a centred flex line, max-width 1280 INCLUDING its own 40px side padding,
 * 10px top and bottom, 8px between the icon and the text. Height is not
 * set: it falls out of the line box, which is why the bar grows from 40.3px
 * to 59.5px to 70.5px as the sentence wraps to two and three lines.
 */
.action-bar__inner {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: auto;
    /* 1280 total, not 1280 + gutters: the reference caps the padding box. */
    max-width: var(--container-wide);
    padding: var(--action-bar-padding-block) 40px;
    text-align: center;
}

.action-bar__icon {
    flex-shrink: 0;
    color: var(--gold-300);
}

/* Default gray, white on hover (CLAUDE.md §5.1). */
.action-bar__link {
    color: var(--text-dim);
    /* 14px / 19.25px on the reference, i.e. a 1.375 ratio. */
    font-size: var(--fs-sm);
    line-height: 1.375;
}

.action-bar__link:hover,
.action-bar__link:focus-visible {
    color: var(--text);
}

.action-bar__link strong {
    color: var(--text);
    font-weight: 700;
}

.action-bar__link .highlight {
    color: var(--gold-300);
    font-weight: 700;
    text-decoration: underline;
    text-underline-offset: 3px;
}

/*
 * 28 x 28 at 12px from the right edge, vertically centred — the reference's
 * own numbers. The ::before below keeps the tappable area at 44px so the
 * smaller visual circle does not shrink the touch target.
 */
.action-bar__close {
    position: absolute;
    top: 50%;
    right: 12px;
    transform: translateY(-50%);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    padding: 6px;
    border-radius: 50%;
    color: var(--text-dim);
    transition: color var(--transition), background var(--transition);
}

/*
 * Invisible 44px hit area centred on the 28px circle. Pointer events only;
 * it paints nothing and cannot affect layout.
 */
.action-bar__close::before {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 44px;
    height: 44px;
    transform: translate(-50%, -50%);
}

.action-bar__close:hover,
.action-bar__close:focus-visible {
    color: var(--text);
    background: var(--surface-2);
}


/* --- 7.2 Header & navigation ----------------------------------------- */

.site-header {
    position: relative;
    z-index: 20;
}

/*
 * Header and hero sit in the same 1280px container as the rest of the page,
 * so the nav, the hero copy and every section heading below share one left
 * edge. Header height is the reference site's 80px.
 */
/*
 * The header rides the SAME horizontal ruler as the hero.
 *
 * Measured on the reference at 1440: its header and its hero grid are both
 * max-w-7xl, i.e. a 1280px cap that INCLUDES the 32px side padding, so the
 * brand and the hero copy both start at x=112 and the header's right edge
 * clears the viewport by the same 80px as the hero grid.
 *
 * Ours inherited .container's 1280 + gutters (1344) cap on the header while
 * the hero was moved to the 1280 cap last pass, which left the brand 32px
 * to the LEFT of the hero copy. Capping the header the same way puts the
 * two back on one ruler. The nav and the language control travel with the
 * header, exactly as they do on the reference; nothing moves independently.
 */
.site-header__inner {
    display: flex;
    align-items: center;
    gap: 32px;
    max-width: var(--container-wide);
    min-height: var(--header-height);
}

/*
 * Brand lockup, measured on the reference header at 1440 / 768 / 390:
 *   mark            40 x 40 at every one of the three widths
 *   mark -> name    12px at 1440 and 768, 8px at 390
 * The name's own metrics already match (14px / 17.5px / 900 / -0.28px);
 * only the combined width differs, because "GOLDENBOX EA" is a longer
 * string than "GOLDTRAP EA".
 */
.brand {
    display: inline-flex;
    align-items: center;
    gap: 12px;
    flex-shrink: 0;
}

.brand__mark {
    width: 40px;
    height: 40px;
}

/*
 * Measured on the reference brand lockup at 1440, 768 and 390: 14px,
 * line-height 17.5px, weight 900, letter-spacing -0.28px, and constant at
 * every width. 0.875rem is that 14px; --ls-heading is -0.02em, which lands
 * on -0.28px by itself. The earlier 0.6rem rendered at 9.6px, well under
 * the reference.
 */
.brand__name {
    font-family: var(--font-display);
    font-size: 0.875rem;
    line-height: 1.25;
    font-weight: 900;
    letter-spacing: var(--ls-heading);
    text-transform: uppercase;
}

.primary-nav {
    flex: 1;
    display: flex;
    justify-content: center;
}

.primary-nav__list {
    display: flex;
    align-items: center;
    gap: clamp(20px, 2.2vw, 40px);
}

/* Nav links become white on hover (CLAUDE.md §5.2). */
.primary-nav__link {
    color: var(--text-dim);
    font-size: var(--fs-sm);
    font-weight: 600;
    line-height: 1.4286;
}

.primary-nav__link:hover,
.primary-nav__link:focus-visible {
    color: var(--text);
}


/* --- 7.2b Header actions group + hamburger ----------------------------
 * The language control and the hamburger live in one group so they stay
 * beside each other on mobile. The hamburger is hidden while the inline
 * navigation still fits; the responsive section reveals it.
 * ------------------------------------------------------------------- */

.site-header__actions {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-shrink: 0;
}

.nav-toggle {
    display: none;                 /* revealed below the nav breakpoint */
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border-radius: 12px;
    background: var(--surface-2);
    border: 1px solid var(--border-subtle);
    transition: background var(--transition), border-color var(--transition);
}

.nav-toggle:hover,
.nav-toggle:focus-visible {
    background: var(--surface-3);
    border-color: var(--border-gold);
}

/* Fixed box so the bars can rotate into an X without moving the button. */
.nav-toggle__box {
    position: relative;
    display: block;
    width: 20px;
    height: 14px;
}

.nav-toggle__bar {
    position: absolute;
    left: 0;
    height: 2px;
    width: 100%;
    border-radius: 2px;
    background: var(--text);
    transition: transform var(--transition), opacity var(--transition),
                top var(--transition);
}

.nav-toggle__bar:nth-child(1) { top: 0; }
.nav-toggle__bar:nth-child(2) { top: 6px; }
.nav-toggle__bar:nth-child(3) { top: 12px; }

/* Open state: the bars cross into an X. */
.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(1) {
    top: 6px;
    transform: rotate(45deg);
}

.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(2) {
    opacity: 0;
}

.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(3) {
    top: 6px;
    transform: rotate(-45deg);
}

/*
 * The header shows the full language name by default; the abbreviation
 * replaces it on mobile. Both are kept current by main.js.
 */
.lang-select__code {
    display: none;
}


/* --- 7.3 Language selector ------------------------------------------- */

.lang-select {
    position: relative;
    flex-shrink: 0;
}

.lang-select__toggle {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    padding: 14px 22px;
    border-radius: var(--radius-pill);
    background: var(--surface-2);
    border: 1px solid var(--border-subtle);
    font-weight: 700;
    transition: background var(--transition), border-color var(--transition);
    font-size: var(--fs-sm);
}

.lang-select__toggle:hover,
.lang-select__toggle:focus-visible {
    background: var(--surface-3);
    border-color: var(--border-gold);
}

.lang-select__chevron {
    transition: transform var(--transition);
}

.lang-select__toggle[aria-expanded="true"] .lang-select__chevron {
    transform: rotate(180deg);
}

.lang-select__panel {
    position: absolute;
    top: calc(100% + 10px);
    right: 0;
    z-index: 40;
    width: 280px;
    padding: 12px;
    background: var(--surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    box-shadow: 0 24px 60px -20px rgba(0, 0, 0, 0.9);
}

.lang-select__panel[hidden] {
    display: none;
}

.lang-select__search {
    width: 100%;
    padding: 11px 14px;
    margin-bottom: 10px;
    background: var(--bg-zinc);
    border: 1px solid var(--border-subtle);
    border-radius: 10px;
    color: var(--text);
    font: inherit;
    font-size: var(--fs-sm);
}

.lang-select__search::placeholder {
    color: var(--text-dim);
}

.lang-select__search:focus {
    outline: none;
    border-color: var(--gold-400);
}

/*
 * iOS Safari zooms the whole page in whenever a focused form control's
 * font-size is under 16px, and it does NOT zoom back out when the field is
 * blurred — only a reload or a manual pinch clears it.
 *
 * openPanel() in main.js focuses this field the moment the language
 * dropdown opens, so on an iPhone every single language change zoomed the
 * page: text looked larger, the layout looked enlarged, and the page
 * gained horizontal scroll. It read as "translation broke the layout",
 * but the zoom happens when the dropdown opens, before Google Translate
 * has done anything at all.
 *
 * 16px is the threshold, so the field is given exactly that on touch
 * devices. The desktop dropdown keeps its 14px from the mockup. The
 * alternative — user-scalable=no / maximum-scale=1 in the viewport meta —
 * would also stop the zoom but at the cost of blocking pinch-zoom for
 * everyone, which is not acceptable.
 */
@media (hover: none), (pointer: coarse) {
    .lang-select__search {
        font-size: 16px;
    }
}

.lang-select__list {
    max-height: 280px;
    overflow-y: auto;
}

.lang-select__option {
    display: block;
    width: 100%;
    padding: 10px 14px;
    border-radius: 8px;
    color: var(--text-dim);
    font-size: var(--fs-sm);
    text-align: left;
    transition: background var(--transition), color var(--transition);
}

.lang-select__option:hover,
.lang-select__option:focus-visible {
    background: var(--surface-2);
    color: var(--text);
}

.lang-select__option[aria-selected="true"] {
    color: var(--gold-300);
    font-weight: 700;
}

.lang-select__empty {
    padding: 14px;
    color: var(--text-dim);
    font-size: var(--fs-sm);
    text-align: center;
}


/* ======================================================================
 * 8. SECTION 1 — HERO
 * ====================================================================== */

.hero {
    position: relative;
    border-bottom: 1px solid var(--rule);
}

/*
 * Warm radial glow from the top-left. It extends UPWARD past the hero so it
 * sits behind the transparent header and the announcement bar, exactly as
 * the mockup shows — sample the mockup at y5-45 and the bar's background is
 * warm (21,19,11) at the edges, not flat #050505.
 *
 * How far up it has to reach differs per page, because the element that
 * carries the glow sits at a different height on each:
 *
 *   FAQ page   .hero is a wrapper DIV starting just below the bar (y66),
 *              so 100px was already enough to cover it.
 *   Homepage   .hero is the hero SECTION, below the header (y146), so a
 *              fixed 100px stopped 46px short and the bar rendered flat.
 *
 * --hero-glow-rise is written by main.js from the measured distance to the
 * top of the page, with 100px as the floor, so ONE rule covers both pages
 * and neither has a hard-coded offset. The fallback keeps the previous
 * behaviour if the script never runs.
 */
.hero::before {
    content: "";
    position: absolute;
    inset: calc(-1 * var(--hero-glow-rise, 100px)) 0 0;
    pointer-events: none;
    background:
        radial-gradient(35% 47% at 24% 16%, rgba(196, 156, 52, 0.20) 0%, rgba(0, 0, 0, 0) 78%),
        radial-gradient(78% 66% at 45% 6%, rgba(180, 145, 50, 0.065) 0%, rgba(0, 0, 0, 0) 88%);
}

/*
 * HERO CONTAINER GEOMETRY, measured on the reference.
 *
 * Every other section caps its CONTENT box at 1280 and adds the gutter
 * outside it, which puts section content 80px from a 1440 viewport edge —
 * the reference does the same, and .container already matches it.
 *
 * The hero is the one exception on the reference: its max-width of 1280
 * includes the 32px side padding, so the copy starts 112px from the edge
 * rather than 80px. Overriding .container's cap here reproduces that
 * without touching any other section.
 *
 *   1440 viewport -> content at x=112, 112px clear on the right
 *    768 viewport -> content at x=32   (cap inactive; gutter binds)
 *    390 viewport -> content at x=20   (mobile gutter, as the reference)
 *
 * min-height is the reference's own calc(100dvh - 84px). With the existing
 * align-items: center it is what opens the tall gap between the header and
 * the eyebrow on a desktop viewport, and it goes inactive on tablet and
 * phone where the stacked content is already taller — the same responsive
 * behaviour the reference shows, from one property and no new breakpoint.
 */
.hero__inner {
    position: relative;
    z-index: 1;
    max-width: var(--container-wide);
    min-height: calc(100dvh - 84px);
    display: grid;
    /*
     * Left copy is fluid; the chart column holds the mockup's panel scaled
     * to the container. The mockup's 694px panel sat in a 1520px container;
     * in the 1280px container that is 694 x (1280 / 1520) = 584px, which
     * also leaves the copy column wide enough for the 72px wordmark to stay
     * on one line at every desktop width.
     */
    grid-template-columns: minmax(0, 1fr) clamp(380px, 30vw, 584px);
    align-items: center;
    gap: clamp(40px, 3.4vw, 64px);
    padding-block: 32px clamp(48px, 4.5vw, 85px);
}

/*
 * HERO TITLE — the shimmering gold wordmark.
 *
 * The gradient is twice the width of the text (background-size: 200%) and
 * the keyframe walks it one full width to the left, so the light band at
 * the 50% stop sweeps continuously across the letters.
 *
 * `color` is a solid gold FALLBACK, not decoration: a browser without
 * background-clip: text ignores the clip and paints this colour instead,
 * so the title is never invisible. The transparent fill is applied only
 * inside the @supports block below.
 */
.hero__title {
    margin: 0 0 26px;
    font-size: var(--fs-h1);
    font-weight: 900;
    line-height: var(--lh-h1);
    letter-spacing: var(--ls-heading);
    text-transform: uppercase;
    /* Desktop keeps the wordmark on one line, as the mockup shows. */
    white-space: nowrap;
    color: var(--gold-300);

    background-image: linear-gradient(105deg,
        #f7e7a6 0%,
        #c9a84c 28%,
        #fff8d7 50%,
        #d6b75a 72%,
        #f7e7a6 100%);
    background-size: 200% auto;
}

@supports ((-webkit-background-clip: text) or (background-clip: text)) {
    .hero__title {
        -webkit-background-clip: text;
        background-clip: text;
        color: transparent;
        animation: gt2-shimmer 7s linear infinite;
    }
}

@keyframes gt2-shimmer {
    100% { background-position: 200% center; }
}

/*
 * Reduced motion freezes the sweep but KEEPS the gradient fill, so the
 * title still renders as gold rather than disappearing.
 */
@media (prefers-reduced-motion: reduce) {
    .hero__title {
        animation: none;
    }
}

.hero__subtitle {
    margin: 0 0 22px;
    color: var(--gold-300);
    font-size: var(--fs-subhead);
    font-weight: 700;
    line-height: 1.5556;
}

.hero__text {
    max-width: 752px;
    color: var(--text-muted);
    font-size: var(--fs-lead);
    line-height: var(--lh-body);
}

.hero__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    margin-top: 40px;
}

/* --- Live chart container --------------------------------------------
 * CLAUDE.md §5.4: this is a real, correctly-sized empty container for an
 * externally supplied chart. The aspect ratio is locked so injecting a
 * widget cannot reflow the hero.
 * ------------------------------------------------------------------- */

.hero__chart-panel {
    padding: 10px;
    background: var(--surface-warm);
    border: 1px solid #2F2B1D;
    border-radius: var(--radius-lg);
    box-shadow: 0 30px 90px -30px rgba(200, 165, 70, 0.35);
}

#live-chart-container {
    aspect-ratio: 672 / 597;
    width: 100%;
    border-radius: 18px;
    background: #0F0F0F;
    overflow: hidden;
}

/* Anything injected into the container fills it without changing layout. */
#live-chart-container > * {
    width: 100%;
    height: 100%;
    border: 0;
}

.hero__chart-caption {
    margin-top: 14px;
    color: var(--text-dim);
    font-size: var(--fs-xs);
    text-align: right;
    line-height: var(--lh-body);
}


/* ======================================================================
 * 9. SECTION 2 — QUICK BENEFITS
 * ====================================================================== */

.benefits__grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 16px;
    margin-top: 48px;
}

.benefit-card {
    display: flex;
    align-items: center;
    gap: 16px;
    min-height: 82px;
    padding: 16px 22px;
}

.benefit-card__label {
    font-size: var(--fs-body);
    font-weight: 900;
    /*
     * As a flex item this defaults to min-width: auto, so its minimum
     * width is its longest word. German compounds are long enough to blow
     * the card past the screen — "Warenkorbverwaltungssystem" measured
     * 242px against 280px of usable width at 320px. Letting the box
     * shrink and the word break keeps the card inside the viewport.
     * `anywhere` rather than `break-word` because only `anywhere` also
     * lowers the min-content size that was forcing the card wide.
     */
    min-width: 0;
    overflow-wrap: anywhere;
    line-height: var(--lh-tight);
}

/*
 * §6: on hover the label takes the tick icon's colour and the border
 * responds. The disc is nudged brighter at the same time.
 */
.benefit-card:hover {
    border-color: var(--border-gold-solid);
    background: rgba(221, 185, 84, 0.04);
}

.benefit-card:hover .benefit-card__label {
    color: var(--gold-300);
}

.benefit-card:hover .icon-disc {
    background: rgba(221, 185, 84, 0.2);
}


/* ======================================================================
 * 10. SECTION 3 — HOW GOLDTRAP WORKS
 * ====================================================================== */

.steps__grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 20px;
    margin-top: 48px;
}

.step-card {
    padding: 32px;
}

/* The numbered disc is 48px on these cards, larger than the default. */
.step-card .icon-disc {
    width: 48px;
    height: 48px;
    font-size: var(--fs-sm);
}

.step-card__title {
    margin: 38px 0 16px;
    font-size: var(--fs-h3);
    line-height: var(--lh-h3);
}

.step-card__text {
    color: var(--text-muted);
    font-size: var(--fs-sm);
    line-height: var(--lh-body);
}


/* ======================================================================
 * 11. SECTION 4 — LIVE RESULTS
 * ====================================================================== */

.live-results__inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 48px;
    padding-block: clamp(64px, 6vw, 104px);
}

.live-results__copy {
    max-width: 800px;
}

/* The stats strip is a second band, separated by warm hairlines. */
.live-stats {
    border-top: 1px solid var(--rule-warm);
}

.live-stats__inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 32px;
    padding-block: 32px;
}

.live-stats__pill {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    padding: 8px 18px;
    border-radius: var(--radius-pill);
    border: 1px solid var(--border-gold);
    color: var(--gold-300);
    font-size: var(--fs-2xs);
    font-weight: 900;
    letter-spacing: var(--ls-eyebrow);
    text-transform: uppercase;
}

.live-stats__figures {
    display: flex;
    align-items: center;
    gap: clamp(32px, 4vw, 72px);
}

.stat {
    text-align: center;
}

.stat__value {
    font-size: var(--fs-stat);
    font-weight: 900;
    line-height: var(--lh-h3-lg);
}

.stat__label {
    margin-top: 6px;
    color: var(--text-dim);
    font-size: var(--fs-2xs);
    font-weight: 700;
    letter-spacing: 0.025em;
    text-transform: uppercase;
}

.stat__divider {
    width: 1px;
    align-self: stretch;
    background: var(--rule-warm);
}


/* ======================================================================
 * 12. SECTION 5 — GET GOLDTRAP EA (PRICING)
 * ======================================================================
 * The grid uses auto-fit so a fourth plan can be added in main.js with no
 * CSS change (CLAUDE.md §9.1). Card internals are padding/flex based, never
 * fixed-width, so they reflow when the column count changes.
 * ====================================================================== */

.pricing__grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 20px;
    margin-top: 48px;
}

.plan-card {
    display: flex;
    flex-direction: column;
    padding: 32px;
    background: var(--surface-warm);
    border: 1px solid var(--border-gold);
    border-radius: var(--radius-lg);
}

.plan-card--free {
    border-color: rgba(43, 193, 138, 0.32);
}

.plan-card__eyebrow {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 18px;
    color: var(--gold-300);
    font-size: var(--fs-xs);
    font-weight: 900;
    letter-spacing: var(--ls-eyebrow);
    text-transform: uppercase;
}

.plan-card--free .plan-card__eyebrow {
    color: var(--green-btn);
}

.plan-card__name {
    font-size: var(--fs-h3);
    margin-bottom: 10px;
    line-height: var(--lh-h3);
}

.plan-card__price-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
}

.plan-card__price {
    font-size: var(--fs-price);
    font-weight: 900;
    line-height: var(--lh-h2);
    letter-spacing: -0.03em;
}

.plan-card--free .plan-card__price {
    color: var(--green-text);
}

.plan-card__currency {
    color: var(--text-dim);
    font-family: var(--font-body);
    font-size: var(--fs-sm);
    font-weight: 500;
    align-self: flex-end;
    margin-left: -6px;
}

.plan-card__caption {
    margin-top: 12px;
    color: var(--text-dim);
    font-size: var(--fs-xs);
}

/* --- Countdown timer (CLAUDE.md §9.3 / §9.4) --------------------------
 * When a plan's status is "hide" the timer uses visibility: hidden, NOT
 * display: none, so the row keeps its space and the card height never
 * shifts between the two states.
 * ------------------------------------------------------------------- */

/*
 * COUNTDOWN TIMER
 * Roboto, not the mono face: `tabular-nums` gives fixed-width digits, so
 * the countdown cannot jitter as it ticks, while the typeface stays the
 * body face. Bold and prominent, as agreed.
 */
/*
 * Shared by the pricing plans and the source-code card — one visual
 * treatment for one countdown implementation.
 */
.plan-card__timer,
.source-code__timer {
    display: flex;
    align-items: center;
    gap: 8px;
    min-height: 28px;
    margin-top: 14px;
    color: var(--gold-300);
    font-size: var(--fs-timer);
    font-weight: 900;
    line-height: var(--lh-h4);
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
}

/*
 * §9.4: a hidden timer keeps its allocated space. visibility, never
 * display, so the card cannot jump when it is turned on or off.
 */
.plan-card__timer.is-hidden,
.source-code__timer.is-hidden {
    visibility: hidden;
}

/* The source-code card's own spacing around the shared timer row. */
.source-code__timer {
    margin-top: 12px;
    font-size: var(--fs-sm);
}

.plan-card__divider {
    height: 1px;
    margin: 24px 0;
    background: var(--border-subtle);
}

.plan-card__features {
    display: grid;
    gap: 14px;
    margin-bottom: 28px;
}

.plan-card__features li {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    font-size: var(--fs-sm);
}

.plan-card__features .check {
    flex-shrink: 0;
    margin-top: 3px;
    color: var(--gold-300);
}

.plan-card--free .plan-card__features .check {
    color: var(--green-btn);
}

/* Numbered step list used by the free plan. */
.plan-card__steps {
    display: grid;
    gap: 14px;
    margin-bottom: 20px;
}

.plan-card__steps li {
    display: flex;
    align-items: center;
    gap: 12px;
    font-size: var(--fs-sm);
}

.plan-card__note {
    padding: 10px 14px;
    margin-bottom: 20px;
    background: var(--danger-bg);
    border: 1px solid rgba(248, 113, 113, 0.28);
    border-radius: 10px;
    color: var(--danger-text);
    font-size: var(--fs-2xs);
    font-weight: 700;
}

.plan-card__note strong {
    font-weight: 700;
}

/* Pushes the CTA to the bottom so buttons align across unequal cards. */
.plan-card__cta {
    margin-top: auto;
}


/* ======================================================================
 * 13. SECTION 6 — SOURCE CODE
 * ====================================================================== */

.source-code {
    position: relative;
    /* The source-code card reads narrower than the pricing grid above it
       (measured 1152px against the pricing row's 1280px). It sits inside
       the same container, so it constrains itself rather than needing a
       second wrapper in the markup. */
    max-width: var(--container-mid);
    margin-inline: auto;
    /*
     * Measured from the mockup: the pricing cards' bottom border sits at
     * y4013 and the source-code card's top border at y4075 — a 62px gap.
     * An earlier reading of 8px was wrong; it mistook the source card's
     * large gold glow, which bleeds upward over the gap, for the cards
     * themselves. Do not reduce this again.
     */
    margin-top: 62px;
}

.source-code__card {
    position: relative;
    max-width: 1550px;
    margin-inline: auto;
    padding: 34px 44px 32px;
    background: #0C0A06;
    border: 1px solid var(--gold-400);
    border-radius: var(--radius-lg);
    box-shadow: 0 40px 120px -40px rgba(221, 185, 84, 0.45);
}

/* The gold pill straddles the top border of the card. */
.source-code__tag {
    position: absolute;
    top: 0;
    left: 40px;
    transform: translateY(-50%);
    margin: 0;
}

.source-code__layout {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 56px;
}

.source-code__copy {
    max-width: 68ch;
}

.source-code__title {
    font-size: var(--fs-h3-lg);
    margin-bottom: 12px;
    line-height: var(--lh-h3-lg);
}

.source-code__text {
    color: var(--text-muted);
    margin-bottom: 20px;
    max-width: 62ch;
}

.source-code__price-row {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 10px;
    margin-top: 24px;
}

.source-code__price {
    font-size: var(--fs-h3-lg);
    font-weight: 900;
    line-height: var(--lh-h3-lg);
    letter-spacing: -0.03em;
}

.source-code__meta {
    color: var(--text-dim);
    font-size: var(--fs-sm);
}

/* The source-code card is darker than the page, so its dark button is lifted. */
.source-code__actions .btn--dark {
    background: #1B1914;
}

.source-code__actions .btn--dark:hover,
.source-code__actions .btn--dark:focus-visible {
    background: #2A2721;
}

.source-code__actions {
    display: flex;
    flex-direction: column;
    gap: 14px;
    flex-shrink: 0;
    min-width: 240px;
}


/* ======================================================================
 * 14. SECTION 7 — FREE ACCESS
 * ====================================================================== */

.free-access__inner {
    text-align: center;
}

.free-access__grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 16px;
    margin-top: 48px;
    text-align: left;
}

.free-access__step {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 18px 22px;
}

.free-access__step-label {
    font-size: var(--fs-sm);
    font-weight: 700;
}

.free-access__actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 16px;
    margin-top: 40px;
}


/* ======================================================================
 * 15. SECTION 8 — DOWNLOAD
 * ====================================================================== */

.download__inner {
    text-align: center;
}

.download__grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 20px;
    margin-top: 48px;
    text-align: left;
}

.download-card {
    padding: 28px;
}

.download-card__head {
    display: flex;
    align-items: center;
    gap: 16px;
    margin-bottom: 22px;
}

.download-card__title {
    font-size: var(--fs-h4);
    margin-bottom: 4px;
    line-height: var(--lh-h4);
}

.download-card__file {
    color: var(--text-dim);
    font-family: var(--font-mono);
    font-size: var(--fs-xs);
}

.download-card__licence {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 14px 16px;
    margin-bottom: 18px;
    background: var(--bg-zinc);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-sm);
    color: var(--text-dim);
    font-size: var(--fs-xs);
}

/* Wide gold-tinted banner pointing at the preset .set files. */
.preset-banner {
    display: flex;
    align-items: center;
    gap: 20px;
    padding: 22px 26px;
    margin-top: 20px;
    background: rgba(221, 185, 84, 0.05);
    border: 1px solid var(--border-gold);
    border-radius: var(--radius-md);
    text-align: left;
}

.preset-banner__copy {
    flex: 1;
}

.preset-banner__title {
    font-weight: 900;
    margin-bottom: 4px;
    font-size: var(--fs-sm);
}

.preset-banner__text {
    color: var(--text-muted);
    font-size: var(--fs-xs);
}

.preset-banner__link {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    flex-shrink: 0;
    color: var(--gold-300);
    font-size: var(--fs-xs);
    font-weight: 700;
}

.preset-banner__link:hover,
.preset-banner__link:focus-visible {
    color: var(--text);
}

.download__licence-hint {
    margin-top: 28px;
    color: var(--text-dim);
    font-size: var(--fs-xs);
}

.download__licence-hint a {
    color: var(--gold-300);
    font-weight: 700;
}

.download__licence-hint a:hover,
.download__licence-hint a:focus-visible {
    color: var(--text);
}

/* Setup note card holding the whitelist URL + copy control. */
.setup-note {
    padding: 26px 28px;
    margin-top: 28px;
    background: rgba(221, 185, 84, 0.04);
    border: 1px solid var(--border-gold);
    border-radius: var(--radius-md);
    text-align: left;
}

.setup-note__title {
    color: var(--gold-300);
    font-weight: 600;
    margin-bottom: 12px;
    font-size: var(--fs-xs);
}

.setup-note__text {
    color: var(--text-muted);
    font-size: var(--fs-xs);
    margin-bottom: 14px;
}

.setup-note__url-row {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    padding: 6px 6px 6px 14px;
    background: var(--bg-zinc);
    border: 1px solid var(--border-subtle);
    border-radius: 10px;
}

.setup-note__url {
    color: var(--gold-300);
    font-family: var(--font-mono);
    font-size: var(--fs-xs);
    font-weight: 600;
}

.setup-note__steps {
    margin-top: 16px;
    color: var(--text-dim);
    font-size: var(--fs-xs);
}


/* ======================================================================
 * 16. SECTION 9 — FAQ
 * ====================================================================== */

.faq__inner {
    text-align: center;
}

.faq__categories {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 12px;
    margin-top: 36px;
}

/* Inactive category text goes white on hover (CLAUDE.md §15.1). */
.faq__category {
    padding: 12px 22px;
    border-radius: var(--radius-pill);
    background: var(--surface-2);
    border: 1px solid var(--border-subtle);
    color: var(--text-dim);
    font-size: var(--fs-xs);
    font-weight: 700;
    transition: background var(--transition), color var(--transition),
                border-color var(--transition);
    letter-spacing: 0.025em;
}

.faq__category:hover,
.faq__category:focus-visible {
    color: var(--text);
    border-color: var(--border-gold);
}

.faq__category[aria-selected="true"] {
    background: var(--grad-gold);
    border-color: transparent;
    color: var(--on-gold);
}

/*
 * Two independent columns rather than one 2-column grid: opening an item
 * must grow only its own column, exactly as the mockup shows.
 */
.faq__columns {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-items: start;
    gap: 20px;
    margin-top: 36px;
    text-align: left;
}

.faq__column {
    display: flex;
    flex-direction: column;
    gap: 20px;
}

.faq-item {
    background: var(--surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    transition: border-color var(--transition), background var(--transition);
}

.faq-item.is-open {
    background: rgba(221, 185, 84, 0.04);
    border-color: var(--border-gold);
}

/* The homepage question header: trigger plus copy control, side by side. */
.faq-item__heading {
    display: flex;
    align-items: center;
    margin: 0;
    padding-inline-end: 8px;
    font-family: inherit;
    font-size: inherit;
    font-weight: inherit;
    line-height: inherit;
    letter-spacing: inherit;
}

.faq-item__trigger {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
    width: 100%;
    padding: 22px 24px;
    font-family: var(--font-body);
    font-size: var(--fs-body);
    font-weight: 900;
    text-align: left;
    transition: color var(--transition);
    line-height: var(--lh-tight);
}

.faq-item__trigger:hover {
    color: var(--gold-300);
}

.faq-item__chevron {
    flex-shrink: 0;
    color: var(--text-dim);
    transition: transform var(--transition), color var(--transition);
}

.faq-item__trigger[aria-expanded="true"] .faq-item__chevron {
    transform: rotate(180deg);
    color: var(--gold-300);
}

.faq-item__panel {
    padding: 0 24px 24px;
    color: var(--text-muted);
    line-height: 1.75;
}

.faq-item__panel[hidden] {
    display: none;
}

.faq__browse {
    margin-top: 40px;
}


/* ======================================================================
 * 17. SECTION 10 — FOOTER
 * ====================================================================== */

.site-footer {
    background: var(--bg-black);
    text-align: center;
}

.site-footer__inner {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding-block: 56px;
}

/* Editable footer caveat / disclaimer — populated from main.js. */
#footer-caveat {
    max-width: var(--container-sm);
    color: var(--text-faint);
    font-size: var(--fs-2xs);
    line-height: 1.64;
}

.terms-notice {
    margin-top: 10px;
    color: var(--text-faint);
    font-size: var(--fs-2xs);
}

/* Terms link behaves like every other site link: dim by default, white on hover. */
#terms-and-conditions-link {
    color: var(--text-dim);
    text-decoration: underline;
    text-underline-offset: 3px;
}

#terms-and-conditions-link:hover,
#terms-and-conditions-link:focus-visible {
    color: var(--text);
}

/* Telegram button: the whole container reacts, not just the icon. */
.footer-telegram {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 50px;
    height: 50px;
    margin-top: 34px;
    border-radius: 50%;
    background: var(--surface);
    border: 1px solid #2A2A2A;
    color: var(--text-dim);
    transition: background var(--transition), border-color var(--transition),
                color var(--transition);
}

.footer-telegram:hover,
.footer-telegram:focus-visible {
    background: var(--surface-3);
    border-color: var(--text);
    color: var(--text);
}

.site-footer__copyright {
    margin-top: 25px;
    color: var(--text-faint);
    font-size: var(--fs-2xs);
    line-height: var(--lh-tight);
}


/* ======================================================================
 * 18. LIVE CHAT WIDGET
 * ====================================================================== */

/*
 * ONE property controls the launcher's size. The wrapper, the avatar and
 * the pulse ring all read from it, so the visible circle measures exactly
 * this and nothing — no padding, no border box, no ring — grows the
 * footprint past it. Measured on the reference site: 56px.
 */
.chat-widget {
    --chat-size: 56px;

    position: fixed;
    right: 24px;
    /* Respect the home indicator on phones without changing the desktop
       offset: the max() keeps 24px unless the inset is larger. */
    bottom: max(24px, env(safe-area-inset-bottom, 0px));
    /* Above page content, below an open dialog (dialogs sit on the top
       layer, so this only has to clear the rest of the page). */
    z-index: 60;
    display: inline-flex;
    align-items: center;
    transition: transform var(--transition);
}

.chat-widget:hover,
.chat-widget:focus-visible {
    transform: scale(1.05);
}

.chat-widget:active {
    transform: scale(0.95);
}

/*
 * The round clipping wrapper. overflow: hidden means the photo is cropped
 * to the circle rather than relying on the image being square.
 */
.chat-widget__avatar-wrap {
    position: relative;
    display: inline-flex;
    flex-shrink: 0;
    width: var(--chat-size);
    height: var(--chat-size);
    border-radius: 50%;
    background: linear-gradient(to bottom, var(--gold-100) 0%, var(--gold-500) 100%);
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.5);
}

.chat-widget__avatar {
    position: relative;
    z-index: 1;
    width: var(--chat-size);
    height: var(--chat-size);
    border-radius: 50%;
    /* A hairline ring in warm white at 40%, as measured. Drawn with an
       inset shadow so it cannot add to the element's 56px box. */
    box-shadow: inset 0 0 0 1px rgba(255, 246, 221, 0.4);
    object-fit: cover;
}

/*
 * Continuous gold "energy" pulse. It is a separate ring behind the photo,
 * so the avatar itself never scales, blurs or distorts. The colour is the
 * configurable site accent, not a hard-coded gold.
 */
.chat-widget__pulse {
    position: absolute;
    inset: 0;
    border-radius: 50%;
    /*
     * A thin ring with a soft outer glow rather than a filled disc, so the
     * effect reads as energy radiating outward instead of a heavy gold
     * plate behind the photo.
     */
    background: var(--site-primary-accent, #C9A84C);
    /* A soft glow, not a hard ring: the blur carries most of the effect. */
    box-shadow: 0 0 18px 4px var(--site-primary-accent, #C9A84C);
    opacity: 0;                    /* nothing at all shows at rest */
    animation: chat-pulse 2.6s ease-out infinite;
}

/*
 * JS-TIMED PULSE MODE.
 * The ring above repeats back-to-back, so the gap between pulses is fixed
 * at the animation's own duration. initLiveChatPulse() in main.js adds
 * .is-js-timed and then drives one pulse at a time, which is what makes
 * liveChatPulseInterval possible.
 *
 * The pulse ITSELF is untouched: same @keyframes, same 2.6s duration, same
 * easing, same colour and glow. Only how often it starts changes. The
 * continuous rule above stays the no-JS default, so the launcher still
 * pulses if the script never runs.
 */
.chat-widget__pulse.is-js-timed {
    animation: none;
}

.chat-widget__pulse.is-js-timed.is-pulsing {
    animation: chat-pulse 2.6s ease-out 1;
}

/*
 * Deliberately a SINGLE ring. A second, offset ring meant one was always
 * sitting close to the avatar, which read as a permanent gold outline —
 * the opposite of the intent. One ring per cycle leaves a clear gap, so
 * the glow is unmistakably an animation rather than a border.
 */

/*
 * Starts fully transparent at the avatar's own size, fades in as it leaves
 * the photo, then fades out as it expands. At no point in the cycle is
 * there a resting ring sitting on the launcher.
 */
@keyframes chat-pulse {
    0%   { transform: scale(1);    opacity: 0; }
    18%  { opacity: 0.45; }
    100% { transform: scale(1.7);  opacity: 0; }
}

/*
 * Hover / focus label, sliding out to the LEFT. It is absolutely
 * positioned so revealing it cannot shift the launcher or the page.
 */
.chat-widget__label {
    position: absolute;
    right: 68px;
    top: 50%;
    transform: translate(8px, -50%);
    white-space: nowrap;
    padding: 10px 16px;
    border-radius: var(--radius-pill);
    background: var(--surface);
    border: 1px solid var(--border-subtle);
    color: var(--text);            /* hover text stays white */
    font-size: var(--fs-xs);
    font-weight: 700;
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--transition), transform var(--transition);
}

/* Keyboard focus gets the same visible state as hover. */
.chat-widget:hover .chat-widget__label,
.chat-widget:focus-visible .chat-widget__label {
    opacity: 1;
    transform: translate(0, -50%);
}

/*
 * Online indicator — green, and deliberately separate from the gold pulse
 * above. Green means "available"; gold is the site's accent animation.
 */
.chat-widget__status {
    position: absolute;
    z-index: 2;
    top: -2px;
    right: -2px;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: var(--green-dot);
    border: 2px solid var(--bg-black);
}


/*
 * Reduced motion for the launcher.
 * This block must come AFTER the .chat-widget rules above: the earlier
 * reduced-motion block in section 6 has equal specificity and would
 * otherwise be overridden by source order.
 */
@media (prefers-reduced-motion: reduce) {
    .chat-widget__pulse,
    /* Same specificity as the timed rule above, so it cannot be outranked. */
    .chat-widget__pulse.is-js-timed.is-pulsing {
        animation: none;
        opacity: 0;                /* no animation, and no static ring either */
    }

    .chat-widget:hover,
    .chat-widget:focus-visible {
        transform: none;
    }
}


/* ======================================================================
 * 19. DIALOGS
 * ======================================================================
 * One dialog element serves both the EA purchase flow and the source-code
 * purchase flow. Its contents are built in main.js from the clicked card.
 * ====================================================================== */

.purchase-dialog {
    width: min(640px, calc(100vw - 48px));
    padding: 0;
    background: var(--surface-warm);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-lg);
    color: var(--text);
    overflow: hidden;
}

.purchase-dialog::backdrop {
    background: rgba(0, 0, 0, 0.72);
    backdrop-filter: blur(3px);
}

.purchase-dialog__head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 24px;
    padding: 32px 32px 26px;
    border-bottom: 1px solid var(--border-subtle);
}

.purchase-dialog__title {
    font-size: var(--fs-h3);
    margin-bottom: 6px;
    line-height: var(--lh-h3);
}

.purchase-dialog__subtitle {
    color: var(--text-muted);
    font-size: var(--fs-sm);
}

.purchase-dialog__close {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    color: var(--text-dim);
    transition: background var(--transition), color var(--transition);
}

.purchase-dialog__close:hover,
.purchase-dialog__close:focus-visible {
    background: var(--surface-2);
    color: var(--text);
}

.purchase-dialog__body {
    padding: 26px 32px 32px;
}

.purchase-dialog__rows {
    display: grid;
    gap: 12px;
}

.purchase-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
    padding: 18px 22px;
    background: var(--bg-zinc);
    border-radius: var(--radius-sm);
}

.purchase-row__label {
    color: var(--text-muted);
    font-size: var(--fs-sm);
}

.purchase-row__value {
    font-weight: 700;
}

.purchase-row__value--gold {
    color: var(--gold-300);
}

.purchase-row__value--amount {
    font-size: var(--fs-h3-lg);
    font-weight: 900;
}

.purchase-row__suffix {
    margin-left: 4px;
    color: var(--text-dim);
    font-family: var(--font-body);
    font-size: var(--fs-xs);
    font-weight: 500;
}

/* --- Wallet address row (CLAUDE.md §10.3) -----------------------------
 * A real <button> wrapping the whole row so it is keyboard operable.
 * ------------------------------------------------------------------- */

.wallet-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
    width: 100%;
    padding: 16px 22px;
    background: var(--bg-zinc);
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    text-align: left;
    transition: border-color var(--transition), color var(--transition);
}

.wallet-row:hover,
.wallet-row:focus-visible {
    border-color: var(--border-gold-solid);
}

.wallet-row:hover .wallet-row__icon,
.wallet-row:focus-visible .wallet-row__icon {
    color: var(--border-gold-solid);
}

.wallet-row__label {
    display: block;
    margin-bottom: 4px;
    color: var(--text-dim);
    font-size: var(--fs-2xs);
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
}

.wallet-row__value {
    color: var(--text);
    font-family: var(--font-mono);
    font-size: var(--fs-sm);
    word-break: break-all;
}

.wallet-row__icon {
    flex-shrink: 0;
    color: var(--text-dim);
    transition: color var(--transition);
}

/* Copied state: the copy icon is replaced by a green check for 5 seconds. */
.wallet-row .icon-check { display: none; }

.wallet-row.is-copied .icon-copy { display: none; }
.wallet-row.is-copied .icon-check { display: block; }

.wallet-row.is-copied,
.wallet-row.is-copied:hover {
    border-color: var(--green-dot);
}

.wallet-row.is-copied .wallet-row__icon {
    color: var(--green-dot);
}

.purchase-dialog__note {
    margin: 20px 0 24px;
    color: var(--text-muted);
    font-size: var(--fs-xs);
    line-height: 1.65;
}

/* Confirm button takes the flat gold fill from the dialog mockups. */
.purchase-dialog__confirm {
    background: var(--gold-400);
}


/* ======================================================================
 * 20. GTRANSLATE OVERRIDES
 * ======================================================================
 * Translation runs on the free GTranslate widget. GTranslate's own UI is
 * hidden here so the site's custom gold dropdown stays the only visible
 * interface, and the banner frame Google injects is suppressed so
 * translating never shifts the layout.
 * ====================================================================== */

/* GTranslate's markup and the hidden engine it mounts inside it. */
.gtranslate_wrapper,
#google_translate_element2 {
    display: none !important;
}

.skiptranslate iframe,
iframe.skiptranslate {
    display: none !important;
}

body {
    top: 0 !important;
}

/*
 * ----------------------------------------------------------------------
 * Translation-induced horizontal overflow
 * ----------------------------------------------------------------------
 * Google appends its own UI directly to <body>, which is OUTSIDE
 * .page-wrapper — the element that carries this site's only overflow-x
 * clip. Anything Google injects therefore sits in the document's
 * scrollable area with nothing to constrain it.
 *
 * The offending element is #goog-gt-tt (Google's "original text" bubble,
 * classes VIpgJd-suEOdc VIpgJd-yAWNEb-L7lbkb skiptranslate). Google gives
 * it position: absolute, a hard width: 420px and an inline
 * margin: 0 0 0 -23px, then shows it when a visitor taps or hovers a
 * translated phrase. Measured on a 390px-wide phone with the real Google
 * engine running, the moment that bubble is displayed:
 *
 *     WebKit   documentElement.scrollWidth 390px -> 537px  (+147px)
 *     Chromium documentElement.scrollWidth 390px -> 397px  (+7px)
 *
 * How far it overflows depends on where Google places the bubble, which
 * follows the phrase the visitor touched — isolated runs measured +111px
 * in WebKit and +157px in Chromium. Any placement overflows, because the
 * bubble alone is wider than the screen.
 *
 * That is the horizontal scrollbar, and it is why reloading clears it:
 * the bubble is rebuilt hidden on every page load. Translating also flips
 * <body> to position: relative, which makes <body> the containing block
 * for that absolutely positioned bubble, so its 420px box lands in the
 * page's scroll area rather than being resolved against the viewport.
 *
 * The bubble is CONSTRAINED, not hidden: it is still a working part of
 * Google's translation UI. It is pinned inside a 12px gutter, sized to the
 * viewport, and capped at Google's own 420px where the screen is wide
 * enough — so it can never be wider than the screen it is drawn on.
 */
#goog-gt-tt {
    box-sizing: border-box !important;
    left: 12px !important;
    right: 12px !important;
    width: auto !important;
    max-width: 420px !important;
    margin-left: 0 !important;
    margin-right: 0 !important;
}

/*
 * Same bubble addressed by its class, in case Google renders a second
 * instance without the id, and for any nested copy: cap the width only,
 * so a nested bubble keeps the placement Google gave it.
 */
.VIpgJd-yAWNEb-L7lbkb {
    box-sizing: border-box !important;
    max-width: min(420px, calc(100vw - 24px)) !important;
}

/* Nothing Google lays out inside the bubble may push past its edges. */
#goog-gt-tt *,
.VIpgJd-yAWNEb-L7lbkb * {
    box-sizing: border-box !important;
    max-width: 100% !important;
}

/* Google wraps translated runs in <font>; keep them inheriting our styles. */
font {
    font: inherit !important;
    color: inherit !important;
    background: transparent !important;
}


/* ======================================================================
 * 21. RESPONSIVE — TABLET AND MOBILE
 * ======================================================================
 * Phases 2 and 3 of the workflow in CLAUDE.md. The desktop layout above
 * is untouched; everything here lives inside a media query so it can only
 * ever apply below desktop widths.
 *
 * THREE BREAKPOINTS, each earning its place:
 *
 *   1024px — layout. The hero stops being two columns, the three-across
 *            grids drop to two, and pricing stacks. Matches the tablet
 *            mockup, which shows 2-up benefit and step cards and
 *            single-column pricing.
 *
 *    900px — navigation. The inline nav needs roughly 820px before it
 *            starts crowding the brand and the language pill, so this is
 *            where it collapses into the hamburger panel. Landscape
 *            tablets keep the inline nav the tablet mockup shows;
 *            portrait tablets and phones get the hamburger.
 *
 *    640px — mobile. Single column throughout, the mobile mockup's 20px
 *            gutter, full-width buttons, and the compact header with the
 *            language abbreviation.
 *
 * Sizing between those points is fluid: the type scale already uses
 * clamp(), the grids use auto-fit/minmax, and spacing uses clamp() so
 * intermediate widths are interpolated rather than snapped.
 *
 * Values were measured from the supplied mobile mockup at 360px:
 *   gutter 20px · section padding ~83px · benefit cards 66px tall with a
 *   12px gap · buttons full width at ~53px · H1 ~48px · H2 ~36px ·
 *   hero body ~18px · chart panel roughly 320 × 370 (portrait).
 * ====================================================================== */


/* ----------------------------------------------------------------------
 * 21.1 TABLET AND BELOW (< 1024px)
 * -------------------------------------------------------------------- */

@media (max-width: 1023.98px) {

    /* The hero becomes one column: copy first, chart beneath it. */
    .hero__inner {
        grid-template-columns: minmax(0, 1fr);
        gap: clamp(32px, 5vw, 48px);
        padding-block: 28px clamp(48px, 6vw, 72px);
    }

    /*
     * The chart panel is landscape on desktop and portrait on mobile;
     * between the two it simply fills the column at a squarer ratio.
     */
    #live-chart-container {
        aspect-ratio: 16 / 12;
    }

    .hero__chart-caption {
        text-align: left;
    }

    /* Three-across grids become two-across, as the tablet mockup shows. */
    .steps__grid {
        grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    }

    /*
     * Pricing stacks to a single column on tablet. auto-fit with a large
     * minimum does this without a hard column count, so a fourth plan
     * still behaves.
     */
    .pricing__grid {
        grid-template-columns: repeat(auto-fit, minmax(min(100%, 420px), 1fr));
    }

    .source-code__card {
        padding: 36px clamp(20px, 4vw, 40px);
    }

    /*
     * Live results keeps its side-by-side arrangement on tablet — the
     * tablet mockup shows the heading block and the button on one row.
     * It only stacks at mobile widths (21.3 below).
     */
    .live-results__inner {
        gap: 32px;
    }

    /*
     * Dialogs must never exceed the viewport on a short or narrow screen.
     * Applied from tablet down so a landscape tablet with little height
     * still scrolls the dialog rather than clipping it.
     */
    .purchase-dialog {
        width: min(640px, calc(100vw - 40px));
        max-height: calc(100dvh - 40px);
        overflow-y: auto;
    }
}


/* ----------------------------------------------------------------------
 * 21.2 NAVIGATION COLLAPSE (< 900px)
 * ----------------------------------------------------------------------
 * The hamburger appears and the inline links become a panel. The markup
 * is unchanged — the same <nav> is restyled, so there is no duplicate
 * navigation anywhere in the project.
 * -------------------------------------------------------------------- */

@media (max-width: 899.98px) {

    .nav-toggle {
        display: inline-flex;
    }

    /*
     * The source-code card's two columns stack.
     *
     * This used to happen below 1024px, but the tablet mockup shows the
     * card still as a row — copy on the left, the two buttons stacked on
     * the right — at roughly 920px. Measured with the row forced on, the
     * copy column is 452px at 920px and 436px at 900px, both comfortable;
     * it is only further down that the column gets cramped. So the state
     * change belongs at the same 900px boundary the navigation already
     * uses, not at 1024px.
     *
     * A breakpoint rather than wrapping: the buttons have to be full width
     * once they drop below the copy (the mobile mockup shows them that
     * way), and a wrapped flex item cannot grow only on the line it
     * wrapped onto.
     */
    .source-code__layout {
        flex-direction: column;
        gap: 32px;
    }

    .source-code__actions {
        width: 100%;
        min-width: 0;
    }

    .site-header__inner {
        justify-content: space-between;
        gap: 12px;
        min-height: 76px;
    }

    /*
     * The panel drops from under the header. It is constrained to the
     * viewport width and scrolls internally if the list is ever taller
     * than the screen, so it can never cause horizontal overflow.
     */
    .primary-nav {
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        z-index: 40;
        display: block;
        max-height: calc(100dvh - 100%);
        overflow-y: auto;
        padding: 8px clamp(16px, 5vw, 32px) 20px;
        background: var(--bg-zinc);
        border-bottom: 1px solid var(--border-subtle);
        box-shadow: 0 24px 48px -24px rgba(0, 0, 0, 0.9);

        /* Closed state. visibility keeps it out of the tab order. */
        opacity: 0;
        visibility: hidden;
        transform: translateY(-8px);
        transition: opacity var(--transition), transform var(--transition),
                    visibility var(--transition);
    }

    .primary-nav.is-open {
        opacity: 1;
        visibility: visible;
        transform: translateY(0);
    }

    .primary-nav__list {
        flex-direction: column;
        align-items: stretch;
        gap: 2px;
    }

    /* Comfortable touch targets, comfortably above the 44px guideline. */
    .primary-nav__link {
        display: block;
        padding: 15px 12px;
        border-radius: 12px;
        font-size: 1.0625rem;
        font-weight: 500;
    }

    .primary-nav__link:hover,
    .primary-nav__link:focus-visible {
        background: var(--surface);
    }

    /* The header must establish the panel's containing block. */
    .site-header {
        position: relative;
    }

    /* Stop the page scrolling behind the open panel. */
    body.nav-is-open {
        overflow: hidden;
    }
}


/* ----------------------------------------------------------------------
 * 21.3 MOBILE (< 640px)
 * -------------------------------------------------------------------- */

@media (max-width: 639.98px) {

    /* The mobile mockup's 20px gutter, for every container width. */
    :root {
        --gutter: 20px;

        /* Measured from the mobile mockup rather than scaled from desktop. */
        --fs-h1: clamp(2.5rem, 13vw, 3rem);           /* H1 ~48px  */
        --fs-h2: clamp(1.75rem, 10vw, 2.25rem);       /* H2 ~36px  */
        --fs-h2-sm: clamp(1.5rem, 8.5vw, 1.875rem);   /* ~30px     */
        --fs-h3: 1.25rem;
        --fs-hero-body: 1.125rem;                     /* 18px      */
        --fs-lead: 1rem;
    }

    /* Section rhythm: ~83px top / ~78px bottom in the mockup. */
    .section__inner {
        padding-block: clamp(56px, 21vw, 84px) clamp(52px, 20vw, 80px);
    }

    /* ---- Header ------------------------------------------------------
     * Brand on the left, language + hamburger grouped on the right.
     * The space between them is what space-between distributes; the two
     * controls stay together.
     * ---------------------------------------------------------------- */

    .site-header__inner {
        min-height: 72px;
        gap: 10px;
    }

    .brand {
        min-width: 0;              /* allows the wordmark to shrink */
        gap: 8px;                  /* the reference's phone gap */
    }

    .brand__name {
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    /* Closed header shows only the current language's abbreviation. */
    .lang-select__name {
        display: none;
    }

    .lang-select__code {
        display: inline;
    }

    .lang-select__toggle {
        gap: 4px;
        padding: 11px 12px;
        font-size: 0.9375rem;
    }

    /*
     * The dropdown is anchored to the right edge of the header and never
     * wider than the viewport minus its gutters, so it cannot overflow on
     * a narrow screen. The search field stays at the top, unchanged.
     */
    .lang-select__panel {
        width: min(280px, calc(100vw - 32px));
        right: 0;
    }

    /* ---- Hero -------------------------------------------------------- */

    .hero__inner {
        padding-block: 24px 40px;
        gap: 28px;
    }

    .hero__title {
        line-height: 1.02;
        /*
         * Releases the desktop nowrap so the wordmark can break at its
         * own space. At 360px the one-line title is 411px wide inside a
         * 328px column, which pushed "EA" past the edge; wrapping puts
         * it on a second line instead. `normal` only breaks when it has
         * to, so wider phones still render it on one line.
         */
        white-space: normal;
    }

    .hero__text {
        max-width: none;
        line-height: 1.7;
    }

    .hero__actions {
        margin-top: 30px;
        gap: 12px;
    }

    /* Portrait chart, matching the mobile mockup's proportions. */
    #live-chart-container {
        aspect-ratio: 320 / 370;
    }

    .hero__chart-panel {
        padding: 8px;
        border-radius: 20px;
    }

    /* ---- Buttons ----------------------------------------------------
     * Calls to action span the column on mobile, as the mockup shows.
     * ---------------------------------------------------------------- */

    .hero__actions .btn,
    .free-access__actions .btn,
    .source-code__actions .btn,
    .plan-card__cta {
        width: 100%;
    }

    .btn {
        padding: 15px 22px;
        white-space: normal;       /* long labels wrap instead of overflowing */
    }

    .btn--lg {
        padding: 16px 24px;
        font-size: 1rem;
    }

    /* ---- Single-column grids ---------------------------------------- */

    .benefits__grid,
    .steps__grid,
    .pricing__grid,
    .free-access__grid,
    .download__grid,
    .faq__columns {
        grid-template-columns: minmax(0, 1fr);
    }

    .benefits__grid {
        gap: 12px;
        margin-top: 36px;
    }

    .benefit-card {
        min-height: 66px;          /* measured from the mobile mockup */
        padding: 12px 16px;
        gap: 12px;
    }

    .benefit-card__label {
        font-size: 0.9375rem;
    }

    .steps__grid,
    .free-access__grid,
    .download__grid {
        gap: 14px;
        margin-top: 32px;
    }

    .step-card {
        padding: 24px 20px;
    }

    .step-card .icon-disc {
        width: 42px;
        height: 42px;
    }

    .step-card__title {
        margin: 24px 0 12px;
    }

    .step-card__text {
        font-size: 1rem;
    }

    /* Free-access step rows: compact enough to keep each label on one line. */
    .free-access__step {
        min-height: 60px;
        padding: 12px 14px;
        gap: 12px;
    }

    .free-access__step-label {
        font-size: 0.875rem;
    }

    .free-access__actions {
        margin-top: 28px;
        gap: 12px;
    }

    /* Download cards */
    .download-card {
        padding: 20px 18px;
    }

    .download-card__head {
        gap: 12px;
        margin-bottom: 16px;
    }

    .download-card__title {
        font-size: 1.1875rem;
    }

    .download-card__licence {
        padding: 12px 14px;
        margin-bottom: 14px;
        font-size: 0.8125rem;
    }

    .setup-note__title {
        font-size: 0.9375rem;
    }

    .setup-note__text,
    .setup-note__steps {
        font-size: 0.8125rem;
    }

    .download__licence-hint {
        margin-top: 22px;
        font-size: 0.8125rem;
    }

    /* ---- Live results ------------------------------------------------ */

    /* Mobile: the button drops below the heading block, as the mockup shows. */
    .live-results__inner {
        flex-direction: column;
        align-items: flex-start;
        padding-block: clamp(56px, 21vw, 84px);
        gap: 24px;
    }

    /* Pill on its own line, the two figures side by side beneath it. */
    .live-stats__inner {
        flex-direction: column;
        gap: 20px;
        padding-block: 24px;
    }

    .live-stats__figures {
        width: 100%;
        justify-content: space-around;
        gap: 16px;
    }

    .stat__label {
        font-size: 0.6875rem;
    }

    /* ---- Pricing ----------------------------------------------------- */

    .pricing__grid {
        gap: 16px;
        margin-top: 32px;
    }

    .plan-card {
        padding: 24px 20px;
    }

    .plan-card__price {
        font-size: 2.75rem;
    }

    /*
     * Card internals are tighter on mobile, matching the mockup's rhythm.
     * The timer row keeps its reserved space (CLAUDE.md §9.4) but at mobile
     * proportions, so hiding and showing it still never resizes the card.
     */
    .plan-card__caption {
        margin-top: 8px;
        font-size: 0.8125rem;
    }

    .plan-card__timer {
        min-height: 20px;
        margin-top: 10px;
    }

    .plan-card__divider {
        margin: 18px 0;
    }

    .plan-card__features,
    .plan-card__steps {
        gap: 11px;
    }

    .plan-card__features li,
    .plan-card__steps li {
        font-size: 0.875rem;
    }

    .plan-card__note {
        margin-bottom: 16px;
    }

    .plan-card__name {
        font-size: 1.1875rem;
    }

    /* ---- Source code -------------------------------------------------- */

    .source-code {
        margin-top: 40px;
    }

    .source-code__card {
        padding: 32px 20px 28px;
        border-radius: 20px;
    }

    .source-code__tag {
        left: 20px;
    }

    .feature-list--2col {
        grid-template-columns: minmax(0, 1fr);
        column-gap: 0;
    }

    .source-code__price-row {
        gap: 6px;
        margin-top: 18px;
    }

    .source-code__title {
        margin-bottom: 10px;
    }

    .source-code__text {
        margin-bottom: 16px;
        font-size: 0.9375rem;
    }

    .feature-list {
        gap: 11px;
    }

    .feature-list li {
        font-size: 0.9375rem;
    }

    /* ---- Download ----------------------------------------------------- */

    /*
     * The mockup keeps the preset banner as a row on mobile — icon at the
     * left, copy beside it — rather than stacking, so only the trailing
     * link moves below the text.
     */
    .preset-banner {
        flex-wrap: wrap;
        align-items: flex-start;
        gap: 12px;
        padding: 16px;
    }

    .preset-banner .icon-disc {
        width: 34px;
        height: 34px;
    }

    .preset-banner__copy {
        flex: 1 1 200px;
    }

    .preset-banner__title {
        font-size: 0.9375rem;
    }

    .preset-banner__text {
        font-size: 0.8125rem;
    }

    /*
     * The link sits on its own row, indented to line up under the copy
     * rather than under the icon. The basis has to leave room for that
     * indent: flex-basis: 100% plus a 46px margin is 46px wider than the
     * row, and the base rule's flex-shrink: 0 stops it shrinking back, so
     * it used to push 9-13px past the viewport at every mobile width — in
     * English as well as every translation.
     */
    .preset-banner__link {
        flex-basis: calc(100% - 46px);
        margin-left: 46px;         /* aligns under the copy, not the icon */
    }

    .setup-note {
        padding: 22px 18px;
    }

    /* The URL chip and its Copy button wrap rather than overflow. */
    .setup-note__url-row {
        display: flex;
        flex-wrap: wrap;
        gap: 8px;
        width: 100%;
        padding: 10px 12px;
    }

    .setup-note__url {
        word-break: break-all;
    }

    /* ---- FAQ ---------------------------------------------------------- */

    .faq__categories {
        gap: 8px;
        margin-top: 28px;
    }

    /* Two pills per row, as the mobile mockup shows. */
    .faq__category {
        flex: 1 1 calc(50% - 4px);
        padding: 11px 12px;
        font-size: 0.875rem;
    }

    .faq__columns {
        gap: 12px;
        margin-top: 24px;
    }

    .faq__column {
        gap: 12px;
    }

    .faq-item__trigger {
        padding: 18px 16px;
        font-size: 1rem;
        gap: 12px;
    }

    .faq-item__panel {
        padding: 0 16px 20px;
        font-size: 0.9375rem;
    }

    /* ---- Footer -------------------------------------------------------- */

    .site-footer__inner {
        padding-block: 44px;
    }

    #footer-caveat,
    .terms-notice,
    .site-footer__copyright {
        font-size: 0.8125rem;
    }

    /* ---- Announcement bar ---------------------------------------------- */

    /*
     * Narrow screens tighten the padding but keep it symmetric, and keep
     * it on the same custom property so the two sides cannot drift.
     */
    /*
     * The reference keeps the bar's padding at 10px / 40px on phones and
     * changes only the type: 14px drops to 12px below 640px, the same
     * breakpoint used here. Line-height stays at 1.375 (12 -> 16.5px), so
     * a three-line bar measures 70.5px exactly as the reference does.
     */
    .action-bar__link {
        font-size: var(--fs-xs);
    }

    /* ---- Live chat ------------------------------------------------------
     * Same 56px launcher, pulled closer to the corner so it sits clear of
     * the content. The hover label is suppressed on touch below.
     * ------------------------------------------------------------------ */

    .chat-widget {
        right: 16px;
        bottom: max(16px, env(safe-area-inset-bottom, 0px));
    }

    /* ---- Dialogs --------------------------------------------------------
     * Full-width within the viewport, scrollable if the content is taller
     * than the screen, and never wider than the screen.
     * ------------------------------------------------------------------ */

    .purchase-dialog {
        width: calc(100vw - 24px);
        max-height: calc(100dvh - 32px);
        overflow-y: auto;
        border-radius: 20px;
    }

    .purchase-dialog__head {
        padding: 22px 20px 18px;
    }

    .purchase-dialog__title {
        font-size: 1.1875rem;
    }

    .purchase-dialog__body {
        padding: 18px 20px 24px;
    }

    .purchase-row {
        padding: 14px 16px;
        gap: 12px;
    }

    .purchase-row__value--amount {
        font-size: 1.1875rem;
    }

    .wallet-row {
        padding: 14px 16px;
        gap: 12px;
    }

    .wallet-row__value {
        font-size: 0.8125rem;
    }
}


/* ----------------------------------------------------------------------
 * 21.4 VERY NARROW SCREENS (< 380px)
 * ----------------------------------------------------------------------
 * Not a device-specific hack: below roughly 380px the brand wordmark and
 * the two header controls genuinely compete for room. Only the header is
 * adjusted, and only enough to keep everything legible and tappable.
 * -------------------------------------------------------------------- */

@media (max-width: 379.98px) {

    :root {
        --gutter: 16px;
    }

    .brand__mark {
        width: 36px;
        height: 36px;
    }

    .lang-select__toggle {
        padding: 10px;
    }

    .nav-toggle {
        width: 40px;
        height: 40px;
    }
}


/* ----------------------------------------------------------------------
 * 21.5 TOUCH DEVICES
 * ----------------------------------------------------------------------
 * The live-chat label is a hover affordance. On touch there is no hover,
 * so it is suppressed rather than left half-triggered by a tap; the
 * launcher's aria-label still carries the same wording for assistive
 * technology, and keyboard focus still reveals it on hybrid devices.
 * -------------------------------------------------------------------- */

@media (hover: none) {

    .chat-widget:hover .chat-widget__label {
        opacity: 0;
    }

    .chat-widget:focus-visible .chat-widget__label {
        opacity: 1;
    }

    /* No lift on tap — it reads as a stuck state on touch. */
    .chat-widget:hover {
        transform: none;
    }
}


/* ======================================================================
 * 22. FAQ PAGE  (frequently-asked-questions.html)
 * ======================================================================
 * Desktop implementation, measured against
 * mockups/desktop/pages/01-faq-desktop.png (1920px wide) and
 * mockups/desktop/pages/02-faq-answers-not-found-desktop.png.
 *
 * Measurements taken from the mockup:
 *   content column      900px
 *   hero search field   720 x 65
 *   category bar        wraps, centred, ~1040px of usable width
 *   question card       900 x 77, 16px apart, 1px #222224 border
 *   hero H1 cap height  44px  ->  ~63px type
 *
 * Widths are max-widths on a centred column and the lists wrap on their
 * own, so the later mobile and tablet passes adapt this structure rather
 * than replacing it (§21). Nothing here touches the homepage: every
 * selector below is new and prefixed faq-page / faq-search / faq-category
 * / faq-question / faq-group / faq-no-results / faq-support / faq-sticky.
 * ====================================================================== */

.faq-page__hero,
.faq-sticky-bar,
.faq-page__content {
    --faq-content-width: 900px;
    --faq-search-width: 720px;
    --faq-bar-width: 1040px;
}


/* ----------------------------------------------------------------------
 * 22.1 HERO
 * -------------------------------------------------------------------- */

.faq-page__hero {
    position: relative;
    padding-block: 76px 64px;
    background-color: var(--bg-hero);
    overflow: hidden;   /* contains the glow; never a scroll container */
}

/*
 * The same warm gold wash the homepage hero uses, so the two pages read
 * as one site. Purely decorative and behind the content.
 */
.faq-page__hero::before {
    content: "";
    position: absolute;
    inset: -220px 0 auto;
    height: 620px;
    background:
        radial-gradient(60% 100% at 22% 0%, rgba(221, 185, 84, 0.16) 0%, transparent 70%),
        radial-gradient(50% 100% at 78% 6%, rgba(221, 185, 84, 0.07) 0%, transparent 72%);
    pointer-events: none;
}

.faq-page__hero-inner {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
}

.faq-page__title {
    margin-top: 26px;
    font-size: var(--fs-h2);   /* ~63px at 1920 */
    line-height: var(--lh-h2);
    letter-spacing: -0.02em;
    background: var(--grad-gold-text);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}

.faq-page__lead {
    margin-top: 20px;
    /* Wide enough to keep the sentence on one line, as the mockup shows. */
    max-width: 820px;
    color: var(--text-muted);
    font-size: var(--fs-subhead);
    line-height: var(--lh-body);
}


/* ----------------------------------------------------------------------
 * 22.2 SEARCH
 * ----------------------------------------------------------------------
 * Shared by the hero field and the compact field in the sticky bar; the
 * compact one only overrides size.
 * -------------------------------------------------------------------- */

.faq-search {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    max-width: var(--faq-search-width);
    margin-top: 45px;
    padding: 0 18px;
    min-height: 66px;
    background: var(--surface);
    border: 1px solid var(--border-gold);
    border-radius: var(--radius-md);
    transition: border-color var(--transition), box-shadow var(--transition);
}

.faq-search:focus-within {
    border-color: var(--gold-400);
    box-shadow: 0 0 0 3px rgba(221, 185, 84, 0.16);
}

/* --- Search border shine ----------------------------------------------
 * A bright highlight travels ONCE around the search bar's gold edge, then
 * the border goes back to normal. Light catching polished metal, not a
 * glow: at any moment only a short arc of the border is lit.
 *
 * HOW IT IS BUILT
 * A pseudo-element covers the control and is painted with a conic
 * gradient whose bright stop sits at one angle. A two-layer mask —
 * everything, minus the content box — leaves only a 1px ring visible, and
 * because the ring is drawn with `border-radius: inherit` it follows the
 * existing rounded corners exactly. Rotating the gradient's start angle
 * then walks the highlight around the perimeter.
 *
 * The angle is a registered custom property (@property below): a bare
 * custom property cannot be animated, only interpolated as a string, so
 * registering it as an <angle> is what makes the trip smooth rather than
 * a jump.
 *
 * The control's own border stays underneath throughout — this layer only
 * adds the moving highlight. Nothing here changes the control's size,
 * radius, position or hit area (`pointer-events: none`).
 *
 * TIMING lives in faq-search.js. It writes --faq-shimmer-duration from
 * `shimmerDuration`, so the CSS animation and the JavaScript that removes
 * the class read one value, and the interval between shines is scheduled
 * there too.
 * ------------------------------------------------------------------- */

@property --faq-shine-angle {
    syntax: "<angle>";
    inherits: false;
    initial-value: 0deg;
}

.faq-search {
    position: relative;
}

.faq-search::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    /* The ring's thickness — matches the control's own 1px border. */
    padding: 1px;
    pointer-events: none;
    opacity: 0;

    /*
     * Normal edge → subtle gold → bright highlight → subtle gold → normal
     * edge, all inside a narrow arc so the lit part is obviously moving.
     */
    background: conic-gradient(
        from var(--faq-shine-angle),
        rgba(221, 185, 84, 0) 0deg,
        rgba(221, 185, 84, 0) 24deg,
        rgba(221, 185, 84, 0.55) 44deg,
        rgba(241, 217, 152, 0.95) 56deg,
        #FFF6DD 62deg,
        rgba(241, 217, 152, 0.95) 68deg,
        rgba(221, 185, 84, 0.55) 80deg,
        rgba(221, 185, 84, 0) 100deg,
        rgba(221, 185, 84, 0) 360deg);

    /* Keep only the ring: the whole box minus its content box. */
    -webkit-mask:
        linear-gradient(#000 0 0) content-box,
        linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask:
        linear-gradient(#000 0 0) content-box,
        linear-gradient(#000 0 0);
    mask-composite: exclude;
}

.faq-search.is-shimmering::after {
    animation: faq-search-shine var(--faq-shimmer-duration, 1400ms) linear 1;
}

@keyframes faq-search-shine {
    0%   { opacity: 0; --faq-shine-angle: 0deg; }
    12%  { opacity: 1; }
    88%  { opacity: 1; }
    100% { opacity: 0; --faq-shine-angle: 360deg; }
}

/*
 * Reduced motion: no travelling highlight at all. The control's own gold
 * border is untouched, and faq-search.js separately keeps the placeholder
 * static, so the whole control is still.
 */
@media (prefers-reduced-motion: reduce) {
    .faq-search.is-shimmering::after {
        animation: none;
        opacity: 0;
    }
}}

.faq-search__icon {
    flex-shrink: 0;
    color: var(--text-dim);
}

.faq-search__input {
    flex: 1;
    min-width: 0;           /* lets the field shrink instead of overflowing */
    border: 0;
    background: transparent;
    color: var(--text);
    font-family: var(--font-body);
    font-size: var(--fs-body);
}

.faq-search__input:focus {
    outline: none;          /* the ring is drawn on the wrapper instead */
}

.faq-search__input::placeholder {
    color: var(--text-dim);
}

/* Chrome draws its own clear affordance on type="search"; ours is better. */
.faq-search__input::-webkit-search-cancel-button {
    -webkit-appearance: none;
    appearance: none;
}

.faq-search__hint {
    flex-shrink: 0;
    min-width: 26px;
    padding: 3px 0;
    border: 1px solid var(--rule);
    border-radius: 7px;
    background: var(--surface-2);
    color: var(--text-dim);
    font-family: var(--font-body);
    font-size: var(--fs-xs);
    text-align: center;
}

.faq-search__clear {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 30px;
    height: 30px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: var(--text-dim);
    cursor: pointer;
    transition: color var(--transition), background var(--transition);
}

.faq-search__clear:hover,
.faq-search__clear:focus-visible {
    background: var(--surface-3);
    color: var(--text);
}


/* ----------------------------------------------------------------------
 * 22.3 POPULAR QUESTION CHIPS
 * -------------------------------------------------------------------- */

.faq-popular {
    /* Breathing room under the search field before the "Popular:" label. */
    margin-top: 40px;
    width: 100%;
    max-width: var(--faq-bar-width);
}

.faq-popular__label {
    color: var(--text-dim);
    font-size: var(--fs-xs);
    font-weight: 900;
    letter-spacing: var(--ls-eyebrow);
}

.faq-popular__list {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 10px;
    /*
     * Kept well under the gap above the label, so "Popular:" continues to
     * read as belonging to the chips beneath it rather than floating
     * between the search field and the list.
     */
    margin-top: 14px;
}

.faq-popular__chip {
    padding: 9px 16px;
    border: 1px solid var(--rule);
    border-radius: var(--radius-pill);
    background: var(--surface);
    color: var(--text-muted);
    font-family: var(--font-body);
    font-size: var(--fs-xs);
    text-align: left;
    cursor: pointer;
    transition: color var(--transition), border-color var(--transition),
                background var(--transition);
}

.faq-popular__chip:hover,
.faq-popular__chip:focus-visible {
    border-color: var(--border-gold-solid);
    background: var(--surface-3);
    color: var(--text);
}


/* ----------------------------------------------------------------------
 * 22.4 STICKY CATEGORY BAR  (§13)
 * ----------------------------------------------------------------------
 * Sticks to the top of the viewport as the list scrolls. The site header
 * is static rather than fixed, so there is nothing to offset against and
 * no second navigation is introduced — these are filters, not links.
 * -------------------------------------------------------------------- */

.faq-sticky-bar {
    position: sticky;
    top: 0;
    z-index: 30;
    padding-block: 18px;
    background: rgba(9, 9, 11, 0.92);
    backdrop-filter: blur(12px);
    border-block: 1px solid transparent;
    border-bottom-color: var(--rule);
    transition: border-color var(--transition);
}

/*
 * .container adds the page gutter as padding, so the max-width has to
 * include it for the CONTENT box to come out at --faq-bar-width — the
 * same calc() the site's other container modifiers use.
 */
.faq-sticky-bar__inner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 10px;
    max-width: calc(var(--faq-bar-width) + var(--gutter) * 2);
}

.faq-category-navigation {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 10px;
}

.faq-category-button {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 14px 16px;   /* 53px tall, measured from the mockup */
    border: 1px solid var(--rule);
    border-radius: var(--radius-pill);
    background: var(--surface-2);
    color: var(--text-dim);
    font-size: var(--fs-xs);
    font-weight: 700;
    white-space: nowrap;
    cursor: pointer;
    transition: color var(--transition), background var(--transition),
                border-color var(--transition);
}

/* Established hover: inactive pills go white (§6). */
.faq-category-button:hover,
.faq-category-button:focus-visible {
    background: var(--surface-3);
    color: var(--text);
}

/* Established active appearance: the site's gold fill on near-black text. */
.faq-category-button.is-active {
    background: var(--gold-400);
    border-color: var(--gold-400);
    color: var(--on-gold);
}

.faq-category-button__count {
    padding: 1px 7px;
    border-radius: var(--radius-pill);
    background: rgba(255, 255, 255, 0.08);
    color: inherit;
    font-size: var(--fs-2xs);
    font-weight: 700;
}

.faq-category-button.is-active .faq-category-button__count {
    background: rgba(9, 9, 11, 0.18);
}


/* ----------------------------------------------------------------------
 * 22.5 COMPACT SEARCH IN THE STICKY BAR  (§14)
 * ----------------------------------------------------------------------
 * The button appears at the end of the pills once the hero search has
 * scrolled out of view; the field expands underneath the bar in place.
 * Nothing scrolls the page, so the reader never loses their position.
 * -------------------------------------------------------------------- */

.faq-sticky-search-button {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 10px 16px;
    border: 1px solid var(--border-gold);
    border-radius: var(--radius-pill);
    background: var(--surface);
    color: var(--gold-300);
    font-size: var(--fs-xs);
    font-weight: 700;
    cursor: pointer;
    transition: color var(--transition), background var(--transition),
                border-color var(--transition);
}

.faq-sticky-search-button:hover,
.faq-sticky-search-button:focus-visible {
    border-color: var(--gold-400);
    background: var(--surface-3);
    color: var(--text);
}

/*
 * The panel is an overlay hanging off the sticky bar rather than an extra
 * row inside it. If it took part in flow, opening it would grow the bar by
 * its own height and push the whole list down under the reader — exactly
 * the layout jump §13 rules out, and a scroll shift §14 rules out. As an
 * absolutely positioned child of the (positioned) sticky bar it changes
 * the document's height by nothing at all.
 */
.faq-sticky-search-panel {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    padding: 14px 0 16px;
    background: rgba(9, 9, 11, 0.96);
    backdrop-filter: blur(12px);
    border-bottom: 1px solid var(--rule);
}

.faq-sticky-search-panel__inner {
    display: flex;
    justify-content: center;
    max-width: calc(var(--faq-bar-width) + var(--gutter) * 2);
}

.faq-search--compact {
    margin-top: 0;
    min-height: 52px;
    max-width: var(--faq-content-width);
}


/* ----------------------------------------------------------------------
 * 22.6 CONTENT COLUMN AND TOOLBAR
 * -------------------------------------------------------------------- */

.faq-page__content {
    padding-block: 18px 96px;
    background: var(--bg-zinc);
}

/* 900px of content, measured from the mockup, plus the page gutter. */
.faq-page__content-inner {
    max-width: calc(var(--faq-content-width) + var(--gutter) * 2);
}

.faq-page__toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    margin-bottom: 27px;
}

.faq-page__count {
    color: var(--text-dim);
    font-size: var(--fs-sm);
}

.faq-page__expand-all {
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--gold-300);
    font-size: var(--fs-xs);
    font-weight: 700;
    cursor: pointer;
    transition: color var(--transition);
}

.faq-page__expand-all:hover,
.faq-page__expand-all:focus-visible {
    color: var(--text);
}


/* ----------------------------------------------------------------------
 * 22.7 CATEGORY GROUPS AND QUESTIONS
 * -------------------------------------------------------------------- */

.faq-group + .faq-group {
    margin-top: 54px;
}

.faq-group__heading {
    display: flex;
    align-items: center;
    gap: 14px;
    margin-bottom: 30px;
    font-size: var(--fs-h3);
    letter-spacing: -0.01em;
    line-height: var(--lh-h3);
}

.faq-group__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 38px;
    height: 38px;
    border: 1px solid var(--border-gold);
    border-radius: 50%;
    background: rgba(221, 185, 84, 0.08);
    color: var(--gold-400);
}

.faq-group__list {
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.faq-question {
    border: 1px solid var(--rule);
    border-radius: 14px;
    background: var(--bg-zinc);
    transition: border-color var(--transition), background var(--transition);
}

.faq-question:hover {
    border-color: var(--border-gold);
}

.faq-question.is-open {
    border-color: var(--border-gold);
    background: var(--surface);
}

/*
 * The heading is a row of TWO sibling controls: the accordion trigger,
 * which takes all the space, and the copy-link button beside it. The copy
 * button is padded away from the trigger's own right padding so the two
 * hit areas do not touch.
 */
.faq-question__heading {
    display: flex;
    align-items: center;
    margin: 0;
    padding-inline-end: 8px;
    font-size: inherit;
    font-weight: inherit;
    line-height: inherit;
}

.faq-question__trigger {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
    width: 100%;
    padding: 26px;   /* 77px tall collapsed, measured from the mockup */
    border: 0;
    border-radius: 14px;
    background: transparent;
    color: var(--text);
    font-family: var(--font-body);
    font-size: var(--fs-body);
    font-weight: 900;
    line-height: var(--lh-tight);
    text-align: left;
    cursor: pointer;
}

.faq-question__text {
    min-width: 0;   /* long translated strings wrap instead of widening */
    overflow-wrap: anywhere;
}

.faq-question__trigger .faq-icon {
    flex-shrink: 0;
    color: var(--text-dim);
    transition: transform var(--transition), color var(--transition);
}

.faq-question__trigger:hover .faq-icon {
    color: var(--text);
}

.faq-question.is-open .faq-question__trigger .faq-icon {
    transform: rotate(180deg);
    color: var(--gold-400);
}

.faq-answer {
    padding: 0 26px 24px;
}

.faq-answer__text {
    max-width: 78ch;
    color: var(--text-muted);
    font-size: var(--fs-sm);
    line-height: var(--lh-body);
    overflow-wrap: anywhere;
}


/* ----------------------------------------------------------------------
 * 22.8 NO RESULTS  (§10)
 * -------------------------------------------------------------------- */

.faq-no-results {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    padding: 60px 32px;
    border: 1px solid var(--rule);
    border-radius: var(--radius-lg);
    background: var(--surface);
}

.faq-no-results__icon {
    color: var(--text-dim);
}

.faq-no-results__title {
    margin-top: 18px;
    font-size: var(--fs-h3);
    line-height: var(--lh-h3);
}

.faq-no-results__text {
    margin-top: 12px;
    max-width: 46ch;
    color: var(--text-muted);
    font-size: var(--fs-sm);
    line-height: 1.65;
}

.faq-no-results__text strong {
    color: var(--text);
}

.faq-no-results__actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 12px;
    margin-top: 26px;
}


/* ----------------------------------------------------------------------
 * 22.9 STILL HAVE A QUESTION  (§16)  AND BACK TO HOMEPAGE  (§17)
 * -------------------------------------------------------------------- */

.faq-support {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    margin-top: 56px;
    padding: 48px 32px 40px;
    border: 1px solid var(--rule);
    border-radius: var(--radius-lg);
    background: var(--surface);
}

.faq-support__icon {
    color: var(--gold-400);
}

.faq-support__title {
    margin-top: 18px;
    font-size: var(--fs-h3);
    line-height: var(--lh-h3);
}

.faq-support__text {
    margin-top: 12px;
    max-width: 46ch;
    color: var(--text-muted);
    font-size: var(--fs-sm);
    line-height: 1.65;
}

.faq-support__action {
    margin-top: 24px;
}

.faq-support__version {
    margin-top: 20px;
    color: var(--text-faint);
    font-size: var(--fs-xs);
}

.faq-page__back {
    display: flex;
    justify-content: center;
    margin-top: 48px;
}


/* ======================================================================
 * 23. FAQ PAGE — MOBILE
 * ======================================================================
 * The desktop layout above is approved and unchanged. Everything in this
 * section applies only below the mobile breakpoint.
 *
 * THE PROBLEM THIS SOLVES
 * The ten category chips sat in a centred, wrapping flex container. At
 * 390px they wrapped onto eight rows and the whole eight-row stack was
 * what got pinned: 507px of sticky chrome, 60% of the viewport, leaving
 * about 280px to read in. Measured, not estimated.
 *
 * THE FIX
 * One row that scrolls horizontally, left-aligned, with the search moved
 * out of the scrolling container so it is always reachable.
 * ====================================================================== */

/*
 * RAIL MECHANICS.
 * The chips wrap badly on anything narrower than a desktop window, so
 * below this query they become one horizontally scrolling row instead.
 *
 * WHY 1065.98px, and how to re-derive it if the categories change.
 * The bar's content box caps at --faq-bar-width (1040px), but until the
 * viewport is wide enough it is `viewport - --gutter * 2` instead. The
 * ten chips need a 1002px content box to make the two rows the desktop
 * design was approved with, and 1002 + 32 * 2 = 1066px of viewport. So:
 *
 *   >= 1066px  two-row bar   199px  <- approved desktop presentation
 *   1024-1065  THREE-row bar 259px  <- more chrome than either neighbour
 *   <= 1023px  scrolling rail 62px
 *
 * That middle band is the fault this query closes. It is not merely
 * "different from desktop": it is a non-monotonic step that peaks at
 * 34% of the viewport height on a 1024 x 768 tablet in landscape, worse
 * than both the tablet width below it and the desktop width above it.
 * Extending the rail to 1065.98px makes the progression monotonic and
 * leaves every width from 1066px up exactly as approved.
 *
 * A landscape phone (844 x 390) is wide but only 390px TALL, where even
 * two rows is most of the screen, so short viewports get the rail
 * regardless of their width.
 */
@media (max-width: 1065.98px), (max-height: 540px) {

    .faq-sticky-bar {
        top: var(--sticky-offset);
        padding-block: 8px;
        /*
         * The blur is dropped on small screens for a reason beyond
         * performance: `backdrop-filter` makes an element a containing
         * block for its fixed-position descendants, so the full-screen
         * search sheet inside this bar would size itself against the BAR
         * (60px tall) instead of the viewport. A solid background keeps
         * the sheet full-screen.
         */
        backdrop-filter: none;
        background: var(--bg-zinc);
    }

    .faq-sticky-bar__inner {
        flex-wrap: nowrap;
        justify-content: flex-start;
        gap: 8px;
        /*
         * The rail handles its own inline padding so the chips can scroll
         * under the edges; the container's padding would clip them.
         */
        padding-inline: 0;
    }

    .faq-category-navigation {
        flex: 1 1 auto;
        min-width: 0;
        flex-wrap: nowrap;
        justify-content: flex-start;
        gap: 8px;
        overflow-x: auto;
        overflow-y: hidden;
        /* Momentum scrolling on iOS. */
        -webkit-overflow-scrolling: touch;
        scroll-snap-type: x proximity;
        scrollbar-width: none;
        /*
         * The first chip lines up with the content below, and the last one
         * can scroll clear of the pinned search button.
         */
        padding-inline: var(--gutter) 56px;
        /*
         * Room for the focus ring: `overflow-x: auto` clips it otherwise,
         * which is the classic way a scroll rail becomes unusable by
         * keyboard. The negative margin keeps the visual position.
         */
        padding-block: 6px;
        margin-block: -6px;
        /*
         * The fade tells the visitor there is more off-screen. Without an
         * affordance, horizontal scroll simply is not discovered.
         */
        -webkit-mask-image: linear-gradient(to right,
            transparent 0, #000 var(--gutter), #000 calc(100% - 40px), transparent 100%);
        mask-image: linear-gradient(to right,
            transparent 0, #000 var(--gutter), #000 calc(100% - 40px), transparent 100%);
    }

    .faq-category-navigation::-webkit-scrollbar {
        display: none;
    }

    /* Once scrolled, the left edge fades too — the class is set from JS. */
    .faq-category-navigation.is-scrolled {
        -webkit-mask-image: linear-gradient(to right,
            transparent 0, #000 24px, #000 calc(100% - 40px), transparent 100%);
        mask-image: linear-gradient(to right,
            transparent 0, #000 24px, #000 calc(100% - 40px), transparent 100%);
    }

    .faq-category-button {
        flex: 0 0 auto;
        scroll-snap-align: start;
        /* Compact chips, but never below the 44px touch minimum. */
        min-height: 44px;
        padding: 10px 14px;
        gap: 6px;
        white-space: nowrap;
    }

    .faq-category-button__count {
        padding: 1px 5px;
    }

    /* ---- Search: pinned outside the scrolling rail ---------------------
     * Inside the rail it would scroll away with the chips. As an icon
     * button at the end of the row it is always one tap away.
     * ------------------------------------------------------------------ */
    .faq-sticky-search-button {
        flex: 0 0 auto;
        width: 44px;
        min-height: 44px;
        margin-inline-end: var(--gutter);
        padding: 0;
        justify-content: center;
        /* The word "Search" is hidden; the icon carries it. */
        font-size: 0;
    }

    .faq-sticky-search-button svg {
        width: 18px;
        height: 18px;
    }

    /* ---- Compact search row ---------------------------------------------
     * A row that expands directly beneath the sticky navigation, NOT a
     * full-screen sheet.
     *
     * The sheet was tried and removed: it covered the results with an
     * opaque panel, so a visitor typing a query could not see what they had
     * matched until they closed the search again. Search is only useful
     * while its results are visible, so the panel now occupies one row and
     * the FAQ list stays on screen underneath it, live-filtering as the
     * visitor types.
     *
     * It keeps the desktop panel's own positioning (absolute, below the
     * bar) — the same visual language, just sized for a phone.
     * ------------------------------------------------------------------ */
    .faq-sticky-search-panel__inner {
        padding-block: var(--space-sm, 12px);
    }

    .faq-sticky-search-panel .faq-search--compact {
        max-width: none;
    }
}


@media (max-width: 767.98px) {

    /* ---- Vertical rhythm ------------------------------------------------
     * A small set of tokens rather than one-off margins, so the page reads
     * as one deliberate rhythm. The mockup's own vertical spacing is not
     * reproduced — see MOBILE.md for what was tightened and why.
     * ------------------------------------------------------------------ */
    .faq-page {
        --space-2xs: 6px;
        --space-xs: 10px;
        --space-sm: 16px;
        --space-md: 24px;
        --space-lg: 32px;
        --space-xl: 44px;
    }

    /* ---- Page rhythm ----------------------------------------------------
     * The mockup's top gap pushed the heading and the search field below
     * the fold on a 390 x 844 screen. Tightened so the eyebrow, the
     * heading and the search are all visible without scrolling.
     * ------------------------------------------------------------------ */
    .faq-page__hero-inner {
        padding-block: var(--space-md) var(--space-lg);
    }

    .faq-page__title {
        margin-bottom: var(--space-xs);
    }

    .faq-page__lead {
        margin-bottom: var(--space-md);
    }

    /*
     * A literal value, not var(--space-md): the token block in this same
     * media query is written against `.faq-page`, and no element carries
     * that class, so the token is undefined here and the margin was
     * collapsing to 0 — leaving a 1px gap under the search field.
     */
    .faq-popular {
        margin-top: 28px;
    }

    /* The mockup left a large gap here; a normal section rhythm is enough. */
    .faq-page__content-inner {
        padding-block: var(--space-lg) var(--space-xl);
    }

    .faq-group + .faq-group {
        margin-top: var(--space-lg);
    }

    .faq-page__back {
        margin-top: var(--space-lg);
    }

    /* ---- Question rows --------------------------------------------------
     * Tighter padding, and the copy control keeps its 44px target without
     * crowding the question text.
     * ------------------------------------------------------------------ */
    .faq-question__trigger {
        gap: 12px;
        padding: 16px 4px 16px 16px;
    }

    /*
     * Scoped to .faq-group, which only exists on the FAQ page. The same
     * copy control is rendered inside the homepage FAQ section, and that
     * section is not part of this pass — an unscoped rule here would
     * quietly restyle it.
     */
    .faq-group .faq-copy-link {
        margin-inline-start: 0;
    }
}

/*
 * Reduced motion: the rail and the sheet stop animating, but both remain
 * fully operable.
 */
@media (prefers-reduced-motion: reduce) {
    .faq-category-navigation {
        scroll-behavior: auto;
    }
}
