/* ════════════════════════════════════════════════════════════════════
   Hegemony Mini App — single stylesheet. Design: "Hegemony Gazette"
   (design/gazette/design-system): the app is set like a 19th-century
   newspaper. The rules, and why they are worth keeping:

     1. PRINTED IN INK, NOT LIGHT. Ink is the only brand colour: the one
        filled button per screen is ink with paper text. No gradients,
        no glow, no shadows in the chrome.
     2. COLOUR IS DATA. Bright hues belong to the powers only (swatches,
        the map). Text next to a power's colour is set in ink.
     3. RULES INSTEAD OF CARDS. Sections are separated by typographic
        rules (hairline, heavy, double); corners are 2px at most, except
        avatars and the round typewriter keys over the map.
     4. TYPE: Old Standard TT headlines, Source Serif 4 text, Barlow
        Condensed caps for buttons/labels/stamps, Courier Prime for order
        notation, deadlines and ids. Grenze Gotisch sets only "Hegemony".
     5. 44px minimum tap target, 16px inputs (no iOS focus zoom),
        safe-area padding, no hover-only affordances.

   The MAP block (#map-wrap / #map / svg, history bar, province
   highlights, order arrows) is intentionally left exactly as it has
   always behaved and looked.
   ════════════════════════════════════════════════════════════════════ */

:root, :root[data-theme="paper"] {
  /* ── Hegemony Gazette tokens (design/gazette/design-system/tokens.json).
     Day edition here, night edition below; the only values in the app. */
  --hg-paper: #ede4d0; --hg-paper-raised: #f5efe1; --hg-paper-sunk: #e2d7bf;
  --hg-ink: #1d1913; --hg-ink-2: #4b4236; --hg-ink-3: #625747; --hg-rule-soft: #b9ad94;
  --hg-press: #2b4a6f; --hg-ochre: #b8872b; --hg-on-ochre: #1d1913; --hg-ochre-tint: #ecd9ad;
  --hg-olive: #4b6636; --hg-oxblood: #8b2c22;
  --hg-desk: #5b4332;
  color-scheme: light;
}
:root[data-theme="night"] {
  --hg-paper: #17140f; --hg-paper-raised: #221e17; --hg-paper-sunk: #1c1813;
  --hg-ink: #ece3ce; --hg-ink-2: #c4b8a0; --hg-ink-3: #9a8f7b; --hg-rule-soft: #3d362b;
  --hg-press: #8eaed4; --hg-ochre: #d2a64e; --hg-on-ochre: #17140f; --hg-ochre-tint: #3a2f19;
  --hg-olive: #9dbb7f; --hg-oxblood: #e08b7c;
  --hg-desk: #2e2219;
  color-scheme: dark;
}
:root {
  --hg-font-nameplate: "Grenze Gotisch", "UnifrakturMaguntia", serif;
  --hg-font-display: "Old Standard TT", "Times New Roman", serif;
  --hg-font-body: "Source Serif 4", Georgia, serif;
  --hg-font-label: "Barlow Condensed", "Arial Narrow", sans-serif;
  /* Courier Prime and Barlow Condensed have no Cyrillic. iOS falls back to
     Courier New for it; Android has no Courier New, so IBM Plex Mono (a
     typewriter-like face with Cyrillic, loaded only for those glyphs)
     keeps Russian looking the same on both. */
  --hg-font-mono: "Courier Prime", "Courier New", "IBM Plex Mono", monospace;

  /* The older names every rule below was written against, mapped onto
     the Gazette: paper for surfaces, ink for text and the one filled
     control, press for links. */
  --accent:    var(--hg-ink);
  --accent-hi: var(--hg-ink-2);
  --accent-lo: var(--hg-ink-2);
  --on-accent: var(--hg-paper);
  --accent-wash: var(--hg-paper-sunk);

  --bg:        var(--hg-paper);
  --bg-deep:   var(--hg-paper-sunk);
  --surface:   var(--hg-paper-raised);
  --raised:    var(--hg-paper-sunk);

  --line:      var(--hg-rule-soft);
  --text:      var(--hg-ink);
  --dim:       var(--hg-ink-2);
  --faint:     var(--hg-ink-3);
  --fill:      var(--hg-paper-sunk);

  /* The map keeps its own selection/arrow colour — the map is not
     redesigned. */
  --gold:      #7cded8;
  /* Border of a province painted in an empire's colour. Neutral on
     purpose — empire-coloured borders were dropped (b72fa14) — and dark
     because the SVG's own #999 vanishes into mid-tone tints. */
  --map-owned-border: rgba(0, 0, 0, 0.55);

  /* State only — never style. Ochre is never text on paper (contrast),
     so "warning" text is ink on an ochre-tint notice instead. */
  --green:     var(--hg-olive);
  --green-ink: var(--hg-paper);
  --red:       var(--hg-oxblood);
  --orange:    var(--hg-ochre);
  --cyan:      var(--hg-press);

  /* Shape. Capsule = action; card = container. */
  --r-card: 16px;
  --r-btn:  10px;
  --r-pill: 999px;
  /* Gazette corners: soft, never sharp. Tags and stamps / buttons and
     fields / sheets, slips and dispatches. */
  --hg-r-sm: 6px;
  --hg-r:    10px;
  --hg-r-lg: 16px;
  /* Device inset (system navigation: ~48px with Android 3-button nav,
     0–24px with gestures, 0 outside fullscreen) PLUS Telegram's own
     content inset. They must be SUMMED — the old var() fallback chain
     collapsed to the content inset, which is defined-but-0px at the
     bottom on 8.0+ clients, so the 3-button nav bar height was ignored
     and the floating bottom controls slid under the system buttons. */
  --safe-b: calc(
    var(--tg-safe-area-inset-bottom, env(safe-area-inset-bottom, 0px)) +
    var(--tg-content-safe-area-inset-bottom, 0px)
  );
  --safe-t: var(--tg-content-safe-area-inset-top, var(--tg-safe-area-inset-top, env(safe-area-inset-top, 0px)));
}

* { box-sizing: border-box; margin: 0; padding: 0; -webkit-tap-highlight-color: transparent; }
html, body { height: 100%; overflow: hidden; }
body {
  background: var(--bg);
  color: var(--text);
  font: 400 15px/1.45 var(--hg-font-body);
  -webkit-font-smoothing: antialiased;
  display: flex; flex-direction: column;
  overscroll-behavior: none;
}
h1, h2, h3 { letter-spacing: -0.3px; }

/* ─── Buttons ─────────────────────────────────────────────────────── */
/* The default button is the *secondary* one: a neutral fill, no border
   heavier than a hairline, and a capsule so it reads as an action. */
.btn {
  background: var(--fill);
  color: var(--text);
  border: 1px solid transparent;
  border-radius: var(--r-pill);
  padding: 10px 18px;
  min-height: 46px;
  font: inherit; font-size: 15px; font-weight: 600;
  cursor: pointer;
  flex: 1 1 auto;
  min-width: 80px;
  transition: transform .12s cubic-bezier(0, 0, 0.58, 1),
              background-color .12s ease;
}
.btn:active { transform: scale(0.97); background: rgba(235, 235, 245, 0.18); }
/* One filled capsule per screen. Gold with a near-black label — white on
   gold fails contrast, which is exactly why the system pairs them. */
.btn-primary {
  background: var(--accent);
  color: var(--on-accent);
  font-weight: 600;
}
.btn-primary:active { background: var(--accent-lo); }
.btn-cancel {
  background: rgba(255, 69, 58, 0.14);
  color: var(--red);
  border-color: transparent;
}
.btn-cancel:active { background: rgba(255, 69, 58, 0.24); }
.btn-back {
  background: var(--fill);
  color: var(--accent);
  border-color: transparent;
  flex: 0 0 auto;
  min-width: 44px;
  padding: 8px 14px;
  font-size: 17px; font-weight: 600;
}
.floating-back {
  position: absolute;
  top: 12px; left: 12px;
  z-index: 100;
  padding: 0; min-width: 44px; width: 44px; height: 44px;
  border-radius: 22px;
  display: flex; align-items: center; justify-content: center;
  /* Floats over the board, so this one keeps a legibility shadow —
     there is no surface behind it to step up from. */
  background: rgba(11, 13, 18, 0.72);
  -webkit-backdrop-filter: blur(12px) saturate(160%);
  backdrop-filter: blur(12px) saturate(160%);
  border: 1px solid var(--line);
}

/* Ready / state colours (classes are swapped from JS). */
.btn-ready-on { background: var(--green); color: var(--green-ink); border-color: transparent; font-weight: 600; }
/* "All orders set, ready?" prompt: amber, so it doesn't look like the
   green "already ready" state. Green only after you press Ready. */
.btn-ready-prompt {
  background: var(--accent) !important;
  color: var(--on-accent) !important;
  border-color: transparent !important;
  font-weight: 600;
  animation: ready-prompt-pulse 1.6s ease-in-out infinite;
}
@keyframes ready-prompt-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(227, 180, 87, 0.45); }
  50%      { box-shadow: 0 0 0 7px rgba(227, 180, 87, 0); }
}
/* Someone who asked not to see motion gets the button, not the pulse. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}
/* Idle Ready button: quiet gold outline so the main action is findable
   at a glance; the state classes above repaint it completely. Dark base —
   it floats straight over the map now, a translucent skin would wash out. */
#btn-ready:not(.btn-ready-on):not(.btn-ready-prompt) {
  background: rgba(11, 13, 18, 0.82);
  -webkit-backdrop-filter: blur(12px) saturate(160%);
  backdrop-filter: blur(12px) saturate(160%);
  border-color: rgba(227, 180, 87, 0.45);
  color: var(--accent);
}
#btn-ready { font-weight: 600; }

/* ─── Lobby & tournament screens ──────────────────────────────────── */
/* Flat ground. The old radial wash was doing the job a surface step does
   better, and it fought every card that sat on top of it. */
#lobby, #tournament-view, #award-room-view, #leaderboard-view {
  flex: 1; overflow-y: auto; overflow-x: hidden; -webkit-overflow-scrolling: touch;
  padding: max(calc(var(--safe-t) + 12px), 52px) 16px calc(48px + var(--safe-b));
  background: var(--bg);
}
.lobby-header {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; margin-bottom: 14px;
}
/* Large title: the one place tracking goes negative. */
.lobby-header h2 {
  font-size: 30px; font-weight: 700; line-height: 1.1;
  letter-spacing: -0.7px;
  color: var(--text);
}
/* Shortcut row for Award Room / Leaderboard — separate line above cards. */
.lobby-shortcuts {
  display: flex; gap: 8px; margin-bottom: 14px;
}
.lobby-shortcuts .btn {
  flex: 1;
  font-size: 14px; font-weight: 600;
  padding: 8px 0;
  border-radius: var(--r-card, 12px);
  background: var(--fill);
  color: var(--text);
  border: 1px solid var(--line);
}
/* Language picker — quiet ghost pill, deliberately understated. */
#lang-select {
  -webkit-appearance: none; appearance: none;
  flex: 0 0 auto;
  background: var(--fill);
  color: var(--dim);
  border: 1px solid transparent;
  border-radius: var(--r-pill);
  min-height: 34px; padding: 5px 12px;
  font: inherit; font-size: 13px; font-weight: 600; text-align: center;
  cursor: pointer;
}
/* Encryption button — same quiet ghost pill as the language picker, not a
   full-size action button. The ID beats the .btn class still on the element. */
