/* ============================================================
   2077.us - stylesheet
   Source of truth: design.md (do not introduce values here that
   aren't represented in design.md tokens).
   ============================================================ */

/* ───── Tokens ────────────────────────────────────────────── */
:root {
  /* Surfaces */
  --bg: #000000;
  --on-bg: #F4F4F4;
  --surface: #0A0A0A;
  --surface-bright: #1F1F1F;
  --surface-container-lowest: #050505;
  --surface-container-low: #0F0F0F;
  --surface-container: #141414;
  --surface-container-high: #1A1A1A;
  --surface-container-highest: #222222;
  --surface-variant: #1F1F1F;
  --on-surface: #F4F4F4;
  --on-surface-variant: #9A9A9A;
  --outline: #2E2E2E;
  --outline-variant: #1F1F1F;

  /* Primary - Cyberpunk yellow */
  --primary: #FCEE0A;
  --on-primary: #000000;
  --primary-container: #3D3902;
  --on-primary-container: #FFF833;
  --primary-fixed: #FFF833;
  --primary-fixed-dim: #FCEE0A;
  --inverse-primary: #A89708;

  /* Secondary - Samurai cyan */
  --secondary: #00F0FF;
  --on-secondary: #001F23;
  --secondary-container: #003F47;
  --on-secondary-container: #7FF8FF;

  /* Tertiary / error - Arasaka red */
  --tertiary: #FF003C;
  --on-tertiary: #FFFFFF;
  --tertiary-container: #5C0015;
  --on-tertiary-container: #FF6680;
  --error: #FF003C;

  /* Heatmap ramp */
  --heatmap-empty: #0F0F0F;
  --heatmap-l1: #3D3902;
  --heatmap-l2: #7E7505;
  --heatmap-l3: #BFB008;
  --heatmap-l4: #FCEE0A;
  --heatmap-today: #00F0FF;

  /* Spacing */
  --xs: 4px;
  --sm: 8px;
  --md: 16px;
  --lg: 24px;
  --xl: 32px;
  --2xl: 48px;
  --3xl: 64px;
  --4xl: 96px;
  --5xl: 128px;
  --gutter: 16px;
  --margin-mobile: 24px;
  --margin-desktop: 64px;
  --container-max: 1280px;
  --hero-vmin: 60vh;
  --section-gap: 96px;

  /* Shapes */
  --r-none: 0;
  --r-sm: 2px;
  --r-md: 4px;
  --r-full: 9999px;

  /* Typography */
  --font-display: "Rajdhani", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-body: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, "Cascadia Mono", monospace;

  /* Glow */
  --bloom-yellow: 0 0 24px rgba(252, 238, 10, 0.35);
  --bloom-cyan: 0 0 16px rgba(0, 240, 255, 0.5);
}

/* ───── Reset ─────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
/* Scrollbars hidden, page still scrolls via wheel / touch / keys.
   Reason: the native scrollbar takes ~14 px of real pixels on the
   right of the viewport, which makes any centred max-width
   container sit ~14 px closer to the left edge than to the right
   when measured against the viewport. We cannot keep both
   "symmetric viewport margins" AND "visible scrollbar" without
   reserving scrollbar-gutter on both edges, which leaves an empty
   strip on the left that the user explicitly rejected. Hiding the
   scrollbar is the cleaner solution for this page - there is no
   long-form chrome that needs a position indicator, and the
   timeline / content below the fold makes scrollability obvious. */
html { background: var(--bg); scrollbar-width: none; }
html::-webkit-scrollbar { display: none; }
body { scrollbar-width: none; }
body::-webkit-scrollbar { display: none; }
body {
  background: var(--bg);
  color: var(--on-bg);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.5;
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}
img { display: block; max-width: 100%; }
svg { display: block; }
/* Note: don't apply max-width:100% to <svg> globally. The timeline
   heatmap is much wider than the viewport when laid out horizontally
   and its width attribute encodes the natural size; clamping it to
   100% scales the whole graphic down (height collapses with it). */
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
input, textarea { font: inherit; color: inherit; }
ul, ol { list-style: none; }
a { color: var(--primary); text-decoration: none; transition: color 150ms ease-out; }
a:hover { color: var(--primary-fixed); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 4px; }

