/* ============================================================================
   NordsGuesser — global stylesheet.

   All visual values live in :root. Components MUST reference semantic tokens
   (--color-*, --space-*, --radius-*, --transition-*) — never the NG_*
   primitives or raw values. See AGENT_GUIDELINES.md §1 (CSS discipline).
   ============================================================================ */

:root {

  /* ─── FONTS ──────────────────────────────────────────────────────────────
     Brand font: Geom. Geom isn't on Google Fonts so Barlow Condensed is the
     served fallback — same proportions, ships from Google Fonts. When the
     Geom files are added the variable doesn't have to change. */
  --font-display: 'Geom', 'Barlow Condensed', sans-serif;
  --font-ui: 'Geom', 'Barlow Condensed', sans-serif;
  --font-body: 'Geom', 'Barlow Condensed', sans-serif;

  /* Two weights only. Black Italic = display/titles. Medium = everything else. */
  --fw-black: 900;
  --fw-medium: 500;

  /* ─── FONT SIZES (16px base = 1rem) ──────────────────────────────────────
     Every font-size in the stylesheet should reference one of these — keeps
     the type scale consistent. clamp()-based responsive headings (subpage
     title, summary total) stay literal on purpose. */
  --fs-xs: 0.6875rem;
  /* 11px - micro labels, eyebrows, tooltips */
  --fs-sm: 0.8125rem;
  /* 13px - small body, secondary text */
  --fs-md: 1rem;
  /* 16px - body, buttons */
  --fs-lg: 1.5rem;
  /* 24px - subheadings, key stat values */
  --fs-xl: 2rem;
  /* 32px - large display numbers */
  --fs-hero: 4rem;
  /* 64px - hero (timer) */

  /* ─── BRAND PALETTE (source of truth) ────────────────────────────────── */
  --NG_RED_500: rgb(234, 0, 0);
  --NG_RED_700: rgb(121, 1, 1);
  --NG_WHITE: rgb(255, 244, 244);
  --NG_GREY_900: rgb(13, 11, 11);
  --NG_GREY_700: rgb(26, 21, 21);

  /* ─── SEMANTIC COLOUR TOKENS ─────────────────────────────────────────── */
  --color-accent: var(--NG_RED_500);
  --color-accent-dark: var(--NG_RED_700);
  --color-accent-dim: rgba(234, 0, 0, 0.15);
  --color-accent-glow: rgba(234, 0, 0, 0.35);

  --color-bg: var(--NG_GREY_900);
  --color-bg-card: rgba(13, 11, 11, 0.92);
  --color-bg-panel: rgba(26, 21, 21, 0.85);
  --color-bg-input: rgba(26, 21, 21, 0.90);
  --color-bg-hover: rgba(255, 244, 244, 0.04);

  --color-border: rgba(255, 244, 244, 0.08);
  --color-border-mid: rgba(255, 244, 244, 0.14);
  --color-border-strong: rgba(255, 244, 244, 0.24);

  --color-text: var(--NG_WHITE);
  --color-text-muted: rgba(255, 244, 244, 0.50);
  --color-text-dim: rgba(255, 244, 244, 0.28);
  --color-text-accent: var(--color-accent);

  --color-success: #48BB78;
  --color-warning: #ECC94B;
  --color-danger: var(--color-accent);

  --color-map-bg: var(--NG_GREY_700);
  --color-map-track: var(--NG_WHITE);
  --color-map-pin: var(--color-accent);
  --color-map-actual: #F6C90E;
  --color-map-line: rgba(234, 0, 0, 0.6);

  /* ─── CORNER RADII ───────────────────────────────────────────────────── */
  --radius-xs: 4px;
  --radius-sm: 8px;
  --radius-md: 12px;
  --radius-lg: 16px;
  --radius-xl: 24px;
  --radius-pill: 999px;

  /* ─── SPACING (4px base) ─────────────────────────────────────────────── */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;
  --space-10: 40px;
  --space-12: 48px;
  --space-16: 64px;

  /* ─── TRANSITIONS ────────────────────────────────────────────────────── */
  --transition-fast: 0.15s ease;
  --transition-base: 0.25s ease;
  --transition-slow: 0.4s ease;
  --transition-screen: 0.45s ease;

  /* ─── Z-INDEX LAYERS ─────────────────────────────────────────────────── */
  --z-bg: 0;
  --z-game: 10;
  --z-hud: 20;
  --z-map: 30;
  --z-overlay: 40;
  --z-toast: 50;

  /* ─── COMPONENT-SCOPED METRICS (not raw values) ──────────────────────── */
  --map-widget-w: 220px;
  --map-widget-h: 165px;
  --map-widget-w-expanded: 760px;
  --map-widget-h-expanded: 570px;
}

* {
  box-sizing: border-box;
}

html,
body {
  height: 100%;
}

body {
  /* `overflow: hidden` alone isn't enough on iOS Safari — the URL bar's
     dynamic resize lets the page bounce/scroll past the map widget even
     when nothing is taller than 100dvh. Pinning the body to the
     viewport coords (`position: fixed`) + disabling overscroll bounce
     fully locks layout to the visible area. Children with their own
     `overflow: auto` (the splash, leaderboard modal, reveal card) still
     scroll their own contents — only the document itself is frozen. */
  margin: 0;
  position: fixed;
  inset: 0;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
  font-weight: var(--fw-medium);
  overflow: hidden;
  overscroll-behavior: none;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

#app {
  position: relative;
  width: 100vw;
  /* 100vh on mobile Safari measures against the LARGEST viewport (URL bar
     hidden), so anything anchored to `bottom: 0` slips below the visible
     area when the URL bar is up. 100dvh tracks the current viewport so the
     FAB and the bottom of the map widget stay above the URL bar. */
  height: 100vh;
  height: 100dvh;
}

/* Form controls don't inherit body font in any browser — explicit override
   here so anything new automatically picks up the brand font. */
button,
input,
select,
textarea {
  font-family: inherit;
}

/* ============================================================================
   View visibility — JS sets data-view, CSS reveals matching <section>.
   ============================================================================ */

.view {
  display: none;
  animation: viewFadeIn var(--transition-screen);
}

/* Splash is flex (centred card), the other views are block (full-bleed). */
#app[data-view="splash"] .view-splash {
  display: flex;
}

#app[data-view="loading"] .view-play,
#app[data-view="round"] .view-play,
#app[data-view="reveal"] .view-play {
  display: block;
}

#app[data-view="summary"] .view-summary {
  display: block;
}

/* Standalone subpages (about.html, support.html, future.html) put this class
   on the section so it overrides the .view { display: none } baseline. */
.view.view-subpage-active {
  display: block;
}

@keyframes viewFadeIn {
  from {
    opacity: 0;
  }

  to {
    opacity: 1;
  }
}

/* ============================================================================
   Buttons (shared primitives)
   ============================================================================ */

.btn {
  appearance: none;
  border: 0;
  background: var(--color-accent);
  color: var(--color-text);
  font-family: var(--font-ui);
  font-weight: var(--fw-medium);
  font-size: var(--fs-md);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: var(--space-3) var(--space-5);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background var(--transition-fast), transform var(--transition-fast);
}

.btn:hover {
  background: var(--color-accent-dark);
}

.btn:active {
  transform: scale(0.98);
}

.btn:focus-visible {
  outline: 2px solid var(--color-text);
  outline-offset: 2px;
}

.btn:disabled {
  background: var(--color-bg-input);
  color: var(--color-text-dim);
  cursor: not-allowed;
}

/* Spinner + label layout for the Loading… state on the Play button. */
.btn .btn-spinner,
.btn .btn-label {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}

.btn .btn-spinner {
  display: none;
  width: 14px;
  height: 14px;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: btnSpin 0.7s linear infinite;
  margin-right: var(--space-2);
  vertical-align: middle;
}

.btn.is-loading .btn-spinner {
  display: inline-block;
}

/* When loading, keep the primary background but tone the look down a notch
   so it visibly differs from a regular hoverable Play button. */
.btn.is-loading {
  background: var(--color-bg-input);
  color: var(--color-text);
  cursor: progress;
  opacity: 0.85;
}

@keyframes btnSpin {
  to {
    transform: rotate(360deg);
  }
}

.btn-primary {
  background: var(--color-accent);
}

.btn-primary:hover {
  background: var(--color-accent-dark);
  transform: scale(1.02);
}