#btn-encryption {
  flex: 0 0 auto;
  min-width: 0;
  min-height: 34px;
  padding: 5px 11px;
  border-radius: var(--r-pill);
  background: var(--fill);
  border: 1px solid transparent;
  font-size: 15px; line-height: 1;
}
.lobby-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 16px; }
/* Icon-only, so language-independent width — all 4 fit one row on any
   phone (an earlier text-label version needed 2x2 wrapping to avoid
   overflow with long RU/DE/UA labels; no longer needed). */
.lobby-tabs { display: flex; gap: 6px; margin-bottom: 8px; }
.finished-filter { display: flex; flex-direction: column; gap: 6px; margin-bottom: 8px; }
.finished-filter-row { display: flex; gap: 6px; }
.finished-filter-row select { flex: 1 1 0; min-width: 0; }
.lobby-tab {
  flex: 1 1 0;
  min-height: 40px; padding: 6px 4px; border-radius: var(--r-pill);
  background: var(--fill); border: 1px solid transparent; color: var(--dim);
  font-size: 18px; text-align: center;
}
.lobby-tab.active { background: var(--accent); color: var(--on-accent); border-color: transparent; }
/* A grouped-list caption: quiet, uppercase, no decoration around it.
   The gap above it is what separates the sections. */
.lobby-section-label {
  display: flex; align-items: center;
  color: var(--dim); font-size: 12px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.6px;
  margin: 28px 4px 10px;
}
.lobby-empty { color: var(--dim); text-align: center; margin-top: 48px; line-height: 1.7; }
.note-dim  { color: var(--dim); font-size: 13px; }
.note-warn { color: var(--orange); }

/* ─── Game cards ──────────────────────────────────────────────────── */
.game-card {
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: 16px;
  margin-bottom: 10px;
  transition: transform .12s cubic-bezier(0, 0, 0.58, 1);
}
.game-card:active { transform: scale(0.985); }
.game-card-header { display: flex; justify-content: space-between; align-items: flex-start; gap: 8px; margin-bottom: 8px; }
.game-card h3 {
  font-size: 17px; font-weight: 600; line-height: 1.3;
  letter-spacing: -0.2px;
  flex: 1; color: var(--text);
}
/* A badge is information, not an action: tinted, never solid, so it can
   never be mistaken for the one filled capsule on the card. */
.status-badge {
  font-size: 11px; font-weight: 600; padding: 3px 9px;
  border-radius: var(--r-pill);
  white-space: nowrap; letter-spacing: 0.2px;
}
.status-lobby    { background: var(--accent-wash);          color: var(--accent); }
.status-active   { background: rgba(8, 214, 162, 0.15);     color: var(--green); }
.status-finished { background: var(--fill);                 color: var(--dim); }
.game-card .meta {
  color: var(--dim); font-size: 12.5px; margin-bottom: 9px;
  display: flex; gap: 10px; flex-wrap: wrap;
}
.game-card .meta span { display: inline-flex; align-items: center; gap: 4px; }
.meta-sub { margin-top: -2px; }
.empire-pill {
  display: inline-block; padding: 2px 9px; border-radius: 10px;
  font-weight: 700; font-size: 12px;
  border: 1px solid rgba(0, 0, 0, 0.3);
}
/* One column width for every chip, whatever its label: a grid, not a
   wrapping row of content-sized pills. */
.empire-chips { display: grid; grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); gap: 7px; }
.lobby-card-actions {
  margin-top: 12px; display: flex; justify-content: flex-end;
  gap: 8px; flex-wrap: wrap;
}
.lobby-card-actions .btn {
  min-height: 42px; padding: 8px 13px; font-size: 14px;
}
.join-code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-weight: 600; letter-spacing: 1.5px;
  padding: 2px 9px; border-radius: 7px;
  background: var(--accent-wash);
  color: var(--accent);
  border: none;
  cursor: pointer; user-select: all;
}
.join-code:active { background: rgba(227, 180, 87, 0.26); }
.card-dismiss {
  background: transparent; border: none; cursor: pointer;
  color: var(--dim); font-size: 16px; line-height: 1;
  min-width: 32px; min-height: 32px; border-radius: 8px;
}
.card-dismiss:active { color: var(--red); background: rgba(255, 69, 58, 0.14); }
.btn-leave { min-height: 38px; padding: 6px 12px; font-size: 13px; min-width: 0; flex: 0 1 auto; }

/* Empire chips — background/text colours are set inline per empire. */
/* Empire chips carry their power's own colour inline — the one place a
   second hue is allowed, because the colour IS the data. */
.empire-chip {
  display: inline-flex; align-items: center; justify-content: center;
  height: 36px; min-width: 0; padding: 0 10px; border-radius: var(--r-pill);
  font-size: 13px; font-weight: 600; cursor: pointer;
  border: 2px solid rgba(0, 0, 0, 0.25);
  white-space: nowrap; overflow: hidden;
  transition: transform .1s cubic-bezier(0, 0, 0.58, 1), box-shadow .1s;
  user-select: none;
}
/* A long "Empire (player)" label is cut with an ellipsis (full text in the
   title) rather than stretching its chip. */
.empire-chip-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.empire-chip .award-badge { width: 20px; height: 20px; margin: 0 0 0 3px; }
.empire-chip:active { transform: scale(0.92); }
.empire-chip.taken { opacity: 0.3; cursor: not-allowed; box-shadow: none; }
/* Joinable state (new or replace) — frame to indicate it's available */
.empire-chip.joinable {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent);
}
/* "This is my empire" — cyan, chosen because no empire in any of our
   maps uses a cyan-ish colour, so the ring stays visible even on a
   yellow chip (Turkey, Cuba, etc.). */
.empire-chip.mine {
  border-color: var(--cyan);
  box-shadow: 0 0 0 2px var(--cyan);
  opacity: 1 !important;
}
.empire-chip.locked { cursor: default; opacity: 0.6; }

/* ─── Forms (create game / sandbox / find by id) ──────────────────── */
.form-card h3 { margin-bottom: 6px; }
.form-note { font-size: 12.5px; color: var(--dim); margin-bottom: 6px; }
.field-label {
  display: block; margin: 18px 0 6px;
  font-size: 12px; font-weight: 600; letter-spacing: 0.6px;
  text-transform: uppercase; color: var(--dim);
}
/* A field is a tinted well, not a boxed border. Focus is the only place
   a 2px line appears anywhere in the app. */
.field-input {
  width: 100%; min-height: 48px; padding: 12px 14px;
  border-radius: var(--r-btn); border: 1px solid transparent;
  background: var(--fill); color: var(--text);
  font: inherit; font-size: 16px;   /* 16px stops the iOS focus-zoom */
  transition: border-color .12s ease, background-color .12s ease;
}
.field-input::placeholder { color: var(--faint); }
.field-input:focus {
  outline: none;
  background: var(--bg-deep);
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent);
}
select.field-input { -webkit-appearance: none; appearance: none; }
textarea.field-input { min-height: 92px; line-height: 1.5; resize: vertical; }
.check-row {
  display: flex; align-items: center; gap: 10px;
  margin: 13px 0; font-size: 14px; min-height: 28px;
}
.check-row input { width: 22px; height: 22px; accent-color: var(--green); flex: 0 0 auto; }
.hint-text { color: var(--dim); }
.form-actions { display: flex; gap: 8px; margin-top: 16px; }
/* The code IS the screen — display size, tracked out so six characters
   read as six discrete characters. */
.code-input {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 26px; font-weight: 600;
  letter-spacing: 8px; text-align: center;
  color: var(--accent);
}

/* ─── Tournament ──────────────────────────────────────────────────── */
/* Was a purple-to-blue gradient — a second and third brand colour in a
   one-accent system. Now it is a card with an accent rule, which is how
   the rest of the app says "this one matters". */
.tournament-banner {
  background: var(--surface);
  color: var(--text); padding: 14px 16px; border-radius: var(--r-card);
  margin-bottom: 14px; cursor: pointer;
  border: 1px solid var(--line);
  border-left: 3px solid var(--accent);
  transition: transform .12s cubic-bezier(0, 0, 0.58, 1);
}
.tournament-banner:active { transform: scale(0.985); }
.tournament-banner h3 { margin: 0 0 3px 0; font-size: 17px; font-weight: 600; line-height: 1.3; letter-spacing: -0.2px; color: var(--text); }
.tournament-banner .sub { font-size: 13px; color: var(--dim); }
.tournament-banner .arrow { float: right; color: var(--faint); font-size: 18px; }
.tournament-banner .banner-close { float: right; background: none; border: 0; padding: 0 0 0 10px;
  color: var(--faint); font-size: 16px; line-height: 1; cursor: pointer; }
#android-banner { margin-top: 8px; }
.view-header { display: flex; gap: 10px; align-items: center; margin-bottom: 14px; }
.view-header h2 {
  margin: 0; flex: 1; min-width: 0;
  font-size: 22px; font-weight: 700; line-height: 1.2;
  letter-spacing: -0.4px; color: var(--text);
}
.t-desc { white-space: pre-wrap; margin: 8px 0; }
#t-games > p { color: var(--dim); }
.game-card.tournament-game { border-left: 3px solid var(--accent); }
.tournament-tag {
  display: inline-block; font-size: 11px; font-weight: 600;
  background: var(--accent-wash); color: var(--accent);
  padding: 2px 8px; border-radius: var(--r-pill);
  margin-left: 6px; vertical-align: 2px;
}

/* ─── Game view: header + sandbox strip ───────────────────────────── */
/* Sits UNDER the info header, so no safe-area offset of its own. */
#sandbox-switcher {
  padding: 5px 10px;
  background: var(--bg-deep); border-bottom: 1px solid var(--line);
  overflow-x: auto; white-space: nowrap; -webkit-overflow-scrolling: touch;
}
.sandbox-label { font-size: 13px; color: var(--dim); margin-right: 6px; }
/* Room number in the sandbox strip — sandboxes are private, so this id is
   the only way to hand the room to a spectator. */
#sandbox-room { font-size: 12px; color: var(--dim); margin-right: 10px; }
#sandbox-room .join-code { font-size: 12px; letter-spacing: 1px; }
.sandbox-chip {
  display: inline-block; margin: 2px 3px; padding: 5px 11px;
  border-radius: 14px; border: 1.5px solid #888;
  background: transparent; color: #ccc;
  font: inherit; font-size: 12px; font-weight: 600; cursor: pointer;
}

/* ─── Layout Helpers ────────────────────────────────────────────────── */
.safe-area-deadzone {
  height: max(var(--safe-t, 0px), 52px);
  width: 100%;
  flex-shrink: 0;
}

/* Slim one-row top bar: orientation only (who/when). */
#header {
  padding: max(calc(var(--safe-t) + 4px), 8px) 20vw 8px;
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center;
}
#header .info { flex: 1; min-width: 0; font-size: 14px; line-height: 1.35; color: var(--dim); }
#header .info strong {
  font-size: 17px; font-weight: 600; line-height: 1.2;
  letter-spacing: -0.2px;
  color: var(--accent);   /* overridden per-empire from JS */
}
#g-deadline { color: var(--dim); font-size: 13px; font-variant-numeric: tabular-nums; }

/* Action row at the top of the bottom panel — the thumb zone. The icon
   toolbar is one segmented group; Ready fills the remaining width.
   Wraps when crowded (e.g. the 💬 chat button appears). */
