[hidden] { display: none !important; }
body { margin: 0; }

/* Layout: a face-to-face table for two. Each player has a die row on their edge, a dice area, and a tracker
   in the middle; the top player's pieces are rotated 180°. Look: neon night-club table — dark grid floor,
   chamfered steel panels with neon edges, hazard stripes. Top side burns red, bottom side cyber yellow.
   Deliberately one dark look. */
:root {
  color-scheme: dark;
  --void: #07060b;
  --floor: #0d0b14;
  --steel: #15121d;
  --steel-hi: #201b2b;
  --ink: #f4f1ff;
  --muted: #8d86a3;
  --line: rgba(244, 241, 255, 0.10);
  --cyan: #00f0ff;
  --magenta: #ff2bd6;
  --red: #ff2a4d;
  --yellow: #fcee0a;
  --crit: #fcee0a;
  --fumble: #ff2a4d;
  --display: 'Orbitron', 'Arial Black', Impact, sans-serif;
  --ui: 'Chakra Petch', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
  --mono: 'Share Tech Mono', ui-monospace, Consolas, monospace;
  --die: 168px;
  --dock-die: 150px;
  --cut: 14px;
}
[data-side="top"] { --neon: var(--red); --neon-ink: #ffffff; --neon-soft: rgba(255, 42, 77, .16); }
[data-side="bot"] { --neon: var(--yellow); --neon-ink: #0b0a10; --neon-soft: rgba(252, 238, 10, .13); }

* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  color: var(--ink);
  font-family: var(--ui);
  font-size: 15px;
  background:
    radial-gradient(900px 420px at 50% 0%, rgba(255, 42, 77, .16), transparent 70%),
    radial-gradient(900px 420px at 50% 100%, rgba(252, 238, 10, .10), transparent 70%),
    radial-gradient(600px 300px at 50% 50%, rgba(0, 240, 255, .07), transparent 70%),
    linear-gradient(rgba(0, 240, 255, .045) 1px, transparent 1px) 0 0 / 44px 44px,
    linear-gradient(90deg, rgba(0, 240, 255, .045) 1px, transparent 1px) 0 0 / 44px 44px,
    var(--void);
  padding-left: max(16px, env(safe-area-inset-left, 0px));
  padding-right: max(16px, env(safe-area-inset-right, 0px));
  padding-block: 14px;
}
/* CRT scanlines over everything, never blocking clicks */
body::after {
  content: ""; position: fixed; inset: 0; pointer-events: none; z-index: 50;
  background: repeating-linear-gradient(0deg, rgba(0, 0, 0, .18) 0 1px, transparent 1px 3px);
  mix-blend-mode: multiply;
}
.table {
  height: 100%; min-height: 940px; max-width: 1060px; margin: 0 auto;
  display: grid; grid-template-rows: auto minmax(min-content, 1fr) auto minmax(min-content, 1fr) auto; gap: 12px;
}
.flip { transform: rotate(180deg); }

/* Chamfered steel panel with a neon edge: the element paints the edge, ::before paints the plate 1px inside. */
:root { --chamfer: polygon(var(--cut) 0, 100% 0, 100% calc(100% - var(--cut)), calc(100% - var(--cut)) 100%, 0 100%, 0 var(--cut)); }
.tracker, .picker-panel {
  position: relative; isolation: isolate;
  clip-path: var(--chamfer);
}
.tracker::before, .picker-panel::before {
  content: ""; position: absolute; inset: 1px; z-index: -1;
  clip-path: inherit;
}

/* Each player's edge: one slot per die type, holding the die until it is rolled */
.dock { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 0; }
.slot { display: grid; justify-items: center; align-content: start; gap: 0; }
.pocket { width: var(--dock-die); height: var(--dock-die); display: grid; place-items: center; position: relative; }
.pocket:empty::before {
  content: ""; width: 56%; aspect-ratio: 1; transform: rotate(45deg);
  border: 1px dashed color-mix(in srgb, var(--neon) 45%, transparent);
  box-shadow: 0 0 12px var(--neon-soft) inset;
}
.slot span {
  font: 12px/1 var(--mono); letter-spacing: .2em; color: var(--muted);
  padding: 3px 7px; border: 1px solid var(--line); background: rgba(0, 0, 0, .35);
}

/* Dice areas. The panel shape is painted by the two pseudo-elements (edge, then plate) rather than by
   clipping the area itself, so a die being dragged or gliding can leave the area without being cut off. */
.area {
  --edge: color-mix(in srgb, var(--neon) 55%, transparent);
  position: relative; isolation: isolate; z-index: 1;
  min-height: 200px;
  display: flex; min-height: 0;
}
.area::before, .area::after { content: ""; position: absolute; z-index: -1; pointer-events: none; clip-path: var(--chamfer); }
.area::before { inset: 0; background: var(--edge); transition: background .15s ease; }
.area::after {
  inset: 1px;
  background:
    repeating-linear-gradient(-45deg, color-mix(in srgb, var(--neon) 55%, transparent) 0 10px, transparent 10px 20px) left bottom / 100% 7px no-repeat,
    linear-gradient(180deg, rgba(255, 255, 255, .025), transparent 40%),
    linear-gradient(var(--neon-soft) 1px, transparent 1px) 0 0 / 28px 28px,
    linear-gradient(90deg, var(--neon-soft) 1px, transparent 1px) 0 0 / 28px 28px,
    var(--steel);
}
.area.removing { --edge: var(--fumble); }
.area.target { --edge: var(--cyan); }
/* A die being dragged or gliding sits above everything else on the table. */
.area:has(.die.dragging), .area:has(.die.moving), .dock:has(.die.moving) { z-index: 40; }
.dice {
  position: relative; flex: 1; min-width: 0; display: flex; flex-direction: column; justify-content: center; align-items: center;
  gap: 0; padding: 0; overflow: visible;
  /* The area's size never depends on its dice; script.js fits the dice to the area instead. */
  container-type: size;
  --cell: 60px; --cols: 6;
}
/* Home row holds this side's own dice; a visiting row above it holds dice handed over from the other side.
   Both run d4 → d20. script.js picks the column count (6, 3 or 2) and die size that fill the area best,
   sized as if all six of a color were out, so dice don't change size as more of the same color arrive. */
.drow {
  display: flex; flex-wrap: wrap; justify-content: center; align-items: flex-start; align-content: flex-start;
  gap: 0; width: calc(var(--cell) * var(--cols)); flex: none;
}
.drow .die { flex: none; width: var(--cell); height: var(--cell); }
.drow:empty { display: none; }
.count {
  position: absolute; top: 0; left: 0; z-index: 2; display: flex; align-items: center; gap: 10px;
  padding: 6px 14px 6px calc(var(--cut) + 6px);
  background: var(--neon); color: var(--neon-ink);
  clip-path: polygon(var(--cut) 0, 100% 0, calc(100% - 12px) 100%, 0 100%, 0 var(--cut));
}
.count .ci > span { font: 900 15px/1 var(--display); letter-spacing: .12em; text-transform: uppercase; }
.count b { font: 900 20px/1 var(--display); font-variant-numeric: tabular-nums; }
.empty {
  position: absolute; inset: 0; margin: 0; display: grid; place-content: center; pointer-events: none; padding: 0 16px;
  font: 13px/1.5 var(--mono); letter-spacing: .14em; text-transform: uppercase; color: var(--muted); text-align: center;
}
.empty::before { content: "// "; color: var(--neon); }

.die {
  width: var(--die); height: var(--die); padding: 0; border: 0; background: none; color: inherit;
  cursor: pointer; border-radius: 14px; position: relative; z-index: 1; touch-action: manipulation; flex: none;
  -webkit-user-select: none; user-select: none; -webkit-tap-highlight-color: transparent;
  transition: opacity .15s ease;
}
.dock .die { width: var(--dock-die); height: var(--dock-die); }
.area .die { touch-action: none; }
.die canvas { width: 100%; height: 100%; display: block; pointer-events: none; }
.die:focus-visible { outline: 2px solid var(--cyan); outline-offset: -4px; }
.die.moving { z-index: 4; }
.die.dragging { z-index: 6; cursor: grabbing; }
.die.dragging canvas { filter: drop-shadow(0 0 14px rgba(0, 240, 255, .7)); }
.die.out { opacity: .45; }
.die.gone { transition: transform .2s ease, opacity .2s ease; opacity: 0; }
.die.crit canvas { filter: drop-shadow(0 0 8px rgba(0, 240, 255, .95)) drop-shadow(0 0 22px rgba(0, 240, 255, .6)); }
.die.fumble canvas { filter: drop-shadow(0 0 8px rgba(255, 43, 214, .95)) drop-shadow(0 0 22px rgba(255, 43, 214, .55)); }

/* Middle: both trackers, controls between */
.mid { display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); gap: 12px; align-items: center; }
.tracker {
  width: 100%; max-width: 250px; display: grid; gap: 4px; padding: 10px 16px;
  background: color-mix(in srgb, var(--neon) 60%, transparent);
}
.tracker::before { background: linear-gradient(160deg, var(--steel-hi), var(--steel) 60%); }
/* STREET CRED trackers swap which player they face with a glitch, not a turn.
   The swap uses the `rotate` property so it stacks on top of the top half's 180° transform. */
