/* ============================================================
   Tic Tac Toe — "Executive Kinetic" design system
   Tokens transcribed from design/DESIGN.md. Depth comes from
   tonal layers + 1px outlines only: no glows, no drop shadows.
   ============================================================ */

:root {
  color-scheme: dark;

  /* surfaces */
  --surface: #0b1326;
  --surface-container-lowest: #060e20;
  --surface-container-low: #131b2e;
  --surface-container: #171f33;
  --surface-container-high: #222a3d;
  --surface-variant: #2d3449;

  /* content */
  --on-surface: #dae2fd;
  --on-surface-variant: #c3c6d7;
  --outline: #8d90a0;
  --outline-variant: #434655;
  --outline-faint: rgba(67, 70, 85, 0.5);

  /* accents */
  --primary: #b4c5ff;
  --primary-container: #2563eb;
  --primary-hover: #1d55d0;
  --on-primary-container: #eeefff;
  --secondary-container: #94a3b8;
  --on-secondary-container: #0b1c30;
  --error: #ffb4ab;

  /* tints and scrims */
  --primary-tint: rgba(37, 99, 235, 0.12);
  --primary-tint-border: rgba(37, 99, 235, 0.35);
  --secondary-tint: rgba(148, 163, 184, 0.12);
  --secondary-tint-border: rgba(148, 163, 184, 0.35);
  --ghost-x: rgba(37, 99, 235, 0.28);
  --ghost-o: rgba(148, 163, 184, 0.28);
  --scrim: rgba(6, 14, 32, 0.5);
  --scrim-strong: rgba(6, 14, 32, 0.75);

  /* type */
  --font-body: "Geist", "Segoe UI", system-ui, -apple-system, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, "Cascadia Mono", Consolas, monospace;

  /* rhythm (4px base) */
  --space-xs: 8px;
  --space-sm: 16px;
  --space-md: 24px;
  --space-lg: 40px;

  /* shape */
  --radius: 4px;
  --radius-lg: 8px;
  --radius-pill: 9999px;

  --transition: 180ms cubic-bezier(0.4, 0, 0.2, 1);

  /* Layout scale. Both grow with the viewport in the responsive block at the
     foot of this file, so every screen gets one column of a comfortable
     reading width rather than a phone layout stretched across a monitor. */
  --page-max: 500px;
  --shell-max: 500px;
  --board-max: 400px;
  /* Vertical room the board must leave for the top bar, scoreboard, tally and
     buttons. Layouts that stack less below the board lower it. */
  --board-reserve: 330px;
}

/* ── Light theme ───────────────────────────────────────────────
   Same Executive Kinetic discipline inverted: tonal layers and 1px
   outlines, no shadows or glows. The brand blue #2563EB is unchanged;
   accents that sit on light surfaces darken so they keep AA contrast. */
:root[data-theme="light"] {
  color-scheme: light;

  --surface: #f1f5f9;
  --surface-container-lowest: #ffffff;
  --surface-container-low: #f8fafc;
  --surface-container: #ffffff;
  --surface-container-high: #e8edf4;
  --surface-variant: #e2e8f0;

  --on-surface: #0f172a;
  --on-surface-variant: #475569;
  --outline: #94a3b8;
  --outline-variant: #cbd5e1;
  --outline-faint: rgba(148, 163, 184, 0.45);

  --primary: #1d4ed8;
  --primary-container: #2563eb;
  --primary-hover: #1a4bc4;
  --on-primary-container: #ffffff;
  --secondary-container: #64748b;
  --on-secondary-container: #ffffff;
  --error: #b3261e;

  --primary-tint: rgba(37, 99, 235, 0.09);
  --primary-tint-border: rgba(37, 99, 235, 0.28);
  --secondary-tint: rgba(100, 116, 139, 0.1);
  --secondary-tint-border: rgba(100, 116, 139, 0.3);
  --ghost-x: rgba(37, 99, 235, 0.22);
  --ghost-o: rgba(100, 116, 139, 0.25);
  --scrim: rgba(241, 245, 249, 0.55);
  --scrim-strong: rgba(15, 23, 42, 0.45);
}

*, *::before, *::after { box-sizing: border-box; }

/* The UA rule for [hidden] is `display: none` at zero specificity, so any
   component class that sets `display` would beat it. Everything here toggles
   visibility through the hidden attribute, so make it win outright. */
[hidden] { display: none !important; }

html, body { min-height: 100%; }
/* dvh tracks the address bar as it hides; the 100% above is the fallback. */
@supports (height: 100dvh) { body { min-height: 100dvh; } }

