:root {
  --bg: #14161c;
  --asphalt: #191a1f;
  --asphalt-dark: #131418;
  --line: #d8d840;
  --panel: #1c1e25;
  --panel-border: #33363f;
  --text: #eef0f4;
  --text-dim: #9aa0ac;
  --good: #4caf50;
  --mid: #ffb300;
  --bad: #e53935;
  --accent: #8a5cff;
  /* The one place the game's typefaces are chosen. The canvas HUD and the
     on-board floats read these two variables at load (HP.cssFont, board.js),
     so a new font is declared here and nowhere else. To use one: put the
     file under assets/fonts/, declare it in the @font-face slot below, and
     put its family name first in --font-ui. The file has to ship with the
     game (the APK is offline), so it cannot be a Google Fonts link. */
  --font-ui: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-mono: "SF Mono", Menlo, Consolas, "Roboto Mono", monospace;
  font-family: var(--font-ui);
}

/* @font-face slot -- fill in once the font is chosen (owner, 2026-09-15).
@font-face {
  font-family: "GameFont";
  src: url("assets/fonts/GameFont.woff2") format("woff2");
  font-weight: 400 700;
  font-display: swap;
}
*/

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  align-items: center;
  min-height: 100vh;
  padding: 16px;
}

#app {
  position: relative;
  width: 1320px;
  max-width: 100%;
}

/* Compact by design: every pixel here is a pixel the board does not get, and
   on a landscape phone the board is already height-bound. nowrap matters as
   much as the padding — wrapping is what took the bar from 42px to 52px. */
/* The HUD is drawn into the canvas now (js/hud.js). The DOM bar stays in the
   page because main.js still writes the stat elements that the canvas HUD reads
   back, but nothing of it is displayed. */
#hud {
  display: none !important;
}
#hud.retired {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
  background: var(--panel);
  border: 1px solid var(--panel-border);
  border-radius: 6px;
  padding: 3px 10px;
  margin-bottom: 4px;
  flex-wrap: nowrap;
}

#hudLeft { display: flex; align-items: center; gap: 10px; flex: 1; min-width: 0; }
#stripName {
  font-weight: 700; font-size: 11px; letter-spacing: .3px; color: var(--accent);
  /* Flavour, not information — it yields first when the bar runs out of room. */
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: 0 1 auto;
}

#flowMeterWrap { flex: 1; min-width: 90px; }
/* The bar is red, moving and the only meter on screen; the caption was
   costing 11px of board height to say what the bar already says. */
#flowMeterLabel { display: none; }
#flowMeterBar {
  position: relative;
  height: 8px;
  background: var(--asphalt-dark);
  border-radius: 5px;
  overflow: hidden;
  border: 1px solid var(--panel-border);
}
#flowMeterFill {
  height: 100%;
  width: 0%;
  background: var(--bad);
  transition: background-color 0.3s ease;
}
#flowMeterThreshold {
  position: absolute;
  top: -2px;
  bottom: -2px;
  width: 2px;
  background: #fff;
  opacity: 0.6;
  left: 70%;
}
#sustainText { font-size: 10px; color: var(--text-dim); margin-top: 2px; height: 12px; }
/* Endless reuses this line for the under-the-bar countdown, which is a warning
   rather than a caption — it is the only thing on screen saying a life is about
   to go. Same 12px box, so it costs no board height. */
#sustainText.warn { color: var(--bad); font-weight: 600; }

#hudRight { display: flex; align-items: center; gap: 6px; flex: 0 0 auto; }
/* Scoped to the HUD on purpose: the global button rule also styles the start
   screen's primary call to action, which should stay full size. */
#hudRight button { padding: 3px 7px; font-size: 12px; border-radius: 5px; line-height: 1.2; }
#charges { font-size: 12px; font-weight: 600; white-space: nowrap; }
/* Buttons keep their glyph and lose their words; the title attribute carries
   the name for hover and for screen readers. */
.btnLabel { display: none; }
.statIcon { color: var(--accent); margin-right: 2px; }
#chargesVal { color: var(--accent); }
#streakInfo { font-size: 10px; font-weight: 500; color: var(--text-dim); }
#banishGoal { font-size: 12px; font-weight: 600; white-space: nowrap; }
#banishedVal, #banishGoalVal { color: var(--good); }
/* Endless only (hidden in strips). It shares the HUD's one nowrap row, so it
   must never add a line — see the height-budget note on #hud. It is affordable
   because endless also drops the "/goal" suffix beside it, and the metres
   readout, which is secondary information, goes away entirely on a short
   viewport (below). */
