/* Tidemark: the playable shell (src/ui). Loaded after style.css on index.html.
   Two registers: the pixel register (HUD, controls, cards, toasts) in
   "Tidemark UI", and the chart register (survey, decisions, end card,
   About) in Source Serif on paper. Both follow prefers-color-scheme. */
:root {
  /* --hud-h and --ctrl-h are the bars' real heights: game.ts measures them
     (they grow when large text makes the bars wrap); these are the defaults. */
  --hud-min: 58px;
  --ctrl-min: 64px;
  --hud-h: var(--hud-min);
  --ctrl-h: var(--ctrl-min);
  --panel-w: 410px;
  /* pixel register surfaces */
  --surf: #f6efdd;
  --surf-2: #ebe1c8;
  --surf-ink: #1f2a30;
  --surf-soft: #55615f;
  --surf-line: #1f2a30;
  --surf-shadow: rgba(23, 20, 43, 0.45);
  --warn: #8a2a1a;
  --focus: #b0287a;
  --gold: #d9a441;
  --gold-ink: #1a1408;
  /* chart register */
  --paper-c: #f3ecda;
  --paper-ink: #1f2a30;
  --paper-soft: #56625f;
  --paper-rule: #8b8574;
  --paper-mag: #b0287a;
  --paper-water: #cfe3df;
  /* text on a magenta button: white on the day chart's magenta, ink on the night chart's lighter one */
  --on-mag: #ffffff;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --surf: #102a33; --surf-2: #17363f; --surf-ink: #f2ead8; --surf-soft: #b9c3bd; --surf-line: #f2ead8; --surf-shadow: rgba(0, 0, 0, 0.55);
    --warn: #f2a26c; --focus: #f8dc8b;
    --paper-c: #0e1a22; --paper-ink: #d9cfb8; --paper-soft: #9aa49c; --paper-rule: #4d5a5c; --paper-mag: #e08ab9; --paper-water: #17363f; --on-mag: #0e1a22;
  }
}

