/* #279: 44px is the tap floor Apple and Google both publish, and the
   header pill (Home / Mute / Help) is the one control on every screen of
   every product. Measured before this: 31.6px to 42px across 12 products.
   Raised to the floor rather than to taste. */
/* Atlas — presentation only. The map is a canvas: 13,449 points redrawn on
   every pan and pinch, and the renderer culls to the visible rectangle so the
   cost is the screen rather than the country. */

:root {
  --bg: #0f172a;
  --panel: #1e293b;
  --line: #334155;
  --ink: #e2e8f0;
  --dim: #94a3b8;
  --accent: #38bdf8;
  --go: #22c55e;
  --stop: #ef4444;
  --gold: #fbbf24;

  /* The map's own palette. Named for the ROLE, not the colour, so a retheme is
     one block — and so the legend can resolve the same custom property the
     canvas does and cannot drift away from it. */
  --sea: #0b1220;
  --land: #1d2c48;       /* a state not yet placed / not the answer */
  --coast: #64748b;      /* the outline of the whole country */
  --frame: #33465f;      /* the same outline at Cartographer: a frame, not a guide */
  --border: #334155;     /* an interior border between two states */
  --ghost: #22364f;      /* the faint "it goes here" outline at Explorer */
  --placed: #2d5a8a;     /* a state you have put down, or the map at rest */
  --held: #38bdf8;       /* the piece in your hand */
  --right: #22c55e;
  --wrong: #ef4444;
  --lit: #fbbf24;        /* the state the question is about */

  /* Chrome that was written as literals until v1.3.0 and could not follow a
     theme. Named for the ROLE for the same reason the map palette is. */
  --onAccent: #04233a;   /* ink on an accent-filled button */
  --raise: var(--raise);  /* a surface lifted off the page */
  --selBg: #10344a;      /* a chosen option's fill */
  --selInk: #bae6fd;     /* ...and its ink */
  --rightBg: #0d3b23;    /* a correct answer's fill */
  --wrongBg: #3b1212;    /* a wrong one's */
  --field: #0b1220;      /* a text input's well */
}

/* ---- light ---------------------------------------------------------------
   A paper atlas rather than an inverted screen: pale water, warm land, dark
   ink. Every value below is the SAME ROLE as its dark twin, so the canvas,
   the legend and the stylesheet all keep resolving one name.

   `data-theme` is resolved in app.js, never by a media query here, so this
   block is written ONCE. An `@media (prefers-color-scheme: light)` copy for
   the Auto setting would be the whole palette written down twice, and
   anything written down twice disagrees eventually. */
:root[data-theme="light"] {
  --bg: #eef2f7;
  --panel: #ffffff;
  --line: #cbd5e1;
  --ink: #0f172a;
  --dim: #52627a;
  --accent: #0369a1;
  --go: #15803d;
  --stop: #b91c1c;
  --gold: #b45309;

  --sea: #cfe0ee;
  --land: #f3ead8;
  --coast: #475569;
  --frame: #94a3b8;
  --border: #a8b6c6;
  --ghost: #e0d5bd;
  --placed: #8ab4d8;
  --held: #0e7490;
  --right: #15803d;
  --wrong: #b91c1c;
  --lit: #e8a317;

  --onAccent: #ffffff;
  --raise: rgba(15, 23, 42, .05);
  --selBg: #d6ebfa;
  --selInk: #0c4a6e;
  --rightBg: #dcf5e4;
  --wrongBg: #fbe0e0;
  --field: #ffffff;
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

/* The UA's `[hidden] { display: none }` is a low-specificity rule, so ANY class
   here that sets `display` beats it and the element stays visible. */
[hidden] { display: none !important; }

html, body {
  margin: 0; padding: 0; height: 100%;
  background: var(--bg); color: var(--ink);
  font: 400 16px/1.45 -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  overflow: hidden; overscroll-behavior: none;
}

#app { height: 100%; display: flex; flex-direction: column; }

.scr { display: none; flex: 1; min-height: 0; flex-direction: column; }
.scr.on { display: flex; }

#scr-menu, #scr-how, #scr-win {
  overflow-y: auto;
  padding: max(16px, env(safe-area-inset-top)) 16px calc(28px + env(safe-area-inset-bottom));
  align-items: stretch;
}

