/* Mappr Suburb Guesser
   Mobile-first. Tested at 375px and 768px.

   ── The Mappr style ────────────────────────────────────────────────
   The tokens, the type, the gold accent and the card elevation all come
   from src/mappr.css in the Mappr product. Where the two disagree, that
   file wins: this is the same brand, not a cousin of it.

   Two things are ours rather than Mappr's, and both are rules, not taste:

     · The figures are never colour-coded. A higher number is not a better
       number, and colour would say it was. Green marks the answer; red
       only ever lands on a card the player picked themselves.
     · Nothing loads from another origin. Mappr pulls Figtree and Inter
       from Google Fonts; here they are served from site/fonts/ so the
       content security policy can keep saying "nothing, from anywhere".
   ─────────────────────────────────────────────────────────────────── */

/* ── Type ────────────────────────────────────────────────────────────
   Figtree for display, Inter for body — the same two faces Mappr uses,
   at the same weights. Both are variable fonts, so each family is one
   file that every weight below is cut from.

   Licences: SIL Open Font License 1.1, both of them. The full text ships
   beside the fonts in site/fonts/, which is what that licence asks for. */

@font-face {
  font-family: "Figtree";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("fonts/figtree-latin.woff2") format("woff2");
}

@font-face {
  font-family: "Figtree";
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url("fonts/figtree-latin.woff2") format("woff2");
}

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/inter-latin.woff2") format("woff2");
}

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("fonts/inter-latin.woff2") format("woff2");
}

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("fonts/inter-latin.woff2") format("woff2");
}

:root {
  /* Mappr's palette, unchanged. */
  --bg-top: #3a4150;
  --bg-bottom: #14161c;
  --card: #ffffff;
  --card-soft: #f6f7f9;
  --ink: #1c2028;
  --body: #3d4350;
  --muted: #707786;
  --line: #e5e7eb;
  --pop: #0f6f52;
  --yes: #0e8a5f;
  --yes-bg: #e7f6ef;
  --no: #c0362c;
  --no-bg: #fcecea;
  --gold: #e8b64a;
  --gold-dark: #c8942a;
  --radius: 14px;

  /* Mappr's type stacks. The system fallbacks are what renders in the
     fraction of a second before the woff2 arrives, and for anyone whose
     browser refuses it. */
  --display: "Figtree", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --text: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

  /* Text and links on the dark ground, from Mappr's header and its
     sources panel. */
  --on-dark: #d6dae3;
  --on-dark-soft: #b6bcc9;
  --on-dark-faint: #8b91a0;
  --link-dark: #9fd0ff;
  --link-card: #2456c8;

  /* Right and wrong on the dark ground. Mappr uses these exact values for
     yes and no when its own surfaces go dark; --yes at #0e8a5f reads as
     near-black against #2b3040. */
  --yes-on-dark: #4fd0a0;
  --no-on-dark: #ff7a6e;

  /* The maps. Named so the dark scheme can repaint them without every
     fill being hunted down one at a time. */
  --map-land: #ffffff;
  --map-edge: #d7dbe2;
  --frame-fill: #e9ebef;
  --frame-edge: #c2c7d1;

  --shadow-card: 0 8px 30px rgba(0, 0, 0, 0.3);
  --shadow-hero: 0 12px 40px rgba(0, 0, 0, 0.35);

  --gap: 16px;
  --map-h: 108px;
  /* The foot of a suburb card: the pick button, then the figure in its place.
     Tall enough for the tallest revealed figure -- public toilets, which adds
     a second line under it -- so no card grows, and the card below it does
     not jump, when the round is answered. */
  --foot-h: 64px;
  /* A clue costs a point, so it is marked in the colour Mappr points with.
     The same wash as Mappr's estimate chip. */
  --gold-wash: rgba(232, 182, 74, 0.12);
}

* { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  min-height: 100vh;
  font-family: var(--text);
  font-size: 17px;
  line-height: 1.6;
  color: var(--body);
  background: linear-gradient(175deg, var(--bg-top) 0%, var(--bg-bottom) 60%) fixed;
  background-color: var(--bg-bottom);
  -webkit-font-smoothing: antialiased;
}

h1, h2 {
  font-family: var(--display);
  font-weight: 700;
  color: var(--ink);
  line-height: 1.25;
  letter-spacing: -0.02em;
  margin: 0 0 8px;
}

p { margin: 0 0 12px; }
a { color: var(--link-card); }

#app, .footer-inner {
  max-width: 640px;
  margin: 0 auto;
  padding-inline: var(--gap);
}

#app { padding-block: 24px 32px; }

/* ── Shared pieces ──────────────────────────────────────────────── */

.card {
  background: var(--card);
  border-radius: var(--radius);
  padding: 22px 24px;
  margin-bottom: var(--gap);
  box-shadow: var(--shadow-card);
}

/* Mappr's buttons: the primary one is ink, not green. Green is reserved
   here for the thing green means -- the answer. */
.button {
  display: inline-block;
  width: 100%;
  padding: 14px 18px;
  border: 1.5px solid var(--line);
  border-radius: 10px;
  background: var(--card);
  color: var(--ink);
  font-family: var(--display);
  font-size: 16px;
  font-weight: 700;
  line-height: 1.3;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}

.button:hover { background: var(--card-soft); }

.button.primary {
  background: var(--ink);
  border-color: var(--ink);
  color: #fff;
}