/* ───── Focus ring (global) ───────────────────────────────── */
:focus-visible { outline: 2px solid var(--secondary); outline-offset: 2px; }

/* ───── Typography utilities ──────────────────────────────── */
.t-display-xl { font-family: var(--font-mono); font-size: clamp(3.5rem, 11vw, 7rem); font-weight: 700; line-height: 1; letter-spacing: -0.04em; font-variant-numeric: tabular-nums; font-feature-settings: "tnum" on; }
.t-display-lg { font-family: var(--font-display); font-size: clamp(3rem, 8vw, 5.5rem); font-weight: 700; line-height: 0.95; letter-spacing: -0.02em; text-transform: uppercase; }
.t-headline-xl { font-family: var(--font-display); font-size: clamp(2.5rem, 5vw, 4rem); font-weight: 700; line-height: 1; text-transform: uppercase; }
.t-headline-lg { font-family: var(--font-display); font-size: clamp(2rem, 4vw, 3rem); font-weight: 700; line-height: 1.05; text-transform: uppercase; }
.t-headline-md { font-family: var(--font-display); font-size: 2.25rem; font-weight: 600; line-height: 1.1; text-transform: uppercase; letter-spacing: 0.005em; }
.t-title-lg { font-family: var(--font-display); font-size: 1.5rem; font-weight: 600; line-height: 1.2; text-transform: uppercase; letter-spacing: 0.01em; }
.t-title-md { font-family: var(--font-display); font-size: 1.125rem; font-weight: 600; line-height: 1.25; text-transform: uppercase; letter-spacing: 0.01em; }
.t-body-lg { font-family: var(--font-body); font-size: 1.125rem; font-weight: 400; line-height: 1.55; }
.t-body-md { font-family: var(--font-body); font-size: 1rem; font-weight: 400; line-height: 1.5; }
.t-body-sm { font-family: var(--font-body); font-size: 0.875rem; font-weight: 400; line-height: 1.45; }
.t-label-lg { font-family: var(--font-display); font-size: 1rem; font-weight: 600; line-height: 1; letter-spacing: 0.10em; text-transform: uppercase; }
.t-label-md { font-family: var(--font-display); font-size: 0.875rem; font-weight: 600; line-height: 1; letter-spacing: 0.12em; text-transform: uppercase; }
.t-label-sm { font-family: var(--font-display); font-size: 0.75rem; font-weight: 600; line-height: 1; letter-spacing: 0.14em; text-transform: uppercase; }
.t-mono-lg { font-family: var(--font-mono); font-size: 1rem; font-weight: 400; line-height: 1.45; font-feature-settings: "tnum" on; }
.t-mono-md { font-family: var(--font-mono); font-size: 0.875rem; font-weight: 400; line-height: 1.4; font-feature-settings: "tnum" on; }
.t-mono-sm { font-family: var(--font-mono); font-size: 0.75rem; font-weight: 400; line-height: 1.3; letter-spacing: 0.02em; font-feature-settings: "tnum" on; }

/* ───── Layout shell ──────────────────────────────────────── */
.container { max-width: var(--container-max); margin-inline: auto; padding-inline: var(--margin-mobile); }
@media (min-width: 1024px) { .container { padding-inline: var(--margin-desktop); } }

.section { padding-block: var(--section-gap); border-top: 1px solid var(--outline-variant); }
.section-head { display: flex; flex-direction: column; gap: var(--sm); margin-bottom: var(--xl); }
.section-head .num { color: var(--primary); }
.section-head .title { color: var(--on-surface); }
.section-head .desc { color: var(--on-surface-variant); max-width: 60ch; }

