/* Zuniq web — design tokens are the ONLY literal source (owner directive:
   design-token boundary). Components consume var() exclusively; the empty
   [data-theme] hook is where a future overhaul re-issues values. */

:root {
  /* canvas + glass surfaces (Obsidian Vector, dark-only by ruling) */
  --canvas: #0b0f17;
  --surface: #0f131c;
  --glass: rgba(15, 23, 42, 0.6);
  --glass-blur: 16px;
  --glass-strong: rgba(18, 24, 38, 0.8);
  --glass-strong-blur: 24px;
  --overlay: rgba(11, 15, 23, 0.72); /* native-<dialog> ::backdrop (e95) */
  --hairline: rgba(255, 255, 255, 0.08);
  --hairline-strong: rgba(255, 255, 255, 0.12);
  --hairline-w: 1px;
  --micro-dot: 1px;
  --board-max: 480px;
  --chip-h: 32px;
  --inset-highlight: inset 0 1px 0 0 rgba(255, 255, 255, 0.2);

  /* players (names/ids live in players.js; these are the accent tokens) */
  --p1: #06b6d4;
  --p2: #a855f7;
  --coral: #f43f5e;            /* error/rejection only, never a player accent */
  --jade: #34d399;             /* success/status only, never a player accent */

  /* grid nodes */
  --node-dim: #334155;
  --node-core: #475569;
  --micro-grid: rgba(51, 65, 85, 0.15);

  /* text */
  --text: #dfe2ef;
  --text-variant: #bcc9cd;
  --text-dim: #94a3b8;

  /* player glows */
  --glow-p1: 0 0 16px rgba(6, 182, 212, 0.4);
  --glow-p2: 0 0 16px rgba(168, 85, 247, 0.4);
  --glow-coral: 0 0 12px rgba(244, 63, 94, 0.35);
  --glow-jade: 0 0 12px rgba(52, 211, 153, 0.35);
  --p1-glow: var(--glow-p1);
  --p2-glow: var(--glow-p2);

  /* type stacks */
  --font-display: "Space Grotesk", "Avenir Next", sans-serif;
  --font-body: "Hanken Grotesk", "Helvetica Neue", sans-serif;
  --font-data: "JetBrains Mono", "SF Mono", monospace;

  /* type scale (mobile) */
  --fs-display: 32px;
  --fs-headline: 18px;
  --fs-body: 14px;
  --fs-data: 13px;
  --fs-data-lg: 16px;
  --fs-label: 10px;
  --fs-zone: 6px;              /* SVG user units inside the 96-unit board viewBox */
  --lh-body: 20px;
  --track-caps: 0.12em;
  --track-wordmark: 0.02em;

  /* help dialog (zuniq-e95) — larger type for a readable popup */
  --fs-help-title: 22px;
  --fs-help-lead: 11px;
  --fs-help-body: 16px;
  --lh-help: 24px;

  /* layout constants */
  --touch: 44px;
  --hud-h: 32px;
  --toast-h: 36px;
  --status-node: 6px;
  --pill-w: 40px;
  --pill-h: 4px;
  --stroke-edge: 1.5px;
  --ghost-dash: 4 3;       /* GapHold preview dash pattern (SVG units) */
  --ghost-opacity: 0.55;   /* GapHold preview opacity */
  --node-radius: 50%;

  /* spacing */
  --space-xs: 4px;
  --space-sm: 8px;
  --space-md: 12px;
  --space-lg: 20px;
  --space-xl: 32px;
  --margin: 16px;

  /* radii */
  --radius-sm: 2px;
  --radius: 4px;
  --radius-md: 6px;
  --radius-lg: 8px;
  --radius-sheet: 28px;

  /* safe areas */
  --safe-top: env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
}

[data-theme] {
  /* intentionally empty: overhaul re-issues values here, one file */
}

/* ------------------------------------------------------------------ fonts */

@font-face {
  font-family: "Space Grotesk";
  font-weight: 500;
  src: url("../assets/fonts/space-grotesk-500.woff2") format("woff2");
}
@font-face {
  font-family: "Space Grotesk";
  font-weight: 700;
  src: url("../assets/fonts/space-grotesk-700.woff2") format("woff2");
}
@font-face {
  font-family: "Hanken Grotesk";
  font-weight: 400;
  src: url("../assets/fonts/hanken-grotesk-400.woff2") format("woff2");
}
@font-face {
  font-family: "Hanken Grotesk";
  font-weight: 500;
  src: url("../assets/fonts/hanken-grotesk-500.woff2") format("woff2");
}
@font-face {
  font-family: "JetBrains Mono";
  font-weight: 400;
  src: url("../assets/fonts/jetbrains-mono-400.woff2") format("woff2");
}
@font-face {
  font-family: "JetBrains Mono";
  font-weight: 700;
  src: url("../assets/fonts/jetbrains-mono-700.woff2") format("woff2");
}