.panel-actions {
  display: flex; gap: 8px; align-items: stretch; flex-wrap: wrap;
  pointer-events: none;   /* row is overlay-transparent, buttons catch taps */
}
/* Segmented control floating over the board. Concentric corners: the
   26px outer pill minus 3px padding leaves 23px for the inner buttons. */
.toolbar-group {
  display: flex; gap: 2px; align-items: center;
  flex:   0 1 auto;
  background: rgba(11, 13, 18, 0.82);
  -webkit-backdrop-filter: blur(16px) saturate(160%);
  backdrop-filter: blur(16px) saturate(160%);
  border: 1px solid var(--line);
  border-radius: 26px;
  padding: 3px;
}
.toolbar-group .btn {
  background: transparent; border: none; box-shadow: none;
  flex: 0 0 auto;
  width: 40px; min-width: 36px;
  height: 40px; min-height: 40px;
  padding: 0; font-size: 17px;
  border-radius: 23px;
}
.toolbar-group .btn:active { background: rgba(235, 235, 245, 0.16); transform: none; }
.toolbar-group .btn-cancel { background: rgba(255, 69, 58, 0.14); }
.toolbar-group .btn.btn-ready-on { background: var(--accent); color: var(--on-accent); }
/* ☰ toggle that the toolbar collapses into. */
#btn-menu {
  flex: 0 0 auto;
  width: 52px; min-width: 52px; min-height: 46px;
  padding: 0; font-size: 19px;
}
#btn-menu.menu-open {
  background: var(--accent-wash);
  border-color: rgba(227, 180, 87, 0.5);
  color: var(--accent);
}
/* Preview mode hides every button in the group — collapse its chrome
   too (progressive enhancement; without :has it's a tiny empty pill). */
.toolbar-group:not(:has(button:not([style*="none"]))) { display: none; }
#btn-ready { flex:   1 1 auto; min-width: 96px; min-height: 46px; }

.quota-badge {
  display: inline-block; margin-left: 6px; padding: 2px 9px;
  border-radius: 10px; font-size: 12px; font-weight: 700;
  vertical-align: middle;
}
.quota-build  { background: rgba(8, 214, 162, 0.18); color: var(--green); }
.quota-disband{ background: rgba(255, 69, 58, 0.18);  color: var(--red); }
.quota-warn   { background: rgba(255, 159, 10, 0.18); color: var(--orange); }

/* ─── In-game banners ─────────────────────────────────────────────── */
/* Banners are a surface step with a coloured rule, not a tinted wash —
   a pale Material tint reads as broken on a dark ground. */
#draw-banner {
  background: var(--surface);
  color: var(--text); padding: 11px 14px; font-size: 14px;
  border-bottom: 1px solid var(--line);
  border-left: 3px solid var(--orange);
  display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
}
#draw-banner .text { flex: 1 1 auto; min-width: 0; }
#draw-banner .btn { min-height: 36px; min-width: 0; padding: 6px 12px; font-size: 13px; flex: 0 0 auto; }
#deadline-banner {
  background: var(--surface);
  color: var(--orange); font-weight: 600; padding: 10px 12px;
  font-size: 14px; border-bottom: 1px solid var(--line);
  border-left: 3px solid var(--orange);
  text-align: center;
}

/* ─── Map (same placement, sizing, layout; only the desk around it) ── */
/* Around the board is the editor's desk: wood grain (fractal noise
   stretched along the fibres) over --hg-desk. The map lies on it as a
   printed sheet (map.js drawMapSheet); the sheet is paper and ink in both
   editions, like the map itself, which is not themed. */
#map-wrap { flex: 1; overflow: hidden; position: relative;
  background: var(--hg-desk) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='600' height='600'%3E%3Cfilter id='g' x='0' y='0'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.003 0.11' numOctaves='4' seed='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0.05 0 0 0 0 0.03 0 0 0 0 0.01 0 0 0 -1.6 1.05'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
  /* The map keeps the font it always had: its SVG text inherits it. */
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Inter", system-ui, Roboto, "Helvetica Neue", sans-serif; }
#map { width: 100%; height: 100%; overflow: hidden; touch-action: none; }
#map svg { width: 100%; height: 100%; display: block; touch-action: none; user-select: none; }
#hg-sheet .hg-sheet-paper { fill: #efe6cf; }
#hg-sheet .hg-sheet-ink { fill: #2b251c; }
#hg-sheet .hg-sheet-rule { fill: none; stroke: #2b251c; }
#hg-sheet .hg-sheet-shadow { fill: #000; fill-opacity: .45; stop-color: #000; stop-opacity: .45; }
#hg-sheet .hg-sheet-shadow-end { stop-color: #000; stop-opacity: 0; }

.prov-clickable { cursor: pointer; }
/* Painted provinces (map.js colorProvinces sets data-tint). */
#map svg [data-tint] { stroke: var(--map-owned-border); }
.prov-selected { stroke: var(--gold) !important; stroke-width: 3px !important; }
/* During "Move where?" / support / convoy / retreat target selection the
   whole map is dimmed except the legal targets, via a masked #dim-overlay
   rect built in orders_ui.js — the destinations stay lit and pop. */

#zoom-controls {
  position: absolute; top: 10px; right: 10px;
  display: flex; flex-direction: column; gap: 6px; z-index: 5;
}
#zoom-controls button {
  width: 42px; height: 42px; border-radius: 12px;
  background: rgba(16, 26, 50, 0.78);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  color: #dfe6ff; border: 1px solid var(--line);
  font-size: 20px; cursor: pointer;
}
#zoom-controls button:active { filter: brightness(1.4); }

/* Floating pill above the bottom controls. */
#history-bar {
  align-items: center; justify-content: center; gap: 6px;
  width: max-content; max-width: 100%;
  margin: 0 auto;
  white-space: nowrap;
  background: rgba(16, 26, 50, 0.88);
  color: var(--gold); border: 1px solid var(--line);
  padding: 4px 7px; border-radius: 16px;
  font-size: 10px; font-weight: 700;
}
.hist-btn {
  background: none; border: none; color: var(--gold);
  font-size: 11px; min-width: 25px; min-height: 22px; cursor: pointer;
  border-radius: 11px;
}
.hist-btn:disabled { color: #5b6889; cursor: default; }
.hist-btn:active:not(:disabled) { background: rgba(255, 209, 102, 0.15); }

/* Order arrows. Colour, width (1.5× the original) and dash are set
   inline per order (empire colour, plus a red outline on failures). */
.arrow        { fill: none; pointer-events: none; stroke-linecap: round; stroke-linejoin: round; }
.arrow-marker { fill: var(--gold); stroke: #1a1a2e; stroke-width: 1.5; pointer-events: none; }

/* ─── Bottom controls (order buttons, ☰, Ready) ───────────────────── */
/* No solid panel any more: the controls float straight over the map,
   which always fills the screen — nothing ever reflows or "jumps" the
   board. The container itself is tap-transparent: the map stays
   pannable/tappable between the floating controls. */
#game-view { position: relative; }
#panel {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 20;
  display: flex; flex-direction: column; gap: 8px;
  padding: 0 12px calc(12px + var(--safe-b));
  pointer-events: none;
}
#panel .btn,
#panel .toolbar-group,
#panel #history-bar,
#panel #observer-roster { pointer-events: auto; }

/* Status hint: tap-transparent pill at the top of the map, between the
   floating back button (left) and the zoom controls (right). */
#hint {
  position: absolute; top: 12px; left: 64px; right: 60px; z-index: 5;
  background: rgba(16, 26, 50, 0.78);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 7px 12px;
  font-size: 12.5px; line-height: 1.35; color: #dfe6ff;
  text-align: center;
  pointer-events: none;
}
#buttons { display: flex; flex-wrap: wrap; gap: 8px; pointer-events: none; }
#buttons:empty { display: none; }
#buttons .btn { min-height: 48px; }
/* The translucent red "cancel" skin was tuned for the solid panel — over
   the open map it needs a dark base to stay readable. */
#panel .btn-cancel {
  background: rgba(48, 16, 16, 0.86);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
}

#observer-roster {
  background: rgba(11, 13, 18, 0.82);
  -webkit-backdrop-filter: blur(16px) saturate(160%);
  backdrop-filter: blur(16px) saturate(160%);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: 8px 14px;
}
#observer-roster .row {
  display: flex; align-items: center; gap: 8px;
  min-height: 40px; padding: 2px 0; font-size: 14px;
  border-bottom: 1px solid var(--line);
}
#observer-roster .row:last-child { border-bottom: none; }
#observer-roster .dot {
  width: 11px; height: 11px; border-radius: 50%; flex: 0 0 auto;
  border: 1px solid rgba(0, 0, 0, 0.4);
}
#observer-roster a { color: var(--accent); text-decoration: none; }
#observer-roster a:hover { text-decoration: underline; }
#observer-roster .empire { color: var(--dim); font-size: 12px; margin-left: auto; }
.roster-title {
  font-size: 12px; font-weight: 600; letter-spacing: 0.6px;
  text-transform: uppercase; color: var(--dim); margin-bottom: 4px;
}

/* ─── Error toast / fatal panel ───────────────────────────────────── */
#error-banner {
  position: fixed; top: 50%; left: 16px; right: 16px; transform: translateY(-50%);
  text-align: center;
  background: var(--red); color: #fff;
  padding: 13px 16px; font-size: 15px; font-weight: 600;
  border-radius: var(--r-btn); border: none;
  z-index: 100; display: none;
  animation: toast-in-center .18s cubic-bezier(0, 0, 0.58, 1);
}
@keyframes toast-in-center {
  from { opacity: 0; transform: translateY(calc(-50% - 8px)); }
  to   { opacity: 1; transform: translateY(-50%); }
}
#toast-banner {
  position: fixed; top: max(calc(var(--safe-t) + 80px), 100px); left: 50%; transform: translateX(-50%);
  background: rgba(32, 36, 45, 0.94); color: var(--text);
  padding: 9px 18px; font-size: 15px; font-weight: 600;
  border-radius: var(--r-pill); border: 1px solid var(--line);
  -webkit-backdrop-filter: blur(16px) saturate(160%);
  backdrop-filter: blur(16px) saturate(160%);
  z-index: 100; display: none; white-space: pre-line; text-align: center;
  animation: toast-in-pill .18s cubic-bezier(0, 0, 0.58, 1);
}
@keyframes toast-in-pill {
  from { opacity: 0; transform: translate(-50%, -8px); }
  to   { opacity: 1; transform: translate(-50%, 0); }
}
@keyframes toast-in {
  from { opacity: 0; transform: translateY(-8px); }
  to   { opacity: 1; transform: none; }
}
.fatal-panel {
  margin: 36px auto; max-width: 380px; padding: 24px 20px;
  border-radius: var(--r-card);
  background: var(--surface);
  border: 1px solid var(--line);
  text-align: center; font-size: 15px;
}
.fatal-icon   { font-size: 34px; line-height: 1; margin-bottom: 12px; opacity: 0.5; }
.fatal-title  { font-weight: 600; margin-bottom: 6px; font-size: 17px; letter-spacing: -0.2px; }
.fatal-msg    { color: var(--dim); }
.fatal-reload { margin-top: 16px; min-width: 140px; flex: 0 0 auto; }