.divider { height: 1px; background: var(--outline-variant); border: 0; margin-block: var(--md); }

/* ───── Brand mark, live dot, edgerunner badge ────────────── */
/* The page has no topbar; the brand mark, live dot, and EDGERUNNER
   badge live inside the hero's left content column. */
.live-dot { display: inline-block; width: 8px; height: 8px; background: var(--secondary); box-shadow: var(--bloom-cyan); animation: pulse 2s ease-in-out infinite; flex-shrink: 0; }
/* The global a / a:hover rules try to push the link colour to
   primary / primary-fixed. On the yellow hero column that means
   "yellow on yellow" - i.e. invisible. Lock the brand colour to
   on-primary across every interactive state, beating the global
   anchor rules with both higher specificity and explicit
   declarations on each state. */
.hero-content .hero-brand,
.hero-content .hero-brand:link,
.hero-content .hero-brand:visited,
.hero-content .hero-brand:hover,
.hero-content .hero-brand:focus,
.hero-content .hero-brand:active { color: var(--on-primary); text-decoration: none; }
.hero-brand { display: inline-flex; align-items: center; gap: 1px; text-transform: uppercase; transition: opacity 150ms ease-out; }
.hero-brand:hover { opacity: 0.85; }
.hero-content .hero-brand .dot { color: var(--on-primary); }
.edgerunner-badge { display: none; padding: 4px 10px; background: var(--on-primary); color: var(--primary); }
.edgerunner-badge.is-active { display: inline-flex; }

/* ───── Hero ──────────────────────────────────────────────── */
/* Bleed-bg + bounded-content pattern. The hero is a positioning
   ancestor that holds three layers:
     1. .hero-bg-left      - yellow fill, full-bleed left half on lg+
     2. .hero-video-wrap   - video, full-bleed right half on lg+
     3. .hero-grid         - bounded to container-max, holds the content
   On lg+ both bleed layers cover their viewport halves; the seam
   between them falls at viewport-centre, which is also the centre
   of the bounded grid (because the grid is centred). On mobile the
   bleed layers collapse: the video moves into normal flow above
   the content as a 16:9 banner, the yellow drops back onto
   .hero-content's own background, and the layout stacks. */
.hero {
  width: 100%;
  min-height: var(--hero-vmin);
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.hero-bg-left {
  display: none;
}
@media (min-width: 1024px) {
  .hero-bg-left {
    display: block;
    position: absolute;
    top: 0; left: 0; bottom: 0;
    width: 50%;
    background: var(--primary);
    z-index: 0;
  }
  /* Scanlines painted on the full-bleed yellow layer (not on the
     bounded content column) so they cover the entire left half of
     the hero, including the strip between the viewport edge and
     where the bounded content actually starts. Same 1 px / 3 px
     period as the video-side scanlines, same top: 0 origin, so
     the lines align across the seam at viewport-centre. */
  .hero-bg-left::before {
    content: "";
    position: absolute; inset: 0; pointer-events: none;
    background-image: repeating-linear-gradient(
      to bottom,
      rgba(0, 0, 0, 0.05) 0 1px,
      transparent 1px 3px
    );
  }
}
.hero-grid {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: var(--container-max);
  display: grid;
  grid-template-columns: 1fr;
  min-height: var(--hero-vmin);
}
@media (min-width: 1024px) {
  .hero-grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  }
}

/* Left content column - solid yellow brand statement, all text and
   numbers inverted to on-primary (black). The single exception to
   the project-wide "yellow is scarce" rule. On lg+ the yellow comes
   from the full-bleed .hero-bg-left layer, so .hero-content itself
   is transparent. On mobile the bleed layer is hidden and the
   yellow is painted directly onto .hero-content. Generous padding
   on the outer/top/bottom edges so the content breathes; tighter
   on the inner edge where it meets the video column. */