#scoreBox { font-size: 12px; font-weight: 600; white-space: nowrap; }
#scoreVal { color: var(--accent); }
#distVal { font-size: 10px; font-weight: 500; color: var(--text-dim); }

button {
  cursor: pointer;
  border: 1px solid var(--panel-border);
  background: var(--asphalt);
  color: var(--text);
  padding: 8px 14px;
  border-radius: 8px;
  font-size: 13px;
  font-weight: 600;
  transition: background-color 0.15s ease, transform 0.1s ease;
}
button:hover { background: #383c46; }
button:active { transform: scale(0.97); }

#gameCanvas {
  display: block;
  /* Bound by width OR height, whichever runs out first. Without the height
     term the board simply ran off the bottom of a landscape phone — at
     844x390 it overflowed by 135px and the lower shoulder was never visible.
     --chrome is body padding + the HUD bar + its margin. dvh rather than vh
     so a mobile browser's collapsing toolbar does not reintroduce the
     overflow it was hiding. */
  --chrome: 34px;
  width: min(100%, calc((100dvh - var(--chrome)) * 1320 / 720));
  height: auto;
  margin-inline: auto;
  aspect-ratio: 1320 / 720;
  /* The board is tapped, never zoomed or scrolled — this kills the browser's
     double-tap-to-zoom wait, which otherwise delays every banish. */
  touch-action: manipulation;
  background: var(--asphalt);
  border-radius: 10px;
  border: 1px solid var(--panel-border);
  cursor: crosshair;
}

#toast {
  position: absolute;
  left: 50%;
  /* Just under the HUD band, which is the top 60/720 of the board. */
  top: 10%;
  /* Flavor text plus a streak-bonus suffix runs to ~180 characters, which at
     13px is well past the 1100px board — nowrap sent it off both edges. */
  max-width: min(760px, calc(100% - 32px));
  text-align: center;
  transform: translate(-50%, -8px);
  background: rgba(20, 22, 28, 0.95);
  border: 1px solid var(--accent);
  color: var(--text);
  padding: 8px 16px;
  border-radius: 20px;
  font-size: 13px;
  font-weight: 600;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s ease, transform 0.25s ease;
  z-index: 20;
}
#toast.show { opacity: 1; transform: translate(-50%, 0); }

/* --- achievement banner ----------------------------------------------------
   Slides in under the HUD band on the right, holds, slides out. Sized in
   board terms (percentages, clamp) so it reads at phone scale, where the
   toast does not. */
#achieveBanner {
  position: absolute;
  top: 10%;
  right: 2%;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 14px 8px 10px;
  background: rgba(20, 22, 28, 0.96);
  border: 1px solid var(--mid);
  border-left-width: 4px;
  border-radius: 10px;
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.45);
  opacity: 0;
  transform: translateX(24px);
  transition: opacity 0.3s ease, transform 0.3s ease;
  pointer-events: none;
  z-index: 21;
  max-width: min(360px, 60%);
}
#achieveBanner.show { opacity: 1; transform: translateX(0); }
#achieveBanner .achIcon { font-size: clamp(18px, 4vw, 28px); line-height: 1; }
#achieveBanner .achLabel { font-size: clamp(8px, 1.6vw, 11px); letter-spacing: .08em; text-transform: uppercase; color: var(--mid); font-weight: 700; }
#achieveBanner .achName { font-size: clamp(11px, 2.4vw, 16px); font-weight: 700; color: var(--text); }

/* --- loading screen ---------------------------------------------------------- */
#loadingScreen { z-index: 40; }
.loadingIcon { width: 96px; height: 96px; border-radius: 22px; margin-bottom: 14px; animation: loadingSpin 2.4s linear infinite; }
@keyframes loadingSpin { to { transform: rotate(360deg); } }
#loadingBar { width: min(320px, 70%); height: 8px; margin-top: 10px; background: var(--asphalt); border: 1px solid var(--panel-border); border-radius: 6px; overflow: hidden; }
#loadingFill { width: 0; height: 100%; background: var(--accent); transition: width 0.25s ease; }
.screen .loadingText { font-size: 12.5px; margin-top: 10px; }