.button.primary:hover { background: #000; }

/* Gold, everywhere, on everything focusable. It is the one accent Mappr
   uses to say "you are here". */
.button:focus-visible,
.clue:focus-visible,
.skip:focus-visible,
.link:focus-visible {
  outline: 3px solid rgba(232, 182, 74, 0.5);
  outline-offset: 2px;
}

.link {
  border: 0;
  background: none;
  padding: 8px 4px;
  font: inherit;
  color: var(--on-dark);
  text-decoration: underline;
  cursor: pointer;
}

.link:hover { color: var(--gold); }

.error {
  background: var(--card);
  border-radius: var(--radius);
  padding: 20px;
  color: var(--ink);
  box-shadow: var(--shadow-card);
}

/* ── The brand lockup ────────────────────────────────────────────────
   Mappr's own header: the wordmark with a gold full stop, and the region
   it covers as a pill beside it. The game's name is the heading under it,
   the way the tagline is on the product. */

.brand {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 10px;
}

.logo {
  font-family: var(--display);
  font-weight: 800;
  font-size: 30px;
  letter-spacing: -0.02em;
  line-height: 1;
  color: #fff;
}

.logo .dot { color: var(--gold); }

.region {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: #c9cedb;
  border: 1px solid rgba(255, 255, 255, 0.25);
  border-radius: 99px;
  padding: 3px 12px;
}

/* ── Start screen ───────────────────────────────────────────────── */

.title {
  font-family: var(--display);
  font-weight: 800;
  color: #fff;
  font-size: 32px;
  letter-spacing: -0.02em;
  margin-bottom: 4px;
}

.tagline { color: var(--on-dark-soft); font-size: 16px; margin-bottom: 26px; max-width: 46ch; }

.mode h2 { font-size: 19px; }
.mode p { color: var(--body); font-size: 15px; }

.stats {
  color: var(--on-dark-soft);
  font-size: 15px;
  text-align: center;
  margin: 4px 0 20px;
}

/* Mappr's translucent panel, the one its sources and trust notes sit in. */
.how {
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: var(--radius);
  padding: 20px 24px;
  color: var(--on-dark);
  font-size: 14px;
}

.how h2 { color: #fff; font-size: 15px; letter-spacing: 0; }
.how p { margin: 10px 0 0; line-height: 1.6; }

/* ── A round ────────────────────────────────────────────────────── */

.round-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  color: var(--on-dark);
  font-size: 14px;
  margin-bottom: 20px;
}

.round-head .back { margin-inline-end: auto; padding-inline-start: 0; }

/* On the result screen the row is all that is left in the head. Push it to
   the same edge it sat on during the set, so it does not appear to move when
   the last round turns over. */
.round-head.is-done { min-height: 37px; }
.round-head.is-done .pips { margin-inline-start: auto; }

/* One block per round: green won, red lost, outlined white for the round
   being played. The score and the position in the set, without a word. */
.pips { display: flex; gap: 4px; }

/* 18px on a phone leaves room for the points beside ten blocks at 375px. */
.pip {
  width: 18px;
  aspect-ratio: 16 / 9;
  border: 1px solid rgba(255, 255, 255, 0.28);
  border-radius: 3px;
}

.pip.is-right { background: var(--yes-on-dark); border-color: var(--yes-on-dark); }
.pip.is-wrong { background: var(--no-on-dark); border-color: var(--no-on-dark); }
.pip.is-now { border-width: 2px; border-color: #fff; }

/* Endless mode's head: the run so far, and the best to beat, where a set
   shows its row of blocks. Same height as the blocks, so the cards below sit
   at the same place in both modes. */
.streak-count {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin-inline-start: auto;
}
.streak-now { color: #fff; font-family: var(--display, inherit); font-weight: 800; font-size: 17px; }
.streak-best { color: var(--on-dark-soft); font-size: 13px; }

/* Points so far, after the blocks. */
.points-tally {
  color: #fff;
  font-family: var(--display);
  font-weight: 800;
  font-size: 16px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* What the round is worth, beside the question. It counts down as clues are
   opened, then turns into what the round earned. */
.worth {
  flex: none;
  display: grid;
  justify-items: center;
  min-width: 56px;
  padding: 5px 8px 4px;
  border: 1px solid rgba(232, 182, 74, 0.4);
  border-radius: 12px;
  background: var(--gold-wash);
}

.worth-points {
  font-family: var(--display);
  font-weight: 800;
  font-size: 22px;
  line-height: 1.1;
  color: var(--gold);
  font-variant-numeric: tabular-nums;
}

/* Mappr's small capitals: Figtree, 12px, 0.04em. */
.worth-unit {
  font-family: var(--display);
  font-size: 12px;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--on-dark-soft);
}

/* Answered: Mappr's translucent panel, the same as the how-it-works box. */
.worth.is-done { border-color: rgba(255, 255, 255, 0.14); background: rgba(255, 255, 255, 0.06); }
.worth.is-done .worth-points { color: #fff; }
.worth.is-bump .worth-points { animation: worth-bump 0.35s ease; }

@keyframes worth-bump {
  40% { transform: scale(1.25); color: #fff; }
}

.clues-hint {
  color: var(--on-dark-faint);
  font-size: 14px;
  margin: -10px 0 16px;
}

.clues-hint.is-spent { visibility: hidden; }

.mode .best { color: var(--ink); font-weight: 600; margin-top: -4px; }

/* The question, and the chevron that moves the round on, on one line. */
.ask {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 20px;
}

.question {
  flex: 1 1 auto;
  min-width: 0;
  font-family: var(--display);
  font-weight: 800;
  color: #fff;
  font-size: 23px;
  letter-spacing: -0.02em;
  line-height: 1.2;
  margin: 0;
  text-wrap: balance;
}

/* Held open whether or not the chevron is in it, so the cards do not move
   down the page when the round is answered. */
.skip-slot {
  flex: none;
  width: 44px;
  height: 44px;
}

/* ── The skip chevron ───────────────────────────────────────────────
   An answered round moves on by itself after five seconds. This skips
   the wait, and the ring around it is that wait, drawn: a circle that
   drains away as the time does, so nobody is moved on by a clock they
   could not see.

   Its duration is set inline from ADVANCE_MS in app.js, which is why the
   animation is written out longhand here rather than in the shorthand. */

.skip {
  position: relative;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  color: var(--on-dark);
  cursor: pointer;
  transition: color 0.15s;
}

.skip:hover { color: var(--gold); }

.skip-ring {
  position: absolute;
  inset: 2px;
  width: 40px;
  height: 40px;
  transform: rotate(-90deg); /* start the drain at twelve o'clock */
}

/* 2 * pi * 18 = 113.1, the circumference the dash pattern runs through. */
.skip-ring .ring {
  fill: none;
  stroke: var(--yes-on-dark);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-dasharray: 113.1;
  animation-name: ring-drain;
  animation-timing-function: linear;
  animation-fill-mode: forwards;
  animation-duration: 5s;
}

.skip-mark { position: relative; }

@keyframes ring-drain {
  from { stroke-dashoffset: 0; }
  to { stroke-dashoffset: 113.1; }
}

/* Shown once, on the first answered round of a set, and never explained.
   It is the only piece of onboarding the game has, and it glows in the
   colour Mappr uses to point at things. */
@keyframes skip-glow {
  0%, 100% { box-shadow: 0 0 0 0 rgba(232, 182, 74, 0); }
  50% { box-shadow: 0 0 16px 3px rgba(232, 182, 74, 0.55); }
}

.skip.is-new { animation: skip-glow 2.4s ease-in-out infinite; }

/* The two suburbs are stacked, never side by side, at every width. Each
   card carries a map, and a map needs width more than the pair needs to
   be compared at a glance. */
.suburbs {
  display: grid;
  grid-template-columns: 1fr;
  gap: 12px;
  margin-bottom: var(--gap);
}

.suburb {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 2px;
  width: 100%;
  /* Without this the card takes its width from the map's natural size and
     runs off the side of a phone. */
  min-width: 0;
  padding: 18px;
  border: 2px solid transparent;
  border-radius: var(--radius);
  background-color: var(--card);
  box-shadow: var(--shadow-card);
  text-align: left;
}

/* The pick button, then the figure in its place, at the same height either
   way, so the page does not shuffle underneath the player's finger. */
.suburb-foot {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: var(--foot-h);
  margin-top: auto;
  padding-top: 12px;
}

.button.pick { width: 100%; }

/* ── Clues ──────────────────────────────────────────────────────────
   A shut clue is a dashed button with its price on it. An opened one is a
   label and a figure, never coloured, like every figure in the game. One
   that was never opened stays shut after the answer, greyed. */
.clues {
  display: grid;
  gap: 6px;
  margin: 12px 0 0;
  padding: 0;
  list-style: none;
}

.clue {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 40px;
  padding: 6px 12px;
  border: 1px solid var(--line);
  border-radius: 9px;
  font: inherit;
  font-size: 14px;
  line-height: 1.35;
  text-align: left;
  color: var(--body);
}

button.clue {
  border-style: dashed;
  border-color: var(--frame-edge);
  background: var(--card-soft);
  cursor: pointer;
}

button.clue:hover:not(:disabled) { border-color: var(--gold-dark); background: var(--gold-wash); }
/* Out of clues for the round. Muted ink on the card, not opacity: opacity
   on top of muted text drops it well under 4.5:1. */
button.clue:disabled { color: var(--muted); background: var(--card); cursor: not-allowed; }
button.clue:disabled .clue-cost { border-color: var(--line); background: transparent; color: var(--muted); }

.clue-name { min-width: 0; font-weight: 500; }

/* Shaped like the region pill. Ink, not gold, for the words: gold-dark on a
   white card is too faint to read at this size, and ink turns light with
   the card in the dark scheme. */
.clue-cost {
  padding: 2px 8px;
  border: 1px solid rgba(232, 182, 74, 0.4);
  border-radius: 99px;
  background: var(--gold-wash);
  color: var(--ink);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  white-space: nowrap;
}

.clue.is-open { background: var(--card); }
.clue.is-open .clue-name { color: var(--muted); font-weight: 400; }

.clue-value {
  font-family: var(--display);
  font-weight: 700;
  color: var(--ink);
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.clue.is-new { animation: clue-open 0.4s ease; }
.clue.is-new:focus { outline: none; }

@keyframes clue-open {
  from { transform: rotateX(70deg); opacity: 0.2; }
}

/* Shut after the answer: no figure, but the label stays readable. It keeps
   the card's own ground, so the green or red wash stops at its edge, as it
   does at the map's. Body ink, not muted: muted on white is 4.49:1, a hair
   under the 4.5:1 small text needs. The dashed edge and the missing figure
   are what say it was never opened. */
.clue.is-shut {
  border-style: dashed;
  border-color: var(--frame-edge);
  background: var(--card);
  color: var(--body);
}

.clue.is-shut .clue-name { font-weight: 400; }

.suburb-name {
  font-family: var(--display);
  font-weight: 800;
  letter-spacing: -0.015em;
  color: var(--ink);
  font-size: 20px;
  line-height: 1.25;
}

.suburb-council { color: var(--muted); font-size: 14px; line-height: 1.4; }

/* Deliberately the same colour whichever suburb is higher. It sits in the
   card's foot, which pins it to the bottom of the card. */
.suburb-value {
  font-family: var(--display);
  font-weight: 700;
  color: var(--ink);
  font-size: 19px;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
}

.suburb-detail { color: var(--muted); font-size: 14px; }

/* ── Marking a card ─────────────────────────────────────────────────
   Only the card the player picked is marked, right or wrong. The card
   they did not pick is left alone, whether or not it held the answer:
   both figures are on screen, so the answer can be read either way, and
   nothing on the page ever colours a suburb nobody chose.

   The wash is Mappr's --yes-bg and --no-bg, the same two tints its report
   uses behind a pass and a fail.

   The border thickens from 2px to 4px and the padding drops by the same
   2px, so a card marks itself without moving anything on the page. */

.suburb.is-right,
.suburb.is-wrong {
  border-width: 4px;
  padding: 16px;
}

.suburb.is-right {
  border-color: var(--yes);
  background-color: var(--yes-bg);
}

.suburb.is-wrong {
  border-color: var(--no);
  background-color: var(--no-bg);
}

.suburb-mark {
  position: absolute;
  top: 10px;
  right: 14px;
  font-size: 27px;
  font-weight: 700;
  line-height: 1;
}

.suburb.is-right .suburb-mark { color: var(--yes); }
.suburb.is-wrong .suburb-mark { color: var(--no); }

/* Muted ink on the light wash is about 4.1:1, under the 4.5:1 small text
   needs, so the council line steps up to body ink on a marked card. */
.suburb.is-right .suburb-council,
.suburb.is-wrong .suburb-council { color: var(--body); }

/* Keep a long name off the mark. */
.suburb.is-right .suburb-name,
.suburb.is-wrong .suburb-name { padding-inline-end: 38px; }

/* ── The map on a card ──────────────────────────────────────────────
   The suburb among its neighbours, and a pin on Greater Melbourne or on
   the state. Inline SVG, no tiles, nothing fetched.

   The panel is painted an opaque card colour so that the green or red wash
   on a marked card stops at its edge. A map that turned pink when you got
   the question wrong would be reading as a judgement on the place. */

.suburb-map {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
  margin-top: 12px;
  border-radius: 10px;
  background: var(--card);
}

.suburb-map svg { display: block; }

/* flex-basis 0, not auto: an svg with a viewBox has a natural width of its
   own, and from `auto` it would push the card wider than the screen instead
   of taking what is left over. */
.suburb-map .context {
  flex: 1 1 0%;
  min-width: 0;
  height: var(--map-h);
  border-radius: 10px;
  background: var(--card-soft);
}

.suburb-map .neighbour {
  fill: var(--map-land);
  stroke: var(--map-edge);
  stroke-width: 1;
  stroke-linejoin: round;
}

.suburb-map .shape {
  fill: var(--pop);
  fill-opacity: 0.18;
  stroke: var(--pop);
  stroke-width: 1.8;
  stroke-linejoin: round;
}

.locator-side {
  flex: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  width: 88px;
}

/* The svg carries width and height attributes so it still draws correctly
   with no stylesheet; these override them once there is one. */
.suburb-map .locator { width: 76px; height: 76px; }

/* evenodd is what makes Port Phillip Bay a hole rather than filled land. */
.suburb-map .state {
  fill: var(--frame-fill);
  stroke: var(--frame-edge);
  stroke-width: 1;
  fill-rule: evenodd;
}

.suburb-map .pin { fill: var(--pop); }
.suburb-map .pin-ring { fill: none; stroke: var(--pop); stroke-width: 1.5; opacity: 0.45; }

.locmap-where {
  color: var(--muted);
  font-size: 11px;
  line-height: 1.3;
  text-align: center;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ── Result ──────────────────────────────────────────────────────────
   One card: how it went, the score, and the line to share. The tier is
   a verdict on the player's ten guesses and on nothing else — the game
   grades a playthrough, never a place.

   The score is set the way Mappr sets its big numbers: Figtree 800, tight
   tracking, --pop green. */

.scorecard {
  background: var(--card);
  border-radius: var(--radius);
  padding: 26px 20px 22px;
  margin-bottom: var(--gap);
  box-shadow: var(--shadow-hero);
  text-align: center;
}

.tier {
  font-family: var(--display);
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -0.015em;
  margin: 0 0 2px;
}

.tier-high { color: var(--pop); }
.tier-mid { color: var(--ink); }
/* Muted, not red. A low score is not a failure worth colouring. */
.tier-low { color: var(--muted); }

.scorecard .score {
  font-family: var(--display);
  font-weight: 800;
  color: var(--pop);
  font-size: 46px;
  letter-spacing: -0.02em;
  line-height: 1.05;
  font-variant-numeric: tabular-nums;
  margin: 0 0 4px;
}

/* The second score: points, under right answers (or the run). */
.scorecard .points-score {
  font-family: var(--display);
  font-weight: 700;
  color: var(--ink);
  font-size: 20px;
  font-variant-numeric: tabular-nums;
  margin: 0 0 8px;
}

.scorecard .result-sub { color: var(--muted); font-size: 15px; margin: 0; }

.share {
  margin-top: 22px;
  padding-top: 20px;
  border-top: 1px solid var(--line);
}

.share-label {
  font-family: var(--display);
  color: var(--muted);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  margin: 0 0 10px;
}

.share-text {
  margin: 0 0 12px;
  padding: 14px 16px;
  border-radius: 10px;
  background: var(--card-soft);
  color: var(--body);
  font: inherit;
  font-size: 15px;
  text-align: start;
  white-space: pre-wrap;
  word-break: break-word;
  user-select: all;
}

.share-feedback { color: var(--muted); font-size: 14px; min-height: 21px; margin: 8px 0 0; }

/* ── What to do next ────────────────────────────────────────────────
   Both products, on every tier. */

.products {
  display: grid;
  grid-template-columns: 1fr;
  gap: 12px;
  margin-bottom: var(--gap);
}

.product {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin-bottom: 0;
}

/* Grows so the two buttons line up whatever length the sentences are. */
.product p { flex: 1 1 auto; color: var(--body); font-size: 15px; margin: 0; }
.product .button { width: 100%; min-width: 0; }
.product .button:disabled { opacity: 0.5; cursor: not-allowed; }
.product .button:disabled:hover { background: var(--card); }

.again { display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; }

/* ── Footer ──────────────────────────────────────────────────────────
   Mappr's sources panel: translucent white on the gradient, hairline
   border, the same radius as a card. */

#footer {
  padding-block: 8px 44px;
  color: var(--on-dark);
  font-size: 14px;
}

.footer-inner {
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: var(--radius);
  padding: 20px 24px;
}

#footer h2 {
  font-family: var(--display);
  color: #fff;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0;
}

#footer a { color: var(--link-dark); }
.pool { color: var(--on-dark); font-size: 13.5px; margin-bottom: 16px; line-height: 1.6; }

.fine { color: var(--on-dark-faint); font-size: 12px; line-height: 1.6; }

.made-by {
  display: inline-block;
  margin-top: 10px;
  font-family: var(--display);
  font-weight: 700;
}

/* ── Wider than a phone ─────────────────────────────────────────── */

@media (min-width: 560px) {
  /* The cards stay stacked -- only the maps get the extra room. */
  :root { --map-h: 132px; }
  .locator-side { width: 112px; }
  .suburb-map .locator { width: 98px; height: 98px; }
  .locmap-where { font-size: 12px; }
  .pip { width: 30px; }
  .question { font-size: 27px; }
  .title { font-size: 38px; }
  .button { width: auto; min-width: 200px; }
  .products { grid-template-columns: 1fr 1fr; }
  .scorecard { padding: 32px 24px 26px; }
  .scorecard .score { font-size: 54px; }
  .tier { font-size: 22px; }
}

/* ── Dark scheme ─────────────────────────────────────────────────────
   Mappr darkens its surfaces when the operating system asks for it, and
   swaps green for a lighter green and ink for gold. The same rules here.

   The maps are the part that does not survive on its own: every fill in
   them is a token above for exactly this reason. */

@media (prefers-color-scheme: dark) {
  :root {
    --bg-top: #1a1d24;
    --bg-bottom: #0a0b0e;
    --card: #191c22;
    --card-soft: #22262e;
    --ink: #f2f4f8;
    --body: #c4c9d4;
    --muted: #8f96a5;
    --line: #2e333d;
    --pop: #4fd0a0;
    --yes: #4fd0a0;
    --yes-bg: rgba(79, 208, 160, 0.12);
    --no: #ff7a6e;
    --no-bg: rgba(255, 122, 110, 0.12);

    --on-dark: #c4c9d4;
    --on-dark-soft: #9aa2b1;
    --on-dark-faint: #8f96a5;
    --link-card: #8fb4ff;

    --map-land: #22262e;
    --map-edge: #39404c;
    --frame-fill: #262b34;
    --frame-edge: #3d4450;

    --shadow-card: 0 8px 30px rgba(0, 0, 0, 0.5);
    --shadow-hero: 0 12px 40px rgba(0, 0, 0, 0.5);
  }

  .card,
  .suburb,
  .scorecard,
  .error { border: 1px solid var(--line); }

  .suburb { border-width: 2px; border-color: var(--line); }
  .suburb.is-right { border-color: var(--yes); }
  .suburb.is-wrong { border-color: var(--no); }

  /* Mappr's dark primary is gold on near-black, not ink on white. */
  .button { background: var(--card-soft); color: var(--ink); border-color: var(--line); }
  .button:hover { background: rgba(232, 182, 74, 0.14); }
  .button.primary { background: var(--gold); border-color: var(--gold); color: #2a1f04; }
  .button.primary:hover { background: #f0c25c; }

  .share-text { background: var(--card-soft); }

  /* Inside the maps the shape needs more fill to read against a dark
     neighbour, and the pin ring needs to be less shy. */
  .suburb-map .shape { fill-opacity: 0.28; }
  .suburb-map .pin-ring { opacity: 0.6; }
}

/* With animation off there is no draining ring, so there is no warning that
   the round is about to turn over -- and app.js does not start the timer at
   all. The chevron becomes a plain next control, with a plain ring round it. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation: none !important; transition: none !important; }
  .skip-ring .ring { stroke: rgba(255, 255, 255, 0.28); }
}