/* ─── Rules agreement modal ───────────────────────────────────────── */
.modal-backdrop {
  position: fixed; inset: 0; z-index: 200;
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
  background: rgba(0, 0, 0, 0.55);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  animation: toast-in .15s cubic-bezier(0, 0, 0.58, 1);
}
.modal-card {
  width: 100%; max-width: 420px; max-height: 82vh;
  display: flex; flex-direction: column;
  padding: 22px 20px calc(18px + var(--safe-b));
  border-radius: 24px;
  background: var(--surface);
  border: 1px solid var(--line);
}
.modal-card h3 { margin-bottom: 12px; }
.settings-card { overflow-y: auto; -webkit-overflow-scrolling: touch; }
.settings-header { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 12px; }
.settings-header h3 { margin: 0; }
.settings-close-top { flex-shrink: 0; }
.settings-profile-section h4 { margin: 0 0 10px; }
.settings-profile-body .profile-hero { padding: 13px; }
.settings-avatar-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.settings-avatar-actions .btn { flex: 1 1 auto; }
#settings-avatar-status { min-height: 18px; margin-top: 7px; }
.rules-text {
  flex: 1 1 auto; min-height: 40px; overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 13px 15px; border-radius: var(--r-btn);
  background: var(--bg-deep); border: 1px solid var(--line);
  color: var(--text); font-size: 15px; line-height: 1.55;
  white-space: pre-wrap; word-break: break-word;
}
.rules-agree-row { margin: 14px 0 4px; }

/* ─── Full-screen overlays (nickname gate, encryption sheet) ───────── */
/* Both are built in JS (profile.js, crypto.js). They used to carry their
   own hardcoded navy palette inline, which is how they drifted out of the
   design system; the styling lives here now and the scripts only set the
   class. */
