/* Design tokens — "the light table": a dim archive room where the one
   thing actually lit is the photograph on the table in front of you.
   Committing to dark rather than the earlier warm-paper look was a
   deliberate swing, not a coat of paint — real cyanotype prints (the
   accent's own namesake) are a vivid, saturated Prussian blue, not the
   muted navy the paper-toned version used; a dark ground is what lets
   that color, and the photo itself, actually read as *lit* rather than
   just "the two least-beige things on the page." Elevation on a dark
   ground mostly comes from surfaces getting lighter as they get closer
   (--surface, --surface-2, --surface-3), the way real dark UIs do it —
   a black shadow is invisible on a near-black page. The one thing that
   gets an actual glow is the photo frame itself: everything else stays
   quiet so that one glow reads as deliberate, not decorative. */
:root {
  --bg: #16130f;
  --surface: #211c16;
  --surface-2: #2c251d;
  --surface-3: #3a3226;
  --border: #423a2c;
  --border-strong: #5c5140;
  --text-primary: #f2ead9;
  --text-secondary: #c2b7a0;
  --text-muted: #8c8168;
  /* Darkened from the first pass specifically so white-ish button text
     sitting on top of it clears 4.5:1 (verified, not eyeballed — see
     CURATION_NOTES-style reasoning: brighter blues read as more "vivid"
     but paradoxically fail contrast against light text sooner, since
     they're closer in luminance to it). --accent-soft is the one used
     as *text* (links) against the dark background instead. */
  --accent: #2a5fd0;
  --accent-soft: #6b9bf2;
  --accent-2: #e8a23c;
  --focus-ring: #6b9bf2;

  --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.4);
  --shadow-md: 0 2px 4px rgba(0, 0, 0, 0.3), 0 10px 28px rgba(0, 0, 0, 0.4);
  --shadow-accent: 0 3px 14px rgba(42, 95, 208, 0.45);
  /* The photo frame's signature: a warm glow (the "lamp") plus a cool
     blue undertone (the cyanotype accent, everywhere else in the UI) —
     the one place the two accent colors meet at once. */
  --glow-photo: 0 0 1px rgba(232, 162, 60, 0.4), 0 12px 20px rgba(0, 0, 0, 0.5), 0 0 90px -10px rgba(232, 162, 60, 0.35), 0 0 140px -20px rgba(42, 95, 208, 0.3);
  --radius-sm: 7px;
  --radius-md: 10px;
  --radius-pill: 999px;
}

/* Reset & base */
*, *::before, *::after { box-sizing: border-box; }
/* Standard screen-reader-only pattern: kept in the accessibility tree
   (and as a real focus target) but removed from sighted view. Used for
   heading labels — "Round result", "Results" — whose content is
   already obvious on screen from the score itself, but that
   screen-reader users and keyboard focus still benefit from as an
   orienting cue when a new screen renders. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
/* Two guards against a white flash at the page edges on a dark theme —
   the browser's own default background is light, so anything that
   reveals it even briefly (a margin-collapse gap, or the elastic
   overscroll "rubber-band" bounce past the top/bottom on trackpad
   scroll) reads as a jarring visible bug against --bg. html's own
   background matches the page's in case anything still peeks through;
   overscroll-behavior stops the bounce from happening in the first
   place. */
html {
  background: var(--bg);
  overscroll-behavior: none;
  -webkit-text-size-adjust: 100%;
}
body {
  margin: 0;
  font-family: "Public Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  line-height: 1.5;
  color: var(--text-primary);
  background: var(--bg);
  overscroll-behavior: none;
  overflow-x: hidden;
}

header, main, footer {
  max-width: 720px;
  margin: 0 auto;
  padding: 1rem 1.25rem;
}

/* The round screen alone gets a wider container, so its two-column
   layout (#round-columns below) has room to sit side by side instead of
   stacking the photo, clues, map, and guess controls into one long
   scroll — that vertical pile-up was the actual complaint this fixes.
   Every other screen (intro, reveal, results) stays at the narrower
   720px reading width above; ID beats the type-selector group above it,
   so this wins without needing !important. */
#game-root.layout-round {
  max-width: 1100px;
}

/* The reveal screen gets a middling-width container too — enough for
   the photo and map to sit side by side (#reveal-columns below)
   without the photo shrinking back down to a thumbnail, but not as
   wide as the round screen, which also has to fit a search box and
   clue buttons. */
#game-root.layout-reveal {
  max-width: 900px;
}