.btn-secondary {
  background: transparent;
  border: 1px solid var(--color-border-strong);
  color: var(--color-text);
}

.btn-secondary:hover {
  background: var(--color-bg-hover);
  border-color: var(--color-accent);
}

.btn-block {
  display: block;
  width: 100%;
}

.btn-large {
  font-size: var(--fs-md);
  padding: var(--space-4) var(--space-6);
  letter-spacing: 0.12em;
}

/* ============================================================================
   Splash screen
   ============================================================================ */

/* Layout only — the data-view rule above controls when this becomes flex.
   Don't add a baseline `display` here; it would beat the .view { display: none }
   rule (same specificity, later in source order) and the splash would never hide. */
.view-splash {
  position: relative;
  width: 100%;
  height: 100%;
  background: var(--color-bg);
  align-items: center;
  justify-content: center;
  padding: var(--space-6);
}

/* Layered day/night backgrounds — fade between them when the toggle flips. */
.splash-bg {
  position: absolute;
  inset: 0;
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
  opacity: 0;
  transition: opacity 0.6s ease;
  z-index: 0;
}

.splash-bg-day {
  background-image: url('../assets/NG-BG-01-Day.jpg');
}

.splash-bg-night {
  background-image: url('../assets/NG-BG-01-Night.jpg');
}

.view-splash[data-difficulty="day"] .splash-bg-day {
  opacity: 1;
}

.view-splash[data-difficulty="night"] .splash-bg-night {
  opacity: 1;
}

.splash-overlay {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(0, 0, 0, 0.65) 0%, rgba(0, 0, 0, 0.45) 50%, rgba(0, 0, 0, 0.85) 100%);
  z-index: 1;
  pointer-events: none;
}

.splash-card {
  position: relative;
  z-index: 2;
}

.splash-card {
  width: min(520px, 100%);
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--space-5);
  text-align: center;
}

.splash-logo {
  width: 100%;
  height: auto;
  margin: 0 auto;
  display: block;
  filter: drop-shadow(0 4px 24px rgba(0, 0, 0, 0.6));
}

/* The wordmark IS the title — keep the H1 in the DOM for a11y but hide it visually. */
.splash-title {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.splash-tagline {
  margin: 0;
  font-family: var(--font-body);
  font-style: italic;
  font-size: var(--fs-md);
  color: var(--color-text);
  letter-spacing: 0.02em;
}

.splash-rules {
  margin: 0;
  padding: var(--space-4) var(--space-5);
  list-style: none;
  background: var(--color-bg-card);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-2) var(--space-4);
  font-size: var(--fs-sm);
  color: var(--color-text);
  text-align: left;
}

.splash-rules li {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
}

.splash-rules li::before {
  content: "›";
  color: var(--color-accent);
  font-weight: var(--fw-black);
}

/* Rule item that spans both columns — used for the lap length line. */
.splash-rules .span-2 {
  grid-column: 1 / -1;
  justify-content: center;
}

/* Splash play-panel rows — labelled timer + map controls (Free Play tab).
   Container styling lives on .play-panel; this just lays out each row. */
.control-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}

.control-label {
  font-family: var(--font-ui);
  font-weight: var(--fw-medium);
  font-size: var(--fs-xs);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  flex: 0 0 auto;
}

.control-pills {
  display: inline-flex;
  background: var(--color-bg-input);
  border: 1px solid var(--color-border-mid);
  border-radius: var(--radius-pill);
  padding: var(--space-1);
  gap: var(--space-1);
}

.control-pill {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--color-text);
  opacity: 0.7;
  font-family: var(--font-ui);
  font-weight: var(--fw-medium);
  font-size: var(--fs-sm);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-pill);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  transition: background var(--transition-fast), opacity var(--transition-fast);
}

/* Icon (sun/moon) inside a pill — small right-margin instead of a flex
   gap so the text stays visually centred when it wraps to a second
   line. The gap-on-parent approach left a phantom gap-width column when
   the text broke onto its own line. */
.control-pill .toggle-icon {
  margin-inline-end: var(--space-2);
  flex: 0 0 auto;
}

.control-pill:hover {
  opacity: 1;
}

.control-pill[aria-pressed="true"] {
  background: var(--color-accent);
  color: var(--color-text);
  opacity: 1;
}

/* Locked / not-yet-available pill (e.g. Night until the dataset ships).
   Greyed out, no hover lift, tiny "Soon™" tooltip on hover. */
.control-pill.is-locked,
.control-pill[disabled] {
  cursor: not-allowed;
  opacity: 0.35;
  position: relative;
}

.control-pill.is-locked:hover {
  opacity: 0.35;
}

.control-pill[data-tooltip]:hover::after {
  content: attr(data-tooltip);
  position: absolute;
  bottom: calc(100% + var(--space-2));
  left: 50%;
  transform: translateX(-50%);
  padding: var(--space-1) var(--space-3);
  background: var(--color-bg-card);
  border: 1px solid var(--color-border-mid);
  border-radius: var(--radius-sm);
  font-family: var(--font-ui);
  font-weight: var(--fw-medium);
  font-size: var(--fs-xs);
  letter-spacing: 0.08em;
  text-transform: none;
  color: var(--color-text);
  white-space: nowrap;
  pointer-events: none;
  opacity: 1;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
  z-index: var(--z-toast);
}

/* Legacy .difficulty-toggle still referenced by older code paths — leave
   the rules in place but the markup now uses .control-pills. */
.difficulty-toggle {
  display: inline-flex;
  align-self: center;
  background: var(--color-bg-input);
  border: 1px solid var(--color-border-mid);
  border-radius: var(--radius-pill);
  padding: var(--space-1);
  gap: var(--space-1);
}

.difficulty-toggle button {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--color-text);
  opacity: 0.7;
  font-family: var(--font-ui);
  font-weight: var(--fw-medium);
  font-size: var(--fs-sm);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-pill);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  transition: background var(--transition-fast), opacity var(--transition-fast);
}

.difficulty-toggle button:hover {
  opacity: 1;
}

.difficulty-toggle button[aria-pressed="true"] {
  background: var(--color-accent);
  color: var(--color-text);
  opacity: 1;
}

.difficulty-toggle .toggle-icon {
  width: 14px;
  height: 14px;
  display: inline-block;
}

.splash-status {
  margin: 0;
  font-size: var(--fs-xs);
  color: var(--color-text);
  opacity: 0.75;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  min-height: 1em;
}

.splash-footer {
  margin: var(--space-4) 0 0;
  font-size: var(--fs-sm);
  font-style: italic;
  color: var(--color-text);
  opacity: 0.75;
}

/* ============================================================================
   Menu button + overlay (top-right CTA, modal nav, used by splash + summary)
   ============================================================================ */

.menu-btn {
  position: absolute;
  top: var(--space-5);
  right: var(--space-5);
  z-index: var(--z-hud);
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  background: var(--color-bg-card);
  border: 1px solid var(--color-border-mid);
  border-radius: var(--radius-pill);
  color: var(--color-text);
  font-family: var(--font-ui);
  font-weight: var(--fw-medium);
  font-size: var(--fs-sm);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  cursor: pointer;
  backdrop-filter: blur(8px);
  transition: background var(--transition-fast), border-color var(--transition-fast);
}

.menu-btn:hover {
  background: var(--color-bg-panel);
  border-color: var(--color-border-strong);
}

.menu-btn svg {
  width: 18px;
  height: 18px;
  display: block;
}

.menu-overlay {
  position: fixed;
  inset: 0;
  z-index: var(--z-overlay);
  display: flex;
  align-items: flex-start;
  justify-content: flex-end;
  padding: var(--space-5);
  background: rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(4px);
  animation: viewFadeIn var(--transition-base);
}

.menu-overlay[hidden] {
  display: none;
}

.menu-overlay-panel {
  width: min(320px, 100%);
  padding: var(--space-5);
  background: var(--color-bg-card);
  border: 1px solid var(--color-border-mid);
  border-radius: var(--radius-lg);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  box-shadow: 0 18px 64px rgba(0, 0, 0, 0.6);
}

.menu-overlay-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.menu-overlay-title {
  font-family: var(--font-display);
  font-weight: var(--fw-black);
  font-style: italic;
  font-size: var(--fs-lg);
  letter-spacing: 0.18em;
  color: var(--color-text-muted);
  text-transform: uppercase;
}