.crypto-overlay {
  position: fixed; inset: 0; z-index: 9999;
  display: flex; align-items: center; justify-content: center;
  padding: 18px; overflow: auto;
  background: rgba(0, 0, 0, 0.55);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
}
.overlay-card {
  max-width: 440px; width: 100%;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 24px;
  padding: 22px 20px;
  color: var(--text);
}
.overlay-card h2 { margin: 0 0 6px; font-size: 22px; font-weight: 700; letter-spacing: -0.4px; }
.overlay-card p  { margin: 0 0 14px; color: var(--dim); font-size: 15px; line-height: 1.45; }
.overlay-card .btn { width: 100%; margin-top: 14px; }
/* Inputs and code blocks inside an overlay: same tinted well as a form. */
.overlay-field {
  width: 100%; box-sizing: border-box;
  background: var(--fill); color: var(--text);
  border: 1px solid transparent; border-radius: var(--r-btn);
  padding: 12px 14px; font: inherit; font-size: 16px;
}
.overlay-field::placeholder { color: var(--faint); }
.overlay-field:focus { outline: none; background: var(--bg-deep); border-color: var(--accent); }
.overlay-code {
  display: block; background: var(--bg-deep);
  border: 1px solid var(--line); border-radius: var(--r-btn);
  padding: 10px 12px; font-size: 13px; word-break: break-all;
  margin-bottom: 10px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.overlay-fingerprint {
  font-size: 17px; letter-spacing: 2px; text-align: center;
  color: var(--accent); word-break: normal;
}
.overlay-error { color: var(--red); font-size: 13px; margin-top: 8px; }

/* ─── Game master's panel (master.js) ──────────────────────────────── */
.master-panel { display: flex; flex-direction: column; overflow: hidden; max-height: 86vh; }
.master-panel-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; -webkit-overflow-scrolling: touch; }
.master-panel .master-phase { margin-bottom: 4px; }
.master-label { color: var(--dim); font-size: 12px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; margin: 14px 0 6px; }
.master-extend { display: flex; gap: 8px; }
.overlay-card .master-extend .btn { margin-top: 0; flex: 1; }
.master-seat { border-top: 1px solid var(--line); padding: 10px 0; }
.master-seat.out { opacity: 0.55; }
.master-seat-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.master-seat .dot { display: inline-block; width: 10px; height: 10px; border-radius: 50%; margin-right: 6px; }
.master-seat-status { color: var(--dim); font-size: 13px; white-space: nowrap; }
.master-orders { margin: 6px 0 0; padding-left: 18px; font-size: 13px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
.master-orders.none { padding-left: 0; color: var(--faint); font-family: inherit; }
.overlay-card .master-seat .master-kick,
.overlay-card .master-seat .master-freeze { width: auto; margin-top: 8px; padding: 6px 12px; font-size: 13px; }
.overlay-card .master-orders .master-cancel-order { width: auto; margin: 0 0 0 6px; padding: 0 8px; min-height: 0; line-height: 1.5; font-size: 14px; }

/* ─── How to play (tutorial.js) ────────────────────────────────────── */
/* Both sheets keep one height whatever the step or tab holds: the middle
   scrolls, and the buttons stay put under the thumb. */
.tutorial-card, .avatar-editor { display: flex; flex-direction: column; overflow: hidden; }
/* The guide opens on its own: clear of Telegram's Close / ⋯ overlay at the
   top, like the other full screens. */
.tutorial-card { height: min(100%, 700px); }
#tutorial-overlay { padding: max(calc(var(--safe-t) + 12px), 52px) 16px calc(12px + var(--safe-b)); }
/* The avatar editor opens from Settings and lies exactly over that sheet. */
#avatar-editor-overlay { padding: 20px; }
.avatar-editor { max-width: 420px; height: 82vh; }
.tutorial-body, .avatar-editor-body {
  flex: 1 1 auto; min-height: 0; overflow-y: auto; -webkit-overflow-scrolling: touch;
}
.tutorial-top { display: flex; align-items: center; justify-content: space-between; min-height: 28px; margin-bottom: 6px; }
.tutorial-count { color: var(--dim); font-size: 13px; font-variant-numeric: tabular-nums; }
.tutorial-skip {
  background: none; border: 0; padding: 4px 0; cursor: pointer;
  color: var(--dim); font: inherit; font-size: 14px; text-decoration: underline;
}
.tutorial-nav { display: flex; gap: 10px; flex: none; }
.tutorial-nav .btn { flex: 1; }
.tutorial-nav .btn[disabled] { opacity: 0.4; }
/* The schematic boards, drawn on the map's own paper with the board's
   colours: "you" and "them" and every arrow read the same in any edition. */
.tut-art { display: block; width: 100%; max-width: 320px; margin: 4px auto 14px; }
.tut-sheet { fill: #e6dbbf; }
.tut-prov { fill: #f4ecd6; stroke: #8a7a5a; stroke-width: 1.2; }
.tut-prov.sea { fill: #b7cfe2; stroke: #7d8fa3; }
.tut-label, .tut-caption { fill: #5a4c34; font-size: 11px; text-anchor: middle; }
.tut-unit { stroke: #1f2a36; stroke-width: 1; }
.tut-unit.you { fill: #b0553f; }
.tut-unit.them { fill: #4f6d9a; }
.tut-unit-letter { fill: #fff; font-size: 13px; font-weight: 700; text-anchor: middle; }
.tut-icon .fill { stroke: #1f2a36; stroke-width: 1; stroke-linejoin: round; }
.tut-icon .stroke { fill: none; stroke: #1f2a36; stroke-width: 1; stroke-linejoin: round; stroke-linecap: round; }
.tut-icon.you .fill { fill: #b0553f; }
.tut-icon.them .fill { fill: #4f6d9a; }
.tut-arrow { fill: none; stroke-width: 3; stroke-linecap: round; }
.tut-arrow.you, .tut-head.you, .tut-dot.you { stroke: #b0553f; fill: #b0553f; }
.tut-arrow.them, .tut-head.them { stroke: #4f6d9a; fill: #4f6d9a; }
.tut-arrow.ink, .tut-head.ink { stroke: #5a4c34; fill: #5a4c34; }
.tut-arrow.you, .tut-arrow.them, .tut-arrow.ink { fill: none; }
.tut-arrow.ink { stroke-width: 2; stroke-dasharray: 1 5; }
.tut-support { stroke-width: 2.5; stroke-dasharray: 4 3; stroke-linecap: butt; }
.tut-dot { stroke: none; }
.tut-bounce { fill: #b03030; font-size: 22px; font-weight: 700; text-anchor: middle; }
.tut-shot { margin: 4px 0 14px; }
.tut-shot img {
  display: block; width: 100%; height: auto; aspect-ratio: 3 / 2;
  border-radius: 12px; border: 1px solid var(--line); background: var(--fill);
}
.tut-shot figcaption { margin-top: 6px; color: var(--dim); font-size: 13px; line-height: 1.4; }
.settings-help-row { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; }
.settings-help-row .btn { flex: 1 1 140px; }
.settings-legal { font-size: 15px; line-height: 1.8; }
.settings-legal a, .overlay-card a[data-legal] { color: var(--accent); text-decoration: underline; }
.settings-credits { font-size: 12px; margin: 8px 0 0; }
#settings-delete-account { width: 100%; margin-top: 12px; }

/* ─── In-game chat ─────────────────────────────────────────────────── */
/* Unread pill on the 💬 toolbar button. */
.chat-badge {
  position: absolute; top: -4px; right: -4px;
  min-width: 18px; height: 18px; padding: 0 5px;
  border-radius: var(--r-pill); background: var(--red); color: #fff;
  font-size: 11px; font-weight: 600; line-height: 18px; text-align: center;
}
#btn-chat { position: relative; overflow: visible; }

/* The chat view's shell — ℹ️ info page (#info-view) and 📰 gazette (#gazette-view) share it. */
#chat-view, #info-view, #player-profile-view, #gazette-view {
  flex: 1; min-height: 0; flex-direction: column; height: 100%;
  padding: max(calc(var(--safe-t) + 12px), 52px) 16px calc(8px + var(--safe-b));
  background: var(--bg);
}
#chat-view .view-header, #info-view .view-header, #player-profile-view .view-header, #gazette-view .view-header { flex: 0 0 auto; }
#chat-view #chat-title, #gazette-view #gazette-title { flex: 1; }
#chat-view #chat-new-btn { flex: 0 0 auto; min-width: 0; }

#chat-list, #info-body, #player-profile-body, #gazette-body { flex: 1; min-height: 0; overflow-y: auto; -webkit-overflow-scrolling: touch; }
#chat-new { flex: 1; min-height: 0; overflow-y: auto; }
.chat-empty { color: var(--dim); text-align: center; margin-top: 40px; line-height: 1.7; }

.chat-conv {
  background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--r-card);
  padding: 13px 15px; margin-bottom: 8px; cursor: pointer;
  transition: transform .12s cubic-bezier(0, 0, 0.58, 1);
}
.chat-conv:active { transform: scale(0.99); }
.chat-conv-top { display: flex; align-items: center; gap: 8px; }
.chat-conv-title { font-weight: 600; font-size: 17px; letter-spacing: -0.2px; flex: 1; display: flex; align-items: center; gap: 5px; flex-wrap: wrap; }
.chat-conv-preview { color: var(--dim); font-size: 14px; margin-top: 4px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.chat-dot { width: 11px; height: 11px; border-radius: 50%; display: inline-block;
  border: 1px solid rgba(0,0,0,0.3); flex: 0 0 auto; }
/* The unread count is the one badge that uses the accent: it is the
   reason you are looking at this row. */
.chat-unread-badge {
  background: var(--accent); color: var(--on-accent); font-weight: 600; font-size: 12px;
  min-width: 22px; height: 22px; line-height: 22px; text-align: center;
  border-radius: var(--r-pill); padding: 0 7px; flex: 0 0 auto;
}
.chat-muted-tag { font-size: 12px; opacity: 0.8; }

/* Thread */
#chat-thread { flex: 1; min-height: 0; flex-direction: column; }
#chat-thread-header {
  flex: 0 0 auto; display: flex; align-items: center; gap: 8px;
  padding: 4px 2px 10px; border-bottom: 1px solid var(--line); margin-bottom: 8px;
}
.chat-members { flex: 1; display: flex; flex-wrap: wrap; gap: 8px; }
.chat-member { display: inline-flex; align-items: center; gap: 5px; font-size: 14px; font-weight: 600; }
.chat-mute-btn { min-height: 36px; padding: 6px 12px; font-size: 13px; flex: 0 0 auto; }

#chat-messages { flex: 1; min-height: 0; overflow-y: auto; -webkit-overflow-scrolling: touch;
  display: flex; flex-direction: column; gap: 8px; padding: 4px 2px; }
.chat-msg { max-width: 82%; align-self: flex-start; }
.chat-msg.mine { align-self: flex-end; }
.chat-msg-who { font-size: 11px; font-weight: 600; margin: 0 0 3px 6px; }
.chat-msg-time {
  display: block; text-align: right; font-size: 10px;
  color: var(--dim); margin-top: 3px; letter-spacing: 0.3px;
}
.chat-msg.mine .chat-msg-time { color: rgba(23, 18, 10, 0.55); }
/* Day / turn separators between messages. */
.chat-divider {
  align-self: center; max-width: 92%; text-align: center;
  font-size: 11px; color: var(--dim); margin: 4px 0 0;
}
.chat-divider.chat-turn {
  font-size: 11px; font-weight: 600; letter-spacing: 0.6px;
  text-transform: uppercase; color: var(--accent);
  background: var(--accent-wash);
  border: none;
  border-radius: var(--r-pill); padding: 3px 11px;
}
/* Copy-by-long-press: on touch the webview's own selection popup would
   hijack the gesture, so suppress it there. Mouse users keep normal
   text selection. */
@media (hover: none) {
  .chat-bubble { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
}
#chat-messages.selecting .chat-msg { cursor: pointer; }
.chat-msg.selected .chat-bubble {
  border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-wash);
}
#chat-select-bar {
  flex: 0 0 auto; align-items: center; gap: 8px;
  padding: 4px 2px 8px; border-bottom: 1px solid var(--line); margin-bottom: 6px;
}
#chat-select-count { flex: 1; font-size: 14px; font-weight: 600; color: var(--accent); }
#chat-select-bar .btn { min-height: 36px; padding: 6px 12px; font-size: 13px; flex: 0 0 auto; }
/* Bubbles: theirs is a surface step, mine is the accent. Gold carries a
   near-black label — the same pairing as every filled control. */
.chat-bubble {
  background: var(--surface); border: 1px solid var(--line);
  padding: 9px 13px; border-radius: 18px; border-bottom-left-radius: 6px;
  font-size: 15px; line-height: 1.4; white-space: pre-wrap; word-break: break-word;
}
.chat-msg.mine .chat-bubble {
  background: var(--accent); color: var(--on-accent);
  border-color: transparent; border-radius: 18px; border-bottom-right-radius: 6px;
}

#chat-composer { flex: 0 0 auto; display: flex; gap: 8px; align-items: flex-end; padding-top: 8px; }
#chat-input {
  flex: 1; min-height: 44px; max-height: 120px; resize: none;
  padding: 11px 16px; border-radius: 22px; border: 1px solid transparent;
  background: var(--fill); color: var(--text); font: inherit; font-size: 16px;
}
#chat-input::placeholder { color: var(--faint); }
#chat-input:focus { outline: none; background: var(--bg-deep); border-color: var(--accent); }
#chat-send { flex: 0 0 auto; min-height: 44px; }

/* ─── Game info (ℹ️) — shell shared with #chat-view above ──────────── */
.info-meta { color: var(--dim); font-size: 14px; margin: 0 2px 10px; }
.info-card {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-card);
  padding: 13px 15px; margin-bottom: 8px;
}
.info-svg { display: block; }
.info-grid { stroke: var(--line); stroke-width: 1; }
.info-win-line { stroke: var(--faint); stroke-width: 1; stroke-dasharray: 4 3; }
.info-tick { fill: var(--dim); font-size: 11px; font-variant-numeric: tabular-nums; }
.info-line { fill: none; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.info-sel { stroke: var(--dim); stroke-width: 1; stroke-dasharray: 2 3; }
.info-sel-dot { stroke: var(--surface); stroke-width: 1.5; }
.info-player { display: flex; align-items: center; gap: 10px; margin-top: 6px; }
.info-player[hidden] { display: none; }
.info-play { flex: 0 0 auto; min-width: 40px; min-height: 36px; padding: 4px 10px; }
.info-scrub { flex: 1; min-width: 0; accent-color: var(--accent); }
.info-point { flex: 0 0 auto; min-width: 3.5em; text-align: right; color: var(--dim);
  font-size: 13px; font-variant-numeric: tabular-nums; }
.info-row { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; padding: 8px 0; }
.info-row + .info-row { border-top: 1px solid var(--line); }
.info-row-main { flex: 1; min-width: 0; }
.info-row-empire { font-weight: 600; font-size: 15px; }
.info-row-player { color: var(--dim); font-size: 13px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.info-row-count { font-size: 14px; font-variant-numeric: tabular-nums; flex: 0 0 auto; }
.info-win { color: var(--dim); font-size: 14px; text-align: center; margin: 6px 0 12px; }

/* ─── Gazette (📰) ─────────────────────────────────────────────────── */
#gazette-view #gazette-year {
  flex: 0 0 auto;
  width: auto;
  min-width: 80px;
  min-height: 36px;
  padding: 4px 10px;
  font-family: var(--hg-font-mono);
  font-size: 14px;
  font-weight: 700;
  background: var(--hg-paper-raised);
  color: var(--hg-ink);
  border: 1px solid var(--hg-ink);
  border-radius: var(--hg-r-sm);
  cursor: pointer;
}
.gz-issue {
  padding: 4px 0 24px;
}
.gz-masthead {
  font-family: var(--hg-font-nameplate);
  font-size: clamp(24px, 7vw, 36px);
  font-weight: 700;
  line-height: 1.15;
  text-align: center;
  color: var(--hg-ink);
  padding: 4px 0 8px;
  border-bottom: 3px double var(--hg-ink);
  margin-bottom: 6px;
}
.gz-dateline {
  font-family: var(--hg-font-mono);
  font-size: 12px;
  text-align: center;
  color: var(--hg-ink-2);
  padding-bottom: 10px;
  border-bottom: 1px solid var(--hg-rule-soft);
  margin-bottom: 14px;
}
.gz-rubric {
  font-family: var(--hg-font-label);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--hg-ink-2);
  margin: 18px 0 8px;
  padding-bottom: 4px;
  border-bottom: 1.5px solid var(--hg-ink);
}
.gz-article {
  margin-bottom: 16px;
}
.gz-article:last-child {
  margin-bottom: 0;
}
.gz-headline {
  font-family: var(--hg-font-display);
  font-size: 19px;
  font-weight: 700;
  line-height: 1.25;
  color: var(--hg-ink);
  margin-bottom: 6px;
}
.gz-lead .gz-headline {
  font-size: 22px;
  line-height: 1.2;
}
.gz-image {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--hg-rule-soft);
  border-radius: var(--hg-r-sm);
  margin: 8px 0 10px;
  mix-blend-mode: multiply;
}
:root[data-theme="night"] .gz-image {
  mix-blend-mode: normal;
}
.gz-body {
  font-family: var(--hg-font-body);
  font-size: 15px;
  line-height: 1.5;
  color: var(--hg-ink);
}
.gz-body p {
  margin-bottom: 8px;
  text-align: left;
}
.gz-body p:last-child {
  margin-bottom: 0;
}
.gz-ledger {
  width: 100%;
  border-collapse: collapse;
  margin: 16px 0 12px;
  font-family: var(--hg-font-mono);
  font-size: 13px;
  border-top: 1.5px solid var(--hg-ink);
  border-bottom: 1.5px solid var(--hg-ink);
}
.gz-ledger tr {
  border-bottom: 1px solid var(--hg-rule-soft);
}
.gz-ledger tr:last-child {
  border-bottom: none;
}
.gz-ledger td {
  padding: 5px 10px 5px 4px;
  vertical-align: middle;
}
.gz-ledger-cell {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.gz-ledger-name {
  font-family: var(--hg-font-label);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--hg-ink);
}
.gz-ledger-sc {
  text-align: right;
  font-weight: 700;
  color: var(--hg-ink);
  white-space: nowrap;
}
.gz-ledger-delta {
  text-align: right;
  font-weight: 700;
  width: 52px;
  white-space: nowrap;
}
.gz-ledger-delta.gz-pos {
  color: var(--hg-olive);
}
.gz-ledger-delta.gz-neg {
  color: var(--hg-oxblood);
}
.gz-ledger-delta.gz-zero {
  color: var(--hg-ink-3);
}
.gz-empty {
  color: var(--hg-ink-2);
  text-align: center;
  margin-top: 48px;
  line-height: 1.7;
  font-family: var(--hg-font-body);
  font-style: italic;
}

.player-profile-link {
  appearance: none; border: 0; padding: 0; background: none; color: var(--accent);
  font: inherit; text-align: left; cursor: pointer; max-width: 100%;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.player-profile-link:hover { text-decoration: underline; }
.profile-hero {
  display: flex; align-items: center; gap: 16px; padding: 18px;
  margin-bottom: 10px; background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-card);
}
.profile-avatar {
  width: 72px; height: 72px; border-radius: 50%; display: grid; place-items: center;
  flex: 0 0 auto; font-size: 34px; background: var(--fill); border: 1px solid var(--line);
}
.profile-avatar img {
  width: 100%; height: 100%; object-fit: cover; border-radius: inherit;
}
/* Small inline avatar next to a nickname — lobby tiles, roster, chat,
   info, leaderboard. Distinct from .profile-avatar (the big profile-hero
   circle), same visual language. */
.mini-avatar {
  width: 20px; height: 20px; border-radius: 50%; object-fit: cover;
  flex: 0 0 auto; vertical-align: middle; background: var(--fill);
  border: 1px solid var(--line); margin-right: 4px;
}
/* Order badges next to a nickname — square (not round, to read as a
   medal/insignia rather than a second avatar), tappable (awards.js). */
.award-badge {
  width: 36px; height: 36px; object-fit: contain;
  flex: 0 0 auto; vertical-align: middle; margin-right: 2px;
  cursor: pointer; border-radius: 3px;
}
/* Can be opened from inside another modal (e.g. the settings sheet,
   z-index 1000) — must stack above whatever's already open. */
#award-modal { z-index: 1100; }
.award-modal-image {
  display: block; max-width: 100%; max-height: 360px; margin: 0 auto 12px;
  object-fit: contain;
}
.award-modal-description {
  color: var(--dim); font-size: 14px; white-space: pre-wrap;
}
/* Own profile: orders + medals, same badge size as .profile-avatar
   context but a touch bigger than the inline nickname ones. */
.profile-awards {
  display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 10px;
}
.profile-awards img {
  width: 72px; height: 72px; object-fit: contain; cursor: pointer;
  border-radius: 6px; background: var(--fill); border: 1px solid var(--line);
  padding: 2px;
}
.profile-awards-label {
  font-size: 12px; font-weight: 600; letter-spacing: 0.6px;
  text-transform: uppercase; color: var(--dim); margin: 10px 0 4px;
}
.profile-display-name { font-size: 21px; font-weight: 700; overflow-wrap: anywhere; }
.profile-elo { margin-top: 5px; color: var(--accent); font-size: 17px; font-weight: 600; }
.profile-rank {
  display: inline-block; font-size: 12px; font-weight: 600;
  background: var(--accent-wash); color: var(--accent);
  padding: 2px 8px; border-radius: var(--r-pill); vertical-align: 2px;
}
.profile-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 7px; margin-bottom: 10px; }
.profile-stat {
  min-width: 0; padding: 12px 5px; text-align: center; background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--r-btn);
}
.profile-stat strong { display: block; font-size: 20px; }
.profile-map-tabs { overflow-x: auto; margin: 8px 0 10px; }
.profile-map-tabs .lobby-tab { flex: 1 0 auto; font-size: 13px; white-space: nowrap; padding: 6px 10px; }
.profile-stat span { display: block; margin-top: 3px; color: var(--dim); font-size: 11px; }
.profile-missed > div:first-child { display: flex; justify-content: space-between; gap: 12px; }
.profile-missed-detail { color: var(--dim); font-size: 13px; margin-top: 6px; }

/* Lobby card unread pill (notification dot). */
.lobby-chat-badge {
  display: inline-flex; align-items: center; gap: 4px;
  background: var(--accent-wash); color: var(--accent);
  border: none;
  font-size: 12px; font-weight: 600; padding: 3px 9px; border-radius: var(--r-pill);
}

/* ════════════════════════════════════════════════════════════════════
   Hegemony Gazette — every screen. The tokens above already turned the
   surfaces into paper and the text into ink; this block sets the type,
   the shapes and the few pieces that change form (cards → listings,
   badges → stamps, bubbles → dispatches, filled wells → ruled fields).
   ════════════════════════════════════════════════════════════════════ */
h1, h2, h3, h4 { font-family: var(--hg-font-display); font-weight: 700; letter-spacing: 0; }
.hg-ico {
  width: 20px; height: 20px; flex: 0 0 auto; fill: none; stroke: currentColor; stroke-width: 1.7;
  stroke-linecap: round; stroke-linejoin: round; pointer-events: none; vertical-align: -4px;
}
hr.rule { border: 0; border-top: 1px solid var(--hg-rule-soft); margin: 15px 0; }
/* Classic-design emoji that sit next to the line icons in the markup. */
.c-ico { display: none; }

/* Buttons: secondary = ink outline, primary = solid ink, danger = oxblood
   outline. Pressing sinks the button a pixel, like type into paper. */
.btn {
  background: transparent; color: var(--hg-ink);
  border: 1.5px solid var(--hg-ink); border-radius: var(--hg-r);
  font-family: var(--hg-font-label); font-weight: 600; font-size: 15px;
  letter-spacing: .08em; text-transform: uppercase;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  transition: transform .06s, background-color .06s;
}
.btn:active { transform: translateY(1px); background: var(--hg-paper-sunk); }
.btn-primary { background: var(--hg-ink); color: var(--hg-paper); border-color: var(--hg-ink); }
.btn-primary:active { background: var(--hg-ink-2); }
.btn-primary:disabled { background: var(--hg-ink-3); border-color: var(--hg-ink-3); cursor: default; }
.btn-cancel { background: transparent; color: var(--hg-oxblood); border-color: var(--hg-oxblood); }
.btn-cancel:active { background: var(--hg-paper-sunk); }
.btn-back {
  background: transparent; border-color: transparent; color: var(--hg-ink);
  font-family: var(--hg-font-display); font-size: 26px; font-weight: 400; letter-spacing: 0;
  padding: 0 8px; min-width: 44px;
}
.btn:focus-visible, .lobby-tab:focus-visible, .field-input:focus-visible { outline: 2px solid var(--hg-press); outline-offset: 2px; }

#toast-banner {
  background: var(--hg-ink); color: var(--hg-paper); border: 0; border-radius: var(--r-pill);
  -webkit-backdrop-filter: none; backdrop-filter: none;
  font-family: var(--hg-font-label); letter-spacing: .06em;
}
#error-banner { background: var(--hg-paper-raised); color: var(--hg-oxblood); border: 1.5px solid var(--hg-oxblood); }
.fatal-panel { background: var(--hg-paper-raised); border: 1.5px solid var(--hg-ink); }
.note-warn { color: var(--hg-ink); background: var(--hg-ochre-tint); border-left: 3px solid var(--hg-ochre); border-radius: var(--hg-r-sm); padding: 2px 8px; }

/* ─── Lobby: the front page ─── */
.masthead { text-align: center; border-top: 1.5px solid var(--hg-ink); border-bottom: 3px double var(--hg-ink); margin-bottom: 14px; }
.nameplate {
  font-family: var(--hg-font-nameplate); font-weight: 600; font-size: 46px; line-height: 1;
  color: var(--hg-ink); padding: 8px 0 6px;
}
.lobby-header { margin: 4px 0 12px; }
.lobby-header h2 { font-family: var(--hg-font-display); font-size: 26px; letter-spacing: 0; }
#btn-encryption, #btn-notifications, #btn-settings {
  width: 44px; min-width: 44px; min-height: 44px; padding: 0;
  background: transparent; border: 1.5px solid var(--hg-ink); border-radius: var(--hg-r); color: var(--hg-ink);
}
.lobby-shortcuts .btn {
  background: transparent; color: var(--hg-ink); border: 1.5px solid var(--hg-ink); border-radius: var(--hg-r);
  font-size: 14px; min-height: 44px;
}
.lobby-tabs { gap: 0; border: 1.5px solid var(--hg-ink); border-radius: var(--hg-r); overflow: hidden; }
.lobby-tab {
  border-radius: 0; background: transparent; color: var(--hg-ink-3); border: 0; min-height: 42px;
  display: inline-flex; align-items: center; justify-content: center;
}
.lobby-tab + .lobby-tab { border-left: 1.5px solid var(--hg-ink); }
.lobby-tab.active { background: var(--hg-ink); color: var(--hg-paper); }
.lobby-section-label {
  font-family: var(--hg-font-label); font-size: 14px; font-weight: 600; letter-spacing: .08em;
  color: var(--hg-ink); margin: 22px 0 0; padding-bottom: 5px; border-bottom: 1.5px solid var(--hg-ink);
}
.lobby-empty { font-style: italic; color: var(--hg-ink-3); }

/* A game is a listing between hairlines, not a floating card. */
.game-card {
  background: transparent; border: 0; border-bottom: 1px solid var(--hg-rule-soft); border-radius: 0;
  padding: 14px 4px; margin: 0;
}
.game-card:active { transform: none; background: var(--hg-paper-sunk); }
.form-card:active { background: transparent; }
.form-card { border-bottom: 3px double var(--hg-ink); padding: 16px 0 20px; }
.game-card h3 { font-family: var(--hg-font-display); font-size: 18px; font-weight: 700; letter-spacing: 0; }
.game-card .meta { font-family: var(--hg-font-mono); font-size: 12.5px; color: var(--hg-ink-3); }
.game-card .meta:not(.meta-sub) { gap: 4px 6px; }
.game-card .meta:not(.meta-sub) > span:not(.status-badge) + span:not(.status-badge)::before { content: "·"; margin-right: 6px; }
.game-card code { font-family: var(--hg-font-mono); }
/* Status badges are rubber stamps. */
.status-badge, .tournament-tag, .profile-rank {
  background: transparent; border: 1.5px solid currentColor; border-radius: var(--hg-r-sm);
  font-family: var(--hg-font-label); font-weight: 700; font-size: 12px; letter-spacing: .1em;
  text-transform: uppercase; padding: 1px 7px 0; transform: rotate(-2deg);
}
.status-lobby, .tournament-tag, .profile-rank { background: transparent; color: var(--hg-press); }
.status-active { background: transparent; color: var(--hg-ink); }
.status-finished { background: transparent; color: var(--hg-ink-3); }
.empire-pill, .empire-chip { border-radius: var(--hg-r-sm); border: 1px solid var(--hg-ink); font-family: var(--hg-font-label); letter-spacing: .06em; text-transform: uppercase; }
.empire-chip.joinable { border-color: var(--hg-ink); box-shadow: 0 0 0 2px var(--hg-ink); }
.empire-chip.mine { border-color: var(--hg-press); box-shadow: 0 0 0 2px var(--hg-press); }
.join-code {
  font-family: var(--hg-font-mono); background: transparent; color: var(--hg-press);
  border-radius: 0; border-bottom: 1px dashed var(--hg-press); padding: 0 2px;
}
.join-code:active { background: var(--hg-paper-sunk); }
.card-dismiss { color: var(--hg-ink-3); }
.card-dismiss:active { color: var(--hg-oxblood); background: var(--hg-paper-sunk); }
.lobby-chat-badge, .chat-unread-badge {
  background: var(--hg-ink); color: var(--hg-paper); border-radius: var(--r-pill);
  font-family: var(--hg-font-mono); font-weight: 700;
}
.tournament-banner { background: var(--hg-paper-raised); border: 1.5px solid var(--hg-ink); border-radius: var(--hg-r-lg); }
.tournament-banner h3 { font-family: var(--hg-font-display); font-size: 18px; }
.view-header h2 { font-family: var(--hg-font-display); font-size: 24px; letter-spacing: 0; }
.view-header { border-bottom: 1.5px solid var(--hg-ink); padding-bottom: 8px; }

/* ─── Forms: ruled fields, like a form printed in the paper ─── */
/* A field is filled with the sheet it lies on, never transparent: Telegram's
   Android WebView re-contrasts the text of a see-through field against an
   assumed white ground, so night-edition cream ink (and the caret) turned
   dark on dark and typing looked blank. */
.modal-card, .overlay-card { --hg-field-bg: var(--hg-paper-raised); }
.field-label { font-family: var(--hg-font-label); font-size: 12px; letter-spacing: .1em; color: var(--hg-ink-2); }
.field-input, #lang-select.field-input, .overlay-field {
  background-color: var(--hg-field-bg, var(--hg-paper)); color: var(--hg-ink);
  border: 0; border-bottom: 1.5px solid var(--hg-ink); border-radius: 0;
  padding: 10px 2px; min-height: 44px; font-family: var(--hg-font-body); font-size: 16px;
  text-align: left; font-weight: 400;
}
.field-input:focus, .overlay-field:focus {
  background-color: var(--hg-field-bg, var(--hg-paper)); border-color: var(--hg-press); box-shadow: 0 1.5px 0 var(--hg-press);
}
textarea.field-input { border: 1px solid var(--hg-ink); border-radius: var(--hg-r); padding: 10px 12px; }
select.field-input, #lang-select.field-input {
  background-image: linear-gradient(45deg, transparent 50%, var(--hg-ink) 50%), linear-gradient(135deg, var(--hg-ink) 50%, transparent 50%);
  background-position: calc(100% - 14px) 52%, calc(100% - 9px) 52%;
  background-size: 5px 5px; background-repeat: no-repeat; padding-right: 24px;
}
.check-row input { accent-color: var(--hg-ink); }
.hint-text, .form-note { font-style: italic; color: var(--hg-ink-3); }
.code-input { font-family: var(--hg-font-mono); color: var(--hg-ink); text-align: center; }

/* ─── Sheets: modals and full-screen overlays are paper laid on top ─── */
.modal-backdrop, .crypto-overlay {
  /* Always a darkening veil — ink turns cream in the night edition. */
  background: rgba(0, 0, 0, 0.45);
  -webkit-backdrop-filter: none; backdrop-filter: none;
}
.modal-card, .overlay-card {
  background: var(--hg-paper-raised); color: var(--hg-ink);
  border: 1.5px solid var(--hg-ink); border-top: 3px double var(--hg-ink); border-radius: var(--hg-r-lg);
}
.overlay-card h2 { font-family: var(--hg-font-display); letter-spacing: 0; }
.overlay-card p { color: var(--hg-ink-2); }
.rules-text { background: var(--hg-paper); border: 1px solid var(--hg-rule-soft); border-radius: var(--hg-r); }
.overlay-code { background: var(--hg-paper-sunk); border-color: var(--hg-rule-soft); border-radius: var(--hg-r); font-family: var(--hg-font-mono); }
.overlay-fingerprint { font-family: var(--hg-font-mono); color: var(--hg-ink); }

/* ─── Dispatches (chat) ─── */
.chat-conv {
  background: transparent; border: 0; border-bottom: 1px solid var(--hg-rule-soft); border-radius: 0;
  padding: 13px 2px; margin: 0;
}
.chat-conv:active { transform: none; background: var(--hg-paper-sunk); }
.chat-conv-title { font-family: var(--hg-font-display); font-size: 17px; letter-spacing: 0; }
.chat-conv-gazette { border-bottom: 2px solid var(--hg-ink); }
.chat-conv-gazette .hg-ico { stroke: var(--hg-ink); color: var(--hg-ink); }
.chat-conv-preview { font-style: italic; }
.chat-dot { border-radius: 3px; border: 0; outline: 1px solid var(--hg-ink); width: 10px; height: 10px; }
.chat-member { font-family: var(--hg-font-label); letter-spacing: .06em; text-transform: uppercase; }
/* Sender line: the empire colour stays as a swatch, the words are ink. */
.chat-msg-who {
  -webkit-text-fill-color: var(--hg-ink); font-family: var(--hg-font-label); font-size: 12px;
  letter-spacing: .08em; text-transform: uppercase; display: flex; align-items: center; gap: 4px; flex-wrap: wrap;
}
.chat-msg-who::before { content: ""; width: 10px; height: 10px; background: currentColor; outline: 1px solid var(--hg-ink); flex: 0 0 auto; }
.chat-bubble {
  background: var(--hg-paper-raised); border: 1px solid var(--hg-rule-soft); border-radius: var(--hg-r-lg); border-bottom-left-radius: var(--hg-r-sm); color: var(--hg-ink);
}
.chat-msg.mine .chat-bubble {
  background: var(--hg-paper-sunk); color: var(--hg-ink); border: 1px solid var(--hg-ink); border-radius: var(--hg-r-lg); border-bottom-right-radius: var(--hg-r-sm);
}
.chat-msg-time, .chat-msg.mine .chat-msg-time { color: var(--hg-ink-3); font-family: var(--hg-font-mono); }
.chat-msg.selected .chat-bubble { border-color: var(--hg-press); box-shadow: 0 0 0 2px var(--hg-press); }
.chat-divider { font-style: italic; color: var(--hg-ink-3); }
.chat-divider.chat-turn {
  background: transparent; color: var(--hg-ink-3); border-radius: 0; padding: 2px 0;
  font-family: var(--hg-font-label); font-style: normal; letter-spacing: .1em;
}
.chat-divider.chat-turn::before, .chat-divider.chat-turn::after { content: " — "; }
#chat-select-count { color: var(--hg-ink); }
#chat-input { background: var(--hg-paper-raised); border: 1px solid var(--hg-ink); border-radius: var(--hg-r-lg); }
#chat-input:focus { background: var(--hg-paper-raised); border-color: var(--hg-press); }
#chat-composer { border-top: 3px double var(--hg-ink); padding-top: 10px; }

/* ─── Game info, profile, leaderboard ─── */
.info-card { background: transparent; border: 0; border-top: 1.5px solid var(--hg-ink); border-radius: 0; padding: 12px 0; }
.info-row-empire { font-family: var(--hg-font-label); letter-spacing: .06em; text-transform: uppercase; }
.info-row-count, .info-meta { font-family: var(--hg-font-mono); }
.player-profile-link { color: var(--hg-press); }
.profile-hero { background: transparent; border: 0; border-bottom: 1.5px solid var(--hg-ink); border-radius: 0; padding: 16px 0; }
.profile-avatar { background: var(--hg-paper-sunk); border: 1.5px solid var(--hg-ink); font-family: var(--hg-font-display); }
.profile-display-name { font-family: var(--hg-font-display); font-size: 24px; }
.profile-elo { font-family: var(--hg-font-mono); color: var(--hg-ink); font-size: 15px; }
.profile-stats { gap: 0; border-bottom: 1px solid var(--hg-rule-soft); }
.profile-stat { background: transparent; border: 0; border-radius: 0; }
.profile-stat strong { font-family: var(--hg-font-display); font-size: 22px; }
.profile-stat span, .profile-awards-label, .roster-title { font-family: var(--hg-font-label); letter-spacing: .08em; text-transform: uppercase; }
.mini-avatar { border-color: var(--hg-ink); }
.idle-mark { color: var(--hg-ink-3); }
.settings-close-top { flex: 0 0 auto; }
.segment { display: flex; flex: 0 0 auto; border: 1.5px solid var(--hg-ink); border-radius: var(--hg-r); overflow: hidden; }
.segment button {
  flex: 1; min-height: 44px; border: 0; background: transparent; color: var(--hg-ink); cursor: pointer;
  font-family: var(--hg-font-label); font-weight: 600; font-size: 14px; letter-spacing: .08em; text-transform: uppercase;
}
.segment button + button { border-left: 1.5px solid var(--hg-ink); }
.segment button.is-on { background: var(--hg-ink); color: var(--hg-paper); }

/* ════════════════════════════════════════════════════════════════════
   Hegemony Gazette — game screen (stage 1 of the redesign).
   Source of truth: design/gazette/design-system (tokens.json, sheet 5).
   Only the chrome around the board changes: the map itself (#map, its
   svg, arrows, highlights) is untouched; around it is the desk (#map-wrap)
   the sheet lies on. Over the map sit only
   typewriter keys and paper slips; #panel stays tap-transparent.
   Theme: core.js sets data-theme on <html> from Telegram's colorScheme.
   ════════════════════════════════════════════════════════════════════ */

/* ─── Dateline (the thin strip above the map) ─── */
/* The whole dateline sits between Telegram's native header buttons
   (Close / ⋯ overlay the top corners in fullscreen, whatever safe-t says),
   so every line keeps the 20vw side padding (3fb0880). */
#game-view #header {
  background: var(--hg-paper); border-bottom: 3px double var(--hg-ink);
  padding: max(calc(var(--safe-t) + 4px), 8px) 20vw 6px;
}
/* Fluid sizes: everything over the map and in the dateline scales with the
   screen width, between a floor that is still easy to read/tap and the
   design size — so a 360px Android fits what a 402px iPhone does.
   --hg-key: seven menu keys + six 6px gaps fill the width inside the 16px
   gutters (360px → 42px, ≥376px → 44px). */
#game-view {
  --hg-key: clamp(36px, calc((100vw - 32px - 36px) / 7), 44px);
  --hg-key-lg: clamp(40px, calc(var(--hg-key) + 4px), 48px);
  --hg-fs-mono: clamp(10px, 2.9vw, 11.5px);
  --hg-fs-label: clamp(12px, 3.6vw, 14px);
}
#game-view #header .info { width: 100%; color: var(--hg-ink-3); font-family: var(--hg-font-mono); font-size: var(--hg-fs-mono); line-height: 1.4; }
#game-view .hdr-who { line-height: 1.35; }
#game-view .hdr-when { display: flex; flex-wrap: wrap; justify-content: center; align-items: baseline; gap: 3px 8px; }
/* Time to the turn's resolution: a clock plate whose colour says how close
   it is (lobby.js paintDeadline → .dl-calm / soon / urgent / over). It
   never breaks inside ("20 ч 5 м"): it moves down whole. */
#game-view #g-deadline:not(:empty) {
  display: inline-flex; align-items: center; gap: 4px; margin-left: 8px; padding: 0 6px;
  border: 1px solid var(--hg-ink); border-radius: var(--hg-r-sm);
  font-size: var(--hg-fs-mono); font-weight: 700; line-height: 17px; white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
#game-view #g-deadline:not(:empty)::before {
  --clock: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M12 7v5l3 2'/%3E%3C/svg%3E") center / contain no-repeat;
  content: ""; flex: none; width: 1.05em; height: 1.05em; background: currentColor;
  -webkit-mask: var(--clock); mask: var(--clock);
}
#game-view #g-deadline.dl-soon:not(:empty)   { background: var(--hg-ochre-tint); border-color: var(--hg-ochre); }
#game-view #g-deadline.dl-urgent:not(:empty) { background: var(--hg-oxblood); border-color: var(--hg-oxblood); color: var(--hg-paper); }
#game-view #g-deadline.dl-over:not(:empty)   { border-style: dashed; border-color: var(--hg-ink-3); color: var(--hg-ink-3); }
/* JS paints #g-empire in the empire colour; keep that colour for the
   swatch (currentColor) and set the text itself in ink. */
#game-view #header .info strong {
  font-family: var(--hg-font-label); font-weight: 600; font-size: var(--hg-fs-label); letter-spacing: .06em;
  text-transform: uppercase; -webkit-text-fill-color: var(--hg-ink); white-space: nowrap;
}
#game-view #header .info strong.has-empire::before {
  content: ""; display: inline-block; width: 11px; height: 11px; margin-right: 6px;
  background: currentColor; outline: 1px solid var(--hg-ink); vertical-align: 0;
}
#game-view #g-deadline { color: var(--hg-ink); font-family: var(--hg-font-mono); }
#game-view .quota-badge {
  border-radius: var(--hg-r-sm); padding: 0 6px; font-family: var(--hg-font-mono); font-size: var(--hg-fs-mono); font-weight: 700;
  line-height: 17px; color: var(--hg-ink); background: transparent; border: 1px solid var(--hg-ink);
}
#game-view .quota-warn    { background: var(--hg-ochre-tint); border-color: var(--hg-ochre); }
#game-view .quota-build   { border-color: var(--hg-olive); color: var(--hg-olive); }
#game-view .quota-disband { border-color: var(--hg-oxblood); color: var(--hg-oxblood); }