/* ------------------------------------------------------------------ base */

* { box-sizing: border-box; margin: 0; padding: 0; }

html { height: 100%; }

body {
  height: 100dvh;
  display: flex;
  flex-direction: column;
  background:
    radial-gradient(circle at var(--micro-dot) var(--micro-dot), var(--micro-grid) var(--micro-dot), transparent 0) 0 0 / var(--space-lg) var(--space-lg),
    var(--canvas);
  color: var(--text);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  padding-top: var(--safe-top);
  padding-bottom: var(--safe-bottom);
  overflow: hidden;
  overscroll-behavior: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}

/* ------------------------------------------------------------------ HUD */

.hud {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  padding: var(--space-sm) var(--margin);
  background: var(--glass);
  backdrop-filter: blur(var(--glass-blur));
  border-bottom: var(--hairline-w) solid var(--hairline);
}

.hud-wordmark {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--fs-headline);
  letter-spacing: var(--track-wordmark);
  color: var(--text);
}

.hud-turn {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-xs) var(--space-md);
  border-radius: var(--radius);
  border: var(--hairline-w) solid var(--hairline-strong);
  background: var(--glass-strong);
  font-family: var(--font-data);
  font-size: var(--fs-data);
  min-height: var(--hud-h);
}

.hud-turn[data-player="p1"] { color: var(--p1); box-shadow: var(--p1-glow); }
.hud-turn[data-player="p2"] { color: var(--p2); box-shadow: var(--p2-glow); }

.hud-turn .status-node {
  width: var(--status-node);
  height: var(--status-node);
  border-radius: var(--node-radius);
  background: currentColor;
  animation: pulse 1.6s ease-in-out infinite;
}

@keyframes pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.45; transform: scale(0.8); }
}

.hud-counter {
  margin-left: auto;
  font-family: var(--font-data);
  font-size: var(--fs-data);
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
}

/* HUD help link (zuniq-e95): the control-option idiom, shrunk — the one
   fixed UI affordance (outside the descriptor-driven controls mount) */
.hud-help {
  font-family: var(--font-data);
  font-size: var(--fs-data);
  color: var(--text-variant);
  background: transparent;
  border: var(--hairline-w) solid var(--hairline);
  border-radius: var(--radius);
  min-height: var(--chip-h);
  min-width: var(--chip-h);
  padding: var(--space-xs) var(--space-sm);
  cursor: pointer;
}

.hud-help:active {
  color: var(--jade);
  border-color: var(--jade);
  box-shadow: var(--glow-jade);
}

/* ------------------------------------------------------------------ board */

.board-area {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-md) var(--margin);
  min-height: 0;
}

.board-bed {
  width: 100%;
  max-width: var(--board-max);
  aspect-ratio: 1 / 1;
  background: var(--glass);
  backdrop-filter: blur(var(--glass-blur));
  border: var(--hairline-w) solid var(--hairline);
  border-radius: var(--radius-lg);
  padding: var(--space-md);
}

.board-svg {
  width: 100%;
  height: 100%;
  display: block;
  touch-action: none; /* the GapHold gesture owns the board: no pan/zoom */
  cursor: pointer;
}

.board-edge {
  stroke-width: var(--stroke-edge);
  stroke-linecap: round;
}

/* GapHold preview — presentation only, never legality: the engine owns
   rules. Token-only: no literals outside :root. */
.layer-ghost .ghost-edge {
  stroke: var(--text-dim);
  stroke-width: var(--stroke-edge);
  stroke-linecap: round;
  stroke-dasharray: var(--ghost-dash);
  opacity: var(--ghost-opacity);
  pointer-events: none;
}
.board-edge[data-player="p1"] { stroke: var(--p1); }
.board-edge[data-player="p2"] { stroke: var(--p2); }
.board-edge[data-last="true"] { filter: drop-shadow(var(--p1-glow)); }
.board-edge[data-last="true"][data-player="p2"] { filter: drop-shadow(var(--p2-glow)); }

