/* ── Space Grotesk (self-hosted) ────────────────────
   Vendored deliberately: Google Fonts is unreliable behind the Great Firewall,
   and a render-blocking <link> to a blocked host stalls the whole page. One
   variable file covers weights 400-700. latin-ext is included so accented
   student names render correctly. */
@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-display: swap;
  font-weight: 400 700;
  src: url('../fonts/space-grotesk-latin-ext-wght-normal.woff2') format('woff2-variations');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-display: swap;
  font-weight: 400 700;
  src: url('../fonts/space-grotesk-latin-wght-normal.woff2') format('woff2-variations');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* styles.css — shared shell + both game boards
   Tokens follow the mistercraig house style: dark by default, light via
   [data-theme="light"] on <html>. */

/* ── Theme tokens ──────────────────────────────────── */
:root {
  --accent:       #22d3ee;
  --accent-dim:   rgba(34, 211, 238, 0.12);
  --bg:           #0b1120;
  --bg-card:      #111827;
  --bg-inset:     #0d1526;
  --border:       rgba(255, 255, 255, 0.07);
  --border-hover: rgba(34, 211, 238, 0.35);
  --text:         #e2e8f0;
  --text-dim:     #94a3b8;
  --shadow:       0 8px 32px rgba(0, 0, 0, 0.5);
  --grid-line:    rgba(255, 255, 255, 0.035);

  /* Player colours sit on the blue/orange axis, which stays distinguishable
     for the most common kinds of colour blindness. */
  --p1:      #22d3ee;
  --p1-soft: rgba(34, 211, 238, 0.16);
  --p2:      #fb923c;
  --p2-soft: rgba(251, 146, 60, 0.16);
  --ok:      #4ade80;
  --warn:    #fbbf24;
}

[data-theme="light"] {
  --accent:       #0284c7;
  --accent-dim:   rgba(2, 132, 199, 0.10);
  --bg:           #f0f4f8;
  --bg-card:      #ffffff;
  --bg-inset:     #f8fafc;
  --border:       rgba(0, 0, 0, 0.09);
  --border-hover: rgba(2, 132, 199, 0.40);
  --text:         #0f172a;
  --text-dim:     #64748b;
  --shadow:       0 8px 32px rgba(0, 0, 0, 0.10);
  --grid-line:    rgba(0, 0, 0, 0.045);

  --p1:      #0284c7;
  --p1-soft: rgba(2, 132, 199, 0.13);
  --p2:      #ea580c;
  --p2-soft: rgba(234, 88, 12, 0.13);
  --ok:      #16a34a;
  --warn:    #b45309;
}

/* ── Reset ─────────────────────────────────────────── */
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }

body {
  font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
  background-color: var(--bg);
  color: var(--text);
  min-height: 100vh;
  transition: background-color 0.3s ease, color 0.3s ease;
  background-image:
    linear-gradient(var(--grid-line) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
  background-size: 44px 44px;
}

/* ── Header ────────────────────────────────────────── */
header {
  position: sticky;
  top: 0;
  z-index: 100;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  padding: 14px 28px;
  background: var(--bg);
  border-bottom: 1px solid var(--border);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
}

.logo {
  font-size: 1.1rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--accent);
  text-decoration: none;
  user-select: none;
}
.logo span { color: var(--text-dim); font-weight: 400; }

.header-right { display: flex; align-items: center; gap: 10px; }

.theme-toggle, .btn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  background: var(--bg-card);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px 14px;
  font: inherit;
  font-size: 0.85rem;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease, transform 0.1s ease;
}
.theme-toggle:hover, .btn:hover { border-color: var(--border-hover); }
.btn:active { transform: translateY(1px); }

.btn-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--bg);
  font-weight: 600;
}
.btn-primary:hover { filter: brightness(1.08); }

.theme-toggle svg { width: 15px; height: 15px; }
[data-theme="light"] .icon-sun  { display: none; }
:root:not([data-theme="light"]) .icon-moon { display: none; }

/* ── Layout ────────────────────────────────────────── */
main {
  max-width: 1040px;
  margin: 0 auto;
  padding: 32px 24px 64px;
}

.page-title {
  font-size: 1.9rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  margin-bottom: 6px;
}
.page-sub { color: var(--text-dim); font-size: 0.95rem; margin-bottom: 28px; }

.card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 14px;
  box-shadow: var(--shadow);
  padding: 22px;
}

/* ── Hub ───────────────────────────────────────────── */
.hub-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 20px;
}
.hub-card {
  display: block;
  text-decoration: none;
  color: inherit;
  transition: border-color 0.15s ease, transform 0.15s ease;
}
.hub-card:hover { border-color: var(--border-hover); transform: translateY(-2px); }
.hub-card h2 { font-size: 1.2rem; margin-bottom: 8px; color: var(--accent); }
.hub-card p { color: var(--text-dim); font-size: 0.9rem; line-height: 1.55; }