.tracker.turned { rotate: 180deg; }
/* The GIGS badge stays put; its text switches to face the other player behind the same glitch
   the STREET CRED number uses when it changes. */
.count .ci { display: flex; align-items: center; gap: 10px; }
.count.turned .ci { rotate: 180deg; }
.count .ci.bump { animation: glitch .4s steps(2, end); }
@media (prefers-reduced-motion: reduce) { .count .ci.bump { animation: none; } }
.glitching { animation: glitch-swap .3s steps(1, end); }
@keyframes glitch-swap {
  0%   { translate: 0 0; opacity: 1; filter: none; }
  15%  { translate: -3px 1px; filter: drop-shadow(2px 0 0 rgba(0, 240, 255, .6)) drop-shadow(-2px 0 0 rgba(255, 43, 214, .6)); }
  35%  { translate: 3px 0; opacity: .7; }
  50%  { translate: 0 0; opacity: .55; }
  65%  { translate: -2px 0; opacity: .85; filter: drop-shadow(-2px 0 0 rgba(0, 240, 255, .6)) drop-shadow(2px 0 0 rgba(255, 43, 214, .6)); }
  85%  { translate: 1px 0; opacity: 1; filter: none; }
  100% { translate: 0 0; opacity: 1; filter: none; }
}
@media (prefers-reduced-motion: reduce) { .glitching { animation: none; } }
.mid .tracker:first-child { justify-self: start; }
.mid .tracker:last-child { justify-self: end; }
.t-head { display: flex; justify-content: space-between; align-items: center; gap: 8px; }
.t-label { font: 900 15px/1 var(--display); color: var(--neon); letter-spacing: .12em; text-transform: uppercase; text-shadow: 0 0 10px var(--neon-soft); }
.total {
  font: 900 40px/1 var(--display); color: var(--ink); font-variant-numeric: tabular-nums;
  text-shadow: 0 0 6px var(--neon), 0 0 18px var(--neon-soft), 2px 0 0 rgba(0, 240, 255, .55), -2px 0 0 rgba(255, 43, 214, .45);
}
.total.bump { animation: glitch .4s steps(2, end); }
@keyframes glitch {
  0% { transform: translate(-3px, 1px) skewX(-8deg); clip-path: inset(0 0 55% 0); }
  25% { transform: translate(3px, -1px); clip-path: inset(40% 0 0 0); }
  50% { transform: translate(-1px, 0) scale(1.06); clip-path: none; }
  100% { transform: none; }
}
.text-btn { font: 600 12px var(--mono); letter-spacing: .14em; text-transform: uppercase; color: var(--muted); background: none; border: 0; cursor: pointer; padding: 4px; }
.text-btn:hover { color: var(--ink); }
.text-btn:disabled { opacity: .35; cursor: default; }
.text-btn:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; }