.zone-fill {
  stroke: none;
  opacity: 0.12;
}
.zone-fill[data-player="p1"] { fill: var(--p1); }
.zone-fill[data-player="p2"] { fill: var(--p2); }

.zone-size-label {
  font-family: var(--font-data);
  font-weight: 700;
  font-size: var(--fs-zone);
  fill: var(--text);
  text-anchor: middle;
  dominant-baseline: central;
  paint-order: stroke;
  stroke: var(--canvas);
  stroke-width: var(--space-xs);
  stroke-linejoin: round;
  pointer-events: none;
}

.selected-dot {
  stroke: var(--p1);
  stroke-width: var(--stroke-edge);
  fill: none;
}

.board-dot {
  fill: var(--node-core);
}
.board-dot[data-oop="true"] {
  fill: var(--node-dim);
  opacity: 0.45;
}

/* ------------------------------------------------------------------ toast */

.toast {
  margin: 0 var(--margin) var(--space-sm);
  min-height: var(--toast-h);
  padding: var(--space-sm) var(--space-md);
  border-radius: var(--radius);
  border: var(--hairline-w) solid var(--hairline);
  background: var(--glass-strong);
  font-family: var(--font-data);
  font-size: var(--fs-data);
  color: var(--text-variant);
  white-space: pre-line; /* terminal toast: closure line + game-over line */
  visibility: hidden;
}
.toast[data-show="true"] { visibility: visible; }
/* tone variants: border + glow carry the tone; text stays the default
   foreground (--text-variant) in all tones. info = neutral base above. */
.toast[data-tone="error"] {
  border-color: var(--coral);
  box-shadow: var(--glow-coral);
}
.toast[data-tone="success"] {
  border-color: var(--jade);
  box-shadow: var(--glow-jade);
}

/* ------------------------------------------------------------------ ledger */

.ledger {
  display: flex;
  gap: var(--space-sm);
  padding: var(--space-sm) var(--margin);
  overflow-x: auto;
  scrollbar-width: none;
  min-height: var(--touch);
  align-items: center;
}
.ledger::-webkit-scrollbar { display: none; }

.ledger-chip {
  font-family: var(--font-data);
  font-size: var(--fs-data);
  color: var(--text-variant);
  padding: var(--space-xs) var(--space-sm);
  min-width: var(--touch);
  min-height: var(--chip-h);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius);
  border: var(--hairline-w) solid var(--node-dim);
  background: var(--glass-strong);
  font-variant-numeric: tabular-nums;
}
.ledger-chip[data-flavor="error"] {
  border-color: var(--coral);
  color: var(--coral);
}

/* ------------------------------------------------------------------ sheet */

.sheet {
  border-top: var(--hairline-w) solid var(--hairline-strong);
  border-radius: var(--radius-sheet) var(--radius-sheet) 0 0;
  background: var(--glass);
  backdrop-filter: blur(var(--glass-blur));
  padding: var(--space-sm) var(--margin);
  padding-bottom: calc(var(--space-md) + var(--safe-bottom));
  min-height: var(--touch);
}

.sheet-drag-pill {
  width: var(--pill-w);
  height: var(--pill-h);
  border-radius: var(--radius);
  background: var(--node-dim);
  margin: 0 auto var(--space-sm);
}

.sheet-preview {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-sm);
  font-family: var(--font-data);
  font-size: var(--fs-data);
  color: var(--text-dim);
  min-height: var(--touch);
}
/* ------------------------------------------------- AI controls (zuniq-0je)
   Rendered by controls.js from ONE descriptor array into the single
   #ai-controls mount point. Layout and state live here; the data lives in
   controls.js. Tokens only — no literal colour, spacing or font. */
.controls-mount {
  display: flex;
  gap: var(--space-sm);
  padding: var(--space-sm) var(--margin);
  overflow-x: auto;
  scrollbar-width: none;
}
.controls-mount::-webkit-scrollbar { display: none; }

.control {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-xs) var(--space-sm);
  border: var(--hairline-w) solid var(--hairline);
  border-radius: var(--radius);
  background: var(--glass);
  backdrop-filter: blur(var(--glass-blur));
}

.control-label {
  font-family: var(--font-data);
  font-size: var(--fs-label);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--text-dim);
}

.control-options { display: flex; gap: var(--space-xs); }

