/* ==========================================================================
   INTERRAIL SIMULATOR - UI DESIGN SYSTEM
   Vintage rail-ticket / departure-board look: cream paper, navy ink, Interrail red, gold.
   Everything is sized in rem (the root font-size scales with the viewport), so it works
   from 800x600 up to 2560x1440.  Catalogue + copy-pasteable snippets: docs/UI-COMPONENTS.md
   ========================================================================== */

/* ---------- 1. tokens ------------------------------------------------------ */
:root {
  --ink: #14213d;  --ink-2: #22315a;  --ink-3: #3a4b78;
  --ink-soft: #46536f;                 /* secondary text on paper (AA)   */
  --ink-mute: #5c6784;                 /* tertiary text on paper  (AA)   */
  --paper: #f6efe0; --paper-hi: #fcf8ee; --paper-2: #eee4cc; --paper-3: #e1d3ae; --paper-edge: #c9ba92;
  --red: #c8102e;  --red-dark: #98091f;  --red-soft: #f7d9dd;
  --gold: #f2a900; --gold-hi: #ffc93a;   --gold-dark: #b57c00; --gold-text: #85590a; --gold-soft: #fbe6a4;
  --green: #2e7d4f; --green-dark: #1e5c39; --green-soft: #d2ead9;
  --blue: #2b5f9e;  --blue-dark: #1d4574;  --blue-soft: #d5e3f4;
  --orange: #c2620f; --orange-soft: #f6dcc0;
  --board: #11141b; --board-2: #1a1f2a; --amber: #ffc94d;
  --hud-bg: rgba(15, 26, 50, 0.95);
  --focus: var(--gold-hi);

  --sans: 'Segoe UI', system-ui, -apple-system, 'Helvetica Neue', Roboto, Arial, sans-serif;
  --mono: ui-monospace, 'Cascadia Mono', 'SF Mono', Consolas, 'Liberation Mono', Menlo, monospace;
  --serif: Georgia, 'Iowan Old Style', 'Palatino Linotype', Palatino, serif;

  --r-sm: 0.35rem; --r: 0.6rem; --r-lg: 0.9rem;
  --shadow-1: 0 1px 2px rgba(8, 14, 32, .25), 0 2px 6px rgba(8, 14, 32, .18);
  --shadow-2: 0 4px 10px rgba(8, 14, 32, .25), 0 10px 26px rgba(8, 14, 32, .28);
  --shadow-3: 0 10px 22px rgba(8, 14, 32, .3), 0 26px 60px rgba(8, 14, 32, .45);
  --ease: cubic-bezier(.2, .8, .2, 1);
  --spring: cubic-bezier(.2, .9, .3, 1.25);

  --hud-h: 0px;      /* height taken by the top HUD (set through body[data-hud]); full-screen panels pad by it */
  --bite: 0.6rem;    /* radius of the perforation notches */
}
body[data-hud="full"]    { --hud-h: 3.85rem; }
body[data-hud="compact"] { --hud-h: 3.3rem; }