.hero-content {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: var(--3xl) var(--lg);
  position: relative;
  background: var(--primary);
  color: var(--on-primary);
}
@media (min-width: 768px) {
  .hero-content { padding: var(--3xl) var(--2xl); }
}
@media (min-width: 1024px) {
  .hero-content {
    padding: var(--4xl) var(--xl) var(--4xl) var(--4xl);
    background: transparent;
  }
}
.hero-content-inner {
  width: 100%;
  position: relative;
  z-index: 1;
}
/* Scanline overlay flipped to dark stripes via multiply so it stays
   visible on the yellow fill. */
.hero-content::before {
  content: "";
  position: absolute; inset: 0; pointer-events: none;
  background-image: repeating-linear-gradient(to bottom, rgba(0, 0, 0, 0.05) 0 1px, transparent 1px 3px);
  mix-blend-mode: multiply;
}

/* All text inside the hero-content column inherits black via the
   color: var(--on-primary) above; the per-element overrides here
   tune contrast (full black for headings/values, ~65 % alpha for
   secondary lines). */
/* Brand row: 2077.us mark on the left, EDGERUNNER unlock on the right
   (it just stays hidden until the konami sequence fires). Sits at the
   top of the yellow column; replaces the deleted topbar. */
.hero-brand-row { display: flex; align-items: center; justify-content: space-between; gap: var(--md); margin-bottom: var(--xl); }

.hero-eyebrow { color: rgba(0, 0, 0, 0.7); margin-bottom: var(--md); display: inline-flex; align-items: center; gap: var(--sm); }
.hero-content .live-dot { background: var(--on-primary); box-shadow: none; }
.hero-headline { color: var(--on-primary); }
.hero-headline .accent { color: var(--on-primary); }
.hero-perspective-badge { display: none; align-items: center; gap: var(--sm); margin-top: var(--md); padding: 8px 12px; background: var(--on-primary); color: var(--primary); }
.hero-perspective-badge.is-active { display: inline-flex; }
.hero-perspective-badge button { color: var(--primary); padding-left: var(--sm); border-left: 1px solid rgba(252, 238, 10, 0.3); }
.hero-perspective-badge button:hover { color: var(--primary-fixed); }

/* minmax(0, 1fr) instead of plain 1fr so the column width is
   capped at half of the parent and the long value ("18,506" wide)
   cannot push past it into the right column. The clamp on .value is
   sized so the widest value still fits in that capped slot. */
.counters { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--3xl); margin-block: var(--xl); }
@media (min-width: 768px) { .counters { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--2xl); } }
.counter { display: flex; flex-direction: column; gap: var(--md); min-width: 0; }
.counter .label { color: rgba(0, 0, 0, 0.7); }
/* Counter values: black on yellow. The yellow bloom drops here
   because it would be invisible against the same colour. */
.counter .value {
  color: var(--on-primary);
  text-shadow: none;
  font-variant-numeric: tabular-nums;
  font-size: clamp(2.5rem, 7vw, 4.5rem);
  min-width: 0;
}
@media (min-width: 1024px) {
  .counter .value { font-size: clamp(2.5rem, 4vw, 4rem); }
}
.counter .subtick { color: rgba(0, 0, 0, 0.65); margin-top: -0.25em; }
.counter .caption { color: rgba(0, 0, 0, 0.65); }

.hero-foot { display: flex; gap: var(--md); align-items: baseline; flex-wrap: wrap; color: rgba(0, 0, 0, 0.65); margin-top: var(--xl); }

/* Hero video wrap - ambient looping video, decorative (aria-hidden).
   On lg+ this is a full-bleed right half of the viewport, absolutely
   positioned beside (not inside) the bounded content grid. On mobile
   it sits in normal flow above the content as a 16:9 banner.
   Pointer-events on the overlays are off so any incidental cursor
   interaction passes through. */