/* --- main menu extras: records ------------------------------------------------- */
#menuExtras { display: flex; gap: 10px; margin-top: 12px; flex-wrap: wrap; justify-content: center; }
.screen #menuExtras button { margin-top: 0; padding: 8px 14px; font-size: 13px; }
.screen #menuStats { font-size: 12px; margin-top: 8px; color: var(--text-dim); min-height: 1em; }

/* --- achievements screen -------------------------------------------------- */
#achievementsGrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 8px;
  width: 100%;
  max-width: 760px;
  margin-top: 8px;
}
.achCard {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  text-align: left;
  padding: 10px 12px;
  background: var(--panel);
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  opacity: 0.55;
}
.achCard.unlocked { opacity: 1; border-color: var(--mid); }
.achCardIcon { font-size: 22px; line-height: 1.2; }
.achCardName { font-size: 13.5px; font-weight: 600; color: var(--text); }
.achCardDesc { font-size: 11.5px; color: var(--text-dim); line-height: 1.4; margin-top: 2px; }
.achCardWhen { font-size: 10.5px; color: var(--mid); margin-top: 4px; }
.achCardBody { flex: 1; min-width: 0; }
.achCardProgress { height: 4px; margin-top: 6px; background: var(--asphalt); border-radius: 3px; overflow: hidden; }
.achCardProgress span { display: block; height: 100%; background: var(--mid); }
.screen #achievementsBackBtn, .screen #leaderboardBackBtn { margin-top: 22px; padding: 8px 16px; font-size: 13px; }

