/* ============================================================
   OnSumn / Bay Area Pulse — Design Tokens
   ============================================================ */

/* ============================================================
   Responsive breakpoints — pragmatic var-only path
   ------------------------------------------------------------
   The CSS `@custom-media` syntax (Media Queries L5) would let us
   write `@media (--bp-md) { … }`, but it requires a build step
   (PostCSS postcss-custom-media) — and the project is a hard
   constraint of "no build tools, babel-standalone only". Polyfills
   exist client-side but they hurt FCP for non-functional gain.

   Decision (Architect ask #7 from Phase B queue, Marco's call):
     1. Document the canonical breakpoint values as CSS custom
        properties so future code references --bp-* by name.
     2. Normalize raw `@media` + `matchMedia` queries to the same
        4 numeric values — no more 639px vs 640px drift across files.
     3. JS-side: window.bp.{sm,md,lg,xl} helper exposed from the
        same source-of-truth (lib/breakpoints.js).

   Canonical breakpoints (mobile-first, min-width):
     --bp-sm : 480px   small phone → big phone (landscape switch)
     --bp-xs2: 640px   big phone → small tablet (legacy venue gate)
     --bp-md : 768px   phone → tablet           (single→multi col)
     --bp-lg : 1024px  tablet → laptop          (sidebar, hover UX)
     --bp-xl : 1200px  laptop → desktop         (max-width clamps)

   The 640px step (`--bp-xs2`, exposed as `bp.minWidth('xs2')` in
   JS) exists for one historical site: VenueEventList +
   VenueHeader's single-col→split-col switch. Pre-normalization,
   that gate fired at 639/640 with a 1px drift between files; both
   now consume `xs2` so the boundary is identical. We chose to
   keep the gate at 640 rather than promote to `md` (768) because
   the venue page has been visually tuned around the iPad-mini-
   landscape boundary since Phase 4.2 and bumping it changes the
   single-col tier behavior on real devices.
   ============================================================ */
:root {
  --bp-sm: 480px;
  --bp-xs2: 640px;
  --bp-md: 768px;
  --bp-lg: 1024px;
  --bp-xl: 1200px;
}


/* ── Fonts ── */
@font-face { font-family: 'Be Vietnam Pro'; src: url('fonts/BeVietnamPro-Light.ttf'); font-weight: 300; }
@font-face { font-family: 'Be Vietnam Pro'; src: url('fonts/BeVietnamPro-Regular.ttf'); font-weight: 400; }
@font-face { font-family: 'Be Vietnam Pro'; src: url('fonts/BeVietnamPro-Medium.ttf'); font-weight: 500; }
@font-face { font-family: 'Be Vietnam Pro'; src: url('fonts/BeVietnamPro-SemiBold.ttf'); font-weight: 600; }
@font-face { font-family: 'Be Vietnam Pro'; src: url('fonts/BeVietnamPro-Bold.ttf'); font-weight: 700; }
@font-face { font-family: 'Be Vietnam Pro'; src: url('fonts/BeVietnamPro-ExtraBold.ttf'); font-weight: 800; }
@font-face { font-family: 'Be Vietnam Pro'; src: url('fonts/BeVietnamPro-Black.ttf'); font-weight: 900; }

/* Barlow — designed by Jeremy Tribby, inspired by Bay Area public signage */
@font-face { font-family: 'Barlow'; src: url('fonts/Barlow-Light.ttf'); font-weight: 300; }
@font-face { font-family: 'Barlow'; src: url('fonts/Barlow-Regular.ttf'); font-weight: 400; }
@font-face { font-family: 'Barlow'; src: url('fonts/Barlow-Medium.ttf'); font-weight: 500; }
@font-face { font-family: 'Barlow'; src: url('fonts/Barlow-SemiBold.ttf'); font-weight: 600; }
@font-face { font-family: 'Barlow'; src: url('fonts/Barlow-Bold.ttf'); font-weight: 700; }