.menu-overlay-close {
  appearance: none;
  background: transparent;
  border: 0;
  color: var(--color-text);
  font-size: var(--fs-xl);
  line-height: 1;
  cursor: pointer;
  padding: 0 var(--space-2);
}

.menu-overlay-close:hover {
  color: var(--color-accent);
}

.menu-overlay-nav {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.menu-overlay-link {
  appearance: none;
  background: transparent;
  border: 0;
  padding: var(--space-3) var(--space-4);
  color: var(--color-text);
  font-family: var(--font-ui);
  font-weight: var(--fw-medium);
  font-size: var(--fs-md);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  text-decoration: none;
  text-align: left;
  cursor: pointer;
  border-radius: var(--radius-md);
  transition: background var(--transition-fast), color var(--transition-fast);
}

.menu-overlay-link:hover,
.menu-overlay-link:focus-visible {
  background: var(--color-bg-hover);
  color: var(--color-accent);
  outline: 0;
}

/* The link for the current page subtly dims so it reads as "you're here". */
.menu-overlay-link[aria-current="page"] {
  color: var(--color-text-muted);
  cursor: default;
}

/* ============================================================================
   Subpages (About / Support / Future Plans) — same shell, different content.
   ============================================================================ */

.view-subpage {
  position: relative;
  width: 100%;
  height: 100%;
  background:
    radial-gradient(circle at 50% 30%, rgba(234, 0, 0, 0.08), transparent 60%),
    var(--color-bg);
  overflow-y: auto;
}

/* Shared page banner — used in-game and on subpages. Logo (left) goes home,
   menu (right) opens the modal nav. Mirrors the .hud-banner look but lives
   in normal flow so the page content sits below it. */
.page-banner {
  position: sticky;
  top: 0;
  left: 0;
  right: 0;
  z-index: var(--z-hud);
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: var(--space-4) var(--space-6);
  background: rgba(13, 11, 11, 0.85);
  border-bottom: 1px solid var(--color-border);
  backdrop-filter: blur(10px);
  gap: var(--space-4);
}

/* The menu button is absolute-positioned by default (for the splash/summary
   top-right placement). Inside a banner it sits in normal flow. */
.page-banner .menu-btn {
  position: static;
  top: auto;
  right: auto;
}

.page-banner .banner-home-btn .banner-logo {
  height: 36px;
}

.subpage-card {
  max-width: 680px;
  margin: 0 auto;
  padding: var(--space-16) var(--space-6) var(--space-16);
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

.subpage-title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: var(--fw-black);
  font-style: italic;
  font-size: clamp(48px, 7vw, 72px);
  line-height: 0.95;
  letter-spacing: 0.01em;
  color: var(--color-text);
}

.subpage-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  font-size: var(--fs-md);
  line-height: 1.65;
  color: var(--color-text);
}

.subpage-body p {
  margin: 0;
}

/* Inline text links inside a subpage body — but NOT the CTA buttons that
   happen to be anchors. .btn keeps its own colours. */
.subpage-body a:not(.btn) {
  color: var(--color-accent);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.subpage-body a:not(.btn):hover {
  color: var(--color-text);
}

/* Anchor-as-button overrides — the default browser link colour and the
   .subpage-body cascade both lose to these. */
a.btn {
  color: var(--color-text);
  text-decoration: none;
}

a.btn-primary {
  color: var(--color-text);
}

a.btn-primary:hover {
  color: var(--color-text);
}

a.btn-secondary {
  color: var(--color-text);
}

a.btn-secondary:hover {
  color: var(--color-text);
}

.subpage-list {
  margin: 0;
  padding-left: var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.subpage-list li::marker {
  color: var(--color-accent);
}

.subpage-actions {
  display: flex;
  gap: var(--space-3);
  flex-wrap: wrap;
  margin-top: var(--space-2);
}

.subpage-aside {
  margin: 0;
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-border);
  font-size: var(--fs-sm);
  color: var(--color-text-muted);
  font-style: italic;
}

/* ============================================================================
   Support callout (inline strip on splash + summary)
   ============================================================================ */

.support-callout {
  padding: var(--space-4) var(--space-5);
  background: var(--color-bg-card);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
}

.support-callout-text {
  margin: 0;
  font-family: var(--font-display);
  font-weight: var(--fw-black);
  font-style: italic;
  font-size: var(--fs-md);
  line-height: 1.25;
  letter-spacing: 0.01em;
  color: var(--color-text);
  text-align: center;
}

.support-callout-links {
  display: flex;
  gap: var(--space-3);
  flex-wrap: wrap;
  justify-content: center;
}

.support-link {
  font-size: var(--fs-sm);
  padding: var(--space-2) var(--space-4);
  letter-spacing: 0.08em;
  text-decoration: none;
}

/* Banner home button (in-game logo click target → exits to splash). */
.banner-home-btn {
  appearance: none;
  border: 0;
  background: transparent;
  padding: 0;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  border-radius: var(--radius-sm);
  transition: opacity var(--transition-fast);
}

.banner-home-btn:hover {
  opacity: 0.85;
}

.banner-home-btn:active {
  transform: scale(0.97);
}

.banner-home-btn .banner-logo {
  pointer-events: none;
}

/* ============================================================================
   Play view container — hosts loading/round/reveal states.
   ============================================================================ */

.view-play {
  position: relative;
  width: 100%;
  height: 100%;
  background: var(--color-bg);
}

.capture-image {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: var(--z-bg);
  transform-origin: 0 0;
  /* origin matters for the wheel-zoom anchor math */
  transition: opacity var(--transition-screen);
  /* Block native image drag (browser's save-image-as drag) which otherwise
     intercepts mousedown and turns the in-game pan into a toggle. */
  -webkit-user-drag: none;
  user-select: none;
  -webkit-user-select: none;
  /* Disable browser-default touch gestures (pinch-zoom the page, swipe to
     navigate, etc) so our pointer-event handlers fully own touch input. */
  touch-action: none;
}

.capture-image.is-zoomed {
  cursor: grab;
}

.capture-image.is-dragging {
  cursor: grabbing;
}

#app[data-view="loading"] .capture-image {
  opacity: 0;
}

#app[data-view="round"] .capture-image {
  opacity: 1;
}

#app[data-view="reveal"] .capture-image {
  opacity: 0.3;
}

/* ─── Loading overlay (between rounds, while image fetches) ────────────── */

.loading-overlay {
  position: absolute;
  inset: 0;
  z-index: var(--z-overlay);
  background: var(--color-bg);
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-6);
}

#app[data-view="loading"] .loading-overlay {
  display: flex;
}

.loading-logo {
  width: 240px;
  height: 144px;
}

.loading-logo .track-line {
  stroke: var(--color-accent);
  stroke-width: 4;
  fill: none;
  stroke-linejoin: round;
  stroke-linecap: round;
  stroke-dasharray: 1200;
  stroke-dashoffset: 1200;
  animation: tracePath 1.6s ease-out forwards;
}

@keyframes tracePath {
  to {
    stroke-dashoffset: 0;
  }
}

.loading-label {
  margin: 0;
  font-family: var(--font-display);
  font-weight: var(--fw-black);
  font-style: italic;
  font-size: var(--fs-xl);
  letter-spacing: 0.16em;
  color: var(--color-text);
}

.loading-bar {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: var(--color-border);
}

.loading-bar-fill {
  height: 100%;
  background: var(--color-accent);
  width: 0;
  transition: width var(--transition-base);
}

/* ─── In-round HUD ─────────────────────────────────────────────────────── */

.hud {
  position: absolute;
  z-index: var(--z-hud);
  display: none;
}

#app[data-view="round"] .hud {
  display: flex;
}

/* Top banner: logo (left), round + score (right). Spans full width. */
.hud-banner {
  top: 0;
  left: 0;
  right: 0;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
  padding: var(--space-4) var(--space-6);
  background: rgba(13, 11, 11, 0.72);
  /* NG_GREY_900 @ 72% */
  border-bottom: 1px solid var(--color-border);
  backdrop-filter: blur(10px);
  gap: var(--space-4);
}

/* Lets us hide the compass without ripping it out — easier to bring back. */
.hud.is-hidden {
  display: none !important;
}

.banner-logo {
  height: 36px;
  width: auto;
  display: block;
  filter: drop-shadow(0 2px 8px rgba(0, 0, 0, 0.6));
}