/* Stacked by default (mobile and any narrow viewport — unchanged from
   before). At 860px+ there's room for the photo/clues and the guess
   map/search to sit side by side, so a full round fits without
   scrolling on anything laptop-sized or larger. */
#round-columns {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}
@media (min-width: 860px) {
  #round-columns {
    display: grid;
    grid-template-columns: 1fr 1fr;
    align-items: start;
    gap: 1.75rem;
  }
}

/* Same stack-then-grid pattern as #round-columns, just at a lower
   breakpoint — the reveal screen's two columns (photo+details, map)
   don't need to fit a search box, so they're comfortable side by side
   sooner. The photo column gets more than half the width: the photo
   itself, plus its title/context/attribution, is the actual point of
   the game, and the map only needs enough room for two pins. */
#reveal-columns {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}
@media (min-width: 700px) {
  #reveal-columns {
    display: grid;
    grid-template-columns: 1.15fr 0.85fr;
    align-items: start;
    gap: 1.75rem;
  }
}
/* Centered below both columns, not left-aligned under whichever column
   happens to be taller (the photo column usually is) — a shared,
   centered action reads as belonging to the whole layout instead of
   looking stuck to one side of it. Same treatment as #replay-btn. */
#next-btn {
  display: block;
  margin: 1.75rem auto 0;
}

/* Centered deliberately, not left by default: the round screen's own
   content spans a wider container than the header does (see
   #game-root.layout-round), so a left-aligned wordmark just sits at the
   edge of a column nothing else lines up with. Both containers share
   the same page center regardless of their own width, so centering here
   keeps the title visually anchored to the content below it either way. */
header {
  text-align: center;
  border-bottom: 1px solid var(--border-strong);
  padding-bottom: 0.75rem;
}
header h1 {
  font-family: "Fraunces", Georgia, serif;
  font-optical-sizing: auto;
  font-weight: 600;
  font-size: 2.3rem;
  letter-spacing: -0.015em;
  margin: 0.5rem 0;
  color: var(--text-primary);
}
/* On the legal pages the wordmark doubles as a link back to the game —
   it should still read as the title, not as a hyperlink. */
header h1 a {
  color: inherit;
  text-decoration: none;
}
header h1 a:hover {
  text-decoration: underline;
}

footer {
  color: var(--text-muted);
  font-size: 0.85rem;
  padding-bottom: 2rem;
}

h2 {
  font-family: "Fraunces", Georgia, serif;
  font-optical-sizing: auto;
  font-weight: 600;
  font-size: 1.55rem;
  color: var(--text-primary);
  outline: none; /* it's a programmatic focus target, not a visible focus ring on click */
}
h2:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

/* Buttons: minimum comfortable touch target, visible focus state, no
   reliance on color alone (also uses text/icons throughout). Filled, not
   outlined — a border-only button is exactly the "generic form control"
   look this page was reading as; a filled surface with a soft shadow
   reads as an actual pressable object instead. Primary actions
   (advancing the game) get the accent fill and a stronger shadow. */
button {
  font: inherit;
  font-weight: 500;
  min-height: 44px;
  padding: 0.5rem 1.1rem;
  border: none;
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  color: var(--text-primary);
  box-shadow: var(--shadow-sm);
  cursor: pointer;
  transition: background-color 0.12s ease, box-shadow 0.12s ease, transform 0.05s ease;
}
button:hover:not(:disabled) { background: var(--surface-3); }
button:active:not(:disabled) { transform: translateY(1px); box-shadow: none; }
button:disabled { opacity: 0.55; cursor: not-allowed; box-shadow: none; }
button:focus-visible {
  outline: 3px solid var(--focus-ring);
  outline-offset: 2px;
}

#start-btn, #submit-guess-btn, #next-btn, #replay-btn, #retry-btn {
  background: var(--accent);
  color: #f7f5ee;
  box-shadow: var(--shadow-accent);
}
#start-btn:hover:not(:disabled), #submit-guess-btn:hover:not(:disabled),
#next-btn:hover:not(:disabled), #replay-btn:hover:not(:disabled), #retry-btn:hover:not(:disabled) {
  background: var(--accent-soft);
}
#start-btn:disabled, #submit-guess-btn:disabled, #next-btn:disabled,
#replay-btn:disabled, #retry-btn:disabled {
  background: var(--surface-2);
  color: var(--text-muted);
  box-shadow: none;
  opacity: 1;
}

#clue-panel-label {
  font-size: 0.78rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted);
  margin: 0 0 0.35rem;
}
#clue-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0.5rem 0;
}
#clue-buttons button {
  font-size: 0.9rem;
  padding: 0.4rem 0.95rem;
  min-height: 38px;
  border-radius: var(--radius-pill);
  background: var(--surface);
}