/* --- leaderboard screen --------------------------------------------------- */
#leaderboardTabs { display: flex; gap: 6px; margin-bottom: 8px; }
.screen .lbTab { margin-top: 0; padding: 7px 16px; font-size: 13px; background: transparent; border: 1px solid rgba(255, 255, 255, 0.28); color: rgba(255, 255, 255, 0.72); }
.screen .lbTab:hover { background: transparent; border-color: rgba(255, 255, 255, 0.5); color: #fff; }
.screen .lbTab.active, .screen .lbTab.active:hover { background: var(--accent); border-color: var(--accent); color: #fff; }
.screen .lbTab[hidden] { display: none; }
#leaderboardTable { width: 100%; max-width: 520px; margin-top: 6px; max-height: 60vh; overflow-y: auto; }
#leaderboardTable table { width: 100%; border-collapse: collapse; font-size: 13px; background: var(--panel); border: 1px solid var(--panel-border); border-radius: 8px; overflow: hidden; }
#leaderboardTable th, #leaderboardTable td { padding: 7px 12px; text-align: left; border-bottom: 1px solid var(--panel-border); }
#leaderboardTable th { font-size: 10.5px; letter-spacing: .06em; text-transform: uppercase; color: var(--text-dim); background: var(--asphalt); }
#leaderboardTable tr:last-child td { border-bottom: none; }
#leaderboardTable td:nth-child(3) { color: var(--accent); font-weight: 700; font-family: var(--font-mono); }
#leaderboardTable tr:first-child td:nth-child(1) { color: var(--mid); font-weight: 700; }
.screen .lbEmpty { font-size: 13px; }

/* The name entry on the run-over screen. */
#leaderboardEntry { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; justify-content: center; margin-top: 14px; font-size: 13px; color: var(--mid); font-weight: 600; }
#leaderboardEntry[hidden] { display: none; }
#playerNameInput { padding: 8px 10px; font-size: 14px; border-radius: 8px; border: 1px solid var(--panel-border); background: var(--asphalt); color: var(--text); width: 150px; font-family: inherit; }
.screen #saveScoreBtn { margin-top: 0; padding: 8px 14px; font-size: 13px; }
.screen #saveScoreBtn:disabled { background: var(--good); border-color: var(--good); opacity: 0.85; cursor: default; }

.screen {
  position: absolute;
  inset: 0;
  background: rgba(10, 11, 15, 0.94);
  border-radius: 10px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 40px;
  z-index: 30;
  overflow-y: auto;
}
.screen.hidden { display: none; }
.screen h1 { margin: 0 0 12px; font-size: 32px; }
.screen p { max-width: 520px; color: var(--text-dim); line-height: 1.5; margin: 6px 0; }
.screen button { margin-top: 20px; padding: 12px 24px; font-size: 15px; background: var(--accent); border-color: var(--accent); }
.screen button:hover { background: #7648e0; }

#sessionSummaryStats {
  margin-top: 8px;
  padding: 16px 20px;
  background: var(--asphalt);
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  font-family: "SF Mono", "Menlo", "Consolas", monospace;
  font-size: 12px;
  line-height: 1.7;
  color: var(--text-dim);
  text-align: left;
  white-space: pre-wrap;
  max-width: 560px;
  max-height: 280px;
  overflow-y: auto;
}
#sessionSummaryStats .missRealRow { color: var(--bad); }
#sessionSummaryStats .missHarmlessRow { color: var(--text-dim); }
#sessionSummaryActions { margin-top: 20px; display: flex; gap: 12px; flex-wrap: wrap; justify-content: center; }
#sessionSummaryActions button { margin-top: 0; }
#logSessionBtn:disabled { background: var(--good); border-color: var(--good); opacity: 0.85; cursor: default; }
#mainMenuBtn, #newRunBtn { background: var(--asphalt); border-color: var(--panel-border); }
#mainMenuBtn:hover, #newRunBtn:hover { background: #383c46; }

/* Start screen: Endless is the main mode and gets the accent-coloured primary
   button that `.screen button` already styles; Strips is the secondary one and
   is toned down to the same treatment as Main Menu / New Run. */
.screen h2 { margin: 20px 0 0; font-size: 20px; color: var(--accent); }
/* --- main menu -----------------------------------------------------------
   Three modes, one tile each. A tile IS the button rather than a card with a
   button inside it, so there is no spot on a mode that does not start it. */
#modeMenu {
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: 100%;
  max-width: 440px;
  margin: 24px 0 4px;
}
/* `.screen button` sets the accent fill and a top margin, which suit a screen
   with one action and not a menu of three — and the specificity has to beat it,
   which is the same trap .ghostBtn fell into. */
.screen .modeTile {
  margin: 0;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 5px;
  padding: 15px 18px;
  text-align: left;
  background: var(--panel);
  border: 1px solid var(--panel-border);
  border-left-width: 3px;
  border-radius: 8px;
}
.screen .modeTile:hover { background: #262932; border-color: #4a4f5c; }
/* Stated after the hover rule, which sets border-color wholesale and would
   otherwise take the accent edge with it on the way past. */
.screen #startEndlessBtn { border-left-color: var(--accent); }
.screen #startSchoolBtn { border-left-color: var(--good); }
.screen #stripsMenuBtn { border-left-color: var(--mid); }
.screen #startEndlessBtn:hover { border-left-color: var(--accent); }
.screen #startSchoolBtn:hover { border-left-color: var(--good); }
.screen #stripsMenuBtn:hover { border-left-color: var(--mid); }
.modeName { font-size: 17px; font-weight: 600; color: var(--text); }
.modeDesc { font-size: 12.5px; font-weight: 400; color: var(--text-dim); line-height: 1.45; }

/* The rules are reference rather than pitch: under the menu, and sized to be
   read once rather than every time. */
.screen .tagline { margin-bottom: 2px; }
.screen .startRules {
  margin-top: 18px;
  padding-top: 14px;
  border-top: 1px solid var(--panel-border);
  font-size: 12.5px;
  max-width: 480px;
}

/* --- strip selection ----------------------------------------------------- */
#stripPickRow {
  margin-top: 20px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 8px;
  max-width: 520px;
}
#stripPickLabel { font-size: 12px; color: var(--text-dim); width: 100%; }
.screen .levelSelectBtn {
  margin-top: 0;
  padding: 8px 14px;
  font-size: 12.5px;
  background: var(--asphalt);
  border-color: var(--panel-border);
}
.screen .levelSelectBtn:hover { background: #383c46; }
#stripBackBtn { margin-top: 26px; padding: 8px 16px; font-size: 13px; }

.overlay {
  position: fixed;
  inset: 0;
  background: rgba(8, 9, 12, 0.96);
  z-index: 50;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 24px;
  overflow: auto;
}
.overlay.hidden { display: none; }
#pileHeader { width: 820px; max-width: 100%; display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; }
#pileHeader h2 { margin: 0; color: var(--accent); }
#pileCanvas {
  width: 820px;
  max-width: 100%;
  height: auto;
  aspect-ratio: 820 / 420;
  background: radial-gradient(ellipse at center, #241830 0%, #0d0e13 75%);
  border-radius: 10px;
  border: 1px solid var(--panel-border);
  cursor: pointer;
}
#pileFlavorPanel {
  width: 820px;
  max-width: 100%;
  min-height: 40px;
  margin-top: 10px;
  padding: 10px 14px;
  background: var(--panel);
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  font-size: 14px;
  color: var(--text-dim);
}

#debugPanel {
  width: 1100px;
  max-width: 100%;
  margin: 16px auto 0;
  padding: 14px 18px;
  background: var(--panel);
  border: 1px solid var(--panel-border);
  border-radius: 10px;
  font-family: "SF Mono", "Menlo", "Consolas", monospace;
  font-size: 12px;
  color: var(--text-dim);
  line-height: 1.6;
}
#debugPanel.hidden { display: none; }
#debugPanel h3 { margin: 0 0 8px; font-size: 13px; color: var(--text); font-family: inherit; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
#copyHistoryBtn { margin-left: auto; padding: 4px 10px; font-size: 11px; font-weight: 500; }
#debugSubtitle { color: var(--text-dim); font-weight: 400; }
#debugStats, #debugBad { white-space: pre-wrap; margin-bottom: 8px; }
#debugMissedHeader, #debugMistakeHeader { color: var(--text); margin-bottom: 4px; }
#debugMissedList, #debugMistakeList {
  max-height: 160px;
  overflow-y: auto;
  border-top: 1px solid var(--panel-border);
  padding-top: 6px;
  margin-bottom: 8px;
}
#debugMissedList .missedRow, #debugMistakeList .missedRow { padding: 1px 0; }
#debugMissedList .missedRow.recent, #debugMistakeList .missedRow.recent { color: var(--bad); }

