/* Game screens. Colours come only from tokens.css. */

.app {
  /* Sizes follow the height the browser leaves us. --s is 0 on a screen 540px tall or less
     and 340px on one 880px tall or more; tiles, gaps and buttons scale between the two. A
     game screen fits a small phone with the browser's bars showing, and fills a big one. */
  --s: clamp(0px, calc(100vh - 540px), 340px);
  --gap: calc(6px + var(--s) * 0.027);
  --tile-h: calc(42px + var(--s) * 0.1);
  --btn-h: calc(46px + var(--s) * 0.036);
  --key-h: calc(44px + var(--s) * 0.027);

  position: relative;
  width: 100%;
  max-width: 430px;
  /* The visible height, between the browser's bars. vh is the fallback for old browsers. */
  height: 100vh;
  height: 100dvh;
  /* Taller than this and the game stops growing and sits in the middle. */
  max-height: 880px;
  margin: 0 auto;
  /* Thin at the top and bottom, so a phone's height goes to the game and not to margins.
     A notch or home bar still gets the room it needs. */
  padding: calc(6px + var(--s) * 0.01) var(--gutter);
  padding-top: max(calc(6px + var(--s) * 0.01), env(safe-area-inset-top, 0px));
  padding-bottom: max(calc(6px + var(--s) * 0.01), env(safe-area-inset-bottom, 0px));
  padding-left: max(var(--gutter), env(safe-area-inset-left, 0px));
  padding-right: max(var(--gutter), env(safe-area-inset-right, 0px));
  display: flex;
  flex-direction: column;
  gap: var(--gap);
  overflow: hidden;
  background: var(--bg);
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}
@supports (height: 100dvh) {
  .app { --s: clamp(0px, calc(100dvh - 540px), 340px); }
}
.app input, .app textarea, .app .share { -webkit-user-select: text; user-select: text; }
/* The layer for sheets and notes has no box of its own, so it adds no gap under the footer.
   What it holds is placed over the whole app. */
.overlay { display: contents; }

/* The screen is sized to fit. If a phone is shorter still, this middle part scrolls and the
   footer below it, which holds the buttons and keypads, stays in view.
   The padding leaves room for shadows and outlines. */