.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.game { position: fixed; inset: 0; overflow: hidden; background: #17142b; color: var(--surf-ink); font-family: var(--font-pixel); }
.game button { font: inherit; color: inherit; }
.game :focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
.stage { position: absolute; inset: 0; }
.diorama-wrap { position: absolute; inset: 0; overflow: hidden; touch-action: none; }
.diorama-wrap canvas { position: absolute; left: 0; top: 0; cursor: pointer; }
.chart-wrap { position: absolute; left: 0; right: 0; top: var(--hud-h); bottom: var(--ctrl-h); background: var(--paper-c); }
.game-chart { display: block; width: 100%; height: 100%; touch-action: manipulation; cursor: pointer; }
.game [hidden] { display: none !important; }

/* ---- HUD ---- */
.hud { position: absolute; left: 0; right: 0; top: 0; z-index: 5; display: flex; flex-wrap: wrap; align-items: stretch; row-gap: 4px; padding: max(4px, env(safe-area-inset-top)) 4px 4px; min-height: var(--hud-min); background: var(--surf); border-bottom: 2px solid var(--surf-line); box-shadow: 0 3px 0 var(--surf-shadow); }
.hud-stat { display: grid; align-content: center; flex: 1 1 auto; padding: 0 5px; min-width: max-content; border-left: 1px dashed color-mix(in srgb, var(--surf-ink) 30%, transparent); }
.hud-stat:first-child { border-left: 0; }
.hud-label { font-size: 0.6875rem; letter-spacing: 0.06em; text-transform: uppercase; color: var(--surf-soft); }
.hud-value { font-size: 1rem; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hud-sub { font-size: 0.6875rem; color: var(--surf-soft); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hud-year .hud-value { font-size: 1.1875rem; }
.hud-homes.is-warn .hud-sub { color: var(--warn); font-weight: 600; }
/* The "!" means homes at risk: it shows only when there are some (playtest 2). */
.hud-homes.has-risk .hud-sub::before { content: "! "; color: var(--warn); }
.hud-bar { display: block; height: 4px; margin-top: 2px; background: color-mix(in srgb, var(--surf-ink) 18%, transparent); }
.hud-bar-fill { display: block; height: 100%; background: var(--surf-ink); }
/* homes: safe | at risk | empty | lost | left, as a stacked bar (the numbers are in the label) */
.hud-split { display: flex; height: 4px; margin-top: 2px; background: color-mix(in srgb, var(--surf-ink) 12%, transparent); }
.hud-split > span { display: block; height: 100%; }
.hud-split-safe { background: var(--surf-ink); }
.hud-split-risk { background: var(--warn); }
.hud-split-empty { background: color-mix(in srgb, var(--warn) 45%, transparent); }
.hud-split-lost { background: repeating-linear-gradient(90deg, var(--surf-soft) 0 2px, transparent 2px 4px); }
.hud-split-left { background: color-mix(in srgb, var(--surf-soft) 40%, transparent); }
@media (min-width: 760px) {
  :root { --hud-min: 64px; }
  .hud { justify-content: flex-start; padding-left: 12px; }
  .hud-stat { flex: 1 1 0; max-width: 17rem; padding: 0 12px; }
  .hud-homes { max-width: 22rem; }
  .hud-value { font-size: 1.25rem; }
  .hud-year .hud-value { font-size: 1.5rem; }
  .hud-label, .hud-sub { font-size: 0.75rem; }
}
/* Very narrow phones (320 px): a little tighter so the five figures and four buttons still fit on one row each. */
@media (max-width: 359px) {
  .hud-stat { padding: 0 3px; }
  .hud-value { font-size: 0.875rem; }
  .hud-year .hud-value { font-size: 1rem; }
  .ctrl { font-size: 0.8125rem; gap: 3px; padding: 0 3px; }
  .ctrl-town .ctrl-glyph, .ctrl-view .ctrl-glyph { display: none; }
}

/* ---- caption, mini fan, zoom ---- */
.caption { position: absolute; z-index: 4; left: 8px; top: calc(var(--hud-h) + 8px); margin: 0; font-size: 0.8125rem; line-height: 1.35; padding: 5px 8px; background: color-mix(in srgb, var(--surf) 90%, transparent); border: 2px solid var(--surf-line); box-shadow: 3px 3px 0 var(--surf-shadow); max-width: min(62ch, calc(100% - 152px)); }
.caption.is-event { border-color: var(--warn); }
.caption.is-event::before { content: "⚠ "; color: var(--warn); }
.game[data-view="chart"] .caption { display: none; }
.mini-fan { position: absolute; z-index: 4; right: 8px; top: calc(var(--hud-h) + 8px); width: 128px; height: 50px; padding: 0; border: 2px solid var(--surf-line); background: color-mix(in srgb, var(--surf) 92%, transparent); box-shadow: 3px 3px 0 var(--surf-shadow); cursor: pointer; display: grid; grid-template-rows: auto 1fr; }
.mini-fan-label { font-size: 0.625rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--surf-soft); padding: 2px 4px 0; text-align: left; }
.mini-fan svg { width: 100%; height: 100%; display: block; }
.mini-fan-range { display: none; }
@media (min-width: 760px) {
  .mini-fan { width: 208px; height: 92px; grid-template-rows: auto 1fr auto; }
  .mini-fan-label { font-size: 0.75rem; color: var(--surf-ink); font-weight: 600; }
  .mini-fan-range { display: block; font-size: 0.75rem; padding: 0 4px 3px; text-align: left; }
  .mini-fan:hover { background: var(--surf); }
}
.game[data-view="chart"] .mini-fan { display: none; }
.zoom { position: absolute; z-index: 4; right: 8px; bottom: calc(var(--ctrl-h) + 10px); display: grid; gap: 6px; }
.zoom-btn { width: 44px; height: 44px; border: 2px solid var(--surf-line); background: var(--surf); box-shadow: 3px 3px 0 var(--surf-shadow); font-size: 1.375rem; line-height: 1; cursor: pointer; }
.game[data-view="chart"] .zoom { display: none; }

/* ---- controls ---- */
.controls { position: absolute; z-index: 6; left: 0; right: 0; bottom: 0; display: flex; flex-wrap: wrap; gap: 6px; padding: 6px 6px max(6px, env(safe-area-inset-bottom)); background: var(--surf); border-top: 2px solid var(--surf-line); min-height: var(--ctrl-min); }
.ctrl { flex: 1 1 auto; display: flex; align-items: center; justify-content: center; gap: 6px; min-height: 48px; padding: 0 6px; border: 2px solid var(--surf-line); background: var(--surf-2); box-shadow: 3px 3px 0 var(--surf-shadow); cursor: pointer; font-size: 0.9375rem; font-weight: 600; white-space: nowrap; }
.ctrl:active { transform: translate(2px, 2px); box-shadow: 1px 1px 0 var(--surf-shadow); }
.ctrl:disabled { opacity: 0.45; cursor: default; }
.ctrl-glyph { font-size: 0.9375rem; }
.game .ctrl-next { background: var(--gold); color: var(--gold-ink); border-color: var(--gold-ink); }
.game .ctrl-play[aria-pressed="true"] { background: var(--surf-ink); color: var(--surf); }
.game .ctrl-view[aria-pressed="true"] { background: var(--paper-c); color: var(--paper-ink); }
@media (min-width: 760px) {
  .controls { left: auto; right: 12px; bottom: 12px; border: 2px solid var(--surf-line); box-shadow: 4px 4px 0 var(--surf-shadow); padding: 6px; min-height: 0; max-width: calc(100% - 24px); justify-content: flex-end; }
  .ctrl { padding: 0 16px; }
  .zoom { bottom: 96px; right: 12px; }
  .game[data-view="chart"] .chart-wrap { bottom: 0; }
}

/* ---- toasts ---- */
.toasts { position: absolute; z-index: 5; left: 8px; bottom: calc(var(--ctrl-h) + 10px); width: min(440px, calc(100% - 70px)); display: flex; flex-direction: column; gap: 6px; pointer-events: none; }
.toast { pointer-events: auto; display: grid; grid-template-columns: 44px 1fr 44px; gap: 8px; align-items: start; padding: 7px 4px 7px 7px; background: var(--surf); border: 2px solid var(--surf-line); box-shadow: 3px 3px 0 var(--surf-shadow); animation: toast-in 180ms ease-out; }
.toast.is-leaving { opacity: 0; transition: opacity 200ms; }
@keyframes toast-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
.portrait { width: 44px; height: 44px; image-rendering: pixelated; border: 2px solid var(--surf-line); }
.portrait-lg { width: 60px; height: 60px; flex: none; }
.toast-who { margin: 0; font-size: 0.8125rem; }
.toast-who span { color: var(--surf-soft); }
.toast-text { margin: 2px 0 0; font-family: var(--font-serif); font-size: 0.9375rem; line-height: 1.35; }
.toast-close { width: 44px; height: 44px; margin: -6px -2px 0 0; border: 0; background: none; font-size: 1.125rem; cursor: pointer; color: var(--surf-soft); }
.toast.is-prompt { border-color: var(--paper-mag); }
.toast-act { margin-top: 6px; }
.has-panel .toasts { display: none; }
/* Phones, chart view: the residents wait for the town view; their lines covered the sea-level outlook (playtest 2, #9). */
@media (max-width: 759px) { .game[data-view="chart"] .toasts { display: none; } }
@media (min-width: 760px) { .toasts { left: 12px; bottom: 12px; } .has-panel .toasts { display: flex; } }

/* ---- panel ---- */
.panel { position: absolute; z-index: 7; left: 0; right: 0; bottom: var(--ctrl-h); max-height: 56%; display: flex; flex-direction: column; background: var(--surf); border-top: 2px solid var(--surf-line); box-shadow: 0 -3px 0 var(--surf-shadow); animation: sheet-in 160ms ease-out; }
@keyframes sheet-in { from { transform: translateY(12px); opacity: 0.6; } to { transform: none; opacity: 1; } }
@media (min-width: 760px) {
  .panel { left: auto; right: 12px; top: calc(var(--hud-h) + 12px); bottom: 84px; width: var(--panel-w); max-height: none; border: 2px solid var(--surf-line); box-shadow: 4px 4px 0 var(--surf-shadow); }
  .has-panel .mini-fan, .has-panel .zoom { right: calc(var(--panel-w) + 24px); }
  .game[data-view="chart"].has-panel .chart-wrap { right: calc(var(--panel-w) + 24px); }
}
.panel-head { display: flex; align-items: center; gap: 4px; padding: 6px 6px 4px; border-bottom: 2px solid var(--surf-line); }
.panel-heading { flex: 1; min-width: 0; text-align: center; }
.panel-title { margin: 0; font-size: 1.1875rem; font-weight: 600; }
.panel-sub { margin: 0; font-size: 0.75rem; color: var(--surf-soft); }
.panel-step, .panel-close { width: 44px; height: 44px; flex: none; border: 2px solid var(--surf-line); background: var(--surf-2); font-size: 1.375rem; cursor: pointer; }
.panel-step:disabled { opacity: 0.3; cursor: default; }
.panel-tabs { display: flex; gap: 4px; padding: 6px 8px 0; border-bottom: 2px solid var(--surf-line); }
.panel-tabs:empty { display: none; }
.panel-tab { flex: 1; min-height: 44px; border: 2px solid var(--surf-line); border-bottom: 0; background: var(--surf-2); cursor: pointer; font-size: 0.9375rem; }
.panel-tab[aria-selected="true"] { background: var(--surf-ink); color: var(--surf); font-weight: 600; }
.panel-body { overflow-y: auto; padding: 8px; overscroll-behavior: contain; scroll-padding-top: 8px; }
.panel-note { font-family: var(--font-serif); font-size: 0.9375rem; margin: 4px; }

/* ---- cards ---- */
.cards { display: grid; gap: 8px; }
.card { border: 2px solid var(--surf-line); background: var(--surf-2); padding: 8px; display: grid; gap: 6px; }
/* Unavailable: a dashed frame, a faded icon and the "Unavailable: why" line; the text keeps full contrast. */
.card.is-unavailable { border-style: dashed; }
.card.is-unavailable .card-icon { opacity: 0.6; }
.card.is-ordered { outline: 3px solid var(--paper-mag); outline-offset: -1px; }
.card-head { display: flex; gap: 10px; align-items: center; }
.card-icon { width: 80px; height: 48px; flex: none; image-rendering: pixelated; border: 2px solid var(--surf-line); background: #f6dcae; }
.card-name { margin: 0; font-size: 1.0625rem; font-weight: 600; }
.card-cat { margin: 0; font-size: 0.75rem; color: var(--surf-soft); }
.cat-hard .card-cat::before { content: "▮ "; }
.cat-nature .card-cat::before { content: "✿ "; }
.cat-hybrid .card-cat::before { content: "▮✿ "; }
.cat-people .card-cat::before { content: "⌂ "; }
.cat-frontier .card-cat::before { content: "✦ "; }
.card-figures { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(4.5rem, 1fr)); gap: 4px; }
.card-figures li { display: grid; padding: 3px 4px; background: var(--surf); border: 1px solid color-mix(in srgb, var(--surf-ink) 35%, transparent); min-width: 0; }
.card-figures .card-k { font-size: 0.6875rem; color: var(--surf-soft); text-transform: uppercase; letter-spacing: 0.04em; }
.card-figures b { font-size: 0.875rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.card-effects { margin: 0; display: grid; grid-template-columns: auto 1fr; gap: 2px 8px; }
.card-effects dt { font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--surf-soft); padding-top: 2px; }
.card-effects dd { margin: 0; font-family: var(--font-serif); font-size: 0.9062rem; line-height: 1.35; }
.card-precedent { font-family: var(--font-serif); font-size: 0.875rem; line-height: 1.35; margin: 0; }
.card-precedent summary { cursor: pointer; min-height: 44px; padding: 6px 0; }
.card-precedent .card-k { font-family: var(--font-pixel); font-size: 0.75rem; text-transform: uppercase; color: var(--surf-soft); }
.card-precedent-body p { margin: 4px 0; }
.card-precedent .cite { color: var(--surf-soft); }
.card-foot { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.card-status { margin: 0; flex-basis: 100%; font-size: 0.8125rem; }
.card-status::before { content: "● "; }
.card-why { margin: 0; flex-basis: 100%; font-size: 0.8125rem; color: var(--warn); }
.card-ordered { margin: 0; flex: 1; font-size: 0.8125rem; }
.btn-build { flex: 1; min-height: 44px; border: 2px solid var(--gold-ink); background: var(--gold); color: var(--gold-ink) !important; font-weight: 600; cursor: pointer; box-shadow: 3px 3px 0 var(--surf-shadow); }
.btn-build:disabled { background: transparent; color: var(--surf-soft) !important; border-color: var(--surf-soft); border-style: dashed; box-shadow: none; cursor: not-allowed; }
.btn-small { min-height: 44px; padding: 0.3rem 0.8rem; font-size: 0.875rem; border-radius: 0; border: 2px solid var(--surf-line); color: var(--surf-ink); background: var(--surf); cursor: pointer; }

/* ---- survey (the inspector): the chart register inside the panel ---- */
.chart-note { font-family: var(--font-serif); background: var(--paper-c); color: var(--paper-ink); border: 1px solid var(--paper-ink); outline: 1px solid var(--paper-ink); outline-offset: 2px; margin: 4px; padding: 10px 12px; }
.survey-eyebrow { margin: 0 0 6px; font-style: italic; color: var(--paper-soft); font-size: 0.875rem; }
.survey-list { margin: 0 0 10px; display: grid; }
.survey-list dt { font-size: 0.7812rem; letter-spacing: 0.05em; text-transform: uppercase; color: var(--paper-soft); margin-top: 7px; }
.survey-list dt.survey-head { font-size: 0.875rem; font-weight: 600; letter-spacing: 0.02em; text-transform: none; color: var(--paper-ink); border-bottom: 1px solid var(--paper-rule); padding-bottom: 2px; margin-top: 4px; }
.survey-list dd { margin: 0; font-size: 1rem; }
.survey-list dd.survey-head { display: none; }
.cite { font-style: italic; font-size: 0.8125rem; color: var(--paper-soft); }
.cite::before { content: "— "; }
.survey-foot { font-size: 0.7812rem; color: var(--paper-soft); margin: 4px 0 0; font-style: italic; }

/* ---- district & town ---- */
.district-stats { display: grid; grid-template-columns: 1fr auto; gap: 2px 10px; margin: 0 0 10px; font-size: 0.875rem; padding: 6px 8px; border: 1px dashed color-mix(in srgb, var(--surf-ink) 40%, transparent); }
.district-stats dt { color: var(--surf-soft); }
.district-stats dd { margin: 0; font-weight: 600; text-align: right; }
.town { display: grid; gap: 10px; }
.town-section { border: 2px solid var(--surf-line); background: var(--surf-2); padding: 8px; display: grid; gap: 8px; }
.town-text { margin: 0; font-family: var(--font-serif); font-size: 0.9062rem; line-height: 1.4; }
.town-lead { margin: 0; font-size: 0.875rem; font-weight: 600; }
.town-h { margin: 4px 0 0; font-size: 0.9375rem; }
.lab-tiers { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.lab-tier { display: grid; text-align: left; gap: 1px; min-height: 52px; padding: 5px 8px; border: 2px solid var(--surf-line); background: var(--surf); cursor: pointer; position: relative; }
.game .lab-tier[aria-checked="true"] { background: var(--surf-ink); color: var(--surf); }
.lab-tier[aria-checked="true"]::after { content: "✓"; position: absolute; right: 6px; top: 4px; }
.lab-tier:disabled { opacity: 0.55; cursor: not-allowed; border-style: dashed; }
.lab-tier-name { font-weight: 600; font-size: 0.875rem; }
.lab-tier-cost, .lab-tier-now, .lab-tier-why { font-size: 0.75rem; }
.lab-tier-now { text-transform: uppercase; letter-spacing: 0.05em; }
.orders { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; }
.orders li { display: grid; grid-template-columns: 1fr auto auto; gap: 8px; align-items: center; font-size: 0.875rem; }
.game .btn { border-radius: 0; border-color: var(--surf-line); color: var(--surf-ink); }
.about-btn { justify-self: start; }

/* ---- the forecast fan ---- */
.fan { width: 100%; height: auto; display: block; background: var(--paper-c); border: 1px solid var(--paper-ink); }
.fan-compact { border: 0; background: transparent; }
.fan-band { fill: color-mix(in srgb, var(--paper-mag) 22%, transparent); stroke: var(--paper-mag); stroke-width: 1; stroke-dasharray: 3 2; }
.fan-compact .fan-band { fill: color-mix(in srgb, var(--surf-ink) 20%, transparent); stroke: var(--surf-ink); }
.fan-median { fill: none; stroke: var(--paper-mag); stroke-width: 1.5; }
.fan-compact .fan-median { stroke: var(--surf-ink); stroke-dasharray: 2 2; }
.fan-realized { fill: none; stroke: var(--paper-ink); stroke-width: 2.5; }
.fan-compact .fan-realized { stroke: var(--surf-ink); }
.fan-axis { stroke: var(--paper-ink); stroke-width: 1; }
.fan-now { stroke: var(--paper-soft); stroke-dasharray: 2 2; }
.fan-text { font-family: var(--font-serif); font-size: 0.6875rem; fill: var(--paper-ink); }

/* ---- coach marks ---- */
.coach { position: absolute; z-index: 30; width: min(320px, calc(100% - 16px)); padding: 10px 12px 8px; background: var(--paper-c); color: var(--paper-ink); border: 2px solid var(--paper-ink); box-shadow: 4px 4px 0 var(--surf-shadow); }
.coach-text { margin: 0 0 8px; font-family: var(--font-serif); font-size: 1rem; line-height: 1.4; }
.coach-actions { display: flex; gap: 6px; align-items: center; }
.coach-actions .btn { white-space: nowrap; }
.coach-count { flex: 1; text-align: center; font-size: 0.75rem; color: var(--paper-soft); white-space: nowrap; }
/* Back is hidden on the first step; keep Next on the right regardless. */
.coach-actions .coach-back[hidden] + .coach-count { text-align: left; }
.coach-skip-row { display: flex; justify-content: flex-end; margin-top: 2px; margin-bottom: -8px; }
.coach-skip { min-height: 44px; min-width: 44px; display: inline-flex; align-items: center; background: none; border: 0; padding: 0 2px; font: inherit; font-size: 0.8rem; color: var(--paper-ink); text-decoration: underline; cursor: pointer; }
.coach-skip:focus-visible { outline: 2px solid var(--paper-ink); outline-offset: 2px; }
.coach .btn-small { background: var(--paper-c); color: var(--paper-ink); border-color: var(--paper-ink); }
.coach .btn-primary.btn-small { background: var(--paper-mag); border-color: var(--paper-mag); color: var(--on-mag); }
.coach-arrow { position: absolute; width: 14px; height: 14px; background: var(--paper-c); border: 2px solid var(--paper-ink); transform: translateX(-50%) rotate(45deg); display: none; }
.coach[data-arrow="up"] .coach-arrow { display: block; top: -9px; border-right: 0; border-bottom: 0; }
.coach[data-arrow="down"] .coach-arrow { display: block; bottom: -9px; border-left: 0; border-top: 0; }
.coach[data-arrow="right"] .coach-arrow { display: block; left: auto; right: -9px; top: 24px; transform: rotate(45deg); border-left: 0; border-bottom: 0; }

/* ---- modals: the chart register ---- */
.modal-backdrop { position: fixed; inset: 0; z-index: 50; display: grid; place-items: center; padding: 10px; background: rgba(10, 16, 22, 0.6); animation: fade-in 160ms ease-out; }
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
.chart-register { font-family: var(--font-serif); background: var(--paper-c); color: var(--paper-ink); border: 3px solid var(--paper-ink); outline: 1px solid var(--paper-ink); outline-offset: -8px; box-shadow: 6px 6px 0 rgba(0, 0, 0, 0.35); }
.modal { position: relative; width: min(580px, 100%); max-height: calc(100% - 8px); overflow-y: auto; padding: 22px 22px 18px; }
.modal-wide { width: min(860px, 100%); }
.modal:focus { outline: 1px solid var(--paper-ink); }
.modal-close { position: absolute; right: 12px; top: 12px; width: 44px; height: 44px; border: 1px solid var(--paper-ink); background: var(--paper-c); color: var(--paper-ink); font-size: 1.375rem; cursor: pointer; }
.modal :focus-visible { outline: 3px solid var(--paper-mag); outline-offset: 2px; }
.eyebrow { margin: 0; font-size: 0.8125rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--paper-soft); }
.modal-title { margin: 4px 0 6px; font-size: clamp(26px, 6vw, 38px); font-weight: 600; line-height: 1.1; }
.chart-register h3 { font-size: 0.875rem; letter-spacing: 0.1em; text-transform: uppercase; margin: 18px 0 6px; border-bottom: 1px solid var(--paper-rule); padding-bottom: 3px; }
.chart-register p { line-height: 1.45; }
.chart-register .btn { font-family: var(--font-pixel); border-radius: 0; color: var(--paper-ink); border-color: var(--paper-ink); background: transparent; display: inline-flex; align-items: center; text-decoration: none; }
.chart-register .btn-primary { background: var(--paper-mag); border-color: var(--paper-mag); color: var(--on-mag); }
.decision-facts { font-size: 1.125rem; margin: 0 0 10px; }
.voice { display: flex; gap: 12px; align-items: center; margin: 10px 0; padding: 8px 10px; border-left: 3px solid var(--paper-ink); background: color-mix(in srgb, var(--paper-ink) 6%, transparent); }
.voice p { margin: 0; display: grid; gap: 2px; }
.voice-text { font-style: italic; font-size: 1.0625rem; }
.voice-who { font-size: 0.8125rem; color: var(--paper-soft); }
.voice .portrait { border-color: var(--paper-ink); }
.decision-ask { font-weight: 600; margin: 12px 0 6px; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 4px 10px; }
.chart-register .what-toggle { display: none; }
.decision-summary { display: none; margin: 0 0 4px; font-size: 1rem; font-weight: 600; }
.choice-note { font-size: 0.8438rem; padding: 4px 6px; border: 1px dashed var(--paper-ink); }
.choices { display: grid; gap: 8px; }
.choice { display: grid; gap: 4px; text-align: left; padding: 10px 12px; min-height: 44px; border: 2px solid var(--paper-ink); background: var(--paper-c); color: var(--paper-ink); cursor: pointer; font-family: var(--font-serif); }
/* Hover only where there is a real hover: on touch, a sticky :hover left by the last tap tinted the first choice as if pre-selected. */
@media (hover: hover) { .choice:hover:not(:disabled) { background: color-mix(in srgb, var(--paper-mag) 10%, var(--paper-c)); } }
.choice:disabled { opacity: 0.6; cursor: not-allowed; border-style: dashed; }
.choice-name { font-size: 1.125rem; font-weight: 600; }
.choice-what { font-size: 0.9375rem; line-height: 1.35; }
.choice-figures { display: flex; flex-wrap: wrap; gap: 4px 14px; font-size: 0.875rem; color: var(--paper-soft); }
.choice-figures span:first-child { color: var(--paper-ink); font-weight: 600; }
.choice-why { font-size: 0.8125rem; color: var(--paper-mag); }
.decision-note { font-size: 0.8438rem; font-style: italic; color: var(--paper-soft); margin: 12px 0 0; }

/* ---- end ---- */
.modal-end { width: min(900px, 100%); }
.end > .eyebrow { padding-right: 52px; }
.end-outcome { font-size: clamp(44px, 12vw, 72px); color: var(--paper-mag); margin-bottom: 0; }
.end-line { font-size: 1.1875rem; font-style: italic; margin: 2px 0 6px; }
.end-reveal { font-size: 1rem; margin: 0; }
.end-big { font-size: clamp(19px, 4.6vw, 24px); font-weight: 600; margin: 4px 0; }
.worlds { display: grid; gap: 2px; margin: 6px 0; }
.worlds dt { font-weight: 600; margin-top: 6px; }
.worlds dd { margin: 0; }
.grade-rules { margin: 6px 0; padding-left: 1.2em; font-size: 0.9375rem; }
.grade-rules .is-yours { font-weight: 600; }
.end-actions-top { margin: 10px 0 0; }
.end-bars { display: grid; gap: 6px; margin: 8px 0 4px; }
.end-bar { display: grid; grid-template-columns: 7.5em 1fr auto; gap: 10px; align-items: center; font-size: 1.0625rem; }
.end-bar-track { height: 18px; border: 1px solid var(--paper-ink); background: transparent; }
.end-bar-fill { display: block; height: 100%; background: color-mix(in srgb, var(--paper-ink) 45%, transparent); }
.end-bar.is-you .end-bar-fill { background: var(--paper-mag); }
.end-bar.is-you .end-bar-label, .end-bar.is-you .end-bar-value { color: var(--paper-mag); font-weight: 600; }
.end-bar-value { font-size: 1.25rem; min-width: 3.5em; text-align: right; }
.end-small { font-size: 0.9375rem; color: var(--paper-soft); margin: 2px 0 8px; }
.end-compare { width: 100%; border-collapse: collapse; font-size: 0.9375rem; margin: 6px 0; }
.end-compare th, .end-compare td { text-align: right; padding: 4px 0 4px 10px; border-top: 1px solid var(--paper-rule); vertical-align: top; }
.end-compare th[scope="row"] { text-align: left; font-weight: 400; padding-left: 0; }
.end-compare thead th { font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--paper-soft); border-top: 0; }
.end-mark { display: block; font-size: 0.8125rem; }
.end-compare .is-worse .end-mark { color: var(--paper-mag); font-weight: 600; }
.end-honest { margin: 6px 0; padding: 6px 10px; border-left: 3px solid var(--paper-mag); font-size: 1rem; }
.end-good { margin: 6px 0; font-size: 1rem; font-style: italic; }
.game .ctrl-summary { background: var(--paper-mag); color: var(--on-mag); border-color: var(--paper-mag); }
.end-png { display: block; width: 100%; height: auto; margin: 14px 0 10px; border: 1px solid var(--paper-ink); background: var(--paper-water); aspect-ratio: 1200 / 675; }
.end-png[data-shape="tall"] { aspect-ratio: 1080 / 1350; }
.end-actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.share-note { font-size: 0.875rem; color: var(--paper-soft); word-break: break-all; }

/* ---- about ---- */
.about p { font-size: 1rem; }
.about-models { display: grid; gap: 4px 14px; grid-template-columns: minmax(110px, auto) 1fr; margin: 0; font-size: 0.9375rem; }
.about-models dt { font-weight: 600; }
.about-models dd { margin: 0; }
.about-group { border: 1px solid var(--paper-rule); margin: 6px 0; padding: 0 8px; }
.about-group summary { cursor: pointer; padding: 10px 0; min-height: 44px; font-weight: 600; }
.about-table { width: 100%; border-collapse: collapse; font-size: 0.8438rem; margin-bottom: 8px; }
.about-table th, .about-table td { text-align: left; vertical-align: top; padding: 4px 6px 4px 0; border-top: 1px solid var(--paper-rule); }
.about-table thead th { font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--paper-soft); }
.about-table tbody th { font-weight: 600; word-break: break-word; }
.about-loc { color: var(--paper-soft); }
.flag { display: inline-block; font-size: 0.6875rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; padding: 0 4px; border: 1px solid var(--paper-mag); color: var(--paper-mag); }
.about-bib { font-size: 0.8438rem; padding-left: 1.6em; }
.about-bib li { margin: 4px 0; }
.about-bib a { color: var(--paper-mag); word-break: break-all; }

@media (prefers-reduced-motion: reduce) {
  .toast, .panel, .modal-backdrop { animation: none; }
  .toast.is-leaving { transition: none; }
  .ctrl:active { transform: none; }
}

/* ---- first paint: shown until the diorama's first frame ---- */
.stage-loading { position: absolute; left: 0; right: 0; top: 45%; margin: 0; text-align: center; font-size: 1.1rem; color: #f2ead8; }

/* ---- keyboard: the maps are focusable; their focus ring is drawn inside the visible stage ---- */
.diorama-canvas:focus, .game-chart:focus { outline: none; }
.diorama-wrap:has(> canvas:focus-visible)::after, .chart-wrap:has(> canvas:focus-visible)::after { content: ""; position: absolute; pointer-events: none; border: 3px solid var(--focus); box-shadow: inset 0 0 0 2px var(--surf); }
.diorama-wrap:has(> canvas:focus-visible)::after { inset: calc(var(--hud-h) + 2px) 2px calc(var(--ctrl-h) + 2px); }
.chart-wrap:has(> canvas:focus-visible)::after { inset: 2px; }
@media (min-width: 760px) { .diorama-wrap:has(> canvas:focus-visible)::after { bottom: 2px; } }
.panel-title:focus { outline: none; }
.panel-title:focus-visible { text-decoration: underline; text-underline-offset: 3px; }

/* ---- placement feedback: "Ordered: X · ready YYYY" over the place, for a few seconds ---- */
.order-pin { position: absolute; z-index: 4; transform: translate(-50%, calc(-100% - 10px)); padding: 3px 8px; font-size: 0.8125rem; font-weight: 600; white-space: nowrap; background: var(--paper-c); color: var(--paper-ink); border: 2px solid var(--paper-mag); box-shadow: 3px 3px 0 var(--surf-shadow); pointer-events: none; animation: pin-in 200ms ease-out; }
.order-pin::after { content: ""; position: absolute; left: 50%; bottom: -9px; width: 10px; height: 10px; background: var(--paper-mag); transform: translateX(-50%) rotate(45deg); }
.order-pin.is-floating { left: 50% !important; top: calc(var(--hud-h) + 74px) !important; transform: translateX(-50%); }
.order-pin.is-floating::after { display: none; }
@keyframes pin-in { from { opacity: 0; transform: translate(-50%, calc(-100% - 2px)); } to { opacity: 1; } }

/* ---- Town panel: districts and links ---- */
.district-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; }
.district-btn { width: 100%; display: flex; flex-wrap: wrap; justify-content: space-between; gap: 2px 10px; text-align: left; }
.district-btn span { font-size: 0.8125rem; color: var(--surf-soft); }
.town-links { display: flex; flex-wrap: wrap; gap: 8px; }

/* ---- keyboard shortcuts ---- */
.keys-table { width: 100%; border-collapse: collapse; font-size: 1rem; }
.keys-table th, .keys-table td { text-align: left; vertical-align: top; padding: 6px 8px 6px 0; border-top: 1px solid var(--paper-rule); }
.keys-table thead th { font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--paper-soft); }
kbd { font-family: var(--font-pixel); font-size: 0.9375rem; padding: 1px 6px; border: 1px solid var(--paper-ink); border-bottom-width: 2px; white-space: nowrap; }