#debugSessionHeader { color: var(--text); margin: 12px 0 4px; border-top: 1px solid var(--panel-border); padding-top: 10px; }
#debugSessionSummary { white-space: pre-wrap; }
#debugSessionSummary .missRealRow { color: var(--bad); }
#debugSessionSummary .missHarmlessRow { color: var(--text-dim); }

#hudRight #muteBtn { padding: 5px 7px; font-size: 13px; line-height: 1; }
#muteBtn[aria-pressed="true"] { opacity: 0.55; }

#stopTestBtn { background: rgba(229, 57, 53, 0.15); border-color: rgba(229, 57, 53, 0.5); color: #ff8a80; }
#stopTestBtn:hover { background: rgba(229, 57, 53, 0.28); }

/* Short viewports — landscape phones, the orientation this game locks to.
   The board is height-bound there, so every pixel of page chrome is board
   width lost at the 1100:660 ratio: trimming 20px of padding buys ~33px of
   board. Keep --chrome in step with what this leaves. */
@media (max-height: 500px) {
  body { padding: 0; }
  #gameCanvas { --chrome: 2px; border-radius: 0; }
  .screen { padding: 16px 24px; }
  .screen h1 { font-size: 22px; margin-bottom: 6px; }
  /* The main menu: three tiles side by side instead of stacked, and the
     paragraphs that made it scroll on a phone are dropped -- the tiles carry
     their own one-line descriptions. */
  #modeMenu { flex-direction: row; gap: 8px; width: 100%; max-width: none; }
  .screen .modeTile { padding: 10px 12px; flex: 1 1 0; }
  .screen .modeName { font-size: 15px; }
  .screen .modeDesc { font-size: 11px; line-height: 1.3; }
  .screen .tagline, .screen .startRules { display: none; }
  .screen p { font-size: 13px; margin: 4px 0; }
  .screen button { margin-top: 10px; padding: 9px 16px; font-size: 14px; }
}

/* --- Phone ------------------------------------------------------------- */
/* Testing furniture -- level jump, Stop Testing, Log Session, Copy JSON -- is
   hidden unless the page was opened with ?test=1 (remembered), so a friend
   with the link never meets it. */