body {
  margin: 0;
  background-color: var(--surface);
  color: var(--on-surface);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 24px;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  display: flex;
  flex-direction: column;
}

button { font: inherit; color: inherit; }

button, summary, [role="button"] {
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}

::selection { background: var(--primary-container); color: var(--on-primary-container); }

:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ────────────────  top bar  ──────────────── */

.topbar {
  width: 100%;
  max-width: var(--page-max);
  margin: 0 auto;
  padding: var(--space-sm) var(--space-md);
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.brand {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  font-size: 24px;
  font-weight: 700;
  letter-spacing: -0.02em;
}

.brand__glyph {
  width: 26px; height: 26px;
  stroke: var(--primary-container);
  stroke-width: 2;
  stroke-linecap: round;
  fill: none;
}

.icon-btn {
  width: 40px; height: 40px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--on-surface-variant);
  cursor: pointer;
  transition: color var(--transition), background-color var(--transition);
}

.icon-btn svg {
  width: 20px; height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.icon-btn:hover { color: var(--primary); background: var(--surface-container); }

.topbar__actions { display: flex; align-items: center; gap: 4px; }

/* The theme button carries both icons and shows the one you'd switch TO. */
:root[data-theme="dark"] .icon--moon,
:root[data-theme="light"] .icon--sun { display: none; }

/* ────────────────  layout  ──────────────── */

.shell {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-md) var(--space-sm) var(--space-lg);
  padding-left: max(var(--space-sm), env(safe-area-inset-left));
  padding-right: max(var(--space-sm), env(safe-area-inset-right));
  padding-bottom: max(var(--space-lg), env(safe-area-inset-bottom));
}

/* The view is the rail every screen shares; the stack is the reading column
   inside it. Below the desktop breakpoint the two are the same width, so this
   only shows up as one consistent left edge on large screens. */
.view { width: 100%; max-width: var(--page-max); margin: 0 auto; }

.stack {
  width: 100%;
  max-width: var(--shell-max);
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

.panel {
  background: var(--surface-container);
  border: 1px solid var(--outline-variant);
  border-radius: var(--radius-lg);
}

/* ────────────────  home  ──────────────── */

.hero { display: flex; flex-direction: column; gap: var(--space-xs); }

.eyebrow {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 16px;
  font-weight: 500;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--primary);
}

.hero__title {
  margin: 0;
  font-size: 32px;
  line-height: 40px;
  font-weight: 700;
  letter-spacing: -0.02em;
}

.hero__sub {
  margin: 0;
  color: var(--on-surface-variant);
  font-size: 16px;
}

/* ── section headings (Choose a grid / Mode) ── */

.section-head { display: flex; align-items: center; gap: var(--space-sm); }

.section-head__title {
  margin: 0;
  font-size: 18px;
  font-weight: 600;
  letter-spacing: -0.01em;
  white-space: nowrap;
}

.section-head::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--outline-variant);
}

/* ── grid size chooser ── */

.size-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-xs); }

.size-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-xs);
  padding: 12px;
  background: var(--surface-container);
  border: 1px solid var(--outline-variant);
  border-radius: var(--radius-lg);
  cursor: pointer;
  transition: background-color var(--transition), border-color var(--transition);
}

.size-card:hover { background: var(--surface-container-high); border-color: var(--outline); }

.size-card[aria-checked="true"] {
  background: var(--primary-container);
  border-color: var(--primary-container);
  color: var(--on-primary-container);
}

.size-card__title {
  font-family: var(--font-mono);
  font-size: 16px;
  font-weight: 700;
  letter-spacing: 0.02em;
}

/* Cell count comes from --cells, set in ui.js when the preview is built. */
.size-card__preview {
  display: grid;
  grid-template-columns: repeat(var(--cells, 3), 1fr);
  gap: 2px;
  width: 100%;
  max-width: 76px;
  aspect-ratio: 1 / 1;
}

.size-card__cell {
  border: 1px solid var(--outline);
  border-radius: 1px;
  background: transparent;
}

.size-card[aria-checked="true"] .size-card__cell { border-color: var(--on-primary-container); }

.size-card__rule {
  font-family: var(--font-mono);
  font-size: 11px;
  line-height: 14px;
  letter-spacing: 0.04em;
  color: var(--on-surface-variant);
  text-align: center;
}

.size-card[aria-checked="true"] .size-card__rule { color: var(--on-primary-container); opacity: 0.85; }