/* ---- end card style ---- */
.card-styles { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin: 0 0 10px; }
.card-styles-label { font-size: 0.875rem; color: var(--paper-soft); }
.chart-register .card-style[aria-pressed="true"] { background: var(--paper-ink); color: var(--paper-c); }
.chart-register .card-style[aria-pressed="true"]::before { content: "✓ "; }

@media (prefers-reduced-motion: reduce) {
  .order-pin { animation: none; }
}

/* ---- recovery co-funding after a major disaster ---- */
.recovery-note { margin: 0 0 8px; padding: 6px 8px; font-size: 0.875rem; border: 2px dashed var(--surf-line); background: var(--surf); }
.recovery-note::before { content: "½ "; font-weight: 600; }
.card-grant { margin: 0; flex-basis: 100%; font-size: 0.8125rem; }
.choice-grant { color: var(--paper-ink); }

/* ---- turning points: a held moment before a decision, or a warned storm ---- */
.beat { position: absolute; inset: 0; z-index: 40; cursor: pointer; display: grid; align-items: start; justify-items: center; padding-top: calc(var(--hud-h) + 14px); background: linear-gradient(to bottom, rgba(10, 16, 22, 0.35), transparent 45%); }
.beat-card { max-width: min(520px, calc(100% - 24px)); padding: 10px 16px 8px; text-align: center; font-family: var(--font-serif); background: var(--paper-c); color: var(--paper-ink); border: 3px solid var(--paper-ink); outline: 1px solid var(--paper-ink); outline-offset: -7px; box-shadow: 6px 6px 0 rgba(0, 0, 0, 0.35); animation: beat-in 260ms ease-out; }
.beat[data-kind="storm"] .beat-card { border-color: var(--paper-mag); }
.beat-eyebrow { margin: 0; font-size: 0.8125rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--paper-soft); }
.beat-title { margin: 2px 0; font-size: clamp(24px, 6vw, 34px); font-weight: 600; line-height: 1.1; }
.beat-text { margin: 4px 0; font-size: 1.0625rem; line-height: 1.35; }
.beat-skip { margin: 6px 0 0; font-family: var(--font-pixel); font-size: 0.75rem; color: var(--paper-soft); }
@keyframes beat-in { from { opacity: 0; transform: translateY(-8px); } to { opacity: 1; transform: none; } }