/* Rounded-rectangle, not pill, and no shadow — these are settled facts
   once revealed, not pressable objects, so they're deliberately quieter
   than the pill-shaped clue buttons that produced them. */
#revealed-clues {
  list-style: none;
  margin: 0.5rem 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}
#revealed-clues li {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.3rem 0.7rem;
  background: var(--surface-2);
  border-radius: var(--radius-sm);
  font-size: 0.9rem;
}
#revealed-clues .clue-key {
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--text-muted);
}
#revealed-clues .clue-value {
  color: var(--text-primary);
  font-weight: 500;
}

/* Recessed, not outlined — an inset shadow instead of a border reads as
   a field you type INTO, distinct from the raised, shadowed buttons and
   cards around it. */
input[type="text"] {
  font: inherit;
  min-height: 44px;
  width: 100%;
  padding: 0.5rem 0.75rem;
  border: none;
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text-primary);
  box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.4);
}
input[type="text"]:focus-visible {
  outline: 3px solid var(--focus-ring);
  outline-offset: 1px;
}
input[type="text"]:disabled {
  background: var(--surface-2);
  color: var(--text-secondary); /* 4.9:1+ on --surface-2 — WCAG AA doesn't require disabled controls to meet contrast, but no reason not to */
  box-shadow: none;
}

#guess-map, #reveal-map {
  height: 260px;
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  overflow: hidden;
}
#guess-map { margin: 0.5rem 0; }
#reveal-map { margin: 0.5rem 0 1rem; }

#city-search-results {
  list-style: none;
  margin: 0.25rem 0;
  padding: 0;
  max-height: 220px;
  overflow-y: auto;
}
/* Only when populated — an empty list has nothing to frame as a card.
   overflow-y stays auto (a long result list must still scroll), so the
   rounded-card look comes from rounding the first/last button directly
   rather than clipping the whole list — clipping would also clip away
   the scrollbar/cut off scrolled content. */
#city-search-results:not(:empty) {
  box-shadow: var(--shadow-md);
}
#city-search-results li { margin: 0; }
#city-search-results li:first-child button { border-radius: var(--radius-sm) var(--radius-sm) 0 0; }
#city-search-results li:last-child button { border-radius: 0 0 var(--radius-sm) var(--radius-sm); }
#city-search-results li:only-child button { border-radius: var(--radius-sm); }
#city-search-results li:not(:last-child) button { border-bottom: 1px solid var(--border); }
#city-search-results button {
  width: 100%;
  text-align: left;
  border-radius: 0;
  background: var(--surface);
  box-shadow: none;
}

figure {
  margin: 1rem 0;
}

/* A fixed-height "mat" the photo sits inside, rather than rendering at
   its own natural width/height — that let a handful of ultra-wide
   panorama crops in the pool (one as extreme as 17:1) render as a
   paper-thin, near-unreadable strip. object-fit: contain keeps every
   image's real proportions inside a frame that's always the same size,
   so the page also no longer jumps in height once the image loads. */
#photo-frame {
  position: relative;
  height: 380px;
  margin: 1rem 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--surface-2);
  border-radius: var(--radius-md);
  box-shadow: var(--glow-photo);
  overflow: hidden;
}
#photo-frame img {
  display: block;
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
}
#image-loading-note {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0;
  font-size: 0.9rem;
  color: var(--text-muted);
}

/* The historical photo is the actual point of the game, so on the
   reveal screen it gets the same full-width, same-height-as-the-map,
   glowing "lit" treatment as #photo-frame during the round itself —
   not demoted to a small thumbnail underneath the map, which is what
   this used to be. */
#reveal-thumb {
  height: 260px;
  width: 100%;
  margin: 0.5rem 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--surface-2);
  border-radius: var(--radius-md);
  box-shadow: var(--glow-photo);
  overflow: hidden;
}
#reveal-thumb img {
  display: block;
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
}
/* Centered, matching the map column's centered legend below — with the
   photo column running noticeably taller than the map column, matching
   captions on both sides is what keeps the two feel like a deliberate
   pair instead of one side just trailing off past the other. */
#reveal-photo-col {
  text-align: center;
}
.reveal-photo-title {
  font-family: "Fraunces", Georgia, serif;
  font-weight: 600;
  font-size: 1.05rem;
  margin: 0.75rem 0 0.35rem;
}
.reveal-photo-context {
  color: var(--text-secondary);
  margin: 0 0 0.5rem;
}