/* ── Setup panel ───────────────────────────────────── */
.setup { display: flex; flex-wrap: wrap; gap: 22px; align-items: flex-end; }

.field { display: flex; flex-direction: column; gap: 7px; }
.field > label {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--text-dim);
  font-weight: 600;
}

.segmented { display: flex; border: 1px solid var(--border); border-radius: 9px; overflow: hidden; }
.segmented input { position: absolute; opacity: 0; pointer-events: none; }
.segmented label {
  padding: 9px 15px;
  font-size: 0.86rem;
  cursor: pointer;
  background: var(--bg-inset);
  border-right: 1px solid var(--border);
  transition: background 0.15s ease, color 0.15s ease;
  user-select: none;
}
.segmented label:last-child { border-right: none; }
.segmented input:checked + label { background: var(--accent); color: var(--bg); font-weight: 600; }
.segmented input:focus-visible + label { outline: 2px solid var(--accent); outline-offset: -2px; }

.field.hidden { display: none; }

/* ── Name inputs ───────────────────────────────────── */
.name-inputs { display: flex; gap: 8px; }

.name-input {
  width: 8.5rem;
  padding: 9px 11px;
  font: inherit;
  font-size: 0.86rem;
  color: var(--text);
  background: var(--bg-inset);
  border: 1px solid var(--border);
  border-left: 3px solid var(--pcol, var(--border));
  border-radius: 9px;
  transition: border-color 0.15s ease;
}
.name-input.p1 { --pcol: var(--p1); }
.name-input.p2 { --pcol: var(--p2); }
.name-input::placeholder { color: var(--text-dim); }
.name-input:focus {
  outline: none;
  border-color: var(--accent);
  border-left-color: var(--pcol);
}

/* Long names must not blow out the scoreboard. */
.player-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ── Scoreboard ────────────────────────────────────── */
.scoreboard { display: flex; gap: 14px; margin-bottom: 22px; }

.player-panel {
  flex: 1;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-left: 4px solid var(--pcol, var(--border));
  border-radius: 12px;
  padding: 14px 18px;
  transition: box-shadow 0.2s ease, border-color 0.2s ease;
}
.player-panel[data-player="1"] { --pcol: var(--p1); }
.player-panel[data-player="2"] { --pcol: var(--p2); }

.player-panel.active {
  box-shadow: 0 0 0 2px var(--pcol);
}

.player-name { font-size: 0.78rem; color: var(--text-dim); letter-spacing: 0.06em; text-transform: uppercase; }
.player-score { font-size: 1.9rem; font-weight: 700; color: var(--pcol); line-height: 1.15; }
.player-note { font-size: 0.78rem; color: var(--text-dim); min-height: 1.1em; }

/* ── Status line ───────────────────────────────────── */
.status {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 44px;
  padding: 11px 16px;
  margin-bottom: 20px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 10px;
  font-size: 0.95rem;
}
.status.warn { border-color: var(--warn); color: var(--warn); }
.status.done { border-color: var(--ok); }
.status strong { color: var(--accent); }

/* ── Factor board ──────────────────────────────────── */
.factor-board {
  display: grid;
  gap: 8px;
  margin-bottom: 22px;
}
.factor-board[data-size="30"] { grid-template-columns: repeat(6, 1fr); }
.factor-board[data-size="49"] { grid-template-columns: repeat(7, 1fr); }

.cell {
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.25rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  background: var(--bg-card);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 10px;
  cursor: pointer;
  transition: transform 0.12s ease, border-color 0.12s ease, background 0.2s ease;
}
.cell:hover:not(:disabled) {
  border-color: var(--accent);
  transform: translateY(-2px);
}
.cell:disabled { cursor: not-allowed; }

/* Unclaimed but unpickable this turn. */
.cell.dead { color: var(--text-dim); opacity: 0.4; }

.cell.owned-1 { background: var(--p1-soft); border-color: var(--p1); color: var(--p1); }
.cell.owned-2 { background: var(--p2-soft); border-color: var(--p2); color: var(--p2); }

.cell.just-picked { animation: pop 0.4s ease; }
.cell.just-factor { animation: pop 0.4s ease 0.06s backwards; }

@keyframes pop {
  0%   { transform: scale(0.75); }
  55%  { transform: scale(1.1); }
  100% { transform: scale(1); }
}

/* ── Product board ─────────────────────────────────── */
.product-layout { display: flex; flex-wrap: wrap; gap: 28px; align-items: flex-start; }
.product-left { flex: 1 1 420px; min-width: 320px; }
.product-right { flex: 0 1 300px; }

.product-grid {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 7px;
  margin-bottom: 22px;
}
.square {
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.15rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 9px;
  transition: background 0.25s ease, border-color 0.25s ease, transform 0.15s ease;
}
.square.owned-1 { background: var(--p1-soft); border-color: var(--p1); color: var(--p1); }
.square.owned-2 { background: var(--p2-soft); border-color: var(--p2); color: var(--p2); }

