/* ============================================================================
   CRIT HIT — DESIGN TOKENS v2
   ----------------------------------------------------------------------------
   The brand is a two-tube neon sign: a cobalt-blue outer tube and an
   amber-orange inner tube. v1 of this file used amber alone on a neutral
   blue-grey ramp, which is why the art and the interface never agreed.

   Two rules govern everything here:

   1. THE GROUND IS VIOLET, NEVER NEUTRAL. Saturated colour on a grey ground
      reads as a paint swatch; on a violet-black ground it reads as emitted
      light. Every neutral below sits on hue ~258.

   2. EVERY NEON IS THREE VALUES, NOT ONE.
        core  - the near-white hot centre of the glass tube ("it is on")
        glass - the saturated body colour
        bloom - the low-alpha halo spilling onto nearby surface
      Using one flat colour is what makes CSS neon look like a fill instead of
      a light. Always compose from all three.

   Spec: docs/design-system.md
   ========================================================================= */

/* ---------------------------------------------------------------- fonts -- */

@font-face {
  font-family: "Inter";
  src: url("../aassets/fonts/Inter-latin-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Inter";
  src: url("../aassets/fonts/Inter-latin-700.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Press Start 2P";
  src: url("../aassets/fonts/PressStart2P-latin-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

:root {
  color-scheme: dark;

  /* ============================================================ ground ==
     Violet-black neutral ramp, hue ~258. Chroma rises as it lightens so
     the darks stay deep and the lights stay readable rather than muddy. */

  --void-1000: #06050c;  /* page ground, the deepest surface        */
  --void-950:  #0a0813;  /* alternate section ground                */
  --void-900:  #100c1c;  /* raised surface: cards, panels           */
  --void-850:  #171227;  /* hover surface                           */
  --void-800:  #1e1833;  /* sunken well, inputs, code               */
  --void-700:  #2a2246;  /* strong hairline                         */
  --void-600:  #3c3363;  /* border                                  */
  --void-500:  #574c85;  /* disabled ink                            */
  --void-400:  #8478b0;  /* muted ink                               */
  --void-300:  #b3aacd;  /* secondary ink                           */
  --void-200:  #d9d3e8;  /* body ink                                */
  --void-100:  #f4f1fb;  /* primary ink                             */

  /* ============================================================== neon ==
     Amber and cobalt come off the logo's two tubes; magenta and cyan off
     the play-games banner and level-up assets. */

  --amber-core:  #ffe2a8;
  --amber:       #ffa51f;
  --amber-deep:  #d97f06;
  --amber-bloom: rgba(255, 165, 31, 0.28);
  --amber-veil:  rgba(255, 165, 31, 0.12);

  --cobalt-core:  #c7d0ff;
  --cobalt:       #4361ff;
  --cobalt-deep:  #2540d6;
  --cobalt-bloom: rgba(67, 97, 255, 0.30);
  --cobalt-veil:  rgba(67, 97, 255, 0.13);

  --magenta-core:  #ffc2dd;
  --magenta:       #ff2e88;
  --magenta-deep:  #d1005f;
  --magenta-bloom: rgba(255, 46, 136, 0.28);
  --magenta-veil:  rgba(255, 46, 136, 0.12);

  --cyan-core:  #bdf3fb;
  --cyan:       #22d3ee;
  --cyan-deep:  #0a9cb5;
  --cyan-bloom: rgba(34, 211, 238, 0.24);
  --cyan-veil:  rgba(34, 211, 238, 0.11);

  /* ========================================================== semantic ==
     Status colours are deliberately NOT neon channels. Neon means brand
     and interaction; these mean outcome. Keeping them apart is what stops
     "success" and "primary action" reading as the same thing. */

  --ok:       #4ade80;
  --ok-veil:  rgba(74, 222, 128, 0.13);
  --warn:     #fbbf24;
  --warn-veil:rgba(251, 191, 36, 0.13);
  --danger:   #f43f5e;
  --danger-veil: rgba(244, 63, 94, 0.13);

  /* ======================================================== role aliases ==
     Usage law (brand-direction.md §1.3):
       amber   = you can act        cobalt  = structure and selection
       magenta = liveness           cyan    = metadata, never interactive  */

  --bg:            var(--void-1000);
  --bg-alt:        var(--void-950);
  --surface:       var(--void-900);
  --surface-hover: var(--void-850);
  --surface-sunk:  var(--void-800);

  --fg:            var(--void-100);
  --fg-body:       var(--void-200);
  --fg-muted:      var(--void-300);
  --fg-dim:        var(--void-400);
  --fg-disabled:   var(--void-500);

  --line:          var(--void-700);
  --line-strong:   var(--void-600);

  --action:        var(--amber);
  --action-core:   var(--amber-core);
  --action-ink:    #201200;          /* text on an amber fill            */
  --action-bloom:  var(--amber-bloom);

  --structure:     var(--cobalt);
  --live:          var(--magenta);
  --meta:          var(--cyan);

  --link:          var(--cobalt-core);
  --ring:          var(--cobalt);

  /* ========================================================= per-game ==
     Constrained set so a shelf of seven cards is a palette, not a rainbow.
     Each is >= 4.5:1 as text on --surface. */

  --game-go-get-em:           #ffa51f;
  --game-time-to-die:         #f43f5e;
  --game-world-expander:      #22d3ee;
  --game-gta-rogue-london:    #7c5cff;
  --game-rogue-tower-defense: #4ade80;
  --game-sky-shard-quest:     #38bdf8;
  --game-star-raiders:        #ff2e88;

  /* ========================================================== cabinet ==
     The arcade chrome. Theme-locked; it is a physical object, not a surface
     that follows the page. */

  --cab-body:       #14101f;
  --cab-edge:       #221b3a;
  --cab-highlight:  rgba(255, 255, 255, 0.07);
  --cab-shadow:     rgba(0, 0, 0, 0.6);
  --crt-bg:         #06050c;
  --crt-bg-2:       #0b0a1c;
  --crt-rim:        rgba(67, 97, 255, 0.45);   /* the glass edge */
  --crt-scanline:   rgba(255, 255, 255, 0.035);
  --crt-glass:      rgba(199, 208, 255, 0.045);
  --marquee-light:  rgba(255, 200, 120, 0.32);

  /* ======================================================= typography ==
     Press Start 2P is DISPLAY ONLY: uppercase, <= 3 words, >= 12px.
     Never a card title, never body, never lowercase. The arcade voice comes
     from a pixel eyebrow above an Inter headline, not from pixel headlines. */

  --font-pixel: "Press Start 2P", "Courier New", monospace;
  --font-sans:  "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

  --fs-display: clamp(2.5rem, 5vw, 4rem);
  --fs-h1:      clamp(2rem, 3.5vw, 2.75rem);
  --fs-h2:      clamp(1.5rem, 2.5vw, 2rem);
  --fs-h3:      1.25rem;
  --fs-lg:      1.0625rem;
  --fs-md:      0.9375rem;
  --fs-sm:      0.8125rem;
  --fs-xs:      0.75rem;

  --fs-pixel-lg: 15px;   /* marquee            */
  --fs-pixel-md: 13px;   /* readouts           */
  --fs-pixel-sm: 12px;   /* eyebrows — floor   */

  --lh-display: 1.05;
  --lh-head:    1.15;
  --lh-body:    1.6;
  --lh-pixel:   1.6;     /* pixel faces need air */

  --tr-display: -0.03em;
  --tr-head:    -0.02em;
  --tr-body:    0;
  --tr-pixel:   0.08em;
  --tr-eyebrow: 0.10em;

  --measure: 68ch;

  /* ============================================================ space ==
     4-based. Section padding varies with the page rhythm — a single flat
     value everywhere is what made v1 mush together. */

  --s-1:  4px;
  --s-2:  8px;
  --s-3:  12px;
  --s-4:  16px;
  --s-5:  24px;
  --s-6:  32px;
  --s-7:  48px;
  --s-8:  64px;
  --s-9:  96px;
  --s-10: 128px;

  --section-y:      clamp(64px, 9vw, 128px);
  --section-y-tight:clamp(40px, 5vw, 72px);
  --gutter:         clamp(16px, 4vw, 40px);

  /* =========================================================== layout == */

  --w-wide:   1440px;
  /* The cabinet gets its own, wider measure: the screen is the product, and at
     --w-wide the playable area was only 847px across on a 1440 viewport. */
  --w-cabinet: 1760px;
  /* Vertical room the cabinet needs around the screen (marquee, toolbar, section
     padding). The screen is capped against the viewport minus this so it never
     pushes its own controls off-screen. */
  --crt-chrome: 300px;
  --w-text:   var(--measure);
  --grid-gap: 24px;
  --topbar-h: 60px;
  --touch:    44px;

  /* =========================================================== radius == */

  --r-xs:   4px;
  --r-sm:   8px;
  --r-md:   14px;
  --r-lg:   22px;
  --r-xl:   32px;
  --r-pill: 999px;

  /* =========================================================== motion ==
     One curve family. No bounce, no elastic. */

  --t-instant: 90ms;
  --t-quick:   180ms;
  --t-slow:    420ms;
  --ease:     cubic-bezier(0.2, 0.7, 0.2, 1);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);

  /* ======================================================== elevation ==
     Dark UI reads depth from a light rim plus a deep shadow, not shadow
     alone — a shadow on near-black is invisible. */

  --shadow-1: 0 1px 2px rgba(0,0,0,.4), 0 2px 8px rgba(0,0,0,.3);
  --shadow-2: 0 2px 4px rgba(0,0,0,.4), 0 12px 32px rgba(0,0,0,.45);
  --shadow-3: 0 4px 8px rgba(0,0,0,.45), 0 28px 64px rgba(0,0,0,.55);
  --rim:      inset 0 1px 0 rgba(255,255,255,.05);

  --focus-ring: 0 0 0 2px var(--bg), 0 0 0 4px var(--ring);

  --z-base: 1;
  --z-sticky: 100;
  --z-overlay: 500;
  --z-modal: 600;
  --z-toast: 700;
}

/* ------------------------------------------------------------- resets -- */

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

* { margin: 0; }

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

body {
  background: var(--bg);
  color: var(--fg-body);
  font-family: var(--font-sans);
  font-size: var(--fs-md);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img, svg, video { display: block; max-width: 100%; }
button, input, select, textarea { font: inherit; color: inherit; }
[hidden] { display: none !important; }

:where(a) { color: var(--link); text-underline-offset: 3px; }

/* One focus treatment for the entire product. Never remove it without a
   replacement — see brand-direction.md §8. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
  border-radius: var(--r-xs);
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
