/* =============================================================================
   Toytastic → Qorx · design tokens
   THE single source of truth for every colour, radius and dimension.
   -----------------------------------------------------------------------------
   The design document promises that correcting the brand orange is "a one-line
   change". This file is what makes that true. Change --tt-orange here and it
   changes everywhere - but read the contrast note before you do.

   Every colour below is either contrast-verified against its documented use, or
   explicitly marked DECORATIVE. There is no third category. Ratios are WCAG 2.2
   relative luminance; thresholds are 4.5:1 normal text, 3:1 large text
   (>=24px, or >=18.66px bold) and non-text UI boundaries (SC 1.4.11).
   ============================================================================= */

:root {
  /* ---- brand -------------------------------------------------------------- */

  /* SAMPLED FROM THE REAL LOGO - this is no longer a working value.
     Source: assets/logo.png, 1121x272 RGBA. #F7B132 is 89.8% of all opaque
     pixels; the rest is antialiasing. The logo is a SINGLE-COLOUR wordmark in
     this golden amber - not the two-tone navy/amber the earlier mockups assumed.

     It is materially lighter than the #F5821F we had been assuming, and that
     cuts the wrong way: FILLS AND LARGE SHAPES ONLY, never text.
       white on this ......  1.86:1   (was 2.59:1 - it got worse, not better)
       this on white ......  1.86:1
       Spurs navy on this .  8.10:1   <- why every label on an amber fill is
                                        navy. Comfortable now, not marginal.
     The token keeps the name --tt-orange because the spec and brief reference it
     as the contract. The colour is an amber; the name is history. */
  --tt-orange:        #F7B132;

  /* ORANGE for TEXT and links on light surfaces (client call, 1 Aug: the earlier
     same-hue derivation read goldy-brown; this is a true orange, hue 26).
     Clears 4.5:1 on EVERY surface here:
       white 5.00:1 · surface 4.75:1 · peach 4.58:1 · peach-2 4.69:1
     If --tt-orange changes, re-derive this and re-run contrast-check.js. */
  --tt-orange-ink:    #B2550E;

  /* Amber fill, hover/pressed. Navy label on it = 6.91:1. Fills only. */
  --tt-orange-hover:  #E6A329;

  /* SPURS NAVY. Deliberate, and confirmed by the client - this is Tottenham
     Hotspur navy and it is meant to be. Text, header, hero, footer, and the
     LABEL COLOUR ON AMBER FILLS, where it scores 8.10:1. */
  --tt-navy:          #132257;
  --tt-navy-2:        #1E3168;   /* raised surfaces on navy */
  --tt-navy-3:        #25407F;   /* hero gradient end */

  /* ---- accents ------------------------------------------------------------ */

  /* ON NAVY ONLY. 9.83:1 on navy, 1.6:1 on white.
     NOTE, now the real brand colour is known: this sits 5deg from --tt-orange
     (44deg vs 38.7deg) and is doing much the same job. The brand amber itself
     reads at 8.10:1 on navy, so the yellow is close to redundant. Recommend
     consolidating to one warm accent - but that is a design call for Sean, not
     something to change silently, so both are kept for now. */
  --tt-yellow:        #FFC94A;

  /* In stock, and the gift-finder band. 5.33:1 on white as text, and 5.33:1 for
     white text on the band. Was #2FA36B (3.20:1), which failed both ways. */
  --tt-green:         #1E7A4C;

  /* Low stock / back-in-stock. 5.43:1 on white. Was #E08600 (2.77:1). */
  --tt-amber:         #9A5B00;

  /* ---- neutrals ----------------------------------------------------------- */

  --ink:              #1F2937;   /* 13.6:1 on white */
  --ink-2:            #374151;   /* 10.3:1 on white - secondary body */
  --muted:            #6B7280;   /* 4.77:1 on white. NB only 4.47:1 on --peach-2,
                                    so use --faint-ink on tinted surfaces. */
  --faint-ink:        #5B6472;   /* 5.98:1 on white, passes on every tint here.
                                    Use for ANY text that carries meaning. */
  --faint:            #9AA3B2;   /* 2.54:1 - DECORATIVE ONLY. Rules, icon
                                    strokes, chrome. Never text. */
  --pale:             #C3CEE8;   /* body text on navy - 9.56:1 */

  --surface:          #F7F9FD;
  --surface-2:        #F2F4F9;
  --peach:            #FFF3E6;   /* orange-tint surface, selected states */
  --peach-2:          #FFF6EE;   /* USP bar */

  --line:             #E6EAF3;   /* DECORATIVE dividers and card edges. 1.21:1,
                                    which is fine - a card edge is not a control. */
  --line-2:           #EDF0F6;   /* decorative */
  /* Warm rules on peach surfaces. Both are DECORATIVE - a hairline on a
     tinted band and a chip edge - so they carry no contrast obligation, but
     they were raw hex in components.css and every colour belongs here. */
  --line-peach:        #F0E0CE;
  --line-peach-strong: #FFD9B8;

  --line-control:     #7C879E;   /* Borders of INPUTS, CHECKBOXES, SELECTS and any
                                    boundary needed to operate a control. 3.61:1,
                                    meets SC 1.4.11. Was #C9D0DE at 1.55:1. */

  --danger:           #A32020;   /* 6.4:1 on white - validation only */
  --warn-ink:         #8A5A2B;   /* 5.49:1 on --peach-2 */

  /* ---- type --------------------------------------------------------------- */

  /* A system stack, not a web font: zero font bytes, so NFR-4's font budget is
     met trivially. The original mockups were rendered on Windows in Segoe UI,
     but near-all Toytastic traffic is mobile - iOS gets San Francisco, Android
     gets Roboto. This makes that intentional rather than accidental. */
  --font-body: system-ui, -apple-system, 'Segoe UI', Roboto,
               'Helvetica Neue', Arial, sans-serif;

  /* TYPE SCALE. Before this existed the CSS carried 28 distinct font sizes,
     every one of them chosen on its own - 13px and 13.5px and 14px all doing
     the same job in three different components. The ladder below is 14 rungs,
     and every one of those 28 sizes lands on a rung within 1px, so this is a
     consolidation rather than a re-sizing: nothing on the pages moves by more
     than a single pixel. See the TYPE SYSTEM block in components.css for the
     full before/after map.

     The ratio is a major second, ~1.125, rounded to values that already sit
     under real content. Measured step-to-step it runs 1.100 - 1.156, and the
     geometric mean across the whole ladder is 1.127. Rounding to real pixels
     rather than carrying 12.64px is what keeps the migration inside 1px; a
     pure geometric ladder would have moved six components by 1.4-1.8px.

       10    11    12.5   14    16    18    20
       23    26    29     32    37    41    47

     --fs-sm (14px) is the workhorse: this is dense retail chrome - cards,
     facets, delivery rows - not an article, so the body rung sits below the
     16px a text-first layout would use. --fs-md (16px) is the smallest size
     used for a control label, which is why buttons start there.

     There is no colour here and none belongs here: a size token that carried a
     colour would sidestep the contrast gate, which only reads hex values. */
  --fs-3xs:  10px;    /* legal/flag microtype - .gapflag, .pip            */
  --fs-2xs:  11px;    /* uppercase eyebrows - .brandline, .badge, .stars  */
  --fs-xs:   12.5px;  /* dense secondary - .util, .crumb, .subst, .srow small */
  --fs-sm:   14px;    /* BODY WORKHORSE - card titles, facets, nav, links */
  --fs-md:   16px;    /* control labels and standard buttons - .btn       */
  --fs-lg:   18px;    /* large buttons, panel headings, .pprice .was      */
  --fs-xl:   20px;    /* card price, qty glyphs, the sign-in code         */
  --fs-2xl:  23px;    /* section headings at <=768                        */
  --fs-3xl:  26px;    /* wordmark, hero at <=400                          */
  --fs-4xl:  29px;    /* section headings                                 */
  --fs-5xl:  32px;    /* page h1                                          */
  --fs-6xl:  37px;    /* PDP price, hero at <=1024                        */
  --fs-7xl:  41px;    /* the article masthead h1 (.arthero h1). Reserved
                         from the migration until 2 Sep 2026 so the
                         ladder's ratio held across the display end; the
                         blog review asked for a bigger article title, and
                         this is the step between the PDP price and the
                         homepage hero it was kept for. */
  --fs-8xl:  47px;    /* hero h1                                          */

  /* LEADING. Five rungs, named by how tight they are rather than by what they
     were first used on, because .price wants heading leading and .card h3
     wants body leading. --lh-body is 1.45, the value body already carried, so
     the default line height on the pages is unchanged. */
  --lh-flat:    1.1;   /* display type - hero h1 only                     */
  --lh-tight:   1.22;  /* headings, and baseline-aligned numeric rows     */
  --lh-snug:    1.35;  /* compact multi-line UI labels                    */
  --lh-body:    1.45;  /* default - matches the existing body value       */
  --lh-relaxed: 1.6;   /* long-form paragraphs and help text             */

  /* ---- radii -------------------------------------------------------------- */
  --r-card: 16px;  --r-pill: 28px;  --r-chip: 18px;  --r-sheet: 20px;
  --r-input: 10px;

  /* ---- interaction -------------------------------------------------------- */
  --focus-ring: 3px solid var(--tt-navy);   /* SC 2.4.7 - 15.58:1 on white */
  --focus-ring-light: 3px solid #fff;       /* for use on navy/green surfaces */
  --tap-min: 44px;

  /* ---- motion --------------------------------------------------------------
     Four durations, one hold, three curves, and nothing outside this scale.
     The reasoning is the same one that put the colours here: a duration decided
     once, in a place you can read, is a duration you can still account for six
     months later. Every transition in components.css resolves to these; there
     is no bare millisecond value left in that file.

     DURATIONS - choose by what the movement is FOR, not by how far it travels.

       --t-fast   hover, focus, selected state, colour. Anything a shopper
                  triggers dozens of times a session gets this or nothing at
                  all: repeated motion spends the same attention every time it
                  plays, so the answer for high-frequency interactions is
                  always "brief, or instant".
       --t-press  the press scale, and only the press scale. 150ms is fixed by
                  the interaction guidance the client cited, and it is its own
                  token so that folding it into --t-fast is a visible decision
                  rather than a tidy-up.
       --t-base   a state change that genuinely travels: the mobile filter
                  sheet, the free-delivery progress bar.
       --t-slow   the ceiling. The category tile's photo zoom is the only user.
                  If something wants longer than this, it wants to not move.

     Neither of the last two is a duration.

     --t-hold is how long the mega menu stays open after the pointer leaves it,
     so that a diagonal slip on the way down to the panel does not snap it shut
     mid-movement. It belongs to intent, not to animation, and it should never
     be used to slow something down.

     --t-stagger is the gap between groups in a staged entrance - the homepage
     hero is the only one, and the only place in this storefront where a
     keyframe sequence is the right tool. Groups go 0, 1x, 2x, 3x. It is a token
     so that the ONE staged entrance cannot quietly become two different
     rhythms, and it is emphatically not a licence to stagger anything a shopper
     triggers more than once.

     CURVES

       --ease-out       the default, and the right answer unless there is a
                        reason. Quick off the mark, settling gently: the shape
                        of something responding to you. Enter and exit both.
       --ease-in-out    eased at both ends, for something crossing a distance
                        under its own steam - the filter sheet is the one.
       --ease-emphasis  the spring-ish curve, for a one-shot moment meant to be
                        noticed. Nothing uses it yet. It is here so that the
                        first thing that needs it inherits a considered curve
                        instead of inventing one at the point of need.

     --press-scale is how far a control sinks under a press: 0.96 exactly.
     Below 0.95 reads as a flinch rather than a press. It is a token, not a
     literal, because the prefers-reduced-motion block in components.css sets
     it to 1 and stops every press on the site moving in one declaration. */
  --t-fast:    120ms;
  --t-press:   150ms;
  --t-base:    180ms;
  --t-slow:    320ms;
  --t-hold:    250ms;
  --t-stagger: 100ms;

  --ease-out:      cubic-bezier(0, 0, .2, 1);
  --ease-in-out:   cubic-bezier(.4, 0, .2, 1);
  --ease-emphasis: cubic-bezier(.2, 0, 0, 1);

  --press-scale: .96;

  /* ---- layout ------------------------------------------------------------- */
  --wrap: 1280px;
  --shadow-card: 0 2px 7px rgba(22, 38, 79, .10);
  --shadow-pop:  0 22px 40px rgba(22, 38, 79, .13);
  --shadow-sheet: 0 -8px 40px rgba(22, 38, 79, .22);
}

/* Dark mode is NOT launched. FR-59 asks only for dark-mode-*ready* tokens, and
   because every colour above is a token, a dark theme is a second block here
   rather than a refactor. Left commented so the omission reads as deliberate.

@media (prefers-color-scheme: dark) { :root { ... } }
*/
