/* ============================================================================
   Shared shell for the three datatype games.

   Aesthetic: cassette futurism. A warm amber CRT bolted into a charcoal machine.
   Hard edges, 2px rules, chunky labelled keys, scanlines over everything.
   Chakra Petch for chrome, JetBrains Mono for anything that is actual Python.

   Colour has four jobs and no others: amber is what you are acting on, lime is
   right, red is wrong, cyan is a number worth glancing at. Types are told apart by
   their name, not their hue. See the note at the top of js/data/types.js.
   ========================================================================= */

:root {
  --void:     #100e0b;
  --panel:    #1a1712;
  --panel-hi: #221e17;
  --rule:     #3c352a;
  --rule-hot: #6b5d45;
  --paper:    #efe7d6;
  --dim:      #9b9180;
  --dimmer:   #6e6655;

  --amber:    #ffb000;
  --cyan:     #36d6c3;
  --lime:     #b8e62e;
  --red:      #ff5d73;

  --mono: 'JetBrains Mono', 'Cascadia Mono', Consolas, 'Courier New', monospace;
  --disp: 'Chakra Petch', 'Trebuchet MS', sans-serif;

  --glow-amber: 0 0 12px rgba(255, 176, 0, 0.35);
  --shadow: 0 10px 0 -4px rgba(0, 0, 0, 0.5), 0 18px 40px rgba(0, 0, 0, 0.45);
}

* { box-sizing: border-box; }

/* JetBrains Mono ships code ligatures, and they are wrong for this project.
   It draws <= as a single ≤ glyph, != as ≠, and >= as ≥. Lovely in an editor,
   where you know what you typed. Here the whole exercise is reading Python
   exactly as written, and a student who sees ≤ in a snippet cannot type it, cannot
   search for it, and has been shown a character Python does not use.
   
   Suppressed on the root so it inherits everywhere. It was previously set on `code`
   alone, which covered one of the thirty-seven places the mono font is used and
   missed the belt items, the operator badge and the probe list. */
html {
  font-variant-ligatures: none;
  font-feature-settings: "liga" 0, "clig" 0, "calt" 0, "dlig" 0;
}

html, body { height: 100%; }

body {
  margin: 0;
  background: var(--void);
  background-image:
    radial-gradient(ellipse 120% 80% at 50% -10%, rgba(255, 176, 0, 0.10), transparent 60%),
    radial-gradient(ellipse 90% 70% at 15% 110%, rgba(54, 214, 195, 0.07), transparent 60%);
  color: var(--paper);
  font-family: var(--disp);
  font-size: 16px;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* Scanlines and grain, over everything, never in the way. */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 9999;
  background-image:
    repeating-linear-gradient(
      to bottom,
      rgba(0, 0, 0, 0.16) 0px,
      rgba(0, 0, 0, 0.16) 1px,
      transparent 1px,
      transparent 3px
    );
  mix-blend-mode: multiply;
  opacity: 0.55;
}

/* ------------------------------------------------------------------ layout */

.shell {
  max-width: 1040px;
  margin: 0 auto;
  padding: 24px 20px 72px;
  position: relative;
  z-index: 1;
}

/* ------------------------------------------------------------------ header */

.masthead {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 20px;
  flex-wrap: wrap;
  border-bottom: 2px solid var(--rule);
  padding-bottom: 14px;
  margin-bottom: 26px;
}

.masthead h1 {
  font-size: clamp(1.5rem, 4.2vw, 2.5rem);
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  margin: 0;
  line-height: 0.95;
  color: var(--amber);
  text-shadow: var(--glow-amber);
}

.masthead .sub {
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--dimmer);
  margin-top: 8px;
}

.masthead-right {
  display: flex;
  gap: 10px;
  align-items: center;
  flex-wrap: wrap;
}

/* Readouts: the little boxed numbers along the top of the machine. */
.readout {
  border: 2px solid var(--rule);
  background: var(--panel);
  padding: 5px 11px 6px;
  min-width: 64px;
  text-align: center;
}

.readout .k {
  display: block;
  font-family: var(--mono);
  font-size: 0.56rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--dimmer);
}

.readout .v {
  display: block;
  font-family: var(--mono);
  font-size: 1.12rem;
  font-weight: 700;
  line-height: 1.15;
  color: var(--paper);
  font-variant-numeric: tabular-nums;
}

.readout.hot .v { color: var(--amber); text-shadow: var(--glow-amber); }
.readout.cool .v { color: var(--cyan); }

/* ------------------------------------------------------------------- panels */

.panel {
  background: var(--panel);
  border: 2px solid var(--rule);
  box-shadow: var(--shadow);
  padding: 20px;
  position: relative;
}

