/* codetug: fight night for two programmers.
   The screen is a broadcast scorebug over a ring. The scorebug is the one loud
   thing: the corner to move is a solid block of its colour, and Submit takes
   the same colour. Everything under it is panes divided by rules, with the
   function on the one lit surface. Blue and Red are the only hues; amber means
   the last five seconds, and red also means "no", always with words.
   Controls are keycaps cut like the Play key: cream is a key that is lit.
   During a game the page never scrolls: the code and the history scroll inside
   their own panes. Typefaces ship in /fonts (SIL OFL). */

@font-face {
  font-family: "Bricolage Grotesque"; font-style: normal; font-weight: 200 800; font-stretch: 75% 100%; font-display: swap;
  src: url("/fonts/bricolage-grotesque-latin.woff2") format("woff2");
  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;
}
@font-face {
  font-family: "Bricolage Grotesque"; font-style: normal; font-weight: 200 800; font-stretch: 75% 100%; font-display: swap;
  src: url("/fonts/bricolage-grotesque-latin-ext.woff2") format("woff2");
  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-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Martian Mono"; font-style: normal; font-weight: 100 800; font-stretch: 75% 112.5%; font-display: swap;
  src: url("/fonts/martian-mono-latin.woff2") format("woff2");
  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;
}
@font-face {
  font-family: "Martian Mono"; font-style: normal; font-weight: 100 800; font-stretch: 75% 112.5%; font-display: swap;
  src: url("/fonts/martian-mono-latin-ext.woff2") format("woff2");
  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-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  color-scheme: dark;
  --arena: #0c0c0f;       /* everything around the ring */
  --ring: #17181d;        /* the function: the one lit surface */
  --raised: #1c1d23;
  --raised-hi: #2a2b33;
  --chalk: #f3f1ec;
  --text-2: #b6b5ba;
  --text-3: #8b8b93;      /* captions and meta only */
  --rule: rgba(243, 241, 236, .11);
  --rule-strong: rgba(243, 241, 236, .24);
  /* The corners. The fill carries white text; the lighter tone is for text on the arena. */
  --blue: #2a66f5;
  --blue-text: #82acff;
  --red: #dc2f27;
  --red-text: #ff8176;
  --bell: #ffb020;        /* the last five seconds */
  --ok: #4cc38a;
  --danger: #ff4d4f;
  --danger-soft: rgba(255, 77, 79, .22);
  --danger-card: #2a1517;
  --danger-text: #ff8f90;
  /* Keys. Cream is the face of the Play key: a key that is lit. */
  --cream: #f0ebd9;
  --cream-hi: #fffdf6;
  --ink: #0b0b0f;         /* words on a lit key */
  --key: #1e1f27;
  --key-hover: #272832;
  --key-edge: #474853;
  --key-ink: #d6d6de;
  --key-base: #0a0a0f;
  --well: #0a0a0e;        /* a surface set in, for typing into */
  /* Whoever is to move: text, the filled key, and the words on it. */
  --turn: var(--chalk);
  --turn-fill: var(--cream);
  --turn-on: var(--ink);
  /* Code. Violet, teal and sand, so nothing reads as a player. */
  --code: #e4e3e8;
  --code-keyword: #c3b1f7;
  --code-name: #7ad7c6;
  --code-literal: #e6cf94;
  --font: "Bricolage Grotesque", ui-sans-serif, system-ui, sans-serif;
  --mono: "Martian Mono", ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  --ease: cubic-bezier(.22, 1, .36, 1);
  --spring: cubic-bezier(.34, 1.56, .64, 1);   /* a key coming back up */
  --row: 28px;            /* one line of code; app.js reads this */
  --code-size: 15px;
  --r: 3px;               /* the only corner radius, on the few controls that are not keys */
}
@media (min-width: 1600px) { :root { --row: 32px; --code-size: 17px; } }
body[data-turn="blue"] { --turn: var(--blue-text); --turn-fill: var(--blue); --turn-on: #fff; }
body[data-turn="red"] { --turn: var(--red-text); --turn-fill: var(--red); --turn-on: #fff; }

*, *::before, *::after { box-sizing: border-box; }
html, body { overflow-x: clip; }
html { scrollbar-color: var(--raised-hi) transparent; scrollbar-width: thin; }
body {
  margin: 0; background: var(--arena); color: var(--chalk);
  font: 400 15px/22px var(--font); font-synthesis: none; -webkit-font-smoothing: antialiased;
}
[hidden] { display: none !important; }
h1, h2, h3, h4, p { margin: 0; }
button, input, textarea { font: inherit; color: inherit; }
button { cursor: pointer; }
code, kbd, pre, textarea { font-family: var(--mono); font-stretch: 87.5%; }
code { font-size: .88em; color: var(--chalk); }
strong { font-weight: 600; }
:focus-visible { outline: 2px solid var(--chalk); outline-offset: 2px; }
::selection { background: rgba(243, 241, 236, .24); }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.icon { width: 16px; height: 16px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }

/* Sparks from the caret and the buttons are drawn here, above everything. */
#sparks { position: fixed; inset: 0; z-index: 60; width: 100%; height: 100%; pointer-events: none; }

.shell { display: flex; flex-direction: column; min-height: 100dvh; }
.arena { display: flex; flex-direction: column; flex: 1; }

/* ---- top bar ---------------------------------------------------------------- */

.site-header { display: flex; align-items: center; gap: 20px; flex: none; height: 48px; padding: 0 12px 0 20px; border-bottom: 1px solid var(--rule); }
.brand { display: inline-flex; align-items: center; gap: 10px; flex: none; color: var(--chalk); text-decoration: none; }
.brand-mark { width: 18px; height: 18px; flex: none; }
.mark-blue { fill: var(--blue); }
.mark-red { fill: var(--red); }
.brand-word { font-size: 20px; font-weight: 800; font-stretch: 80%; line-height: 1; }
.card-line { display: flex; align-items: baseline; gap: 8px; min-width: 0; padding-left: 20px; border-left: 1px solid var(--rule); font-size: 14px; line-height: 20px; color: var(--text-3); white-space: nowrap; }
.card-line strong { overflow: hidden; color: var(--chalk); text-overflow: ellipsis; }
.header-actions { display: flex; align-items: center; gap: 4px; margin-left: auto; }
.local-label { margin-right: 8px; font-size: 13px; color: var(--text-3); white-space: nowrap; }

/* ---- keys ---------------------------------------------------------------------
   Every control is a keycap cut like the Play key on the landing page: stepped
   pixel corners, and a face that stands a few pixels off a hatched base.
   Pointing lifts the face, pressing drives it onto the base, and a latched key
   (the chosen mode, the chosen clock, the open chapter) stays down and lit. The
   face moves inside the button's own box, so the target under the pointer never
   shifts. Wells are the opposite surface: set in, for typing into. */

.key, .well, .modal {
  --step: 3px;
  --stepped: polygon(
    0 calc(2 * var(--step)), var(--step) calc(2 * var(--step)), var(--step) var(--step), calc(2 * var(--step)) var(--step), calc(2 * var(--step)) 0,
    calc(100% - 2 * var(--step)) 0, calc(100% - 2 * var(--step)) var(--step), calc(100% - var(--step)) var(--step), calc(100% - var(--step)) calc(2 * var(--step)), 100% calc(2 * var(--step)),
    100% calc(100% - 2 * var(--step)), calc(100% - var(--step)) calc(100% - 2 * var(--step)), calc(100% - var(--step)) calc(100% - var(--step)), calc(100% - 2 * var(--step)) calc(100% - var(--step)), calc(100% - 2 * var(--step)) 100%,
    calc(2 * var(--step)) 100%, calc(2 * var(--step)) calc(100% - var(--step)), var(--step) calc(100% - var(--step)), var(--step) calc(100% - 2 * var(--step)), 0 calc(100% - 2 * var(--step)));
}
.key {
  --cap: 40px;            /* height of the face */
  --travel: 4px;          /* how far the face stands off its base */
  --face: var(--key); --edge: var(--key-edge); --label: var(--key-ink); --hatch: var(--key-edge);
  --shine: rgba(255, 255, 255, .07);
  position: relative; display: inline-flex; flex: none; min-width: 0; margin: 0; padding: 0 0 var(--travel);
  border: 0; background: none; color: var(--label); font: 600 14px/1 var(--font); text-align: center; white-space: nowrap;
  cursor: pointer; -webkit-tap-highlight-color: transparent; -webkit-user-select: none; user-select: none;
}
/* The base: what shows under the face, and what the face lands on. */
.key::before {
  content: ""; position: absolute; inset: var(--travel) 0 0;
  background: repeating-linear-gradient(-63.4deg, var(--hatch) 0 1px, transparent 1px 4px), var(--key-base);
  clip-path: var(--stepped);
}
/* The face: a hairline edge with the fill laid one pixel inside it. */
.key-cap {
  position: relative; isolation: isolate; display: flex; flex: 1; align-items: center; justify-content: center; gap: 8px;
  min-width: 0; height: var(--cap); padding: 0 16px; background: var(--edge); clip-path: var(--stepped);
  transition: transform .22s var(--spring), background-color .15s var(--ease);
}
.key-cap::before {
  content: ""; position: absolute; z-index: -1; inset: 1px; background: var(--face); clip-path: var(--stepped);
  box-shadow: inset 0 1px 0 var(--shine); transition: background-color .15s var(--ease);
}
.key-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.key .icon { width: 17px; height: 17px; opacity: .72; transition: opacity .15s var(--ease), transform .2s var(--ease); }
.key input { position: absolute; z-index: 1; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: inherit; }

@media (hover: hover) {
  .key:hover { --face: var(--key-hover); --edge: #5d5e6b; --label: var(--chalk); }
  .key:hover > .key-cap { transform: translateY(-1px); }
  .key:hover .icon { opacity: 1; }
}
.key:active > .key-cap, .key.is-down > .key-cap {
  transform: translateY(var(--travel)); transition: transform .05s ease-out, background-color .15s var(--ease);
}
.key:focus-visible, .key:has(> input:focus-visible) { outline: 2px solid var(--chalk); outline-offset: 2px; }

/* Latched: down and lit, like the Play key. One key of a set at a time. */
.key-latch[aria-pressed="true"], .key-latch[aria-selected="true"], .key-latch:has(> input:checked) {
  --face: var(--cream); --edge: var(--cream-hi); --label: var(--ink); --hatch: var(--cream); --shine: #fff;
}
.key-latch[aria-pressed="true"] > .key-cap, .key-latch[aria-selected="true"] > .key-cap, .key-latch > input:checked + .key-cap {
  transform: translateY(calc(var(--travel) - 1px));
}
.key-latch[aria-pressed="true"] .icon, .key-latch[aria-selected="true"] .icon, .key-latch:has(> input:checked) .icon { opacity: 1; }
.key-latch:active > .key-cap { transform: translateY(var(--travel)); }
/* Choosing a corner lights the key in that corner's colour. */
.key-blue.key-latch:has(> input:checked) { --face: var(--blue); --edge: #7fa6ff; --label: #fff; --hatch: var(--blue); --shine: rgba(255, 255, 255, .3); }
.key-red.key-latch:has(> input:checked) { --face: var(--red); --edge: #ff8076; --label: #fff; --hatch: var(--red); --shine: rgba(255, 255, 255, .3); }

/* The one key a screen is asking for. In a match it takes the mover's colour. */
.key-primary {
  --face: var(--turn-fill); --edge: color-mix(in srgb, var(--turn-fill) 64%, #fff); --label: var(--turn-on);
  --hatch: var(--turn-fill); --shine: rgba(255, 255, 255, .45);
}
.key-primary .icon { opacity: 1; }
/* A sheen crosses the face when the pointer arrives, as it does on the Play key. */
.key-primary > .key-cap::after {
  content: ""; position: absolute; z-index: -1; top: 0; bottom: 0; left: -34%; width: 26%;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .5), transparent);
  transform: skewX(-22deg); opacity: 0; transition: transform .6s var(--ease), opacity .25s var(--ease);
}
@media (hover: hover) {
  .key-primary:hover { --face: color-mix(in srgb, var(--turn-fill) 90%, #fff); --edge: #fff; --label: var(--turn-on); }
  .key-primary:hover > .key-cap::after { transform: skewX(-22deg) translateX(640%); opacity: 1; }
}

/* Sizes and shapes. */
.key-lg { --cap: 48px; font-size: 16px; font-weight: 620; }
.key-lg > .key-cap { gap: 10px; padding: 0 20px; }
.key-lg .icon { width: 18px; height: 18px; }
.key-sm { --cap: 32px; --travel: 3px; --step: 2px; font-size: 13px; }
.key-sm > .key-cap { gap: 6px; padding: 0 12px; }
.key-sm .icon { width: 15px; height: 15px; }
.key-icon > .key-cap { flex: none; width: var(--cap); padding: 0; }
.key-block { display: flex; width: 100%; }

/* Out of reach: the face goes dark and flat, and it does not lift. */
.key:disabled, .key[aria-disabled="true"], .key:has(> input:disabled) {
  --face: #14151a; --edge: #2a2b33; --label: #6c6d78; --hatch: #23242b; --shine: transparent; cursor: not-allowed;
}
.key:disabled > .key-cap, .key[aria-disabled="true"] > .key-cap, .key > input:disabled + .key-cap { transform: none; }
.key:disabled .icon, .key[aria-disabled="true"] .icon { opacity: .5; }
.key-primary:disabled {
  --face: color-mix(in srgb, var(--turn-fill) 34%, var(--arena)); --edge: color-mix(in srgb, var(--turn-fill) 46%, var(--arena));
  --label: color-mix(in srgb, var(--turn-on) 62%, var(--turn-fill)); --hatch: color-mix(in srgb, var(--turn-fill) 34%, var(--arena));
}
/* A choice that is locked in keeps its place and half its light. */
.key-latch:has(> input:checked:disabled), .key-latch[aria-pressed="true"]:disabled {
  --face: #8e8a7d; --edge: #a8a497; --label: var(--ink); --hatch: #8e8a7d;
}
.key-latch > input:checked:disabled + .key-cap, .key-latch[aria-pressed="true"]:disabled > .key-cap { transform: translateY(calc(var(--travel) - 1px)); }

/* Working: the face runs like a belt until the answer is back. */
.key.is-busy { cursor: progress; pointer-events: none; }
.key.is-busy > .key-cap { transform: translateY(calc(var(--travel) - 1px)); }
.key.is-busy > .key-cap::before {
  background-image: repeating-linear-gradient(-63.4deg, rgba(0, 0, 0, .13) 0 6px, transparent 6px 12px);
  background-size: calc(100% + 14px) 100%; background-repeat: no-repeat; animation: belt .5s linear infinite;
}
@keyframes belt { to { background-position: -13.42px 0; } }

/* A label that changes rolls to its new words, like the clock's digits. */
.rolling { display: inline-grid; overflow: hidden; }
.rolling > * { grid-area: 1 / 1; }
.roll-out { animation: roll-out .2s var(--ease) forwards; }
.roll-in { animation: roll-in .24s var(--ease); }
@keyframes roll-out { to { opacity: 0; transform: translateY(-70%); } }
@keyframes roll-in { from { opacity: 0; transform: translateY(70%); } }

/* Small actions are words; brackets close round them when they are in reach. */
.link-key {
  position: relative; display: inline-flex; align-items: center; gap: 6px; flex: none; height: 28px; padding: 0 11px; border: 0;
  background: none; color: var(--text-2); font: 500 13px/20px var(--font); white-space: nowrap; cursor: pointer;
  -webkit-tap-highlight-color: transparent; transition: color .15s var(--ease);
}
.link-key::before, .link-key::after {
  position: absolute; top: 50%; color: var(--chalk); font: 500 14px/1 var(--mono); opacity: 0;
  transition: transform .18s var(--ease), opacity .12s var(--ease);
}
.link-key::before { content: "["; left: 0; transform: translate(6px, -54%); }
.link-key::after { content: "]"; right: 0; transform: translate(-6px, -54%); }
.link-key:focus-visible { color: var(--chalk); }
.link-key:focus-visible::before, .link-key:focus-visible::after { opacity: 1; transform: translate(0, -54%); }
@media (hover: hover) {
  .link-key:hover:not(:disabled) { color: var(--chalk); }
  .link-key:hover:not(:disabled)::before, .link-key:hover:not(:disabled)::after { opacity: 1; transform: translate(0, -54%); }
}
.link-key:active:not(:disabled)::before { transform: translate(3px, -54%); transition-duration: .05s; }
.link-key:active:not(:disabled)::after { transform: translate(-3px, -54%); transition-duration: .05s; }
.link-key:disabled { opacity: .45; cursor: not-allowed; }

/* An icon on its own, where a key would be too much. */
.icon-button {
  display: inline-grid; place-items: center; flex: none; width: 32px; height: 32px; padding: 0; border: 0;
  border-radius: var(--r); background: transparent; color: var(--text-2); cursor: pointer; -webkit-tap-highlight-color: transparent;
  transition: background-color .15s var(--ease), color .15s var(--ease), transform .12s var(--ease);
}
.icon-button.small { width: 28px; height: 28px; }
.icon-button .icon { transition: transform .2s var(--ease); }
@media (hover: hover) { .icon-button:hover { background: var(--raised-hi); color: var(--chalk); } }
.icon-button:active { transform: scale(.9); }

/* What each icon does when its key is pointed at. Once, never on a loop. */
.icon path, .icon rect, .icon circle { transform-box: fill-box; transform-origin: center; transition: transform .2s var(--ease), opacity .15s var(--ease); }
.i-book .page { transform-origin: left center; }
.player-avatar { width: 26px; height: 26px; flex: none; shape-rendering: crispEdges; }
.player-avatar .eyes { transform-box: fill-box; transform-origin: center; }
@media (hover: hover) {
  .key:hover .i-pad { animation: tilt .5s var(--ease); }
  .key:hover .i-cup, .key:hover .i-user { animation: hop .42s var(--ease); }
  .key:hover .i-lock .shackle { transform: translateY(-2px); }
  .key:hover .i-book .page { transform: scaleX(.74) skewY(-8deg); }
  .key:hover .i-next, .link-key:hover .i-next { transform: translateX(3px); }
  .key:hover .i-back { transform: translateX(-3px); }
  .key:hover .i-close, .icon-button:hover .i-close { transform: rotate(90deg); }
  .key:hover .i-chevron { transform: translateY(2px); }
  .key:hover .i-out { transform: translateX(2px); }
  .sound-key:hover .wave { animation: wave .5s var(--ease); }
  .sound-key:hover .wave + .wave { animation-delay: .09s; }
  .key:hover .player-avatar .eyes { animation: blink .34s steps(1); }
}
@keyframes tilt { 30% { transform: rotate(-11deg); } 65% { transform: rotate(8deg); } }
@keyframes hop { 40% { transform: translateY(-3px); } 70% { transform: translateY(0); } 85% { transform: translateY(-1px); } }
@keyframes wave { 40% { opacity: .2; } }
@keyframes blink { 0%, 100% { transform: none; } 30%, 60% { transform: scaleY(.15); } }
.sound-key .sound-off, .sound-key[aria-pressed="false"] .sound-on { display: none; }
.sound-key[aria-pressed="false"] .sound-off { display: block; }
.sound-key[aria-pressed="false"] { color: var(--text-3); }

kbd {
  display: inline-flex; align-items: center; justify-content: center; height: 20px; min-width: 20px; padding: 0 6px;
  border: 1px solid var(--rule-strong); border-radius: var(--r); background: var(--raised);
  color: var(--text-2); font-size: 11px; font-weight: 400; line-height: 1; white-space: nowrap;
}
.key-primary kbd { border-color: currentColor; background: transparent; color: inherit; opacity: .8; }
.pill { font-size: 13px; line-height: 20px; color: var(--text-3); white-space: nowrap; }

/* A well: a display set into the surface, lit round its edge while it has the caret. */
.well {
  --edge: var(--key-edge);
  position: relative; isolation: isolate; display: flex; align-items: center; min-width: 0;
  background: var(--edge); clip-path: var(--stepped); transition: background-color .15s var(--ease);
}
.well::before {
  content: ""; position: absolute; z-index: -1; inset: 1px; background: var(--well); clip-path: var(--stepped);
  box-shadow: inset 0 2px 0 rgba(0, 0, 0, .55); transition: inset .12s var(--ease);
}
.well:focus-within { --edge: var(--cream); }
.well:focus-within::before { inset: 2px; }
.well:has([aria-invalid="true"]) { --edge: var(--danger); }
.well input {
  flex: 1; min-width: 0; width: 100%; height: 44px; padding: 0 14px; border: 0; background: transparent; outline: none;
  color: var(--chalk); font-size: 16px; line-height: 20px; caret-color: var(--cream);
}
.well input::placeholder { color: var(--text-3); }
.well input:-webkit-autofill { -webkit-text-fill-color: var(--chalk); transition: background-color 99999s; }

/* ---- before a match: what this is ------------------------------------------- */

.intro { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: 40px; flex: none; padding: 20px; border-bottom: 1px solid var(--rule); }
.arena.in-match .intro { display: none; }   /* once a match is on, the board matters more */
.intro-title { font-size: 44px; font-weight: 800; font-stretch: 76%; line-height: 40px; letter-spacing: -.01em; }
.intro-title span { display: block; white-space: nowrap; }
.intro-copy { display: flex; flex-direction: column; gap: 4px; max-width: 64ch; }
.intro-sub { font-size: 16px; line-height: 24px; color: var(--text-2); text-wrap: pretty; }
.intro-card { font-size: 14px; line-height: 20px; color: var(--text-3); }

/* ---- the scorebug: two corners and the clock --------------------------------- */

.scoreboard { display: grid; grid-template-columns: minmax(0, 1fr) 216px minmax(0, 1fr); flex: none; border-bottom: 1px solid var(--rule); background: var(--arena); }
.corner {
  --seat: var(--blue);
  display: flex; flex-direction: column; gap: 6px; min-width: 0; padding: 14px 20px 14px 26px;
  box-shadow: inset 6px 0 0 var(--seat);
  transition: background-color .2s var(--ease), color .2s var(--ease);
}
.corner.red { --seat: var(--red); align-items: flex-end; padding: 14px 26px 14px 20px; box-shadow: inset -6px 0 0 var(--seat); text-align: right; }
/* The corner to move, and the winner: a solid block of its colour. */
.corner.active { background: var(--seat); color: #fff; }
.corner-head { display: flex; align-items: baseline; gap: 10px; width: 100%; min-width: 0; }
.corner.red .corner-head { flex-direction: row-reverse; }
.corner-name { min-width: 0; overflow: hidden; font-size: 34px; font-weight: 800; font-stretch: 78%; line-height: 36px; text-overflow: ellipsis; white-space: nowrap; }
.corner-label { flex: none; font-size: 13px; line-height: 20px; color: var(--text-3); white-space: nowrap; }
.chip { font-size: 14px; font-weight: 600; line-height: 20px; color: var(--text-3); white-space: nowrap; }
.corner-head .chip { margin-left: auto; }
.corner.red .corner-head .chip { margin-left: 0; margin-right: auto; }
.corner-goal { max-width: 64ch; min-height: 22px; font-size: 15px; line-height: 22px; color: var(--text-2); text-wrap: pretty; }
.corner-foot { display: flex; align-items: center; gap: 12px; width: 100%; min-height: 24px; }
.corner.red .corner-foot { flex-direction: row-reverse; }
.pips { display: flex; gap: 3px; }
.pip { width: 14px; height: 6px; background: var(--raised-hi); }
.pip.used { background: var(--seat); }
.pip.now { background: var(--chalk); }
.turns-count { font-size: 13px; line-height: 20px; color: var(--text-3); font-variant-numeric: tabular-nums; white-space: nowrap; }
.corner.active .corner-label, .corner.active .chip, .corner.active .corner-goal, .corner.active .turns-count { color: #fff; }
.corner.active .pip { background: rgba(255, 255, 255, .34); }
.corner.active .pip.used { background: #fff; }
.corner.active .pip.now { background: var(--arena); }
/* One return from winning. */
.chip.point { margin-left: auto; padding: 2px 8px; background: var(--chalk); color: var(--arena); font-size: 13px; }
.corner.red .chip.point { margin-left: 0; margin-right: auto; }
.chip.point code { color: inherit; }

.clock {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; padding: 10px 12px;
  border-left: 1px solid var(--rule); border-right: 1px solid var(--rule); text-align: center;
}
.clock-label { font-size: 14px; line-height: 20px; color: var(--text-2); }
.clock-face {
  display: flex; align-items: center; justify-content: center; height: 60px;
  font: 700 60px/60px var(--mono); font-stretch: 100%; font-variant-numeric: tabular-nums; color: var(--chalk);
  transition: color .2s var(--ease);
}
.clock-words { font: 800 26px/32px var(--font); font-stretch: 80%; color: var(--text-2); }
.clock-detail { font-size: 13px; line-height: 18px; color: var(--text-3); font-variant-numeric: tabular-nums; }
.clock.urgent .clock-face { color: var(--bell); }
/* Each digit is a column of 0 to 9 that slides to the one it shows. */
.flip { display: inline-flex; }
.roll { display: inline-block; height: 60px; overflow: hidden; }
.roll-strip { display: flex; flex-direction: column; transition: transform .32s var(--ease); }
.roll-strip span { display: block; height: 60px; }

/* ---- news about the match ----------------------------------------------------- */

.notice {
  display: flex; align-items: baseline; gap: 10px; flex: none; padding: 8px 20px; border-bottom: 1px solid var(--rule);
  font-size: 14px; line-height: 20px; color: var(--text-2); animation: rise .25s var(--ease);
}
.notice::before { content: ""; flex: none; align-self: center; width: 8px; height: 8px; background: var(--text-3); }
.notice[data-tone="blue"]::before { background: var(--blue); }
.notice[data-tone="red"]::before { background: var(--red); }
.notice[data-tone="winner"] { color: var(--chalk); font-weight: 600; }
.notice[data-tone="winner"]::before { background: var(--turn-fill); }
.notice[data-tone="error"]::before { background: var(--danger); }
.notice-label { flex: none; font-weight: 600; color: var(--chalk); }
@keyframes rise { from { opacity: 0; transform: translateY(6px); } }

/* ---- workspace: the ring on the left, the tape and the log on the right ------- */

.workspace-grid { display: grid; grid-template-columns: minmax(0, 11fr) minmax(0, 9fr); }
.workspace-aside { display: flex; flex-direction: column; min-width: 0; }
.panel { display: flex; flex-direction: column; min-width: 0; }
.editor-panel { position: relative; border-right: 1px solid var(--rule); }
.history-panel { border-top: 1px solid var(--rule); }
.panel-header { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex: none; min-height: 44px; padding: 0 20px; }
.panel-header h2 { font-size: 18px; font-weight: 700; font-stretch: 84%; line-height: 24px; }

/* The shared function. */
.editor-panel.shake { animation: shake .28s var(--ease); }
@keyframes shake { 25% { transform: translateX(-5px); } 50% { transform: translateX(4px); } 75% { transform: translateX(-2px); } }
/* The turn's time, where the mover is looking. */
.time-bar { flex: none; height: 3px; background: var(--rule); }
.time-bar i { display: block; height: 100%; background: var(--turn-fill); transform: scaleX(0); transform-origin: left center; }
body.urgent .time-bar i { background: var(--bell); }
.editor-header h2 { font: 400 13px/20px var(--mono); font-stretch: 87.5%; color: var(--text-2); }
.editor-badges { display: flex; align-items: center; gap: 8px; }
.file-dot { width: 6px; height: 6px; background: var(--chalk); }
.file-dot:not([hidden]) + .pill { color: var(--chalk); }

/* The code scrolls here, never the page. */
.editor-scroll {
  position: relative; min-height: 232px; overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain;
  border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule); background: var(--ring);
}
.editor-shell { position: relative; display: flex; min-height: 100%; }
.editor-shell.punch { animation: punch .11s var(--ease); }
.editor-shell.thud { animation: thud .16s var(--ease); }
@keyframes punch { 40% { transform: translateY(2px); } }
@keyframes thud { 40% { transform: translateY(3px); } }
/* Gutter: who wrote the line, a lock if it cannot be retyped, and its number. */
.line-gutter { flex: none; width: 76px; padding: 16px 0; font: 400 12px/var(--row) var(--mono); font-stretch: 87.5%; color: var(--text-3); user-select: none; }
.line-gutter div { display: flex; align-items: center; justify-content: flex-end; gap: 6px; height: var(--row); padding-right: 14px; border-left: 4px solid transparent; }
.line-gutter div.blue { border-left-color: var(--blue); }
.line-gutter div.red { border-left-color: var(--red); }
.lock {
  display: inline-block; flex: none; width: 11px; height: 11px; background: currentColor; opacity: .75;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect width='18' height='11' x='3' y='11' rx='2'/%3E%3Cpath d='M7 11V7a5 5 0 0 1 10 0v4'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect width='18' height='11' x='3' y='11' rx='2'/%3E%3Cpath d='M7 11V7a5 5 0 0 1 10 0v4'/%3E%3C/svg%3E") center / contain no-repeat;
}
.line-gutter div.deny, .line-gutter div.fault { color: var(--danger-text); }
.line-gutter div.deny .lock { opacity: 1; }
/* Point between two lines and this appears in the margin: press it for a new line there. */
.insert-line {
  position: absolute; z-index: 4; left: 10px; top: 4px; display: grid; place-items: center; width: 24px; height: 24px; padding: 0;
  border: 1px solid var(--rule-strong); border-radius: var(--r); background: var(--raised-hi); color: var(--chalk);
  transform: translateY(calc(var(--at, 1) * var(--row)));
  transition: background-color .12s var(--ease), color .12s var(--ease), scale .1s var(--ease);
}
.insert-line::after { content: ""; position: absolute; left: 100%; top: 50%; width: 200vw; height: 2px; margin-top: -1px; background: var(--turn-fill); opacity: 0; pointer-events: none; }
.insert-line:hover { border-color: transparent; background: var(--turn-fill); color: var(--turn-on); }
.insert-line:active { scale: .88; }
.insert-line .icon { transition: transform .2s var(--ease); }
.insert-line:hover .icon { transform: rotate(90deg); }
.insert-line:hover::after { opacity: 1; }
.code-region { position: relative; flex: 1; min-width: 0; overflow: hidden; font: 400 var(--code-size)/var(--row) var(--mono); font-stretch: 87.5%; }
/* The row the caret is on. On a locked row there is no caret, only a hold on the line. */
.caret-row { position: absolute; left: 0; right: 0; top: 16px; height: var(--row); pointer-events: none; transform: translateY(calc(var(--caret, 0) * var(--row))); }
.editor-shell:focus-within .caret-row { background: rgba(243, 241, 236, .07); }
.caret-row.hit { animation: row-hit .2s var(--ease); }
@keyframes row-hit { from { background: rgba(243, 241, 236, .2); box-shadow: inset 3px 0 0 var(--turn); } }
.editor-shell:focus-within .caret-row[data-kind="locked"] { background: var(--raised-hi); box-shadow: inset 0 0 0 1px var(--rule-strong); }
.caret-row[data-kind="locked"]::after {
  content: "Locked. ↵ adds a line below, Alt ↑ ↓ moves it"; position: absolute; right: 12px; top: 0;
  font: 400 12px/var(--row) var(--font); color: var(--text-2); opacity: 0;
}
.editor-shell:focus-within .caret-row[data-kind="locked"]::after { opacity: 1; }
.row-marks { position: absolute; inset: 0; padding: 16px 0; pointer-events: none; }
.row-marks div { height: var(--row); }
.row-marks div.fresh { background: rgba(243, 241, 236, .05); box-shadow: inset 3px 0 0 var(--chalk); }
.row-marks div.moved { box-shadow: inset 3px 0 0 var(--text-3); }
.row-marks div.fault { background: var(--danger-soft); box-shadow: inset 3px 0 0 var(--danger); }
.row-marks div.deny { animation: deny .5s var(--ease); }
@keyframes deny { 0%, 30% { background: var(--danger-soft); box-shadow: inset 3px 0 0 var(--danger); } }
.code-region pre, .code-region textarea {
  position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; border: 0; padding: 16px 24px 16px 12px;
  font: inherit; font-variant-ligatures: none; tab-size: 4; letter-spacing: 0;
  white-space: pre; word-wrap: normal; word-break: normal;
  overflow-x: auto; overflow-y: hidden; resize: none; background: transparent;
}
.code-region pre { pointer-events: none; scrollbar-width: none; color: var(--code); }
.code-region pre::-webkit-scrollbar { display: none; }
.code-region pre code { font: inherit; color: inherit; }
.code-region textarea { color: transparent; caret-color: var(--turn); -webkit-text-fill-color: transparent; outline: none; }
.code-region textarea.on-locked { caret-color: transparent; }
.code-region textarea::selection { background: rgba(243, 241, 236, .2); }
.syntax-keyword { color: var(--code-keyword); }
.syntax-name { color: var(--code-name); }
.syntax-string, .syntax-number { color: var(--code-literal); }
.syntax-comment { color: var(--text-3); }
/* A keystroke lands: the glyph drops onto the line in the mover's colour. */
.key-ghost {
  position: absolute; z-index: 2; pointer-events: none; color: var(--turn); font-weight: 600; transform-origin: 50% 55%;
  animation: key-land .26s var(--ease) forwards;
}
@keyframes key-land { from { opacity: 1; transform: translateY(-10px) scale(3); } 60% { opacity: .9; } to { opacity: 0; transform: none; } }
/* A note pinned to the end of one row: why a locked line refused a key, or where a move failed. */
.row-tag {
  position: absolute; z-index: 3; right: 12px; top: 18px; height: calc(var(--row) - 4px); padding: 0 8px; border-radius: var(--r);
  background: var(--danger); color: #fff; font: 600 12px/calc(var(--row) - 4px) var(--font); white-space: nowrap; pointer-events: none;
  transform: translateY(calc(var(--at, 0) * var(--row)));
}
.deny-hint { animation: rise .2s var(--ease); }
.fault-tag { background: var(--danger-card); color: var(--danger-text); box-shadow: inset 0 0 0 1px rgba(255, 77, 79, .6); }

.line-check {
  display: flex; align-items: baseline; gap: 12px; flex: none; padding: 10px 20px; border-bottom: 1px solid var(--rule);
  font-size: 14px; line-height: 20px; color: var(--text-2);
}
.line-check .label { flex: none; font-weight: 600; color: var(--text-3); }
.line-check.good .label { color: var(--ok); }
.line-check.bad { color: var(--chalk); }
.line-check.bad .label { color: var(--danger-text); }

.editor-legend {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px 16px; flex: none; padding: 8px 20px;
  border-bottom: 1px solid var(--rule); font-size: 13px; line-height: 20px; color: var(--text-3);
}
.editor-legend > span { display: inline-flex; align-items: center; gap: 8px; }
.editor-legend span span, .editor-legend > span:not(.editor-keys) { white-space: nowrap; }
.editor-keys { flex-wrap: wrap; margin-left: auto; gap: 6px 14px; }
.editor-keys span { display: inline-flex; align-items: center; gap: 4px; }
.swatch { display: inline-block; flex: none; width: 4px; height: 12px; }
.swatch.blue { background: var(--blue); }
.swatch.red { background: var(--red); }
.swatch.fresh { background: var(--chalk); }
.swatch.moved { background: var(--text-3); }

.editor-actions { position: relative; display: flex; flex-wrap: wrap; align-items: center; gap: 16px; flex: none; padding: 12px 20px; }
.submission-hint { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.submission-hint strong { font-size: 20px; font-weight: 800; font-stretch: 84%; line-height: 24px; color: var(--turn); }
.action-line { display: flex; align-items: center; gap: 8px; font-size: 13px; line-height: 20px; color: var(--text-2); }
/* Attempts left this turn: one mark each, hollow once spent. */
.attempts { display: inline-flex; gap: 4px; flex: none; }
.attempts i { width: 8px; height: 8px; background: var(--chalk); }
.attempts i.spent { background: transparent; box-shadow: inset 0 0 0 1.5px var(--text-3); }
.submit-buttons { display: flex; align-items: flex-start; gap: 8px; flex: none; }

/* Targets and values. */
.values-intro { max-width: 76ch; padding: 0 20px 10px; font-size: 14px; line-height: 20px; color: var(--text-2); text-wrap: pretty; }
.values-intro strong { color: var(--chalk); }
.table-scroll { flex: none; overflow-x: auto; border-top: 1px solid var(--rule); }
.values-table { width: 100%; border-collapse: collapse; font: 400 14px/20px var(--mono); font-stretch: 87.5%; font-variant-numeric: tabular-nums; }
.values-table th, .values-table td { height: 36px; padding: 0 12px; border-bottom: 1px solid var(--rule); text-align: left; white-space: nowrap; }
.values-table th:first-child { position: sticky; left: 0; padding-left: 20px; background: var(--arena); }
.values-table thead th { font-weight: 400; color: var(--text-3); }
.values-table tbody th { font-weight: 400; color: var(--chalk); }
.values-table tr.target th { font: 600 14px/20px var(--font); }
.values-table tr.target.blue th, .values-table tr.target.blue td { color: var(--blue-text); }
.values-table tr.target.red th, .values-table tr.target.red td { color: var(--red-text); border-bottom-color: var(--rule-strong); }
/* A lit value: it equals that player's target on this input. */
.values-table td.hit-blue { background: var(--blue); color: #fff; }
.values-table td.hit-red { background: var(--red); color: #fff; }
.values-table td.hit-blue.hit-red { background: linear-gradient(90deg, var(--blue) 50%, var(--red) 50%); }
.values-table td.unset { color: var(--text-3); }
.values-table td.changed { animation: cell-flash 1s var(--ease); }
@keyframes cell-flash { 0%, 35% { box-shadow: inset 0 0 0 2px var(--chalk); } }
/* What duel returns, once it has a return. */
.values-table tr.returned th, .values-table tr.returned td { border-top: 1px solid var(--rule-strong); font-weight: 700; }
.values-table tr.returned th { font-family: var(--font); font-stretch: 100%; }
.tag { margin-left: 8px; font: 600 12px/20px var(--font); font-stretch: 100%; white-space: nowrap; }
.tag.blue { color: var(--blue-text); }
.tag.red { color: var(--red-text); }
.target-footnote { flex: none; padding: 10px 20px 12px; font-size: 13px; line-height: 20px; color: var(--text-3); text-wrap: pretty; }

/* Blow by blow. */
.count-badge { font-size: 14px; line-height: 20px; font-variant-numeric: tabular-nums; color: var(--text-3); }
.history-list { max-height: 252px; overflow-y: auto; overscroll-behavior: contain; border-top: 1px solid var(--rule); }
.history-item {
  display: grid; grid-template-columns: 24px 8px minmax(0, 1fr) auto; align-items: center; gap: 10px;
  min-height: 36px; padding: 6px 20px; border-bottom: 1px solid var(--rule); font-size: 14px; line-height: 20px; color: var(--text-2);
}
.history-item.fresh { animation: rise .3s var(--ease); }
.history-turn, .history-seconds { font-size: 13px; line-height: 20px; font-variant-numeric: tabular-nums; color: var(--text-3); }
.history-dot { width: 8px; height: 8px; background: var(--blue); }
.history-item.red .history-dot { background: var(--red); }
.history-what { min-width: 0; text-wrap: pretty; }
.history-what b { font-weight: 600; color: var(--chalk); }
.history-empty { display: flex; flex-direction: column; gap: 2px; padding: 14px 20px; font-size: 14px; line-height: 20px; color: var(--text-3); }
.history-empty strong { color: var(--text-2); }

.arena-footer { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 4px 16px; flex: none; padding: 6px 20px; border-top: 1px solid var(--rule); font-size: 12px; line-height: 16px; color: var(--text-3); }

/* ---- a move was rejected: what went wrong, where, and what to do -------------- */

.reject-pop {
  position: absolute; z-index: 5; right: 20px; bottom: calc(100% - 4px); display: flex; align-items: flex-start; gap: 12px;
  width: min(480px, calc(100% - 40px)); padding: 12px 12px 14px 14px;
  border: 1px solid rgba(255, 77, 79, .6); border-left: 4px solid var(--danger); border-radius: var(--r);
  background: var(--danger-card); color: var(--chalk); box-shadow: 0 16px 40px rgba(0, 0, 0, .5);
  font-size: 14px; line-height: 20px; animation: pop-in .22s var(--ease);
}
.reject-pop::after {
  content: ""; position: absolute; right: 68px; bottom: -6px; width: 10px; height: 10px; background: var(--danger-card);
  border-right: 1px solid rgba(255, 77, 79, .6); border-bottom: 1px solid rgba(255, 77, 79, .6); transform: rotate(45deg);
}
.reject-pop > .icon { width: 18px; height: 18px; margin-top: 2px; color: var(--danger); }
.reject-body { display: flex; flex: 1; flex-direction: column; gap: 6px; min-width: 0; }
#reject-label { font-size: 18px; font-weight: 800; font-stretch: 84%; line-height: 22px; color: var(--danger-text); }
#reject-text { text-wrap: pretty; overflow-wrap: anywhere; }
.reject-facts { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 2px 12px; margin: 0; padding: 8px 0; border-top: 1px solid rgba(255, 77, 79, .3); border-bottom: 1px solid rgba(255, 77, 79, .3); font-size: 13px; }
.reject-facts dt { color: var(--text-2); }
.reject-facts dd { margin: 0; font-family: var(--mono); font-stretch: 87.5%; overflow-wrap: anywhere; }
.reject-next { font-size: 13px; color: var(--text-2); }
.reject-pop .icon-button { margin: -4px -4px 0 0; }
@keyframes pop-in { from { opacity: 0; transform: translateY(8px); } }

/* ---- dialogs ------------------------------------------------------------------
   Cut with the same stepped corners as the keys. The head and the foot stay
   where they are and the body scrolls between them. */

.modal {
  --step: 5px; --turn-fill: var(--cream); --turn-on: var(--ink);
  position: fixed; inset: 0; width: min(620px, calc(100% - 32px)); height: fit-content; max-height: calc(100dvh - 48px);
  margin: auto; padding: 1px; overflow: hidden; border: 0; background: #3f3f48; color: var(--chalk); clip-path: var(--stepped);
}
.modal[open] { display: flex; animation: modal-in .26s var(--ease); }
.modal::backdrop { background: rgba(4, 4, 7, .78); animation: fade .2s ease-out; }
.modal.shake { animation: shake .28s var(--ease); }
@keyframes modal-in { from { opacity: 0; transform: translateY(12px) scale(.985); } }
@keyframes fade { from { opacity: 0; } }
.modal-frame { display: flex; flex: 1; flex-direction: column; min-width: 0; min-height: 0; background: #111116; clip-path: var(--stepped); }
.modal-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; flex: none; padding: 22px 20px 16px 24px; }
.modal-titles { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.modal-head h2 { font-size: 32px; font-weight: 800; font-stretch: 78%; line-height: 34px; text-wrap: balance; overflow-wrap: anywhere; }
.modal-sub { max-width: 62ch; font-size: 15px; line-height: 22px; color: var(--text-2); text-wrap: pretty; }
.modal-body { display: flex; flex: 1; flex-direction: column; gap: 20px; min-height: 0; padding: 4px 24px 24px; overflow-y: auto; overscroll-behavior: contain; }
.modal-foot { display: flex; align-items: center; gap: 12px; flex: none; padding: 14px 24px 14px; border-top: 1px solid var(--rule); }
.modal-foot .spacer { flex: 1; }
.modal-note { font-size: 13px; line-height: 20px; color: var(--text-3); text-wrap: pretty; }

.field { display: flex; flex-direction: column; gap: 8px; min-width: 0; margin: 0; padding: 0; border: 0; }
.field-label { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding: 0; font-size: 13px; font-weight: 600; line-height: 20px; color: var(--text-2); }
.field-note { font-size: 13px; font-weight: 400; line-height: 18px; color: var(--text-3); }
.field-note.bad { color: var(--danger-text); }
.field-note.good { color: var(--ok); }
.field-note.warn { color: var(--chalk); }
.optional { font-weight: 400; color: var(--text-3); }
.form-error { font-size: 14px; line-height: 20px; color: var(--danger-text); text-wrap: pretty; }
.restart-warning { font-size: 14px; line-height: 20px; color: var(--bell); }
.key-set { display: flex; gap: 6px; }
.key-set > .key { flex: 1 1 0; }
.well.blue::after, .well.red::after { content: ""; position: absolute; left: 1px; top: 1px; bottom: 1px; width: 4px; background: var(--blue); }
.well.red::after { background: var(--red); }
.well.blue input, .well.red input { padding-left: 18px; }

/* Setting up a local match. */
.scenario-options { display: flex; flex-direction: column; border-top: 1px solid var(--rule); }
.scenario-option {
  position: relative; display: flex; flex-direction: column; gap: 4px; padding: 12px 44px 12px 16px;
  border-bottom: 1px solid var(--rule); box-shadow: inset 4px 0 0 transparent; cursor: pointer;
  transition: background-color .15s var(--ease), box-shadow .15s var(--ease), padding .15s var(--ease);
}
.scenario-option input { position: absolute; opacity: 0; width: 1px; height: 1px; }
@media (hover: hover) { .scenario-option:hover { background: var(--raised); box-shadow: inset 4px 0 0 var(--text-3); } }
.scenario-option:active { background: var(--raised-hi); }
.scenario-option:has(input:checked) { background: var(--raised-hi); box-shadow: inset 4px 0 0 var(--cream); }
.scenario-option:has(input:focus-visible) { outline: 2px solid var(--chalk); outline-offset: -2px; }
/* The mark at the end of the row is a pip, lit for the scenario that is chosen. */
.scenario-option::after {
  content: ""; position: absolute; top: 18px; right: 16px; width: 14px; height: 14px; background: transparent;
  box-shadow: inset 0 0 0 1.5px var(--text-3); transition: background-color .15s var(--ease), box-shadow .15s var(--ease), transform .2s var(--spring);
}
.scenario-option:has(input:checked)::after { background: var(--cream); box-shadow: inset 0 0 0 1.5px var(--cream), inset 0 0 0 4px var(--raised-hi); transform: scale(1.1); }
.scenario-option strong { font-size: 18px; font-weight: 700; font-stretch: 84%; line-height: 24px; }
.scenario-option .about { font-size: 14px; line-height: 20px; color: var(--text-2); }
.goals { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 16px; margin-top: 4px; font-size: 13px; line-height: 20px; color: var(--text-2); }
.goals span { padding-left: 8px; border-left: 3px solid var(--blue); }
.goals .red { border-left-color: var(--red); }
.setup-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 16px; }
.setup-foot { flex-direction: column; align-items: stretch; gap: 10px; padding-bottom: 16px; }

/* ---- the account: log in, register, or your record ----------------------------- */

.account-modal { width: min(440px, calc(100% - 32px)); }
.account-heading { display: flex; align-items: center; gap: 14px; min-width: 0; }
.account-heading .player-avatar { width: 44px; height: 44px; }
.account-heading .player-avatar.guest { opacity: .38; filter: grayscale(1); }
.account-form, .account-profile { gap: 16px; }
.well .peek {
  display: grid; place-items: center; flex: none; width: 44px; height: 44px; padding: 0; border: 0; background: none;
  color: var(--text-3); cursor: pointer; transition: color .15s var(--ease), transform .12s var(--ease);
}
.well .peek:hover, .well .peek:focus-visible { color: var(--chalk); }
.well .peek:active { transform: scale(.86); }
.well .peek:focus-visible { outline: 2px solid var(--chalk); outline-offset: -6px; }
.peek .eye-off, .peek[aria-pressed="true"] .eye-on { display: none; }
.peek[aria-pressed="true"] .eye-off { display: block; }
/* Eight pips, one for each character the password still needs. */
.length-pips { display: inline-flex; gap: 3px; }
.length-pips i { width: 10px; height: 5px; background: var(--raised-hi); transition: background-color .12s var(--ease), transform .2s var(--spring); }
.length-pips i.on { background: var(--chalk); transform: scaleY(1.4); }
.length-pips.full i { background: var(--ok); }
.rank-stats { display: grid; grid-template-columns: 1.3fr repeat(3, 1fr); margin: 0; border: 1px solid var(--rule); }
.rank-stats div { display: flex; flex-direction: column-reverse; gap: 2px; padding: 12px 14px; border-left: 1px solid var(--rule); }
.rank-stats div:first-child { border-left: 0; }
.rank-stats dt { font-size: 13px; line-height: 18px; color: var(--text-3); }
.rank-stats dd { margin: 0; font: 700 26px/30px var(--mono); font-stretch: 100%; font-variant-numeric: tabular-nums; color: var(--chalk); }

/* ---- how to play ----------------------------------------------------------------
   Four chapters with one idea each. The pictures use the board's own marks, so
   reading them teaches the board. */

.guide { width: min(1010px, calc(100% - 32px)); }
.guide-tabs { display: flex; gap: 6px; flex: none; padding: 0 24px 13px; border-bottom: 1px solid var(--rule); overflow-x: auto; scrollbar-width: none; }
.guide-tabs::-webkit-scrollbar { display: none; }
.guide-tab b { font: 600 11px/1 var(--mono); font-stretch: 100%; opacity: .55; }
/* Every chapter gets the same room, so the foot never jumps. */
.guide-body { flex: none; height: min(556px, calc(100dvh - 290px)); min-height: 220px; padding: 0; gap: 0; }
/* Words on the left, the picture on the right, and the picture's column runs to the foot. */
.guide-panel { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); grid-template-rows: 1fr auto; flex: 1; min-height: 100%; }
.guide-panel[hidden] { display: none; }
.guide-panel:focus-visible { outline: 2px solid var(--chalk); outline-offset: -2px; }
.guide-panel > * { animation: panel-in .3s var(--ease) backwards; }
.guide-panel > :nth-child(2) { animation-delay: .05s; }
.guide-panel > :nth-child(3) { animation-delay: .1s; }
@keyframes panel-in { from { opacity: 0; transform: translateY(8px); } }
.guide-copy, .guide-intro { display: flex; flex-direction: column; gap: 12px; padding: 22px 24px 24px; }
.guide-intro { grid-column: 1 / -1; flex-direction: row; align-items: baseline; gap: 8px 24px; flex-wrap: wrap; padding-bottom: 16px; }
.guide-panel h3 { font-size: 28px; font-weight: 800; font-stretch: 78%; line-height: 30px; text-wrap: balance; }
.guide-panel h4 { font-size: 19px; font-weight: 800; font-stretch: 84%; line-height: 24px; }
.guide-panel p { font-size: 15px; line-height: 23px; color: var(--text-2); text-wrap: pretty; }
.guide-panel p strong { color: var(--chalk); }
.guide-intro p { flex: 1 1 320px; }
.guide-panel .guide-aside { padding-left: 12px; border-left: 3px solid var(--rule-strong); font-size: 14px; line-height: 21px; color: var(--text-3); }
.guide-legend { display: flex; flex-direction: column; gap: 6px; margin: 4px 0 0; padding: 14px 0 0; border-top: 1px solid var(--rule); list-style: none; font-size: 13px; line-height: 20px; color: var(--text-2); }
.guide-legend li { display: grid; grid-template-columns: 18px minmax(0, 1fr); align-items: center; gap: 10px; }
.guide-legend .mark { display: flex; gap: 4px; }
.guide-legend .swatch { height: 14px; }
.guide-legend .lit { width: 14px; height: 14px; background: var(--blue); }
.guide-figure, .guide-side { display: flex; flex-direction: column; gap: 14px; min-width: 0; margin: 0; padding: 22px 24px 24px; border-left: 1px solid var(--rule); background: #0c0c10; }
.guide-figure figcaption { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; font-size: 14px; line-height: 21px; color: var(--text-2); }
.guide-figure .chip.point { margin: 0; flex: none; }

/* A few lines of the function, marked the way the editor marks them. */
.fig-code { min-width: 0; padding: 6px 0; border: 1px solid var(--rule); background: var(--ring); color: var(--code); font: 400 13px/24px var(--mono); font-stretch: 87.5%; }
.fig-row { display: grid; grid-template-columns: 34px minmax(0, 1fr); align-items: center; height: 24px; border-left: 4px solid transparent; }
.fig-row.blue { border-left-color: var(--blue); }
.fig-row.red { border-left-color: var(--red); }
.fig-no { display: flex; align-items: center; justify-content: flex-end; gap: 3px; padding-right: 10px; font-size: 11px; color: var(--text-3); white-space: nowrap; -webkit-user-select: none; user-select: none; }
.fig-no .lock { width: 9px; height: 9px; }
.fig-row code { display: block; height: 24px; padding: 0 10px 0 8px; overflow: hidden; color: inherit; font-size: inherit; text-overflow: ellipsis; white-space: pre; }
.fig-row.fresh code { background: rgba(243, 241, 236, .06); box-shadow: inset 3px 0 0 var(--chalk); }
.fig-row.moved code { box-shadow: inset 3px 0 0 var(--text-3); }
.fig-row.gone code { color: var(--text-3); text-decoration: line-through; text-decoration-color: var(--danger); }
.fig-row.later code { opacity: .45; }
.fig-values { font-size: 12px; line-height: 18px; border: 1px solid var(--rule); border-bottom: 0; }
.fig-values th, .fig-values td { height: 28px; padding: 0 10px; }
.fig-values th:first-child { position: static; padding-left: 14px; background: transparent; }
.fig-values tr.target th { font-size: 13px; }
.fig-scroll { min-width: 0; overflow-x: auto; }

/* Chapter two: the three beats of a turn, what a return does, and the numbers. */
.guide-steps { display: flex; flex-direction: column; margin: 4px 0 0; padding: 0; list-style: none; }
.guide-steps li { display: grid; grid-template-columns: 28px minmax(0, 1fr); gap: 14px; padding: 12px 0; border-top: 1px solid var(--rule); }
.guide-steps b { display: grid; place-items: center; width: 28px; height: 28px; background: var(--chalk); color: var(--arena); font: 700 13px/1 var(--mono); font-stretch: 100%; }
.guide-steps strong { font-size: 17px; font-weight: 700; font-stretch: 84%; line-height: 28px; }
.guide-steps p { font-size: 14px; line-height: 21px; }
.outcomes { display: flex; flex-direction: column; margin: 0; padding: 0; list-style: none; border-top: 1px solid var(--rule); }
.outcomes li { display: grid; grid-template-columns: minmax(0, 1fr) 20px minmax(0, 1fr); align-items: center; gap: 10px; min-height: 52px; padding: 8px 0; border-bottom: 1px solid var(--rule); font-size: 14px; line-height: 20px; color: var(--text-2); }
.outcomes .icon { color: var(--text-3); }
.outcomes strong { color: var(--chalk); }
.guide-numbers { grid-column: 1 / -1; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); margin: 0; padding: 0; list-style: none; border-top: 1px solid var(--rule); }
.guide-numbers li { display: flex; flex-direction: column; gap: 2px; padding: 16px 24px 18px; border-left: 1px solid var(--rule); }
.guide-numbers li:first-child { border-left: 0; }
.guide-numbers b { font: 700 44px/46px var(--mono); font-stretch: 100%; font-variant-numeric: tabular-nums; color: var(--chalk); }
.guide-numbers strong { font-size: 15px; line-height: 20px; }
.guide-numbers span { font-size: 13px; line-height: 19px; color: var(--text-3); text-wrap: pretty; }

/* Chapter three: the six moves. Chapter four: what is refused. */
.guide-panel.wide { grid-template-rows: none; align-content: start; }
.move-grid, .limit-list { grid-column: 1 / -1; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); border-top: 1px solid var(--rule); }
.limit-list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.move, .limit { display: flex; flex-direction: column; gap: 10px; min-width: 0; padding: 14px 18px 16px 24px; border-bottom: 1px solid var(--rule); border-left: 1px solid var(--rule); }
.move:nth-child(3n + 1), .limit:nth-child(odd) { border-left: 0; }
.move header { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 24px; }
.move-keys { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 4px; font-size: 13px; line-height: 20px; color: var(--text-3); }
.move .fig-code { font-size: 12px; }
.move p, .limit p { font-size: 13px; line-height: 19px; }
.guide-panel > .guide-aside { grid-column: 1 / -1; margin: 14px 24px 16px; }
.checks { display: flex; flex-direction: column; gap: 4px; margin: 2px 0 0; padding: 0; list-style: none; }
.checks li { display: grid; grid-template-columns: 58px minmax(0, 1fr) auto; align-items: center; gap: 10px; min-height: 28px; padding: 0 10px; background: var(--ring); font-size: 12px; line-height: 18px; color: var(--text-3); }
.checks .label { font-weight: 600; color: var(--ok); }
.checks .bad .label { color: var(--danger-text); }
.checks code { overflow: hidden; font-size: 12px; color: var(--code); text-overflow: ellipsis; white-space: nowrap; }
.builtins { display: flex; flex-wrap: wrap; gap: 4px; }
.builtins code { padding: 1px 6px; background: var(--ring); color: var(--code-name); font-size: 12px; line-height: 20px; }

.guide-foot { gap: 10px; }
.guide-progress { display: flex; gap: 3px; }
.guide-progress i { width: 18px; height: 6px; background: var(--raised-hi); transition: background-color .2s var(--ease); }
.guide-progress i.on { background: var(--chalk); }
.guide-count { margin-right: auto; font-size: 13px; line-height: 20px; color: var(--text-3); font-variant-numeric: tabular-nums; }

.noscript-notice { position: fixed; left: 16px; right: 16px; bottom: 16px; padding: 16px; background: var(--chalk); color: var(--arena); }

/* ---- a window big enough to play in: nothing scrolls the page ---------------- */

@media (min-width: 960px) and (min-height: 560px) {
  .shell { height: 100dvh; overflow: hidden; }
  .arena { min-height: 0; }
  .workspace-grid { flex: 1; min-height: 0; grid-template-rows: minmax(0, 1fr); }
  .editor-panel, .workspace-aside { min-height: 0; }
  .editor-scroll { flex: 1; min-height: 0; }
  .line-check { max-height: 92px; overflow-y: auto; }
  .values-panel { flex: 0 1 auto; min-height: 0; overflow-y: auto; }
  .history-panel { flex: 1 1 0; min-height: 104px; }
  .history-list { flex: 1; min-height: 0; max-height: none; }
}
/* Short windows give the room to the board. */
@media (min-width: 960px) and (min-height: 560px) and (max-height: 760px) {
  .corner { gap: 2px; padding-top: 10px; padding-bottom: 10px; }
  .corner-name { font-size: 28px; line-height: 30px; }
  .clock-face, .roll, .roll-strip span { height: 48px; }
  .clock-face { font-size: 48px; line-height: 48px; }
  .intro { padding: 12px 20px; }
  .intro-title { font-size: 34px; line-height: 32px; }
  .values-intro, .target-footnote { display: none; }
  .arena-footer { display: none; }
}

/* ---- smaller screens: the page scrolls, and the scorebug stays in view -------- */

@media (max-width: 959px), (max-height: 559px) {
  .workspace-grid { grid-template-columns: minmax(0, 1fr); }
  .editor-panel { border-right: 0; border-bottom: 1px solid var(--rule); }
  .arena.in-match .scoreboard { position: sticky; top: 0; z-index: 20; }
  .local-label, .card-line .label { display: none; }
}
@media (max-width: 720px) {
  .site-header { gap: 12px; padding: 0 8px 0 12px; }
  .card-line { display: none; }
  .intro { grid-template-columns: minmax(0, 1fr); gap: 12px; padding: 16px 12px; }
  .intro-title { font-size: 34px; line-height: 32px; }
  .scoreboard { grid-template-columns: minmax(0, 1fr) 84px minmax(0, 1fr); }
  .corner { gap: 2px; padding: 8px 10px 8px 14px; box-shadow: inset 4px 0 0 var(--seat); }
  .corner.red { padding: 8px 14px 8px 10px; box-shadow: inset -4px 0 0 var(--seat); }
  .corner-head { flex-wrap: wrap; gap: 0 8px; }
  .corner-name { font-size: 22px; line-height: 24px; }
  .corner-label, .pips { display: none; }
  .chip { font-size: 13px; }
  .corner-goal { font-size: 13px; line-height: 18px; }
  .clock { padding: 6px 4px; }
  .clock-label, .clock-detail { font-size: 11px; line-height: 14px; }
  .clock-face, .roll, .roll-strip span { height: 36px; }
  .clock-face { font-size: 34px; line-height: 36px; }
  .clock-words { font-size: 16px; line-height: 20px; }
  .notice, .panel-header, .line-check, .editor-legend, .editor-actions, .target-footnote, .arena-footer { padding-left: 12px; padding-right: 12px; }
  .values-intro { padding: 0 12px 10px; }
  .values-table th:first-child { padding-left: 12px; }
  .history-item, .history-empty { padding-left: 12px; padding-right: 12px; }
  .editor-keys { margin-left: 0; }
  .submit-buttons { width: 100%; }
  .submit-buttons .key { flex: 1; }
  .reject-pop { right: 12px; width: calc(100% - 24px); }
  .setup-grid, .goals { grid-template-columns: minmax(0, 1fr); }
  .modal-head { padding: 18px 14px 14px 18px; }
  .modal-head h2 { font-size: 28px; line-height: 30px; }
  .modal-body { padding: 4px 18px 20px; }
  .modal-foot { padding-left: 18px; padding-right: 18px; }
}

/* The guide on narrower screens: the six moves go to two columns and then one,
   words go above their picture, and each chapter scrolls inside the dialog. */
@media (max-width: 940px) {
  .move-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .move-grid .move { border-left: 1px solid var(--rule); }
  .move-grid .move:nth-child(odd) { border-left: 0; }
}
@media (max-width: 820px) {
  .guide-panel { grid-template-columns: minmax(0, 1fr); grid-template-rows: none; align-content: start; }
  .guide-figure, .guide-side { border-top: 1px solid var(--rule); border-left: 0; }
  .guide-numbers { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .guide-numbers li:nth-child(odd) { border-left: 0; }
  .guide-numbers li:nth-child(n + 3) { border-top: 1px solid var(--rule); }
  .limit-list { grid-template-columns: minmax(0, 1fr); }
  .limit-list .limit { border-left: 0; }
}
@media (max-width: 620px) {
  .move-grid { grid-template-columns: minmax(0, 1fr); }
  .move-grid .move { border-left: 0; }
  .guide-tabs { padding: 0 18px 12px; }
  .guide-copy, .guide-intro, .guide-figure, .guide-side { padding: 18px; }
  .guide-intro { gap: 8px; }
  .guide-intro p { flex-basis: auto; }
  .guide-panel h3 { font-size: 24px; line-height: 26px; }
  .guide-numbers li { padding: 14px 18px 16px; }
  .guide-numbers b { font-size: 36px; line-height: 38px; }
  .move, .limit { padding: 14px 18px 16px; }
  .guide-panel > .guide-aside { margin: 14px 18px 16px; }
  .outcomes li { grid-template-columns: minmax(0, 1fr) 16px minmax(0, 1fr); gap: 8px; }
  .guide-count, #guide-back .key-label { display: none; }
  .guide-progress { margin-right: auto; }
  .guide-progress i { width: 10px; }
  #guide-next { flex: 0 1 auto; }
}

/* With reduced motion switched on, nothing moves: states change at once. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
  .row-marks div.deny { background: var(--danger-soft); box-shadow: inset 3px 0 0 var(--danger); }
}