#game-view #sandbox-switcher { background: var(--hg-paper-sunk); border-bottom: 1px solid var(--hg-rule-soft); padding: 6px 16px; scroll-padding: 0 16px; }
#game-view .sandbox-label, #game-view #sandbox-room, #game-view #sandbox-room .join-code { color: var(--hg-ink-3); font-family: var(--hg-font-mono); }
#game-view .sandbox-chip { color: var(--hg-ink); background: transparent; border-radius: var(--hg-r-sm); font-family: var(--hg-font-label); letter-spacing: .06em; text-transform: uppercase; }

#game-view #draw-banner, #game-view #deadline-banner {
  background: var(--hg-paper-raised); color: var(--hg-ink);
  margin: 8px 16px 0; border: 1px solid var(--hg-rule-soft); border-left: 4px solid var(--hg-ochre);
  border-radius: var(--hg-r);
}
#game-view #draw-banner .btn {
  background: transparent; color: var(--hg-ink); border: 1.5px solid var(--hg-ink); border-radius: var(--hg-r);
  font-family: var(--hg-font-label); letter-spacing: .08em; text-transform: uppercase;
}
#game-view #draw-banner .btn-cancel { color: var(--hg-oxblood); border-color: var(--hg-oxblood); }

/* ─── Typewriter keys ─── */
#game-view .floating-back,
#game-view #btn-menu,
#game-view .toolbar-group .btn,
#game-view #btn-ready,
#game-view #buttons .btn {
  background: var(--hg-ink); color: var(--hg-paper);
  border: 1.5px solid var(--hg-ink); border-radius: 24px;
  box-shadow: inset 0 0 0 1.5px var(--hg-rule-soft), 0 2px 0 var(--hg-ink-3);
  -webkit-backdrop-filter: none; backdrop-filter: none;
  font-family: var(--hg-font-label); font-weight: 600; letter-spacing: .08em; text-transform: uppercase;
  display: inline-flex; align-items: center; justify-content: center;
  transition: transform .06s, box-shadow .06s;
}
#game-view .floating-back:active,
#game-view #btn-menu:active,
#game-view .toolbar-group .btn:active,
#game-view #btn-ready:active,
#game-view #buttons .btn:active {
  transform: translateY(1px); background: var(--hg-ink);
  box-shadow: inset 0 0 0 1.5px var(--hg-rule-soft), 0 1px 0 var(--hg-ink-3);
}
#game-view .floating-back, #game-view #btn-menu {
  width: var(--hg-key-lg); min-width: var(--hg-key-lg); height: var(--hg-key-lg); min-height: var(--hg-key-lg);
  padding: 0; flex: 0 0 auto;
}
/* Keys and slips stay clear of the screen edges. */
#game-view .floating-back { top: 14px; left: 16px; }
#game-view #panel { padding: 0 16px calc(16px + var(--safe-b)); }
#game-view .hg-ico { width: calc(var(--hg-key) * .44); height: calc(var(--hg-key) * .44); stroke-width: 1.5; fill: none; stroke: currentColor; stroke-linecap: round; stroke-linejoin: round; pointer-events: none; }
#game-view #btn-menu .ico-close, #game-view #btn-menu.menu-open .ico-menu { display: none; }
#game-view #btn-menu.menu-open .ico-close { display: block; }
#game-view #btn-menu.menu-open { transform: translateY(2px); box-shadow: inset 0 0 0 2px var(--hg-rule-soft), 0 1px 0 var(--hg-ink-3); }