.banner-meta {
  display: flex;
  align-items: center;
  gap: var(--space-6);
}

.banner-stat {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 2px;
  line-height: 1;
}

.banner-stat-label {
  font-family: var(--font-ui);
  font-weight: var(--fw-medium);
  font-size: var(--fs-xs);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

.banner-stat-value {
  font-family: var(--font-display);
  font-weight: var(--fw-black);
  font-style: italic;
  font-size: var(--fs-lg);
  letter-spacing: 0.04em;
  color: var(--color-text);
  font-variant-numeric: tabular-nums;
  text-shadow: 0 2px 8px rgba(0, 0, 0, 0.6);
}

/* Compass + timer block, centered below the banner. */
.hud-compass-block {
  top: calc(var(--space-12) + var(--space-6));
  left: 50%;
  transform: translateX(-50%);
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
}

/* Timer-only block (compass is hidden right now). */
.hud-timer-block {
  top: calc(var(--space-12) + var(--space-10) + var(--space-6));
  left: 50%;
  transform: translateX(-50%);
  flex-direction: column;
  align-items: center;
}

.compass-strip {
  width: 280px;
  height: 36px;
  overflow: hidden;
  background: linear-gradient(180deg, rgba(0, 0, 0, 0.45), rgba(0, 0, 0, 0.25));
  border: 1px solid var(--color-border-mid);
  border-radius: var(--radius-pill);
  filter: drop-shadow(0 2px 8px rgba(0, 0, 0, 0.5));
  /* Fade out the ribbon at both edges so labels feel like they slide past. */
  mask-image: linear-gradient(90deg, transparent 0, #000 12%, #000 88%, transparent 100%);
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 12%, #000 88%, transparent 100%);
}

.compass-tick {
  stroke: var(--color-text-muted);
  stroke-linecap: round;
}

.compass-tick.major {
  stroke-width: 1.5;
}

.compass-tick.minor {
  stroke-width: 1;
  stroke: var(--color-text-dim);
}

.compass-label {
  font-family: var(--font-ui);
  font-weight: var(--fw-medium);
  font-size: var(--fs-xs);
  letter-spacing: 0.18em;
  fill: var(--color-text-muted);
  dominant-baseline: middle;
}

/* The cardinal label nearest the centre indicator gets emphasised. */
.compass-label.is-active {
  font-size: var(--fs-sm);
  font-weight: var(--fw-black);
  font-style: italic;
  fill: var(--color-text);
}

.compass-indicator {
  fill: var(--color-accent);
  filter: drop-shadow(0 0 4px var(--color-accent-glow));
}

.timer {
  font-family: var(--font-display);
  font-weight: var(--fw-black);
  font-style: italic;
  font-size: var(--fs-hero);
  line-height: 1;
  color: var(--color-text);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
  text-shadow: 0 2px 16px rgba(0, 0, 0, 0.75);
}

.timer.is-urgent {
  color: var(--color-accent);
  animation: pulseUrgent 0.6s ease-in-out infinite alternate;
}

@keyframes pulseUrgent {
  from {
    transform: scale(1);
    text-shadow: 0 2px 12px rgba(0, 0, 0, 0.75);
  }

  to {
    transform: scale(1.06);
    text-shadow: 0 2px 24px var(--color-accent-glow);
  }
}


/* ─── Map widget (bottom right, expands on hover/focus) ────────────────── */

.map-widget {
  position: absolute;
  z-index: var(--z-map);
  bottom: var(--space-6);
  right: var(--space-6);
  width: var(--map-widget-w);
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  transition: width var(--transition-base);
}

/* "Guess!" nudge above the corner widget so first-time players notice
   they need to drop a pin on the small map. Fades out once they've
   either opened the widget or placed a pin — by then the hint has done
   its job. Hidden on portrait phones where the map fills half the
   screen and the affordance is already obvious. */
.map-hint {
  align-self: flex-end;
  margin: 0;
  padding: var(--space-1) var(--space-3);
  background: var(--color-bg-card);
  border-radius: var(--radius-pill);
  font-family: var(--font-display);
  font-weight: var(--fw-black);
  font-style: italic;
  font-size: var(--fs-sm);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-accent);
  text-align: center;
  backdrop-filter: blur(8px);
  pointer-events: none;
  transition: opacity var(--transition-fast);
}

.map-widget.has-pin .map-hint,
.map-widget.is-open .map-hint {
  opacity: 0;
}

.map-widget-panel {
  position: relative;
  width: 100%;
  height: var(--map-widget-h);
  background: var(--color-bg-panel);
  border: 1px solid var(--color-border-mid);
  border-radius: var(--radius-md);
  overflow: hidden;
  backdrop-filter: blur(8px);
  transition: width var(--transition-base), height var(--transition-base);
}

/* Expansion is JS-controlled now (mouseenter adds .is-open immediately;
   mouseleave removes it after a delay) — that lets us keep the panel up for
   a beat if the cursor briefly leaves. */
.map-widget.is-open,
.map-widget.is-dragging {
  width: var(--map-widget-w-expanded);
}

.map-widget.is-open .map-widget-panel,
.map-widget.is-dragging .map-widget-panel {
  height: var(--map-widget-h-expanded);
}

#app[data-view="round"] .map-widget {
  display: flex;
}

#app[data-view="loading"] .map-widget,
#app[data-view="reveal"] .map-widget {
  display: none;
}

.map-svg {
  width: 100%;
  height: 100%;
  display: block;
  background: var(--color-map-bg);
  cursor: pointer;
  touch-action: none;
  /* Don't let a drag inside the map double as a text-selection. */
  user-select: none;
  -webkit-user-select: none;
}

/* The grabbing cursor only appears while the user is actively dragging. */
.map-widget.is-dragging .map-svg {
  cursor: grabbing;
}

/* Reserve space for the Confirm button always so dropping the first pin
   doesn't cause the widget (bottom-anchored) to jump upward. */
.confirm-guess {
  width: 100%;
  visibility: hidden;
  pointer-events: none;
}

/* Icon-only checkmark — hidden on desktop, swapped in for the text label
   inside the portrait media query (where the button becomes a FAB). */
.confirm-guess .confirm-icon {
  display: none;
  width: 28px;
  height: 28px;
}

.map-widget.has-pin .confirm-guess {
  visibility: visible;
  pointer-events: auto;
}

/* ─── Reveal overlay (above screenshot, screenshot stays at 0.3 opacity) ─ */

.reveal-overlay {
  position: absolute;
  inset: 0;
  z-index: var(--z-overlay);
  display: none;
  align-items: center;
  justify-content: center;
  padding: var(--space-6);
}

#app[data-view="reveal"] .reveal-overlay {
  display: flex;
}

.reveal-card {
  width: min(560px, 100%);
  max-height: 90vh;
  overflow-y: auto;
  padding: var(--space-6);
  background: var(--color-bg-card);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  text-align: center;
  backdrop-filter: blur(12px);
}

.reveal-round-label {
  margin: 0;
  font-size: var(--fs-xs);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-text);
}

.reveal-map {
  width: 100%;
  aspect-ratio: 1.255 / 1;
  background: var(--color-map-bg);
  border-radius: var(--radius-md);
  overflow: hidden;
  border: 1px solid var(--color-border);
}

.reveal-map .map-svg {
  cursor: default;
}

.reveal-distance {
  margin: 0;
  font-family: var(--font-display);
  font-weight: var(--fw-black);
  font-style: italic;
  font-size: var(--fs-xl);
  color: var(--color-text);
}

.reveal-distance .reveal-distance-value {
  color: var(--color-accent);
}

.reveal-score-bar {
  width: 100%;
  height: 12px;
  background: var(--color-bg-input);
  border-radius: var(--radius-pill);
  overflow: hidden;
}

.reveal-score-bar-fill {
  height: 100%;
  width: 0%;
  background: linear-gradient(90deg, var(--color-accent-dark), var(--color-accent));
  border-radius: var(--radius-pill);
  transition: width 0.8s cubic-bezier(0.22, 1, 0.36, 1);
}

.reveal-totals {
  display: flex;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-3) var(--space-4);
  background: var(--color-bg-panel);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  font-variant-numeric: tabular-nums;
}

