/* css/theme.css — Retheme Phase 1: THE TOKEN LAYER (today's values).
   ============================================================================
   Single source of brand values. Pages compose these tokens; pages MUST NOT
   define brand values directly (constitution §3.2).

   PHASE 1 CONTRACT: every token below holds the site's CURRENT value, so a page
   converting a literal (e.g. `color:#2ecc71`) to its token (`color:var(--ps-accent)`)
   is PIXEL-IDENTICAL — verifiable by screenshot diff (docs/retheme/diff.mjs).
   That is the whole point: once every page speaks in tokens, the brand change is
   editing THIS file, not 46 pages.

   THE BRAND CHANGE IS A PHASE-3 EDIT TO THESE VALUES — the NAMES don't change:
     - accent green #2ecc71  ->  Court blue #0E4DA4   (one line, reversible)
     - dark-green surfaces    ->  light "marketplace" ground
     - green-as-everything    ->  green rationed to --ps-status-verified only
   Because --ps-accent and --ps-status-verified are already SEPARATE names (both green
   today), Phase 3 turns actions blue while verified stays green, automatically.

   TOKEN LAYER ONLY (per the split decision): no base-element styles, no
   components, no font import, no theme/density switching yet — those are inert
   here and would move pixels, so they wait for Phase 2 (components) / Phase 3
   (brand + the marketplace/performance split). Load order: theme.css -> buttons.css -> page CSS.
   ============================================================================ */