h1 { font-size: 30px; margin: 8px 0 2px; text-align: center; }
h2 { font-size: 17px; margin: 0 0 6px; }
.sub { text-align: center; color: var(--dim); margin-bottom: 16px; }

/* ---- buttons ---- */

.big {
  display: block; width: 100%; margin: 8px 0; padding: 14px 16px;
  font: 600 16px/1 inherit; color: var(--ink);
  background: var(--panel); border: 1px solid var(--line); border-radius: 12px;
  cursor: pointer; text-align: center; text-decoration: none;
  -webkit-appearance: none; appearance: none; touch-action: manipulation;
}
.big.primary { background: var(--accent); color: var(--onAccent); border-color: transparent; }
.big:active { transform: translateY(1px); }

.btn {
  padding: 9px 12px; font: 600 14px/1 inherit; color: var(--ink);
  background: var(--panel); border: 1px solid var(--line); border-radius: 10px;
  cursor: pointer; -webkit-appearance: none; appearance: none;
  touch-action: manipulation; min-height: 44px;}

.pill {
  padding: 8px 10px; min-width: 44px; min-height: 44px;
  font: 600 14px/1 inherit; color: var(--ink);
  background: var(--raise); border: 1px solid var(--line);
  border-radius: 10px; cursor: pointer; white-space: nowrap;
  display: flex; align-items: center; justify-content: center;
  -webkit-appearance: none; appearance: none; touch-action: manipulation;
}
.pill:disabled { opacity: .35; cursor: default; }

/* ---- mode + tiers ---- */

#modeRow { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 12px; }
#modeRow .opt { flex: 1 1 40%; padding: 12px 6px; }

#tierRow { display: flex; gap: 8px; margin-bottom: 4px; }
.tier {
  flex: 1; padding: 12px 6px; border-radius: 12px; cursor: pointer;
  background: var(--panel); border: 1px solid var(--line); color: var(--ink);
  font: 600 13px/1.2 inherit; text-align: center;
  -webkit-appearance: none; appearance: none; touch-action: manipulation;
}
.tier .age { display: block; font-weight: 400; font-size: 11px; color: var(--dim); margin-top: 3px; }
.tier[aria-checked="true"] { border-color: var(--accent); background: var(--selBg); }

/* ---- settings ---- */

details#custom {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 12px; margin: 8px 0; padding: 0 14px;
}
details#custom summary {
  padding: 14px 0; font-weight: 600; cursor: pointer; list-style: none;
  display: flex; align-items: center; gap: 8px;
}
details#custom summary::-webkit-details-marker { display: none; }
.badge {
  margin-left: auto; font: 400 12px/1 inherit; color: var(--dim);
  max-width: 60%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.fields { padding-bottom: 12px; }
/* WRAPS (R-G26.9). A settings row is [label][segmented control], and the
   control's width is decided by its option labels at runtime. Measured at
   320px this row ran 13px past the screen edge, so the last option was
   cut in half — a control you cannot see or reliably hit. Wrapping drops
   the control onto its own line ONLY when it has to; at 375px and wider
   nothing moves. */
.field { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin: 10px 0; min-height: 44px; }
.field .lbl { flex: 0 0 76px; font-size: 13px; color: var(--dim); }
.opt {
  flex: 1 1 auto; min-width: 0; padding: 9px 6px; border-radius: 9px;
  font: 600 13px/1 inherit; color: var(--ink); cursor: pointer;
  background: var(--raise); border: 1px solid var(--line);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  -webkit-appearance: none; appearance: none; touch-action: manipulation;
}
.opt[aria-checked="true"] { border-color: var(--accent); background: var(--selBg); color: var(--selInk); }
/* Declaring a height is what puts a rule in front of `just check-tap` at all —
   the guard measures the 264 interactive rules that state one. `.opt` states
   none, so these do, and are measured. */
#themeRow { display: flex; flex: 1; gap: 6px; }
#themeRow .opt { min-height: 44px; }
.seedRow { display: flex; flex: 1; gap: 6px; }
#seedIn {
  flex: 1; min-width: 0; padding: 9px 10px; border-radius: 9px;
  font: 600 13px/1 inherit; color: var(--ink);
  background: var(--raise); border: 1px solid var(--line);
  -webkit-appearance: none; appearance: none;
}
.hint { font-size: 12px; color: var(--dim); margin: 10px 0 0; }
#statsLine { text-align: center; font-size: 12px; color: var(--dim); margin-top: 14px; }