.reveal-totals span:first-child {
  color: var(--color-text-muted);
  font-size: var(--fs-sm);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.reveal-totals span:last-child {
  color: var(--color-text);
  font-family: var(--font-display);
  font-weight: var(--fw-black);
  font-style: italic;
  font-size: var(--fs-lg);
}

/* ============================================================================
   Summary screen
   ============================================================================ */

.view-summary {
  width: 100%;
  height: 100%;
  background:
    radial-gradient(circle at 50% 30%, rgba(234, 0, 0, 0.10), transparent 60%),
    var(--color-bg);
  overflow-y: auto;
  position: relative;
}

.summary-bg-map {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: min(90vw, 1100px);
  aspect-ratio: 600 / 478;
  height: auto;
  opacity: 0.08;
  pointer-events: none;
  z-index: var(--z-bg);
}

.summary-bg-map .track-line {
  stroke: var(--color-text);
  stroke-width: 2;
  fill: none;
}

.summary-card {
  position: relative;
  z-index: var(--z-hud);
  max-width: 640px;
  margin: 0 auto;
  padding: var(--space-10) var(--space-6);
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  text-align: center;
}

.summary-logo {
  width: clamp(180px, 30%, 240px);
  height: auto;
  margin: 0 auto;
  display: block;
  filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.5));
}

.summary-total {
  margin: 0;
  font-family: var(--font-display);
  font-weight: var(--fw-black);
  font-style: italic;
  font-size: clamp(72px, 14vw, 120px);
  line-height: 1;
  color: var(--color-text);
  font-variant-numeric: tabular-nums;
}

.summary-total-of {
  display: block;
  font-size: var(--fs-md);
  font-weight: var(--fw-medium);
  font-style: italic;
  color: var(--color-text-muted);
  letter-spacing: 0.12em;
  margin-top: var(--space-2);
}

.summary-rank {
  margin: 0;
  padding: var(--space-3) var(--space-5);
  display: inline-flex;
  align-self: center;
  align-items: center;
  gap: var(--space-2);
  background: var(--color-bg-panel);
  border: 1px solid var(--color-border-mid);
  border-radius: var(--radius-pill);
  font-family: var(--font-display);
  font-weight: var(--fw-black);
  font-style: italic;
  font-size: var(--fs-md);
  letter-spacing: 0.16em;
  color: var(--color-text);
}

.summary-rounds {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.summary-round {
  display: grid;
  grid-template-columns: 56px 1fr auto;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-3) var(--space-4);
  background: var(--color-bg-card);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  text-align: left;
}

.summary-round-num {
  font-family: var(--font-display);
  font-weight: var(--fw-black);
  font-style: italic;
  font-size: var(--fs-lg);
  color: var(--color-text-muted);
  letter-spacing: 0.08em;
}

.summary-round-meta {
  font-size: var(--fs-sm);
  color: var(--color-text-muted);
  letter-spacing: 0.02em;
}

.summary-round-score {
  font-family: var(--font-display);
  font-weight: var(--fw-black);
  font-style: italic;
  font-size: var(--fs-lg);
  font-variant-numeric: tabular-nums;
}

.summary-round.score-high .summary-round-score {
  color: var(--color-success);
}

.summary-round.score-mid .summary-round-score {
  color: var(--color-warning);
}

.summary-round.score-low .summary-round-score {
  color: var(--color-danger);
}

.summary-round.score-zero .summary-round-score {
  color: var(--color-text-dim);
}

.summary-actions {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-3);
}

/* ============================================================================
   SVG primitives — pins, lines, underlay (shared by widget + reveal + splash)
   ============================================================================ */

.map-underlay {
  pointer-events: none;
  filter: brightness(0.7) saturate(0.85);
}

.track-line {
  fill: none;
  stroke: var(--color-map-track);
  stroke-width: 2;
  stroke-linejoin: round;
  stroke-linecap: round;
  opacity: 0.85;
  filter: drop-shadow(0 0 1px rgba(0, 0, 0, 0.85));
  pointer-events: none;
  /* When the map-content group is zoom/transformed, keep the stroke a
     consistent pixel width instead of fattening with the scale. */
  vector-effect: non-scaling-stroke;
}

.pin-dot {
  stroke: var(--color-bg);
  stroke-width: 1.5;
  filter: drop-shadow(0 0 2px rgba(0, 0, 0, 0.85));
  pointer-events: none;
}

.pin-guess .pin-dot {
  fill: var(--color-map-pin);
}

.pin-actual .pin-dot {
  fill: var(--color-map-actual);
}

.pin-label {
  font-family: var(--font-ui);
  font-weight: var(--fw-medium);
  font-size: var(--fs-xs);
  fill: var(--color-text);
  paint-order: stroke;
  stroke: var(--color-bg);
  stroke-width: 3;
  pointer-events: none;
}

.reveal-connector {
  stroke: var(--color-map-line);
  stroke-width: 1.5;
  stroke-dasharray: 5 4;
  pointer-events: none;
  vector-effect: non-scaling-stroke;
}

/* Corner-name labels. Hidden by default — fade in only when the map widget
   is expanded so the compact map stays clean. */
.corner-label {
  font-family: var(--font-ui);
  font-weight: var(--fw-medium);
  font-size: calc(var(--fs-xs) / var(--map-scale, 1));
  letter-spacing: 0.04em;
  fill: var(--color-text);
  paint-order: stroke;
  stroke: rgba(0, 0, 0, 0.85);
  stroke-width: calc(3px / var(--map-scale, 1));
  pointer-events: none;
  opacity: 0;
  /* Fade-out is instant when the panel collapses (rule below is overridden). */
  transition: opacity 0.25s ease;
}

/* Fade-in is delayed past the panel-expand transition (var(--transition-base)
   ≈ 0.25s) so the labels don't appear at the compact viewBox size and get
   scaled up 3× by the SVG during the expand. The re-projection on
   transitionend re-renders them at the correct size before they become
   visible. */
.map-widget.is-open .corner-label,
.map-widget.is-dragging .corner-label {
  opacity: 0.92;
  transition: opacity 0.25s ease 0.3s;
}

/* Reveal map: corner names stay hidden during the auto-zoom animation so the
   result lands clean. They fade in once the player interacts (scroll, drag,
   pinch) — a little reward for poking around plus a chance to learn the
   corner names. The .reveal-map selector has higher specificity than the
   portrait media query, so it wins on phones too. */
.reveal-map .corner-label {
  opacity: 0;
}

.reveal-map.show-corners .corner-label {
  opacity: 0.92;
}

/* ============================================================================
   Toast (clipboard confirmation)
   ============================================================================ */

.toast {
  position: fixed;
  bottom: var(--space-8);
  left: 50%;
  transform: translateX(-50%) translateY(20px);
  padding: var(--space-3) var(--space-5);
  background: var(--color-bg-card);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-pill);
  color: var(--color-text);
  font-size: var(--fs-sm);
  letter-spacing: 0.04em;
  z-index: var(--z-toast);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--transition-base), transform var(--transition-base);
}

.toast.is-visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

/* ============================================================================
   Map viewer dev tool (/map-viewer.html) — full-screen interactive map with
   a side panel for the corner-positioning workflow.
   ============================================================================ */

/* Flex layout (not grid) so the SVG can resolve height: 100% — a grid
   without an explicit row track collapses to 0 height. */
.map-viewer {
  flex: 1 1 auto;
  display: flex;
  min-height: 0;
}

.map-viewer-stage {
  flex: 1 1 auto;
  position: relative;
  background: var(--color-map-bg);
  border-right: 1px solid var(--color-border);
  overflow: hidden;
  min-width: 0;
}

.map-viewer-svg {
  width: 100%;
  height: 100%;
}

.map-viewer-panel {
  flex: 0 0 320px;
  padding: var(--space-5) var(--space-4);
  background: var(--color-bg);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  overflow-y: auto;
}

.map-viewer-panel-title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: var(--fw-black);
  font-style: italic;
  font-size: var(--fs-lg);
  letter-spacing: 0.08em;
  color: var(--color-text);
  text-transform: uppercase;
}

.map-viewer-panel-help {
  margin: 0;
  font-size: var(--fs-sm);
  line-height: 1.5;
  color: var(--color-text-muted);
}

.map-viewer-panel-help code {
  background: var(--color-bg-input);
  padding: 1px 5px;
  border-radius: var(--radius-xs);
  font-size: var(--fs-sm);
  color: var(--color-text);
}

.map-viewer-output {
  margin: 0;
  padding: var(--space-3);
  background: var(--color-bg-input);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  font-family: var(--font-ui);
  font-size: var(--fs-sm);
  line-height: 1.5;
  color: var(--color-text);
  white-space: pre-wrap;
}