/* The ☰ menu: keys simply slide out on their own row at the bottom,
   right above ☰, with air between them — no backing strip. */
#game-view .panel-actions { gap: 12px 8px; align-items: center; }
#game-view .toolbar-group {
  order: -1; flex: 1 0 100%; flex-wrap: wrap; gap: 8px 6px; padding: 0;
  background: none; border: 0; -webkit-backdrop-filter: none; backdrop-filter: none; pointer-events: none;
}
#game-view .toolbar-group .btn {
  width: var(--hg-key); min-width: var(--hg-key); height: var(--hg-key); min-height: var(--hg-key); padding: 0; border-radius: 50%;
  position: relative; overflow: visible; animation: hg-key-in .16s ease-out both;
}
#game-view .toolbar-group .btn:nth-child(2) { animation-delay: .02s; }
#game-view .toolbar-group .btn:nth-child(3) { animation-delay: .04s; }
#game-view .toolbar-group .btn:nth-child(4) { animation-delay: .06s; }
#game-view .toolbar-group .btn:nth-child(5) { animation-delay: .08s; }
#game-view .toolbar-group .btn:nth-child(6) { animation-delay: .10s; }
#game-view .toolbar-group .btn:nth-child(n+7) { animation-delay: .12s; }
@keyframes hg-key-in { from { opacity: 0; transform: translateY(14px); } }
/* Toggled keys (history shown, delay on) stay pressed with a press ring. */
#game-view .toolbar-group .btn.btn-ready-on {
  background: var(--hg-ink); color: var(--hg-paper); transform: translateY(2px);
  box-shadow: inset 0 0 0 2px var(--hg-press), 0 1px 0 var(--hg-ink-3);
}
#game-view .toolbar-group .btn-cancel,
#game-view #buttons .btn-cancel,
#game-view #panel .btn-cancel {
  background: var(--hg-paper-raised); color: var(--hg-oxblood); border-color: var(--hg-oxblood);
  box-shadow: inset 0 0 0 2px var(--hg-paper-raised), 0 3px 0 var(--hg-ink-3);
}
#game-view .chat-badge {
  top: -5px; right: -5px; background: var(--hg-paper); color: var(--hg-ink);
  border: 1.5px solid var(--hg-ink); font-family: var(--hg-font-mono); line-height: 15px; letter-spacing: 0;
}

