/* ============================================================================
   GAMESWA — DESIGN TOKENS
   Session A scaffold · 2026-08-10
   ----------------------------------------------------------------------------
   THE ONLY PLACE COLOURS, TYPE AND MOTION ARE DEFINED. Page sessions consume
   the semantic tokens (--gw-surface, --gw-text, ...) and never hardcode a hex.

   Brand law:
     Ink #0A0A0A · Blue #1A47E8 · Lime #C8E000 · White #FFFFFF · Off-white #F6F6F2
     Lime is FILLS AND ACCENTS ONLY, never text on white (WCAG).
     Signal red is reserved EXCLUSIVELY for ON AIR bugs (a live camera).
     No new hues without Arpit's sign-off on the preview.

   Theming: dark is the default (matches the current site). Light is
   first-class, not an inversion. Resolution order:
     1. html.gw-dark / html.gw-light, mirrored as data-theme="dark|light"
        (explicit stored choice, set by the inline boot script)
     2. prefers-color-scheme          (first visit, no stored choice)
     3. :root                         (dark — also the no-JS default)
   ========================================================================== */

/* ── SELF-HOSTED TYPE ─────────────────────────────────────────────────────
   Latin subsets, woff2, display:swap. No Google Fonts request: the old
   external stylesheet was render-blocking on a 3G turf connection. */