/* Middle controls: sound and reset stacked between the trackers */
.ctrls { display: grid; gap: 10px; justify-items: center; }
.sound {
  width: 44px; height: 44px; border: 1px solid rgba(255, 42, 77, .65); background: rgba(255, 42, 77, .08);
  color: var(--red); cursor: pointer; display: grid; place-items: center;
  clip-path: polygon(25% 0, 75% 0, 100% 50%, 75% 100%, 25% 100%, 0 50%);
  transition: background .15s ease;
}
.sound svg { width: 18px; height: 18px; filter: drop-shadow(0 0 4px rgba(255, 42, 77, .8)); }
.sound:hover { background: rgba(255, 42, 77, .18); }
.sound:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; }
.reset {
  font: 700 12px/1 var(--mono); letter-spacing: .16em; text-transform: uppercase; white-space: nowrap;
  padding: 9px 12px; border: 1px solid rgba(255, 42, 77, .65); background: rgba(255, 42, 77, .08);
  color: var(--red); cursor: pointer; text-shadow: 0 0 6px rgba(255, 42, 77, .7);
  clip-path: polygon(8px 0, 100% 0, calc(100% - 8px) 100%, 0 100%);
}
.reset:hover { background: rgba(255, 42, 77, .18); }
.reset.confirm {
  color: #ffffff; text-shadow: none; border-color: transparent; background: var(--red);
  box-shadow: inset 0 -4px 0 #0b0a10;
  animation: pulse .5s ease-in-out infinite alternate;
}
@keyframes pulse { to { filter: brightness(1.25); } }
.reset:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; }