.attribution {
  font-size: 0.85rem;
  color: var(--text-muted);
}

/* Base link color — the game screens mostly avoid freeform links, but
   the legal pages (privacy.html, terms.html) are full of them, and the
   browser default blue reads poorly on this dark background. */
a { color: var(--accent-soft); }

/* Legal pages (privacy.html, terms.html): plain long-form reading, not
   game UI — heading rhythm, paragraph spacing, and a muted list style,
   reusing the same tokens as everything else. */
.legal h2 {
  margin-top: 2rem;
}
.legal h2:first-of-type {
  margin-top: 1.5rem;
}
.legal p, .legal li {
  color: var(--text-secondary);
}
.legal ul {
  padding-left: 1.25rem;
}
.legal .updated {
  color: var(--text-muted);
  font-size: 0.85rem;
}

#reveal-map-legend {
  list-style: none;
  margin: 0 0 1rem;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.25rem 1rem;
  font-size: 0.9rem;
  color: var(--text-secondary);
}
.legend-swatch {
  display: inline-block;
  width: 0.75rem;
  height: 0.75rem;
  border-radius: 50%;
  border: 2px solid var(--surface);
  outline: 1px solid var(--border-strong);
  margin-right: 0.35rem;
  vertical-align: middle;
}
/* Matches ANSWER_MARKER_COLOR / GUESS_MARKER_COLOR in map-style.js — the
   map pins and this text legend are the same two colors everywhere. */
.legend-swatch--answer { background: #2fae5a; }
.legend-swatch--guess { background: #e8a23c; }

/* Reveal screen: the round score leads as a big, glowing headline
   figure rather than a plain sentence — same idea as the results
   screen's own hero figure below, just smaller since a per-round
   score isn't the session's main event. The "Round result" / "Time's
   up" heading above it (h2, .visually-hidden in the markup) stays in
   the accessibility tree as the screen's orienting cue for keyboard/
   screen-reader users, but isn't rendered — the score itself already
   makes the screen's purpose obvious to sighted players. */
/* Centered, matching the columns below (photo caption, map legend) —
   the whole reveal screen reads as one centered composition instead of
   a left-aligned block sitting on top of centered content. */
.score-hero, .score-breakdown, .reveal-verdict {
  text-align: center;
}
.score-hero {
  margin: 0 0 0.3rem;
}
.score-hero-label {
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--text-muted);
  margin-right: 0.5rem;
}
.score-hero-figure {
  font-size: 2.6rem;
  font-weight: 600;
  color: var(--accent-2);
  text-shadow: 0 0 40px rgba(232, 162, 60, 0.35);
}
.score-hero-max {
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 1.2rem;
  color: var(--text-muted);
}
.score-breakdown {
  color: var(--text-muted);
  font-size: 0.9rem;
  margin: 0 0 1.25rem;
}
.reveal-verdict {
  margin: 0 0 1.5rem;
}

/* Results screen: the total score is the session's one headline
   moment, so it gets its own glowing "victory card" — a radial fade
   from --surface-2 down to --bg plus the same warm/cool double glow as
   the photo frame — instead of sitting as a plain paragraph above the
   round list. */
.victory-card {
  position: relative;
  text-align: center;
  padding: 2.5rem 1.5rem 2.25rem;
  border-radius: var(--radius-md);
  background: radial-gradient(120% 140% at 50% 0%, var(--surface-2) 0%, var(--surface) 55%, var(--bg) 100%);
  box-shadow: 0 0 1px rgba(232, 162, 60, 0.4), 0 16px 30px rgba(0, 0, 0, 0.5), 0 0 100px -20px rgba(232, 162, 60, 0.3), 0 0 160px -30px rgba(42, 95, 208, 0.28);
  margin: 1rem 0 1.75rem;
}
/* Its "Results" / "Total score:" labels (h2 + span, both
   .visually-hidden in the markup) stay in the accessibility tree but
   aren't rendered — a huge glowing number inside its own card is
   already unambiguous without them. */
.victory-figure {
  margin: 0;
}
.victory-figure-number {
  font-size: 3.6rem;
  font-weight: 600;
  line-height: 1;
}
.victory-figure-max {
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  color: var(--text-muted);
  font-size: 1.3rem;
}
.victory-badge-wrap {
  margin: 1rem 0 0;
}
.badge {
  display: inline-block;
  background: rgba(232, 162, 60, 0.16);
  color: var(--accent-2);
  border-radius: var(--radius-pill);
  padding: 0.35rem 1rem;
  font-size: 0.88rem;
  font-weight: 600;
}
.victory-best {
  color: var(--text-secondary);
  font-size: 0.95rem;
}
.results-list-label {
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--text-muted);
  margin: 0 0 0.6rem;
}