.mode-grid { display: grid; gap: var(--space-sm); }

.mode-card {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-md);
  text-align: left;
  background: var(--surface-container);
  border: 1px solid var(--outline-variant);
  border-left: 4px solid var(--outline-variant);
  border-radius: var(--radius-lg);
  cursor: pointer;
  transition: background-color var(--transition), border-color var(--transition);
}

.mode-card:hover { background: var(--surface-container-high); border-color: var(--outline); }

.mode-card[aria-checked="true"] {
  border-color: var(--outline-variant);
  border-left-color: var(--primary-container);
  background: var(--surface-container-high);
}

.mode-card__icon {
  flex: 0 0 auto;
  width: 44px; height: 44px;
  display: grid;
  place-items: center;
  border-radius: var(--radius);
  background: var(--surface-container-lowest);
  border: 1px solid var(--outline-variant);
  color: var(--on-surface-variant);
}

.mode-card[aria-checked="true"] .mode-card__icon { color: var(--primary); }

.mode-card__icon svg {
  width: 24px; height: 24px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.mode-card__body { display: flex; flex-direction: column; }
.mode-card__title { font-size: 18px; font-weight: 600; }
.mode-card__desc { font-family: var(--font-mono); font-size: 12px; line-height: 16px; color: var(--on-surface-variant); }

.option-panel {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  padding: var(--space-md);
  background: var(--surface-container-low);
  border: 1px solid var(--outline-variant);
  border-radius: var(--radius-lg);
}

.option-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  flex-wrap: wrap;
}

.option-row__label {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--on-surface-variant);
}

.segmented {
  display: flex;
  padding: 2px;
  gap: 2px;
  background: var(--surface-container-lowest);
  border: 1px solid var(--outline-variant);
  border-radius: var(--radius);
}

.segmented button {
  padding: 6px 12px;
  min-height: 32px;
  border: 0;
  border-radius: 2px;
  background: transparent;
  color: var(--on-surface-variant);
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.05em;
  cursor: pointer;
  transition: background-color var(--transition), color var(--transition);
}

.segmented button:hover { color: var(--on-surface); }

.segmented button[aria-checked="true"] {
  background: var(--primary-container);
  color: var(--on-primary-container);
}

.hint { opacity: 0.65; }

/* ── adaptive strength readout (no control: the engine sets it) ── */

.skill { display: flex; align-items: center; gap: var(--space-xs); }

.skill__pips { display: flex; gap: 3px; }

.skill__pip {
  width: 7px; height: 14px;
  border-radius: 1px;
  border: 1px solid var(--outline);
  background: transparent;
}

.skill__pip.is-on { background: var(--primary-container); border-color: var(--primary-container); }

.skill__label {
  min-width: 84px;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.04em;
  color: var(--primary);
  text-align: right;
}

.option-note--tight { margin-top: calc(var(--space-sm) * -1 + 2px); }

.record {
  margin: 0;
  text-align: center;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.05em;
  color: var(--on-surface-variant);
  min-height: 16px;
}

/* ────────────────  buttons  ──────────────── */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-xs);
  min-height: 48px;
  padding: 0 var(--space-md);
  border-radius: var(--radius-pill);
  border: 1px solid transparent;
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background-color var(--transition), border-color var(--transition), color var(--transition);
}

.btn__icon {
  width: 18px; height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.btn--primary { background: var(--primary-container); color: var(--on-primary-container); }
.btn--primary:hover { background: var(--primary-hover); }

.btn--ghost {
  background: var(--surface-container);
  border-color: var(--outline-variant);
  color: var(--on-surface-variant);
}

.btn--ghost:hover { background: var(--surface-variant); color: var(--on-surface); border-color: var(--outline); }

.btn--block { width: 100%; }

.actions { display: flex; gap: var(--space-sm); justify-content: center; flex-wrap: wrap; }
.actions .btn { flex: 1 1 180px; }

/* ────────────────  scoreboard  ──────────────── */

.scoreboard {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-xs);
  padding: var(--space-sm);
}

.score {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  min-width: 100px;
  padding: 12px;
  background: var(--surface-container-low);
  border: 1px solid var(--outline-faint);
  border-radius: var(--radius);
  opacity: 0.6;
  transition: opacity var(--transition), border-color var(--transition);
}

.score.is-active { opacity: 1; }
.score.is-active[data-mark="X"] { border-color: var(--primary-container); }
.score.is-active[data-mark="O"] { border-color: var(--secondary-container); }

