/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
   RAVESTREAMS DESIGN TOKENS v1
   Single source of truth. See /docs/design-system-v1.md for usage.
   Import order:
     1. fonts.css   (font-face, label override)
     2. design-tokens.css   (this file — CSS custom properties only)
     3. component / page styles
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */

:root {
  /* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
     TYPE — Trio 3 (Neue Machina + Hubot Sans + Monaspace Neon)
     All free, all anti-vibe-coded. Fontshare + jsdelivr GitHub mirror.
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
  --display: 'Neue Machina', 'Hubot Sans', system-ui, sans-serif;
  --sans:    'Hubot Sans', system-ui, -apple-system, sans-serif;
  /* --label: small all-caps chrome. Proportional sans reads cleaner than
     mono at 7-10px (mono goes choppy at chip / pill sizes). */
  --label:   'Hubot Sans', system-ui, -apple-system, sans-serif;
  --mono:    'Monaspace Neon', ui-monospace, 'JetBrains Mono', monospace;

  /* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
     SURFACES — cool-biased near-black stack
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
  --bg:         #08080a;
  --surface:    #111113;
  --surface-el: #191920;
  --surface-hi: #222228;

  /* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
     BORDERS — three intensities, all derived from #f5fafe alpha
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
  --border:     rgba(245, 250, 255, 0.07);
  --border-hi:  rgba(245, 250, 255, 0.13);
  --border-str: rgba(245, 250, 255, 0.22);

  /* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
     TEXT — 3-stop hierarchy
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
  --text:   #f0f0f5;   /* primary */
  --text-2: #8a8a9a;   /* secondary / body dim */
  --text-3: #48485a;   /* tertiary / chrome */

  /* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
     SPACING SCALE — committed, no off-scale pixel values
     Multiples-of-4 with 2px / 6px / 10px / 28px exceptions
     for tight chrome (badges, hairlines, icon padding).
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
  --s2:  2px;   /* hairline gap (eq bars, dot edges) */
  --s4:  4px;   /* tight badge padding */
  --s6:  6px;   /* chip inner gap */
  --s8:  8px;   /* default chrome gap */
  --s10: 10px;  /* compact card padding */
  --s12: 12px;  /* default card / row padding */
  --s16: 16px;  /* section internal gap */
  --s20: 20px;  /* large content gap */
  --s24: 24px;  /* CTA padding */
  --s28: 28px;  /* hero internal */
  --s32: 32px;  /* section vertical rhythm */
  --s40: 40px;  /* between major sections (mobile) */
  --s60: 60px;  /* between major sections (desktop) */

  /* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
     RADII — chips < tiles < sheets
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
  --r-xs:  4px;   /* tier badges, latency pills */
  --r-sm:  6px;   /* chips, nav buttons, stage tiles */
  --r-md:  10px;  /* CTAs, mini-player */
  --r-lg:  14px;  /* cards (live, festival, dj) */
  --r-xl:  18px;  /* large panels */
  --r-2xl: 24px;  /* sheets, modals */

  /* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
     MOTION — shared easing + 4 durations
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
  --ease:      cubic-bezier(0.4, 0, 0.2, 1);   /* default — Material-style */
  --dur-fast:  200ms;  /* hover, focus, micro-feedback */
  --dur-base:  250ms;  /* default UI transitions */
  --dur-slow:  400ms;  /* ambient color crossfade, haze tint */
  --dur-xslow: 600ms;  /* hero background crossfade */

  /* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
     LAYOUT — max-width + page padding
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
  --max-w:   1440px;
  --page-px: clamp(20px, 4vw, 56px);

  /* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
     LATENCY BADGES — three color codes
     green  <10s   |   amber 10-30s   |   red  >30s
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
  --latency-good:  #6ee7a5;
  --latency-amber: #ffb547;
  --latency-red:   #ff5a5a;

  /* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
     AMBIENT COLOR — JS-driven, sampled every 600ms from active video
     via fast-average-color. Falls back to programmed cycle when video
     is cross-origin or unavailable. Default neutral white-ish so
     pages render correctly before JS has sampled anything.
     Use --ambient-color-rgb (and the legacy --ambient-r/g/b triple)
     inside rgba() for translucent glows.
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
  --ambient-color:     #f0f0f5;
  --ambient-color-rgb: 240, 240, 245;
  --ambient-r: 240;
  --ambient-g: 240;
  --ambient-b: 245;

  /* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
     FESTIVAL PALETTE — extracted from events-data.js
     Top-tier festivals get a named token. Anything else can use
     [data-festival-color="#hex"] on the element for a per-instance
     override (see below).
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
  --edc:          #ff2bd6;   /* EDC Las Vegas / Orlando / Korea — magenta */
  --tml:          #a056ff;   /* Tomorrowland fallback — violet */
  --tml-belgium:  #ffb547;   /* Tomorrowland Belgium / Brasil — amber */
  --tml-winter:   #1a3c6e;   /* Tomorrowland Winter — alpine blue */
  --ult:          #00e5ff;   /* Ultra (generic) — cyan */
  --ult-europe:   #ff2bd6;   /* Ultra Europe — magenta */
  --ult-japan:    #cc0000;   /* Ultra Japan — rising-sun red */
  --br:           #ffb547;   /* Boiler Room — amber */
  --ins:          #cc22aa;   /* Insomniac Radio — pink */
  --owr:          #00b8cc;   /* Official Worldwide Radio — teal */
  --mvmt:         #3cffd0;   /* Movement Detroit — aqua */
  --crcl:         #4ade80;   /* Cercle — green */
  --kpkt:         #9eff3c;   /* Kappa FuturFestival — neon lime */
  --awkn:         #9eff3c;   /* Awakenings — neon lime */
  --coachella:    #ffb547;   /* Coachella — desert amber */
  --time-warp:    #3cffd0;   /* Time Warp (Mexico) — aqua */
  --time-warp-de: #c8001a;   /* Time Warp Germany — Mannheim red */
  --dgtl:         #00b4a0;   /* DGTL Amsterdam — industrial teal */
  --defqon:       #ff3a5c;   /* Defqon.1 — hardstyle red */
  --hor:          #3cffd0;   /* HÖR Berlin — aqua */
  --liquicity:    #3cffd0;   /* Liquicity — drum and bass aqua */
  --sziget:       #009900;   /* Sziget — island green */
  --bass-canyon:  #00ffaa;   /* Bass Canyon — Gorge green */
  --dreamstate:   #0033cc;   /* Dreamstate — trance blue */
  --boom:         #cc6600;   /* Boom Festival — Portuguese earth */

  /* Per-instance override pattern (see [data-festival-color] below) */
  --festival-color: var(--edc);
}