/* Bounded height + visible border/background make this read as its own
   scrollable region (same affordance pattern as #city-search-results)
   instead of relying on the page's own scroll, which on a 10-round list
   wasn't an obvious enough cue that there was more below the fold. */
#results-breakdown {
  list-style: none;
  margin: 0.75rem 0;
  padding: 0.4rem 0.5rem;
  max-height: 40vh;
  overflow-y: auto;
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  background: var(--surface);
}
#results-breakdown li {
  padding: 0.15rem 0;
}
#results-breakdown li:not(:last-child) {
  border-bottom: 1px solid var(--border);
}
#replay-btn {
  display: block;
  margin: 1.5rem auto 0;
}

/* Each round's own fraction of MAX_ROUND_SCORE, as a bar filled behind
   the row rather than a separate chart — reads at a glance next to the
   9 other numbers already in the layout, without another axis/legend to
   parse for something this simple. The flex layout lives on this inner
   div, not the <li> itself — overriding an <li>'s display strips its
   numbered-list-item semantics (both the visible marker and often the
   ARIA list-item role), which a wrapper avoids needing to work around. */
.score-row {
  position: relative;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.3rem 0.6rem;
  overflow: hidden;
}
/* A soft trailing fade instead of a hard rectangular cutoff — the same
   proportional read, without looking like a raw <progress> bar. */
.score-row-fill {
  position: absolute;
  inset: 0;
  width: var(--score-pct, 0%);
  background: linear-gradient(to right, color-mix(in srgb, var(--accent) 40%, transparent), color-mix(in srgb, var(--accent) 40%, transparent) 80%, transparent);
  z-index: 0;
}
.score-row-rank, .score-row-label, .score-row-value {
  position: relative;
  z-index: 1;
}
.score-row-rank {
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 0.82rem;
  color: var(--text-muted);
  margin-right: 0.4rem;
}
.score-row-label {
  color: var(--text-primary);
}
.score-row-value {
  flex: none;
  color: var(--text-secondary);
}

/* Any raw point figure — the timer excluded, which has its own ring —
   reads as data, not prose: monospace, tabular digits so scores don't
   jitter in width as they tally up. */
.score-figure {
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-variant-numeric: tabular-nums;
}

/* The round timer reads as data, not prose — tabular digits so it
   doesn't jitter in width as it counts down. */
/* Round counter and timer share one row now, instead of the counter
   owning a full heading-sized line of its own above a second row for
   the timer — "Round 2 of 5" is orientation, not the main event, so it
   reads at a label-like size next to the ring rather than competing
   with it. */
#round-status-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin: 0.75rem 0;
}
#round-heading {
  font-family: "Public Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  font-size: 1.05rem;
  font-weight: 600;
  margin: 0;
}
#round-timer-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
#round-timer-label {
  font-size: 0.85rem;
  color: var(--text-secondary);
}
#round-timer {
  position: relative;
  width: 44px;
  height: 44px;
  flex: none;
}
#round-timer svg {
  width: 100%;
  height: 100%;
  transform: rotate(-90deg); /* start the countdown at 12 o'clock */
}
.timer-track {
  fill: none;
  stroke: var(--border);
  stroke-width: 4;
}
#timer-ring {
  fill: none;
  stroke: var(--accent);
  stroke-width: 4;
  stroke-linecap: round;
  stroke-dasharray: 119.38; /* 2*pi*19 — the circle's own circumference */
  stroke-dashoffset: 0;
  transition: stroke-dashoffset 0.25s linear, stroke 0.3s ease;
}
#timer-ring.timer-ring--urgent {
  stroke: #e5484d;
}
#timer-remaining {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 0.8rem;
  font-variant-numeric: tabular-nums;
  color: var(--text-primary);
}

/* Visually hidden but still available to assistive tech — used for the
   timer's threshold announcements, which are separate from the visible
   (aria-hidden) ticking countdown. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

@media (max-width: 480px) {
  header h1 { font-size: 1.4rem; }
  h2 { font-size: 1.15rem; }
  /* Shorter frames on a small screen: the fixed heights are sized for
     desktop, and on a short device (an SE-class phone is ~570px tall)
     380px of photo plus 260px of map is most of the viewport before a
     player ever reaches the controls. */
  #photo-frame { height: 260px; }
  #guess-map, #reveal-map { height: 200px; }
}