/* Number picker for setting a die by hand; lives inside the area so it reads upright for that side */
.picker {
  position: absolute; inset: 0; z-index: 8; display: grid; place-items: center; padding: 10px;
  background: rgba(7, 6, 11, .78); backdrop-filter: blur(2px);
  clip-path: var(--chamfer);
}
.picker-panel {
  width: min(100%, 460px); display: grid; gap: 10px; padding: 12px 16px 16px;
  background: var(--neon);
}
.picker-panel::before { background: linear-gradient(160deg, var(--steel-hi), var(--steel) 70%); }
.picker-panel { transition: transform .45s ease; }
.picker.turned .picker-panel { transform: rotate(180deg); }
@media (prefers-reduced-motion: reduce) { .picker-panel { transition: none; } }
.picker-head { display: flex; justify-content: space-between; align-items: center; gap: 12px; }
.picker-die { display: flex; align-items: center; gap: 10px; min-width: 0; }
.picker-die canvas { width: 120px; height: 120px; flex: none; display: block; }
.picker-die b { font: 900 40px/1 var(--display); color: var(--ink); font-variant-numeric: tabular-nums; text-shadow: 0 0 8px var(--neon); }
.picker-head span { font: 900 14px/1 var(--display); letter-spacing: .12em; color: var(--neon); }
.picker-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(40px, 1fr)); gap: 6px; }
.picker-grid button {
  height: 38px; border: 1px solid var(--line); background: rgba(0, 0, 0, .35);
  color: var(--ink); font: 700 15px/1 var(--display); cursor: pointer; font-variant-numeric: tabular-nums;
  clip-path: polygon(6px 0, 100% 0, 100% calc(100% - 6px), calc(100% - 6px) 100%, 0 100%, 0 6px);
}
.picker-grid button:hover { border-color: var(--cyan); color: var(--cyan); background: rgba(0, 240, 255, .08); }
.picker-grid button[aria-pressed="true"] { background: var(--neon); color: var(--neon-ink); border-color: transparent; }
.picker-grid button:focus-visible, .picker-head button:focus-visible { outline: 2px solid var(--cyan); outline-offset: -2px; }

/* Turns */
.dock { position: relative; z-index: 2; padding: 6px 4px 4px; transition: background .2s ease; }
.dock.active {
  background:
    linear-gradient(var(--neon), var(--neon)) left top / 100% 2px no-repeat,
    linear-gradient(180deg, var(--neon-soft), transparent 70%);
}
.dock.active::before {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 2px;
  box-shadow: 0 0 16px 2px var(--neon); pointer-events: none;
}
.dock.waiting .die { opacity: .35; cursor: not-allowed; filter: saturate(.4); }
.die.locked { opacity: .28; cursor: not-allowed; filter: grayscale(.7); }
.dock.waiting .die.locked { opacity: .18; }

.msg { position: fixed; inset: 0; display: grid; place-items: center; color: var(--cyan); font: 14px var(--mono); letter-spacing: .2em; text-transform: uppercase; text-align: center; padding: 24px; }

@media (max-width: 520px) {
  :root { --die: 110px; --dock-die: 58px; --cut: 10px; }
  .table { min-height: 760px; gap: 10px; }
  .dock { gap: 0; padding-inline: 0; }
  .slot span { font-size: 10px; letter-spacing: .1em; padding: 2px 4px; }
  .picker-die canvas { width: 92px; height: 92px; }
  .total { font-size: 28px; }
  .t-label { font-size: 10px; letter-spacing: .08em; }
  .tracker { padding: 6px 10px; gap: 2px; }
  .mid { gap: 8px; }
  .ctrls { gap: 6px; }
  .sound { width: 34px; height: 34px; }
  .reset { font-size: 10px; padding: 6px 8px; letter-spacing: .1em; }
  .count { padding: 4px 10px 4px calc(var(--cut) + 4px); }
  .count b { font-size: 16px; }
  .count .ci > span { font-size: 13px; }
}
@media (prefers-reduced-motion: reduce) {
  .total.bump, .reset.confirm { animation: none; }
}