/* ---- sheets: decisions and reviews leave the town in view ---- */
.modal-backdrop.is-sheet { place-items: end stretch; padding: 0; background: linear-gradient(to top, rgba(10, 16, 22, 0.55), rgba(10, 16, 22, 0.1) 70%); }
.is-sheet .modal { display: flex; flex-direction: column; overflow: hidden; width: 100%; max-height: 64%; border-left: 0; border-right: 0; border-bottom: 0; animation: sheet-up 220ms ease-out; padding: 16px 16px max(14px, env(safe-area-inset-bottom)); }
@keyframes sheet-up { from { transform: translateY(24px); opacity: 0.4; } to { transform: none; opacity: 1; } }
@media (min-width: 760px) {
  .modal-backdrop.is-sheet { place-items: stretch end; background: linear-gradient(to left, rgba(10, 16, 22, 0.55), rgba(10, 16, 22, 0.05) 55%); }
  .is-sheet .modal { width: min(480px, 40vw); max-height: none; height: 100%; border: 3px solid var(--paper-ink); border-right: 0; border-top: 0; border-bottom: 0; animation-name: sheet-left; padding: 22px 22px 18px; }
  @keyframes sheet-left { from { transform: translateX(24px); opacity: 0.4; } to { transform: none; opacity: 1; } }
  .is-sheet .modal-review { width: min(460px, 38vw); }
}
.is-sheet .modal-title { font-size: clamp(24px, 5vw, 32px); }
.modal-scroll { overflow-y: auto; min-height: 0; overscroll-behavior: contain; }
.is-sheet .modal-close { z-index: 1; }
.decision-route { margin: 0 0 8px; padding: 4px 8px; border-left: 3px solid var(--paper-mag); font-size: 1rem; }
.decision-also { margin: 0 0 8px; font-size: 0.9375rem; }
.choice-impact { font-size: 0.875rem; font-weight: 600; }
.choice-impact::before { content: "◆ "; color: var(--paper-mag); }
.choice-warn { font-size: 0.8438rem; padding: 4px 6px; border: 1px dashed var(--paper-mag); }
.choice-warn::before { content: "! "; font-weight: 600; }