.testOnly { display: none !important; }
body.testMode .testOnly { display: inline-block !important; }
body.testMode #stripPickRow.testOnly { display: flex !important; }

/* A thumb needs 44 CSS px. Every screen button gets it on a touch device;
   the board's own controls are sized in js/hud.js. */
@media (pointer: coarse) {
  .screen button { min-height: 44px; }
  /* The toast is unreadable at phone scale and the portal colour already
     carries the verdict. */
  #toast { display: none; }
}

/* Landscape only, by decision. Portrait on a touch device shows this instead
   of a 190px-tall road. */
#rotateOverlay {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 100;
  background: var(--bg);
  color: var(--text);
  align-items: center;
  justify-content: center;
  text-align: center;
  font-size: 20px;
  font-weight: 600;
}
#rotateOverlay .rotateIcon { font-size: 48px; display: inline-block; transform: rotate(90deg); }
@media (orientation: portrait) and (pointer: coarse) {
  #rotateOverlay { display: flex; }
}

/* The pause screen. */
/* One under the other (owner, 2026-09-18): a list reads as a menu, a wrapped
   row read as a toolbar. Every button takes the column's width so they line
   up whatever their labels. */
#pauseActions { display: flex; flex-direction: column; align-items: stretch; gap: 8px; width: min(280px, 80%); }
#pauseActions button { margin-top: 0; width: 100%; }
#settingsPanel { margin-top: 18px; display: flex; flex-wrap: wrap; justify-content: center; gap: 14px 18px; align-items: center; color: var(--text-dim); font-size: 14px; }
#settingsPanel input[type="range"] { width: 110px; margin-left: 8px; vertical-align: middle; accent-color: var(--accent, #a586ff); }
/* The author display rule above would beat the `hidden` attribute's UA rule. */
#settingsPanel[hidden] { display: none; }
#settingsPanel select { margin-left: 8px; padding: 6px 8px; font-size: 14px; background: var(--panel); color: var(--text); border: 1px solid var(--panel-border); border-radius: 6px; }
#settingsPanel #muteBtn { margin-top: 0; padding: 8px 12px; font-size: 16px; background: var(--panel); border-color: var(--panel-border); }

/* --- Traffic School ------------------------------------------------------
   The lesson brief is the one screen in the game that is mostly prose, so it
   is the one screen that needs a reading measure: the paragraph is capped at
   ~58 characters rather than running the full width of a 1100px board. */
#lessonBadge {
  font-size: 12px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--mid, #d8a33a);
  margin-bottom: 10px;
}
#lessonScreen h1 {
  margin: 0 0 14px;
  max-width: 22ch;
}
#lessonBrief {
  max-width: 58ch;
  margin: 0 auto 14px;
  line-height: 1.6;
}
#lessonGoal {
  font-weight: 600;
  margin: 0 0 22px;
}
#lessonActions {
  display: flex;
  gap: 10px;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
}
/* A quiet second action: leaving school should be possible without being
   offered as loudly as continuing it. Written as `.screen .ghostBtn` because
   `.screen button` above sets the accent fill and would otherwise win on
   specificity — which it did, and the two buttons rendered identically. */
.screen .ghostBtn {
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.28);
  color: rgba(255, 255, 255, 0.72);
}
.screen .ghostBtn:hover {
  background: transparent;
  border-color: rgba(255, 255, 255, 0.5);
  color: #fff;
}

/* --- the attract menu (2026-09-18) ------------------------------------------
   A live road runs behind the menu (main.js, attract mode), so the start
   screen stops being a wall: a vignette instead of the 94% black, the logo
   first, then the tiles. Everything here is scoped to body.attractMenu; with
   the class off, the rules under "classic" below put the old screen back. */
#titleStage, #menuIcons, .menuLogo { display: none; }
#menuStage { display: flex; flex-direction: column; align-items: center; width: 100%; }
.loadingLogo { width: min(70%, 620px); height: auto; margin-bottom: 8px; filter: drop-shadow(0 6px 22px rgba(0, 0, 0, 0.6)); }