/* In the viewer we want labels always visible (no .is-open gating). */
.corner-label-visible {
  opacity: 0.92;
}

/* Anchor dots show exactly where a corner snaps onto the centerline. */
.corner-anchor {
  fill: var(--color-accent);
  fill-opacity: 0.75;
  stroke: var(--color-bg);
  stroke-width: calc(1px / var(--map-scale, 1));
  r: calc(3px / var(--map-scale, 1));
  pointer-events: none;
}

/* Blocked-section overlay (map-viewer dev tool only). Stroke + font scale
   with the zoom transform via vector-effect / --map-scale so the overlay
   feels consistent with the corner-label tooling. */
.blocked-range-line {
  fill: none;
  stroke: #ff3333;
  stroke-width: 5;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.85;
  pointer-events: none;
  vector-effect: non-scaling-stroke;
}

.blocked-range-label {
  font-family: var(--font-ui);
  font-weight: var(--fw-black);
  font-size: calc(var(--fs-sm) / var(--map-scale, 1));
  letter-spacing: 0.04em;
  fill: #ff3333;
  paint-order: stroke;
  stroke: rgba(0, 0, 0, 0.85);
  stroke-width: calc(3px / var(--map-scale, 1));
  pointer-events: none;
}

/* ============================================================================
   Cookie consent banner — bottom-left, splash-only.
   ============================================================================ */

.cookies-notice {
  position: absolute;
  left: var(--space-5);
  bottom: var(--space-5);
  z-index: var(--z-toast);
  max-width: 360px;
  padding: var(--space-3) var(--space-4);
  background: var(--color-bg-card);
  border: 1px solid var(--color-border-mid);
  border-radius: var(--radius-md);
  display: flex;
  align-items: center;
  gap: var(--space-3);
  backdrop-filter: blur(10px);
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.45);
  animation: viewFadeIn var(--transition-base);
}

.cookies-notice[hidden] {
  display: none;
}

.cookies-notice-text {
  margin: 0;
  font-size: var(--fs-sm);
  line-height: 1.5;
  color: var(--color-text);
  flex: 1 1 auto;
}

.cookies-accept-btn {
  font-size: var(--fs-sm);
  padding: var(--space-2) var(--space-4);
  letter-spacing: 0.08em;
  flex: 0 0 auto;
}

/* ============================================================================
   Calibration page (unchanged from prior phase — kept for the calibrator tool)
   ============================================================================ */

.calibrate-body {
  overflow: hidden;
}

.calibrate-layout {
  display: grid;
  grid-template-columns: 1fr 360px;
  width: 100vw;
  height: 100vh;
  background: var(--color-bg);
  color: var(--color-text);
}

.calibrate-stage {
  position: relative;
  background: var(--color-bg-panel);
  border-right: 1px solid var(--color-border);
}

.calibrate-svg {
  width: 100%;
  height: 100%;
  display: block;
  cursor: grab;
  background:
    radial-gradient(circle at 50% 50%, var(--color-bg-input) 0, transparent 70%),
    var(--color-bg-panel);
  touch-action: none;
}

.calibrate-svg:active {
  cursor: grabbing;
}

.calibrate-status,
.calibrate-hint {
  position: absolute;
  margin: 0;
  padding: var(--space-2) var(--space-3);
  background: var(--color-bg-card);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  font-size: var(--fs-sm);
  color: var(--color-text-muted);
}

.calibrate-status {
  top: var(--space-3);
  left: var(--space-3);
}

.calibrate-hint {
  bottom: var(--space-3);
  left: var(--space-3);
  right: var(--space-3);
  font-size: var(--fs-xs);
  line-height: 1.6;
}

.calibrate-hint kbd {
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xs);
  padding: 1px 5px;
  font-size: var(--fs-xs);
  color: var(--color-text);
}

.calibrate-bbox {
  fill: none;
  stroke: var(--color-text-muted);
  stroke-width: 1;
  stroke-dasharray: 4 3;
  opacity: 0.6;
  pointer-events: none;
}

.calibrate-panel {
  padding: var(--space-6) var(--space-4);
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  background: var(--color-bg);
}

.calibrate-header h1 {
  margin: 0 0 var(--space-1);
  font-size: var(--fs-md);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-accent);
}

.calibrate-sub {
  margin: 0 0 var(--space-2);
  font-size: var(--fs-sm);
  color: var(--color-text-muted);
  line-height: 1.4;
}

.calibrate-control {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.calibrate-control label {
  font-size: var(--fs-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

.calibrate-row {
  display: grid;
  grid-template-columns: 1fr 72px;
  gap: var(--space-2);
  align-items: center;
}

.calibrate-row input[type="range"] {
  width: 100%;
  accent-color: var(--color-accent);
}

.calibrate-row input[type="number"] {
  width: 100%;
  padding: var(--space-1) var(--space-2);
  background: var(--color-bg-input);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xs);
  color: var(--color-text);
  font-size: var(--fs-sm);
  text-align: right;
}

.calibrate-readout {
  font-size: var(--fs-sm);
  color: var(--color-text);
  text-align: right;
  padding-right: var(--space-2);
}

.calibrate-toggle label {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  text-transform: none;
  letter-spacing: 0;
  font-size: var(--fs-sm);
  color: var(--color-text);
  cursor: pointer;
}

.calibrate-toggle input[type="checkbox"] {
  accent-color: var(--color-accent);
}

.calibrate-sep {
  border: none;
  border-top: 1px solid var(--color-border);
  margin: var(--space-2) 0;
}

.calibrate-actions {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-2);
}

.calibrate-snippet {
  margin: 0;
  padding: var(--space-2);
  background: var(--color-bg-input);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xs);
  font-size: var(--fs-xs);
  color: var(--color-text);
  white-space: pre;
  overflow-x: auto;
}

.calibrate-status-inline {
  position: static;
  background: transparent;
  border: none;
  padding: 0;
  font-size: var(--fs-xs);
  color: var(--color-success);
}

.calibrate-footer {
  margin-top: auto;
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-border);
  font-size: var(--fs-sm);
}

.calibrate-footer a {
  color: var(--color-text-muted);
  text-decoration: none;
}

.calibrate-footer a:hover {
  color: var(--color-accent);
}

/* ============================================================================
   Play card (splash) — tabs for Daily + Free Play, and leaderboard modal.
   ============================================================================ */

.play-card {
  background: var(--color-bg-card);
  border: 1px solid var(--color-border-mid);
  border-radius: var(--radius-lg);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

/* When the Daily tab is active, the card's border picks up the accent
   colour to telegraph the "today only" vibe. Free Play keeps the plain
   border below. */
.play-card[data-active-tab="daily"] {
  border-color: var(--color-accent-dim, var(--color-border-mid));
}

.play-tabs {
  display: grid;
  grid-template-columns: 1fr 1fr;
  background: var(--color-bg-input);
  border-bottom: 1px solid var(--color-border);
}

.play-tab {
  appearance: none;
  background: transparent;
  border: 0;
  padding: var(--space-4) var(--space-4);
  color: var(--color-text);
  font-family: var(--font-ui);
  font-weight: var(--fw-black);
  font-size: var(--fs-sm);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  cursor: pointer;
  position: relative;
  transition: color var(--transition-fast), background var(--transition-fast);
}

.play-tab:hover {
  color: var(--color-accent);
}

.play-tab[aria-selected="true"] {
  color: var(--color-accent);
  background: var(--color-bg-card);
}

/* Accent underline on the selected tab — flips colour by tab so Daily is
   "today only" red, Free Play is a neutral cool indicator. */
.play-tab[aria-selected="true"]::after {
  content: "";
  position: absolute;
  left: var(--space-3);
  right: var(--space-3);
  bottom: -1px;
  height: 2px;
  border-radius: 2px;
  background: var(--color-border-mid);
}

.play-tab[data-tab="daily"][aria-selected="true"]::after {
  background: var(--color-accent);
}

.play-panel {
  padding: var(--space-4) var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  position: relative;
  overflow: hidden;
}

.play-panel[hidden] {
  display: none;
}

/* Daily panel gets the red gradient wash that used to live on .daily-card. */
.play-panel-daily::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(135deg, rgba(234, 0, 0, 0.18) 0%, transparent 60%);
  pointer-events: none;
}