/* ---- the decade review ---- */
.review-table { width: 100%; border-collapse: collapse; font-size: 0.9375rem; margin: 6px 0 4px; }
.review-table th, .review-table td { text-align: right; padding: 4px 0 4px 8px; border-top: 1px solid var(--paper-rule); vertical-align: top; }
.review-table th[scope="row"] { text-align: left; font-weight: 400; padding-left: 0; }
.review-table thead th { font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--paper-soft); border-top: 0; }
.review-table td:nth-child(2), .review-table b { white-space: nowrap; }
.review-note { display: block; font-size: 0.8125rem; color: var(--paper-soft); }
.review-watch { margin: 6px 0 8px; font-size: 1rem; padding: 6px 10px; border: 1px solid var(--paper-ink); display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; }
.review-watch p, .review-also p { margin: 0; flex: 1 1 16rem; }
.review-also { margin: 0 0 8px; font-size: 0.9375rem; padding: 0 10px; display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; }
.chart-register .review-go { flex: none; min-height: 44px; }
.review-foot { position: sticky; bottom: 0; padding: 8px 0 2px; background: var(--paper-c); display: flex; flex-wrap: wrap; gap: 8px 14px; align-items: center; }
.review-toggle { display: inline-flex; align-items: center; gap: 6px; min-height: 44px; font-size: 0.9375rem; cursor: pointer; }
.modal > .sheet-foot { position: static; flex: none; }
.review-check { width: 22px; height: 22px; accent-color: var(--paper-mag); }