/* ── Base Tokens ── */
:root {
  /* --- Typography Families --- */
  --font-display: 'Be Vietnam Pro', sans-serif;
  --font-body: 'Barlow', sans-serif;

  /* --- Brand Colors --- */
  --amber-gold: #D57800;
  --amber-gold-light: #FFB778;
  --international-orange: #FF4F00;
  --international-orange-bright: #FF5717;

  /* --- Eucalyptus Green (Pantone 7736 C) — category tags, badges, subtle highlights --- */
  --eucalyptus-green: #395542;
  --eucalyptus-green-light: #5A7A68;
  --eucalyptus-green-dim: #2A3F32;

  /* --- Fog Blue (Pantone 5425 C) — cards, borders, hover states, secondary bg --- */
  --fog-blue: #7A99AC;
  --fog-blue-light: #A3BDCC;
  --fog-blue-dim: #5B7A8D;
  --fog-blue-deep: #4A6678;

  /* Theme-aware fog-blue semantic aliases — overridden in light theme below */
  --fog-blue-ink: var(--fog-blue-light);
  --fog-blue-rule: var(--fog-blue);

  /* --- Surfaces (Dark Mode Default) --- */
  --surface: #121414;
  --surface-dim: #0A0A0A;
  --surface-bright: #38393A;
  --surface-container-lowest: #0C0F0F;
  --surface-container-low: #1A1C1C;
  --surface-container: #1E2020;
  --surface-container-high: #282A2B;
  --surface-container-highest: #333535;

  /* --- On-Surface (Text) --- */
  --on-surface: #E2E2E2;
  --on-surface-variant: #DBC2AF;
  --on-surface-muted: #A38D7C;

  /* --- Primary --- */
  --primary: #FFB778;
  --on-primary: #4C2700;
  --primary-container: #D77902;
  --on-primary-container: #422100;
  --inverse-primary: #8E4E00;

  /* --- Secondary --- */
  --secondary: #FFB59E;
  --on-secondary: #5E1700;
  --secondary-container: #FF5717;
  --on-secondary-container: #521300;

  /* --- Tertiary --- */
  --tertiary: #C6C6C6;
  --on-tertiary: #303030;
  --tertiary-container: #919191;

  /* --- Eucalyptus / Fog semantic aliases --- */
  --accent-green: var(--eucalyptus-green);
  --accent-blue: var(--fog-blue);

  /* --- Error --- */
  --error: #FFB4AB;
  --on-error: #690005;
  --error-container: #93000A;

  /* --- Outline --- */
  --outline: #A38D7C;
  --outline-variant: #554335;

  /* --- Inverse --- */
  --inverse-surface: #E2E2E2;
  --inverse-on-surface: #2F3131;

  /* --- Fixed --- */
  --primary-fixed: #FFDCC1;
  --primary-fixed-dim: #FFB778;
  --secondary-fixed: #FFDBD0;
  --secondary-fixed-dim: #FFB59E;

  /* --- Spacing (4px baseline) --- */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;
  --space-10: 40px;
  --space-12: 48px;
  --space-16: 64px;
  --space-20: 80px;
  --space-24: 96px;

  --gutter: 24px;
  --margin: 32px;
  --container-max: 1280px;

  /* --- Borders & Elevation --- */
  --border-default: 1px solid var(--outline-variant);
  --border-accent: 1px solid var(--amber-gold);
  --border-thick: 2px solid var(--international-orange);
  --hard-shadow-offset: 4px;

  /* --- Corner Radii (sharp by default) --- */
  --radius-none: 0px;
  --radius-brand: 50%; /* only for brand marks / avatars */
}

/* ── Light Mode Override ── */
:root[data-theme="light"] {
  --surface: #F8F8F8;
  --surface-dim: #EFEFEF;
  --surface-container-low: #FFFFFF;
  --surface-container: #F2F2F2;
  --surface-container-high: #E8E8E8;
  --on-surface: #1A1A1A;
  --on-surface-variant: #4A3A2D;
  --on-surface-muted: #6B5B4F;
  --primary: #D57800;
  --on-primary: #FFFFFF;
  --fog-blue-ink: var(--fog-blue-deep);
  --fog-blue-rule: var(--fog-blue-deep);
}

/* ── Global body shell — paints surface token in both modes ──
   Baseline for pages without their own body rule (e.g. /venue, /admin).
   index.html overrides via inline <style> using --surface-dim for the
   moodier homepage; that inline rule wins by load-order specificity. */
body {
  background: var(--surface);
  color: var(--on-surface);
  margin: 0;
  -webkit-font-smoothing: antialiased;
}

/* ── Venue-only light surface — warm cream so amber/orange reads as ink ── */
:root[data-theme="light"][data-page="venue"] {
  --surface: #F5F0E7;
  --surface-dim: #ECE5D7;
  --surface-container-low: #FAF6EE;
  --surface-container: #EFE9DC;
  --surface-container-high: #E5DECF;
}