.score__name {
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 16px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--on-surface-variant);
  white-space: nowrap;
}

.score__row { display: flex; align-items: baseline; gap: var(--space-xs); }

.score__mark { font-size: 26px; font-weight: 700; line-height: 32px; }
.score[data-mark="X"] .score__mark { color: var(--primary-container); }
.score[data-mark="O"] .score__mark { color: var(--secondary-container); }

.score__value { font-family: var(--font-mono); font-size: 16px; font-weight: 700; }

.turn { display: flex; flex-direction: column; align-items: center; gap: 4px; }

.turn__label {
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 16px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--on-surface-variant);
}

.turn__pill {
  padding: 6px 16px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--primary-tint-border);
  background: var(--primary-tint);
  color: var(--primary);
  font-size: 14px;
  font-weight: 600;
  white-space: nowrap;
  transition: color var(--transition), background-color var(--transition), border-color var(--transition);
}

.turn__pill[data-mark="O"] {
  border-color: var(--secondary-tint-border);
  background: var(--secondary-tint);
  color: var(--secondary-container);
}

.turn__pill[data-mark="end"] {
  border-color: var(--outline-variant);
  background: var(--surface-container-low);
  color: var(--on-surface-variant);
}

.draws {
  margin: calc(var(--space-md) * -1 + 12px) 0 0;
  text-align: center;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--on-surface-variant);
}

/* ────────────────  board  ──────────────── */

.board-frame {
  position: relative;
  width: 100%;
  max-width: min(var(--board-max), 100%);
  margin: 0 auto;
  aspect-ratio: 1 / 1;
  padding: 12px;
  background: var(--surface-container-low);
  border: 1px solid var(--outline);
  border-radius: var(--radius-lg);
}

/* Cell count comes from --cells, set in ui.js when the board is built.
   Bigger grids tighten the gutter so the cells keep a usable tap size. */
/* Shrink the board rather than push the buttons off a short screen. Guarded:
   without dvh the width-only rule above still applies. */
@supports (height: 100dvh) {
  .board-frame { max-width: min(var(--board-max), 100%, calc(100dvh - var(--board-reserve))); }
}

.board {
  display: grid;
  grid-template-columns: repeat(var(--cells, 3), 1fr);
  grid-template-rows: repeat(var(--cells, 3), 1fr);
  gap: 12px;
  width: 100%;
  height: 100%;
}

.board[data-size="5"] { gap: 7px; }
.board[data-size="7"] { gap: 5px; }

/* The hover lift reads as jitter once cells are small. */
.board[data-size="7"] .tile:hover:not(.is-occupied):not(:disabled) { transform: none; }

.tile {
  position: relative;
  display: grid;
  place-items: center;
  padding: 0;
  background: var(--surface-container);
  border: 1px solid var(--outline-variant);
  border-radius: var(--radius);
  cursor: pointer;
  transition: background-color var(--transition), border-color var(--transition), transform var(--transition);
}

.tile:disabled { cursor: default; }

.tile:hover:not(.is-occupied):not(:disabled) {
  background: var(--surface-container-high);
  border-color: var(--outline);
  transform: translateY(-2px);
}

.tile:active:not(.is-occupied):not(:disabled) { transform: translateY(1px); }

.mark {
  width: 68%; height: 68%;
  fill: none;
  stroke-width: 12;
  stroke-linecap: round;
  animation: pop-in 220ms cubic-bezier(0.175, 0.885, 0.32, 1.275);
}

.mark path, .mark circle { stroke-dasharray: 300; stroke-dashoffset: 300; animation: draw 280ms ease-out forwards; }
.mark path:nth-child(2) { animation-delay: 120ms; }

.mark--x { stroke: var(--primary-container); }
.mark--o { stroke: var(--secondary-container); }

.tile__ghost {
  position: absolute;
  inset: 16%;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--transition);
}

.tile__ghost svg { width: 100%; height: 100%; fill: none; stroke-width: 12; stroke-linecap: round; }
.tile__ghost--x svg { stroke: var(--ghost-x); }
.tile__ghost--o svg { stroke: var(--ghost-o); }

.tile:hover:not(.is-occupied):not(:disabled) .tile__ghost { opacity: 1; }

.tile.is-win[data-mark="X"] { background: var(--primary-container); border-color: var(--primary-container); }
.tile.is-win[data-mark="X"] .mark--x { stroke: var(--on-primary-container); }
.tile.is-win[data-mark="O"] { background: var(--secondary-container); border-color: var(--secondary-container); }
.tile.is-win[data-mark="O"] .mark--o { stroke: var(--on-secondary-container); }