.hero-video-wrap {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: var(--bg);
  z-index: 0;
}
@media (min-width: 1024px) {
  .hero-video-wrap {
    position: absolute;
    top: 0;
    right: 0;
    width: 50%;
    height: 100%;
    aspect-ratio: auto;
  }
}
.hero-video-wrap video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Anchor the video to its right edge: the cover-fit cropping
     happens on the left edge instead of the right, and that left
     edge sits next to the yellow seam where it isn't read as
     "lost frame". The right side of the video is preserved. */
  object-position: right center;
  display: block;
}
/* Scanline overlay over the video, mirroring the dark stripes on
   the yellow column. Same 1 px / 3 px period and same origin
   (top of the hero), so the lines align across the seam. Yellow
   tint at low alpha so the stripes read on the dark video. */
.hero-video-wrap::before {
  content: "";
  position: absolute; inset: 0; pointer-events: none;
  z-index: 1;
  background-image: repeating-linear-gradient(
    to bottom,
    rgba(252, 238, 10, 0.12) 0 1px,
    transparent 1px 3px
  );
}
.hero-video-wrap::after {
  content: "";
  position: absolute; inset: 0; pointer-events: none;
  /* subtle top/bottom vignette so the raw video edges feel framed */
  background: linear-gradient(
    to bottom,
    rgba(0, 0, 0, 0.30) 0%,
    transparent 22%,
    transparent 78%,
    rgba(0, 0, 0, 0.30) 100%
  );
}

/* ───── Stats strip ───────────────────────────────────────── */
.stats-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--md); }
@media (min-width: 768px) { .stats-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 1024px) { .stats-grid { grid-template-columns: repeat(6, minmax(0, 1fr)); } }
.stat { min-width: 0; }
.stat .stat-value { min-width: 0; overflow-wrap: anywhere; }
.stat { background: var(--surface); padding: var(--lg); display: flex; flex-direction: column; gap: var(--sm); }
.stat .stat-label { color: var(--on-surface-variant); }
.stat .stat-value { color: var(--on-surface); font-family: var(--font-display); font-size: clamp(1.75rem, 3.2vw, 2.5rem); font-weight: 700; line-height: 1; letter-spacing: -0.01em; font-variant-numeric: tabular-nums; }
.stat .stat-caption { color: var(--on-surface-variant); }

/* ───── Timeline + heatmap + lore ─────────────────────────── */
.section--timeline { padding-block: var(--4xl) var(--5xl); }
.section-head--centered { text-align: center; align-items: center; max-width: 720px; margin-inline: auto; margin-bottom: var(--3xl); }
.section-head--centered .desc { margin-inline: auto; }

.timeline-wrap { display: flex; flex-direction: column; gap: var(--lg); width: 100%; }
.heatmap-meta { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: var(--md); color: var(--on-surface-variant); width: 100%; }
.heatmap-meta-left { display: inline-flex; align-items: center; gap: var(--md); flex-wrap: wrap; }
.heatmap-meta--top { padding-bottom: var(--xs); }
.heatmap-meta--bottom { padding-top: var(--xs); border-top: 1px solid var(--outline-variant); }
.heatmap-legend { display: inline-flex; align-items: center; gap: var(--sm); flex-wrap: wrap; max-width: 100%; }
.heatmap-legend .sw { width: 12px; height: 12px; border-radius: var(--r-sm); flex-shrink: 0; }
.heatmap-legend .sw-today { box-shadow: var(--bloom-cyan); }
.heatmap-legend .sw-ring { background: transparent; box-shadow: inset 0 0 0 1.5px var(--primary); }
.heatmap-legend .sw-ring--fiction { box-shadow: inset 0 0 0 1.5px var(--secondary); }

/* Continuous, full-width grid. No internal scroll - the page itself
   does the scrolling and the timeline is the spine of the document.
   Generous internal padding so the grid never feels cramped against
   the legend above or the next section below. */
.heatmap-scroll {
  width: 100%;
  position: relative;
  overflow: visible;
  padding-block: var(--xl);
}
/* overflow: visible - milestone rings stick 1.5 px outside their cell on
   every side, and row-0 tags float a few px above their cell row; without
   this the SVG's default overflow:hidden clips both at the viewport edge. */