/* ── Semantic Typography ── */
.display-xl {
  font-family: var(--font-display);
  font-size: 84px;
  font-weight: 800;
  line-height: 80px;
  letter-spacing: -0.04em;
}
.headline-lg {
  font-family: var(--font-display);
  font-size: 48px;
  font-weight: 700;
  line-height: 52px;
  letter-spacing: -0.02em;
}
.headline-md {
  font-family: var(--font-display);
  font-size: 32px;
  font-weight: 700;
  line-height: 36px;
}
.body-lg {
  font-family: var(--font-body);
  font-size: 18px;
  font-weight: 400;
  line-height: 28px;
}
.body-md {
  font-family: var(--font-body);
  font-size: 16px;
  font-weight: 400;
  line-height: 24px;
}
.label-bold {
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 700;
  line-height: 16px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* Venue link affordance — event cards link the venue name to /venue/[slug].
   Dotted underline by default (subtle, brand-consistent), solid amber on hover. */
.venue-link {
  transition: color 120ms ease, border-color 120ms ease;
}
.venue-link:hover,
.venue-link:focus-visible {
  color: var(--amber-gold, #D57800);
  border-bottom-color: var(--amber-gold, #D57800);
  border-bottom-style: solid;
}
.venue-link:focus-visible {
  outline: 2px solid var(--amber-gold, #D57800);
  outline-offset: 2px;
  border-radius: 2px;
}

/* Double-ring focus indicator — orange outline + inner surface halo.
   Use on any focusable element whose backdrop (glass, gradient, mixed
   tones) makes the bare 2px orange ring blur into the background. Pair
   with the -thick variant on image/photo backdrops where the 1px halo
   gets visually lost.
   Theme-aware via var(--surface) — dark color on dark theme, cream on
   light. Lives here (not index.html inline) so all four entry points
   (index/venue/admin/flows) pick it up.
   Iris HIGH (2026-05-26). */
.focus-double-ring:focus-visible {
  outline: 2px solid var(--international-orange);
  outline-offset: 3px;
  box-shadow: 0 0 0 1px var(--surface, #121414);
  border-radius: 6px;
}

/* Thick halo variant — for elements sitting on event-card images, dynamic
   gradients, or other busy/high-contrast photo backdrops where the 1px
   inner halo would be lost. Used on ReportButton sitting inside a card. */
.focus-double-ring-thick:focus-visible {
  outline: 2px solid var(--international-orange);
  outline-offset: 3px;
  box-shadow: 0 0 0 2px var(--surface, #121414);
}

/* Windows High Contrast Mode (HCM) strips box-shadow, so the inner halo
   above disappears. Re-paint with system Highlight color + thicker outline
   so HCM users still get a clearly perceivable focus indicator.
   References: WCAG 1.4.11 non-text contrast on system-colored UI. */
@media (forced-colors: active) {
  :focus-visible,
  .focus-double-ring:focus-visible,
  .focus-double-ring-thick:focus-visible {
    outline: 3px solid Highlight;
    outline-offset: 3px;
    box-shadow: none;
  }
}

/* ============================================================
   Side-stripe replacement utilities
   ------------------------------------------------------------
   Per Zora's 2026-05-26 spec, colored `border-left >1px` is an
   absolute-ban AI-aesthetic pattern. Three replacement devices:

     A. Tick marker  — 6×6 filled square via `::before`. Zine-bullet
        energy. Pairs with kicker text. HCM-safe (forced-color-adjust
        auto so it renders as CanvasText square).
     B. Surface wash — `color-mix` tint on the row background. Hover
        lifts tint (6% → 10%) instead of animating border width.
        Pairs with a 1px hairline `border-top` for HCM fallback.
     C. Brutalist offset shadow — `4px 4px 0 0` flat colored shadow.
        Static editorial blocks; matches VenuePage CTA language.
     D. Typography-only — drop the visual marker; let the amber kicker
        do the job. (No utility needed — just don't add a stripe.)

   Lux color math:
     - 6% wash on dark amber: ~ rgba(213,120,0,0.06) — matches the
       pre-existing VEL_AMBER_TINT constant.
     - 10% wash on warm-cream venue surface stays under WCAG 1.4.11
       non-text contrast (decorative-only) and reads as sun-bleached
       newsprint band.
   Iris a11y:
     - Tick squares: full-saturation OKLCH brand tokens, AA-clear
       against both surfaces. `forced-color-adjust: auto` so HCM
       renders them as CanvasText squares.
     - Surface washes: degrade to `transparent` in HCM — that's fine
       because each row also carries `border-top: 1px solid currentColor`
       which HCM preserves, so structure isn't lost.
   ============================================================ */

/* Device A — tick markers. Inline-block so they sit on the baseline
   beside uppercase kickers. Theme tokens already swap correctly so a
   single class works in both modes. */
.tick-marker {
  display: inline-block;
}
.tick-marker::before {
  content: '';
  display: inline-block;
  width: 6px; height: 6px;
  margin-right: 10px;
  vertical-align: 0.08em;
  background: var(--amber-gold);
  forced-color-adjust: auto;
}
.tick-marker--amber::before     { background: var(--amber-gold); }
.tick-marker--eucalyptus::before { background: var(--eucalyptus-green-light); }
.tick-marker--fog::before       { background: var(--fog-blue); }
/* Wider, shorter bar variant for "row is hot/live" — 8×2 stamp. */
.tick-bar--amber::before {
  content: '';
  display: inline-block;
  width: 8px; height: 2px;
  margin-right: 10px;
  vertical-align: 0.35em;
  background: var(--amber-gold);
  forced-color-adjust: auto;
}

/* Device B — tinted surface washes. The `currentColor`-based hairline
   in HCM still draws so row structure survives even when the wash
   drops to transparent. Hover transition is under the 200ms reduced-
   motion threshold so no explicit media query needed. */
.surface-wash--amber-upcoming {
  background: color-mix(in oklch, var(--amber-gold) 6%, transparent);
  transition: background 120ms ease;
}
.surface-wash--amber-upcoming:hover {
  background: color-mix(in oklch, var(--amber-gold) 10%, transparent);
}
.surface-wash--amber-expanded {
  background: color-mix(in oklch, var(--amber-gold) 10%, transparent);
}
/* Past-row surface — quieter than upcoming; signals "spent". */
.surface-wash--amber-past {
  background: color-mix(in oklch, var(--amber-gold) 4%, transparent);
}

/* Device C — brutalist offset shadow. Static blocks only; uses the
   project's existing `--hard-shadow-offset` and amber token so the
   shape reads as a deliberate ink-block, not a drop-shadow. */
.brutalist-shadow {
  box-shadow: var(--hard-shadow-offset) var(--hard-shadow-offset) 0 0 var(--amber-gold);
}

/* Flat category-placeholder surfaces — replaces the diagonal
   `linear-gradient(135deg, …)` overlays on no-poster event cards.
   Same "no AI-aesthetic" family of violation as the side stripes;
   bundled into this pass. OKLCH tints keep each category readable
   in dark and light without per-theme overrides. */
.cat-surface--music     { background: oklch(22% 0.04 60); }
.cat-surface--cards     { background: oklch(22% 0.04 250); }
.cat-surface--art       { background: oklch(22% 0.06 25); }
.cat-surface--food      { background: oklch(22% 0.04 145); }
.cat-surface--nightlife { background: oklch(22% 0.05 310); }
.cat-surface--community { background: oklch(22% 0.02 200); }
:root[data-theme="light"] .cat-surface--music     { background: oklch(88% 0.04 60); }
:root[data-theme="light"] .cat-surface--cards     { background: oklch(88% 0.04 250); }
:root[data-theme="light"] .cat-surface--art       { background: oklch(88% 0.06 25); }
:root[data-theme="light"] .cat-surface--food      { background: oklch(88% 0.04 145); }
:root[data-theme="light"] .cat-surface--nightlife { background: oklch(88% 0.05 310); }
:root[data-theme="light"] .cat-surface--community { background: oklch(88% 0.02 200); }

/* "NO POSTER YET" mono kicker — pairs with the flat surface above.
   Brand-on, mono-cap, dim — reads as zine placeholder, not error. */
.no-poster-kicker {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--on-surface-muted, #A38D7C);
  opacity: 0.7;
}

/* Skip-to-content link — WCAG 2.4.1 bypass.
   Lives here (not inline in index.html) so admin.html, venue.html, flows.html,
   and 404.html all share one rule rather than duplicating per entry point. */
.skip-to-content {
  position: absolute;
  top: -100%;
  left: 16px;
  z-index: 10000;
  padding: 12px 24px;
  background: var(--international-orange);
  color: #fff;
  font-family: var(--font-body), system-ui, sans-serif;
  font-size: 14px;
  font-weight: 700;
  text-decoration: none;
  border-radius: 0 0 8px 8px;
  transition: top 0.2s;
}
.skip-to-content:focus,
.skip-to-content:focus-visible {
  top: 0;
  outline: 2px solid #fff;
  outline-offset: -4px;
}