.tile.is-dim { opacity: 0.4; }

@keyframes pop-in {
  from { transform: scale(0.6); opacity: 0; }
  to   { transform: scale(1); opacity: 1; }
}

@keyframes draw { to { stroke-dashoffset: 0; } }

/* ────────────────  result overlay  ──────────────── */

.overlay {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  padding: var(--space-sm);
  /* light enough that the highlighted winning line still reads through */
  background: var(--scrim);
  border-radius: var(--radius-lg);
  animation: fade-in 200ms ease-out;
}

.overlay__card {
  width: 100%;
  max-width: 280px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-md);
  text-align: center;
  background: var(--surface-container);
  border: 1px solid var(--outline);
  border-radius: var(--radius-lg);
}

.overlay__eyebrow {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--on-surface-variant);
}

.overlay__title { margin: 0; font-size: 24px; line-height: 32px; font-weight: 600; }

@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }

/* ────────────────  settings modal  ──────────────── */

.modal {
  position: fixed;
  inset: 0;
  z-index: 20;
  display: grid;
  place-items: center;
  padding: var(--space-sm);
}

.modal__backdrop { position: absolute; inset: 0; background: var(--scrim-strong); }

.modal__card {
  position: relative;
  width: 100%;
  max-width: 420px;
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  padding: var(--space-md);
}

.modal__head { display: flex; align-items: center; justify-content: space-between; }
.modal__head h2 { margin: 0; font-size: 24px; line-height: 32px; font-weight: 600; }

.switch-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  padding: 12px 0;
  border-top: 1px solid var(--surface-variant);
  cursor: pointer;
}

.switch-row__title { display: block; font-size: 16px; }
.switch-row__desc { display: block; font-family: var(--font-mono); font-size: 12px; line-height: 16px; color: var(--on-surface-variant); }

.switch-row input[type="checkbox"] {
  flex: 0 0 auto;
  appearance: none;
  -webkit-appearance: none;
  margin: 0;
  width: 44px; height: 24px;
  border-radius: var(--radius-pill);
  background: var(--surface-container-lowest);
  border: 1px solid var(--outline-variant);
  position: relative;
  cursor: pointer;
  transition: background-color var(--transition), border-color var(--transition);
}

.switch-row input[type="checkbox"]::after {
  content: "";
  position: absolute;
  top: 3px; left: 3px;
  width: 16px; height: 16px;
  border-radius: var(--radius-pill);
  background: var(--outline);
  transition: transform var(--transition), background-color var(--transition);
}

.switch-row input[type="checkbox"]:checked { background: var(--primary-container); border-color: var(--primary-container); }
.switch-row input[type="checkbox"]:checked::after { transform: translateX(20px); background: var(--on-primary-container); }

/* ────────────────  online lobby  ──────────────── */

.option-note {
  margin: 0;
  font-size: 14px;
  line-height: 20px;
  color: var(--on-surface-variant);
}

.id-card,
.room-card,
.friends {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  padding: var(--space-md);
}

.id-card__grid { display: grid; gap: var(--space-sm); grid-template-columns: 1fr; }

.field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }

.field__label {
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 16px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--on-surface-variant);
}

.field__input {
  min-width: 0;
  min-height: 44px;
  padding: 0 12px;
  background: var(--surface-container-lowest);
  border: 1px solid var(--outline-variant);
  border-radius: var(--radius);
  color: var(--on-surface);
  font: inherit;
  font-size: 16px;
  transition: border-color var(--transition);
}

.field__input:hover { border-color: var(--outline); }
.field__input:focus { outline: 2px solid var(--primary); outline-offset: 1px; }

.field__input--code {
  flex: 0 1 8ch;
  font-family: var(--font-mono);
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

.field__input--code::placeholder { letter-spacing: 0.18em; }

.field-row { display: flex; gap: var(--space-xs); align-items: center; flex-wrap: wrap; }
.field-row .field__input { flex: 1 1 120px; }

.field__hint {
  margin: 0;
  font-size: 12px;
  line-height: 18px;
  color: var(--on-surface-variant);
}

.field__hint code {
  font-family: var(--font-mono);
  background: var(--surface-container-lowest);
  border: 1px solid var(--outline-variant);
  border-radius: 3px;
  padding: 0 4px;
}

/* the code chip — the thing people actually read out loud */
.code-chip {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-xs);
  min-height: 44px;
  padding: 0 6px 0 12px;
  background: var(--surface-container-lowest);
  border: 1px solid var(--primary-tint-border);
  border-radius: var(--radius);
}