/* The square the current marker pair points at. */
.square.target {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent-dim);
}
.square.just-claimed { animation: pop 0.4s ease; }
.square.win { animation: pop 0.5s ease; box-shadow: 0 0 0 3px var(--ok); }

/* Where the move you are hovering or dragging would land. */
.square.preview {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent);
  transform: scale(1.06);
}

/* Same, but the square is already claimed -- dropping here forfeits the turn. */
.square.preview-taken {
  border-color: var(--warn);
  box-shadow: 0 0 0 2px var(--warn);
  transform: scale(1.06);
}

/* ── Factor strip ──────────────────────────────────── */
.factor-strip-label {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--text-dim);
  font-weight: 600;
  margin-bottom: 10px;
}
.factor-strip { display: grid; grid-template-columns: repeat(9, 1fr); gap: 6px; }

.factor-btn {
  position: relative;
  aspect-ratio: 3 / 4;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  gap: 4px;
  padding-bottom: 6px;
  background: var(--bg-card);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 9px;
  font: inherit;
  font-size: 1.1rem;
  font-weight: 600;
  cursor: pointer;
  user-select: none;
  touch-action: none;
  transition: border-color 0.12s ease, transform 0.12s ease, background 0.15s ease, opacity 0.15s ease;
}
.factor-btn:hover:not(:disabled) { border-color: var(--accent); transform: translateY(-2px); }
.factor-btn:disabled { cursor: not-allowed; opacity: 0.45; }

/* The marker currently picked up. */
.factor-btn.selected {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent-dim);
  background: var(--accent-dim);
}

.pips { display: flex; gap: 3px; height: 11px; align-items: center; }
.pip { width: 9px; height: 9px; border-radius: 50%; background: var(--text-dim); }
.pip.m1 { background: var(--accent); box-shadow: 0 0 6px var(--accent); }
.pip.m2 { background: var(--warn); box-shadow: 0 0 6px var(--warn); }

.marker-legend {
  display: flex;
  gap: 18px;
  margin-top: 14px;
  font-size: 0.82rem;
  color: var(--text-dim);
}
.marker-legend span { display: inline-flex; align-items: center; gap: 6px; }

/* ── Marker dragging ───────────────────────────────── */
.factor-btn.draggable { cursor: grab; }
body.dragging { cursor: grabbing; user-select: none; }
body.dragging .factor-btn { cursor: grabbing; }

/* The factor the dragged marker came from. */
.factor-btn.drag-origin {
  border-style: dashed;
  border-color: var(--text-dim);
  opacity: 0.6;
}

/* Under the cursor, and a legal place to drop. */
.factor-btn.drop-target {
  border-color: var(--accent);
  background: var(--accent-dim);
  box-shadow: 0 0 0 2px var(--accent);
  transform: translateY(-3px);
}

/* Back over its own factor: releasing here snaps back. */
.factor-btn.drop-invalid {
  border-color: var(--warn);
  box-shadow: 0 0 0 2px var(--warn);
}

/* The marker travelling with the cursor. */
.marker-ghost {
  position: fixed;
  left: 0;
  top: 0;
  transform: translate(-50%, -50%);
  pointer-events: none;
  z-index: 1000;
}
.marker-ghost .pip {
  width: 18px;
  height: 18px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.45);
}
.marker-ghost.snapping {
  transition: left 0.18s ease, top 0.18s ease;
}

@media (prefers-reduced-motion: reduce) {
  .marker-ghost.snapping { transition: none; }
}

/* ── Rules panel ───────────────────────────────────── */
.rules { font-size: 0.85rem; line-height: 1.65; color: var(--text-dim); }
.rules h3 { font-size: 0.95rem; color: var(--text); margin-bottom: 8px; }
.rules ol { padding-left: 18px; }
.rules li { margin-bottom: 6px; }

/* ── Test page ─────────────────────────────────────── */
.test-row {
  display: flex;
  gap: 12px;
  align-items: baseline;
  padding: 7px 12px;
  border-bottom: 1px solid var(--border);
  font-size: 0.88rem;
}
.test-row .mark { font-weight: 700; width: 4.5em; flex: none; }
.test-row.ok .mark { color: var(--ok); }
.test-row.fail .mark { color: var(--p2); }
.test-row .ms { margin-left: auto; color: var(--text-dim); font-size: 0.8rem; }
.test-row .err { flex-basis: 100%; color: var(--p2); font-family: ui-monospace, monospace; font-size: 0.8rem; }

.utility-row { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 22px; }

@media (max-width: 640px) {
  main { padding: 22px 14px 48px; }
  .scoreboard { flex-direction: column; }
  .cell { font-size: 1rem; }
}