.heatmap-svg { display: block; overflow: visible; }
/* Cell fill is assigned via class, not the SVG fill attribute, so
   the camera-reflection rule below can override it cleanly. */
.heatmap-svg rect.cell { transition: fill 150ms ease-out; cursor: pointer; fill: var(--heatmap-empty); }
.heatmap-svg rect.cell.is-past { fill: var(--heatmap-l4); }
.heatmap-svg rect.cell.is-today { fill: var(--heatmap-today); animation: pulse 2s ease-in-out infinite; }
.heatmap-svg rect.cell.is-future { fill: var(--heatmap-empty); }
.heatmap-svg rect.cell:hover { fill: var(--primary-fixed); }
.heatmap-svg rect.cell.is-perspective { stroke: var(--primary); stroke-width: 2; }

/* Milestone rings - drawn in a non-interactive layer above cells so the
   cell underneath still owns hover/click. */
.heatmap-svg [data-layer="rings"] { pointer-events: none; }
.heatmap-svg .ring { fill: none; stroke: var(--primary); stroke-width: 1.4; }
.heatmap-svg .ring.is-fiction { stroke: var(--secondary); }
.heatmap-svg .ring.is-both { stroke: var(--primary); stroke-width: 1.6; stroke-dasharray: 2 2; }

/* Annotation layer - pointer-transparent so cells stay hover-able as
   tags pass over them; tags slide horizontally away from the cursor. */
.heatmap-svg .ann-layer { pointer-events: none; }
.heatmap-svg .ann { transition: transform 140ms cubic-bezier(.22, 1, .36, 1); }
.heatmap-svg .ann-line {
  stroke: var(--primary);
  stroke-width: 1;
  opacity: 0.55;
  transition: x2 140ms cubic-bezier(.22, 1, .36, 1);
}
.heatmap-svg .ann-line.is-fiction { stroke: var(--secondary); }
.heatmap-svg .ann-bg { fill: var(--surface-container-highest); stroke: var(--primary); stroke-width: 1; }
.heatmap-svg .ann-bg.is-fiction { stroke: var(--secondary); }
.heatmap-svg .ann-text {
  font-family: var(--font-display);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  fill: var(--primary);
}
.heatmap-svg .ann-text.is-fiction { fill: var(--secondary); }

/* ───── Camera reflection toggle + overlay ────────────────── */
.camera-toggle {
  display: inline-flex; align-items: center; gap: var(--xs);
  padding: 6px 12px;
  background: transparent;
  color: var(--on-surface-variant);
  box-shadow: inset 0 0 0 1px var(--outline);
  cursor: pointer;
  transition: background-color 150ms ease-out, color 150ms ease-out, box-shadow 150ms ease-out;
}
.camera-toggle:hover { color: var(--primary); box-shadow: inset 0 0 0 1px var(--primary); }
.camera-toggle .cam-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--on-surface-variant);
  transition: background 150ms ease-out, box-shadow 150ms ease-out;
}
.camera-toggle:hover .cam-dot { background: var(--primary); }
.camera-toggle[aria-pressed="true"] {
  background: var(--secondary); color: var(--on-secondary);
  box-shadow: inset 0 0 0 1px var(--secondary), var(--bloom-cyan);
}
.camera-toggle[aria-pressed="true"] .cam-dot {
  background: var(--on-secondary);
  animation: pulse 2s ease-in-out infinite;
}
.camera-toggle[disabled] { opacity: 0.5; cursor: not-allowed; }

/* Camera reflection: the <video> is a top-level element (sibling of
   <main>) positioned `fixed` against the viewport. It does NOT
   scroll with the page, so as the heatmap cells move under it, each
   cell catches a different region of the live frame - the chrome
   reflects the room while the surface moves, not the other way
   round. Only displayed while the timeline section is on-screen
   (.is-visible toggled by IntersectionObserver) AND the user has
   activated the CAM toggle (.is-active). Both classes required. */