.code-chip code {
  font-family: var(--font-mono);
  font-size: 18px;
  font-weight: 700;
  letter-spacing: 0.22em;
  color: var(--primary);
}

.code-chip--lg { justify-content: center; padding: 8px; gap: var(--space-sm); }
.code-chip--lg code { font-size: 32px; line-height: 40px; }

/* the invite link — the primary way a room gets shared */
.share { display: flex; flex-direction: column; gap: 6px; }

.share__actions { display: flex; gap: var(--space-xs); flex-wrap: wrap; }
.share__actions .btn { flex: 1 1 140px; }

.field__input--link {
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--primary);
  text-overflow: ellipsis;
}

.field__input--link:read-only { cursor: pointer; }

.icon-btn--sm { width: 32px; height: 32px; }
.icon-btn--sm svg { width: 16px; height: 16px; }

.btn--mini { min-height: 36px; padding: 0 14px; }

.btn--danger {
  background: transparent;
  border-color: var(--error);
  color: var(--error);
}

.btn--danger:hover { background: var(--error); color: var(--surface-container-lowest); }

/* room */
.room-card__head,
.friends__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-xs);
}

.room-card__head h2,
.friends__head h2 { margin: 0; font-size: 18px; line-height: 24px; font-weight: 600; }

.room-card > div { display: flex; flex-direction: column; gap: var(--space-sm); }

.badge {
  padding: 2px 10px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--primary-tint-border);
  background: var(--primary-tint);
  color: var(--primary);
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.friends__count {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.05em;
  color: var(--on-surface-variant);
}

.friends__record {
  margin: -8px 0 0;
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 16px;
  letter-spacing: 0.05em;
  color: var(--on-surface-variant);
}

/* ── the online card: a door, not a radio ── */

.mode-card--link { width: 100%; text-align: left; }

.mode-card--link:hover { border-left-color: var(--primary-container); }

.mode-card__go {
  flex: 0 0 auto;
  width: 20px; height: 20px;
  margin-left: auto;
  fill: none;
  stroke: var(--on-surface-variant);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform var(--transition), stroke var(--transition);
}

.mode-card--link:hover .mode-card__go { transform: translateX(3px); stroke: var(--primary); }

/* friend list */
.friend-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.friend-list:empty { display: none; }

.friend {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  padding: 8px 10px;
  background: var(--surface-container-low);
  border: 1px solid var(--outline-faint);
  border-radius: var(--radius);
}

.friend__dot {
  flex: 0 0 auto;
  width: 8px; height: 8px;
  border-radius: var(--radius-pill);
  background: var(--outline-variant);
}

.friend__dot[data-online="true"] { background: #22c55e; }

.friend__body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }

.friend__name {
  font-size: 15px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.friend__meta {
  font-family: var(--font-mono);
  font-size: 11px;
  line-height: 16px;
  letter-spacing: 0.05em;
  color: var(--on-surface-variant);
}

.friend .btn--mini { flex: 0 0 auto; }
.friend .btn:disabled { opacity: 0.4; cursor: default; }
.friend .btn:disabled:hover { background: var(--surface-container); color: var(--on-surface-variant); border-color: var(--outline-variant); }

.friends__empty,
.lobby-note {
  margin: 0;
  font-size: 13px;
  line-height: 20px;
  color: var(--on-surface-variant);
}

.add-friend {
  display: flex;
  gap: var(--space-xs);
  flex-wrap: wrap;
  padding-top: 12px;
  border-top: 1px solid var(--surface-variant);
}

.add-friend .field__input { flex: 1 1 120px; }
.add-friend .field__input--code { flex: 0 1 9ch; }

.lobby-note {
  padding: 12px 14px;
  border-radius: var(--radius);
  border: 1px solid var(--outline-variant);
  background: var(--surface-container-low);
}

.lobby-note[data-tone="error"] { border-color: var(--error); color: var(--error); }
.lobby-note[data-tone="ok"] { border-color: var(--primary-tint-border); color: var(--primary); }

/* invite */
.modal__card--tight { max-width: 340px; text-align: center; align-items: center; }
.modal__card--tight .actions { width: 100%; }

.invite__title { margin: 0; font-size: 22px; line-height: 28px; font-weight: 600; }

.invite__code {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 14px;
  letter-spacing: 0.15em;
  color: var(--primary);
}

/* ============================================================
   RESPONSIVE
   Four things change with the viewport, in this order:
     --shell-max   how wide one column of content is allowed to get
     --board-max   how large the board may grow
     stacking      rows become columns, and back again
     layout        wide screens put the board beside its panels
   Phone styles are the ones above; everything here is an addition.
   ============================================================ */

/* ── small phones ── */
@media (max-width: 340px) {
  /* below this the two labels cannot sit side by side without wrapping */
  .actions .btn { flex: 1 1 100%; }
}

@media (max-width: 380px) {
  .topbar { padding: 12px var(--space-sm); }
  .shell { padding-top: var(--space-sm); }
  .stack { gap: var(--space-sm); }
  .brand { font-size: 20px; }
  .hero__title { font-size: 28px; line-height: 36px; }
  .id-card, .room-card, .friends, .modal__card { padding: var(--space-sm); }
}

/* ── phones: one column, full-width controls, nothing side by side ── */
@media (max-width: 420px) {
  .field-row .btn,
  .add-friend .field__input,
  .add-friend .btn,
  .share__actions .btn { flex: 1 1 100%; }

  .size-card { padding: 8px; gap: 6px; }
  .size-card__title { font-size: 14px; }
  .size-card__rule { font-size: 10px; letter-spacing: 0; }

  .board[data-size="7"] { gap: 3px; }
  .board, .board-frame { gap: var(--space-xs); }

  /* let the three scoreboard cells share one line instead of wrapping */
  .score { min-width: 0; flex: 1 1 0; padding: 10px 6px; }
  .score__name { font-size: 11px; }
  .turn__pill { padding: 6px 10px; font-size: 13px; }
  /* trimmer buttons, and a basis two of them can actually share a row */
  .actions .btn { flex: 1 1 140px; padding: 0 12px; }

}

/* Only the narrowest phones need the turn pill on its own row; keeping the
   scoreboard to one line above that saves ~50px of height on the game screen. */
@media (max-width: 340px) {
  .scoreboard { flex-wrap: wrap; justify-content: center; }
  .turn { order: -1; width: 100%; padding-bottom: var(--space-xs); }
  .score { flex: 1 1 45%; min-width: 0; }
}

/* ── phone held sideways ──
   Height is the scarce dimension, so the board moves beside the panels and
   takes what vertical room there is. */
@media (orientation: landscape) and (max-height: 560px) {
  :root { --shell-max: 100%; --page-max: 100%; }
  .shell { align-items: flex-start; padding-top: var(--space-xs); }
  .topbar { padding: var(--space-xs) var(--space-sm); }
  .brand { font-size: 18px; }
  .brand__glyph { width: 20px; height: 20px; }

  #view-game .stack {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(220px, 300px);
    grid-template-rows: auto auto 1fr;
    align-items: start;
    column-gap: var(--space-md);
    row-gap: var(--space-xs);
    max-width: 860px;
  }

  /* only the top bar and page padding share the height with the board */
  #view-game .stack { --board-reserve: 92px; }
  #view-game .board-frame { grid-column: 1; grid-row: 1 / span 3; }

  /* Everything in the side column shrinks: with ~330px of usable height the
     buttons have to stay above the fold, and the board is the only thing
     that deserves the space. */
  #view-game .scoreboard { grid-column: 2; grid-row: 1; flex-direction: column; gap: 6px; padding: 10px; }
  #view-game .score { width: 100%; padding: 6px; gap: 0; }
  #view-game .score__mark { font-size: 20px; line-height: 24px; }
  #view-game .score__name { font-size: 11px; }
  #view-game .turn__label { display: none; }
  #view-game .draws { grid-column: 2; grid-row: 2; margin: 0; }
  #view-game .actions { grid-column: 2; grid-row: 3; gap: var(--space-xs); }
  #view-game .actions .btn { flex: 1 1 100%; min-height: 40px; }
}

/* ── large phones and up ── */
@media (min-width: 560px) {
  .id-card__grid { grid-template-columns: 1fr auto; align-items: end; }
}

/* ── tablets ── */
@media (min-width: 600px) {
  :root { --page-max: 560px; --shell-max: 560px; --board-max: 440px; }
  .hero__title { font-size: 40px; line-height: 48px; }
}

@media (min-width: 640px) {
  .mode-grid { grid-template-columns: 1fr 1fr; }
  .mode-card { flex-direction: column; align-items: flex-start; }
  /* the online card sits below the mode grid and stays a single row */
  .mode-card--wide { flex-direction: row; align-items: center; }
}