/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
   PER-INSTANCE FESTIVAL COLOR OVERRIDE
   Any element can set --festival-color via attribute. Use it
   on tiles, cards, ribbons:
       <article class="festival-card" data-festival-color="#00ccff">
   The CSS-only `attr(* color)` would handle this but cross-browser
   support is still limited (mid-2026). For now JS reads the attr
   and sets the property inline — but you can also set it directly
   via style="--festival-color: #00ccff" with zero JS.
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
[data-festival-color] {
  /* JS sets --festival-color from the attribute value.
     Fallback to --edc if the attribute is empty / unset. */
  --festival-color: var(--edc);
}

/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
   REDUCED MOTION — global override
   Every component that uses --dur-* should respect this.
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
@media (prefers-reduced-motion: reduce) {
  :root {
    --dur-fast:  0.01ms;
    --dur-base:  0.01ms;
    --dur-slow:  0.01ms;
    --dur-xslow: 0.01ms;
  }
}

/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
   ADAPTIVE CHROME RULES (MLW-2853)
   Added by adaptive-chrome.js builder. Class names are applied to
   :root (and to any [data-chrome-target] elements) by the module
   based on the active audio source's `tier`.

   Show/hide semantics: pages label their chrome elements with
   `.live-pulse`, `.latency-badge`, `.set-progress`, `.viewer-count`.
   The selectors below hide each one whenever its matching
   `show-*` class is ABSENT from :root.

   Mode classes (`chrome-festival` / `chrome-event` / `chrome-calm`)
   are reserved for downstream visual treatments — left blank here
   so page-level CSS can define them without conflict.
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */

:root:not(.show-live-pulse) .chrome-target .live-pulse,
:root:not(.show-live-pulse) .live-pulse { display: none; }

:root:not(.show-latency) .chrome-target .latency-badge,
:root:not(.show-latency) .latency-badge { display: none; }

:root:not(.show-set-progress) .chrome-target .set-progress,
:root:not(.show-set-progress) .set-progress { display: none; }

:root:not(.show-viewers) .chrome-target .viewer-count,
:root:not(.show-viewers) .viewer-count { display: none; }

/* Calm-mode hook — pages can override here for desaturated chrome
   without coupling to specific selectors. Intentionally empty so
   the contract is documented but visual treatment lives downstream. */
:root.chrome-calm .chrome-target { /* calm-mode treatments go here */ }