body.attractMenu #startScreen {
  background:
    radial-gradient(ellipse at center, rgba(10, 11, 15, 0.30) 0%, rgba(10, 11, 15, 0.62) 70%, rgba(10, 11, 15, 0.82) 100%);
}
/* The other menu screens keep their dark ground, a little thinner, so the road
   is still felt behind a list without fighting the text on it. */
body.attractMenu #achievementsScreen,
body.attractMenu #leaderboardScreen,
body.attractMenu #stripSelectScreen,
body.attractMenu #settingsScreen { background: rgba(10, 11, 15, 0.88); }

/* Stage one: the logo and a prompt. The whole screen is the button. */
body.attractMenu #startScreen.stage-title { cursor: pointer; }
body.attractMenu #startScreen.stage-title #titleStage { display: flex; flex-direction: column; align-items: center; }
body.attractMenu #startScreen.stage-title #menuStage,
body.attractMenu #startScreen.stage-title #menuIcons { display: none; }
#titleLogo {
  width: min(78%, 900px);
  height: auto;
  filter: drop-shadow(0 10px 34px rgba(0, 0, 0, 0.7));
  animation: titleFloat 3.2s ease-in-out infinite;
  user-select: none;
  -webkit-user-drag: none;
}
@keyframes titleFloat { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-7px); } }
.screen #titlePrompt {
  margin-top: 18px;
  font-size: clamp(13px, 2.2vw, 18px);
  font-weight: 700;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: #d8ffe0;
  text-shadow: 0 2px 10px rgba(0, 0, 0, 0.9);
  animation: titlePulse 1.6s ease-in-out infinite;
}
@keyframes titlePulse { 0%, 100% { opacity: 0.35; } 50% { opacity: 1; } }

/* Stage two: the tiles, under a small logo where the title text was. */
body.attractMenu #startScreen.stage-menu #menuStage { animation: menuIn 0.35s ease-out both; }
@keyframes menuIn { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
body.attractMenu .menuLogo { display: block; width: min(46%, 430px); height: auto; filter: drop-shadow(0 6px 20px rgba(0, 0, 0, 0.7)); user-select: none; -webkit-user-drag: none; }
body.attractMenu #startScreen h1,
body.attractMenu #startScreen .startRules,
body.attractMenu #menuExtras { display: none; }
body.attractMenu #startScreen .tagline { color: #cfd3da; text-shadow: 0 1px 8px rgba(0, 0, 0, 0.9); margin-top: 2px; }
body.attractMenu #modeMenu { margin-top: 22px; }
/* Tiles sit on moving traffic now, so they carry their own ground. */
body.attractMenu .screen .modeTile { background: rgba(24, 26, 33, 0.90); backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px); box-shadow: 0 6px 22px rgba(0, 0, 0, 0.45); }
body.attractMenu .screen .modeTile:hover { background: rgba(38, 41, 50, 0.95); }
body.attractMenu .screen #menuStats { color: #cfd3da; text-shadow: 0 1px 6px rgba(0, 0, 0, 0.9); }

/* Records and settings: icons in the corner, out of the tiles' way. */
body.attractMenu #menuIcons { display: flex; position: absolute; top: 14px; right: 16px; gap: 10px; z-index: 2; }
.screen .iconBtn {
  margin-top: 0;
  width: 46px;
  height: 46px;
  padding: 0;
  font-size: 21px;
  line-height: 1;
  border-radius: 50%;
  background: rgba(24, 26, 33, 0.88);
  border: 1px solid rgba(255, 255, 255, 0.22);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.45);
}
.screen .iconBtn:hover { background: rgba(48, 52, 62, 0.95); border-color: rgba(255, 255, 255, 0.45); }

#settingsHost { display: flex; justify-content: center; width: 100%; }
#settingsHost #settingsPanel { margin-top: 8px; }
.screen #settingsBackBtn { margin-top: 22px; padding: 8px 16px; font-size: 13px; }

@media (max-height: 500px) {
  body.attractMenu .menuLogo { width: min(30%, 260px); }
  body.attractMenu #modeMenu { margin-top: 8px; }
  #titleLogo { width: min(64%, 640px); }
  body.attractMenu #menuIcons { top: 8px; right: 10px; gap: 8px; }
  .screen .iconBtn { width: 40px; height: 40px; font-size: 18px; min-height: 0; }
}