/* ── tablet landscape and small laptops ── */
@media (min-width: 900px) {
  :root { --page-max: 640px; --shell-max: 640px; --board-max: 480px; }
  .hero__title { font-size: 48px; line-height: 56px; }
}

/* ── desktop and tablets in landscape ──
   Enough width for two columns: the board gets the room it deserves and the
   scoreboard, tally and buttons sit beside it instead of below the fold. This
   starts at 1024 so an iPad in landscape gets it too — stacked, that layout
   runs about 50px past the bottom of a 768-tall screen. */
@media (min-width: 1024px) {
  /* the rail widens for the two-column layouts; prose stays a readable column */
  :root { --page-max: 940px; --shell-max: 720px; --board-max: 520px; }

  .shell { padding-top: var(--space-lg); }

  /* Both rails are now the same width and centred the same way, so dropping
     the bar's inner padding lines the brand up with the board's left edge. */
  .topbar { padding-left: 0; padding-right: 0; }

  #view-game .stack {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(260px, 300px);
    grid-template-rows: auto auto 1fr;
    align-items: start;
    column-gap: var(--space-lg);
    row-gap: var(--space-sm);
    max-width: var(--page-max);
  }

  #view-game .stack { --board-reserve: 150px; }
  #view-game .board-frame { grid-column: 1; grid-row: 1 / span 3; margin: 0; }
  #view-game .scoreboard { grid-column: 2; grid-row: 1; flex-direction: column; gap: var(--space-sm); }
  #view-game .score { width: 100%; }
  #view-game .turn { order: -1; }
  #view-game .draws { grid-column: 2; grid-row: 2; margin: 0; }
  #view-game .actions { grid-column: 2; grid-row: 3; }
  #view-game .actions .btn { flex: 1 1 100%; }

  /* the lobby reads as two columns once there is room for them */
  #view-online .stack {
    display: grid;
    grid-template-columns: 1fr 1fr;
    align-items: start;
    gap: var(--space-md);
    max-width: var(--page-max);
  }
  #view-online .hero,
  #view-online .id-card,
  #view-online .lobby-note,
  #view-online .btn--block { grid-column: 1 / -1; }
}

/* ── very wide ── */
@media (min-width: 1500px) {
  :root { --page-max: 1000px; --board-max: 560px; }
}

/* ── tall screens: tablets in portrait have room for a bigger board ── */
@media (min-width: 768px) and (min-height: 900px) {
  :root { --board-max: 520px; }
}

/* ── short screens in portrait ──
   Small phones and split-screen windows: the scoreboard gives up its label and
   padding so the board and the buttons both stay on screen. */
@media (orientation: portrait) and (max-height: 700px) {
  :root { --board-reserve: 250px; }
  .shell {
    padding-top: var(--space-sm);
    padding-bottom: max(var(--space-md), env(safe-area-inset-bottom));
  }
  .topbar { padding-top: 10px; padding-bottom: 10px; }
  .stack { gap: var(--space-sm); }
  .scoreboard { padding: 10px; }
  .score { padding: 8px; }
  .turn__label { display: none; }
  .draws { margin-top: calc(var(--space-sm) * -1 + 6px); }
}

/* very short: give the scoreboard one compact row and shrink the marks */
@media (orientation: portrait) and (max-height: 620px) {
  :root { --board-reserve: 230px; }
  .score { padding: 6px; }
  .score__mark { font-size: 20px; line-height: 24px; }
  .score__name { font-size: 11px; }
}

/* ── coarse pointers ──
   Finger targets, not cursor targets: 40px minimum on anything tappable. */
@media (pointer: coarse) {
  .icon-btn--sm { width: 40px; height: 40px; }
  .icon-btn--sm svg { width: 18px; height: 18px; }
  .segmented button { min-height: 40px; }
  .btn--mini { min-height: 42px; }
  .friend { padding: 10px; }
  /* hover styles stick after a tap on touch devices, so keep them for mice */
  .tile:hover:not(.is-occupied):not(:disabled) { transform: none; }
  .tile:hover:not(.is-occupied):not(:disabled) .tile__ghost { opacity: 0; }
}

/* ── printing a finished game ── */
@media print {
  .topbar, .actions, .overlay, .modal { display: none !important; }
  body { background: #fff; color: #000; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 1ms !important; transition-duration: 1ms !important; }
  .mark path, .mark circle { stroke-dashoffset: 0; }
}