.heatmap-cam-fixed {
  position: fixed;
  inset: 0;
  width: 100vw;
  height: 100vh;
  object-fit: cover;
  pointer-events: none;
  z-index: 5;
  opacity: 0.15;
  transform: scaleX(-1);
  display: none;
}
.heatmap-cam-fixed.is-active.is-visible { display: block; }

/* ───── Your-wait ─────────────────────────────────────────── */
.your-wait { background: var(--surface); padding: var(--xl); max-width: 720px; margin-inline: auto; position: relative; }
.your-wait .dismiss { position: absolute; top: var(--md); right: var(--md); width: 32px; height: 32px; display: inline-flex; align-items: center; justify-content: center; color: var(--on-surface-variant); transition: color 150ms ease-out; }
.your-wait .dismiss:hover { color: var(--primary); }
.your-wait .field { margin-block: var(--md); }
.your-wait-output { display: none; flex-direction: column; gap: var(--sm); margin-top: var(--md); padding-top: var(--md); border-top: 1px solid var(--outline-variant); }
.your-wait-output.is-active { display: flex; }
.your-wait-output p { color: var(--on-surface); }
.your-wait-output strong { color: var(--primary); font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-weight: 700; }

/* ───── Quote ticker ──────────────────────────────────────── */
/* Same width truth as every other section: bounded to container-max
   with the standard inline padding. */
.quote {
  text-align: center;
  padding: var(--3xl) var(--margin-mobile);
  max-width: var(--container-max);
  margin-inline: auto;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--md);
  flex-wrap: wrap;
}
@media (min-width: 1024px) {
  .quote { padding-inline: var(--margin-desktop); }
}
.quote-text { color: var(--on-surface); transition: opacity 200ms ease-out, color 200ms ease-out; min-height: 1.5em; }
.quote-text.is-glitching { color: var(--secondary); opacity: 0.6; }
.quote-reroll { width: 32px; height: 32px; display: inline-flex; align-items: center; justify-content: center; color: var(--on-surface-variant); transition: color 150ms ease-out, transform 150ms ease-out; }
.quote-reroll:hover { color: var(--primary); transform: rotate(60deg); }

/* ───── Footer ────────────────────────────────────────────── */
footer { padding-block: var(--xl); border-top: 1px solid var(--outline-variant); color: var(--on-surface-variant); }
footer .container { display: grid; grid-template-columns: 1fr; gap: var(--md); align-items: center; }
@media (min-width: 768px) { footer .container { grid-template-columns: 1fr auto 1fr; } }
.footer-credit { color: var(--on-surface-variant); }
.footer-share { justify-self: center; }
.footer-by { justify-self: end; }
@media (max-width: 767px) { .footer-share, .footer-by { justify-self: start; } }

/* ───── Components ────────────────────────────────────────── */
/* Buttons */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: var(--sm); height: 48px; padding: 0 32px; border-radius: var(--r-none); transition: background-color 150ms ease-out, color 150ms ease-out; }
.btn--primary { background: var(--primary); color: var(--on-primary); }
.btn--primary:hover { background: var(--primary-fixed); }
.btn--primary:active { background: var(--primary-fixed-dim); }
.btn--primary[disabled] { background: var(--surface-container-high); color: var(--on-surface-variant); cursor: not-allowed; }
.btn--secondary { background: transparent; color: var(--primary); box-shadow: inset 0 0 0 1px var(--primary); }
.btn--secondary:hover { background: var(--primary); color: var(--on-primary); }
.btn--ghost { background: transparent; color: var(--on-surface); height: 40px; padding: 0 24px; }
.btn--ghost:hover { background: var(--surface-container-high); color: var(--primary); }
.btn--sm { height: 32px; padding: 0 20px; }
.btn-icon { display: inline-flex; align-items: center; justify-content: center; width: 40px; height: 40px; color: var(--on-surface); transition: background-color 150ms ease-out, color 150ms ease-out; }
.btn-icon:hover { background: var(--surface-container-high); color: var(--primary); }