.control-option {
  font-family: var(--font-data);
  font-size: var(--fs-data);
  color: var(--text-variant);
  background: transparent;
  border: var(--hairline-w) solid var(--hairline);
  border-radius: var(--radius);
  min-height: var(--chip-h);
  padding: var(--space-xs) var(--space-sm);
  cursor: pointer;
}

/* active/"on" state: jade, never a player accent (owner token ruling) */
.control-option[aria-pressed="true"] {
  color: var(--jade);
  border-color: var(--jade);
  box-shadow: var(--glow-jade);
}

/* the side control carries its seat's own accent (data-accent comes from the
   registry through the descriptor — one rule set, driven by data) */
.control-accented .control-option[aria-pressed="true"][data-accent="p1"] {
  color: var(--p1);
  border-color: var(--p1);
  box-shadow: var(--p1-glow);
}
.control-accented .control-option[aria-pressed="true"][data-accent="p2"] {
  color: var(--p2);
  border-color: var(--p2);
  box-shadow: var(--p2-glow);
}

.control-option:focus-visible {
  outline: var(--hairline-w) solid var(--text);
  outline-offset: var(--space-xs);
}

/* ------------------------------------------------------------------ help
   Quick how-to + win conditions (zuniq-e95): one native <dialog>, top-layer
   (no z-index machinery), glass idioms from the surface/hairline tokens. */
.help-sheet {
  /* CENTER the dialog on both axes: all insets 0 + height fit-content +
     margin auto — deterministic in every engine (rev 2 owner fix). */
  inset: 0;
  margin: auto;
  height: fit-content;
  width: min(88vw, var(--board-max));
  max-height: min(86vh, 720px);
  overflow-y: auto;
  color: var(--text);
  background: var(--glass-strong);
  backdrop-filter: blur(var(--glass-strong-blur));
  border: var(--hairline-w) solid var(--hairline-strong);
  border-radius: var(--radius-sheet);
  padding: var(--space-lg);
  box-shadow: var(--inset-highlight);
}

.help-sheet::backdrop { background: var(--overlay); }

.help-sheet h2 {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--fs-help-title);
  font-weight: 700;
  letter-spacing: var(--track-wordmark);
  color: var(--text);
}

/* gesture demo strip: two dots + the dashed gap + the Tabler hand-click
   glyph — the how-to IS the gesture, shown once before the words */
.help-demo { margin: var(--space-md) 0 0; }

.help-demo-svg {
  display: block;
  width: 100%;
  height: auto;
  color: var(--text-variant);
}

.help-demo-svg .demo-dot { fill: var(--node-core); stroke: none; }

.help-demo-svg .demo-dash {
  stroke: var(--hairline-strong);
  stroke-width: var(--stroke-edge);
  stroke-dasharray: var(--ghost-dash);
}

.help-demo-svg .demo-hand {
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  color: var(--jade);
}

.demo-caption {
  margin: var(--space-xs) 0 0;
  font-family: var(--font-data);
  font-size: var(--fs-label);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--text-dim);
  text-align: center;
}

/* scannable bullets: bold lead on its own line, one plain sentence below */
.help-list {
  margin: var(--space-md) 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: var(--space-sm);
}

.help-list li {
  display: grid;
  gap: 2px;
  grid-template-columns: minmax(var(--touch) / 2, auto) 1fr;
  align-items: baseline;
}

.help-list strong {
  font-family: var(--font-data);
  font-size: var(--fs-help-lead);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--text);
}

.help-list span {
  font-family: var(--font-body);
  font-size: var(--fs-help-body);
  line-height: var(--lh-help);
  color: var(--text-variant);
}

.help-win {
  margin: var(--space-lg) 0 0;
  padding: var(--space-sm) var(--space-md);
  border: var(--hairline-w) solid var(--hairline);
  border-radius: var(--radius);
  font-family: var(--font-data);
  font-size: var(--fs-help-body);
  line-height: var(--lh-help);
  color: var(--jade);
}

.help-close {
  margin-top: var(--space-md);
  width: 100%;
  min-height: var(--touch);
  font-family: var(--font-data);
  font-size: var(--fs-help-body);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--jade);
  background: transparent;
  border: var(--hairline-w) solid var(--jade);
  border-radius: var(--radius);
  cursor: pointer;
}

.help-close:focus-visible {
  outline: var(--hairline-w) solid var(--text);
  outline-offset: var(--space-xs);
}