.panel > h2, .panel-title {
  margin: 0 0 14px;
  font-size: 0.76rem;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--dim);
  display: flex;
  align-items: center;
  gap: 10px;
}

.panel > h2::after, .panel-title::after {
  content: '';
  flex: 1;
  height: 2px;
  background: var(--rule);
}

/* --------------------------------------------------------------- type chips */

.chip {
  display: inline-block;
  font-family: var(--mono);
  font-size: 0.86rem;
  font-weight: 700;
  padding: 4px 10px;
  border: 2px solid var(--rule-hot);
  color: var(--paper);
  background: var(--panel-hi);
  letter-spacing: 0.02em;
  white-space: nowrap;
}

/* ------------------------------------------------------------------- code */

code, .code {
  font-family: var(--mono);
  /* ligatures are off at the root; see the note there for why */
}

.code-slab {
  font-family: var(--mono);
  font-size: clamp(1.3rem, 5vw, 2.3rem);
  font-weight: 700;
  color: var(--paper);
  background: #0b0a08;
  border: 2px solid var(--rule-hot);
  padding: 18px 22px;
  text-align: center;
  letter-spacing: 0.01em;
  word-break: break-word;
  box-shadow: inset 0 0 40px rgba(255, 176, 0, 0.06);
}

/* ------------------------------------------------------------------ buttons */

.btn {
  font-family: var(--disp);
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--paper);
  background: var(--panel-hi);
  border: 2px solid var(--rule-hot);
  padding: 11px 20px;
  cursor: pointer;
  position: relative;
  top: 0;
  box-shadow: 0 4px 0 0 var(--rule);
  transition: top 70ms, box-shadow 70ms, background 120ms, color 120ms;
  text-decoration: none;
  display: inline-block;
}

.btn:hover { background: #2b261d; color: var(--amber); }
.btn:active { top: 4px; box-shadow: 0 0 0 0 var(--rule); }

.btn.primary {
  background: var(--amber);
  color: #1a1205;
  border-color: #ffd166;
  box-shadow: 0 4px 0 0 #8a5f00;
}
.btn.primary:hover { background: #ffc333; color: #1a1205; }
.btn.primary:active { box-shadow: 0 0 0 0 #8a5f00; }

.btn.ghost { background: transparent; box-shadow: none; border-color: var(--rule); }
.btn.ghost:active { top: 0; }

.btn:disabled, .btn[aria-disabled='true'] {
  opacity: 0.4;
  cursor: not-allowed;
  pointer-events: none;
}

.btn-row { display: flex; gap: 12px; flex-wrap: wrap; }

/* --------------------------------------------------------------- belt picker */

.belts { display: grid; gap: 10px; }

.belt-card {
  display: grid;
  grid-template-columns: 54px 1fr auto;
  align-items: center;
  gap: 16px;
  background: var(--panel-hi);
  border: 2px solid var(--rule);
  border-left: 6px solid var(--amber);
  padding: 12px 16px;
  cursor: pointer;
  text-align: left;
  width: 100%;
  font-family: inherit;
  color: inherit;
  transition: border-color 120ms, transform 120ms, background 120ms;
}

.belt-card:hover:not(:disabled) {
  border-color: var(--rule-hot);
  background: #282318;
  transform: translateX(3px);
}

.belt-card.locked { opacity: 0.38; cursor: not-allowed; border-left-color: var(--rule-hot); }
.belt-card.cleared { border-left-color: var(--lime); }

.belt-card .num {
  font-family: var(--mono);
  font-size: 1.9rem;
  font-weight: 700;
  line-height: 1;
  color: var(--paper);
  text-align: center;
}

.belt-card .nm {
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-size: 0.92rem;
}

.belt-card .bl {
  font-size: 0.78rem;
  color: var(--dim);
  margin-top: 3px;
  line-height: 1.35;
}

.belt-card .roster {
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.02em;
  color: var(--dimmer);
  margin-top: 7px;
  word-spacing: 0.1em;
}

.belt-card .meta {
  font-family: var(--mono);
  font-size: 0.66rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--dimmer);
  text-align: right;
  line-height: 1.6;
  white-space: nowrap;
}

.belt-card .meta b { color: var(--amber); font-weight: 700; }

/* Section headings in the belt picker. The sections are the scalar/container seam,
   never an age band. */
.group-head {
  font-family: var(--mono);
  font-size: 0.64rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--dimmer);
  margin: 22px 0 8px;
  display: flex;
  align-items: center;
  gap: 10px;
}
.group-head::after { content: ''; flex: 1; height: 1px; background: var(--rule); }
.group-head:first-child { margin-top: 0; }

/* -------------------------------------------------------------- feedback bar */

.verdict {
  border: 2px solid var(--rule);
  background: var(--panel-hi);
  padding: 13px 16px;
  display: flex;
  gap: 14px;
  align-items: flex-start;
  min-height: 64px;
}

.verdict .mark {
  font-family: var(--mono);
  font-size: 1.5rem;
  font-weight: 700;
  line-height: 1;
  flex: 0 0 auto;
}

.verdict .txt { font-size: 0.9rem; line-height: 1.45; }
.verdict .txt b { color: var(--paper); }
.verdict.good { border-color: var(--lime); }
.verdict.good .mark { color: var(--lime); }
.verdict.bad { border-color: var(--red); }
.verdict.bad .mark { color: var(--red); }
.verdict.idle { color: var(--dimmer); }

/* ----------------------------------------------------------------- game over */

.gameover { text-align: center; padding: 30px 20px; }

.gameover .big {
  font-family: var(--mono);
  font-size: clamp(2.6rem, 12vw, 5rem);
  font-weight: 700;
  line-height: 0.9;
  color: var(--amber);
  text-shadow: var(--glow-amber);
  font-variant-numeric: tabular-nums;
}

.gameover .cap {
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--dimmer);
  margin-bottom: 4px;
}