/* ---------- 2. base (ids the engine relies on: #gl #ui-root #fade #loading) ---------- */
* { box-sizing: border-box; }
html { font-size: clamp(14px, calc(0.35vw + 0.7vh + 6.5px), 28px); }
html, body { margin: 0; height: 100%; background: #0b1020; overflow: hidden; font-family: var(--sans); color: #fff; -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; }
button, input, select, textarea { font: inherit; color: inherit; }
button { -webkit-tap-highlight-color: transparent; }
::selection { background: var(--gold); color: var(--ink); }
#gl { position: fixed; inset: 0; width: 100%; height: 100%; display: block; outline: none; }
#ui-root { position: fixed; inset: 0; pointer-events: none; user-select: none; -webkit-user-select: none; }
#ui-root > * { pointer-events: auto; }
#fade { position: fixed; inset: 0; background: #000; opacity: 0; pointer-events: none; transition: opacity 0.3s ease; z-index: 9000; }
#loading { position: fixed; inset: 0; z-index: 9500; display: grid; place-items: center; background: radial-gradient(ellipse at 50% 40%, #22346a, #0b1020 75%); transition: opacity 0.6s ease; }
#loading.hidden { opacity: 0; pointer-events: none; }
.loading-card { position: relative; text-align: center; padding: 2.2rem 3.4rem 1.9rem; color: var(--ink); filter: drop-shadow(0 12px 30px rgba(0, 0, 0, .5));
  background:
    radial-gradient(circle 0.7rem at 0 50%, #0000 calc(0.7rem - 1px), var(--paper) 0.7rem) left / 51% 100% no-repeat,
    radial-gradient(circle 0.7rem at 100% 50%, #0000 calc(0.7rem - 1px), var(--paper) 0.7rem) right / 51% 100% no-repeat;
  border-radius: 0.8rem; }
.loading-card::before { content: ''; position: absolute; inset: 0.45rem 1.4rem; border: 2px dashed rgba(20, 33, 61, .25); border-radius: 0.5rem; pointer-events: none; }
.loading-logo { font-size: 2.7rem; font-weight: 900; letter-spacing: 0.22em; color: var(--red); margin-right: -0.22em; }
.loading-sub { margin-top: 0.15rem; letter-spacing: 0.62em; margin-right: -0.62em; font-size: 0.85rem; font-weight: 700; color: var(--ink); }
.loading-bar { margin: 1.4rem auto 0; width: 13rem; height: 0.3rem; background: rgba(20, 33, 61, .18); border-radius: 4px; overflow: hidden; }
.loading-bar i { display: block; height: 100%; width: 40%; background: var(--red); animation: load 1.1s ease-in-out infinite; }
@keyframes load { 0% { transform: translateX(-100%); } 100% { transform: translateX(350%); } }

/* keyboard-friendly focus rings (visible for keyboard users only) */
:focus { outline: none; }
:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; border-radius: 0.3rem; }
.modal, .panel, .card, .ticket, .banner-card, .toast { --focus: #1f5fd6; }
.on-dark, .on-dark :focus-visible { --focus: var(--gold-hi); }
canvas:focus-visible { outline: none; }
/* touch: no focus ring while the player is using fingers (UI.js sets body[data-input]); a keyboard (Tab / arrows / Enter / Space) brings it back.  Text fields keep theirs. */
body.touch-ui[data-input="pointer"] :focus-visible:not(input[type="text"], input[type="search"], input[type="number"], input[type="email"], textarea) { outline: none !important; }
body.touch-ui[data-input="pointer"] .seg input:focus-visible + span { outline: none !important; }
body.touch-ui[data-input="pointer"] [data-tip]:focus-visible::after { opacity: 0 !important; }

/* ---------- 3. typography & utilities ------------------------------------- */
.h1, .h2, .h3, .eyebrow, .label { margin: 0; }
.h1 { font: 900 1.9rem/1.1 var(--sans); letter-spacing: 0.04em; text-transform: uppercase; }
.h2 { font: 800 1.25rem/1.15 var(--sans); letter-spacing: 0.03em; }
.h3 { font: 800 1rem/1.2 var(--sans); letter-spacing: 0.02em; }
.eyebrow { font: 800 0.68rem/1.2 var(--sans); letter-spacing: 0.2em; text-transform: uppercase; color: var(--gold-text); }
.on-dark .eyebrow, .modal-head .eyebrow { color: var(--gold-hi); }
.label { font: 800 0.68rem/1.2 var(--sans); letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-soft); }
.serif { font-family: var(--serif); font-style: italic; }
.mono { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.num  { font-family: var(--mono); font-variant-numeric: tabular-nums; font-weight: 700; }
.muted { color: var(--ink-mute); }
.on-dark { color: var(--paper); }
.on-dark .muted { color: rgba(246, 239, 224, .68); }
.small { font-size: 0.82rem; }
.tiny { font-size: 0.7rem; }
.caps { text-transform: uppercase; letter-spacing: 0.12em; }
.bold { font-weight: 800; }
.nowrap { white-space: nowrap; }
.ellipsis { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.center { text-align: center; } .right { text-align: right; }
.good { color: var(--green-dark); } .bad { color: var(--red); } .warn { color: var(--orange); } .gold { color: var(--gold-text); }
.on-dark .good { color: #7fdca2; } .on-dark .bad { color: #ff8c9c; } .on-dark .warn { color: #ffbe73; } .on-dark .gold { color: var(--gold-hi); }
.hidden { display: none !important; }
.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.selectable, .selectable * { user-select: text; -webkit-user-select: text; }
.row { display: flex; align-items: center; gap: 0.6rem; } .col { display: flex; flex-direction: column; gap: 0.6rem; }
.wrap { flex-wrap: wrap; } .grow { flex: 1 1 auto; min-width: 0; } .between { justify-content: space-between; } .end { justify-content: flex-end; } .top { align-items: flex-start; } .baseline { align-items: baseline; }
.gap-1 { gap: 0.25rem; } .gap-2 { gap: 0.5rem; } .gap-3 { gap: 0.9rem; } .gap-4 { gap: 1.4rem; }
.mt-1 { margin-top: 0.3rem; } .mt-2 { margin-top: 0.6rem; } .mt-3 { margin-top: 1rem; } .mb-1 { margin-bottom: 0.3rem; } .mb-2 { margin-bottom: 0.6rem; } .mb-3 { margin-bottom: 1rem; }
.p-2 { padding: 0.6rem; } .p-3 { padding: 1rem; }
.grid-2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); gap: 0.7rem; }
.grid-3 { display: grid; grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr)); gap: 0.7rem; }
hr, .divider { border: 0; height: 0; border-top: 2px dashed rgba(20, 33, 61, .22); margin: 0.9rem 0; }
.on-dark hr, .on-dark .divider { border-top-color: rgba(246, 239, 224, .25); }
.rule-gold { height: 0.2rem; border: 0; background: var(--gold); margin: 0.6rem 0; border-radius: 2px; }
p { margin: 0 0 0.7rem; line-height: 1.5; } p:last-child { margin-bottom: 0; }

/* ---------- 4. icons -------------------------------------------------------- */
.ico { display: inline-flex; flex: none; width: var(--ico, 1.15em); height: var(--ico, 1.15em); vertical-align: -0.2em; }
.ico svg { width: 100%; height: 100%; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
.ico-fill svg { fill: currentColor; stroke: none; }

/* ---------- 5. tooltips: data-tip="text" (\n for line breaks), data-tip-pos=top|bottom|left|right|bottom-end|bottom-start ---------- */
[data-tip] { position: relative; }
[data-tip]::after {
  content: attr(data-tip); position: absolute; z-index: 500; left: 50%; bottom: calc(100% + 0.5rem); transform: translate(-50%, 4px);
  width: max-content; max-width: 17rem; padding: 0.45rem 0.7rem; border-radius: 0.45rem; text-align: left;
  background: var(--ink); color: var(--paper); box-shadow: 0 6px 16px rgba(0, 0, 0, .35), 0 0 0 1px rgba(246, 239, 224, .15);
  font: 600 0.78rem/1.4 var(--sans); letter-spacing: 0; text-transform: none; white-space: pre-line;
  opacity: 0; pointer-events: none; transition: opacity 0.12s ease, transform 0.12s ease; }
[data-tip]:hover::after, [data-tip]:focus-visible::after { opacity: 1; transform: translate(-50%, 0); transition-delay: 0.25s; }
[data-tip-pos="bottom"]::after { bottom: auto; top: calc(100% + 0.5rem); transform: translate(-50%, -4px); }
[data-tip-pos="bottom"]:hover::after, [data-tip-pos="bottom"]:focus-visible::after { transform: translate(-50%, 0); }
[data-tip-pos="bottom-end"]::after { bottom: auto; top: calc(100% + 0.5rem); left: auto; right: 0; transform: translate(0, -4px); }
[data-tip-pos="bottom-end"]:hover::after, [data-tip-pos="bottom-end"]:focus-visible::after { transform: none; }
[data-tip-pos="bottom-start"]::after { bottom: auto; top: calc(100% + 0.5rem); left: 0; transform: translate(0, -4px); }
[data-tip-pos="bottom-start"]:hover::after, [data-tip-pos="bottom-start"]:focus-visible::after { transform: none; }
[data-tip-pos="right"]::after { bottom: auto; left: calc(100% + 0.5rem); top: 50%; transform: translate(-4px, -50%); }
[data-tip-pos="right"]:hover::after, [data-tip-pos="right"]:focus-visible::after { transform: translate(0, -50%); }
[data-tip-pos="left"]::after { bottom: auto; left: auto; right: calc(100% + 0.5rem); top: 50%; transform: translate(4px, -50%); }
[data-tip-pos="left"]:hover::after, [data-tip-pos="left"]:focus-visible::after { transform: translate(0, -50%); }

/* ---------- 6. buttons: .btn  .btn-primary  .btn-gold  .btn-dark  .btn-danger  .btn-ghost  (+ .btn-sm .btn-lg .btn-block .btn-icon) ---------- */
.btn {
  --b-bg: var(--paper-hi); --b-fg: var(--ink); --b-bd: var(--ink); --b-sh: rgba(20, 33, 61, .38);
  position: relative; display: inline-flex; align-items: center; justify-content: center; gap: 0.5em;
  min-height: 2.5rem; padding: 0.45rem 1.15rem; margin: 0;
  font: 800 0.9rem/1.15 var(--sans); letter-spacing: 0.04em; text-decoration: none; text-align: center; white-space: nowrap;
  color: var(--b-fg); background: var(--b-bg); border: 2px solid var(--b-bd); border-radius: var(--r);
  box-shadow: 0 3px 0 var(--b-sh); cursor: pointer; user-select: none; -webkit-user-select: none;
  transition: transform 0.08s ease, box-shadow 0.08s ease, background-color 0.15s ease, filter 0.15s ease; }
.btn:hover:not(:disabled):not([aria-disabled="true"]) { transform: translateY(-1px); box-shadow: 0 4px 0 var(--b-sh); background: #fff; }
.btn:active:not(:disabled):not([aria-disabled="true"]) { transform: translateY(2px); box-shadow: 0 1px 0 var(--b-sh); }
.btn:disabled, .btn[aria-disabled="true"] { opacity: 0.5; cursor: not-allowed; filter: saturate(0.5); box-shadow: 0 2px 0 var(--b-sh); }
.btn-primary { --b-bg: var(--red); --b-fg: #fff8ee; --b-bd: var(--red-dark); --b-sh: var(--red-dark); }
.btn-primary:hover:not(:disabled):not([aria-disabled="true"]) { background: #d9173a; }
.btn-gold { --b-bg: var(--gold); --b-fg: var(--ink); --b-bd: var(--gold-dark); --b-sh: var(--gold-dark); }
.btn-gold:hover:not(:disabled):not([aria-disabled="true"]) { background: var(--gold-hi); }
.btn-dark { --b-bg: var(--ink-2); --b-fg: var(--paper); --b-bd: #0b1428; --b-sh: #0b1428; }
.btn-dark:hover:not(:disabled):not([aria-disabled="true"]) { background: var(--ink-3); }
.btn-danger { --b-bg: transparent; --b-fg: var(--red-dark); --b-bd: var(--red); --b-sh: rgba(200, 16, 46, .4); }
.btn-danger:hover:not(:disabled):not([aria-disabled="true"]) { background: var(--red-soft); }
.btn-ghost { --b-bg: transparent; --b-fg: var(--ink); --b-bd: transparent; --b-sh: transparent; }
.btn-ghost:hover:not(:disabled):not([aria-disabled="true"]) { background: rgba(20, 33, 61, .09); box-shadow: none; transform: none; }
.on-dark .btn-ghost { --b-fg: var(--paper); } .on-dark .btn-ghost:hover:not(:disabled) { background: rgba(246, 239, 224, .14); }
.btn-sm { min-height: 2rem; padding: 0.25rem 0.75rem; font-size: 0.78rem; border-radius: var(--r-sm); }
.btn-lg { min-height: 3.2rem; padding: 0.6rem 1.7rem; font-size: 1.05rem; }
.btn-block { display: flex; width: 100%; }
.btn-icon { min-width: 2.5rem; padding: 0.4rem; } .btn-icon.btn-sm { min-width: 2rem; padding: 0.25rem; }
.btn .kbd { margin-left: 0.15rem; }
.btn-hint { font: 600 0.72rem var(--mono); letter-spacing: 0; opacity: 0.85; text-transform: none; }

/* ---------- 7. panels & cards: .panel(.panel-head .panel-body .panel-foot)  .panel-dark  .card ---------- */
.panel { position: relative; color: var(--ink); background: linear-gradient(180deg, var(--paper-hi), var(--paper) 35%); border-radius: var(--r-lg); box-shadow: 0 0 0 1px rgba(20, 33, 61, .2), var(--shadow-2); }
.panel::before { content: ''; position: absolute; inset: 0.3rem; border: 1px dashed rgba(20, 33, 61, .2); border-radius: calc(var(--r-lg) - 0.25rem); pointer-events: none; }
.panel-head { position: relative; display: flex; align-items: center; gap: 0.6rem; padding: 0.7rem 1rem; color: var(--paper); background: var(--ink); border-radius: var(--r-lg) var(--r-lg) 0 0;
  font: 800 0.78rem/1.2 var(--sans); letter-spacing: 0.16em; text-transform: uppercase; box-shadow: inset 0 -3px 0 var(--gold); }
.panel-body { position: relative; padding: 1rem 1.1rem; }
.panel-foot { position: relative; display: flex; align-items: center; justify-content: flex-end; gap: 0.6rem; padding: 0.75rem 1rem; border-top: 2px dashed rgba(20, 33, 61, .2); }
.panel-dark { color: var(--paper); background: linear-gradient(180deg, #1d2d57, #14213d 60%); box-shadow: 0 0 0 1px rgba(246, 239, 224, .14), var(--shadow-2); --focus: var(--gold-hi); }
.panel-dark::before { border-color: rgba(246, 239, 224, .16); }
.panel-dark .panel-head { background: #0e182f; }
.panel-dark .label { color: rgba(246, 239, 224, .7); } .panel-dark .muted { color: rgba(246, 239, 224, .68); }
.panel-dark .card { color: var(--ink); }
.panel-flush .panel-body { padding: 0; }
.panel-scroll { overflow: auto; min-height: 0; }

.card { position: relative; display: block; width: 100%; text-align: left; color: var(--ink); padding: 0.75rem 0.9rem; background: var(--paper-hi); border: 1.5px solid rgba(20, 33, 61, .24); border-radius: var(--r); box-shadow: 0 2px 0 rgba(20, 33, 61, .14); font: inherit; }
button.card, a.card { cursor: pointer; transition: transform 0.1s ease, border-color 0.15s, box-shadow 0.15s, background 0.15s; }
.card-hover:hover, button.card:hover, a.card:hover { border-color: var(--ink); transform: translateY(-1px); box-shadow: 0 4px 0 rgba(20, 33, 61, .2); background: #fff; }
.card.selected, .card[aria-pressed="true"], .card[aria-selected="true"] { border-color: var(--red); box-shadow: 0 0 0 2px var(--red), 0 3px 0 rgba(200, 16, 46, .25); background: #fff; }
.card.is-disabled, .card[aria-disabled="true"] { opacity: 0.55; cursor: not-allowed; }
.card-title { font: 800 1rem/1.2 var(--sans); margin: 0 0 0.15rem; }
.card-meta { font-size: 0.82rem; color: var(--ink-soft); }
.card-flat { box-shadow: none; }
.callout { display: flex; gap: 0.6rem; align-items: flex-start; padding: 0.6rem 0.8rem; border-radius: var(--r); background: var(--gold-soft); border: 1.5px solid var(--gold-dark); color: var(--ink); font-size: 0.88rem; line-height: 1.4; }
.callout-info { background: var(--blue-soft); border-color: var(--blue); }
.callout-bad { background: var(--red-soft); border-color: var(--red); }
.callout-good { background: var(--green-soft); border-color: var(--green); }
.empty { padding: 1.4rem 1rem; text-align: center; color: var(--ink-mute); border: 2px dashed rgba(20, 33, 61, .25); border-radius: var(--r); font-size: 0.92rem; }

/* ---------- 8. tabs: .tabs > .tab[aria-selected] + .tab-panel ---------- */
.tabs { display: flex; gap: 0.25rem; padding: 0 0.3rem; border-bottom: 2px solid var(--ink); overflow-x: auto; scrollbar-width: none; }
.tab { position: relative; appearance: none; margin: 0 0 -2px; padding: 0.55rem 1rem 0.5rem; cursor: pointer; white-space: nowrap;
  font: 800 0.74rem/1.1 var(--sans); letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-soft); background: var(--paper-2);
  border: 2px solid rgba(20, 33, 61, .28); border-bottom: 2px solid var(--ink); border-radius: 0.55rem 0.55rem 0 0; transition: background 0.15s, color 0.15s; }
.tab:hover { background: var(--paper-hi); color: var(--ink); }
.tab[aria-selected="true"] { color: var(--ink); background: var(--paper-hi); border-color: var(--ink); border-bottom-color: var(--paper-hi); box-shadow: inset 0 3px 0 var(--red); }
.tab .badge { margin-left: 0.4rem; }
.tab-panel { padding-top: 0.9rem; }
.tabs-dark { border-bottom-color: rgba(246, 239, 224, .5); }

/* ---------- 9. chips, badges, tag colours ---------- */
.chip { display: inline-flex; align-items: center; gap: 0.3em; padding: 0.1rem 0.6rem; border-radius: 99px; white-space: nowrap; vertical-align: middle;
  font: 700 0.68rem/1.6 var(--mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink); background: var(--paper-3); border: 1px solid rgba(20, 33, 61, .28); }
.chip-red { background: var(--red); color: #fff8ee; border-color: var(--red-dark); }
.chip-gold { background: var(--gold); color: var(--ink); border-color: var(--gold-dark); }
.chip-navy { background: var(--ink); color: var(--paper); border-color: #0b1428; }
.chip-green { background: var(--green-soft); color: var(--green-dark); border-color: var(--green); }
.chip-blue { background: var(--blue-soft); color: var(--blue-dark); border-color: var(--blue); }
.chip-orange { background: var(--orange-soft); color: #7d3d05; border-color: var(--orange); }
.chip-grey { background: rgba(20, 33, 61, .08); color: var(--ink-soft); }
.chip-outline { background: transparent; border-color: currentColor; }
button.chip { cursor: pointer; } button.chip:hover { filter: brightness(1.06); } button.chip[aria-pressed="true"] { background: var(--ink); color: var(--paper); }
.badge { display: inline-grid; place-items: center; min-width: 1.4rem; height: 1.4rem; padding: 0 0.35rem; border-radius: 99px; font: 800 0.7rem/1 var(--mono); background: var(--red); color: #fff8ee; }
/* semantic tag colours: <span class="chip" data-kind="HS">  (train classes, log kinds, sight/landmark kinds, toast kinds) */
.chip[data-kind="HS"] { background: var(--red); color: #fff8ee; border-color: var(--red-dark); }
.chip[data-kind="IC"] { background: var(--ink); color: var(--paper); border-color: #0b1428; }
.chip[data-kind="EC"] { background: var(--blue); color: #fff; border-color: var(--blue-dark); }
.chip[data-kind="REG"] { background: var(--green-soft); color: var(--green-dark); border-color: var(--green); }
.chip[data-kind="NIGHT"] { background: #2a2f63; color: var(--gold-hi); border-color: #171a3d; }
.chip[data-kind="system"], .chip[data-kind="info"] { background: var(--paper-3); color: var(--ink-soft); }
.chip[data-kind="pass"] { background: var(--gold); color: var(--ink); border-color: var(--gold-dark); }
.chip[data-kind="booking"] { background: var(--blue-soft); color: var(--blue-dark); border-color: var(--blue); }
.chip[data-kind="trip"] { background: var(--ink); color: var(--paper); border-color: #0b1428; }
.chip[data-kind="warn"] { background: var(--orange-soft); color: #7d3d05; border-color: var(--orange); }
.chip[data-kind="bad"] { background: var(--red-soft); color: var(--red-dark); border-color: var(--red); }
.chip[data-kind="good"] { background: var(--green-soft); color: var(--green-dark); border-color: var(--green); }
.chip[data-kind="city"] { background: var(--blue-soft); color: var(--blue-dark); border-color: var(--blue); }
.chip[data-kind="landmark"] { background: var(--gold-soft); color: var(--gold-text); border-color: var(--gold-dark); }
.chip[data-kind="scenic"] { background: var(--green-soft); color: var(--green-dark); border-color: var(--green); }
.chip[data-kind="achievement"] { background: var(--gold); color: var(--ink); border-color: var(--gold-dark); }

/* ---------- 10. key caps: <kbd class="kbd">E</kbd> ---------- */
.kbd { display: inline-grid; place-items: center; min-width: 1.75em; height: 1.75em; padding: 0 0.45em; margin: 0 0.1em; vertical-align: middle;
  font: 800 0.76em/1 var(--mono); letter-spacing: 0; text-transform: none; color: var(--ink);
  background: linear-gradient(180deg, #fffaf0, #eee2c4); border: 1px solid rgba(20, 33, 61, .55); border-bottom-width: 3px; border-radius: 0.4em; box-shadow: inset 0 1px 0 rgba(255, 255, 255, .7); }
.kbd-sm { font-size: 0.68em; }

/* ---------- 11. tables, boards, key/value lists ---------- */
.table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 0.9rem; color: var(--ink); }
.table th { position: sticky; top: 0; z-index: 1; padding: 0.5rem 0.7rem; text-align: left; white-space: nowrap; color: var(--paper); background: var(--ink); font: 800 0.68rem/1.2 var(--sans); letter-spacing: 0.13em; text-transform: uppercase; }
.table th:first-child { border-radius: var(--r-sm) 0 0 0; } .table th:last-child { border-radius: 0 var(--r-sm) 0 0; }
.table td { padding: 0.5rem 0.7rem; border-bottom: 1px dashed rgba(20, 33, 61, .28); vertical-align: middle; }
.table tbody tr { transition: background 0.12s; }
.table tbody tr:hover td { background: rgba(242, 169, 0, .16); }
.table-zebra tbody tr:nth-child(even) td { background: rgba(20, 33, 61, .045); }
.table tr.selected td { background: var(--gold-soft); box-shadow: inset 0 0 0 0 transparent; }
.table tr.selected td:first-child { box-shadow: inset 4px 0 0 var(--red); }
.table tr.is-clickable { cursor: pointer; }
.table td.num, .table th.num { text-align: right; }
.board { padding: 0.5rem 0.7rem 0.7rem; color: var(--amber); background: var(--board); border-radius: var(--r); font-family: var(--mono); box-shadow: inset 0 0 0 2px #2a303d, var(--shadow-2); }
.board table { width: 100%; border-collapse: collapse; font-size: 0.95rem; }
.board th { padding: 0.35rem 0.5rem; text-align: left; color: rgba(255, 201, 77, .55); font: 700 0.66rem/1 var(--mono); letter-spacing: 0.16em; text-transform: uppercase; border-bottom: 1px solid #2a303d; }
.board td { padding: 0.42rem 0.5rem; border-bottom: 1px solid rgba(255, 255, 255, .06); font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; }
.board tr.selected td { background: rgba(255, 201, 77, .13); }
.board .ok { color: #7be0a2; } .board .late { color: #ff8b5e; } .board .boarding { color: #fff; animation: blink 1.1s steps(2, jump-none) infinite; } .board .gone { color: rgba(255, 201, 77, .35); text-decoration: line-through; }
@keyframes blink { 50% { opacity: 0.25; } }
.kv { margin: 0; display: grid; gap: 0.35rem; }
.kv > div { display: flex; align-items: baseline; gap: 0.5rem; }
.kv dt { display: flex; flex: 1 1 auto; align-items: baseline; min-width: 0; color: var(--ink-soft); font-size: 0.86rem; }
.kv dt::after { content: ''; flex: 1 1 1rem; margin: 0 0.4rem; border-bottom: 2px dotted rgba(20, 33, 61, .3); transform: translateY(-0.2em); }
.kv dd { margin: 0; font: 800 0.95rem var(--mono); font-variant-numeric: tabular-nums; text-align: right; }
.list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.4rem; }
.list-row { display: flex; align-items: center; gap: 0.7rem; padding: 0.55rem 0.8rem; background: var(--paper-hi); border: 1.5px solid rgba(20, 33, 61, .2); border-radius: var(--r); }
.stat { display: grid; gap: 0.15rem; text-align: center; }
.stat-num { font: 900 1.8rem/1 var(--mono); font-variant-numeric: tabular-nums; color: var(--ink); }
.stat-lbl { font: 800 0.62rem/1.2 var(--sans); letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-soft); }

/* ---------- 12. split-flap text: <span class="flap"><i>1</i><i>2</i><i class="sep">:</i>...</span>  (helper: flap()/setFlap() in UI.js) ---------- */
.flap { display: inline-flex; gap: 0.12em; align-items: center; font: 800 1.4rem/1 var(--mono); perspective: 320px; --flap-fg: #f6efe0; }
.flap > i { position: relative; display: inline-grid; place-items: center; width: 0.8em; height: 1.28em; overflow: hidden; font-style: normal; color: var(--flap-fg); text-shadow: 0 1px 0 rgba(0, 0, 0, .6);
  border-radius: 0.14em; background: linear-gradient(180deg, #2a2f3d 0 49.5%, #0e1118 50.5% 100%); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .07), 0 1px 0 rgba(0, 0, 0, .55); }
.flap > i::after { content: ''; position: absolute; left: 0; right: 0; top: 50%; height: 1px; background: rgba(0, 0, 0, .8); box-shadow: 0 1px 0 rgba(255, 255, 255, .08); }
.flap > i.sep { width: 0.42em; background: none; box-shadow: none; color: var(--flap-sep, var(--gold-hi)); text-shadow: none; overflow: visible; }
.flap > i.sep::after { display: none; }
.flap > i.flip { animation: flap-flip 0.34s ease-in-out; }
.flap-sm { font-size: 1rem; } .flap-lg { font-size: 2.2rem; } .flap-xl { font-size: 3.2rem; }
.flap-gold { --flap-fg: var(--gold-hi); }
.flap-light { --flap-fg: var(--ink); --flap-sep: var(--red); }
.flap-light > i { background: linear-gradient(180deg, #fffaf0 0 49.5%, #e9dcbc 50.5% 100%); text-shadow: none; box-shadow: inset 0 0 0 1px rgba(20, 33, 61, .3), 0 1px 0 rgba(20, 33, 61, .25); }
.flap-light > i::after { background: rgba(20, 33, 61, .5); box-shadow: none; }
.flap-cur { margin-right: 0.3em; color: var(--gold-hi); font-weight: 900; }
@keyframes flap-flip { 0% { transform: rotateX(0); } 45% { transform: rotateX(-88deg); } 55% { transform: rotateX(88deg); } 100% { transform: rotateX(0); } }

/* ---------- 13. bars & progress: <div class="bar bar-energy" style="--v:70"><i></i></div>  (.low = pulsing red) ---------- */
.bar { --v: 50; position: relative; height: 0.5rem; overflow: hidden; border-radius: 99px; background: rgba(20, 33, 61, .18); box-shadow: inset 0 1px 2px rgba(0, 0, 0, .28); }
.bar > i { display: block; width: calc(var(--v) * 1%); height: 100%; border-radius: inherit; background: var(--bar, var(--green)); transition: width 0.45s var(--ease), background-color 0.3s; }
.bar-lg { height: 0.8rem; } .bar-sm { height: 0.35rem; }
.bar-energy { --bar: #f5b82e; } .bar-hunger { --bar: #ee8353; } .bar-mood { --bar: #58c790; } .bar-red { --bar: var(--red); } .bar-gold { --bar: var(--gold); } .bar-green { --bar: var(--green); } .bar-navy { --bar: var(--ink); }
.bar.low > i { --bar: #ff4d5f; animation: pulse-bar 1s ease-in-out infinite; }
.on-dark .bar, .hud .bar { background: rgba(246, 239, 224, .17); }
.pips { display: inline-flex; flex-wrap: wrap; gap: 0.2rem; }
.pips > i { width: 0.8rem; height: 0.8rem; border-radius: 0.2rem; border: 1.5px solid var(--ink); background: transparent; }
.pips > i.on { background: var(--red); border-color: var(--red-dark); } .pips > i.gold { background: var(--gold); border-color: var(--gold-dark); }
@keyframes pulse-bar { 50% { filter: brightness(1.5); } }
.spinner { width: 1.4rem; height: 1.4rem; border-radius: 50%; border: 3px solid rgba(20, 33, 61, .2); border-top-color: var(--red); animation: spin 0.8s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

/* ---------- 14. form controls: .field .label .input .select .textarea .switch .range .seg ---------- */
.field { display: grid; gap: 0.3rem; }
.hint { font-size: 0.8rem; color: var(--ink-mute); line-height: 1.35; }
.input, .select, .textarea { width: 100%; padding: 0.55rem 0.8rem; color: var(--ink); font: 600 1rem var(--sans); background: var(--paper-hi); border: 2px solid var(--ink); border-radius: var(--r-sm); box-shadow: inset 0 2px 0 rgba(20, 33, 61, .08); }
.input::placeholder, .textarea::placeholder { color: var(--ink-mute); font-weight: 500; }
.input:focus-visible, .select:focus-visible, .textarea:focus-visible { outline: 3px solid var(--focus); outline-offset: 1px; }
.textarea { min-height: 5rem; resize: vertical; }
.select { appearance: none; padding-right: 2.2rem; cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5l5 5 5-5' fill='none' stroke='%2314213d' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 0.8rem center; background-size: 0.8rem; }
input.switch { appearance: none; -webkit-appearance: none; position: relative; flex: none; width: 3rem; height: 1.6rem; margin: 0; cursor: pointer; border-radius: 99px; background: var(--paper-3); border: 2px solid var(--ink); transition: background 0.18s; }
input.switch::after { content: ''; position: absolute; top: 50%; left: 0.18rem; width: 1rem; height: 1rem; margin-top: -0.5rem; border-radius: 50%; background: var(--ink); transition: transform 0.2s var(--spring), background 0.18s; }
input.switch:checked { background: var(--green); border-color: var(--green-dark); }
input.switch:checked::after { transform: translateX(1.4rem); background: var(--paper-hi); }
input.switch:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; border-radius: 99px; }
input.range { --v: 50%; -webkit-appearance: none; appearance: none; width: 100%; height: 1.7rem; margin: 0; background: transparent; cursor: pointer; }
input.range::-webkit-slider-runnable-track { height: 0.55rem; border-radius: 99px; background: linear-gradient(90deg, var(--red) var(--v), var(--paper-3) var(--v)); box-shadow: inset 0 1px 2px rgba(0, 0, 0, .3); }
input.range::-webkit-slider-thumb { -webkit-appearance: none; width: 1.3rem; height: 1.3rem; margin-top: -0.4rem; border-radius: 50%; background: var(--paper-hi); border: 3px solid var(--ink); box-shadow: 0 2px 0 rgba(20, 33, 61, .35); transition: transform 0.1s; }
input.range:hover::-webkit-slider-thumb { transform: scale(1.1); }
input.range::-moz-range-track { height: 0.55rem; border-radius: 99px; background: var(--paper-3); }
input.range::-moz-range-progress { height: 0.55rem; border-radius: 99px; background: var(--red); }
input.range::-moz-range-thumb { width: 1rem; height: 1rem; border-radius: 50%; background: var(--paper-hi); border: 3px solid var(--ink); }
input.range:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; border-radius: 99px; }
.seg { display: inline-flex; padding: 0.2rem; gap: 0.15rem; background: var(--paper-3); border: 2px solid var(--ink); border-radius: var(--r); }
.seg label { position: relative; display: block; cursor: pointer; }
.seg input { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; }
.seg span { display: block; padding: 0.35rem 0.85rem; border-radius: calc(var(--r) - 0.2rem); font: 800 0.78rem/1.2 var(--sans); letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-soft); transition: background 0.15s, color 0.15s; }
.seg input:hover + span { color: var(--ink); background: rgba(255, 255, 255, .5); }
.seg input:checked + span { background: var(--ink); color: var(--paper); box-shadow: 0 2px 0 rgba(0, 0, 0, .3); }
.seg input:focus-visible + span { outline: 3px solid var(--focus); outline-offset: 2px; }
.check { display: inline-flex; align-items: center; gap: 0.6rem; cursor: pointer; font-weight: 700; }

/* ---------- 15. tickets, stubs, stamps, perforations ---------- */
.ticket { --nr: 0.6rem; position: relative; display: flex; color: var(--ink); filter: drop-shadow(0 3px 5px rgba(8, 14, 32, .35)); }
.ticket-main, .ticket-stub { position: relative; padding: 0.85rem 1.1rem; }
.ticket-main { flex: 1 1 auto; min-width: 0; border-radius: var(--r) 0 0 var(--r);
  background:
    radial-gradient(circle var(--nr) at 100% 0, #0000 calc(var(--nr) - 1px), var(--paper) var(--nr)) top / 100% 51% no-repeat,
    radial-gradient(circle var(--nr) at 100% 100%, #0000 calc(var(--nr) - 1px), var(--paper) var(--nr)) bottom / 100% 51% no-repeat; }
.ticket-stub { flex: none; min-width: 6rem; display: grid; place-items: center; text-align: center; border-radius: 0 var(--r) var(--r) 0; background:
    radial-gradient(circle var(--nr) at 0 0, #0000 calc(var(--nr) - 1px), var(--paper-2) var(--nr)) top / 100% 51% no-repeat,
    radial-gradient(circle var(--nr) at 0 100%, #0000 calc(var(--nr) - 1px), var(--paper-2) var(--nr)) bottom / 100% 51% no-repeat; }
.ticket-stub::before { content: ''; position: absolute; left: -1px; top: calc(var(--nr) + 3px); bottom: calc(var(--nr) + 3px); border-left: 2px dashed rgba(20, 33, 61, .35); }
.ticket-main::before { content: ''; position: absolute; inset: 0.32rem 0.4rem 0.32rem 0.32rem; border: 1px dashed rgba(20, 33, 61, .18); border-radius: 0.35rem; pointer-events: none; }
.ticket-red .ticket-stub { background:
    radial-gradient(circle var(--nr) at 0 0, #0000 calc(var(--nr) - 1px), var(--red) var(--nr)) top / 100% 51% no-repeat,
    radial-gradient(circle var(--nr) at 0 100%, #0000 calc(var(--nr) - 1px), var(--red) var(--nr)) bottom / 100% 51% no-repeat; color: #fff8ee; }
.ticket-red .ticket-stub::before { border-left-color: rgba(255, 248, 238, .55); }
.ticket-navy .ticket-stub { background:
    radial-gradient(circle var(--nr) at 0 0, #0000 calc(var(--nr) - 1px), var(--ink) var(--nr)) top / 100% 51% no-repeat,
    radial-gradient(circle var(--nr) at 0 100%, #0000 calc(var(--nr) - 1px), var(--ink) var(--nr)) bottom / 100% 51% no-repeat; color: var(--paper); }
.ticket-navy .ticket-stub::before { border-left-color: rgba(246, 239, 224, .5); }
.ticket-route { font: 900 1.25rem/1.1 var(--sans); letter-spacing: 0.04em; text-transform: uppercase; }
.ticket-times { font: 800 1.1rem var(--mono); font-variant-numeric: tabular-nums; }
button.ticket, a.ticket { padding: 0; margin: 0; border: 0; background: none; text-align: left; font: inherit; cursor: pointer; transition: transform 0.12s var(--ease), filter 0.12s; }
button.ticket:hover, a.ticket:hover { transform: translateY(-2px); filter: drop-shadow(0 6px 8px rgba(8, 14, 32, .4)); }
button.ticket.selected .ticket-main::before, .ticket.selected .ticket-main::before { border: 2px solid var(--red); }
.perf { height: 0; margin: 0.8rem 0; border: 0; border-top: 2px dashed rgba(20, 33, 61, .3); }
.stamp { display: inline-block; padding: 0.15rem 0.7rem; color: var(--red); border: 3px solid currentColor; border-radius: 0.4rem; transform: rotate(-6deg); opacity: 0.9;
  font: 900 0.95rem/1.2 var(--mono); letter-spacing: 0.2em; text-transform: uppercase; box-shadow: inset 0 0 0 2px rgba(255, 255, 255, .0), 0 0 0 2px rgba(200, 16, 46, .0); mix-blend-mode: multiply; }
.stamp-green { color: var(--green-dark); } .stamp-navy { color: var(--ink-3); } .stamp-gold { color: var(--gold-text); }
.stamp-in { animation: stamp-in 0.5s var(--ease) both; }
@keyframes stamp-in { 0% { transform: scale(2.2) rotate(-14deg); opacity: 0; } 60% { transform: scale(0.94) rotate(-6deg); opacity: 1; } 100% { transform: scale(1) rotate(-6deg); } }

/* ---------- 16. scrollbars ---------- */
* { scrollbar-width: thin; scrollbar-color: rgba(20, 33, 61, .5) transparent; }
::-webkit-scrollbar { width: 0.6rem; height: 0.6rem; }
::-webkit-scrollbar-thumb { background: rgba(20, 33, 61, .45); border-radius: 99px; border: 2px solid transparent; background-clip: padding-box; }
::-webkit-scrollbar-thumb:hover { background: rgba(20, 33, 61, .7); background-clip: padding-box; border: 2px solid transparent; }
::-webkit-scrollbar-track { background: transparent; }

/* ---------- 17. layout helpers for scene UIs (mounted with scene.mountUI(node, 'screen ...')) ----------
   .screen        full viewport BELOW the HUD; itself click-through, its children are clickable (3D view stays interactive)
   .screen-solid  same but opaque-ish backdrop that blocks the 3D view (title / summary)
   .side-panel    tall panel docked right (.side-left = left), below the HUD
   .dock-bottom   bottom-centre bar (controls, timetable strip)                                                        */
.screen { position: absolute; inset: 0; top: var(--hud-h); pointer-events: none; }
#ui-root > .screen { pointer-events: none; }   /* beats "#ui-root > * { pointer-events: auto }" so a transparent .screen never blocks the 3D canvas */
#ui-root > .screen.screen-solid { pointer-events: auto; }
.screen > * { pointer-events: auto; }
.screen-solid { top: 0; padding-top: var(--hud-h); pointer-events: auto; background: radial-gradient(ellipse at 50% 30%, rgba(20, 33, 61, .55), rgba(8, 12, 26, .85)); overflow: auto; }   /* dims the strip behind the HUD too; content still starts below it */
.screen-center { display: grid; place-items: center; padding: 1rem; }
.screen-solid.screen-center { padding-top: calc(var(--hud-h) + 1rem); }
.side-panel { position: absolute; top: 0.5rem; bottom: 0.75rem; right: 0.75rem; width: min(28rem, 46vw); display: flex; flex-direction: column; min-height: 0; }
.side-panel.side-left { right: auto; left: 0.75rem; }
.side-panel > .panel-body { flex: 1 1 auto; min-height: 0; overflow: auto; }
.dock-bottom { position: absolute; left: 50%; bottom: 0.9rem; transform: translateX(-50%); max-width: calc(100vw - 1.5rem); }

/* ---------- 18. HUD: ticket strip along the top (built by UI.js) ---------- */
#ui-root > .hud { position: fixed; top: 0; left: 0; right: 0; z-index: 60; pointer-events: none; padding: 0.5rem 0.75rem 0; transform: translateY(-115%); visibility: hidden; transition: transform 0.4s var(--ease), visibility 0s 0.4s; }
body[data-hud="full"] #ui-root > .hud, body[data-hud="compact"] #ui-root > .hud { transform: none; visibility: visible; transition: transform 0.4s var(--ease); }
.hud-strip { pointer-events: auto; display: flex; align-items: stretch; max-width: 60rem; height: 3.2rem; margin: 0 auto; color: var(--paper); filter: drop-shadow(0 2px 3px rgba(5, 9, 22, .45)) drop-shadow(0 6px 10px rgba(5, 9, 22, .25)); }
body[data-hud="compact"] .hud-strip { height: 2.7rem; max-width: 30rem; }
.hud-seg { --bl: radial-gradient(circle var(--bite) at 0 100%, #0000 calc(var(--bite) - 1px), var(--hud-bg) var(--bite)); --br: radial-gradient(circle var(--bite) at 100% 100%, #0000 calc(var(--bite) - 1px), var(--hud-bg) var(--bite));
  position: relative; display: flex; align-items: center; gap: 0.55rem; flex: none; min-width: 0; margin: 0; padding: 0 0.95rem; color: inherit; text-align: left; border: 0; border-top: 3px solid var(--gold);
  background: var(--bl) left / 51% 100% no-repeat, var(--br) right / 51% 100% no-repeat; --bite: 0.42rem; }
.hud-seg:first-child { --bl: linear-gradient(var(--hud-bg), var(--hud-bg)); border-radius: 0.85rem 0 0 0.85rem; }
.hud-seg:last-child { --br: linear-gradient(var(--hud-bg), var(--hud-bg)); border-radius: 0 0.85rem 0.85rem 0; }
.hud-seg:only-child { border-radius: 0.85rem; }
.hud-seg + .hud-seg { margin-left: -1px; }
.hud-seg + .hud-seg::before { content: ''; position: absolute; left: 0; top: 0.6rem; bottom: 0.95rem; border-left: 2px dashed rgba(246, 239, 224, .26); pointer-events: none; }
button.hud-seg { cursor: pointer; font: inherit; transition: filter 0.15s; }
button.hud-seg:hover { filter: brightness(1.25); }
button.hud-seg:focus-visible { outline-offset: -4px; --focus: var(--gold-hi); }
.hud-lbl { display: block; margin-bottom: 0.22rem; font: 700 max(9.5px, 0.6rem)/1 var(--sans); letter-spacing: 0.16em; text-transform: uppercase; color: rgba(246, 239, 224, .66); white-space: nowrap; }
.hud-val { font: 800 0.98rem/1.1 var(--sans); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hud-txt { min-width: 0; }
.hud-time .flap { font-size: 1.12rem; }
.hud-loc { flex: 1 1 auto; min-width: 6.5rem; }
.hud-loc .ico { --ico: 1.3rem; color: var(--gold-hi); }
.hud-loc.on-train .ico { color: #ff8c9c; }
.hud-money { position: relative; }
.hud-money .flap { font-size: 1.12rem; }
.hud-money .flap-cur { font-size: 1rem; }
.hud-money.flash-good .flap > i { animation: flash-good 0.7s ease; } .hud-money.flash-bad .flap > i { animation: flash-bad 0.7s ease; }
@keyframes flash-good { 30% { color: #7dffb0; box-shadow: 0 0 0.6rem rgba(125, 255, 176, .7); } }
@keyframes flash-bad { 30% { color: #ff7a8c; box-shadow: 0 0 0.6rem rgba(255, 122, 140, .7); } }
.hud-deltas { position: absolute; left: 0.7rem; top: 100%; pointer-events: none; }
.money-delta { position: absolute; left: 0; top: 0.2rem; padding: 0.1rem 0.55rem; border-radius: 99px; font: 900 0.9rem/1.4 var(--mono); white-space: nowrap; background: rgba(15, 26, 50, .92); box-shadow: 0 2px 6px rgba(0, 0, 0, .4); animation: delta-float 1.7s ease-out forwards; }
.money-delta.good { color: #7dffb0; } .money-delta.bad { color: #ff8c9c; }
@keyframes delta-float { 0% { opacity: 0; transform: translateY(-6px) scale(0.85); } 12% { opacity: 1; transform: translateY(0) scale(1); } 75% { opacity: 1; } 100% { opacity: 0; transform: translateY(1.6rem); } }
.hud-pass-main { display: flex; align-items: baseline; gap: 0.15rem; white-space: nowrap; }
.hud-num { font: 900 1.25rem/1 var(--mono); color: var(--paper); font-variant-numeric: tabular-nums; }
.hud-of { font: 700 0.8rem var(--mono); color: rgba(246, 239, 224, .68); }
.hud-of em { font-style: normal; margin-left: 0.25rem; font: 700 max(9.5px, 0.62rem) var(--sans); letter-spacing: 0.12em; text-transform: uppercase; }
.pass-dot { align-self: center; width: 0.6rem; height: 0.6rem; margin-left: 0.35rem; border-radius: 50%; background: var(--dot, #46d17b); box-shadow: 0 0 0 2px rgba(255, 255, 255, .12), 0 0 0.5rem var(--dot, #46d17b); }
.hud-pass[data-state="idle"] .pass-dot { --dot: var(--gold-hi); animation: dot-pulse 1.6s ease-in-out infinite; }
.hud-pass[data-state="done"] .pass-dot { --dot: #ff5468; animation: none; }
@keyframes dot-pulse { 50% { transform: scale(1.35); opacity: 0.65; } }
.hud-vitals { gap: 0.8rem; }
.hud-vital { display: flex; align-items: center; gap: 0.35rem; }
.hud-vital .ico { --ico: 1.05rem; color: var(--vc, var(--paper)); }
.hud-vital .bar { width: 3.1rem; height: 0.42rem; }
.hud-vital.v-energy { --vc: #f5b82e; } .hud-vital.v-hunger { --vc: #ee8353; } .hud-vital.v-mood { --vc: #58c790; }
.hud-vital.is-low .ico { color: #ff5468; animation: dot-pulse 1s ease-in-out infinite; }
.hud-menu { justify-content: center; padding: 0 0.85rem; }
.hud-menu .ico { --ico: 1.4rem; }
body[data-hud="compact"] .hud-loc, body[data-hud="compact"] .hud-pass, body[data-hud="compact"] .hud-vitals { display: none; }
body[data-hud="compact"] .hud-seg:not(.hud-menu) { flex: 1 1 auto; justify-content: center; }
@media (max-width: 62rem) { .hud-vital .bar { width: 2.2rem; } .hud-vitals { gap: 0.55rem; } .hud-seg { padding: 0 0.7rem; } .hud-of em { display: none; } }
@media (max-width: 52rem) { .hud-loc .ico { display: none; } .hud-lbl { letter-spacing: 0.1em; } .hud-loc { min-width: 4.5rem; } }

/* ---------- 19. toasts, prompt, objective, banner ---------- */
#ui-root > .toasts { position: fixed; top: calc(var(--hud-h) + 0.35rem); right: 0.9rem; z-index: 300; width: min(23rem, calc(100vw - 1.8rem)); display: flex; flex-direction: column; align-items: flex-end; gap: 0.5rem; pointer-events: none; transition: top 0.4s var(--ease); }
.toast { --tc: var(--ink); position: relative; display: flex; align-items: center; gap: 0.7rem; width: 100%; padding: 0.6rem 0.9rem 0.6rem 0.7rem; color: var(--ink); cursor: pointer; pointer-events: auto;
  background: var(--paper-hi); border-radius: var(--r); border-left: 0.4rem solid var(--tc); box-shadow: 0 0 0 1px rgba(20, 33, 61, .18), var(--shadow-2); font: 600 0.92rem/1.3 var(--sans); animation: toast-in 0.4s var(--spring) both; }
.toast.leaving { animation: toast-out 0.3s ease-in forwards; }
.toast-ico { display: grid; place-items: center; flex: none; width: 1.9rem; height: 1.9rem; border-radius: 50%; color: #fff; background: var(--tc); }
.toast-ico .ico { --ico: 1.1rem; }
.toast-body { flex: 1 1 auto; min-width: 0; }
.toast-title { display: block; font: 800 0.66rem/1.2 var(--sans); letter-spacing: 0.16em; text-transform: uppercase; color: var(--gold-text); margin-bottom: 0.1rem; }
.toast-text { overflow-wrap: anywhere; }
.toast-count { flex: none; }
.toast.k-info { --tc: var(--blue); } .toast.k-good { --tc: var(--green); } .toast.k-warn { --tc: var(--orange); } .toast.k-bad { --tc: var(--red); }
.toast.k-achievement { --tc: var(--gold); background: linear-gradient(90deg, #fff4d0, var(--paper-hi) 60%); border-left-color: var(--gold-dark); box-shadow: 0 0 0 1.5px var(--gold), var(--shadow-2), 0 0 1.4rem rgba(242, 169, 0, .4); }
.toast.k-achievement .toast-ico { color: var(--ink); }
/* a docked .side-panel owns its corner: toasts (right panel) / the objective card (left panel) move beside it instead of covering its header */
body:has(.side-panel:not(.side-left)) #ui-root > .toasts { right: calc(min(28rem, 46vw) + 1.5rem); width: min(23rem, calc(100vw - min(28rem, 46vw) - 2.4rem)); }
body:has(.side-panel.side-left) #ui-root > .objective { left: calc(min(28rem, 46vw) + 1.5rem); max-width: min(24rem, calc(100vw - min(28rem, 46vw) - 2.4rem)); }
@keyframes toast-in { from { opacity: 0; transform: translateX(1.6rem) scale(0.96); } to { opacity: 1; transform: none; } }
@keyframes toast-out { to { opacity: 0; transform: translateY(-0.6rem) scale(0.96); } }
/* compact toasts (phones / touch / narrow windows, class set by UI._placeToasts): one or two lines, at most two at a time, parked under the HUD / objective / journey dock */
#ui-root > .toasts.compact { gap: 0.35rem; transition: top 0.25s var(--ease); }
.toasts.compact .toast { gap: 0.5rem; padding: 0.35rem 0.6rem 0.35rem 0.45rem; border-left-width: 0.3rem; font: 600 0.84rem/1.25 var(--sans); }
.toasts.compact .toast-ico { width: 1.45rem; height: 1.45rem; } .toasts.compact .toast-ico .ico { --ico: 0.9rem; }
.toasts.compact .toast-text { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; }
.toasts.compact .toast-lead { font-weight: 800; color: var(--gold-text); }
.toasts.compact .toast.k-achievement { box-shadow: 0 0 0 1.5px var(--gold), var(--shadow-2); }
@media (max-width: 40rem) { #ui-root > .toasts.compact { right: 0.6rem; width: calc(100vw - 1.2rem); } }
/* short landscape phones: the stick (bottom left) and the buttons (bottom right) leave the top-left free */
@media (max-height: 30rem) { #ui-root > .toasts.compact { left: 0.9rem; right: auto; width: min(21rem, 46vw); align-items: flex-start; } }
/* title wordmark: 62px type is 359px wide, it was cut off by the screen edge on 360 / 375 wide phones - scale it down there (TitleScene injects its own sheet, hence the body prefix) */
@media (max-width: 30rem) { body .tt-logo { font-size: min(4.45rem, calc((100vw - 2.2rem) / 5.8)); } }
@media (max-height: 30rem) { #ui-root > .toasts.compact.wide { width: min(44rem, calc(100vw - 1.8rem)); } }

#ui-root > .prompt { position: fixed; left: 50%; bottom: max(9vh, 3.5rem); z-index: 55; transform: translateX(-50%); pointer-events: none; }
.prompt-pill { display: flex; align-items: center; gap: 0.5rem; max-width: min(34rem, calc(100vw - 2rem)); padding: 0.55rem 1.15rem; color: var(--paper); text-align: center; white-space: nowrap;
  background: rgba(15, 26, 50, .92); border: 1.5px solid rgba(246, 239, 224, .3); border-radius: 99px; box-shadow: 0 6px 18px rgba(0, 0, 0, .4); font: 700 1rem/1.2 var(--sans); letter-spacing: 0.02em;
  opacity: 0; transform: translateY(0.6rem) scale(0.96); transition: opacity 0.18s ease, transform 0.22s var(--spring); }
.prompt.show .prompt-pill { opacity: 1; transform: none; }
.prompt .kbd { font-size: 0.85rem; }
body:has(.dock-bottom) #ui-root > .prompt { bottom: calc(max(9vh, 3.5rem) + 4.4rem); }   /* keep the [E] prompt above a .dock-bottom bar */
.prompt.pop .prompt-pill { animation: prompt-pop 0.3s var(--spring); }
@keyframes prompt-pop { 0% { transform: scale(0.94); } 100% { transform: none; } }

#ui-root > .objective { position: fixed; left: 0.9rem; top: calc(var(--hud-h) + 0.35rem); z-index: 55; max-width: min(24rem, 36vw); pointer-events: none; transition: top 0.4s var(--ease), opacity 0.25s ease, transform 0.25s var(--ease); opacity: 0; transform: translateX(-0.8rem); }
#ui-root > .objective.show { opacity: 1; transform: none; }
.objective-card { position: relative; padding: 0.5rem 0.95rem 0.55rem 0.9rem; color: var(--paper); background: rgba(15, 26, 50, .9); border-left: 0.32rem solid var(--gold); border-radius: 0.2rem 0.7rem 0.7rem 0.2rem; box-shadow: 0 5px 14px rgba(0, 0, 0, .38); }
.objective-lbl { display: flex; align-items: center; gap: 0.35rem; margin-bottom: 0.2rem; font: 800 max(9.5px, 0.62rem)/1 var(--sans); letter-spacing: 0.2em; text-transform: uppercase; color: var(--gold-hi); }
.objective-lbl .ico { --ico: 0.85rem; }
.objective-text { font: 700 0.95rem/1.3 var(--sans); overflow-wrap: anywhere; }
.objective.bump .objective-card { animation: obj-bump 0.7s var(--ease); }
@keyframes obj-bump { 0% { transform: translateX(-0.5rem); box-shadow: 0 0 0 0 rgba(242, 169, 0, .9); } 40% { box-shadow: 0 0 0 0.5rem rgba(242, 169, 0, 0); } 100% { transform: none; } }

#ui-root > .banner-host { position: fixed; inset: 0; z-index: 120; pointer-events: none; display: flex; justify-content: center; align-items: flex-start; padding-top: 20vh; }
.banner-card { --nr: 0.75rem; position: relative; min-width: min(28rem, 88vw); max-width: min(42rem, 92vw); padding: 1.5rem 3rem 1.7rem; text-align: center; color: var(--ink); border-radius: var(--r-lg);
  filter: drop-shadow(0 12px 22px rgba(4, 8, 20, .5));
  background:
    radial-gradient(circle var(--nr) at 0 50%, #0000 calc(var(--nr) - 1px), var(--paper) var(--nr)) left / 51% 100% no-repeat,
    radial-gradient(circle var(--nr) at 100% 50%, #0000 calc(var(--nr) - 1px), var(--paper) var(--nr)) right / 51% 100% no-repeat;
  animation: banner-in 0.55s var(--spring) both; }
.banner-card::before { content: ''; position: absolute; inset: 0.4rem 1.35rem; border: 2px double rgba(20, 33, 61, .32); border-radius: 0.5rem; pointer-events: none; }
.banner-card.out { animation: banner-out 0.42s ease-in forwards; }
.banner-eyebrow { display: flex; align-items: center; justify-content: center; gap: 0.7rem; margin-bottom: 0.5rem; color: var(--red); font: 800 0.66rem/1 var(--sans); letter-spacing: 0.3em; text-transform: uppercase; }
.banner-eyebrow::before, .banner-eyebrow::after { content: ''; width: 2.6rem; height: 2px; background: currentColor; opacity: 0.6; }
.banner-title { margin: 0; font: 900 clamp(1.6rem, 3.4vw, 2.7rem)/1.05 var(--sans); letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink); }
.banner-sub { margin: 0.6rem 0 0; font: italic 1.1rem/1.35 var(--serif); color: var(--ink-soft); }
.banner-bar { height: 0.32rem; margin: 1rem auto 0; width: 6rem; border-radius: 3px; background: linear-gradient(90deg, var(--red) 0 60%, var(--gold) 60% 100%); }
@keyframes banner-in { from { opacity: 0; transform: translateY(-1.4rem) scale(0.9); } to { opacity: 1; transform: none; } }
@keyframes banner-out { to { opacity: 0; transform: translateY(0.8rem) scale(0.97); } }

/* ---------- 20. modals: dialog / menu / wallet / journal / settings / help ---------- */
#ui-root > .modal-host { position: fixed; inset: 0; z-index: 200; pointer-events: none; }
.modal-backdrop { position: absolute; inset: 0; display: grid; place-items: center; padding: 0.8rem; pointer-events: auto; background: radial-gradient(ellipse at 50% 42%, rgba(12, 20, 42, .5), rgba(5, 9, 22, .8)); animation: fade-in 0.2s ease both; }
.modal-backdrop.closing { pointer-events: none; animation: fade-out 0.17s ease forwards; }
.modal { --bite: 0.7rem; position: relative; display: flex; flex-direction: column; width: min(31rem, calc(100vw - 1.6rem)); max-height: min(calc(100vh - 1.6rem), 60rem); color: var(--ink); border-radius: var(--r-lg);
  box-shadow: var(--shadow-3), 0 0 0 1px rgba(5, 9, 22, .55); animation: modal-in 0.28s var(--spring) both; }
.modal.shake { animation: shake 0.3s ease; }
.modal-backdrop.closing .modal { animation: modal-out 0.17s ease-in forwards; }
.modal-wide { width: min(50rem, calc(100vw - 1.6rem)); }
.modal-xwide { width: min(62rem, calc(100vw - 1.6rem)); }
.modal-narrow { width: min(23rem, calc(100vw - 1.6rem)); }
.modal-head { position: relative; flex: none; display: flex; align-items: center; gap: 0.8rem; padding: 0.95rem 1.2rem 1.05rem; color: var(--paper); border-radius: var(--r-lg) var(--r-lg) 0 0;
  background:
    radial-gradient(circle var(--bite) at 0 100%, #0000 calc(var(--bite) - 1px), var(--ink) var(--bite)) left / 51% 100% no-repeat,
    radial-gradient(circle var(--bite) at 100% 100%, #0000 calc(var(--bite) - 1px), var(--ink) var(--bite)) right / 51% 100% no-repeat; }
.modal-head::before { content: ''; position: absolute; left: 0; right: 0; top: 0; height: 0.28rem; border-radius: var(--r-lg) var(--r-lg) 0 0; background: linear-gradient(90deg, var(--red) 0 34%, var(--gold) 34% 40%, var(--red) 40% 100%); }
.modal-head::after { content: ''; position: absolute; left: calc(var(--bite) + 0.3rem); right: calc(var(--bite) + 0.3rem); bottom: 0; border-bottom: 2px dashed rgba(246, 239, 224, .4); }
.modal-ico { display: grid; place-items: center; flex: none; width: 2.5rem; height: 2.5rem; border-radius: 50%; color: var(--ink); background: var(--gold); box-shadow: 0 0 0 3px rgba(242, 169, 0, .25); }
.modal-ico .ico { --ico: 1.35rem; }
.modal-titles { flex: 1 1 auto; min-width: 0; }
.modal-title { margin: 0; font: 900 1.2rem/1.15 var(--sans); letter-spacing: 0.06em; text-transform: uppercase; overflow-wrap: anywhere; }
.modal-titles .eyebrow { display: block; margin-bottom: 0.2rem; }
.modal-close { flex: none; }
.modal-head .btn-ghost { --b-fg: var(--paper); } .modal-head .btn-ghost:hover:not(:disabled) { background: rgba(246, 239, 224, .16); }
.modal-body { position: relative; flex: 1 1 auto; min-height: 0; overflow: auto; padding: 1.15rem 1.4rem 1.3rem;
  background:
    radial-gradient(circle var(--bite) at 0 0, #0000 calc(var(--bite) - 1px), var(--paper) var(--bite)) left / 51% 100% no-repeat,
    radial-gradient(circle var(--bite) at 100% 0, #0000 calc(var(--bite) - 1px), var(--paper) var(--bite)) right / 51% 100% no-repeat; }
.modal-body:last-child { border-radius: 0 0 var(--r-lg) var(--r-lg); }
.modal-body p { font-size: 1rem; white-space: pre-line; }
.modal-foot { flex: none; display: flex; align-items: center; justify-content: flex-end; flex-wrap: wrap; gap: 0.6rem; padding: 0.85rem 1.2rem; background: var(--paper-2); border-top: 2px dashed rgba(20, 33, 61, .22); border-radius: 0 0 var(--r-lg) var(--r-lg); }
.modal-foot .foot-note { margin-right: auto; font-size: 0.78rem; color: var(--ink-mute); }
.modal-tone-warn .modal-ico { background: var(--orange-soft); color: var(--orange); }
.modal-tone-bad .modal-ico { background: var(--red); color: #fff8ee; }
.modal-tone-good .modal-ico { background: #7fdca2; color: var(--green-dark); }
@keyframes fade-in { from { opacity: 0; } } @keyframes fade-out { to { opacity: 0; } }
@keyframes modal-in { from { opacity: 0; transform: translateY(1.2rem) scale(0.95); } to { opacity: 1; transform: none; } }
@keyframes modal-out { to { opacity: 0; transform: translateY(0.6rem) scale(0.97); } }
@keyframes shake { 20% { transform: translateX(-0.4rem); } 40% { transform: translateX(0.4rem); } 60% { transform: translateX(-0.25rem); } 80% { transform: translateX(0.2rem); } }

/* choices (dialogs) & menu lists */
.choices { display: grid; gap: 0.5rem; margin-top: 0.9rem; }
.choices:first-child { margin-top: 0; }
.choice { justify-content: flex-start; flex-wrap: wrap; width: 100%; min-height: 2.9rem; padding: 0.55rem 0.9rem; text-align: left; white-space: normal; letter-spacing: 0.02em; }
.choice-key { flex: none; display: grid; place-items: center; width: 1.6rem; height: 1.6rem; border-radius: 0.35rem; font: 800 0.8rem/1 var(--mono); color: var(--paper); background: var(--b-fg); }
.btn-primary .choice-key { color: var(--red-dark); background: #fff8ee; }
.btn-danger .choice-key { color: #fff8ee; background: var(--red); }
.choice-label { flex: 1 1 auto; min-width: 0; font-size: 0.98rem; }
.choice-hint { flex: none; margin-left: auto; padding-left: 0.5rem; font: 700 0.76rem/1.2 var(--mono); letter-spacing: 0; opacity: 0.85; }
.choice[aria-disabled="true"] { opacity: 0.7; }
.btn[aria-disabled="true"] .choice-hint { color: var(--red-dark); opacity: 1; }
.btn-primary[aria-disabled="true"] .choice-hint { color: #ffe0b8; }
.menu-status { margin-bottom: 0.9rem; }
.menu-status .ticket-main { padding: 0.6rem 0.9rem; }
.menu-item { justify-content: flex-start; gap: 0.75rem; width: 100%; min-height: 2.9rem; text-align: left; }
.menu-item .ico { --ico: 1.25rem; }
.menu-item .kbd { margin-left: auto; }
.menu-list { display: grid; gap: 0.5rem; }

/* pass wallet */
.wallet { display: flex; flex-wrap: wrap; gap: 1.3rem; align-items: flex-start; }
.wallet-card-col { flex: 1 1 17rem; min-width: 0; }
.wallet-cal-col { flex: 1.5 1 21rem; min-width: 0; }
.pass-card { position: relative; overflow: hidden; color: var(--ink); background: linear-gradient(160deg, #fffaf0, var(--paper) 55%, var(--paper-2)); border-radius: var(--r-lg); box-shadow: 0 0 0 2px var(--ink), 0 6px 0 rgba(20, 33, 61, .25), var(--shadow-2); }
.pass-card-band { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; padding: 0.65rem 0.9rem; color: #fff8ee; background: var(--red); box-shadow: inset 0 -3px 0 var(--gold); }
.pass-logo { display: flex; align-items: center; gap: 0.5rem; font: 900 1.05rem/1 var(--sans); letter-spacing: 0.2em; }
.pass-logo svg { width: 1.7rem; height: 1.7rem; }
.pass-sub { font: 800 0.62rem/1 var(--sans); letter-spacing: 0.26em; text-transform: uppercase; color: var(--gold-hi); text-align: right; }
.pass-card-body { position: relative; display: grid; gap: 0.6rem; padding: 0.9rem 1rem 1rem; }
.pass-field .label { display: block; margin-bottom: 0.1rem; font-size: 0.6rem; }
.pass-field .v { font: 800 1.05rem/1.2 var(--mono); }
.pass-field .v.serif { font: italic 700 1.3rem/1.2 var(--serif); }
.pass-barcode { display: block; width: 100%; height: 1.6rem; margin-top: 0.2rem; fill: var(--ink); opacity: 0.85; }
.pass-stamp { position: absolute; right: 0.9rem; bottom: 2.6rem; font-size: 1.1rem; }
.pass-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.5rem; margin-top: 0.8rem; }
.pass-stats .stat { padding: 0.55rem 0.3rem; background: var(--paper-hi); border: 1.5px solid rgba(20, 33, 61, .22); border-radius: var(--r); }
.pass-stats .stat-num { font-size: 1.6rem; }
.pass-note { margin-top: 0.8rem; }
.cal-head { display: flex; align-items: baseline; justify-content: space-between; gap: 0.6rem; margin-bottom: 0.5rem; }
.cal { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 0.25rem; }
.cal-dow { padding-bottom: 0.15rem; text-align: center; font: 800 0.6rem/1 var(--sans); letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-mute); }
.day { position: relative; display: grid; place-items: center; aspect-ratio: 1 / 1; min-height: 2.2rem; padding: 0; margin: 0; appearance: none; color: var(--ink); background: var(--paper-hi); border: 1.5px solid rgba(20, 33, 61, .22); border-radius: 0.45rem;
  font: 800 0.85rem/1 var(--mono); font-variant-numeric: tabular-nums; cursor: default; transition: transform 0.1s, background 0.15s, box-shadow 0.15s; }
.day.m-alt { background: var(--paper-2); }
.day.outside { visibility: hidden; }
.day .mon { position: absolute; top: 0.14rem; left: 0.22rem; font: 800 0.5rem/1 var(--sans); letter-spacing: 0.06em; text-transform: uppercase; color: var(--red); }
.day .day-mark { position: absolute; right: 0.14rem; bottom: 0.12rem; display: inline-flex; width: 0.8rem; height: 0.8rem; }
.day .day-mark svg { width: 100%; height: 100%; fill: none; stroke: currentColor; stroke-width: 3.2; stroke-linecap: round; stroke-linejoin: round; }
.day.past { color: var(--ink-mute); background: repeating-linear-gradient(135deg, var(--paper-2) 0 4px, var(--paper) 4px 8px); border-style: dashed; }
.day.avail { cursor: pointer; border-color: var(--ink); }
.day.avail:hover { background: var(--gold-soft); transform: translateY(-1px); box-shadow: 0 2px 0 var(--gold-dark); }
.day.preview { border-style: dashed; }
.day.active { color: var(--ink); background: var(--gold); border-color: var(--gold-dark); box-shadow: 0 2px 0 var(--gold-dark); }
.day.used { color: var(--red-dark); background: var(--red-soft); border-color: rgba(200, 16, 46, .55); }
.day.used::after { content: ''; position: absolute; inset: 0.18rem; border: 2px solid var(--red); border-radius: 50%; transform: rotate(-14deg) scale(1.02); opacity: 0.6; clip-path: polygon(0 0, 100% 0, 100% 78%, 82% 100%, 0 100%); }
.day.today { outline: 3px solid var(--ink); outline-offset: 1px; z-index: 1; }
.day.today .day-tag { position: absolute; bottom: -0.55rem; left: 50%; transform: translateX(-50%); padding: 0 0.3rem; border-radius: 99px; font: 800 0.46rem/1.5 var(--sans); letter-spacing: 0.12em; text-transform: uppercase; color: var(--paper); background: var(--ink); }
.day.just-stamped { animation: stamp-cell 0.6s var(--ease); }
@keyframes stamp-cell { 0% { transform: scale(1.6); } 60% { transform: scale(0.94); } 100% { transform: none; } }
.legend { display: flex; flex-wrap: wrap; gap: 0.4rem 0.9rem; margin-top: 0.8rem; font-size: 0.78rem; color: var(--ink-soft); }
.legend span { display: inline-flex; align-items: center; gap: 0.35rem; }
.legend i { display: inline-block; width: 0.9rem; height: 0.9rem; border-radius: 0.25rem; border: 1.5px solid rgba(20, 33, 61, .4); }
.legend i.l-used { background: var(--red-soft); border-color: var(--red); } .legend i.l-active { background: var(--gold); border-color: var(--gold-dark); }
.legend i.l-avail { background: var(--paper-hi); border-color: var(--ink); } .legend i.l-past { background: repeating-linear-gradient(135deg, var(--paper-2) 0 3px, var(--paper) 3px 6px); border-style: dashed; }

/* journal */
.journal-meta { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-bottom: 0.9rem; }
.journal-meta .stat { flex: 1 1 5rem; padding: 0.5rem 0.4rem; background: var(--paper-hi); border: 1.5px solid rgba(20, 33, 61, .2); border-radius: var(--r); }
.journal-meta .stat-num { font-size: 1.45rem; }
.log-day { position: sticky; top: -1.15rem; z-index: 2; margin: 0.8rem -0.2rem 0.3rem; padding: 0.3rem 0.5rem; font: 800 0.68rem/1.2 var(--sans); letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink); background: var(--paper-3); border-radius: 0.3rem; }
.log-day:first-child { margin-top: 0; }
.log-row { display: grid; grid-template-columns: 3rem 5.6rem 1fr; align-items: baseline; gap: 0.6rem; padding: 0.38rem 0.3rem; border-bottom: 1px dashed rgba(20, 33, 61, .2); font-size: 0.92rem; line-height: 1.35; }
.log-time { font: 700 0.82rem var(--mono); color: var(--ink-soft); }
.log-text { overflow-wrap: anywhere; }
.stamps { display: grid; grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr)); gap: 0.8rem; padding: 0.3rem; }
.city-stamp { --c: var(--ink-3); position: relative; display: grid; gap: 0.15rem; justify-items: center; padding: 0.8rem 0.6rem 0.7rem; text-align: center; color: var(--c); border: 3px double var(--c); border-radius: 0.6rem; transform: rotate(var(--rot, -2deg)); background: rgba(255, 255, 255, .35); }
.city-stamp .cs-no { font: 800 0.6rem/1 var(--mono); letter-spacing: 0.2em; opacity: 0.8; }
.city-stamp .cs-name { font: 900 1.05rem/1.15 var(--sans); letter-spacing: 0.08em; text-transform: uppercase; overflow-wrap: anywhere; }
.city-stamp .cs-cc { font: 800 0.7rem/1 var(--mono); letter-spacing: 0.24em; padding: 0.15rem 0.5rem; border: 1.5px solid var(--c); border-radius: 99px; }
.city-stamp .cs-flags { display: flex; gap: 0.3rem; min-height: 1.2rem; margin-top: 0.15rem; }
.city-stamp.here { box-shadow: 0 0 0 3px rgba(242, 169, 0, .55); }
.city-stamp.c-red { --c: var(--red-dark); } .city-stamp.c-green { --c: var(--green-dark); } .city-stamp.c-navy { --c: var(--ink-3); } .city-stamp.c-gold { --c: var(--gold-text); }
.postcards { display: grid; grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr)); gap: 0.8rem; }
.postcard-mini { position: relative; display: flex; flex-direction: column; justify-content: flex-end; min-height: 7.5rem; padding: 0.6rem 0.7rem; color: #fff; border: 4px solid #fffaf0; border-radius: 0.3rem; box-shadow: 0 3px 8px rgba(8, 14, 32, .3); overflow: hidden;
  background: linear-gradient(180deg, hsl(var(--h) 55% 68%) 0 46%, hsl(var(--h) 38% 46%) 46% 70%, hsl(calc(var(--h) + 30) 32% 32%) 70% 100%); transform: rotate(var(--rot, 1deg)); }
.postcard-mini::before { content: ''; position: absolute; top: 0.6rem; right: 0.9rem; width: 1.1rem; height: 1.1rem; border-radius: 50%; background: #fff2c4; box-shadow: 0 0 0.8rem rgba(255, 242, 196, .8); }
.postcard-mini .pm-label { position: relative; font: 800 0.86rem/1.15 var(--serif); font-style: italic; text-shadow: 0 1px 3px rgba(0, 0, 0, .55); }
.postcard-mini .pm-meta { position: relative; margin-top: 0.25rem; display: flex; gap: 0.3rem; align-items: center; }
.postcard-mini .chip { font-size: 0.58rem; }
.stats-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); gap: 0.4rem 1.6rem; }

/* settings & help */
.settings { display: grid; gap: 1.1rem; }
.settings-group { display: grid; gap: 0.75rem; }
.settings-group > .label { padding-bottom: 0.3rem; border-bottom: 2px solid var(--ink); color: var(--ink); }
.setting { display: grid; grid-template-columns: minmax(7rem, 11rem) 1fr; gap: 0.4rem 1rem; align-items: center; }
.setting-name { font-weight: 800; font-size: 0.95rem; }
.setting-name small { display: block; font-weight: 500; font-size: 0.76rem; color: var(--ink-mute); line-height: 1.3; }
.setting-ctl { display: flex; align-items: center; gap: 0.8rem; min-width: 0; }
.setting-val { flex: none; width: 3.2rem; text-align: right; font: 800 0.9rem var(--mono); font-variant-numeric: tabular-nums; }
.help-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr)); gap: 0.9rem; }
.help-sec { padding: 0.75rem 0.9rem 0.85rem; background: var(--paper-hi); border: 1.5px solid rgba(20, 33, 61, .22); border-radius: var(--r); }
.help-sec h3 { margin: 0 0 0.55rem; padding-bottom: 0.35rem; border-bottom: 2px dashed rgba(20, 33, 61, .25); font: 800 0.74rem/1.2 var(--sans); letter-spacing: 0.16em; text-transform: uppercase; color: var(--red-dark); }
.help-sec ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.45rem; }
.help-sec li { display: grid; grid-template-columns: minmax(4.4rem, auto) 1fr; gap: 0.7rem; align-items: center; font-size: 0.92rem; line-height: 1.35; }
.help-sec li.note { display: block; color: var(--ink-soft); }
.help-keys { display: flex; flex-wrap: wrap; align-items: center; gap: 0.15rem; color: var(--ink-mute); }
.help-keys .kbd { font-size: 0.8rem; }

/* ---------- 21. responsive & motion ---------- */
@media (max-width: 52rem) {
  .modal-body { padding: 1rem 1rem 1.1rem; } .modal-head { padding: 0.8rem 1rem 0.9rem; }
  .setting { grid-template-columns: 1fr; }
  .log-row { grid-template-columns: 2.8rem 1fr; } .log-row .chip { grid-row: 2; grid-column: 1 / -1; justify-self: start; } .log-text { grid-column: 2; grid-row: 1; }
}
@media (max-height: 38rem) {
  .modal-body { padding-top: 0.9rem; padding-bottom: 1rem; }
  #ui-root > .banner-host { padding-top: 12vh; }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; scroll-behavior: auto !important; }
  .money-delta { animation: none; opacity: 1; }
  .bar.low > i, .hud-pass[data-state="idle"] .pass-dot, .hud-vital.is-low .ico, .board .boarding { animation: none !important; }
}

/* ---------- 22. touch (phones & tablets) ----------------------------------------------------------------------------
   Everything below only matters when the touch interface is active (body.touch-ui, set by src/core/Input.js: touch-primary
   device, a real touch event or ?touch=1) or on narrow screens (max-width media queries).  Desktop is unchanged.
   Overlay for the first-person scenes: src/ui/TouchControls.js (.tc-*).  Sizes are in px/max() because the root font-size
   is only 14px on phones and every control must be >= 56px.                                                                */
#gl { touch-action: none; }
html, body { overscroll-behavior: none; }
body.touch-ui { -webkit-touch-callout: none; }
body.touch-ui #ui-root .btn, body.touch-ui #ui-root button { touch-action: manipulation; }

.tc-root { display: none; }
.tc-root.on { display: contents; }
.tc-stick-zone { position: fixed; left: 0; bottom: 0; width: min(46vw, 24rem); height: 58vh; touch-action: none; pointer-events: auto; z-index: 1; }
.tc-stick-base { position: fixed; left: calc(env(safe-area-inset-left, 0px) + 20px); bottom: calc(env(safe-area-inset-bottom, 0px) + 26px); width: calc(var(--tc-r, 58px) * 2); height: calc(var(--tc-r, 58px) * 2);
  border-radius: 50%; border: 2px solid rgba(246, 239, 224, .42); background: radial-gradient(circle, rgba(20, 33, 61, .1) 0 35%, rgba(20, 33, 61, .34) 100%); opacity: .5; pointer-events: none; transition: opacity .2s ease; }
.tc-stick-base::before { content: ''; position: absolute; inset: 22%; border-radius: 50%; border: 2px dashed rgba(246, 239, 224, .28); }
.tc-stick-base.float { bottom: auto; transform: translate(-50%, -50%); transition: none; }
.tc-stick-base.held { opacity: .95; }
.tc-knob { position: absolute; left: 50%; top: 50%; width: calc(var(--tc-r, 58px) * .92); height: calc(var(--tc-r, 58px) * .92); margin: calc(var(--tc-r, 58px) * -.46) 0 0 calc(var(--tc-r, 58px) * -.46); border-radius: 50%;
  background: rgba(246, 239, 224, .82); box-shadow: 0 2px 8px rgba(8, 14, 32, .5), inset 0 -3px 0 rgba(20, 33, 61, .18); }
.tc-stick-base.run { border-color: var(--gold-hi); } .tc-stick-base.run .tc-knob { background: var(--gold-hi); }

.tc-ui { position: fixed; inset: 0; z-index: 52; pointer-events: none; }
.tc-actions { position: absolute; right: calc(env(safe-area-inset-right, 0px) + 14px); bottom: calc(env(safe-area-inset-bottom, 0px) + 18px); display: flex; flex-direction: column; align-items: flex-end; gap: 12px; pointer-events: none; }
.tc-secs { display: grid; grid-template-columns: repeat(2, max(60px, 4.3rem)); gap: 9px; justify-items: end; }
.tc-btn { appearance: none; pointer-events: auto; touch-action: none; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; width: max(60px, 4.3rem); height: max(60px, 4rem); padding: 0; border-radius: 50%;
  border: 2px solid rgba(246, 239, 224, .6); color: #fff; background: rgba(20, 33, 61, .52); -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px); box-shadow: 0 3px 10px rgba(5, 9, 22, .45);
  font: 800 10px/1 var(--sans); letter-spacing: .04em; text-transform: uppercase; transition: transform .08s ease, background .15s ease, opacity .15s ease; }
.tc-btn .ico { --ico: 24px; }
.tc-btn.down { transform: scale(.9); background: rgba(242, 169, 0, .72); color: var(--ink); }
.tc-btn.dis { opacity: .3; }
.tc-btn.hidden { display: none !important; }
.tc-btn.tc-use { width: max(78px, 5.8rem); height: max(78px, 5.8rem); background: rgba(200, 16, 46, .62); border-color: rgba(255, 244, 214, .85); font-size: 12px; }
.tc-btn.tc-use .ico { --ico: 32px; }
.tc-btn.tc-use.down { background: rgba(255, 201, 58, .85); }
.tc-btn.tc-use.tc-shutter { width: max(92px, 6.9rem); height: max(92px, 6.9rem); background: rgba(246, 239, 224, .26); border-width: 4px; border-color: #fff; font-size: 13px; }
.tc-btn.tc-use.tc-shutter .ico { --ico: 38px; }
.tc-btn.tc-use.tc-shutter.down { background: rgba(255, 255, 255, .9); }
.tc-btn.ready { border-color: var(--gold-hi); animation: tc-ready 1.15s ease-in-out infinite; }
.tc-btn.tc-use.ready { background: rgba(200, 16, 46, .86); }
@keyframes tc-ready { 0%, 100% { box-shadow: 0 3px 10px rgba(5, 9, 22, .45), 0 0 0 0 rgba(255, 201, 58, .75); } 55% { box-shadow: 0 3px 10px rgba(5, 9, 22, .45), 0 0 0 11px rgba(255, 201, 58, 0); } }
@media (orientation: landscape) and (max-height: 34rem) { .tc-secs { grid-template-columns: repeat(3, max(60px, 4.3rem)); } .tc-actions { gap: 9px; bottom: calc(env(safe-area-inset-bottom, 0px) + 12px); } }

.tc-rotate { position: absolute; left: 50%; top: 40%; z-index: 2; display: flex; align-items: center; gap: 8px; max-width: calc(100vw - 24px); padding: 4px 4px 4px 14px; border-radius: 999px; color: var(--paper);
  background: rgba(15, 26, 50, .95); box-shadow: 0 4px 14px rgba(5, 9, 22, .5), 0 0 0 1px rgba(246, 239, 224, .22); font: 700 13px/1.25 var(--sans); opacity: 0; transform: translate(-50%, -8px); pointer-events: none; transition: opacity .3s ease, transform .3s var(--ease); }
.tc-rotate.show { opacity: 1; transform: translate(-50%, 0); pointer-events: auto; }
.tc-rotate > .ico { --ico: 20px; color: var(--gold-hi); flex: none; }
.tc-rot-x { appearance: none; flex: none; width: 44px; height: 44px; display: grid; place-items: center; border: 0; border-radius: 50%; background: rgba(246, 239, 224, .12); color: var(--paper); padding: 0; }

/* prompts / objective around the controls */
body.tc-on #ui-root > .prompt { bottom: calc(env(safe-area-inset-bottom, 0px) + 22px); max-width: calc(100vw - 25rem); }
body.tc-on .prompt-pill { white-space: normal; text-align: center; max-width: 100%; }
@media (orientation: portrait) {
  body.tc-on #ui-root > .prompt { bottom: calc(env(safe-area-inset-bottom, 0px) + 12.5rem); max-width: calc(100vw - 1.6rem); }
  body.tc-on[data-scene="journey"] #ui-root > .prompt { bottom: calc(env(safe-area-inset-bottom, 0px) + 22rem); }
}
body.touch-ui .menu-item .kbd { display: none; }

/* journey: the dock keeps only the route strip on touch (its buttons live in the overlay) and moves under the HUD */
body.touch-ui .jr-ctrl, body.touch-ui .vf-hint { display: none; }
body.touch-ui .jr-dock { bottom: auto; top: calc(var(--hud-h) + .4rem); min-width: 0; width: min(30rem, calc(100vw - 1.5rem)); padding: .4rem .8rem .45rem; }
body.touch-ui .jr-dock.hide { transform: translate(-50%, -1.2rem); }
body.touch-ui[data-scene="journey"] #ui-root > .objective { display: none; }

/* ---------- 23. narrow screens & short landscape phones (HUD, objective, dialogs) ---------------------------------- */
@media (max-width: 40rem) {
  body[data-hud="full"] { --hud-h: 5.6rem; }
  #ui-root > .hud { padding: 0.4rem 0.45rem 0; }
  body[data-hud="full"] .hud-strip { height: 3rem; }
  .hud-seg { padding: 0 0.55rem; gap: 0.4rem; }
  .hud-lbl { letter-spacing: 0.06em; font-size: max(9px, 0.56rem); }
  .hud-val { font-size: 0.9rem; }
  .hud-time .flap, .hud-money .flap { font-size: 1rem; }
  .hud-money .flap-cur { font-size: 0.85rem; }
  .hud-num { font-size: 1.1rem; }
  .hud-loc { flex: 1 1 3rem; min-width: 0; } .hud-loc .hud-txt { min-width: 0; max-width: 100%; }
  .hud-menu { padding: 0 0.7rem; min-width: 2.9rem; }
  /* the three vitals hang under the strip as a small pill on the right instead of squeezing it */
  body[data-hud="full"] .hud-vitals { position: absolute; right: 0.6rem; top: 3.25rem; height: 1.7rem; padding: 0 0.6rem; gap: 0.5rem; border: 0; border-radius: 0.9rem; background: var(--hud-bg); pointer-events: auto; }
  body[data-hud="full"] .hud-vitals::before { display: none; }
  body[data-hud="full"] .hud-vitals .hud-vital .bar { width: 2.2rem; height: 0.38rem; }
  body[data-hud="full"] .hud-seg:nth-last-child(2) { --br: linear-gradient(var(--hud-bg), var(--hud-bg)); }
  #ui-root > .objective { max-width: calc(100vw - 1.8rem); }
  .objective-card { padding: 0.4rem 0.75rem 0.45rem 0.75rem; } .objective-text { font-size: 0.86rem; }
  body:has(.side-panel:not(.side-left)) #ui-root > .toasts { right: 0.6rem; width: calc(100vw - 1.2rem); }
}
@media (max-height: 30rem) {
  body[data-hud="full"] { --hud-h: 3.4rem; } body[data-hud="compact"] { --hud-h: 3rem; }
  #ui-root > .hud { padding-top: 0.3rem; }
  body[data-hud="full"] .hud-strip { height: 2.8rem; } body[data-hud="compact"] .hud-strip { height: 2.5rem; }
  .hud-lbl { margin-bottom: 0.1rem; }
}
/* station: the compass chip would sit on the vitals pill / objective card of a portrait phone, so it moves above the prompt */
@media (max-width: 40rem) { body.tc-on .st-goal { top: auto; bottom: calc(env(safe-area-inset-bottom, 0px) + 17rem); } }
body.touch-ui .map-ctl button { width: max(44px, 3rem); height: max(44px, 3rem); }
/* the sheet handle and header are swipe surfaces: the generic 'manipulation' above would let the browser claim the pan */
body.touch-ui #ui-root .mp-handle, body.touch-ui #ui-root .map-panel .panel-head { touch-action: none; }
/* thumb-sized panel controls */
body.touch-ui .map-panel .tab { min-height: 44px; }
body.touch-ui .map-panel .btn, body.touch-ui .map-panel .pick-row { min-height: 44px; }
body.touch-ui .map-panel .ft-change { padding: 1rem .8rem; margin: -1rem -.8rem; }
body.touch-ui .map-panel input[type="checkbox"] { width: 22px; height: 22px; }
/* phones: while the plan's "Go to the station" dock is up, the Pass / Journal / End trip row steps aside (more room for the itineraries) */
@media (max-width: 40rem), (max-height: 30rem) {
  body.touch-ui .map-panel:has(.mp-dock:not(.hidden)) .panel-foot { display: none; }
}
@media (max-height: 30rem) {   /* landscape phones: no legend (it would cover a third of the map), reserve checkbox and the Go button share one row */
  body.touch-ui .map-root .map-legend { display: none; }
  body.touch-ui .map-panel .mp-dock { display: flex; align-items: center; gap: .6rem; }
  body.touch-ui .map-panel .mp-dock .check { flex: 0 1 11rem; font-size: .74rem; line-height: 1.15; }
  body.touch-ui .map-panel .mp-dock .btn { flex: 1 1 auto; width: auto; }
}
body.touch-ui .map-ctl { gap: .5rem; }
body.touch-ui .btn .kbd { display: none; }
/* thumb-sized controls everywhere: buttons, the dialog cross, sliders, the title's "next view" chip */
body.touch-ui #ui-root .btn { min-height: 44px; }
body.touch-ui #ui-root .btn-icon, body.touch-ui #ui-root .modal-close { min-width: 44px; min-height: 44px; }
body.touch-ui input.range { height: 2.5rem; }
body.touch-ui input.range::-webkit-slider-thumb { width: 1.7rem; height: 1.7rem; margin-top: -0.6rem; }
body.touch-ui input.range::-moz-range-thumb { width: 1.4rem; height: 1.4rem; }
body.touch-ui button.tt-caption { min-height: 40px; }