/* ---- play ---- */

#hdr {
  flex: 0 0 auto; display: flex; gap: 6px; align-items: center;
  padding: max(6px, env(safe-area-inset-top)) 8px 6px;
  border-bottom: 1px solid var(--line); background: var(--bg);
}
#hdrTitle {
  flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; font-weight: 700; font-size: 15px;
}
#hdr .pill { min-width: 44px; min-height: 44px; font-size: 17px; }

#bar {
  display: flex; gap: 6px; align-items: center;
  padding: 6px 8px; border-bottom: 1px solid var(--line); background: var(--bg);
}
#barSpace { flex: 1; min-width: 0; }
#bar .pill { padding: 8px 7px; font-size: 13px; min-width: 44px; min-height: 44px;}
/* R-C19: a number the player watches change gets tabular figures, or the pill
   beside it slides sideways every second. */
#hudLeft, #hudTime { flex-shrink: 1; overflow: hidden; font-variant-numeric: tabular-nums; }

/* The question. Its own row above the map, because in three of the four modes
   it is the thing the player is answering and it must not move when the map
   redraws. min-height reserves the row in Explore too, so switching modes does
   not resize the board. */
#ask {
  min-height: 40px; display: flex; align-items: center; justify-content: center;
  padding: 6px 12px; font-size: 15px; text-align: center; gap: 8px;
}
#ask b { color: var(--accent); }
#ask.good b { color: var(--go); }
#ask.bad b { color: var(--stop); }

#stage { flex: 1; min-height: 0; position: relative; overflow: hidden; }
#cv { position: absolute; inset: 0; width: 100%; height: 100%; touch-action: none; display: block; }

/* The held piece (atlas-spec.md R21) — drawn at whatever size it needs to be
   handled, never at the board's zoom. Rhode Island is 7.5px on the map and
   full height in here. */
#tray {
  flex: 0 0 auto; display: flex; align-items: center; gap: 12px;
  padding: 8px 12px; border-top: 1px solid var(--line); background: var(--panel);
  min-height: 96px;
}
#piece { width: 96px; height: 80px; flex: none; touch-action: none; display: block; }
#pieceName { font-weight: 700; font-size: 17px; }

/* Capitals. Four buttons that must each clear the tap floor on a 320px phone,
   so they stack rather than sit in a row — a four-across row of city names at
   320px is 74px per button and "Oklahoma City" does not fit in it. */
#choices { flex: 0 0 auto; display: flex; flex-direction: column; gap: 6px; padding: 8px 12px; }
#choices button {
  min-height: 46px; padding: 10px 12px; border-radius: 10px;
  font: 600 15px/1.2 inherit; color: var(--ink);
  background: var(--panel); border: 1px solid var(--line); cursor: pointer;
  -webkit-appearance: none; appearance: none; touch-action: manipulation;
}
#choices button.right { border-color: var(--go); background: var(--rightBg); min-height: 44px;}
#choices button.wrong { border-color: var(--stop); background: var(--wrongBg); min-height: 44px;}
#choices button:disabled { cursor: default; }

#playHint {
  padding: 6px 12px calc(6px + env(safe-area-inset-bottom));
  font-size: 12px; color: var(--dim); text-align: center; min-height: 24px;
}

/* ---- cards ---- */

.card {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 12px; padding: 14px; margin: 8px 0; font-size: 14px;
}
.card.win { text-align: center; }
#winStars { font-size: 34px; letter-spacing: 4px; }
#winBody { color: var(--dim); margin-top: 6px; }
#winBest { color: var(--gold); font-weight: 600; margin-top: 8px; min-height: 20px; }
/* A result carries its evidence (#173): the run-down of what was missed sits
   under the headline, not behind another tap. */
.evid { text-align: left; font-size: 13px; color: var(--dim); margin-top: 10px; }
.evid div { padding: 2px 0; }