.gameover .pb {
  display: inline-block;
  margin-top: 14px;
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  border: 2px solid var(--lime);
  color: var(--lime);
  padding: 5px 12px;
}

.missed-list {
  text-align: left;
  margin: 22px auto 0;
  max-width: 520px;
  display: grid;
  gap: 7px;
}

.missed-list .row {
  display: flex;
  align-items: center;
  gap: 12px;
  border-left: 4px solid var(--rule-hot);
  background: #0e0d0a;
  padding: 8px 12px;
  font-size: 0.84rem;
}

.missed-list .row code {
  flex: 1;
  font-size: 0.94rem;
  color: var(--paper);
  word-break: break-all;
}

/* ------------------------------------------------------------------- focus */

/* Every control here is restyled, which means the browser's own focus ring lands
   on a dark custom background and is easy to lose. A student driving this from the
   keyboard needs to see where they are at a glance, so the ring is amber, thick,
   and drawn outside the control. :focus-visible so a mouse click does not light it
   up. */
:focus-visible {
  outline: 3px solid var(--amber);
  outline-offset: 2px;
}

/* The bins sit edge to edge in a grid, so an offset ring would sit on its
   neighbour. Draw this one inside instead. */
.bin:focus-visible {
  outline-offset: -3px;
  background: #2a251b;
}

.belt-card:focus-visible { outline-offset: -3px; }

/* A keyboard hint, shown near the controls it describes. */
.kbd-hint {
  font-family: var(--mono);
  font-size: 0.64rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--dimmer);
  margin-top: 10px;
}
.kbd-hint b { color: var(--dim); font-weight: 700; }

/* ---------------------------------------------------------------- utilities */

.hidden { display: none !important; }
.muted { color: var(--dim); }
.tiny {
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--dimmer);
}
.center { text-align: center; }
/* Grid items default to min-width:auto, so one wide child refuses to shrink and
   pushes the whole column past the viewport. On a 400px screen the panels were
   coming out 423px wide and taking the page with them. */
.stack { display: grid; gap: 16px; min-width: 0; }
.stack > * { min-width: 0; }

.kbd {
  font-family: var(--mono);
  font-size: 0.72rem;
  font-weight: 700;
  border: 2px solid var(--rule-hot);
  border-bottom-width: 4px;
  background: var(--panel-hi);
  padding: 1px 6px 2px;
  color: var(--paper);
}

.backlink {
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--dimmer);
  text-decoration: none;
  border-bottom: 1px solid transparent;
}
.backlink:hover { color: var(--amber); border-bottom-color: var(--amber); }

@keyframes popin {
  from { opacity: 0; transform: translateY(10px) scale(0.97); }
  to   { opacity: 1; transform: none; }
}
.popin { animation: popin 260ms cubic-bezier(0.2, 0.9, 0.3, 1) both; }

@keyframes shake {
  10%, 90% { transform: translateX(-2px); }
  20%, 80% { transform: translateX(4px); }
  30%, 50%, 70% { transform: translateX(-6px); }
  40%, 60% { transform: translateX(6px); }
}
.shake { animation: shake 420ms both; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    transition-duration: 0.001ms !important;
  }
  body::after { opacity: 0.25; }
}

@media (max-width: 768px) {
  .shell { padding: 18px 14px 56px; }
  .masthead { align-items: flex-start; }
  .belt-card { grid-template-columns: 40px 1fr; }
  .belt-card .meta { grid-column: 1 / -1; text-align: left; }
}
