/* =============================================================================
   Ravenspire Games - design tokens
   THE single source of truth for every colour, radius, duration and dimension.
   -----------------------------------------------------------------------------
   The storefront serves this file and components.css straight from ../mock;
   neither is ever copied or forked. Change a value here and it changes
   everywhere - but read the contrast note beside it first.

   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).

   THE PALETTE IS THE DEV SITE'S AND THE COMPANION APP'S. The shop is one
   brand with the app at game.ravenspiregames.co.uk, so the three colours the
   theme is built on are taken from there and not re-chosen:

     ground  #190128   the page background on the dev site and the app's
                       darkest surface
     purple  #431a5f   the brand purple: body text on light surfaces there,
                       raised surfaces here
     gold    #f9d020   the brand accent: buttons, the compass, the wordmark

   DARK-FIRST, because the brand is. Every contrast figure below is measured
   against the dark surfaces the page is actually made of.

   BUT NOT DARK-ONLY, and that is a correction. The dev site's own body is
   white; its bands are gold and lilac; only its header and its footer are
   dark. A shop that is ground-purple from the masthead to the legal line is
   more purple than the brand has ever been, so the light tokens below are
   no longer four exceptions - they carry four jobs:

     every packshot plate     --paper-2   the field a photograph sits on
     content and legal pages  --paper     prose reads as a document
     the play-free band       --paper     as the dev site has it
     the Discord band         --rs-lilac  as the dev site has it (bg-lp)

   plus the inputs, the order summary, the consent banner and the suggest
   panel they always carried. On every one of them the ink flips dark and
   the focus ring flips purple, and GOLD IS NOT A COLOUR THERE at all: it is
   1.3:1 to 1.5:1 on all three light surfaces, as text and as an edge.
   ============================================================================= */

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

  /* THE GROUND. The page itself. White text on it: 17.6:1. Gold on it: 13.6:1. */
  --rs-ground:        #FFFFFF;
  --rs-ground-2:      #F6F1FB;   /* a step up: header, footer, the filter rail  */

  /* BRAND PURPLE. Raised surfaces - cards, panels, the mega menu. White on it
     is 11.0:1, gold on it is 8.5:1, so anything that sits on a card is fine.
     It is NOT a text colour on the ground (1.6:1) - use --rs-purple-ink for
     that, or do not use purple as text at all. */
  --rs-purple:        #431A5F;
  --rs-purple-2:      #552678;   /* hover/pressed on a purple surface          */
  --rs-purple-3:      #6B3594;   /* the hero gradient's far end                */

  /* BRAND GOLD. Fills and large shapes; the primary button; the wordmark.
       purple on gold ......  7.2:1   <- why every label on a gold fill is purple
       ground on gold ......  13.6:1
       white on gold .......  1.6:1   NEVER. No white text on gold.
     As text it works only on dark surfaces, where it clears 8.5:1 even on a
     card. Links on the ground are gold; links on white are purple. */
  --rs-gold:          #F9D020;
  --rs-gold-hover:    #E8C01A;   /* gold fill, hover/pressed. Purple on it 6.4:1 */
  --rs-gold-ink:      #7A5A00;   /* gold as TEXT on white - 6.4:1. Nowhere else. */

  /* BRAND LILAC. The dev theme's bg-lp, verbatim: the ground of its Discord
     row, and the disc the "Awaiting image" placeholder is drawn on. It is a
     LIGHT surface, so everything on it is dark:
       purple on lilac .....  6.7:1   the copy, the headings and the links
       ground on lilac .....  9.6:1
       paper-ink-2 on lilac.  5.1:1   secondary copy
       gold on lilac .......  1.4:1   NEVER, as text or as an edge
       white/ink on lilac ..  1.8:1   NEVER
     It is 9.6:1 against the page, which is why a lilac band needs no rule
     above or below it to read as a band. */
  --rs-lilac:         #D3A3F4;

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

  /* In stock. 6.3:1 on the ground, 4.6:1 on purple - readable on a card. */
  --rs-green:         #6EDC8C;
  /* Low stock / on order. 9.2:1 on the ground. */
  --rs-amber:         #F4B860;
  /* Sold out, validation, the danger button. 5.7:1 on the ground. */
  --rs-red:           #FF7A7A;
  --rs-red-deep:      #A32020;   /* the danger FILL; white on it 6.4:1          */

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

  --ink:              #1B0B2A;   /* body text on dark surfaces - 16.3:1 on ground */
  --ink-2:            #4A3860;   /* secondary body - 12.1:1 on ground, 8.2:1 on purple */
  --muted:            #6B5C80;   /* captions, crumbs - 7.9:1 on ground, 5.2:1 on purple */
  --faint:            #B7A8C9;   /* 3.7:1 - DECORATIVE ONLY. Rules, strokes. Never text. */

  /* THE LIGHT SIDE. --paper is the sheet a content page is printed on, the
     order summary, the consent banner, the suggest panel and every input.
     --paper-2 is the tinted one, and its main job is the PACKSHOT PLATE
     behind every product photograph: sealed product is shot dark, busy and
     usually on white, and a light plate is the only field it reads on.
     Every figure below holds on both, because the two are 1.05:1 apart:
       paper-ink on paper .... 17.9:1   paper-ink on paper-2 .... 16.6:1
       paper-ink-2 on paper ..  8.8:1   paper-ink-2 on paper-2 ..  9.2:1
       paper-muted on paper ..  5.9:1   paper-muted on paper-2 ..  5.4:1
       purple on paper ....... 12.7:1   purple on paper-2 ....... 12.1:1 */
  --paper:            #FFFFFF;
  --paper-2:          #F5F0FA;   /* a tinted paper */
  --paper-ink:        #1B0B2A;   /* text on paper - 17.9:1 */
  --paper-ink-2:      #4A3860;   /* secondary text on paper - 8.8:1 */
  --paper-muted:      #6B5C80;   /* 5.9:1 on paper, the floor for meaning */

  /* Rules and edges. DECORATIVE; a card edge is not a control. */
  --line:             rgba(27, 11, 42, .11);
  --line-2:           rgba(27, 11, 42, .19);
  --line-paper:       #E3DBEC;
  /* Boundaries of INPUTS, CHECKBOXES, SELECTS and any boundary needed to
     operate a control: 3:1 against its surface (SC 1.4.11). */
  --line-control:     #7C6D92;   /* 3.3:1 on purple, 5.2:1 on ground */
  --line-control-paper: #7C6D92; /* 4.0:1 on paper */

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

  /* The dev site's two faces, self-hosted from mock/assets/fonts. Reem Kufi
     for display - the wordmark, headings, prices - and Figtree for
     everything else. Both have system fallbacks that share their metrics
     closely enough that a page does not reflow when they land. */
  --font-display: 'Reem Kufi', 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
  --font-body:    'Figtree', system-ui, -apple-system, 'Segoe UI', Roboto,
                  'Helvetica Neue', Arial, sans-serif;

  /* TYPE SCALE. A major-second ladder (~1.125) rounded to real pixels. Dense
     retail chrome - cards, facets, rows - so the body rung is 14px; 16px is
     the smallest size a control label uses, which is why buttons start there. */
  --fs-3xs:  10px;
  --fs-2xs:  11px;
  --fs-xs:   12.5px;
  --fs-sm:   14px;    /* BODY WORKHORSE */
  --fs-md:   16px;    /* control labels, standard buttons */
  --fs-lg:   18px;
  --fs-xl:   20px;    /* card price */
  --fs-2xl:  23px;
  --fs-3xl:  26px;
  --fs-4xl:  29px;    /* section headings */
  --fs-5xl:  32px;    /* page h1 */
  --fs-6xl:  37px;    /* PDP price */
  --fs-7xl:  41px;
  --fs-8xl:  47px;    /* hero h1 */

  --lh-flat:    1.1;
  --lh-tight:   1.22;
  --lh-snug:    1.35;
  --lh-body:    1.45;
  --lh-relaxed: 1.6;

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

  /* ---- interaction -------------------------------------------------------- */
  /* Gold on white is 1.6:1, so the ring is purple on a light page and
     gold on a dark one (the [data-theme="dark"] block below). */
  --focus-ring: 3px solid var(--rs-purple);
  --focus-ring-paper: 3px solid var(--rs-purple); /* on light surfaces */
  --tap-min: 44px;

  /* ---- motion --------------------------------------------------------------
     Four durations, one hold, three curves, and nothing outside this scale.
       --t-fast   hover, focus, colour - anything triggered dozens of times
       --t-press  the press scale, and only the press scale
       --t-base   a state change that genuinely travels (the filter sheet)
       --t-slow   the ceiling; the tile photo zoom is the only user
     --t-hold is how long the mega menu stays open after the pointer leaves.
     --press-scale is a token so the reduced-motion block can set it to 1. */
  --t-fast:    120ms;
  --t-press:   150ms;
  --t-base:    180ms;
  --t-slow:    320ms;
  --t-hold:    250ms;
  /* --t-open is how long the pointer must REST on a pillar before its panel
     appears. Hover intent was solved on the way out and never on the way in:
     the panel closed on a hold so a diagonal slip re-opened it, and opened
     instantly, so a cursor merely crossing the bar threw a full-width card
     over the top of the page - which the close hold then held there.

     NOT --t-hold, though the temptation is obvious. 250ms is tuned for a
     CLOSE, where it is invisible because the visitor has already left. As an
     open delay it is also paid moving sideways from one open pillar to its
     neighbour, by somebody who has plainly declared intent, and CSS cannot
     tell that cursor from one passing through. So the number is the only
     lever, and this one is tuned for the sideways case.

     IT SURVIVES prefers-reduced-motion ON PURPOSE. Nothing moves during an
     intent delay; it is a waiting period, not an animation. Zeroing it there
     would hand the original fault back to the visitors least able to chase a
     panel around the screen. */
  --t-open:    140ms;
  --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 10px rgba(27, 11, 42, .12);
  --shadow-pop:  0 22px 48px rgba(27, 11, 42, .20);
  --shadow-sheet: 0 -8px 40px rgba(27, 11, 42, .22);
  --glow-gold:   0 0 0 1px rgba(249, 208, 32, .35), 0 8px 28px rgba(249, 208, 32, .12);

  /* ---- the two roles a theme has to be able to move -----------------------

     --surface-raised is the CARD, and it is BRAND PURPLE IN BOTH THEMES.
     A tint of purple was the first attempt and it read as washed: on a white
     page every card, tile and panel went pale and the brand drained out of
     everything except the masthead. What the light theme changes is the
     PAGE, not the furniture on it - white ground, purple throughout, which
     is the same relationship the dark theme has, lit differently.
     Everything on a purple surface therefore carries the dark theme's ink
     whatever the page is doing, which components.css states once for the
     whole set. White on this purple is 11.0:1.
       muted on raised (light).  5.3:1     muted on raised (dark).  5.2:1

     --accent-ink is GOLD USED AS TEXT, and it is the one thing that cannot
     survive the flip unchanged. Gold on the dark ground is 13.6:1; gold on
     white is 1.6:1, which is not a contrast failure so much as invisible
     ink. --rs-gold-ink already existed in this file for exactly this and was
     unused. The gold FILL does not move: a gold button stays gold in both,
     because its label is purple and that is 7.2:1 on either page. */
  --surface-raised:   var(--rs-purple);
  /* Ink for anything sitting on a BRAND FILL - the purple buttons, the
     pressed heart. A fill is a dark surface wherever it lands, so this
     is the same colour in both themes and never flips. */
  --on-fill:          #F4EEFA;

  /* ---- CHROME: the parts that are dark in both themes ---------------------
     The masthead is brand purple whatever the page is doing, so it is a dark
     surface sitting on a light one and everything inside it needs the dark
     theme's values. These are those values, named, so components.css can
     redeclare the ROLES on .hdr in one rule instead of pinning thirty
     descendants - and so no colour is written as a literal down there. They
     do not flip; that is the whole point of them. */
  --chrome-ink:        #F4EEFA;
  --chrome-ink-2:      #D9CFE6;
  --chrome-muted:      #B3A4C7;
  --chrome-faint:      #7A6A90;
  --chrome-ground:     #190128;
  --chrome-ground-2:   #22073A;
  --chrome-control:    #9D8CB5;
  --accent-ink:       var(--rs-gold-ink);

  /* THE PRICE. Gold everywhere until now, which made it the loudest thing on
     a card and put it in the same voice as the buttons. It reads as brand
     purple on a light surface (12.7:1) and as white on a dark one (11.0:1 on
     a purple card, 17.6:1 on the ground).

     Note it follows the SURFACE, not the theme: a product card is brand
     purple in BOTH themes, so a light-theme card still needs the white one.
     The chrome scope in components.css restates it for exactly that reason,
     which is why this cannot simply be "purple when light". */
  --price-ink:        var(--rs-purple);
}