@media (prefers-reduced-motion: reduce) {
  .beat-card, .is-sheet .modal { animation: none; }
}

/* phones: while a sheet is up, the caption and the forecast make room for the town */
@media (max-width: 759px) {
  .game:has(> .modal-backdrop.is-sheet) .caption, .game:has(> .modal-backdrop.is-sheet) .mini-fan { display: none; }
  /* The decision: the facts, then the choices as compact rows (their descriptions one tap away), then the
     resident's voice and the route below (playtest 2, #9: only the first choice was above the fold). */
  .decision { display: flex; flex-direction: column; }
  .decision > * { order: 5; }
  .decision > .eyebrow, .decision > .modal-title { order: 0; }
  .decision > .decision-summary { order: 1; display: block; }
  .decision > .decision-facts { margin-top: 10px; }
  .choices:not(.show-what) .choice-note-more { display: none; }
  .decision > .decision-ask { order: 2; margin-top: 4px; }
  .decision > .choices { order: 3; }
  .decision > .decision-also, .decision > .decision-route { margin-top: 10px; }
  .chart-register .what-toggle { display: inline-flex; }
  .choices:not(.show-what) .choice-what { display: none; }
  .choice { padding: 7px 10px; gap: 2px; }
  .choice-name { font-size: 1.0625rem; }
}
/* Desktops: sheets start under the HUD, so the numbers the review talks about stay in view (playtest 2). */
@media (min-width: 760px) {
  .modal-backdrop.is-sheet { top: var(--hud-h); }
}
/* A modal that scrolls inside its frame (the end card): the frame line never cuts through a heading. */
.modal.has-inner { display: flex; flex-direction: column; overflow: hidden; padding: 12px; }
.modal.has-inner > .modal-scroll { padding: 10px 12px 12px; }