@font-face {
  font-family: 'Barlow';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/barlow-400.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Barlow';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('../fonts/barlow-600.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Barlow Condensed';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../fonts/barlow-condensed-700.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Barlow Condensed';
  font-style: normal;
  font-weight: 900;
  font-display: swap;
  src: url('../fonts/barlow-condensed-900.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* Data / timestamp face. Already the site's established broadcast-data voice;
   the brief permits "Barlow or mono variant" here. */
@font-face {
  font-family: 'DM Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/dm-mono-400.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  /* ── CORE BRAND (never themed, never overridden) ──────────────────────── */
  --gw-ink:        #0A0A0A;
  --gw-blue:       #1A47E8;
  --gw-lime:       #C8E000;
  --gw-white:      #FFFFFF;
  --gw-offwhite:   #F6F6F2;

  /* Signal red — ON AIR bugs ONLY, meaning a camera is live RIGHT NOW. Not
     for errors, not for emphasis, not for status, not for anything else.

     Session F, 2026-08-11: this used to be spent on the LIVE STATUS chip,
     which claims "this capability is shipped", not "this picture is happening
     now". That is the wrong claim for broadcast red, and it left us nothing
     stronger to reach for when a real stream goes on the page. LIVE is now a
     lime fill; red belongs to .gw-chip--onair alone.

     If you are using this token and the thing is not a live camera, you are
     using the wrong token. */
  --gw-signal:     #E5342A;

  /* ── DERIVED BLUE (tints/shades of --gw-blue only) ────────────────────── */
  --gw-blue-ink:   #0E2A8C;   /* blue darkened — text-safe on light surfaces */
  --gw-blue-lift:  #4A70F0;   /* blue lightened — hover on dark */
  --gw-blue-wash:  rgba(26, 71, 232, 0.08);
  --gw-blue-veil:  rgba(26, 71, 232, 0.16);

  /* ── DERIVED LIME ─────────────────────────────────────────────────────── */
  --gw-lime-ink:   #6B7800;   /* lime darkened far enough to be text on white */
  --gw-lime-wash:  rgba(200, 224, 0, 0.12);

  /* ── INK-NEUTRAL RAMP (secondary text, dividers) ──────────────────────── */
  --gw-n-900: #0A0A0A;
  --gw-n-800: #161616;
  --gw-n-700: #232323;
  --gw-n-600: #3A3A3A;
  --gw-n-500: #5A5A5A;
  --gw-n-400: #808080;
  --gw-n-300: #A8A8A8;
  --gw-n-200: #D2D0CB;
  --gw-n-100: #E6E4DF;
  --gw-n-050: #F2F0EB;

  --gw-wa:    #25D366;  /* WhatsApp brand green — CTA chrome only */
  /* Type on the WhatsApp fill. Ink, in both themes, and this is a measured
     choice rather than a taste one: on #25D366, ink is 9.86:1 and white is
     1.98:1. White fails AA on our single most important CTA. Same reasoning
     as --gw-on-punct, which is ink on lime for exactly the same reason.
     If Arpit wants WhatsApp's own white-on-green lockup instead, this one
     line is the revert, and it is a documented AA failure. */
  --gw-on-wa: #0A0A0A;

  /* ── TYPE ─────────────────────────────────────────────────────────────── */
  --gw-font-display: 'Barlow Condensed', 'Arial Narrow', sans-serif;
  --gw-font-body:    'Barlow', system-ui, -apple-system, sans-serif;
  --gw-font-data:    'DM Mono', ui-monospace, 'SF Mono', monospace;

  /* Fluid display scale. Mobile-first: the min is the 390px value. */
  --gw-t-hero:  clamp(3.5rem, 11vw, 8.5rem);
  --gw-t-xxl:   clamp(2.5rem, 7vw,  5rem);
  --gw-t-xl:    clamp(2rem,   5vw,  3.5rem);
  --gw-t-lg:    clamp(1.5rem, 3.5vw, 2.25rem);
  --gw-t-md:    1.25rem;
  --gw-t-body:  1rem;
  --gw-t-sm:    0.875rem;
  --gw-t-xs:    0.75rem;
  --gw-t-data:  0.6875rem;   /* 11px — the timestamp/eyebrow size */

  --gw-track-display: -0.01em;
  --gw-track-data:     0.16em;
  --gw-leading-display: 0.93;
  --gw-leading-body:    1.7;

  /* ── SPACE (4px base) ─────────────────────────────────────────────────── */
  --gw-s-1:  0.25rem;
  --gw-s-2:  0.5rem;
  --gw-s-3:  0.75rem;
  --gw-s-4:  1rem;
  --gw-s-5:  1.5rem;
  --gw-s-6:  2rem;
  --gw-s-7:  3rem;
  --gw-s-8:  4rem;
  --gw-s-9:  6rem;

  --gw-section-y:  clamp(3.25rem, 8vw, 7rem);   /* vertical section rhythm */
  --gw-wrap:       1200px;
  --gw-gutter:     clamp(1.25rem, 5vw, 3.5rem);

  /* ── SHAPE ────────────────────────────────────────────────────────────── */
  --gw-r-xs: 2px;
  --gw-r-sm: 3px;      /* the site's established button radius */
  --gw-r-md: 6px;
  --gw-r-lg: 12px;

  /* ── MOTION ───────────────────────────────────────────────────────────── */
  --gw-ease:      cubic-bezier(.16, 1, .3, 1);
  --gw-dur-fast:  0.18s;
  --gw-dur-base:  0.32s;
  --gw-dur-slow:  0.85s;

  /* ── DEPTH ────────────────────────────────────────────────────────────── */
  --gw-z-base:    1;
  --gw-z-sticky:  50;
  --gw-z-nav:     100;
  --gw-z-overlay: 200;

  /* Height of the mobile sticky CTA bar. Pages add this to their bottom
     padding so the bar never covers the last line of content. */
  --gw-cta-bar-h: 64px;

  /* ── SEMANTIC · DARK (default, and the no-JS default) ─────────────────── */
  --gw-surface:      #0A0A0A;   /* page ground */
  --gw-surface-2:    #131313;   /* raised card */
  --gw-surface-3:    #1C1C1C;   /* hover / inset */
  --gw-text:         #FFFFFF;
  --gw-text-muted:   #A8A8A8;
  /* 5.0:1 on ink. The data voice is 11px, so it needs to clear AA for normal
     text, not the large-text allowance. Measured, not eyeballed. */
  --gw-text-faint:   #8A8A8A;
  --gw-rule:         rgba(255, 255, 255, 0.12);
  --gw-rule-strong:  rgba(255, 255, 255, 0.24);
  --gw-accent:       #1A47E8;   /* the working accent */
  --gw-accent-text:  #4A70F0;   /* accent as TYPE on this surface */
  --gw-on-accent:    #FFFFFF;   /* type on an accent fill */

  /* LIME, SPLIT IN TWO, and this split is the whole reason lime is safe:
       --gw-punct       lime as TYPE. Darkens in light theme, because lime
                        type on white fails WCAG and that is not negotiable.
       --gw-punct-fill  lime as a FILL. Stays the real brand lime in BOTH
                        themes, because a fill is not type.
     If you are colouring text, you want --gw-punct. If you are colouring a
     background, you want --gw-punct-fill and --gw-on-punct on top of it. */
  --gw-punct:        #C8E000;
  --gw-punct-fill:   #C8E000;
  --gw-on-punct:     #0A0A0A;   /* type on a lime fill — always ink, 13.3:1 */
  --gw-shadow:       0 4px 24px rgba(0, 0, 0, 0.5);
  --gw-scrim:        rgba(10, 10, 10, 0.72);
}

/* ── SEMANTIC · LIGHT ────────────────────────────────────────────────────
   Not an inversion. Off-white ground, ink type, blue as the working accent,
   lime strictly as a fill. --gw-punct darkens to --gw-lime-ink because lime
   type on white fails WCAG and that is not negotiable.

   SPECIFICITY, and do not "tidy" this: the dark defaults sit on :root, which
   is (0,1,0). Every override below must beat that, so they are written as
   `html.gw-light` (0,1,1) and `html:not(.gw-dark)` (0,1,1 — :not takes its
   argument's weight). Wrapping either in :where() drops them to zero and the
   page silently stays dark forever. That exact mistake was made and caught
   here on 2026-08-10. */
html.gw-light,
html[data-theme="light"] {
  --gw-surface:      #F6F6F2;
  --gw-surface-2:    #FFFFFF;
  --gw-surface-3:    #EDEBE4;
  --gw-text:         #0C0C0C;
  --gw-text-muted:   #4A4A4A;
  --gw-text-faint:   #5A5A5A;   /* 6.4:1 on off-white */
  --gw-rule:         rgba(10, 10, 10, 0.10);
  --gw-rule-strong:  rgba(10, 10, 10, 0.20);
  --gw-accent:       #1A47E8;
  --gw-accent-text:  #0E2A8C;
  --gw-on-accent:    #FFFFFF;
  --gw-punct:        #5E6900;   /* lime as TYPE, darkened for AA */
  --gw-punct-fill:   #C8E000;   /* lime as a FILL stays the real brand lime */
  --gw-on-punct:     #0A0A0A;
  --gw-shadow:       0 4px 24px rgba(10, 10, 10, 0.08);
  --gw-scrim:        rgba(246, 246, 242, 0.82);
}

/* First visit, no stored choice, OS says light. html.gw-dark always wins. */
@media (prefers-color-scheme: light) {
  html:not(.gw-dark):not([data-theme="dark"]) {
    --gw-surface:      #F6F6F2;
    --gw-surface-2:    #FFFFFF;
    --gw-surface-3:    #EDEBE4;
    --gw-text:         #0C0C0C;
    --gw-text-muted:   #4A4A4A;
    --gw-text-faint:   #5A5A5A;   /* 6.4:1 on off-white */
    --gw-rule:         rgba(10, 10, 10, 0.10);
    --gw-rule-strong:  rgba(10, 10, 10, 0.20);
    --gw-accent:       #1A47E8;
    --gw-accent-text:  #0E2A8C;
    --gw-on-accent:    #FFFFFF;
    --gw-punct:        #5E6900;   /* lime as TYPE, darkened for AA */
    --gw-punct-fill:   #C8E000;   /* lime as a FILL stays the real brand lime */
    --gw-on-punct:     #0A0A0A;
    --gw-shadow:       0 4px 24px rgba(10, 10, 10, 0.08);
    --gw-scrim:        rgba(246, 246, 242, 0.82);
  }
}

/* ── INVERTED BLOCK ──────────────────────────────────────────────────────
   A section that stays ink in BOTH themes (the closing CTA, broadcast
   panels). Flips the semantic layer locally instead of hardcoding hexes.

   Written as `html .gw-invert` (0,1,1) so it matches the weight of the light
   overrides above and wins on source order. IT MUST STAY BELOW THEM. A bare
   `.gw-invert` (0,1,0) loses to html.gw-light and the block comes out cream
   in light theme, which is the one thing it must never do. */
html .gw-invert {
  --gw-surface:      #0A0A0A;
  --gw-surface-2:    #131313;
  --gw-surface-3:    #1C1C1C;
  --gw-text:         #FFFFFF;
  --gw-text-muted:   #A8A8A8;
  --gw-text-faint:   #8A8A8A;
  --gw-rule:         rgba(255, 255, 255, 0.12);
  --gw-rule-strong:  rgba(255, 255, 255, 0.24);
  --gw-accent-text:  #4A70F0;
  --gw-punct:        #C8E000;
  --gw-punct-fill:   #C8E000;
  --gw-shadow:       0 4px 24px rgba(0, 0, 0, 0.5);
  background: var(--gw-surface);
  color: var(--gw-text);
}

/* ── MOTION OPT-OUT ──────────────────────────────────────────────────────
   Quality floor: every scroll animation and count-up becomes instant. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --gw-dur-fast: 0.01ms;
    --gw-dur-base: 0.01ms;
    --gw-dur-slow: 0.01ms;
  }
}
