/* ──────────────────────────────────────────────────────────────
   TicketHub design tokens — 2026 identity.

   Replaces the old root.css amber/neutral set. Values are sampled from
   media/disign/*.pdf and media/disign/logo.svg; see the redesign plan for
   the source of each one.

   Two surface contexts instead of two whole themes: a section opts in with
   data-surface="ink" or data-surface="paper" and the semantic tokens below
   flip. That is what lets one page mix a black hero with a concrete band
   without the old base-dark / base-light split.

   Loaded before every other stylesheet.
   ────────────────────────────────────────────────────────────── */

:root {
  /* ── Brand primitives ───────────────────────────────────────── */
  --ink:        #0b0b0b;  /* logo.svg .cls-3 — dark sections, footer   */
  --ink-2:      #262626;  /* logo.svg .cls-1 — logo mark body          */
  --ink-3:      #141414;  /* raised surface on ink                     */
  --paper:      #ededed;  /* concrete section ground                   */
  --paper-2:    #f7f8f8;  /* logo.svg .cls-2 — cards, panels           */
  --paper-3:    #e2e2e2;  /* recessed surface on paper                 */
  --red:        #ca3333;  /* accent: HUB, day numbers, key words       */
  --red-bright: #e03a3a;  /* hover                                     */
  --green:      #3ad272;  /* payment success panel. Brand success green,
                             set from the design, NOT sampled from the
                             clip                                       */
  --green-clip: #3ad272;  /* Surfaces the success clip sits on. Held equal
                             to --green on purpose.

                             Note this is deliberately NOT the clip's own
                             ground. payment-success-full is tagged
                             bt709/limited-range with a ground of
                             Y=157 Cb=99 Cr=65, which every conforming
                             decoder expands to rgb(51, 204, 103) — about
                             7 units darker than the brand green, in both
                             the .mp4 and the .webm and in the 2160x3840
                             master in media/disign. So where CSS meets
                             the clip there is a faint edge by design;
                             the only way to remove it is to re-export
                             the clip on this green. Do not "fix" it by
                             sampling the video back into this token     */
  --warning:    #f97316;  /* countdown / hold-expiry states            */
  --warning-bg: #fff7ed;
  --rule:       #8e8e8e;  /* torn banner + photo frame strokes         */

  /* ── Radii, shadows, motion ─────────────────────────────────── */
  --radius:      10px;
  --radius-lg:   16px;
  --radius-xl:   24px;   /* event cards, hero bottom corners */
  --radius-pill: 999px;

  --shadow-card: 0 10px 30px rgba(0, 0, 0, 0.18);
  --shadow-ink:  0 4px 32px rgba(0, 0, 0, 0.55);

  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --dur:  0.25s;

  /* ── Layout ─────────────────────────────────────────────────── */
  --measure:     1440px;  /* standard desktop content width           */
  --measure-wide: 2400px; /* ultra-wide cap, per the extended mockup  */
  --gutter:      clamp(16px, 3vw, 48px);

  /* ── Textures ───────────────────────────────────────────────── */
  --tex-grain: url("../images/texture/concrete-grain.f8904e94ae5e.webp");
  /* The marbled "dirty black" behind every ink surface — hero (.surface-smoke),
     the coincidence slab (.section[data-surface='ink']::before) and the whole
     footer (.site-footer), all single-layer so they read as one material.

     Lifted from the intro animation's black-flip frame (t=2.6s of
     media/disign/loading screen desktop.webm) so those surfaces are literally
     the same black the animation lands on, then CROPPED to the swirl-dense
     region (2400x1200 of the 4K frame, scaled to 2000x1000). The uncropped
     frame has its marbling bunched in one corner, so under background-size:
     cover the swirls only surfaced in a band near the bottom of the footer and
     the rest read as flat black. Keep any replacement evenly marbled edge to
     edge for the same reason. */
  --tex-smoke: url("../images/texture/dirty-black.07e24c7e27af.webp");
}

/* ── Semantic tokens, per surface ─────────────────────────────── */

:root,
[data-surface='paper'] {
  --bg:       var(--paper);
  --surface:  var(--paper-2);
  --surface-2: var(--paper-3);
  --text:     var(--ink);
  --text-dim: #5a5a5a;
  --line:     #d2d2d2;
  --shadow:   var(--shadow-card);
}

[data-surface='ink'] {
  --bg:       var(--ink);
  --surface:  var(--ink-3);
  --surface-2: #1e1e1e;
  --text:     var(--paper-2);
  --text-dim: #9a9a9a;
  --line:     #2a2a2a;
  --shadow:   var(--shadow-ink);
}