.screen-wrap {
  position: relative;
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.screen {
  flex: 1;
  min-height: 0;
  margin: 0 -8px;
  padding: 2px 12px 8px 8px;
  display: flex;
  flex-direction: column;
  gap: var(--gap);
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
}

/* The buttons and keypads for the screen. Never scrolls. */
.footer { flex: none; display: flex; flex-direction: column; gap: var(--gap); }

.label {
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 2px;
  text-transform: uppercase;
}

.row-between {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
}

/* ---------- Top bar ---------- */

.topbar { display: flex; justify-content: space-between; align-items: center; }
.topbar .left { display: flex; align-items: center; gap: 8px; }
.brand { font-family: var(--font-display); font-size: 16px; letter-spacing: 2px; }
.menu-btn {
  min-width: var(--touch);
  min-height: var(--touch);
  padding: 0 8px;
  display: flex;
  align-items: center;
  gap: 6px;
  background: transparent;
  border: none;
  font-weight: 700;
  font-size: 13px;
}
.tracker { display: flex; align-items: center; gap: 4px; }
.step {
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 2px solid var(--ink);
  border-radius: 50%;
  font-weight: 700;
  font-size: 13px;
}
.step--now { background: var(--ink); color: var(--bg); }
.step--done { color: var(--on-part); }
.step--done[data-part='1'] { background: var(--word); }
.step--done[data-part='2'] { background: var(--bomb); }
.step--done[data-part='3'] { background: var(--vault); }
.clock {
  padding: 6px 9px;
  background: var(--ink);
  color: var(--bg);
  font-weight: 700;
  font-size: 17px;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.title {
  margin: 0;
  font-family: var(--font-display);
  /* A label for the screen, not a headline: the game below it gets the room. */
  font-size: calc(14px + var(--s) * 0.014);
  font-weight: 400;
  line-height: 1;
  letter-spacing: 1px;
  text-transform: uppercase;
}
.story {
  padding: calc(6px + var(--s) * 0.014) 12px;
  background: var(--part);
  color: var(--on-part);
  font-weight: 700;
  font-size: calc(13px + var(--s) * 0.009);
  line-height: 1.2;
}
/* The word and the bomb keep room for two lines, so the screen below doesn't move when a
   short "wrong" message takes the briefing's place for a second. */
.app[data-part="1"] > .story,
.app[data-part="2"] > .story {
  min-height: calc(2.4em + 2 * (6px + var(--s) * 0.014));
  display: flex;
  align-items: center;
}
.story[hidden] { display: none; }

/* ---------- Buttons ---------- */

.btn {
  min-height: var(--btn-h);
  padding: 0 12px;
  background: var(--surface);
  color: var(--ink);
  border: var(--border) solid var(--ink);
  border-radius: 0;
  font-family: var(--font-display);
  font-size: 18px;
  letter-spacing: 1px;
  text-transform: uppercase;
}
.btn--ghost { background: transparent; }
.btn--part { background: var(--part); color: var(--on-part); }
.btn--small {
  min-height: var(--touch);
  padding: 0 6px;
  border-width: 2px;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0;
  text-transform: none;
}
.btn--used { opacity: 0.45; text-decoration: line-through; }
/* An unused power-up flashes in the part's colour once every ten seconds. The length here
   matches POWER_FLASH_MS in word.js. Switched off under reduced motion (base.css). */
.btn--flash { animation: power-flash 10s linear infinite; }
@keyframes power-flash {
  0%, 82%, 100% { background-color: var(--surface); color: var(--ink); }
  91% { background-color: var(--part); color: var(--on-part); }
}
.actions { display: flex; gap: 12px; }
.actions .grow { flex: 1; }

/* ---------- Part 1: the word ---------- */

.pips { display: flex; gap: 5px; }
.pip { width: 12px; height: 12px; border: 2px solid var(--ink); border-radius: 50%; }
.pip--used { background: var(--ink); }
.pip--now { background: var(--part); }

.slots { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: calc(6px + var(--s) * 0.018); }
.slots .tile { width: 100%; height: calc(48px + var(--s) * 0.109); font-size: calc(26px + var(--s) * 0.045); position: relative; z-index: 2; }

.hand {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  /* Three rows that grow into whatever height is free, from touch size up to full size. */
  --hand-gap: calc(8px + var(--s) * 0.027);
  grid-template-rows: repeat(3, minmax(var(--touch), 84px));
  flex: 1 1 auto;
  min-height: calc(3 * var(--touch) + 2 * var(--hand-gap));
  gap: var(--hand-gap);
  align-content: start;
}
.hand .tile { width: 100%; height: auto; min-height: 0; font-size: calc(24px + var(--s) * 0.045); }

.hints { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
.hints .btn { line-height: 1.15; }

/* ---------- Part 2: the bomb ---------- */

.bomb-panel { padding: calc(8px + var(--s) * 0.018); display: flex; flex-direction: column; gap: calc(6px + var(--s) * 0.018); border: var(--border) solid var(--ink); }
.leds { display: flex; gap: 6px; }
.led { width: 16px; height: 16px; border: 2px solid var(--ink); border-radius: 50%; }
.led--left { background: var(--ink); }
.led--used { background: var(--wrong); }

[data-wire='red'] { --wire: var(--wire-red); }
[data-wire='blue'] { --wire: var(--wire-blue); }
[data-wire='green'] { --wire: var(--wire-green); }
[data-wire='yellow'] { --wire: var(--wire-yellow); }

/* The four wires, in the order the code is entered. */
.wires { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }
.wire {
  padding: 0;
  display: flex;
  flex-direction: column;
  background: var(--surface);
  color: var(--ink);
  border: var(--border) solid var(--ink);
  border-radius: 0;
  text-align: center;
}
.wire-name {
  padding: 3px 0;
  background: var(--wire);
  color: var(--on-part);
  border-bottom: var(--border) solid var(--ink);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 1px;
  text-transform: uppercase;
}
.wire-value {
  height: calc(30px + var(--s) * 0.045);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-size: calc(18px + var(--s) * 0.018);
  font-variant-numeric: tabular-nums;
}
.wire--now { outline: var(--border) solid var(--part); outline-offset: 2px; }
.wire--wrong .wire-value { background: var(--wrong); color: var(--wrong-ink); }

.target-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.target { width: 96px; height: calc(44px + var(--s) * 0.055); font-size: calc(24px + var(--s) * 0.027); }

.sums {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  /* Three rows that grow into whatever height is free. */
  --sum-gap: calc(8px + var(--s) * 0.018);
  grid-template-rows: repeat(3, minmax(var(--touch), 76px));
  flex: 1 1 auto;
  min-height: calc(3 * var(--touch) + 2 * var(--sum-gap));
  align-content: start;
  gap: var(--sum-gap);
}
/* While the code is being entered the sums aren't tapped, so they can sit a little smaller. */
.sums--coding { grid-template-rows: repeat(3, minmax(36px, 76px)); min-height: calc(108px + 2 * var(--sum-gap)); }
.sum {
  height: auto;
  min-height: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  background: var(--surface);
  color: var(--ink);
  border: var(--border) solid var(--ink);
  border-radius: 0;
  box-shadow: var(--shadow-offset) var(--shadow-offset) 0 var(--ink);
  font-family: var(--font-display);
  font-size: calc(17px + var(--s) * 0.018);
  line-height: 1;
  white-space: nowrap;
}
/* Found: a thick border in its wire colour, and the colour's name. */
.sum--found { box-shadow: inset 0 0 0 5px var(--wire); }
.sum--found .sum-wire { font-family: var(--font-body); font-weight: 700; font-size: 9px; letter-spacing: 1px; text-transform: uppercase; }
.sum--wrong { background: var(--wrong); color: var(--wrong-ink); }

.keypad-wrap { display: flex; flex-direction: column; gap: var(--gap); }
.code-keys { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: calc(6px + var(--s) * 0.009); }
.key {
  height: var(--key-h);
  padding: 0;
  background: var(--surface);
  color: var(--ink);
  border: var(--border) solid var(--ink);
  border-radius: 0;
  font-family: var(--font-display);
  font-size: 24px;
}
.key--word { font-size: 14px; }

/* ---------- Part 3: the vault ---------- */

.dial {
  --dial: calc(84px + var(--s) * 0.3);
  flex: none;
  align-self: center;
  width: var(--dial);
  height: var(--dial);
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--surface);
  border: 4px solid var(--ink);
  border-radius: 50%;
}
.dial-ring {
  width: 76%;
  height: 76%;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 3px dashed var(--ink);
  border-radius: 50%;
}
.dial-knob {
  position: relative;
  width: 56%;
  height: 56%;
  border-radius: 50%;
  background: var(--part);
  border: 3px solid var(--ink);
}
.dial-knob::after {
  content: '';
  position: absolute;
  top: 6%;
  left: calc(50% - 3px);
  width: 6px;
  height: 34%;
  background: var(--on-part);
}

.strikes { display: flex; align-items: center; gap: 6px; }
.strikes--compact { flex: none; flex-direction: column; justify-content: center; gap: 3px; }
.strikes--compact .strike { width: 12px; height: 12px; }
.strike { width: 16px; height: 16px; border: 2px solid var(--ink); border-radius: 50%; }
.strike--used { background: var(--wrong); }

.combo { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: calc(8px + var(--s) * 0.027); }
.combo .tile { width: 100%; height: calc(48px + var(--s) * 0.1); font-size: calc(26px + var(--s) * 0.036); }

.chips { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; }
.chip {
  padding: 6px 4px;
  text-align: center;
  border: 2px solid var(--ink);
  font-weight: 700;
  font-size: 13px;
}
.chip--now { background: var(--ink); color: var(--bg); }
.chip--done { background: var(--tick); color: var(--on-part); }
.chip--later { opacity: 0.45; }

.doc-open {
  /* Takes whatever height the screen has spare, up to a comfortable size. */
  flex: 1 1 auto;
  max-height: calc(170px + var(--s) * 0.5);
  display: flex;
  flex-direction: column;
  gap: calc(8px + var(--s) * 0.018);
  padding: calc(8px + var(--s) * 0.018);
  background: var(--surface);
  color: var(--ink);
  border: var(--border) solid var(--ink);
  border-radius: 0;
  box-shadow: var(--shadow-offset) var(--shadow-offset) 0 var(--ink);
  text-align: left;
}
.doc-open-label { font-family: var(--font-display); font-size: calc(15px + var(--s) * 0.014); letter-spacing: 1px; text-transform: uppercase; }
.doc-cards { flex: 1; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
.doc-card {
  min-height: calc(58px + var(--s) * 0.17);
  padding: 8px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  background: var(--surface);
  color: var(--ink);
  border: var(--border) solid var(--ink);
  border-radius: 0;
  box-shadow: var(--shadow-offset) var(--shadow-offset) 0 var(--ink);
  text-align: left;
}
.doc-card .n { font-family: var(--font-display); font-size: calc(16px + var(--s) * 0.018); line-height: 1; }
.doc-card .t { font-weight: 700; font-size: 13px; line-height: 1.15; }
.doc-card .bar { height: 5px; background: var(--ink); }

.tabs { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.tab {
  min-height: var(--touch);
  padding: 0 4px;
  background: var(--surface);
  color: var(--ink);
  border: var(--border) solid var(--ink);
  border-radius: 0;
  font-weight: 700;
  font-size: 13px;
}
.tab--on { background: var(--part); color: var(--on-part); }

.doc-wrap {
  position: relative;
  flex: 1 1 auto;
  min-height: 96px;
  display: flex;
  background: var(--surface);
  border: var(--border) solid var(--ink);
  box-shadow: var(--shadow-offset) var(--shadow-offset) 0 var(--ink);
}
.doc {
  /* Positioned, so the hidden labels for screen readers stay inside the scrolling box. */
  position: relative;
  flex: 1;
  min-width: 0;
  min-height: 0;
  padding: calc(8px + var(--s) * 0.02) 12px;
  display: flex;
  flex-direction: column;
  gap: calc(2px + var(--s) * 0.012);
  font-family: var(--font-body);
  font-weight: 500;
  font-size: calc(12.5px + var(--s) * 0.008);
  line-height: 1.36;
  overflow-wrap: anywhere;
  overflow-y: auto;
  /* The arrows show there's more, so the browser's own scrollbar is hidden here. */
  scrollbar-width: none;
}
.doc::-webkit-scrollbar { display: none; }
/* A strip down the right for the arrows, so they never cover the document's text. */
.doc-wrap.has-scroll .doc { padding-right: 50px; }
.doc-wrap .scroll-hint { left: auto; right: 0; width: 38px; height: 38px; font-size: 15px; }
.doc-wrap .scroll-hint--up::before { inset: 0 0 -8px -8px; }
.doc-wrap .scroll-hint--down::before { inset: -8px 0 0 -8px; }
.doc-wrap .scroll-hint--up { border-left: var(--border) solid var(--ink); border-bottom: var(--border) solid var(--ink); }
.doc-wrap .scroll-hint--down { border-left: var(--border) solid var(--ink); border-top: var(--border) solid var(--ink); }
.redacted {
  display: inline-block;
  max-width: 100%;
  height: 0.95em;
  margin: 0 3px 0 1px;
  background: var(--ink);
  vertical-align: -0.12em;
}

/* Printed slips: tickets, bills and timetables are set in the typewriter face. */
.doc--ticket, .doc--bill, .doc--timetable { font-family: var(--font-mono); font-weight: 400; }
.doc-line--head, .doc-head { font-weight: 700; letter-spacing: 1px; }
.doc--news .doc-line--head { font-family: var(--font-display); font-weight: 400; font-size: 1.12em; line-height: 1.15; letter-spacing: 0; }
.doc-dim { font-size: 0.92em; font-style: italic; }
.doc-rows { display: grid; grid-template-columns: minmax(0, 1fr); column-gap: 18px; }
.doc--ticket .doc-rows { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.doc-row { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
.doc-row-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.doc-row-value { flex: none; font-weight: 700; }
/* A bill's last three rows, under a rule: subtotal, tax and total. */
.doc--bill .doc-row:nth-last-child(3) { margin-top: 3px; padding-top: 3px; border-top: 2px dashed var(--ink); }
.doc--note .doc-line:last-child { font-style: italic; }

/* An email: who it's from and to, then what it says. */
.mail-head { padding-bottom: calc(4px + var(--s) * 0.01); border-bottom: 2px solid var(--ink); }
.mail-field { display: flex; align-items: baseline; gap: 8px; }
.mail-label { flex: none; width: 54px; font-weight: 700; font-size: 0.82em; letter-spacing: 1px; text-transform: uppercase; }
.mail-value { min-width: 0; font-weight: 700; }
.mail-body { margin: calc(3px + var(--s) * 0.01) 0 0; }

/* A text conversation: the phone's owner on the right in the part's colour, the other
   person on the left. */
.chat-head { font-weight: 700; font-size: 0.86em; letter-spacing: 1px; text-transform: uppercase; }
.chat { display: flex; flex-direction: column; gap: calc(3px + var(--s) * 0.012); }
.bubble { max-width: 84%; padding: calc(2px + var(--s) * 0.008) 9px; border: 2px solid var(--ink); }
.bubble--left { align-self: flex-start; background: var(--bg); }
.bubble--right { align-self: flex-end; background: var(--part); color: var(--on-part); }

.plan-head {
  display: flex;
  justify-content: space-between;
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 1px;
  text-transform: uppercase;
}
.plan-end {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 1px;
}
.plan-end span:last-child { text-align: right; }
.plan-mark { padding: 2px 8px; background: var(--ink); color: var(--surface); }
.plan {
  flex: none;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 38px minmax(0, 1fr);
  border: 2px solid var(--ink);
}
.plan-side { display: flex; flex-direction: column; }
.room {
  height: calc(19px + var(--s) * 0.045);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 8px;
  border-bottom: 2px solid var(--ink);
  font-weight: 700;
  font-size: calc(13.5px + var(--s) * 0.012);
}
.corridor {
  border-left: 2px solid var(--ink);
  border-right: 2px solid var(--ink);
  background: repeating-linear-gradient(45deg, transparent 0 5px, var(--dim) 5px 6px); /* design-ok: hard-edged hatching for the corridor, not a blend */
}

.notes {
  flex: none;
  height: 64px;
  padding: 8px;
  background: var(--surface);
  color: var(--ink);
  border: var(--border) solid var(--ink);
  border-radius: 0;
  font-family: var(--font-mono);
  font-size: 16px;
  resize: none;
}

.entry-row { display: flex; gap: 10px; }
.entry {
  flex: 1;
  height: calc(46px + var(--s) * 0.045);
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--surface);
  border: var(--border) solid var(--ink);
  box-shadow: var(--shadow-offset) var(--shadow-offset) 0 var(--ink);
  font-family: var(--font-display);
  font-size: 32px;
}
.entry--wrong { background: var(--wrong); color: var(--wrong-ink); }
.entry-row .btn { height: calc(46px + var(--s) * 0.045); min-height: 0; }
.entry-row .notes-btn { width: 70px; padding: 0; font-size: 14px; }
.entry-row .try-btn { width: 92px; font-size: 20px; }

.doc-keys { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: calc(6px + var(--s) * 0.009); }

/* ---------- Scorecard ---------- */

.card {
  padding: calc(8px + var(--s) * 0.027) 14px;
  display: flex;
  flex-direction: column;
  gap: calc(4px + var(--s) * 0.018);
  background: var(--surface);
  border: var(--border) solid var(--ink);
}
.big-time { font-family: var(--font-display); font-size: calc(40px + var(--s) * 0.055); line-height: 0.95; }
.split {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 4px 0;
  border-top: 2px solid var(--ink);
  font-weight: 700;
  font-size: 15px;
}
.split .dot { width: 16px; height: 16px; border: 2px solid var(--ink); }
.split .name { flex: 1; }
.dot[data-part='1'] { background: var(--word); }
.dot[data-part='2'] { background: var(--bomb); }
.dot[data-part='3'] { background: var(--vault); }
.dot--failed { background: var(--wrong); }
.share {
  margin: 0;
  padding: calc(5px + var(--s) * 0.023) 14px;
  background: var(--surface);
  border: var(--border) solid var(--ink);
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.4;
  white-space: pre-line;
}
.answer-line { font-weight: 700; font-size: 14px; line-height: 1.3; }
.score-actions .btn { font-size: 16px; }

/* ---------- Part transition ---------- */

.wipe {
  position: absolute;
  inset: 0;
  z-index: 5;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  background: var(--part);
  color: var(--on-part);
  font-family: var(--font-display);
  font-size: 56px;
  transform: translateY(-101%);
  animation: wipe var(--t-wipe) cubic-bezier(0.7, 0, 0.3, 1) 0.35s both;
}
.wipe--long { font-size: 44px; }
@keyframes wipe {
  from { transform: translateY(0); }
  to { transform: translateY(-101%); }
}

/* ---------- Menu ---------- */

.veil {
  position: absolute;
  inset: 0;
  z-index: 8;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  background: var(--veil);
}
.sheet {
  padding: 18px var(--gutter) 22px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  background: var(--bg);
  border-top: 4px solid var(--ink);
}
.sheet h2 { margin: 0; font-family: var(--font-display); font-weight: 400; font-size: 22px; text-transform: uppercase; }
.sheet .note { font-weight: 700; font-size: 13px; }
.sheet .btn { font-size: 17px; }

/* ---------- Start screen and tutorial ---------- */

.app--plain { padding-top: 14px; }
.btn--ink { background: var(--ink); color: var(--bg); }
.btn--small-caps { flex: 1; min-height: calc(44px + var(--s) * 0.018); font-size: 14px; }
.link-btn {
  min-height: var(--touch);
  padding: 0 10px;
  background: transparent;
  border: none;
  font-weight: 700;
  font-size: 14px;
  text-decoration: underline;
}

/* Fills the screen's height. The how-to box takes what's spare, so there's no empty band
   above the name box. */
.start { flex: 1 0 auto; display: flex; flex-direction: column; align-items: center; gap: calc(7px + var(--s) * 0.03); padding-top: max(calc(var(--s) * 0.04), 3px); padding-bottom: 5px; }
/* The tilted O in the logo rises above the other tiles, into the page's thin top edge.
   On the start screen the scrolling area reaches up through that edge, so the tile's top
   corner is drawn and not cut off. Nothing moves: the padding gives back what the margin takes. */
.screen-wrap:has(.start) > .screen { margin-top: -8px; padding-top: 10px; }
.logo { display: flex; gap: 8px; padding-right: var(--shadow-offset); }
.logo .tile { width: min(calc(46px + var(--s) * 0.055), calc((100vw - 76px) / 5)); height: calc(46px + var(--s) * 0.06); min-width: 0; min-height: 0; font-size: calc(26px + var(--s) * 0.036); }
.logo .logo-o { background: var(--word); color: var(--on-part); transform: rotate(-9deg) translateY(-6px); }
.tagline {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(17px + var(--s) * 0.023);
  line-height: 1.1;
  text-transform: uppercase;
  text-align: center;
  text-wrap: balance;
}
.badge {
  align-self: center;
  padding: 5px 12px;
  background: var(--ink);
  color: var(--bg);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 2px;
  text-transform: uppercase;
}
.tut-head + .badge { align-self: flex-start; }
.howto {
  align-self: stretch;
  flex: 1 1 auto;
  max-height: calc(150px + var(--s) * 0.7);
  margin-top: calc(var(--s) * 0.045);
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: var(--border) solid var(--ink);
}
.howto-line { flex: 1 1 auto; display: flex; align-items: center; gap: 12px; padding: calc(5px + var(--s) * 0.022) 12px; font-weight: 700; font-size: calc(13.5px + var(--s) * 0.007); line-height: 1.25; }
.howto-line + .howto-line { border-top: 2px solid var(--ink); }
.swatch { flex: none; width: 22px; height: 22px; border: 2px solid var(--ink); background: var(--part); }
.best { margin: 0; font-weight: 700; font-size: 14px; text-align: center; }
.status-line { margin-top: calc(-4px - var(--s) * 0.027); }

.name-label {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 2px;
  text-transform: uppercase;
}
.name-input {
  height: calc(44px + var(--s) * 0.036);
  padding: 0 12px;
  background: var(--surface);
  color: var(--ink);
  border: var(--border) solid var(--ink);
  border-radius: 0;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 18px;
  letter-spacing: 0;
  text-transform: none;
}
.name-input::placeholder { color: var(--dim); }
.start-btn { min-height: calc(48px + var(--s) * 0.05); font-size: calc(20px + var(--s) * 0.018); letter-spacing: 2px; }
.start-row { display: flex; gap: 12px; }
.start-row .btn { flex: 1 1 0; min-width: 0; padding: 0 6px; }

.tut-count { font-weight: 700; font-size: 14px; }
.tut-title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: calc(22px + var(--s) * 0.036);
  line-height: 1.05;
  text-transform: uppercase;
  text-wrap: balance;
}
.tut-text { padding: calc(7px + var(--s) * 0.014) 12px; font-size: calc(14px + var(--s) * 0.014); line-height: 1.3; }
.tut-cap { margin-top: calc(var(--s) * 0.018); }
.tut-grid { display: grid; gap: calc(8px + var(--s) * 0.018); }
.tut-grid .tile { width: 100%; height: calc(44px + var(--s) * 0.073); padding: 0 4px; text-align: center; line-height: 1.1; text-transform: none; }

/* ---------- Dossier and mission brief ---------- */

/* A card folder with a sheet of paper showing above its edge. It takes the room the screen
   has left, up to a comfortable size. */
.dossier {
  position: relative;
  flex: 1 1 0;
  align-self: center;
  width: min(100%, calc(270px + var(--s) * 0.35));
  min-height: 132px;
  /* As tall as the screen has room for, so nothing is left empty under the mission line. */
  max-height: calc(300px + var(--s) * 1.1);
  margin-top: calc(4px + var(--s) * 0.05);
  padding: calc(26px + var(--s) * 0.04) var(--shadow-offset) var(--shadow-offset) 0;
  display: flex;
  flex-direction: column;
}
.dossier-paper {
  position: absolute;
  top: 0;
  left: 9%;
  right: 12%;
  height: 70%;
  padding: 8px 12px;
  display: flex;
  flex-direction: column;
  gap: 5px;
  background: var(--paper);
  color: var(--paper-ink);
  border: var(--border) solid var(--ink);
  transform: rotate(-2deg);
  transform-origin: 50% 100%;
  transition: transform 0.38s ease-out;
}
.dossier-paper-head { font-weight: 700; font-size: 10px; letter-spacing: 2px; text-transform: uppercase; }
.redact { display: block; height: 6px; background: var(--paper-ink); }
.dossier-folder {
  position: relative;
  flex: 1;
  margin-top: 14px;
  padding: 12px 14px;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  background: var(--folder);
  color: var(--on-part);
  border: var(--border) solid var(--ink);
  box-shadow: var(--shadow-offset) var(--shadow-offset) 0 var(--ink);
  transform-origin: 50% 100%;
  transition: transform 0.38s ease-out;
}
/* The folder's index tab, standing up from its top edge. */
.dossier-tab {
  position: absolute;
  left: calc(-1 * var(--border));
  bottom: 100%;
  height: 20px;
  padding: 0 12px;
  display: flex;
  align-items: center;
  background: var(--folder-dark);
  border: var(--border) solid var(--ink);
  border-bottom: none;
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 2px;
  text-transform: uppercase;
}
.dossier-label { display: flex; flex-direction: column; gap: 2px; }
.dossier-kicker, .dossier-for { font-weight: 700; font-size: 11px; letter-spacing: 2px; text-transform: uppercase; }
.dossier-for { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dossier-title { font-family: var(--font-display); font-size: calc(22px + var(--s) * 0.03); line-height: 1; text-transform: uppercase; }
.dossier-stamp {
  position: absolute;
  top: 12%;
  right: 8%;
  padding: 3px 8px;
  border: 3px solid var(--stamp);
  color: var(--stamp);
  font-family: var(--font-display);
  font-size: calc(13px + var(--s) * 0.012);
  letter-spacing: 2px;
  text-transform: uppercase;
  transform: rotate(-8deg);
}
/* Open File: the cover tips forward and the paper lifts out. */
.dossier--opening .dossier-folder { transform: perspective(600px) rotateX(-38deg); }
.dossier--opening .dossier-paper { transform: rotate(0deg) translateY(-8%); }
.dossier-text { font-size: calc(14px + var(--s) * 0.012); line-height: 1.3; }

/* The mission brief: one card per part, each a third of the height. On a small phone a card
   with more to say takes the lines it needs and the others share what's left; nothing is cut
   off, and if it still doesn't fit the screen scrolls. */
.brief { flex: 1 0 auto; display: flex; flex-direction: column; gap: calc(6px + var(--s) * 0.02); }
.brief-card {
  flex: 1 1 0;
  min-height: min-content;
  padding: calc(6px + var(--s) * 0.02) 12px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: calc(3px + var(--s) * 0.012);
  background: var(--surface);
  border: var(--border) solid var(--ink);
  border-left: calc(10px + var(--s) * 0.02) solid var(--part);
  box-shadow: inset var(--border) 0 0 var(--ink);
}
.brief-name { margin: 0; display: flex; align-items: center; gap: 8px; font-family: var(--font-display); font-weight: 400; font-size: calc(15px + var(--s) * 0.02); line-height: 1; text-transform: uppercase; }
.brief-no {
  flex: none;
  width: 20px;
  height: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--part);
  color: var(--on-part);
  border: 2px solid var(--ink);
  border-radius: 50%;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 12px;
}
.brief-text { margin: 0; font-weight: 500; font-size: calc(12.5px + var(--s) * 0.012); line-height: 1.25; }
.brief-stakes { margin: 0; font-weight: 700; font-size: 13px; text-align: center; }

/* ---------- The briefing over a part as it starts ---------- */

/* The game behind goes soft, so the eye lands on the briefing. */
.app > .topbar, .app > .title, .app > .story, .app > .debug-bar, .app > .screen-wrap, .app > .footer { transition: filter 0.25s ease-out; }
.app--intro > .topbar, .app--intro > .title, .app--intro > .debug-bar, .app--intro > .screen-wrap, .app--intro > .footer { filter: blur(3px); pointer-events: none; }
/* The instruction's usual place is kept, empty, for it to come back to. */
.story--away { visibility: hidden; }

/* Over the whole app, under the coloured panel that slides away as a part opens. */
.intro {
  position: absolute;
  inset: 0;
  z-index: 4;
  padding: 0 max(var(--gutter), env(safe-area-inset-right, 0px)) 0 max(var(--gutter), env(safe-area-inset-left, 0px));
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: calc(10px + var(--s) * 0.03);
  background: var(--scrim);
  cursor: pointer;
  transition: background-color 0.3s ease-out;
}
/* The part's name: smaller than the instruction under it. */
.intro-title { font-family: var(--font-display); font-size: calc(13px + var(--s) * 0.009); letter-spacing: 4px; text-align: center; text-transform: uppercase; }
/* The instruction, in its part's colour, 30% bigger than in its usual place. */
.intro-box {
  padding: calc((6px + var(--s) * 0.014) * 1.6) 16px;
  background: var(--part);
  color: var(--on-part);
  border: 0 solid var(--ink);
  box-shadow: var(--shadow-offset) var(--shadow-offset) 0 var(--ink);
  font-weight: 700;
  font-size: calc((13px + var(--s) * 0.009) * 1.3);
  line-height: 1.2;
}
.intro-timer { font-weight: 700; font-size: calc(12.5px + var(--s) * 0.008); line-height: 1.3; text-align: center; }
/* Start is the app's usual main button. Nothing of its own to style. */
/* On its way: the scrim clears and everything but the instruction fades. */
.intro--leaving { background: transparent; pointer-events: none; }
.intro--leaving > :not(.intro-box) { opacity: 0; transition: opacity 0.12s ease-out; }

/* Two words each: kept on one line on a narrow phone. */
.training-actions .btn { padding: 0 6px; font-size: calc(14px + var(--s) * 0.012); letter-spacing: 0.5px; white-space: nowrap; }
.training-name { font-family: var(--font-display); font-size: calc(30px + var(--s) * 0.04); line-height: 1; text-transform: uppercase; }
.training-note { font-weight: 700; font-size: 14px; }
.training-card { border-left: calc(10px + var(--s) * 0.02) solid var(--part); box-shadow: inset var(--border) 0 0 var(--ink); }

/* ---------- Leaderboard ---------- */

.board { padding: 10px 14px; gap: 2px; }
.board-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 3px 8px;
  font-weight: 700;
  font-size: 15px;
  font-variant-numeric: tabular-nums;
}
.board-row .rank { width: 26px; }
.board-row .who { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.board-row--me { background: var(--part); color: var(--on-part); }
.board-note { font-weight: 700; font-size: 13px; }
/* Today, This week, All time: the shared tabs, a little shorter inside the card. */
.board-tabs { margin: 2px 0 4px; gap: 6px; }
.board-tabs .tab { min-height: var(--touch); font-size: 13px; }
.board-rows { display: flex; flex-direction: column; gap: 2px; }
.board-row--spare { visibility: hidden; }
/* Your own row: the part's colour, and a star. */
.board-row .you { font-weight: 700; }
/* Which day's puzzle a time was set on, on the longer boards. */
.board-row .on-day { flex: none; font-size: 12px; font-weight: 500; opacity: 0.75; }

/* ---------- Development options ---------- */

.debug-bar {
  padding: 6px 10px;
  border: 2px dashed var(--ink);
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.35;
}

.small-links { align-self: center; display: flex; gap: 8px; }
/* The links are small to look at but take a full-size tap: the padding reaches past the row. */
.small-link { align-self: center; margin: -11px 0; padding: 13px 10px; color: inherit; font-weight: 700; font-size: 13px; }
button.small-link { background: none; border: none; font-family: inherit; text-decoration: underline; }

.tut-wire { background: var(--wire); color: var(--on-part); }

/* ---------- Scroll arrows ---------- */

/* A tab on the top or bottom edge of anything that scrolls, shown while there's more that way. */
.scroll-hint {
  position: absolute;
  left: calc(50% - 30px);
  z-index: 4;
  width: 60px;
  height: 28px;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--ink);
  color: var(--surface);
  border: none;
  border-radius: 0;
  font-size: 14px;
  line-height: 1;
}
.scroll-hint--up { top: 0; }
.scroll-hint--down { bottom: 0; }
.scroll-hint--still { pointer-events: none; }
/* On the game screen the down arrow sits in the empty margin under the content. */
.screen-wrap > .scroll-hint--down { bottom: 0; height: 20px; font-size: 12px; }
.screen-wrap > .scroll-hint--up { height: 20px; font-size: 12px; }
/* Room at the end, so the last line clears the arrow. */
.screen-wrap.has-scroll .screen { padding-bottom: 28px; }
/* A bigger area to tap than the tab itself. */
.scroll-hint::before { content: ''; position: absolute; inset: -10px -14px; }
.scroll-hint--down .scroll-hint-arrow { animation: nudge-down 1.2s ease-in-out infinite; }
.scroll-hint--up .scroll-hint-arrow { animation: nudge-up 1.2s ease-in-out infinite; }
@keyframes nudge-down { 50% { transform: translateY(3px); } }
@keyframes nudge-up { 50% { transform: translateY(-3px); } }

/* The list of what's at stake on the opening How to play page. */
.tut-points { margin: 0; padding: 0; list-style: none; }
.tut-points .howto-line { display: block; }
.tut-how { width: 150px; font-size: 13px; letter-spacing: 0.5px; }

/* ---------- Very short screens ---------- */

/* On a short screen the big part title goes: the 1-2-3 tracker already says where you are. */
@media (max-height: 520px) {
  .app > .title { display: none; }
}

/* The little bars on the document cards are decoration. They go when height is tight. */
@media (max-height: 640px) {
  .doc-card .bar { display: none; }
}

/* A phone on its side, or a keyboard covering most of the screen: nothing can be pinned, so
   the whole page scrolls like an ordinary one. */
@media (max-height: 400px) {
  .app { height: auto; min-height: 100vh; overflow: visible; }
  .screen-wrap { flex: none; }
  .screen { overflow: visible; }
  .screen-wrap > .scroll-hint { display: none; }
}

/* ---------- Tablets and desktop ---------- */

/* On a wide screen the game is a phone-sized panel in the middle of the page. */
@media (min-width: 700px) and (min-height: 401px) {
  body { display: flex; align-items: center; justify-content: center; }
  .app {
    max-height: min(880px, calc(100dvh - 40px));
    margin: 0;
    border: var(--border) solid var(--ink);
    box-shadow: 8px 8px 0 var(--ink);
  }
}
/* A very tall phone: the game keeps its full size and sits in the middle. */
@media (max-width: 699px) and (min-height: 881px) {
  body { display: flex; align-items: center; justify-content: center; }
}

.practice-btn { min-height: calc(44px + var(--s) * 0.018); font-size: 15px; }

/* A practice dossier: the stamp is plain ink, and the one card doesn't stretch. */
.dossier--practice .dossier-stamp { border-color: var(--on-part); color: var(--on-part); }
.dossier--practice { min-height: 96px; max-height: calc(170px + var(--s) * 0.9); }
.brief--one { flex: 0 0 auto; }
.brief--one .brief-card { flex: 0 0 auto; }

/* In place of the clock on a training run. */
.training-tag {
  padding: 4px 10px;
  background: var(--ink);
  color: var(--bg);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 2px;
  text-transform: uppercase;
}