/* Badges */
.badge { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px; background: var(--surface-container-high); color: var(--primary); border-radius: var(--r-none); }
.badge--live { background: var(--secondary); color: var(--on-secondary); }

/* Inputs */
.field { display: flex; flex-direction: column; gap: var(--xs); }
.field-label { color: var(--on-surface-variant); }
.field-input { background: var(--surface-container-lowest); color: var(--on-surface); height: 48px; padding: 0 16px; border: 0; border-bottom: 1px solid var(--outline-variant); border-radius: var(--r-none); font-family: var(--font-body); font-size: 1rem; transition: background-color 150ms ease-out, border-color 150ms ease-out; }
.field-input::selection { background: var(--primary); color: var(--on-primary); }
.field-input:focus { outline: 0; background: var(--surface-container-low); border-bottom-color: var(--outline); border-bottom-width: 2px; }
.field-helper { color: var(--on-surface-variant); }

/* Tooltip (heatmap + lore) */
.tooltip { position: absolute; pointer-events: none; background: var(--surface-container-highest); color: var(--on-surface); padding: 8px 12px; border-radius: var(--r-none); white-space: pre-line; opacity: 0; transform: translate(-50%, calc(-100% - 12px)); transition: opacity 100ms ease-out; z-index: 50; max-width: min(90vw, 480px); }
.tooltip.is-visible { opacity: 1; }
.tooltip .pin-type { color: var(--on-surface-variant); }

/* Modal */
.modal-overlay { position: fixed; inset: 0; z-index: 100; display: none; align-items: center; justify-content: center; background: rgba(0, 0, 0, 0.85); padding: var(--md); }
.modal-overlay.is-open { display: flex; }
.modal { background: var(--surface-container); padding: var(--xl); max-width: 560px; width: 100%; display: flex; flex-direction: column; gap: var(--lg); }
.modal-head { display: flex; justify-content: space-between; align-items: center; gap: var(--md); }
.modal-head h2 { color: var(--on-surface); }
.modal-row { display: flex; gap: var(--sm); align-items: center; }
.modal-row .field-input { flex: 1; }
.modal-tweet { background: var(--surface-container-low); padding: var(--md); color: var(--on-surface); cursor: pointer; }
.modal-tweet:hover { background: var(--surface-container-high); color: var(--primary); }

/* Toast */
.toast { position: fixed; top: var(--xl); left: 50%; transform: translateX(-50%); z-index: 90; background: var(--surface-container-highest); color: var(--on-surface); padding: 12px 16px; opacity: 0; pointer-events: none; transition: opacity 200ms ease-out; box-shadow: var(--bloom-cyan); }
.toast.is-visible { opacity: 1; }

/* ───── Animations ────────────────────────────────────────── */
@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.55; }
}
@keyframes rgb-glitch {
  0%, 100% { text-shadow: none; transform: translate(0); }
  20% { text-shadow: 2px 0 var(--tertiary), -2px 0 var(--secondary); transform: translate(-1px, 0); }
  40% { text-shadow: -2px 0 var(--tertiary), 2px 0 var(--secondary); transform: translate(1px, 0); }
  60% { text-shadow: 2px 1px var(--tertiary), -2px -1px var(--secondary); transform: translate(0, 1px); }
  80% { text-shadow: -2px -1px var(--tertiary), 2px 1px var(--secondary); transform: translate(0, -1px); }
}
.is-glitching { animation: rgb-glitch 200ms ease-in-out 1; }

/* ───── Reduced motion ────────────────────────────────────── */
@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;
  }
  .hero::before { display: none; }
  .live-dot { animation: none; opacity: 1; }
  .heatmap-svg rect.cell.is-today { animation: none; }
}

/* ───── Utilities ─────────────────────────────────────────── */
.visually-hidden { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