/* ---- the legend (docs/offline-games-pwa.md R-L1) ----
   Every swatch takes its colour from `--m`, which app.js sets to the SAME
   custom property the canvas resolves. The stylesheet holds the shape and
   nothing else, so a retheme cannot leave the legend behind. */
.lgSub { font-weight: 600; font-size: 13px; color: var(--dim); margin: 10px 0 6px; }
.legend { display: flex; flex-direction: column; gap: 8px; }
.lgRow { display: flex; align-items: center; gap: 10px; }
.lgArt { flex: none; width: 40px; height: 20px; display: flex; align-items: center; justify-content: center; font-style: normal; }
.lgArt.lg-fill::after { content: ''; width: 26px; height: 16px; border-radius: 3px; background: var(--m); }
.lgArt.lg-out::after { content: ''; width: 26px; height: 16px; border-radius: 3px; border: 2px solid var(--m); }
.lgArt.lg-dash::after { content: ''; width: 30px; height: 0; border-top: 2px dashed var(--m); }
.lgArt.lg-thin::after { content: ''; width: 30px; height: 1px; background: var(--m); opacity: .8; }
.lgTxt { display: flex; flex-direction: column; min-width: 0; }
.lgTxt b { font-weight: 700; }
.lgTxt small { font-size: 12.5px; color: var(--dim); line-height: 1.35; }

/* ---- toast ---- */

#toast {
  position: fixed; left: 50%; bottom: calc(64px + env(safe-area-inset-bottom));
  transform: translateX(-50%) translateY(12px);
  background: var(--field); border: 1px solid var(--line); color: var(--ink);
  padding: 10px 14px; border-radius: 10px; font-size: 14px;
  opacity: 0; pointer-events: none; transition: opacity .18s, transform .18s;
  z-index: 50; max-width: calc(100vw - 32px); text-align: center;
}
#toast.on { opacity: 1; transform: translateX(-50%) translateY(0); }

@media (min-width: 720px) {
  #scr-menu, #scr-how, #scr-win { max-width: 560px; margin: 0 auto; width: 100%; }
}

/* ---- landscape ----------------------------------------------------------
   MEASURED, on an 812x375 window: header 56 + bar 50 + ask 40 + tray 96 +
   hint 24 leaves the map 109px of a 375px screen. The country came out the
   size of a postage stamp — which is the same defect #223 found in the card
   games, one product later and with a different set of rows stacked up.

   Everything except the map is NARROW and the screen is WIDE, so the fix is
   to stop stacking: the map takes the whole height on the left, and the
   question, the piece and the hint go into a column beside it. The tray and
   the choices share one grid area because a mode never shows both. */
@media (orientation: landscape) and (max-height: 520px) {
  #scr-play {
    display: grid;
    grid-template-columns: 1fr minmax(170px, 32%);
    grid-template-rows: auto auto 1fr auto;
    grid-template-areas:
      "bar   bar"
      "stage ask"
      "stage tray"
      "stage hint";
    min-height: 0;
  }
  #bar { grid-area: bar; }
  #stage { grid-area: stage; min-height: 0; }
  #ask { grid-area: ask; min-height: 0; padding: 8px 10px 2px; font-size: 14px; }
  #tray, #choices { grid-area: tray; min-height: 0; }
  #tray { flex-direction: column; gap: 6px; border-top: 0;
          border-left: 1px solid var(--line); justify-content: center; }
  #choices { justify-content: center; padding: 4px 10px; }
  #choices button { min-height: 44px; padding: 6px 8px; font-size: 13px; }
  /* The floated version chip lands bottom-right in this window (#228), which
     is exactly where the hint's last line goes. Measured overlap on 812x375;
     the right padding is the chip's width plus its gutter. */
  #playHint { grid-area: hint; padding: 2px 62px 6px 10px; }
}

/* #228: a landscape window under 500px tall must not spend a 44px row on the
   version chip. The min-width guard keeps the floated chip off the map on a
   narrow landscape window. */
@media (orientation: landscape) and (max-height: 500px) and (min-width: 600px) {
  #app { position: relative; }
  #footer { position: absolute; right: 0; bottom: 0;
            padding-bottom: env(safe-area-inset-bottom); }
}