/* ──────────────────────────────────────────────────────────────
   Legacy aliases.

   ~20 public templates still carry their own <style> blocks written
   against the previous amber token set. These keep them rendering
   (in the new palette) until Phase 4 migrates each one. Delete this
   block once no template references the old names.

   WHY THE SELECTORS LOOK LIKE THIS: a var() inside a custom property is
   substituted at computed-value time ON THE ELEMENT THAT DECLARES IT, and
   the substituted literal is what inherits — it never re-resolves further
   down the tree. An alias declared only on :root therefore freezes at the
   :root (paper) value, so inside a data-surface='ink' subtree
   --text-primary stayed #0b0b0b on a #0b0b0b ground: 1:1, invisible. That
   was the sitewide "text and background are not complementary" bug.

   So any alias whose value contains a var() pointing at a per-surface
   token MUST be declared on every surface root. [data-surface] is exactly
   the set of surface roots, so one block covers ink, paper and either
   nesting direction with no per-value duplication. Aliases that resolve to
   brand primitives are surface-invariant and stay on :root.
   ────────────────────────────────────────────────────────────── */

/* Surface-invariant: resolve to brand primitives, identical everywhere. */
:root {
  --color-white: var(--paper-2);
  --color-logo:  var(--ink-2);
  /* Deliberately NOT var(--bg): ~10 templates have repurposed this as "the
     ink colour" rather than "the page background" — about_us.html is a paper
     page and uses it 15x for dark text and deliberate dark bands. Pointing
     it at --bg would invert that page wholesale. */
  --color-bg:    var(--ink);
  --color-green: var(--green);
  --color-red:   var(--red);

  --accent:       var(--red);
  --accent-dark:  #a82a2a;
  --accent-glow:  rgba(202, 51, 51, 0.10);
  --accent-glow2: rgba(202, 51, 51, 0.20);

  --green-glow: rgba(51, 204, 103, 0.12);
  --blue:       #3b82f6;

  --shadow-accent: 0 4px 24px rgba(202, 51, 51, 0.22);
  --shadow-green:  0 4px 20px rgba(51, 204, 103, 0.18);
}

/* Surface-dependent: re-resolved once per surface root. */
:root,
[data-surface] {
  --text-primary:   var(--text);
  --text-secondary: var(--text-dim);
  --border:         var(--line);
  /* Was var(--paper-3) — a near-white panel on ink pages. All 6 uses are
     form-field backgrounds paired with color: var(--text-primary) in the
     SAME rule, so the two must flip together: fixing --text-primary while
     leaving this at #e2e2e2 would turn 15.2:1 into 1.06:1 and simply move
     the invisible-text bug. Collapsing it onto --surface-2 is a no-op on
     paper (#e2e2e2 either way) and correct (#1e1e1e) on ink. */
  --surface-3:      var(--surface-2);
}

/* --text-muted, --text-tertiary, --border-hover and --line-strong have no
   modern counterpart, so they carry literals and need one block per surface.
   --text-muted's two values were polarised BACKWARDS (#aaaaaa on paper =
   1.98:1, #4a4a4a on ink = 2.22:1 — both illegible); these follow
   --text-dim's polarity and clear AA on bg, surface and surface-2 alike.

   --line-strong is new and load-bearing: --line is a deliberately quiet
   divider (#2a2a2a on ink), which is fine for rules but only 1.16:1 against
   --surface-2 — below the 3:1 WCAG minimum for a form-control boundary. It
   went unnoticed while --border was frozen at the paper #d2d2d2, which was
   inverted but at least visible. Anything that outlines an interactive
   control should point here, not at --line. */
:root,
[data-surface='paper'] {
  --text-muted:    #636363;  /* 5.13 / 5.65 / 4.64 on bg / surface / surface-2 */
  --text-tertiary: #6f6f6f;  /* 4.29 / 4.72 / 3.88 — decorative, see note */
  --border-hover:  #b8b8b8;
  --line-strong:   #808080;  /* 3.37 / 3.71 / 3.05 — clears 3:1 for controls */
}

[data-surface='ink'] {
  --text-muted:    #8a8a8a;  /* 5.70 / 5.34 / 4.83 */
  --text-tertiary: #7d7d7d;  /* 4.78 / 4.48 / 4.05 */
  --border-hover:  #3d3d3d;
  --line-strong:   #6b6b6b;  /* 3.69 / 3.46 / 3.13 */
}