/* ---------------------------------------------------------------------------
   DARK. The palette every figure in this file was measured against, kept
   whole and reachable by choice rather than by default. Only the roles that
   a theme actually moves are listed - brand purple, brand gold, the accents
   and the paper family are the same colours in both, because they are the
   brand and not the lighting.
   --------------------------------------------------------------------------- */
:root[data-theme="dark"] {
  --rs-ground:        #190128;
  --rs-ground-2:      #22073A;
  --surface-raised:   var(--rs-purple);
  --accent-ink:       var(--rs-gold);
  --price-ink:        var(--chrome-ink);
  --ink:              #F4EEFA;
  --ink-2:            #D9CFE6;
  --muted:            #B3A4C7;
  --faint:            #7A6A90;
  --line:             rgba(255, 255, 255, .10);
  --line-2:           rgba(255, 255, 255, .16);
  --line-control:     #9D8CB5;
  --focus-ring:       3px solid var(--rs-gold);
  --shadow-card:      0 2px 10px rgba(0, 0, 0, .35);
  --shadow-pop:       0 22px 48px rgba(0, 0, 0, .55);
  --shadow-sheet:     0 -8px 40px rgba(0, 0, 0, .6);
}

/* Form controls and scrollbars are painted by the browser, so they have to be
   told which way round the page is or they flash the wrong one on first
   paint. LIGHT IS THE DEFAULT; dark is a choice the visitor makes and the
   inline script in base.html stamps before any CSS arrives. */
:root { color-scheme: light; }
:root[data-theme="dark"] { color-scheme: dark; }