.play-panel-daily>* {
  position: relative;
  z-index: 1;
}

.daily-card-sub {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  color: var(--color-text);
  line-height: 1.4;
  text-align: center;
}

/* "You scored X / 25,000 today as Roamy." block — only shown when the
   daily panel is in 'done' state. Centred, sized up from the intro copy. */
.daily-done {
  display: flex;
  justify-content: center;
}

.daily-done[hidden] {
  display: none;
}

.daily-done-score {
  margin: 0;
  text-align: center;
  font-family: var(--font-display);
  font-weight: var(--fw-black);
  font-style: italic;
  font-size: var(--fs-md);
  letter-spacing: 0.02em;
  color: var(--color-text);
  line-height: 1.25;
}

/* Tab-specific game-stats list. Read-only display of what you're getting.
   Daily hides the Map row on purpose — that's a gameplay hint we don't
   surface up-front. Items centre-align so the row looks balanced
   regardless of how many stats are present. */
.play-stats {
  margin: 0;
  padding: var(--space-2) var(--space-3);
  list-style: none;
  background: var(--color-bg-input);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-3) var(--space-4);
}

.play-stats li {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
}

.play-stats-label {
  font-family: var(--font-ui);
  font-weight: var(--fw-medium);
  font-size: var(--fs-xs);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

.play-stats-value {
  font-family: var(--font-display);
  font-weight: var(--fw-black);
  font-style: italic;
  font-size: var(--fs-sm);
  letter-spacing: 0.04em;
  color: var(--color-text);
}

.daily-card-actions {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.daily-card-countdown {
  margin: 0;
  font-family: var(--font-ui);
  font-size: var(--fs-xs);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  text-align: center;
}

.daily-card-countdown[hidden] {
  display: none;
}

#daily-countdown-value {
  color: var(--color-accent);
  font-variant-numeric: tabular-nums;
  font-weight: var(--fw-black);
}

/* JS flips data-daily-state to swap intro copy ↔ score-with-copy line, and
   to disable the play button (its label becomes the countdown to next
   challenge). */
.play-panel-daily[data-daily-state="available"] .daily-done {
  display: none;
}

.play-panel-daily[data-daily-state="done"] .daily-card-sub {
  display: none;
}

.play-panel-daily[data-daily-state="available"] #daily-leaderboard-btn {
  background: transparent;
  border: 1px solid var(--color-border-mid);
}

/* Disabled-play-button-with-countdown — the "Next challenge in …" label.
   Background drops to a muted card colour and the label sits in the brand
   dark red so it still reads as part of the daily theme. */
#daily-play-btn[disabled] {
  cursor: default;
  background: var(--color-bg-card);
  border: 1px solid var(--color-border-mid);
  color: var(--color-accent-dark);
  opacity: 1;
}

#daily-play-btn[disabled] .btn-label {
  color: var(--color-accent-dark);
  font-variant-numeric: tabular-nums;
}

#daily-play-btn[disabled]:hover {
  /* Suppress the primary-button hover style on the disabled state. */
  filter: none;
  background: var(--color-bg-card);
}

/* Free Play panel — plain, no gradient. Inherits the existing control row
   styles by reusing .control-row + .control-pills selectors. */
.play-panel-free {
  background: var(--color-bg-card);
}

/* ── Leaderboard modal ─────────────────────────────────────────────── */

.leaderboard-overlay {
  position: fixed;
  inset: 0;
  z-index: var(--z-overlay);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-5);
  background: rgba(0, 0, 0, 0.7);
  backdrop-filter: blur(6px);
  animation: viewFadeIn var(--transition-base);
}

.leaderboard-overlay[hidden] {
  display: none;
}

.leaderboard-panel {
  width: min(520px, 100%);
  max-height: min(80vh, 720px);
  display: flex;
  flex-direction: column;
  background: var(--color-bg-card);
  border: 1px solid var(--color-border-mid);
  border-radius: var(--radius-lg);
  box-shadow: 0 18px 64px rgba(0, 0, 0, 0.6);
  overflow: hidden;
}

.leaderboard-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-5) var(--space-5) var(--space-3);
  border-bottom: 1px solid var(--color-border);
}

.leaderboard-eyebrow {
  margin: 0;
  font-family: var(--font-ui);
  font-weight: var(--fw-medium);
  font-size: var(--fs-xs);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--color-accent);
}

.leaderboard-title {
  margin: var(--space-1) 0 0;
  font-family: var(--font-display);
  font-weight: var(--fw-black);
  font-style: italic;
  font-size: var(--fs-xl);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-text);
}