:root {
  /* ---- RGB triples: single source for a color + all its alpha tints ----
     rgb(46,204,113) === #2ecc71 (pixel-identical). Any translucent accent/hairline
     derives from these — `rgba(var(--ps-accent-rgb), 0.1)` — so Phase 3 flips every
     accent-tinted border/wash by editing ONE triple, not each alpha.

     PHASE-3 ACCENT EDIT — a PAIR + two strays. --ps-accent below is DERIVED from
     --ps-accent-rgb (`rgb(var(--ps-accent-rgb))`), so editing THIS triple flips the
     solid accent AND every rgba(var(--ps-accent-rgb), …) tint together — they cannot
     diverge. BUT --ps-accent-hover and --ps-accent-bright are SEPARATE literals; move
     them too, or you get a blue button with a green hover. VERIFY after: no raw
     `46, 204, 113` or `#2ecc71` survives OUTSIDE this file's --ps-accent-rgb /
     --ps-c-green / --ps-status-verified (which intentionally stays green). */
  --ps-accent-rgb:   46, 204, 113;    /* -> the blue triple in Phase 3 (drives --ps-accent + all tints) */
  --ps-hairline-rgb: 255, 255, 255;   /* white-alpha hairlines over dark surfaces (-> dark on light in P3) */
  --ps-status-verified-rgb: 46, 204, 113;  /* SAME green as accent today, but a SEPARATE triple: verified
                                              stays green in Phase 3 while accent flips blue. The verified
                                              badge's fill/border derive from THIS, never --ps-accent-rgb,
                                              or the badge would turn blue with the buttons. Do NOT edit
                                              this in the Phase-3 accent flip. */
  --ps-booking-available-rgb: 46, 204, 113;  /* availability "go" green — its OWN stays-green triple (same
                                                reasoning as verified: independent semantic axis, so a P3
                                                designer can keep it green or restyle it without touching
                                                accent or verified). */
  --ps-success-rgb: 46, 204, 113;  /* success-feedback green (confirmation checkmarks, "submitted" cards).
                                      Stays green in P3 — a green "done" check is a convention independent
                                      of brand. Its OWN triple (its tints derive from here, not accent).
                                      NOTE: --ps-status-verified-rgb / --ps-booking-available-rgb /
                                      --ps-success-rgb are three stays-green sources holding the same value
                                      today; kept separate because they're independent semantic axes. If a
                                      P3 pass decides they always move together, collapse them into one
                                      then — cheap, since each already flows from a single triple. */
  /* --ps-accent-venue-legacy-rgb — DECIDED (not a tier color): the teal on spaces.html / the homepage
     "Search Spaces" button is DRIFT, not a designed venue identity. The proof is on the page itself —
     teal search/book buttons sit next to GREEN "List Your Space" / "Confirm Booking" CTAs; a real tier
     color doesn't contradict itself in one viewport. So this is --ps-accent that happens to hold a
     different value TODAY and COLLAPSES INTO --ps-accent in Phase 3 (teal -> Court blue with everything
     else; actions = one color). Named ugly ON PURPOSE (same principle as a ledger that says NOT APPLIED)
     so no future page reaches for a hue-named "teal" token. Its cyan gradient partner #06b6d4 is a
     <5-use tail literal — collapse it in the same Phase-3 pass. (NOTE: teal-as-performance-state lives
     separately in --ps-perf-improving and is a legitimate semantic — this token is only the venue drift.) */
  --ps-accent-venue-legacy-rgb: 20, 184, 166;   /* === #14b8a6 today; -> --ps-accent-rgb value in Phase 3 */

  /* ---- Base palette: current de-facto values (reference; semantics alias these) ---- */
  --ps-c-green:        #2ecc71;   /* signature green — 297 uses */
  --ps-c-green-deep:   #27ae60;   /* gradient/hover partner */
  --ps-c-green-brand:  #16a34a;
  --ps-c-green-bright: #4ade80;
  /* (no --ps-c-teal base token: teal-as-accent is drift -> --ps-accent-venue-legacy; teal-as-perf-state
     is a literal in --ps-perf-improving. A bare hue-named teal token would just invite more drift.) */

  --ps-c-ink-950:      #070f09;
  --ps-c-ink-900:      #08140c;
  --ps-c-ink-850:      #0a1a10;   /* primary page ground — 123 */
  --ps-c-ink-800:      #0d1f14;   /* raised surface — 106 */
  --ps-c-ink-750:      #112518;   /* cards / modals */
  --ps-c-ink-700:      #1a2e22;
  --ps-c-ink-650:      #1e3a2a;

  --ps-c-white:        #ffffff;
  --ps-c-sage:         #6b8f76;   /* muted green-gray — 210 */
  --ps-c-sage-light:   #86a895;
  --ps-c-sage-dim:     #4b6b57;
  --ps-c-gray-400:     #9ca3af;   /* neutral muted — 119 */
  --ps-c-gray-300:     #d1d5db;
  --ps-c-gray-600:     #4b5563;

  --ps-c-red:          #e74c3c;
  --ps-c-red-soft:     #f87171;
  --ps-c-red-deep:     #c0392b;
  --ps-c-amber:        #f39c12;
  --ps-c-amber-alt:    #f59e0b;
  --ps-c-blue:         #3498db;

  --ps-c-mint-50:      #f0fdf4;   /* light-green wash (light components) */
  --ps-c-mint-100:     #e8f5e9;

  /* Neutral-dark surfaces of the styles.css foundation — NOT the green-black --ps-surface-* above.
     Held at today's values; the Phase-3 tier split decides whether performance/professional adopt
     these neutral asphalts. Kept as base values so the foundation can alias them without moving pixels. */
  --ps-c-neutral-950:  #0a0f0d;   /* styles.css --dark   */
  --ps-c-neutral-900:  #111714;   /* styles.css --dark-2 */
  --ps-c-neutral-850:  #16211a;   /* styles.css --dark-3 */
  --ps-c-neutral-800:  #1a2620;   /* styles.css --dark-card */

  /* Purple-DRIFT surfaces + text (the teams/messages tier) — a THIRD tinted surface family alongside
     green-black and neutral. Held at today's values; they collapse in the Phase-3 surface neutralization
     (a blue brand on green AND purple grounds reads as three half-finished themes — neutral is what makes
     one identity one). Paired with --ps-accent-legacy-purple above. */
  --ps-c-purple-950:   #0f0f1a;   /* purple-dark ground */
  --ps-c-purple-900:   #16162a;   /* purple raised surface */
  --ps-c-purple-text:  #f0f0ff;   /* purple-tinted white text */

  /* Orange second-accent of the styles.css foundation (Tailwind orange-500/400 — drift, like the
     tailwind green; a P3 pass decides its fate). Not green, so it's outside the accent flip. */
  --ps-c-orange:       #f97316;
  --ps-c-orange-light: #fb923c;

  /* ---- Surfaces (constitution names; current dark-green values) ---- */
  --ps-surface-0:       #0a1a10;  /* page ground        (Phase 3 -> light) */
  --ps-surface-1:       #0d1f14;  /* raised             */
  --ps-surface-2:       #112518;  /* card / modal       */
  --ps-surface-3:       #1a2e22;  /* elevated           */
  --ps-surface-inverse: #ffffff;

  /* ---- Text ---- */
  --ps-text-primary:   #ffffff;
  --ps-text-secondary: #86a895;
  --ps-text-muted:     #6b8f76;
  --ps-text-faint:     #4b6b57;
  --ps-text-gray:      #9ca3af;   /* the neutral-gray muted (distinct hue, 119 uses) */
  --ps-text-inverse:   #0a1a10;
  /* Body copy across much of the site. TODAY it's mint-white #f0fdf4 (a green-tinted white — invisible on
     green grounds, reads subtly wrong once the accent is blue). Tokenized so its Phase-3 neutralization is
     ONE deliberate edit, not a mechanical sweep: it's the change most likely to make the site "feel
     different" without anyone naming why, so change it here and LOOK. Distinct from --ps-text-primary
     (#ffffff, pure white used for headings). */
  --ps-text-body:      #f0fdf4;

  /* ---- Accent (green TODAY; -> Court blue #0E4DA4 in Phase 3) ---- */
  --ps-accent:        rgb(var(--ps-accent-rgb));      /* === #2ecc71 */
  --ps-accent-hover:  #27ae60;
  --ps-accent-bright: #4ade80;
  --ps-on-accent:     #0a1a10;    /* text/icon on an accent fill */
  --ps-accent-bg:     rgba(var(--ps-accent-rgb), 0.12);
  --ps-accent-wash:   #f0fdf4;    /* light-surface accent tint */
  --ps-accent-venue-legacy: rgb(var(--ps-accent-venue-legacy-rgb));  /* venue teal drift; collapses into --ps-accent in P3 */
  --ps-accent-venue-legacy-cyan-rgb: 6, 182, 212;   /* the venue gradient's CYAN partner (#06b6d4) — collapses
                                                        WITH the teal in P3, or a teal->blue gradient strands a
                                                        cyan end. Tokenized so the venue gradients flip clean. */
  --ps-accent-venue-legacy-cyan:     rgb(var(--ps-accent-venue-legacy-cyan-rgb));
  /* Tailwind-DRIFT accent — the styles.css/auth.css foundation's green. NOT a tier colour: it's
     Tailwind's default green-600/500/400 (the palette of whatever built those pages), sitting next to
     the hand-picked #2ecc71. Same class as the venue teal, one scale up. Ugly-on-purpose name so nothing
     reaches for it; collapses into --ps-accent in Phase 3 (edit these to the accent's blue then).
     Pixel-identical to today. (styles.css ALSO uses brand #2ecc71 in places -> that maps to --ps-accent,
     not here.) */
  --ps-accent-legacy-tailwind-rgb:    34, 197, 94;   /* green-500 (=#22c55e) — drives the rgba glows/tints */
  --ps-accent-legacy-tailwind:        #16a34a;        /* green-600 — the solid "--green" */
  --ps-accent-legacy-tailwind-light:  #22c55e;        /* green-500 — "--green-light" */
  --ps-accent-legacy-tailwind-bright: #4ade80;        /* green-400 — auth-success text */
  /* Purple-DRIFT accent — the teams/team-analysis/messages tier's #6c63ff identity. DECIDED drift
     (not a sub-brand): nothing in the constitution, tier map, or pricing makes social/teams a distinct
     identity, and no one would choose to fragment a product already fighting a "six platforms" problem.
     Consistent across 3 pages built in one sitting is a session, not design intent. Same treatment as
     teal/tailwind: ugly name, collapses into --ps-accent in Phase 3. Exposed by the flip preview (the
     gate greps couldn't see a non-green accent). Pixel-identical today. Its purple-dark surfaces + text
     come WITH it — see --ps-c-purple-* below (they join the Phase-3 surface neutralization). */
  --ps-accent-legacy-purple-rgb:   108, 99, 255;   /* === #6c63ff — drives solid + rgba tints */
  --ps-accent-legacy-purple:       rgb(var(--ps-accent-legacy-purple-rgb));
  --ps-accent-legacy-purple-light: #8b84ff;

  /* ---- Borders / hairlines (the court-keyline material) ---- */
  --ps-border:            rgba(var(--ps-hairline-rgb), 0.06);  /* 110 uses */
  --ps-border-strong:     rgba(var(--ps-hairline-rgb), 0.10);
  --ps-border-faint:      rgba(var(--ps-hairline-rgb), 0.04);
  --ps-border-accent:     rgba(var(--ps-accent-rgb), 0.30);
  --ps-border-accent-soft:rgba(var(--ps-accent-rgb), 0.12);

  /* ---- Status — SEPARATE names, same green today; they DIVERGE in Phase 3 ----
     (verified stays green; accent -> blue). Every status also needs an icon +
     text label in markup — color is never the only signal (constitution §4/§9). */
  --ps-status-verified:      rgb(var(--ps-status-verified-rgb));   /* === #2ecc71, but its OWN triple */
  --ps-status-pending:       #f39c12;
  --ps-status-restricted:    #e74c3c;
  --ps-status-verified-bg:   rgba(var(--ps-status-verified-rgb), 0.12);   /* stays green in P3 */
  --ps-status-verified-border: rgba(var(--ps-status-verified-rgb), 0.35); /* badge keyline */
  --ps-status-pending-bg:    rgba(243,156,18,0.12);
  --ps-status-restricted-bg: rgba(231,76,60,0.12);

  /* ---- Feedback / semantic aliases used across pages ---- */
  --ps-danger:        #e74c3c;
  --ps-danger-hover:  #c0392b;
  --ps-danger-soft:   #f87171;
  --ps-warning:       #f39c12;
  --ps-success:       rgb(var(--ps-success-rgb));   /* === #2ecc71, its OWN stays-green triple */
  --ps-info:          #3498db;

  /* ---- Performance + booking states (constitution §4; current analogs) ---- */
  --ps-perf-elite:     #2ecc71;
  --ps-perf-improving: #14b8a6;
  --ps-perf-baseline:  #6b8f76;
  --ps-booking-available:   rgb(var(--ps-booking-available-rgb));  /* === #2ecc71, its OWN triple */
  --ps-booking-limited:     #f39c12;
  --ps-booking-unavailable: #6b8f76;

  /* ---- Radius (small + consistent; constitution §2.1) ---- */
  --ps-radius-sm:   6px;
  --ps-radius:      12px;
  --ps-radius-lg:   16px;
  --ps-radius-pill: 999px;

  /* ---- Spacing scale (rem; inert until pages convert to it) ---- */
  --ps-space-1: 0.25rem;  --ps-space-2: 0.5rem;   --ps-space-3: 0.75rem;  --ps-space-4: 1rem;
  --ps-space-6: 1.5rem;   --ps-space-8: 2rem;     --ps-space-12: 3rem;    --ps-space-16: 4rem;

  /* ---- Type scale (rem so it respects browser font-size; a11y §9) ---- */
  --ps-size-display: 2.5rem;  --ps-size-h2: 1.75rem;  --ps-size-h3: 1.25rem;
  --ps-size-body: 1rem;       --ps-size-small: 0.875rem;  --ps-size-caption: 0.8125rem;

  /* ---- Motion (communicates or it doesn't ship; constitution §8) ---- */
  --ps-motion-fast: 120ms;  --ps-motion-standard: 220ms;  --ps-motion-emphasis: 420ms;
  --ps-ease: cubic-bezier(0.2, 0, 0.13, 1);

  /* ---- Elevation (functional only) ---- */
  --ps-shadow-overlay: 0 12px 32px rgba(0,0,0,0.35);
}