/* Ready: a long space-bar key. Idle = outline; "all set" = ink; done = olive. */
#game-view #btn-ready { height: var(--hg-key-lg); min-height: var(--hg-key-lg); font-size: var(--hg-fs-label); padding: 0 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#game-view #btn-ready:not(.btn-ready-on):not(.btn-ready-prompt) {
  background: var(--hg-paper-raised); color: var(--hg-ink); border-color: var(--hg-ink);
}
#game-view #btn-ready.btn-ready-prompt {
  background: var(--hg-ink) !important; color: var(--hg-paper) !important; border-color: var(--hg-ink) !important;
  animation: none;
}
#game-view #btn-ready.btn-ready-on {
  background: var(--hg-paper-raised); color: var(--hg-olive); border-color: var(--hg-olive);
  box-shadow: inset 0 0 0 2px var(--hg-paper-raised), 0 1px 0 var(--hg-ink-3); transform: translateY(2px);
}

/* Unit orders (Hold / Move / Support / Convoy / ✕…): text keys. */
#game-view #buttons { gap: 10px 8px; }
#game-view #buttons .btn {
  /* Order keys wrap onto rows, so they keep the full 44px tap size. */
  flex: 0 1 auto; min-width: 44px; max-width: 100%; height: max(44px, var(--hg-key)); min-height: 44px;
  padding: 0 clamp(10px, 3.5vw, 16px); font-size: clamp(12px, 3.6vw, 14px);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  animation: hg-key-in .14s ease-out both;
}

/* ─── Paper slips over the map ─── */
#game-view #hint {
  top: 18px; left: calc(16px + var(--hg-key-lg) + 10px); right: 16px; padding: 7px clamp(8px, 3vw, 14px) 6px;
  background: var(--hg-paper-raised); color: var(--hg-ink);
  border: 1px solid var(--hg-rule-soft); border-radius: var(--hg-r);
  -webkit-backdrop-filter: none; backdrop-filter: none;
  font-family: var(--hg-font-mono); font-size: var(--hg-fs-mono); line-height: 1.35; letter-spacing: .02em; text-transform: uppercase;
}
#game-view #hint:empty, #game-view.hints-off #hint { display: none; }
#game-view #observer-roster, #game-view #history-bar {
  background: var(--hg-paper-raised); color: var(--hg-ink);
  border: 1.5px solid var(--hg-ink); border-radius: var(--hg-r-lg);
  -webkit-backdrop-filter: none; backdrop-filter: none;
}
#game-view #observer-roster .row { border-bottom-color: var(--hg-rule-soft); }
#game-view #observer-roster a, #game-view .player-profile-link { color: var(--hg-press); }
#game-view #observer-roster .empire, #game-view .roster-title { color: var(--hg-ink-3); font-family: var(--hg-font-label); letter-spacing: .06em; }
#game-view #history-bar { font-family: var(--hg-font-mono); color: var(--hg-ink); }
#game-view .hist-btn { color: var(--hg-ink); }
#game-view .hist-btn:disabled { color: var(--hg-rule-soft); }

/* Friends & blacklist (social.js) */
.social-actions { margin-top: 12px; display: flex; flex-direction: column; gap: 6px; }
.social-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 6px 0; }
.social-row + .social-row { border-top: 1px solid var(--line); }
.social-row-name { display: inline-flex; align-items: center; gap: 6px; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.social-row-actions { display: flex; gap: 6px; flex: 0 0 auto; }
.social-row-actions .btn, .info-row-block, .info-row-report { padding: 4px 8px; font-size: 13px; }
/* Anonymous-game block/report: their own line under the empire, so the
   name and counts keep the width; the long label wraps, "Report" doesn't.
   Set in the body face, not the label face: Barlow Condensed has no
   Cyrillic, so uppercase Russian fell back to a wide system font and the
   buttons broke over several lines. */
.info-row-actions { flex: 1 0 100%; display: flex; gap: 6px; }
.info-row-block, .info-row-report {
  flex: 1 1 auto; min-width: auto; min-height: 32px; white-space: normal;
  font-family: var(--hg-font-body); font-weight: 600; letter-spacing: 0; text-transform: none;
}
.info-row-report { flex: 0 0 auto; }
.notif-btn { position: relative; }
.notif-badge { position: absolute; top: -6px; right: -6px; min-width: 18px; height: 18px; padding: 0 4px; border-radius: 9px; background: #b03030; color: #fff; font-size: 11px; line-height: 18px; text-align: center; }
.social-row-text { flex: 1 1 auto; min-width: 0; }

/* Avatar editor (avatar_editor.js) */
.avatar-editor-preview canvas {
  display: block; width: 180px; height: 180px; margin: 6px auto 14px;
  border-radius: 50%; border: 1px solid var(--line);
}
.avatar-editor-tabs { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }
.avatar-editor-tabs button {
  padding: 6px 12px; border-radius: 999px; font: inherit; font-size: 14px;
  border: 1px solid var(--line); background: transparent; color: var(--text); cursor: pointer;
}
.avatar-editor-tabs button.active { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.avatar-editor-options { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
.avatar-editor-options button {
  position: relative; aspect-ratio: 1; padding: 0; overflow: hidden; cursor: pointer;
  border: 2px solid var(--line); border-radius: 14px; background: var(--bg-deep);
}
.avatar-editor-options button.active { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.avatar-editor-options canvas { display: block; width: 100%; height: 100%; }
.avatar-editor-options span {
  position: absolute; inset: auto 0 4px; font-size: 12px; color: var(--text);
  text-align: center;
}
.avatar-editor-label { font-size: 13px; color: var(--dim); margin: 4px 0 6px; }
.avatar-editor-swatches { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 10px; }
.avatar-editor-swatches button {
  width: 34px; height: 34px; padding: 0; border-radius: 50%; cursor: pointer;
  border: 2px solid var(--line);
}
.avatar-editor-swatches button.active { border-color: var(--accent); box-shadow: 0 0 0 2px var(--surface) inset; }

/* ─── The map from a chat (chat.js chatPeekMap): look only ────────── */
#btn-peek-back { display: none; }
body.map-peek #btn-peek-back {
  display: block; position: absolute; left: 50%; bottom: calc(20px + env(safe-area-inset-bottom));
  transform: translateX(-50%); z-index: 30; width: auto; padding: 10px 22px;
}
body.map-peek #panel, body.map-peek #hint, body.map-peek #btn-back,
body.map-peek #sandbox-switcher, body.map-peek #deadline-banner, body.map-peek #draw-banner { display: none !important; }
#chat-view #chat-map-btn { flex: 0 0 auto; min-width: 0; margin-right: 6px; }