/* ---- compact cards: icon, name, cost, a one-line effect and Build; tap the name for the full card ---- */
.cards-expand { justify-self: end; font-size: 0.8125rem; }
.card.is-compact { padding: 6px 8px; gap: 4px; }
.card-row { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 8px; align-items: center; }
.is-compact .card-icon { width: 60px; height: 36px; }
.card-row-text { min-width: 0; display: grid; gap: 1px; }
.is-compact .card-name { font-size: 1rem; }
.card-toggle { display: inline-flex; align-items: center; gap: 6px; min-height: 30px; padding: 0; border: 0; background: none; cursor: pointer; font-weight: 600; text-align: left; text-decoration: underline; text-decoration-style: dotted; text-underline-offset: 3px; }
.card-caret { font-size: 0.75rem; }
/* A 44 px target that only takes 30 px of the row. */
.card-toggle { min-height: 44px; margin: -7px 0; }
.card-row .btn-build, .card-row .card-cancel { flex: none; min-width: 72px; padding: 0 10px; }
.card-sub { margin: 0; font-size: 0.8125rem; color: var(--surf-soft); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Phones: the figures may wrap rather than cut off support, the one that locks players out (playtest 2). */
@media (max-width: 759px) { .card-sub { white-space: normal; } }
.card-note { margin: 0; font-size: 0.8125rem; }
.card-note::before { content: "≈ "; color: var(--warn); font-weight: 600; }
.card-alt { margin: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; font-size: 0.8125rem; }
.card-alt span { flex: 1 1 12rem; }
.is-ordered .card-sub { color: var(--surf-ink); font-weight: 600; }
.card-line { margin: 0; font-family: var(--font-serif); font-size: 0.875rem; line-height: 1.3; }
.card-impact { list-style: none; margin: 0; padding: 0; display: grid; gap: 1px; font-size: 0.8125rem; font-weight: 600; }
.card-impact li::before { content: "◆ "; color: var(--paper-mag); }
/* A closed row shows the two most telling lines; the open card shows them all. */
.card.is-compact:not(.is-open) .card-impact li:nth-child(n + 3) { display: none; }
.card-basis { margin: 0; font-size: 0.75rem; color: var(--surf-soft); font-style: italic; font-family: var(--font-serif); }
.card-warn { margin: 0; font-size: 0.8125rem; color: var(--warn); }
.card-warn::before { content: "! "; font-weight: 600; }
.card-detail { display: grid; gap: 6px; padding-top: 6px; border-top: 1px dashed color-mix(in srgb, var(--surf-ink) 35%, transparent); }
/* Phones: the closed row is icon, name, cost and impact; the one-line effect waits for the open card. */
@media (max-width: 759px) {
  .card.is-compact:not(.is-open) .card-line { display: none; }
  .panel { max-height: min(62%, calc(100% - var(--hud-h) - var(--ctrl-h) - 4px)); }
}

/* ---- small additions: survey notes, Lab status, Town hall ---- */
.survey-list dd.survey-why { font-size: 0.8438rem; font-style: italic; color: var(--paper-soft); margin-top: 2px; }
.lab-status { font-size: 0.8438rem; }
/* chart view on a desktop: the residents speak from the right column, clear of the map */
@media (min-width: 760px) {
  .game[data-view="chart"] .toasts { left: auto; right: 12px; bottom: 96px; width: min(330px, calc(100% - 24px)); }
}
.hud-more { display: none; }
@media (min-width: 760px) { .hud-more { display: inline; } }

/* ---- phones: the chart scrolls (taller than the screen) ---- */
.chart-wrap.is-scroll { overflow-y: auto; overscroll-behavior: contain; }
.chart-wrap.is-scroll .game-chart { touch-action: pan-y; }
.game[data-view="chart"] .order-pin.is-floating { top: auto !important; bottom: calc(var(--ctrl-h) + 12px); transform: translateX(-50%); }
@media (min-width: 760px) { .game[data-view="chart"] .order-pin.is-floating { bottom: 96px; } }
/* Narrow phones: the four controls stay on one row. */
@media (max-width: 420px) {
  .ctrl { font-size: 0.875rem; gap: 4px; padding: 0 4px; }
}
@media (max-width: 420px) { .ctrl-town .ctrl-glyph, .ctrl-view .ctrl-glyph { display: none; } }

/* ---- HUD: support and homes explain themselves on tap ---- */
.hud { position: absolute; }
.hud-explain { cursor: pointer; }
.hud-explain:hover .hud-label { text-decoration: underline dotted; }
.hud-pop { position: absolute; right: 8px; top: calc(100% + 6px); z-index: 8; width: min(420px, calc(100% - 16px)); margin: 0; padding: 8px 10px; font-family: var(--font-serif); font-size: 0.9375rem; line-height: 1.4; background: var(--surf); color: var(--surf-ink); border: 2px solid var(--surf-line); box-shadow: 3px 3px 0 var(--surf-shadow); }
@media (max-width: 759px) { .card.is-compact:not(.is-open) .card-impact li:nth-child(n + 2) { display: none; } }