/* NOTE (Phase 3): the marketplace/performance split + light brand values get added
   here as [data-theme="marketplace"] / [data-theme="performance"] blocks that
   REDEFINE the values above. Nothing else in the codebase changes. */

/* ============================================================================
   ICON PRIMITIVE — .ico, for the emoji→SVG rollout (constitution §4 credibility).
   Lives here for the same reason as the §8 net below: theme.css is the ONLY stylesheet
   universal to all 46 pages (buttons.css is 40/46), and icons appear on every page. Emoji are
   replaced by <svg class="ico" aria-hidden="true"><use href="/icons/sprite.svg#name"/></svg>.
   Sized in `em` so each icon inherits the font-size of the slot it replaces (a 1.75rem
   .value-icon → a 1.75rem glyph), keeping reflow to a minimum. Color is `currentColor` (set by
   the slot), so icons flip with the brand in Phase 3 with zero extra edits. Sport emoji are NOT
   converted (kept as categorical markers — see README component log).
   ============================================================================ */
.ico {
  width: 1em; height: 1em;
  display: inline-block; vertical-align: -0.125em;
  flex-shrink: 0;
}

/* ============================================================================
   §8 REDUCED-MOTION — the ONE element rule in this otherwise token-only file.
   Justified: motion accessibility is a SYSTEM-LEVEL requirement (constitution §8), theme.css is the
   only stylesheet universal to every page, and this block is opt-in (it does nothing for default
   users — so it moves zero default pixels and verifies diff-green; the capture harness's own
   animation-freeze dominates during capture). A per-page fix would leave the next animation unguarded.
   Site-wide scan found the marquee was just the worst case: styles.css scrollDown/float + assorted
   spinners/pulses all animated with no guard before this.

   The standard reset (near-zero duration, single iteration, forwards) jumps animations to their END
   frame — correct for fade-ins/pulses (they land on their final, visible state). LOOPS are the
   exception: an end-frame freeze leaves a marquee shifted mid-scroll, so any infinite-scroll element
   needs an explicit `animation: none` to rest at its START. Today that's only .proof-track (index);
   add the same override for any future marquee. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  /* loops must rest at start, not their -50% end frame (see note above) */
  .proof-track { animation: none !important; }
}