.leaderboard-date {
  margin: var(--space-1) 0 0;
  font-family: var(--font-ui);
  font-size: var(--fs-xs);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

.leaderboard-close {
  appearance: none;
  background: transparent;
  border: 0;
  color: var(--color-text);
  font-size: var(--fs-xl);
  line-height: 1;
  cursor: pointer;
  padding: 0 var(--space-2);
}

.leaderboard-close:hover {
  color: var(--color-accent);
}

.leaderboard-submit {
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--color-border);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.leaderboard-submit[hidden],
.leaderboard-submit[data-submit-state="hidden"] {
  display: none;
}

.leaderboard-submit-score {
  margin: 0;
  font-family: var(--font-display);
  font-weight: var(--fw-black);
  font-style: italic;
  font-size: var(--fs-lg);
  color: var(--color-text);
}

.leaderboard-submit-form {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: var(--space-2) var(--space-3);
}

.leaderboard-submit-label {
  font-family: var(--font-ui);
  font-weight: var(--fw-medium);
  font-size: var(--fs-xs);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

.leaderboard-submit-input {
  appearance: none;
  background: var(--color-bg-input);
  border: 1px solid var(--color-border-mid);
  border-radius: var(--radius-md);
  color: var(--color-text);
  font-family: var(--font-ui);
  font-size: var(--fs-md);
  padding: var(--space-2) var(--space-3);
  letter-spacing: 0.04em;
  /* Belt-and-braces with the JS uppercaser — kills the one-frame flash
     of lowercase between keystroke landing and sanitiseName running. */
  text-transform: uppercase;
}

.leaderboard-submit-input:focus {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

.leaderboard-submit-btn {
  padding-inline: var(--space-4);
}

.leaderboard-submit-msg {
  margin: 0;
  font-family: var(--font-ui);
  font-size: var(--fs-sm);
  color: var(--color-text-muted);
}

.leaderboard-submit-msg.is-error {
  color: var(--color-danger, var(--color-accent));
}

.leaderboard-submit-msg.is-success {
  color: var(--color-success, var(--color-accent));
}

.leaderboard-submit[data-submit-state="done"] .leaderboard-submit-form,
.leaderboard-submit[data-submit-state="blocked"] .leaderboard-submit-form {
  display: none;
}

.leaderboard-body {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: var(--space-3) var(--space-5);
}

.leaderboard-status {
  margin: 0;
  padding: var(--space-4) 0;
  font-family: var(--font-ui);
  font-size: var(--fs-sm);
  color: var(--color-text-muted);
  text-align: center;
}

.leaderboard-status[hidden] {
  display: none;
}

.leaderboard-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.leaderboard-list[hidden] {
  display: none;
}

.leaderboard-row {
  display: grid;
  grid-template-columns: 2em 1fr auto;
  align-items: baseline;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  font-family: var(--font-ui);
  font-size: var(--fs-md);
}

.leaderboard-row:nth-child(odd) {
  background: var(--color-bg-input);
}

.leaderboard-row.is-self {
  background: rgba(234, 0, 0, 0.16);
  border: 1px solid var(--color-accent-dim, var(--color-accent));
}

.leaderboard-rank {
  font-family: var(--font-display);
  font-weight: var(--fw-black);
  font-style: italic;
  color: var(--color-text-muted);
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.leaderboard-row:nth-child(1) .leaderboard-rank,
.leaderboard-row:nth-child(2) .leaderboard-rank,
.leaderboard-row:nth-child(3) .leaderboard-rank {
  color: var(--color-accent);
}

.leaderboard-name {
  color: var(--color-text);
  font-weight: var(--fw-medium);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.leaderboard-score {
  font-family: var(--font-display);
  font-weight: var(--fw-black);
  font-style: italic;
  color: var(--color-text);
  font-variant-numeric: tabular-nums;
}

.leaderboard-footer {
  padding: var(--space-3) var(--space-5) var(--space-4);
  border-top: 1px solid var(--color-border);
}

.leaderboard-countdown {
  margin: 0;
  font-family: var(--font-ui);
  font-size: var(--fs-xs);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  text-align: center;
}

.leaderboard-countdown span {
  color: var(--color-accent);
  font-variant-numeric: tabular-nums;
  font-weight: var(--fw-black);
}

.leaderboard-more-btn {
  margin: var(--space-3) auto 0;
  display: block;
  padding-inline: var(--space-5);
}

.leaderboard-more-btn[hidden] {
  display: none;
}

/* Visually hide an element while keeping it readable by screen readers. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ============================================================================
   Phones — non-game pages.

   The desktop splash is a centred card sized to the viewport. On short
   phones that clips content (cookie banner, support callout drop off the
   bottom; the wordmark gets pushed under the menu button). This block
   converts the splash to a top-aligned scrollable view, pins the
   wordmark + menu + cookie banner to the viewport corners so they stay
   visible while the card scrolls, and reserves top padding so the
   content starts below the lockup.
   ============================================================================ */
@media (max-width: 640px) {
  .view-splash {
    align-items: flex-start;
    justify-content: flex-start;
    overflow-y: auto;
    overflow-x: hidden;
    padding: 76px var(--space-3) var(--space-5);
  }

  /* Background + overlay are anchored to the viewport instead of the
     scroll container, so the card scrolls past a static backdrop rather
     than dragging the photo with it. */
  .view-splash .splash-bg,
  .view-splash .splash-overlay {
    position: fixed;
  }

  /* Wordmark + menu form a virtual top bar — both fixed-positioned with
     matching height so they centre against each other. No max-width on
     the logo: with `width: auto` the browser computes width from the
     natural 6.6:1 aspect, ~265px at 40px tall — fits next to an
     icon-only menu button on every phone width down to 320px.
     Shared with the summary screen so the post-game header matches the
     splash and the in-game banner. */
  .splash-logo,
  .summary-logo {
    position: fixed;
    top: var(--space-3);
    left: var(--space-3);
    height: 32px;
    width: auto;
    max-width: none;
    margin: 0;
    z-index: var(--z-hud);
  }

  .view-splash .menu-btn,
  .view-summary .menu-btn {
    position: fixed;
    top: var(--space-3);
    right: var(--space-3);
    height: 40px;
    width: 40px;
    padding: 0;
    justify-content: center;
  }

  /* Drop the "Menu" label on phones — the icon is enough and it frees
     up width for the wordmark. The aria-label on the button keeps the
     accessible name intact. */
  .view-splash .menu-btn>span,
  .view-summary .menu-btn>span {
    display: none;
  }

  /* Push the summary content below the fixed top lockup (32px logo +
     12px top + breathing room). */
  .summary-card {
    padding-top: 68px;
  }

  .splash-card {
    gap: var(--space-4);
    padding-top: var(--space-4)
  }

  .splash-tagline {
    font-size: var(--fs-md);
  }

  /* Cookie banner — pin to bottom of the viewport so it doesn't sit at
     the bottom of a scroll container the user has to scroll to reach. */
  .cookies-notice {
    position: fixed;
    left: var(--space-3);
    right: var(--space-3);
    bottom: var(--space-3);
    max-width: none;
  }

}

/* ============================================================================
   Mobile (portrait): split view — world top half, map bottom half.

   Trigger: orientation: portrait — covers phones held upright and any narrow
   portrait window. Tablets in portrait also get this layout (intentional —
   the touch ergonomics are similar).
   ============================================================================ */

@media (orientation: portrait) {

  /* ── World half: image fills the top 50% by HEIGHT, letting the natural
     screenshot aspect ratio push the IMG element wider than the parent. The
     .view-play parent + body's `overflow: hidden` clips the overflow, and
     the in-game pointer handlers let the player drag the image horizontally
     to see the cropped sides without needing to zoom in. */
  .view-play .capture-image {
    top: 0;
    left: 0;
    height: 50%;
    width: auto;
    right: auto;
    bottom: auto;
    max-width: none;
    object-fit: cover;
  }

  /* ── Map half: replaces the corner widget. Bottom 50%, full width. ────── */
  .map-widget {
    top: 50%;
    left: 0;
    right: 0;
    bottom: 0;
    width: auto;
    height: auto;
    gap: 0;
  }

  /* No "Guess!" pill on portrait — the map IS the bottom half. */
  .map-hint {
    display: none;
  }

  .map-widget-panel {
    height: 100%;
    width: 100%;
    border-radius: 0;
    border: none;
  }

  /* Hover-expand is a desktop affordance — disable it on touch. */
  .map-widget.is-open,
  .map-widget.is-dragging {
    width: auto;
  }

  .map-widget.is-open .map-widget-panel,
  .map-widget.is-dragging .map-widget-panel {
    height: 100%;
  }

  /* Map is always full-size on mobile, so corner labels are always visible. */
  .corner-label {
    opacity: 0.92;
  }

  /* ── Banner: keep the layout, just tighten and slot the timer on the right. */
  .hud-banner {
    padding: var(--space-3) var(--space-4);
  }

  .banner-logo {
    height: 28px;
  }

  .banner-meta {
    gap: var(--space-4);
  }

  .banner-stat-value {
    font-size: var(--fs-md);
  }

  /* Timer centred at the top of the world half, just below the banner —
     not inside the header itself. 84px clears the banner (~52px tall) with
     enough gap that the readout doesn't crowd the banner; the text-shadow
     keeps it readable over any screenshot. */
  .hud-timer-block {
    top: 84px;
    left: 50%;
    right: auto;
    transform: translateX(-50%);
  }

  .timer {
    font-size: var(--fs-xl);
    /* shrink from 64px hero down to 32px so it doesn't dominate the half */
  }

  /* ── Confirm button → circular FAB inside the map half. The bottom/right
     offsets pad against the iOS safe-area-inset so the FAB clears the URL
     bar / home indicator instead of sitting behind them. Requires the
     viewport meta to include viewport-fit=cover for env() to resolve. */
  .confirm-guess {
    position: absolute;
    bottom: calc(var(--space-4) + env(safe-area-inset-bottom, 0px));
    right: calc(var(--space-4) + env(safe-area-inset-right, 0px));
    width: 56px;
    height: 56px;
    padding: 0;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: var(--z-overlay);
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.55);
  }

  .confirm-guess .confirm-label {
    display: none;
  }

  .confirm-guess .confirm-icon {
    display: block;
  }

  /* Belt-and-suspenders — make sure the post-pin visibility rule wins inside
     this media block too. Avoids any cascade surprises if a future tweak to
     the base rule changes the specificity contest. */
  .map-widget.has-pin .confirm-guess {
    visibility: visible;
    pointer-events: auto;
  }

  /* ── Reveal overlay: full-bleed modal on phones (the card was already
     scrollable but capped at 560px — let it use the full viewport). */
  .reveal-overlay {
    padding: var(--space-3);
  }

  .reveal-card {
    width: 100%;
    max-height: 100%;
    padding: var(--space-5);
  }

  /* ── Subpage banner padding: a little less generous on phones. ────────── */
  .page-banner {
    padding: var(--space-3) var(--space-4);
  }

  .subpage-card {
    padding: var(--space-10) var(--space-4) var(--space-10);
  }

  /* ── Hero font shrinks for phones ─────────────────────────────────────
     The clamp()-driven display sizes were tuned for desktop; on a 390px
     phone they bottom out at their min and feel oversized for the column
     width. Snap them down to fixed tokens here. */
  .summary-total {
    font-size: var(--fs-hero);
    /* was clamp(72px → 120px) → ~64px feels right */
  }

  .subpage-title {
    font-size: var(--fs-xl);
    /* was clamp(48 → 72), now 32px */
  }

  .reveal-distance {
    font-size: var(--fs-lg);
    /* was --fs-xl (32px), now 24px */
  }

  /* Score values in the This-round / Total boxes — one step down from
     desktop's --fs-lg so they don't dominate the reveal card. */
  .reveal-totals span:last-child {
    font-size: var(--fs-md);
  }

  .support-callout-text {
    font-size: var(--fs-md);
    /* was --fs-lg (24px), now 16px */
  }

  .summary-round-num,
  .summary-round-score {
    font-size: var(--fs-md);
    /* was --fs-lg (24px), now 16px in the per-round list */
  }
}