/* Type: carved small capitals for titles, a calligraphic book face for text, a brush hand for flourishes. */
:root {
  --font-title: "Alegreya SC", "Noto Serif Display", Georgia, serif;
  --font-body: "Alegreya", "Noto Serif", Georgia, serif;
  --font-brush: "Charmonman", "Alegreya", serif;
}
:root {
  --bg: #f4efe4;
  --panel: #fffaf0;
  --ink: #2b2118;
  --muted: #7a6a58;
  --line: #d9ccb4;
  --accent: #9b2c1f;
  --accent-ink: #fff;
  --good: #2f6b3a;
  --bad: #9b2c1f;
  --sea: #e6dcc8;
}
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #1c1814;
    --panel: #26211b;
    --ink: #eee4d3;
    --muted: #a8977f;
    --line: #40372d;
    --accent: #d0553f;
    --good: #6fbf7c;
    --bad: #e2725e;
    --sea: #2c261f;
  }
}
* { box-sizing: border-box; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 15px/1.5 var(--font-body);
}
button, textarea { font: inherit; color: inherit; }
button {
  background: var(--accent);
  color: var(--accent-ink);
  border: 0;
  border-radius: 6px;
  padding: 8px 14px;
  cursor: pointer;
}
button:disabled { opacity: .5; cursor: wait; }
/* Every box to choose or type in wears the game's look (parchment, a gold caret), not the browser's.
   Places that need the dark of the war table set their own colours; the caret stays. */
select, input[type="text"], input[type="number"], input[type="password"], input[type="search"], input:not([type]) {
  font: inherit; font-size: 14px; color: var(--ink); background-color: var(--panel);
  border: 1px solid var(--line); border-radius: 6px; padding: 4px 8px; min-height: 30px; box-sizing: border-box;
}
select {
  -webkit-appearance: none; appearance: none; padding-right: 26px; cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23b8892e' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 9px center; background-size: 10px 6px;
}
select:disabled { opacity: .55; cursor: not-allowed; }
select option { color: #2a1d12; background: #f8f0de; }
select:focus, input:focus, textarea:focus { outline: none; border-color: var(--gold, #b8892e); box-shadow: 0 0 0 2px rgba(184,137,46,.25); }
input[type="checkbox"], input[type="radio"], input[type="range"] { accent-color: var(--accent); }
input[type="checkbox"], input[type="radio"] { width: 15px; height: 15px; vertical-align: -2px; cursor: pointer; }
button.ghost { background: transparent; color: var(--ink); border: 1px solid var(--line); }
button.chip {
  background: transparent; color: var(--ink); border: 1px solid var(--line);
  padding: 3px 9px; font-size: 13px; border-radius: 999px;
}
.topbar {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 16px; border-bottom: 1px solid var(--line);
}
.topbar h1 { font-size: 20px; margin: 0; flex: 1; letter-spacing: .02em; }
/* The game's name in the bar leads home; it keeps the look of the title. */
.topbar h1 { cursor: pointer; }
.topbar h1 .home-link { color: inherit; text-decoration: none; cursor: pointer; }
.topbar h1 .home-link:hover { filter: brightness(1.15); text-decoration: none; }
.notice-address { margin: 0 0 12px; font-size: 14px; line-height: 1.55; }
.pace-pick { display: flex; flex-wrap: wrap; gap: 8px; align-items: stretch; margin: 0 0 14px; }
.pace-pick .pace-title { align-self: center; font-family: var(--font-title); font-weight: 600; margin-right: 4px; }
.pace-pick label { flex: 1 1 200px; display: grid; grid-template-columns: auto 1fr; column-gap: 8px; align-items: center; cursor: pointer;
  padding: 8px 12px; border: 1px solid var(--line); border-radius: 10px; background: var(--panel); }
.pace-pick label:has(input:checked) { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); background: rgba(163, 39, 28, .06); }
.pace-pick input { grid-row: span 2; }
.pace-pick small { color: var(--muted); font-size: 12.5px; line-height: 1.4; }
.community-box { max-width: 380px; display: flex; flex-direction: column; align-items: center; gap: 8px; }
.community-box h2 { font-family: var(--font-title); font-size: 22px; margin: 0; padding: 0 40px; text-align: center; }
.community-box p { margin: 0; line-height: 1.5; }
.community-box img { width: 220px; height: 220px; border-radius: 10px; background: #fff; padding: 6px; border: 1px solid var(--line); }
.community-box small { color: var(--muted); }
.community-join { font-size: 15px; padding: 8px 18px; }
.community-link { display: flex; gap: 6px; width: 100%; }
.community-link input { flex: 1; min-width: 0; font-size: 12.5px; }
.crews { margin: 8px 0; padding: 8px 10px; border: 1px solid var(--line); border-radius: 8px; background: #f3ead6; color: #2a1d12; font-size: 13px; }
.crews-head { margin-bottom: 4px; }
.crews-list { list-style: none; margin: 0 0 4px; padding: 0; display: grid; gap: 2px; }
.crews-list li { display: flex; flex-wrap: wrap; gap: 4px 6px; align-items: baseline; padding: 3px 6px; border-radius: 5px; background: rgba(255,255,255,.45); }
.crews-list li.crew-on { border-left: 3px solid #b8892e; }
.crews-list li.crew-off { border-left: 3px solid #3f7a3a; }
.crews-list small, .crews-note { color: #6b5a45; }
.crew-busy { color: #8a5a12; font-weight: 600; }
.crew-free { color: #2f7a3a; font-weight: 600; }
.pp-gov-effect { margin: 2px 0; font-size: 13px; }
.pp-gov-effect .good { color: #2f7a3a; }
.pp-gov-effect .bad { color: #9c2b22; }
.supply { margin: 6px 0 10px; padding: 8px 10px; border: 1px solid var(--line); border-radius: 8px; background: #f3ead6; color: #2a1d12; font-size: 13px; }
.supply p { margin: 3px 0; line-height: 1.5; }
.supply small { color: #6b5a45; }
.supply .bad { color: #9c2b22; }
.pp-store { margin: 0 0 10px; padding: 6px 10px; border-radius: 8px; background: #f3ead6; color: #2a1d12; border: 1px solid var(--line); font-size: 13px; }
.pp-store p { margin: 2px 0; }
.pp-store small { color: #6b5a45; }
.notice-saved { margin: 0 0 10px; padding: 8px 10px; font-size: 14px; line-height: 1.55; border-left: 3px solid #3f7a3a; background: rgba(63, 122, 58, .08); border-radius: 4px; }
.hud-seal .saved { color: #9fd08f; white-space: nowrap; cursor: help; }
.mg-saved { margin: 0 0 8px; font-size: 13px; color: var(--muted); }
.notice-address a { color: #8b2a1a; font-weight: 600; }
.badge { background: var(--panel); border: 1px solid var(--line); border-radius: 999px; padding: 2px 10px; font-size: 13px; }

.setup { max-width: 960px; margin: 24px auto; padding: 0 16px; }
.lead { color: var(--muted); }
.choices { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 12px; }
.choice {
  text-align: left; background: var(--panel); color: var(--ink);
  border: 1px solid var(--line); border-left: 6px solid var(--c, var(--accent));
  padding: 12px; border-radius: 8px;
}
.choice strong { font-size: 18px; }
.choice small { display: block; color: var(--muted); margin-top: 4px; }

.map-panel { position: relative; }
.map-find { position: absolute; top: 8px; left: 8px; z-index: 5; width: min(260px, calc(100% - 16px)); font-family: var(--font-body); }
/* The search box wears the board's dark-and-gold like the camera buttons beside it; its list is the
   province panel's parchment. */
.map-find .mf-glass { position: absolute; left: 9px; top: 50%; transform: translateY(-50%); font-size: 12px; opacity: .8; pointer-events: none; }
.map-find .mf-clear { position: absolute; right: 4px; top: 50%; transform: translateY(-50%); width: 22px; height: 22px; padding: 0;
  border: 0; border-radius: 50%; background: transparent; color: #f3d27a; font-size: 12px; cursor: pointer; }
.map-find .mf-clear:hover { background: rgba(243,210,122,.18); }
.mf-list { position: absolute; top: calc(100% + 4px); left: 0; right: 0; margin: 0; padding: 4px; list-style: none; z-index: 30;
  background: var(--panel); color: var(--ink); border: 1px solid var(--gold, #b8892e); border-radius: 8px;
  box-shadow: 0 8px 22px rgba(0,0,0,.35); max-height: 300px; overflow-y: auto; text-align: left; }
.mf-list li { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 6px 9px; border-radius: 5px; cursor: pointer; }
.mf-list li b { font-family: var(--font-title); font-size: 14px; font-weight: 600; letter-spacing: .02em; }
.mf-list li:hover, .mf-list li.on { background: rgba(184,137,46,.18); }
.mf-list li.on { box-shadow: inset 3px 0 0 var(--accent); }
.mf-list .mf-owner { font-size: 11.5px; color: var(--muted, #7a6a55); white-space: nowrap; }
.mf-list .mf-owner::before { content: ""; display: inline-block; width: 9px; height: 9px; border-radius: 50%; background: var(--c);
  margin-right: 5px; vertical-align: -1px; box-shadow: 0 0 0 1px rgba(0,0,0,.25); }
.mf-list .mf-none { color: var(--muted, #7a6a55); font-size: 13px; font-style: italic; cursor: default; }
/* Over the flat map: its top-left corner, clear of the title cartouche in the middle. */
.game.lobby .map-panel > .map-find { top: 142px; left: 118px; transform: none; }
.map3d-bar .map-find { position: relative; width: 240px; transform: none; }
.map3d-bar .map-find input { height: 100%; min-height: 26px; }
@media (max-width: 700px) {
  /* On a phone the camera bar is a column at the right: the search box stands alone at the left. */
  .game.lobby .map3d-bar .map-find { position: fixed; top: 170px; left: 8px; width: min(220px, calc(100vw - 70px)); }
}
.map-find input { width: 100%; box-sizing: border-box; height: 30px; padding: 0 28px 0 28px; border-radius: 4px; font: inherit; font-size: 13px;
  border: 1px solid rgba(243,210,122,.45); background: rgba(33,22,12,.85); color: #fbeacb; box-shadow: 0 2px 6px rgba(0,0,0,.25); outline: none; }
.map-find input::placeholder { color: rgba(251,234,203,.65); }
.map-find input:focus { border-color: #f3d27a; box-shadow: 0 0 0 2px rgba(243,210,122,.25), 0 2px 6px rgba(0,0,0,.25); }
#map { width: 100%; height: auto; background: var(--sea); border-radius: 10px; border: 1px solid var(--line); }
#map .hex { stroke: var(--bg); stroke-width: 1.5; cursor: pointer; transition: opacity .15s; }
#map .hex.player { stroke: var(--ink); stroke-width: 2.5; }
#map .hex.fallen-owner { opacity: .4; }
#map .hex:hover { opacity: .8; }
#map .hex.selected { stroke: #ffd54a; stroke-width: 3; }
#map text { pointer-events: none; fill: #fff; font-size: 9px; text-anchor: middle; paint-order: stroke; stroke: rgba(0,0,0,.45); stroke-width: 2px; }
#map text.cap { font-size: 13px; }
.legend { display: flex; flex-wrap: wrap; gap: 6px 14px; margin-top: 8px; font-size: 13px; }
.legend span::before { content: ""; display: inline-block; width: 10px; height: 10px; border-radius: 2px; background: var(--c); margin-right: 5px; }
.province-info { margin-top: 6px; color: var(--muted); font-size: 13px; min-height: 1.5em; }

.side { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.card { background: var(--panel); border: 1px solid var(--line); border-radius: 10px; padding: 12px 14px; }
.card h2 { font-size: 16px; margin: 0 0 8px; }
.stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }
.stat { border: 1px solid var(--line); border-radius: 6px; padding: 4px 6px; }
.stat b { display: block; font-size: 16px; }
.stat span { font-size: 11px; color: var(--muted); }
.realm-title { display: flex; align-items: baseline; gap: 8px; margin-bottom: 8px; }
.realm-title strong { font-size: 20px; }
.realm-note { font-size: 13px; color: var(--muted); margin-top: 6px; }

textarea { width: 100%; background: var(--bg); border: 1px solid var(--line); border-radius: 6px; padding: 8px; resize: vertical; }
.quick { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0; }
.turn-result { margin-top: 10px; font-size: 14px; }
.turn-result .ok { color: var(--good); }
.turn-result .fail { color: var(--bad); }
.turn-result li { margin-bottom: 4px; }

.guard-event { border-top: 1px solid var(--line); padding-top: 8px; margin-top: 8px; }
.guard-event:first-child { border-top: 0; margin-top: 0; padding-top: 0; }
.guard-event ul { margin: 4px 0; padding-left: 18px; font-size: 13px; color: var(--muted); }
.guard-event .rec { font-size: 13px; font-style: italic; }
.guard-event .actions { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 6px; }
#guard { border-color: var(--accent); }

table.nations { width: 100%; border-collapse: collapse; font-size: 14px; }
table.nations th { text-align: left; font-weight: normal; color: var(--muted); font-size: 12px; }
table.nations td, table.nations th { padding: 4px 4px; border-bottom: 1px solid var(--line); }
table.nations td:first-child::before { content: ""; display: inline-block; width: 9px; height: 9px; border-radius: 2px; background: var(--c); margin-right: 6px; }
table.nations tr.fallen { opacity: .45; text-decoration: line-through; }
.rel-WAR { color: var(--bad); font-weight: bold; }
.rel-ALLIANCE, .rel-VASSAL { color: var(--good); }

.chronicle { margin: 0; padding-left: 18px; max-height: 320px; overflow: auto; font-size: 13px; }
.chronicle li { margin-bottom: 4px; }
.chronicle .t { color: var(--muted); }
.chronicle .BATTLE b { color: var(--bad); }
.chronicle .WORLD b { color: var(--accent); }

.overlay, .busy {
  position: fixed; inset: 0; background: rgba(0,0,0,.55);
  display: flex; align-items: center; justify-content: center; z-index: 10; padding: 16px;
}
.overlay[hidden], .busy[hidden], [hidden] { display: none !important; }
.overlay-box { background: var(--panel); border-radius: 12px; padding: 24px; max-width: 460px; text-align: center; }
.overlay-box h2 { font-size: 26px; margin: 0 0 8px; }
.busy { flex-direction: column; gap: 12px; color: #fff; }
.spinner { width: 36px; height: 36px; border: 4px solid rgba(255,255,255,.3); border-top-color: #fff; border-radius: 50%; animation: spin 1s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

.court-group { margin-bottom: 8px; }
.court-group h3 { font-size: 13px; color: var(--muted); font-weight: normal; margin: 6px 0 2px; }
.person { display: flex; justify-content: space-between; gap: 8px; font-size: 13px; padding: 2px 0; border-bottom: 1px dashed var(--line); }
.person .who { min-width: 0; }
.person .who small { color: var(--muted); }
.person .nums { white-space: nowrap; color: var(--muted); font-variant-numeric: tabular-nums; }
.person.child .who::before { content: "└ "; color: var(--muted); }
.person.child.d2 .who { padding-left: 14px; }
.person.child.d1 .who { padding-left: 4px; }
.person.low-loyalty .nums b { color: var(--bad); }
.traits i { font-style: normal; font-size: 11px; margin-left: 4px; padding: 0 5px; border: 1px solid var(--line); border-radius: 8px; color: var(--muted); white-space: nowrap; }
.talent { display: flex; align-items: center; justify-content: space-between; gap: 8px; font-size: 13px; padding: 2px 0; }

.order-status { font-size: 13px; color: var(--muted); margin: 6px 0 0; min-height: 0; }
.order-status:empty { display: none; }
#year-submit.thinking::before {
  content: ""; display: inline-block; width: 12px; height: 12px; margin-right: 8px; vertical-align: -1px;
  border: 2px solid rgba(255,255,255,.4); border-top-color: #fff; border-radius: 50%; animation: spin 1s linear infinite;
}
.year-summary { margin-top: 8px; padding-top: 8px; border-top: 1px dashed var(--line); }
.order-error { color: var(--bad); font-size: 14px; margin: 6px 0 0; padding: 6px 8px; border: 1px solid var(--bad); border-radius: 6px; }

.order-buttons { display: flex; flex-wrap: wrap; gap: 8px; }
.consult-log { list-style: none; margin: 0 0 8px; padding: 0; max-height: 260px; overflow: auto; font-size: 14px; }
.consult-log li { padding: 4px 0; border-bottom: 1px dashed var(--line); }
.consult-log .q { color: var(--muted); }
.consult-log .a b { color: var(--accent); }
.consult-form { display: flex; gap: 6px; flex-wrap: wrap; }
.consult-form select, .consult-form input {
  font: inherit; color: inherit; background: var(--bg); border: 1px solid var(--line); border-radius: 6px; padding: 6px 8px;
}
.consult-form select { max-width: 40%; }
.consult-form input { flex: 1; min-width: 140px; }
.lane { margin-bottom: 8px; }
.lane h3 { font-size: 13px; color: var(--muted); font-weight: normal; margin: 4px 0 2px; }
.task { display: flex; justify-content: space-between; align-items: center; gap: 8px; font-size: 13px; padding: 2px 0; }
.task.ACTIVE b { color: var(--good); }
.task small { color: var(--muted); white-space: nowrap; }
.task button { padding: 0 7px; font-size: 12px; }
.bar { height: 4px; background: var(--line); border-radius: 2px; overflow: hidden; margin: 2px 0 4px; }
.bar i { display: block; height: 100%; background: var(--good); }
.army { border-top: 1px dashed var(--line); padding: 6px 0; font-size: 13px; }
.army:first-child { border-top: 0; }
.army .units { color: var(--muted); }
#map text.army-flag { font-size: 11px; fill: #ffd54a; }

.topbar h1 { flex: 0 1 auto; }
.tabs { display: flex; gap: 4px; flex: 1; }
.tab { background: transparent; color: var(--ink); border: 1px solid transparent; padding: 4px 12px; border-radius: 999px; }
.tab.active { border-color: var(--line); background: var(--panel); font-weight: bold; }
.guide { max-width: 1000px; margin: 16px auto; padding: 0 16px 40px; }
.guide h2 { font-size: 20px; margin: 24px 0 8px; border-bottom: 1px solid var(--line); padding-bottom: 4px; }
.guide h3 { font-size: 16px; margin: 14px 0 6px; }
.guide p, .guide li { line-height: 1.6; }
.guide nav.toc { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0 4px; }
.guide nav.toc a { font-size: 13px; color: var(--ink); border: 1px solid var(--line); border-radius: 999px; padding: 2px 10px; text-decoration: none; }
.guide .scroll { overflow-x: auto; }
.guide table { border-collapse: collapse; font-size: 13px; margin: 6px 0 10px; min-width: 100%; }
.guide th, .guide td { border: 1px solid var(--line); padding: 4px 6px; text-align: left; vertical-align: top; }
.guide th { background: var(--panel); font-weight: normal; color: var(--muted); }
.guide td.num { text-align: right; font-variant-numeric: tabular-nums; }
.guide td.up { background: color-mix(in srgb, var(--good) 22%, transparent); }
.guide td.down { background: color-mix(in srgb, var(--bad) 22%, transparent); }
.guide code { background: var(--panel); border: 1px solid var(--line); border-radius: 4px; padding: 0 4px; }
.guide .example { border-left: 3px solid var(--accent); padding: 4px 10px; margin: 6px 0; background: var(--panel); }

/* ---------- battle viewer (chiến báo) ---------- */
.battle { position: fixed; inset: 0; z-index: 20; background: #120d09; color: #f4e9d4; display: flex; flex-direction: column; }
.battle-top { display: flex; align-items: center; gap: 6px; padding: 8px 12px; border-bottom: 1px solid #3a2c1f; flex-wrap: wrap; }
.battle-top .spacer { flex: 1; }
.battle-top .counter { color: #b9a37f; font-size: 13px; }
.battle-top button.ghost { color: #f4e9d4; border-color: #5a4630; }
.battle .steps { display: flex; gap: 4px; list-style: none; margin: 0; padding: 6px 12px; font-size: 12px; color: #8d7a5d; overflow-x: auto; }
.battle .steps li { padding: 2px 10px; border: 1px solid #3a2c1f; border-radius: 999px; white-space: nowrap; }
.battle .steps li.on { color: #120d09; background: #e2b45a; border-color: #e2b45a; }
.battle .stage { position: relative; flex: 1; overflow: hidden; min-height: 0; }
.battle .subtitle { min-height: 3.2em; padding: 10px 16px 14px; text-align: center; font-size: 17px; background: linear-gradient(transparent, rgba(0,0,0,.6)); text-shadow: 0 1px 2px #000; }
.stage > div { position: absolute; inset: 0; opacity: 0; pointer-events: none; transition: opacity .6s; }
.stage[data-phase="report"] .report-screen,
.stage[data-phase="array"] .array-screen,
.stage[data-phase="clash"] .field-screen,
.stage[data-phase="skill"] .field-screen, .stage[data-phase="skill"] .skill-screen,
.stage[data-phase="result"] .field-screen, .stage[data-phase="result"] .result-screen,
.stage[data-phase="plot"] .field-screen, .stage[data-phase="crisis"] .field-screen { opacity: 1; pointer-events: auto; }

.report-screen { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 16px; padding: 20px;
  background: radial-gradient(circle at 50% 40%, #3b2414, #120d09 70%); }
.report-screen .messenger { font-size: 64px; color: #e2b45a; animation: run-in 1.2s ease-out both; }
.report-screen .report-text { max-width: 760px; font-size: clamp(18px, 3vw, 28px); text-align: center; line-height: 1.5; animation: fade-up 1s .4s both; }

.array-screen { display: flex; align-items: center; justify-content: center; gap: 14px; padding: 16px; flex-wrap: wrap; overflow: auto;
  background: linear-gradient(90deg, rgba(120,30,20,.25), transparent 45%, transparent 55%, rgba(30,60,120,.25)); }
.array-screen .versus { font-size: 34px; font-weight: bold; color: #e2b45a; letter-spacing: .1em; }
.side-card { display: flex; gap: 12px; background: rgba(0,0,0,.35); border: 1px solid #5a4630; border-radius: 12px; padding: 12px; width: min(420px, 100%); }
.side-card.atk { animation: slide-l .8s both; }
.side-card.def { animation: slide-r .8s both; }
.side-card .who { min-width: 0; flex: 1; }
.side-card .nation { font-weight: bold; letter-spacing: .05em; filter: brightness(1.6); }
.side-card .gname { font-size: 20px; font-weight: bold; }
.side-card small { color: #b9a37f; }
.side-card q { display: block; margin: 6px 0; font-style: italic; color: #f3d27a; }
.side-card .units { list-style: none; padding: 0; margin: 4px 0; font-size: 13px; columns: 2; }
.side-card .units small { color: #8d7a5d; }
.side-card .total { font-size: 13px; color: #b9a37f; }
.portrait { width: 96px; flex: 0 0 96px; aspect-ratio: 3 / 4; border-radius: 10px; overflow: hidden; box-shadow: 0 0 0 2px #e2b45a, 0 6px 18px rgba(0,0,0,.6); background: var(--c); }
.portrait img, .portrait svg { width: 100%; height: 100%; object-fit: cover; display: block; }
.portrait.big { width: min(42vw, 300px); flex-basis: auto; }


.skill-screen { display: flex; align-items: center; justify-content: center; gap: 20px; padding: 20px; background: rgba(10,6,3,.72); }
.skill-screen .bars::before, .skill-screen .bars::after { content: ""; position: absolute; left: 0; right: 0; height: 11%; background: #000; }
.skill-screen .bars::before { top: 0; }
.skill-screen .bars::after { bottom: 0; }
.stage[data-phase="skill"] .skill-screen .portrait { animation: zoom-in .7s cubic-bezier(.2,.9,.3,1.3) both; }
.skill-text { max-width: 420px; }
.skill-name { font-size: clamp(26px, 5vw, 46px); font-weight: bold; color: #f3d27a; text-shadow: 0 0 18px #c0392b; letter-spacing: .04em; }
.stage[data-phase="skill"] .skill-name { animation: stamp .6s .3s both; }
.skill-by { color: #b9a37f; margin: 4px 0 8px; }
.skill-text q { font-size: 20px; font-style: italic; }
.stage.shake { animation: shake .5s; }

.result-screen { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; padding: 20px; background: rgba(10,6,3,.55); }
.seal-title { font-size: clamp(34px, 7vw, 64px); font-weight: bold; color: #f3d27a; border: 4px solid #b3261e; padding: 4px 22px; border-radius: 8px; transform: rotate(-4deg); background: rgba(179,38,30,.25); }
.seal-title.bad { color: #f4e9d4; border-color: #6b6b6b; background: rgba(60,60,60,.4); }
.stage[data-phase="result"] .seal-title { animation: stamp .5s both; }
.result-text { max-width: 760px; font-size: clamp(16px, 2.6vw, 22px); text-align: center; line-height: 1.5; }

@keyframes run-in { from { transform: translateX(-60vw); } to { transform: none; } }
@keyframes fade-up { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }
@keyframes slide-l { from { opacity: 0; transform: translateX(-40px); } to { opacity: 1; transform: none; } }
@keyframes slide-r { from { opacity: 0; transform: translateX(40px); } to { opacity: 1; transform: none; } }
@keyframes wave { from { transform: skewY(-8deg) scaleX(.9); } to { transform: skewY(8deg) scaleX(1.05); } }
@keyframes volley { 0% { stroke-dashoffset: 614; opacity: 0; } 15% { opacity: 1; } 85% { opacity: 1; } 100% { stroke-dashoffset: 0; opacity: 0; } }
@keyframes dust { 0% { opacity: 0; transform: scale(.4); } 40% { opacity: .55; } 100% { opacity: 0; transform: scale(1.6); } }
@keyframes zoom-in { from { opacity: 0; transform: scale(.4) translateX(-80px); } to { opacity: 1; transform: none; } }
@keyframes stamp { 0% { opacity: 0; transform: scale(2.2) rotate(-4deg); } 100% { opacity: 1; transform: scale(1) rotate(-4deg); } }
@keyframes shake { 0%, 100% { transform: none; } 20% { transform: translate(-8px, 4px); } 40% { transform: translate(7px, -5px); } 60% { transform: translate(-5px, 3px); } 80% { transform: translate(4px, -2px); } }
@media (prefers-reduced-motion: reduce) {
  .battle *, .stage.shake { animation: none !important; transition: none !important; }
}

.sound-toggles { display: flex; gap: 4px; }
.sound-toggles button { padding: 3px 9px; font-size: 13px; }
.sound-toggles button[aria-pressed="false"] { opacity: .5; }
.watch-battle { margin-left: 6px; padding: 0 8px; font-size: 12px; }
.toast { position: fixed; left: 50%; bottom: 24px; transform: translateX(-50%); z-index: 15; background: #2b1d12; color: #f4e9d4;
  border: 1px solid #e2b45a; border-radius: 10px; padding: 10px 16px; max-width: min(92vw, 640px); box-shadow: 0 8px 24px rgba(0,0,0,.4); animation: toast-in .4s both; }
/* Rising into place, still centred (a plain fade-up would undo the centring). */
@keyframes toast-in { from { opacity: 0; transform: translate(-50%, 16px); } to { opacity: 1; transform: translate(-50%, 0); } }

/* =====================================================================
   Cổ phong theme: rice paper, lacquer, cinnabar seals and gold leaf.
   ===================================================================== */
:root {
  --bg: #efe4cc;
  --panel: #f8f0de;
  --ink: #2a1d12;
  --muted: #7a6650;
  --line: #d2bf98;
  --accent: #a3271c;
  --gold: #b8892e;
  --lacquer: #1f120b;
  --sea: #cdbf9f;
  --paper-noise: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' seed='4'/><feColorMatrix values='0 0 0 0 .42 0 0 0 0 .3 0 0 0 0 .15 0 0 0 .09 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
}
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #17110c;
    --panel: #221912;
    --ink: #f0e3c8;
    --muted: #a8926f;
    --line: #47372a;
    --accent: #d2553f;
    --gold: #d9ab52;
    --sea: #2a2018;
  }
}
body {
  background-color: var(--bg);
  background-image: var(--paper-noise), radial-gradient(ellipse at top, rgba(255,255,255,.35), transparent 60%);
  font-family: var(--font-body);
}
.topbar {
  background: linear-gradient(180deg, #2a160d, #170c07);
  color: #f3dfb0;
  border-bottom: 3px solid var(--gold);
  box-shadow: 0 2px 12px rgba(0,0,0,.35);
  position: sticky; top: 0; z-index: 5;
}
.topbar h1 {
  font-family: var(--font-title);
  letter-spacing: .06em; color: #f3d27a; text-shadow: 0 1px 0 #000;
  display: flex; align-items: center; gap: 10px;
}
.topbar h1::before {
  content: "⚔"; display: inline-grid; place-items: center; width: 30px; height: 30px; border-radius: 4px;
  background: #a3271c; color: #fff3d6; font-size: 18px; box-shadow: inset 0 0 0 2px #f3d27a; transform: rotate(-4deg);
}
.topbar .badge { background: #3a2112; color: #f3d27a; border-color: var(--gold); }
.topbar button.ghost, .tab { color: #f3dfb0; border-color: #6b4a2a; }
.tab.active { background: #a3271c; color: #fff3d6; border-color: #f3d27a; }
.card {
  background-color: var(--panel);
  background-image: var(--paper-noise);
  border: 1px solid var(--line);
  border-top: 3px solid var(--gold);
  border-radius: 6px;
  box-shadow: 0 1px 0 rgba(255,255,255,.4) inset, 0 6px 16px rgba(60,35,10,.12);
  position: relative;
}
.card h2 {
  font-family: var(--font-title); letter-spacing: .04em;
  display: flex; align-items: center; gap: 8px; color: var(--accent);
}
.card h2::before { content: ""; width: 10px; height: 10px; background: var(--accent); transform: rotate(45deg); box-shadow: 0 0 0 2px var(--panel), 0 0 0 3px var(--gold); }
button { box-shadow: 0 2px 0 rgba(0,0,0,.25); transition: transform .08s, filter .15s; }
button:hover:not(:disabled) { filter: brightness(1.08); }
button:active:not(:disabled) { transform: translateY(1px); box-shadow: none; }
button.chip { background: var(--panel); box-shadow: none; }
button.chip:hover { border-color: var(--gold); color: var(--accent); }
.stat { background: linear-gradient(180deg, rgba(255,255,255,.35), transparent); border-color: var(--line); }
.stat b { font-family: var(--font-title); color: var(--accent); }
.realm-title strong { font-family: var(--font-title); font-size: 26px; }

.choice {
  background-color: var(--panel); background-image: var(--paper-noise);
  border: 1px solid var(--line); border-left: 8px solid var(--c, var(--accent));
  position: relative; overflow: hidden; transition: transform .15s, box-shadow .15s;
}
.choice:hover { transform: translateY(-3px); box-shadow: 0 10px 24px rgba(60,35,10,.2); }
.choice strong { font-family: var(--font-title); font-size: 22px; color: var(--c); filter: brightness(.85); }
.choice::after {
  content: attr(data-seal); position: absolute; right: 12px; top: 12px; width: 40px; height: 40px; display: grid; place-items: center;
  background: var(--c); color: #fff3d6; font-size: 18px; border-radius: 5px; box-shadow: inset 0 0 0 2px rgba(255,243,214,.7); transform: rotate(6deg); opacity: .9;
}
.setup .lead { font-size: 17px; }

#map { background: transparent; border: 1px solid var(--line); box-shadow: 0 8px 22px rgba(60,35,10,.18); border-radius: 8px; }
#map .sea { fill: var(--sea); }
#map .hex { stroke: rgba(42,29,18,.25); stroke-width: .8; fill-opacity: .78; }
#map .hex:hover { fill-opacity: .95; }
#map .hex.player { fill-opacity: .9; stroke: #f3d27a; stroke-width: 1.4; }
#map .hex.selected { fill-opacity: 1; stroke: #ffe28a; stroke-width: 3.2; }
#map .realm-edge { stroke: #24170d; stroke-width: 2.6; stroke-linecap: round; opacity: .85; }
#map .coast { stroke: #3b2a1a; stroke-width: 1.6; stroke-linecap: round; opacity: .55; }
#map .river { fill: none; stroke: #3d6f8f; stroke-width: 3.2; stroke-linecap: round; opacity: .75; }
#map .mount { fill: none; stroke: rgba(30,20,12,.65); stroke-width: 1.4; stroke-linejoin: round; }
#map .grove circle { fill: rgba(25,40,20,.5); }
#map .palace path { fill: #2a1a10; }
#map .palace .roof { fill: #f3d27a; stroke: #2a1a10; stroke-width: .8; }
#map .fort rect { fill: #e8dcc0; stroke: #2a1a10; stroke-width: .7; }
#map .banner line { stroke: #1d140c; stroke-width: 1.4; }
#map .banner path { stroke: #f3d27a; stroke-width: .6; }
#map .banner text { fill: #fff; font-size: 7.5px; stroke: rgba(0,0,0,.7); stroke-width: 2px; paint-order: stroke; text-anchor: start; }
.legend span::before { border-radius: 50%; box-shadow: 0 0 0 1px rgba(0,0,0,.25); }
.legend .legend-key::before { display: none; }
.province-info { background: var(--panel); border: 1px solid var(--line); border-radius: 6px; padding: 6px 10px; color: var(--ink); }

.chronicle li { padding: 3px 0; border-bottom: 1px dashed var(--line); }
.task, .army { border-bottom: 1px dashed var(--line); }
.bar i { background: linear-gradient(90deg, var(--gold), var(--accent)); }

/* A new year unrolls like a scroll. */
.year-scroll {
  position: fixed; left: 50%; top: 38%; transform: translate(-50%, -50%); z-index: 12; pointer-events: none;
  padding: 18px 54px; background: #f3e6c4; color: #2a1d12; border-top: 8px solid #6b3f1f; border-bottom: 8px solid #6b3f1f;
  font: 700 clamp(28px, 5vw, 46px) var(--font-title); letter-spacing: .12em;
  box-shadow: 0 16px 40px rgba(0,0,0,.45); animation: unroll 2.6s ease both;
}
.year-scroll small { display: block; font-size: 15px; letter-spacing: .04em; color: #7a5a3a; text-align: center; }
@keyframes unroll {
  0% { clip-path: inset(0 50% 0 50%); opacity: 0; }
  20% { clip-path: inset(0 0 0 0); opacity: 1; }
  80% { clip-path: inset(0 0 0 0); opacity: 1; }
  100% { clip-path: inset(0 0 0 0); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) { .year-scroll { animation: none; display: none; } }
/* The cut-in must appear at once, even when a busy frame delays transitions. */
.stage[data-phase="skill"] .skill-screen, .stage[data-phase="result"] .result-screen { transition: none; }

.choice { padding-right: 66px; }
.choice::after { width: 48px; height: 48px; font-size: 13px; line-height: 1.1; text-align: center; padding: 2px; }

@media (max-width: 640px) {
  .topbar { flex-wrap: wrap; gap: 6px 8px; padding: 8px 12px; }
  .topbar h1 { font-size: 17px; flex: 1 1 auto; white-space: nowrap; }
  .topbar h1::before { width: 24px; height: 24px; font-size: 14px; }
  .tabs { order: 3; flex: 1 1 100%; }
  .sound-toggles .lbl { display: none; }
  .game { padding: 10px; gap: 10px; }
  .battle-top { gap: 4px; padding: 6px 8px; }
  .battle-top .title { flex: 1 1 100%; }
  .battle .subtitle { font-size: 15px; }
}

/* ---------- the drawn battlefield: images moved by transforms only ---------- */
.field-screen { overflow: hidden; }
.bf { position: absolute; inset: 0; overflow: hidden; container-type: size; }
.bf-bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; user-select: none; }
.bf-fort { position: absolute; left: 70%; bottom: -2%; width: 12%; height: var(--h, 80%); }
.bf-palace { position: absolute; left: 80%; top: 36%; width: 16%; aspect-ratio: 220 / 150; }
.bf-place { position: absolute; left: 50%; top: 13%; transform: translateX(-50%); color: #fff3d6; font-size: clamp(12px, 1.6vw, 18px);
  text-shadow: 0 1px 3px #000, 0 0 8px #000; letter-spacing: .05em; white-space: nowrap; }
.bf-layer { position: absolute; inset: 0; transition: transform 2.6s cubic-bezier(.4,.1,.3,1), opacity 1.6s; will-change: transform; }
.bf-push { position: absolute; inset: 0; }
.co { position: absolute; width: var(--w); transform: translate(-50%, -100%); transform-origin: 50% 100%; transition: transform 1.4s, opacity 1.4s; }
.co-art { display: block; width: 100%; aspect-ratio: var(--ar); filter: drop-shadow(0 4px 3px rgba(0,0,0,.35)); }
.bf-layer.def .co-art { transform: scaleX(-1); }
.co-flag { position: absolute; left: 0; bottom: 92%; width: 34%; min-width: 22px; aspect-ratio: 40 / 70; color: inherit; }
.bf-layer.def .co-flag { left: auto; right: 0; }
.co-flag svg { width: 100%; height: 100%; display: block; }
.co-flag span { position: absolute; left: 12%; top: 6%; width: 78%; text-align: center; color: #fff3d6; font-size: clamp(9px, 1vw, 13px); font-weight: bold; text-shadow: 0 1px 1px #000; }
.co-flag b { position: absolute; left: 100%; top: 6%; margin-left: 2px; color: #fff3d6; font-size: clamp(9px, .9vw, 12px); font-weight: normal; text-shadow: 0 1px 2px #000; white-space: nowrap; }
.bf-layer.def .co-flag b { left: auto; right: 100%; margin: 0 2px 0 0; }

/* Advance: each wing moves as one picture. */
.bf.advance .bf-layer.atk.foot { transform: translateX(18%); }
.bf.advance .bf-layer.atk.horse { transform: translateX(24%); }
.bf.advance .bf-layer.atk.ranged { transform: translateX(10%); }
.bf.advance .bf-layer.def.foot { transform: translateX(-12%); }
.bf.advance .bf-layer.def.horse { transform: translateX(-18%); }
.bf.advance .bf-layer.def.ranged { transform: translateX(-4%); }
.bf.walled.advance .bf-layer.def { transform: none; }
.bf.walled.advance .bf-layer.atk.foot { transform: translateX(38%); }
.bf.walled.advance .bf-layer.atk.horse { transform: translateX(30%); }
.bf.walled.advance .bf-layer.atk.ranged { transform: translateX(22%); }
/* Melee: the lines heave back and forth against each other. */
.bf.melee .bf-layer.foot .bf-push, .bf.melee .bf-layer.horse .bf-push { animation: heave .9s ease-in-out infinite alternate; }
.bf.melee .bf-layer.def .bf-push { animation-direction: alternate-reverse; }
.bf.melee .bf-layer.horse .bf-push { animation-duration: .7s; }
@keyframes heave { from { transform: translateX(-1.2%); } to { transform: translateX(1.2%); } }
/* Rout: the beaten host falls back and thins, the victors press on. */
.bf.rout .bf-push { animation: none; }
.bf.rout.atk-wins .bf-layer.def { transform: translateX(45%); opacity: 0; }
.bf.rout.def-wins .bf-layer.atk { transform: translateX(-45%); opacity: 0; }
.bf.rout.atk-wins .bf-layer.atk.foot, .bf.rout.atk-wins .bf-layer.atk.horse { transform: translateX(34%); }
.bf.walled.rout.atk-wins .bf-layer.atk.foot, .bf.walled.rout.atk-wins .bf-layer.atk.horse { transform: translateX(48%); }
.bf.rout.def-wins .bf-layer.def.foot, .bf.rout.def-wins .bf-layer.def.horse { transform: translateX(-16%); }
.bf.walled.rout.def-wins .bf-layer.def { transform: none; }
.bf.rout .co { transform: translate(-50%, -100%) scale(var(--keep)); }
.bf.done.atk-wins .bf-layer.def, .bf.done.def-wins .bf-layer.atk { transition: none; }
.bf.walled.rout.atk-wins .bf-fort { filter: brightness(.7) saturate(.6); }

/* Effects: a few small pictures with looping transforms. */
.bf-fx { position: absolute; inset: 0; pointer-events: none; }
.fallen { position: absolute; width: 3.2%; aspect-ratio: 32 / 14; opacity: 0; }
.bf.melee .fallen { animation: appear .5s var(--d) forwards; }
.fallen.def { transform: scaleX(-1); }
@keyframes appear { to { opacity: 1; } }
.spark { position: absolute; width: 2.6%; aspect-ratio: 1; opacity: 0; transform: translate(-50%, -50%) scale(.3); }
.bf.melee .spark { animation: flash 1.1s var(--d) infinite; }
.bf.rout .spark { animation: none; }
@keyframes flash { 0%, 60%, 100% { opacity: 0; transform: translate(-50%, -50%) scale(.3); } 70% { opacity: 1; transform: translate(-50%, -50%) scale(1); } 85% { opacity: 0; transform: translate(-50%, -50%) scale(1.3); } }
/* Arrows fly in an arc: the outer element moves across, the inner one rises and falls. */
.arw { position: absolute; left: 13%; width: 3%; aspect-ratio: 40 / 6; opacity: 0; }
.arw.from-def { left: 83%; }
.bf.walled .arw.from-def { left: 71%; }
/* Before a wall the attackers' archers loose from close in, so the volley reaches the wall (70–82%). */
.bf.walled .arw.from-atk { left: 34%; }
/* Three layers, so the flight is a true arc: across at an even pace (.arw), up then down (.arw-y,
   rising fast and slowing at the top, then falling ever faster), and the shaft turning nose-down as it
   goes (svg). The lift is in container units, so the arc keeps its shape on any field. */
.arw-y { position: absolute; inset: 0; }
.arw-y svg { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.bf.advance .arw { animation: fly-x 1.5s var(--d) linear infinite; }
.bf.advance .arw.from-def { animation-name: fly-x-back; }
.bf.advance .arw-y { animation: fly-y 1.5s var(--d) infinite; }
.bf.advance .arw-y svg { animation: tilt 1.5s var(--d) linear infinite; }
.bf.advance .arw.from-def .arw-y svg { animation-name: tilt-back; }
.bf.rout .arw { animation: none; opacity: 0; }
@keyframes fly-x { 0% { transform: translateX(0); opacity: 0; } 8% { opacity: 1; } 92% { opacity: 1; } 100% { transform: translateX(1100%); opacity: 0; } }
@keyframes fly-x-back { 0% { transform: translateX(0); opacity: 0; } 8% { opacity: 1; } 92% { opacity: 1; } 100% { transform: translateX(-1200%); opacity: 0; } }
@keyframes fly-y {
  0% { transform: translateY(0); animation-timing-function: cubic-bezier(.33, .67, .67, 1); }
  50% { transform: translateY(calc(var(--lift, 16) * -1cqh)); animation-timing-function: cubic-bezier(.33, 0, .67, .33); }
  100% { transform: translateY(0); }
}
@keyframes tilt { from { transform: rotate(-32deg); } to { transform: rotate(32deg); } }
@keyframes tilt-back { from { transform: scaleX(-1) rotate(-32deg); } to { transform: scaleX(-1) rotate(32deg); } }
@media (prefers-reduced-motion: reduce) { .bf * { animation: none !important; transition: none !important; } }

/* Live headcounts over the field. */
.field-screen .morale { position: absolute; top: 10px; width: min(36%, 280px); font-size: 12px; z-index: 2; }
.field-screen .morale.atk { left: 12px; }
.field-screen .morale.def { right: 12px; text-align: right; }
.field-screen .morale span { filter: brightness(1.7); font-weight: bold; text-shadow: 0 1px 2px #000; }
.field-screen .morale b { font-weight: normal; color: #f4e9d4; font-variant-numeric: tabular-nums; text-shadow: 0 1px 2px #000; }
.field-screen .morale i { display: block; height: 8px; margin-top: 3px; border-radius: 4px; background: rgba(20,12,6,.7); overflow: hidden; position: relative; }
.field-screen .morale i::after { content: ""; position: absolute; inset: 0; transform-origin: left; transform: scaleX(var(--m, 1)); background: linear-gradient(90deg, #e2b45a, #c0392b); transition: transform .25s linear; }
.field-screen .morale.def i::after { transform-origin: right; }
.field-screen .morale.routed span::after { content: " · tháo chạy"; color: #e06a4f; }
.stage[data-phase="skill"] .field-screen { filter: brightness(.45) saturate(.6); }

/* =====================================================================
   Bày trận: the war tent. Lacquer frame, a paper table for the array,
   memorials from the council, a gauge for the king's last look.
   ===================================================================== */
.muster { position: fixed; inset: 0; z-index: 25; background: rgba(8, 5, 3, .78); display: flex; align-items: center; justify-content: center;
  padding: max(10px, env(safe-area-inset-top, 0px)) max(10px, env(safe-area-inset-right, 0px)) max(10px, env(safe-area-inset-bottom, 0px)) max(10px, env(safe-area-inset-left, 0px)); }
.mu-frame { width: min(1360px, 100%); max-height: 100%; display: flex; flex-direction: column; overflow-y: auto; overscroll-behavior: contain; color: #f2e4c6;
  background: linear-gradient(180deg, #24150c, #160d07); border: 2px solid #c99a3a; border-radius: 10px;
  box-shadow: 0 0 0 6px #2a170c, 0 0 0 7px #7a5520, 0 30px 80px rgba(0,0,0,.6); animation: mu-in .45s cubic-bezier(.2,.9,.3,1.1) both; }
@keyframes mu-in { from { opacity: 0; transform: translateY(18px) scale(.98); } to { opacity: 1; transform: none; } }
.mu-head { display: flex; align-items: center; gap: 14px; padding: 12px 18px; border-bottom: 1px solid #5a3e1e;
  background: linear-gradient(90deg, rgba(163,39,28,.35), transparent 40%), repeating-linear-gradient(90deg, rgba(255,255,255,.02) 0 2px, transparent 2px 6px); flex-wrap: wrap; }
.mu-seal { display: grid; place-items: center; width: 46px; height: 46px; flex: 0 0 46px; background: #a3271c; color: #fff3d6; font: 700 26px var(--font-title);
  border-radius: 6px; box-shadow: inset 0 0 0 2px #f3d27a, 0 4px 10px rgba(0,0,0,.4); transform: rotate(-5deg); }
.mu-title { margin: 0; font: 700 26px/1.2 var(--font-title); color: #f3d27a; letter-spacing: .06em; display: grid; flex: 1 1 260px; }
.mu-title small { font: 400 14px var(--font-body); color: #c9b08a; letter-spacing: 0; }
.mu-target { display: flex; gap: 10px; flex-wrap: wrap; font-size: 13px; color: #c9b08a; }
.mu-target select { margin-left: 6px; font: inherit; color: #f2e4c6; background-color: #2c1a0e; border: 1px solid #7a5520; border-radius: 5px; padding: 4px 26px 4px 8px; }
.mu-close { color: #f2e4c6 !important; border-color: #7a5520 !important; }

/* Quân nghị: memorials from the strategist and the generals. */
.mu-council { padding: 12px 18px 4px; border-bottom: 1px solid #3d2a17; flex: 0 0 auto; }
.mu-council-head { display: flex; gap: 12px; align-items: baseline; flex-wrap: wrap; margin-bottom: 8px; }
.mu-council-head b { font: 700 17px var(--font-title); color: #f3d27a; letter-spacing: .05em; }
.mu-council-head span { font-size: 13px; color: #c9b08a; }
.mu-memorials { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(260px, 1fr); gap: 12px; overflow-x: auto; padding-bottom: 8px; scroll-snap-type: x mandatory; }
.mu-memorial { scroll-snap-align: start; display: grid; gap: 6px; align-content: start; padding: 10px 12px 12px; border-radius: 8px; color: #2a1d12;
  background: linear-gradient(180deg, #f6ead0, #e9d8b4); border: 1px solid #b8945a; box-shadow: inset 0 0 0 3px rgba(255,255,255,.35), 0 6px 14px rgba(0,0,0,.35);
  position: relative; transition: transform .2s, box-shadow .2s; }
.mu-memorial::before, .mu-memorial::after { content: ""; position: absolute; left: 8px; right: 8px; height: 5px; border-radius: 3px; background: #6b3f1f; }
.mu-memorial::before { top: -3px; } .mu-memorial::after { bottom: -3px; }
.mu-memorial.on { transform: translateY(-3px); box-shadow: 0 0 0 2px #a3271c, 0 10px 22px rgba(0,0,0,.45); }
.mu-memorial header { display: flex; gap: 10px; align-items: center; }
.mu-memorial header > div { display: grid; flex: 1; min-width: 0; }
.mu-memorial header b { font: 700 16px var(--font-title); }
.mu-memorial header small { color: #6b5a40; font-size: 12px; }
.mu-memorial .portrait { width: 44px; flex: 0 0 44px; box-shadow: 0 0 0 1.5px #b8945a; }
.mu-memorial .stance { font-style: normal; font-size: 11px; color: #fff3d6; background: #6b3f1f; border-radius: 999px; padding: 0 8px; justify-self: start; }
.mu-memorial .odds { font: 700 20px var(--font-title); color: #6b5a40; }
.mu-memorial .odds.good { color: #2f6b3a; } .mu-memorial .odds.bad { color: #a3271c; }
.mu-memorial q { font-style: italic; font-size: 14px; line-height: 1.5; quotes: "«" "»"; }
.mu-plan-line { margin: 0; font-size: 12px; color: #5a4a35; }
.mu-adopt { justify-self: start; background: #a3271c; color: #fff3d6; border-radius: 5px; padding: 5px 14px; font-size: 14px; }
.mu-adopt.on { background: #2f6b3a; }

.mu-body { display: grid; grid-template-columns: minmax(250px, 1fr) minmax(360px, 1.6fr) minmax(250px, 1fr); gap: 0; flex: 0 0 auto; }
.mu-body > section { padding: 14px 16px; min-width: 0; }
.mu-ours, .mu-theirs { background: linear-gradient(180deg, rgba(255,255,255,.03), transparent); }
.mu-ours { border-right: 1px solid #3d2a17; }
.mu-theirs { border-left: 1px solid #3d2a17; }
.mu-body h3 { margin: 0 0 10px; font: 700 18px var(--font-title); color: #f3d27a; display: flex; justify-content: space-between; gap: 8px;
  border-bottom: 2px solid var(--c, #c99a3a); padding-bottom: 6px; }
.mu-body h3 span { font: 400 13px var(--font-body); color: #c9b08a; }
.mu-bar { display: flex; height: 10px; border-radius: 5px; overflow: hidden; box-shadow: inset 0 0 0 1px rgba(0,0,0,.4); margin-bottom: 6px; }
.mu-units { list-style: none; margin: 0 0 12px; padding: 0; display: grid; grid-template-columns: 1fr 1fr; gap: 2px 12px; font-size: 13px; }
.mu-units li { display: flex; align-items: center; gap: 6px; }
.mu-units b { margin-left: auto; font-variant-numeric: tabular-nums; }
.mu-units small { color: #9c8564; width: 3ch; text-align: right; }
.mu-units .sw { width: 10px; height: 10px; border-radius: 2px; flex: 0 0 10px; }

.mu-slots { display: grid; gap: 8px; }
.mu-slot { display: grid; grid-template-columns: 56px 1fr; grid-template-rows: auto auto auto; column-gap: 10px; text-align: left; padding: 8px; color: #f2e4c6;
  background: rgba(0,0,0,.25); border: 1px solid #5a3e1e; border-radius: 8px; box-shadow: none; }
.mu-slot:hover, .mu-slot.on { border-color: #f3d27a; background: rgba(243,210,122,.08); }
.mu-slot .portrait { grid-row: 1 / span 4; width: 56px; }
.mu-slot .slot-label { font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: #c99a3a; }
.mu-slot b { font: 700 16px var(--font-title); }
.mu-slot small { color: #b49b76; font-size: 12px; }
.mu-slot .chips i, .mu-person .chips i, .mu-foe .chips i { font-style: normal; font-size: 11px; padding: 0 6px; margin: 2px 4px 0 0; border: 1px solid #7a5520; border-radius: 8px; color: #e2c98f; display: inline-block; }
.mu-roster { margin-top: 10px; border: 1px solid #7a5520; border-radius: 8px; background: #1d110a; padding: 8px; }
.mu-roster-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 6px; color: #f3d27a; }
.mu-roster-head button { color: #f2e4c6; border-color: #7a5520; padding: 2px 10px; font-size: 13px; }
.mu-people { display: grid; gap: 6px; max-height: 300px; overflow: auto; }
.mu-person { display: grid; grid-template-columns: 40px 1fr; gap: 8px; text-align: left; padding: 6px; color: #f2e4c6; background: transparent; border: 1px solid #3d2a17; border-radius: 6px; box-shadow: none; }
.mu-person:hover, .mu-person.on { border-color: #f3d27a; background: rgba(243,210,122,.08); }
.mu-person .portrait { width: 40px; flex: none; }
.mu-person b { display: block; font-size: 14px; }
.mu-person small { color: #9c8564; font-size: 11px; }
.mu-person .stats em { font-style: normal; font-size: 12px; margin-right: 8px; color: #c9b08a; }
.mu-person .stats em.key { color: #f3d27a; font-weight: bold; }

/* The table: the array drawn on paper. */
.mu-table { display: grid; gap: 12px; align-content: start;
  background: radial-gradient(ellipse at center, rgba(243,226,181,.06), transparent 70%); }
.mu-map { position: relative; border-radius: 10px; overflow: hidden; color: #2a1d12;
  background: #efe1bf url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='120' height='120'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='2' seed='3'/><feColorMatrix values='0 0 0 0 .4 0 0 0 0 .28 0 0 0 0 .12 0 0 0 .12 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
  border: 3px solid #7a5520; box-shadow: inset 0 0 40px rgba(110,70,30,.35), 0 10px 26px rgba(0,0,0,.45); }
.diagram { display: block; width: 100%; height: auto; }
.diagram.big { aspect-ratio: 1.55; max-height: 300px; }
.diagram text { font: 700 3.6px var(--font-body); fill: #fff3d6; text-anchor: middle; paint-order: stroke; stroke: rgba(0,0,0,.45); stroke-width: .6px; }
.diagram text.enemy { fill: #9b2c1f; stroke: none; font-size: 4px; text-anchor: end; }
.diagram.big .blk { animation: blk-in .5s calc(var(--i) * 45ms) both; transform-box: fill-box; transform-origin: center; }
@keyframes blk-in { from { opacity: 0; transform: translateX(-6px) scale(.7); } to { opacity: 1; transform: none; } }
.mu-map-title { position: absolute; left: 12px; bottom: 10px; right: 12px; display: grid; gap: 1px; text-shadow: 0 1px 0 rgba(255,255,255,.6); }
.mu-map-title .han, .mu-form .han, .mu-plan-line .han, .mu-intel .han, .array-plan .han { font-family: "Noto Serif TC", "Noto Serif SC", serif; }
.mu-map-title .han { font-size: 26px; color: #a3271c; letter-spacing: .12em; }
.mu-map-title b { font: 700 18px var(--font-title); }
.mu-map-title small { font-size: 13px; color: #5a4a35; max-width: 60ch; }
.mu-forms { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.mu-form { position: relative; display: grid; gap: 2px; text-align: left; padding: 8px; color: #f2e4c6; background: rgba(0,0,0,.28); border: 1px solid #5a3e1e; border-radius: 8px; box-shadow: none; }
.mu-form:hover { border-color: #c99a3a; }
.mu-form.on { border-color: #f3d27a; background: linear-gradient(180deg, rgba(243,210,122,.16), rgba(0,0,0,.2)); box-shadow: 0 0 0 1px #f3d27a; }
.mu-form .diagram { background: #e9d8b4; border-radius: 5px; aspect-ratio: 1.6; margin-bottom: 4px; }
.mu-form .han { font-size: 15px; color: #e2b45a; letter-spacing: .1em; }
.mu-form b { font: 700 14px var(--font-title); }
.mu-form small { font-size: 11.5px; color: #b49b76; }
.mu-form .tag { position: absolute; top: 6px; right: 6px; font-style: normal; font-size: 10.5px; padding: 1px 7px; border-radius: 999px; }
.mu-form .tag.good { background: #2f6b3a; color: #e9f5e6; }
.mu-form .tag.bad { background: #8e2219; color: #ffe6e0; }

.mu-foe { display: flex; gap: 10px; align-items: center; margin-bottom: 8px; }
.mu-foe .portrait { width: 64px; flex: 0 0 64px; }
.mu-foe b { font: 700 17px var(--font-title); display: block; }
.mu-foe small { color: #b49b76; font-size: 12px; }
.mu-intel { font-size: 13px; color: #d9c7a4; margin: 6px 0 10px; line-height: 1.5; }
.mu-intel b { color: #f3d27a; }
.mu-theirs .diagram { background: #e9d8b4; border-radius: 6px; aspect-ratio: 1.6; margin-bottom: 10px; transform: scaleX(-1); }

/* The king's last look: the gauge, the reckoning, the decree. */
.mu-foot { display: grid; grid-template-columns: 220px 1fr auto; gap: 16px; align-items: center; padding: 12px 18px; border-top: 1px solid #5a3e1e;
  background: #1f130b; position: sticky; bottom: 0; z-index: 3; }
.mu-gauge { position: relative; display: grid; justify-items: center; }
.mu-gauge svg { width: 200px; height: auto; }
.mu-gauge .needle { transform-origin: 100px 104px; transition: transform .7s cubic-bezier(.3,1.4,.5,1); }
.mu-gauge.busy .needle { animation: quiver .4s ease-in-out infinite alternate; }
@keyframes quiver { from { filter: none; } to { filter: drop-shadow(0 0 3px #f3d27a); } }
.mu-chance { display: grid; justify-items: center; margin-top: -14px; }
.mu-chance b { font: 700 30px var(--font-title); color: #f3d27a; font-variant-numeric: tabular-nums; }
.mu-chance span { font-size: 13px; color: #c9b08a; letter-spacing: .05em; }
.mu-notes { font-size: 13px; color: #d9c7a4; min-width: 0; }
.mu-notes b { color: #f3d27a; font: 700 15px var(--font-title); }
.mu-notes ul { margin: 4px 0 0; padding-left: 16px; columns: 2; column-gap: 24px; }
.mu-actions { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; justify-content: flex-end; }
.mu-actions .ghost { color: #f2e4c6; border-color: #7a5520; }
.mu-go { font: 700 17px var(--font-title); letter-spacing: .06em; padding: 12px 26px; background: linear-gradient(180deg, #c0392b, #8e2219);
  border: 1px solid #f3d27a; box-shadow: 0 0 0 3px rgba(243,210,122,.18), 0 6px 16px rgba(0,0,0,.4); }
.mu-error { color: #ff9c86; font-size: 13px; margin: 0; flex-basis: 100%; text-align: right; }
.mu-error:empty { display: none; }
.army .march { float: right; margin-left: 8px; }
.array-plan { font-size: 13px; color: #f3d27a; margin: 2px 0 4px; }

/* The war orders: three tabs (kế sách, bày trận, quân lệnh). */
.mu-center { padding: 0 !important; display: flex; flex-direction: column; min-width: 0;
  background: radial-gradient(ellipse at center, rgba(243,226,181,.06), transparent 70%); }
.mu-center .mu-table { padding: 12px 16px 16px; }
.mu-tabs { display: flex; gap: 4px; padding: 10px 16px 0; border-bottom: 1px solid #5a3e1e; position: sticky; top: 0; background: #23150c; z-index: 2; }
.mu-tab { flex: 1; display: flex; gap: 8px; align-items: center; justify-content: center; padding: 8px 10px; color: #c9b08a; background: transparent;
  border: 1px solid #3d2a17; border-bottom: 0; border-radius: 8px 8px 0 0; box-shadow: none; font: 700 15px var(--font-title); letter-spacing: .04em; }
.mu-tab i { font-style: normal; display: grid; place-items: center; width: 22px; height: 22px; border-radius: 50%; border: 1px solid currentColor; font-size: 12px; }
.mu-tab.on { color: #f3d27a; background: rgba(243,210,122,.1); border-color: #7a5520; }
.mu-lead { margin: 0; font-size: 13px; color: #c9b08a; }
.mu-ways { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(190px, 100%), 1fr)); gap: 8px; }
.mu-way { display: grid; gap: 3px; align-content: start; text-align: left; padding: 10px; color: #f2e4c6; background: rgba(0,0,0,.28);
  border: 1px solid #5a3e1e; border-radius: 8px; box-shadow: none; }
.mu-way:hover { border-color: #c99a3a; }
.mu-way.on { border-color: #f3d27a; background: linear-gradient(180deg, rgba(243,210,122,.16), rgba(0,0,0,.2)); box-shadow: 0 0 0 1px #f3d27a; }
.mu-way .han { font-family: "Noto Serif TC", "Noto Serif SC", serif; font-size: 18px; color: #e2b45a; letter-spacing: .1em; }
.mu-way b { font: 700 15px var(--font-title); }
.mu-way small { font-size: 12px; color: #c9b08a; line-height: 1.4; }
.mu-way .needs { color: #a8916c; }
.mu-way .why { color: #e2c98f; font-style: italic; }
.mu-way .cost { color: #e0a46a; }
.mu-way .odds { font-style: normal; font: 700 13px var(--font-title); color: #e2c98f; }
.mu-way .odds.good { color: #8fd09a; } .mu-way .odds.bad { color: #ff9c86; }
.mu-board { position: relative; display: grid; gap: 8px; padding: 12px 34px 12px 12px; border-radius: 10px; color: #2a1d12;
  grid-template-columns: repeat(3, minmax(0, 1fr)); grid-template-areas: ". TA ." "HAU TRUNG TIEN" ". HUU ." "title title title";
  background: #efe1bf; border: 3px solid #7a5520; box-shadow: inset 0 0 40px rgba(110,70,30,.35), 0 10px 26px rgba(0,0,0,.45); }
.mu-board-enemy { position: absolute; right: 6px; top: 50%; transform: translateY(-50%); writing-mode: vertical-rl; font: 700 13px var(--font-title); color: #9b2c1f; }
.mu-board .mu-map-title { position: static; grid-area: title; display: flex; gap: 10px; align-items: baseline; }
.mu-board .mu-map-title .han { font-size: 20px; }
.mu-post { display: grid; gap: 2px; align-content: start; padding: 5px 7px; border-radius: 6px; min-width: 0;
  background: rgba(255,250,236,.92); border: 2px solid var(--c); box-shadow: 0 3px 8px rgba(60,30,10,.3); font-size: 12px; }
.mu-post[data-post="TIEN"] { grid-area: TIEN; } .mu-post[data-post="TA"] { grid-area: TA; } .mu-post[data-post="HUU"] { grid-area: HUU; }
.mu-post[data-post="TRUNG"] { grid-area: TRUNG; } .mu-post[data-post="HAU"] { grid-area: HAU; }
.mu-post.empty { opacity: .7; border-style: dashed; }
.mu-post.on { box-shadow: 0 0 0 3px #f3d27a; }
.mu-post-name { font: 700 12px var(--font-title); color: #7a3b1a; letter-spacing: .06em; text-transform: uppercase; }
.mu-post-gen { padding: 1px 6px; font: 700 13px var(--font-title); color: #2a1d12; background: transparent; border: 1px dashed #a07a46; border-radius: 4px; text-align: left; box-shadow: none; }
.mu-post-arms { display: flex; flex-wrap: wrap; gap: 2px; }
.mu-post-arms i { font-style: normal; font-size: 10.5px; color: #fff3d6; padding: 0 4px; border-radius: 3px; }
.mu-post-arms i.none { color: #8a7454; background: none; }
.mu-ords { display: flex; gap: 2px; flex-wrap: wrap; }
.mu-ord { padding: 0 6px; font-size: 11px; line-height: 18px; background: #e6d3a8; color: #4a3220; border-radius: 3px; box-shadow: none; }
.mu-ord.on { background: #a3271c; color: #fff3d6; }
.mu-arms { font-size: 13px; color: #d9c7a4; }
.mu-arms summary { cursor: pointer; color: #f3d27a; font: 700 14px var(--font-title); }
.mu-arms table { width: 100%; border-collapse: collapse; margin-top: 4px; }
.mu-arms th { text-align: left; font-weight: normal; padding: 2px 0; }
.mu-arms th small { color: #9c8564; }
.mu-arms .sw { display: inline-block; width: 10px; height: 10px; border-radius: 2px; margin-right: 6px; }
.mu-arms select, .mu-rule select { width: 100%; font: inherit; color: #f2e4c6; background-color: #2c1a0e; border: 1px solid #7a5520; border-radius: 5px; padding: 2px 6px; }
.mu-rule { border: 1px solid #5a3e1e; border-radius: 8px; padding: 6px 10px 8px; margin: 0; display: grid; gap: 4px; }
.mu-rule legend { font: 700 14px var(--font-title); color: #f3d27a; padding: 0 4px; }
.mu-rule label { display: grid; grid-template-columns: auto 1fr; column-gap: 8px; align-items: baseline; padding: 4px 6px; border-radius: 6px; cursor: pointer; }
.mu-rule label.on { background: rgba(243,210,122,.1); }
.mu-rule label small { grid-column: 2; font-size: 12px; color: #b49b76; }
.mu-rule input { accent-color: #c0392b; }
.mu-wings-staff { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(220px, 100%), 1fr)); gap: 8px; }
.mu-counsel-head { font: 700 14px var(--font-title); color: #f3d27a; margin: 4px 0; }
.mu-counsel { list-style: none; margin: 0 0 8px; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(min(380px, 100%), 1fr)); gap: 4px 16px; font-size: 13px; color: #e8d6b2; }
.mu-counsel li { display: flex; gap: 8px; align-items: center; }
.mu-counsel .portrait { width: 28px; flex: 0 0 28px; }
.mu-counsel b { color: #f3d27a; white-space: nowrap; }

@media (max-width: 980px) {
  .mu-body { grid-template-columns: 1fr; }
  .mu-ours, .mu-theirs { border: 0; border-top: 1px solid #3d2a17; }
  .mu-center { order: -1; }
  .mu-post { font-size: 11px; padding: 4px; }
  .mu-board { padding-right: 24px; gap: 5px; }
  .mu-foot { grid-template-columns: 1fr; justify-items: center; }
  .mu-notes ul { columns: 1; }
  .mu-actions { justify-content: center; }
  .mu-forms { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (prefers-reduced-motion: reduce) { .mu-frame, .diagram.big .blk, .mu-gauge .needle { animation: none !important; transition: none !important; } }

/* ---------- the drawn map: land, water, mountains, realms ---------- */
#map { background: #d9c9a3; }
#map .map-paper { fill: #e3d3ad; }
#map .wild path { fill: #d6c49a; stroke: #b9a274; stroke-width: .6; }
#map .sea path { fill: #9fb7b0; stroke: #8aa59e; stroke-width: .6; }
#map .wave { fill: none; stroke: #e9f0e8; stroke-width: .9; opacity: .8; }
#map .steppe { fill: #a58e5c; opacity: .55; }
#map .hex { stroke: rgba(60, 40, 20, .28); stroke-width: .7; stroke-dasharray: 2 2; fill-opacity: .42; transition: fill-opacity .15s; }
#map .hex:hover { fill-opacity: .62; }
#map .hex.player { fill-opacity: .5; stroke: #f3d27a; stroke-width: 1; stroke-dasharray: none; }
#map .hex.selected { fill-opacity: .7; stroke: #ffe28a; stroke-width: 2.6; stroke-dasharray: none; }
#map .land { mix-blend-mode: multiply; }
#map .river-bank { fill: none; stroke: #e9dcc0; stroke-linecap: round; stroke-linejoin: round; opacity: .9; }
#map .river { fill: none; stroke: #4f7f99; stroke-linecap: round; stroke-linejoin: round; opacity: .95; }
#map .lake { fill: #6d97ab; stroke: #e9dcc0; stroke-width: 1.4; }
#map .tree { fill: #3f5a32; opacity: .85; }
#map .peak-body { fill: #b5a07a; stroke: #4a3a28; stroke-width: .8; stroke-linejoin: round; }
#map .peak-shade { fill: #8a7454; }
#map .peak-snow { fill: none; stroke: #f6eedc; stroke-width: 1.1; stroke-linecap: round; }
#map .terrain-name, #map .river-name, #map .region, #map .sea-name {
  font: italic 6.5px var(--font-body); fill: #4a3a28; text-anchor: middle; paint-order: stroke; stroke: rgba(240,228,200,.8); stroke-width: 2px; }
#map .river-name { fill: #2f5a72; }
#map .region { font-size: 9px; letter-spacing: .2em; fill: #6b5638; }
#map .sea-name { font-size: 11px; letter-spacing: .3em; fill: #3f6b78; }
#map .realm-edge { fill: none; stroke: #2a1b10; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; opacity: .8; }
#map .realm-name { font: 700 16px var(--font-title); text-anchor: middle; letter-spacing: .25em; text-transform: uppercase;
  fill: rgba(42, 27, 16, .55); paint-order: stroke; stroke: rgba(240, 228, 200, .55); stroke-width: 3px; }
#map .capital-name { font: 700 6.5px var(--font-body); fill: #2a1b10; text-anchor: middle; paint-order: stroke; stroke: rgba(240,228,200,.9); stroke-width: 2px; }
#map .palace path { fill: #2a1a10; }
#map .palace .roof { fill: #c0392b; stroke: #2a1a10; stroke-width: .7; }

/* Realms as washes of colour; provinces show only when picked. */
#map .realm { opacity: .46; }
#map .realm.mine { opacity: .55; }
#map .realm .hex, #map .realm .hex:hover, #map .realm .hex.player, #map .realm .hex.selected { fill-opacity: 1; stroke-width: 1.4; stroke-dasharray: none; }
#map .realm .hex { cursor: pointer; }
#map .wild path { stroke: #d6c49a; stroke-width: 1.4; }
#map .sea path { stroke: #9fb7b0; stroke-width: 1.4; }
#map .selected-outline { fill: rgba(255, 226, 138, .18); stroke: #ffe28a; stroke-width: 2.4; stroke-linejoin: round; }
/* The tent scrolls as one; the decree bar stays in reach at the bottom. */
.mu-frame { overflow-y: auto; overscroll-behavior: contain; }
.mu-body { overflow: visible; flex: none; }
.mu-foot { position: sticky; bottom: 0; z-index: 3; background: linear-gradient(180deg, #1f120a, #140b06); box-shadow: 0 -8px 18px rgba(0,0,0,.45); }
.mu-head { position: sticky; top: 0; z-index: 3; background-color: #22140b; }
.mu-memorial q { font-size: 13.5px; }
@media (max-width: 640px) {
  .mu-memorials { grid-auto-columns: minmax(240px, 86%); }
  .mu-foot { gap: 6px; padding: 8px 12px; }
  .mu-gauge svg { width: 150px; }
  .mu-notes { display: none; }
  .mu-head .mu-target { flex-basis: 100%; }
  .mu-title { font-size: 22px; }
}

.mu-chance { margin-top: -10px; }
.mu-chance span { font-size: 12px; letter-spacing: .12em; text-transform: uppercase; color: #9c8564; }
.mu-chance b { font-size: 22px; letter-spacing: .02em; }
.mu-memorial .odds { font-size: 14px; white-space: nowrap; border: 1.5px solid currentColor; border-radius: 4px; padding: 1px 8px; transform: rotate(-3deg); }
.mu-notes li { letter-spacing: .01em; }
.mu-chance b { font-size: 17px; text-align: center; line-height: 1.2; }

/* Painted terrain map: one wash per realm over the picture, unbroken ink borders. */
#map .land { mix-blend-mode: multiply; }
#map .land .realm { opacity: .5; }
#map .land .realm.mine { opacity: .6; }
#map .hits .hex { fill: transparent; stroke: none; cursor: pointer; transition: fill .15s; }
#map .hits .hex:hover { fill: rgba(255, 240, 200, .16); }
#map .province-line { fill: none; stroke: rgba(50, 32, 16, .32); stroke-width: .6; stroke-dasharray: 1.6 2.2; stroke-linecap: round; }
#map .realm-edge-halo { fill: none; stroke: rgba(250, 238, 206, .55); stroke-width: 4.2; stroke-linecap: round; stroke-linejoin: round; }
#map .realm-edge { fill: none; stroke: #2a1b10; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; opacity: .9; }
#map .selected-outline { fill: rgba(255, 226, 138, .14); stroke: #ffe28a; stroke-width: 2; stroke-linejoin: round;
  filter: drop-shadow(0 0 2px rgba(80, 50, 10, .7)); }
#map .terrain-name { fill: #4a3a28; font-style: italic; }

/* ---------- painted battle scenes (static/img/field-*.webp; portraits painted by faces.js) ---------- */
.battle .stage { background: #120d09 var(--backdrop) center / cover no-repeat; }
.report-screen { background: radial-gradient(circle at 50% 45%, rgba(40, 22, 10, .45), rgba(12, 8, 5, .9) 75%); }
.report-screen .messenger { width: min(28vw, 220px); aspect-ratio: 166 / 100; color: #b98a3a; filter: drop-shadow(0 8px 10px rgba(0, 0, 0, .7)); animation: run-in 1.4s ease-out both; }
.report-screen .report-text { text-shadow: 0 2px 6px #000; }
.array-screen { background: linear-gradient(90deg, rgba(90, 20, 12, .62), rgba(12, 8, 5, .82) 38%, rgba(12, 8, 5, .82) 62%, rgba(16, 30, 60, .62)); }
.side-card { background: linear-gradient(rgba(26, 17, 10, .9), rgba(14, 9, 5, .86)); border: 1px solid rgba(226, 180, 90, .5);
  box-shadow: 0 10px 30px rgba(0, 0, 0, .55), inset 0 0 0 1px rgba(0, 0, 0, .6); }
.array-screen .versus { font-size: 44px; color: #f3d27a; text-shadow: 0 0 18px #b3261e, 0 2px 4px #000; }
.skill-screen { background: radial-gradient(circle at 40% 50%, rgba(120, 30, 18, .55), rgba(8, 5, 3, .85) 70%); }
.result-screen { background: radial-gradient(circle at 50% 50%, rgba(12, 8, 5, .35), rgba(12, 8, 5, .75)); }
.result-text { text-shadow: 0 2px 6px #000; }

.portrait.painted { position: relative; container-type: inline-size;
  background: linear-gradient(172deg, #f1dfb9, #c79f6a 72%, color-mix(in srgb, var(--c) 40%, #5d4026)); }
.portrait.painted svg { width: 100%; height: 100%; }
.portrait.painted .seal-mark { position: absolute; right: 6%; bottom: 5%; padding: 2% 5%; border-radius: 3px; background: #b3261e; color: #fff4dc;
  font: 700 12cqw/1.1 var(--font-body); box-shadow: 0 1px 3px rgba(0, 0, 0, .5); }
.portrait.painted.big .seal-mark { font-size: 9cqw; }

.field-screen .morale.hud { display: flex; gap: 8px; align-items: flex-start; top: 8px; width: min(40%, 360px); padding: 6px 8px; z-index: 5;
  background: linear-gradient(rgba(14, 9, 5, .86), rgba(14, 9, 5, .6)); border: 1px solid rgba(226, 180, 90, .38); border-radius: 10px;
  box-shadow: 0 6px 18px rgba(0, 0, 0, .45); }
.field-screen .morale.hud.def { flex-direction: row-reverse; }
.field-screen .morale.hud .portrait { width: 48px; flex: 0 0 48px; box-shadow: 0 0 0 1.5px var(--c), 0 2px 6px rgba(0, 0, 0, .6); }
.field-screen .morale.hud .portrait .seal-mark { display: none; }
.hud-body { flex: 1; min-width: 0; }
.hud-name { font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-shadow: 0 1px 2px #000; }
.field-screen .morale .hud-name span { color: var(--c); filter: brightness(1.7); }
.field-screen .morale.routed span::after { content: none; }
.field-screen .morale.routed .hud-name span::after { content: " · tháo chạy"; color: #e06a4f; }
.hud-arms { display: flex; flex-wrap: wrap; gap: 1px 8px; margin-top: 3px; font-size: 11px; color: #d2bb90; }
.hud-arms span { white-space: nowrap; }
.field-screen .morale.hud.def .hud-arms { justify-content: flex-end; }
.bf-place { top: 21%; font-size: clamp(13px, 1.8vw, 20px); letter-spacing: .12em; }

.standard { position: absolute; top: 28%; height: 38%; aspect-ratio: 1 / 5; z-index: 3; pointer-events: none; }
.standard.atk { left: 4%; }
.standard.def { right: 4%; }
.standard.def.walled { right: 8%; top: 16%; }
.standard > i { position: absolute; left: 0; top: -4%; bottom: 0; width: 8%; min-width: 2px; border-radius: 2px;
  background: linear-gradient(90deg, #2e1f12, #9a7642, #2e1f12); }
.standard.def > i { left: auto; right: 0; }
.standard span { position: absolute; left: 8%; top: 2%; width: 140%; height: 60%; display: flex; align-items: center; justify-content: center;
  writing-mode: vertical-rl; text-orientation: upright; color: #fff3d6; font: 700 clamp(12px, 1.7vw, 22px)/1 var(--font-title); letter-spacing: -.05em;
  background: linear-gradient(90deg, rgba(0, 0, 0, .28), transparent 40%, rgba(0, 0, 0, .32)), var(--c);
  box-shadow: inset 0 0 0 2px rgba(243, 210, 122, .75); clip-path: polygon(0 0, 100% 0, 100% 100%, 50% 88%, 0 100%);
  transform-origin: left center; animation: banner-sway 3.2s ease-in-out infinite alternate; text-shadow: 0 1px 2px #000; }
.standard.def span { left: auto; right: 8%; transform-origin: right center; }
.standard small { position: absolute; left: 8%; top: 64%; width: 140%; text-align: center; color: #f3d27a;
  font-size: clamp(10px, 1.2vw, 15px); text-shadow: 0 1px 2px #000; }
.standard.def small { left: auto; right: 8%; }
@keyframes banner-sway { from { transform: skewY(-3deg) scaleX(.96); } to { transform: skewY(3deg) scaleX(1.03); } }
.bf.rout.atk-wins .standard.def, .bf.rout.def-wins .standard.atk { opacity: 0; transition: opacity 1.4s; }
@media (prefers-reduced-motion: reduce) { .standard span { animation: none; } }
@media (max-width: 640px) {
  .field-screen .morale.hud { width: 46%; padding: 4px; }
  .field-screen .morale.hud .portrait { display: none; }
  .hud-arms { display: none; }
}
/* Blend each wash, not the masked group: Chrome clips a blended, masked group to a stale tile at high DPI. */
#map .land { mix-blend-mode: normal; }
#map .land .realm { mix-blend-mode: multiply; }

/* Difficulty of each realm on the setup screen. */
.choice .difficulty { display: inline-flex; gap: 4px; align-items: center; margin-left: 6px; padding: 0 8px; border-radius: 999px;
  font-size: 12px; font-weight: bold; vertical-align: middle; color: #fff8e6; background: #4f7a3a; }
.choice .difficulty i { font-style: normal; letter-spacing: .05em; color: #ffe39a; }
.choice .difficulty.d3 { background: #a8741c; }
.choice .difficulty.d4, .choice .difficulty.d5 { background: #a3332a; }
.choice .difficulty-note { font-style: italic; }
#nation-choices .resume { grid-column: 1 / -1; justify-self: start; padding: 8px 16px; border-radius: 999px; font-weight: bold;
  background: #2a160d; color: #f3d27a; border: 1px solid var(--gold); cursor: pointer; }

/* ---------- 3D-rendered troops (static/img/troops): flip-book sheets, moved by transforms ---------- */
.co-art.sprite, .corpse, .rider { position: relative; display: block; width: 100%; aspect-ratio: var(--ar); overflow: hidden; filter: none; }
.sprite .sheet { position: absolute; left: 0; top: 0; width: calc(var(--n) * 100%); height: calc(var(--rows) * 100%);
  translate: 0 calc(var(--row, 0) * -100% / var(--rows)); will-change: transform; }
.sprite .paint, .sprite .tint { position: absolute; inset: 0; }
.sprite .paint { background: var(--sheet) 0 0 / 100% 100% no-repeat; }
/* Robes in the realm's colour: the mask says where, multiply keeps the folds and shading. */
.sprite .tint { background: currentColor; mix-blend-mode: multiply; opacity: .92;
  -webkit-mask: var(--mask) 0 0 / 100% 100% no-repeat; mask: var(--mask) 0 0 / 100% 100% no-repeat; }
@keyframes troop-frames { from { transform: translateX(0); } to { transform: translateX(-100%); } }
.bf.advance .co-art.sprite .sheet, .bf.rout .co-art.sprite .sheet, .rider .sheet {
  animation: troop-frames .8s steps(var(--n)) var(--delay, 0s) infinite; }
.bf.melee .co-art.sprite { --row: 1; }
.bf.melee .co-art.sprite .sheet { animation: troop-frames .9s steps(var(--n)) var(--delay, 0s) infinite; }
.bf-layer.horse .co-art.sprite .sheet { animation-duration: .6s; }
/* The beaten side turns and runs; the winners march on. */
.bf.rout .co-art.sprite { --row: 0; }
.bf.rout.atk-wins .bf-layer.def .co-art.sprite { transform: none; }
.bf.rout.def-wins .bf-layer.atk .co-art.sprite { transform: scaleX(-1); }
.bf.rout.atk-wins .bf-layer.atk .co-art.sprite .sheet, .bf.rout.def-wins .bf-layer.def .co-art.sprite .sheet { animation-duration: .7s; }
/* Once the result is in, nothing moves: no frames painted for nothing. */
.bf.done .co-art.sprite .sheet { animation-play-state: paused; }
.fallen .corpse { width: 100%; }
.fallen:has(.corpse) { width: 4.2%; aspect-ratio: auto; }
.report-screen .messenger:has(.rider) { width: min(46vw, 360px); aspect-ratio: auto; }
@media (prefers-reduced-motion: reduce) { .sprite .sheet { animation: none !important; } }

/* ---------- the camera, the air, the brush and the seal ---------- */
/* The camera closes on the front as the hosts advance, shakes in the press, then follows the winners. */
.bf { transform-origin: var(--front, 45%) 66%; transition: transform 5s cubic-bezier(.3, .1, .2, 1); }
.bf.advance { transform: scale(1.03); }
.bf.melee { transform: scale(1.06); }
.bf.melee.shaking { animation: cam-shake .45s 2; }
.bf.rout.atk-wins { transform: scale(1.05) translateX(-2%); transition-duration: 3s; }
.bf.rout.def-wins { transform: scale(1.05) translateX(2%); transition-duration: 3s; }
@keyframes cam-shake { 0%, 100% { translate: 0 0; } 25% { translate: -.5% .3%; } 50% { translate: .4% -.3%; } 75% { translate: -.3% -.2%; } }
/* Evening sun through the dust. */
.bf-rays { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; pointer-events: none; mix-blend-mode: screen;
  opacity: .55; z-index: 1; }
.bf.melee .bf-rays { opacity: .5; transition: opacity 3s; }
/* A bank of dust rising where the lines meet, drifting with the wind. */
.bf-dustbank { position: absolute; left: calc(var(--front) - 30%); width: 60%; top: 38%; height: 42%; pointer-events: none;
  opacity: 0; transition: opacity 2.5s; overflow: hidden; z-index: 2; }
.bf-dustbank img { position: absolute; bottom: 0; width: 100%; height: 100%; object-fit: fill; opacity: .9; }
.bf-dustbank img + img { left: -100%; transform: scaleX(-1); }
.bf.advance .bf-dustbank { opacity: .45; }
.bf.melee .bf-dustbank { opacity: .95; }
.bf.advance .bf-dustbank img { animation: dust-drift 14s linear infinite; }
.bf.done .bf-dustbank { opacity: .35; }
.bf.done .bf-dustbank img { animation-play-state: paused; }
@keyframes dust-drift { from { translate: 0 0; } to { translate: 100% 0; } }

/* The signature stroke: a wet vermilion brush stroke behind its name, and speed lines. */
.skill-screen::before { content: ""; position: absolute; inset: -50%; pointer-events: none; opacity: .18;
  background: repeating-conic-gradient(from 0deg at 50% 50%, rgba(255, 230, 180, .9) 0 1.2deg, transparent 1.2deg 7deg); }
.stage[data-phase="skill"] .skill-screen::before { animation: speed-lines 1.6s linear both; }
@keyframes speed-lines { from { transform: rotate(0deg) scale(1.2); opacity: .32; } to { transform: rotate(10deg) scale(1); opacity: .12; } }
.skill-name { position: relative; text-shadow: 0 2px 0 #3a0a06, 0 0 14px rgba(0, 0, 0, .6); color: #fff2d2; }
.skill-name span { position: relative; z-index: 1; }
.skill-name::before { content: ""; position: absolute; left: -9%; right: -14%; top: -28%; bottom: -30%;
  background: url(/static/img/fx-brush.webp) center / 100% 100% no-repeat; z-index: 0; transform-origin: left center; }
.stage[data-phase="skill"] .skill-name::before { animation: brush-in .45s .15s cubic-bezier(.2, .8, .3, 1) both; }
@keyframes brush-in { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }

/* The verdict, pressed like a seal. */
.seal-title { border: 0; border-radius: 0; padding: .45em .8em .5em; color: #fbf0d8; letter-spacing: .08em;
  background: url(/static/img/fx-seal.webp) center / 100% 100% no-repeat; text-shadow: 0 1px 0 rgba(80, 10, 6, .6);
  filter: drop-shadow(0 6px 14px rgba(0, 0, 0, .55)); }
.seal-title.bad { background: url(/static/img/fx-seal.webp) center / 100% 100% no-repeat; filter: grayscale(1) brightness(.62) drop-shadow(0 6px 14px rgba(0, 0, 0, .55)); }
@media (prefers-reduced-motion: reduce) {
  .bf, .bf.advance, .bf.melee, .bf.rout.atk-wins, .bf.rout.def-wins { transform: none; transition: none; }
  .bf-dustbank img, .skill-screen::before { animation: none !important; }
}

/* The map as an old scroll: a double ink frame, a compass rose, a title cartouche. */
#map .map-frame { fill: none; stroke: #3a2614; stroke-width: 2.2; }
#map .map-frame.inner { stroke: #a0773a; stroke-width: .8; }
#map .map-corner { fill: #3a2614; }
#map .compass .ring { fill: rgba(240, 228, 198, .55); stroke: #3a2614; stroke-width: .8; }
#map .compass .needle { fill: #3a2614; }
#map .compass .needle.north { fill: #b3261e; }
#map .compass text { font: 700 7px var(--font-body); fill: #3a2614; text-anchor: middle; }
#map .cartouche rect { fill: rgba(243, 232, 205, .88); stroke: #3a2614; stroke-width: .9; }
#map .cartouche .seal { fill: #b3261e; stroke: none; }
#map .cartouche text { font: 700 9.5px var(--font-title); fill: #2a1b10; letter-spacing: .12em; }
#map .cartouche .seal-text { font: 700 7px var(--font-body); fill: #fbf0d8; letter-spacing: 0; text-anchor: middle; }

/* Mulberry paper under everything (tools/art/paint_scenes.py). */
:root { --paper-noise: url(/static/img/paper.webp); }

/* Realm seals: the realm's character, cut in white from a worn block of its colour. */
.chop {
  position: relative; isolation: isolate; display: inline-grid; place-items: center; flex: 0 0 auto;
  width: 44px; height: 44px; transform: rotate(4deg); color: #fff6e0;
  font: 600 27px/1 "Noto Serif TC", "Noto Serif SC", serif; text-shadow: 0 0 1px rgba(0, 0, 0, .3);
}
.chop::before {
  content: ""; position: absolute; inset: 0; z-index: -1; background: var(--c);
  -webkit-mask: url(/static/img/fx-seal.webp) center / 100% 100% no-repeat; mask: url(/static/img/fx-seal.webp) center / 100% 100% no-repeat;
  filter: drop-shadow(0 1px 1px rgba(0, 0, 0, .25));
}
.realm-title { align-items: center; }
.realm-title .chop { width: 40px; height: 40px; font-size: 24px; }
.choice::after { content: none; }
.choice .chop { position: absolute; right: 12px; top: 12px; width: 50px; height: 50px; font-size: 30px; transition: transform .2s; }
.choice:hover .chop { transform: rotate(-3deg) scale(1.08); }
/* The realm's character again, as a faint watermark in the paper. */
.choice::before {
  content: attr(data-han); position: absolute; right: -6px; bottom: -34px; z-index: 0; pointer-events: none;
  font: 600 128px/1 "Noto Serif TC", "Noto Serif SC", serif; color: var(--c); opacity: .07;
}
.choice > * { position: relative; }

/* The kingdom picker opens on an ink-wash landscape, bleeding to both edges of the window. */
body { overflow-x: clip; }
.setup .hero {
  position: relative; margin: -24px calc(50% - 50vw) 4px; height: clamp(210px, 29vw, 460px);
  background: url(/static/img/hero-setup.webp) 30% top / cover no-repeat;
  display: flex; flex-direction: column; align-items: center; padding-top: clamp(14px, 4.5%, 44px);
}
.hero-title {
  margin: 0; font: 700 clamp(30px, 6.4vw, 60px)/1.1 var(--font-title); letter-spacing: .08em;
  color: #2a1d14; text-shadow: 0 0 18px rgba(245, 236, 215, .9), 0 0 3px rgba(245, 236, 215, .9);
  animation: hero-in 1.2s ease-out both;
}
.hero-sub {
  margin: 4px 0 0; font-size: clamp(13px, 1.8vw, 17px); letter-spacing: .12em; color: #6b5440;
  text-shadow: 0 0 8px rgba(245, 236, 215, .95); animation: hero-in 1.2s .25s ease-out both;
}
.hero-seal {
  position: absolute; right: 6%; top: 50%; padding: 6px 7px; color: #fff3dc; background: #a3271c;
  font: 600 clamp(14px, 1.8vw, 19px)/1.15 "Noto Serif TC", "Noto Serif SC", serif; transform: rotate(3deg);
  -webkit-mask: url(/static/img/fx-seal.webp) center / 100% 100% no-repeat; mask: url(/static/img/fx-seal.webp) center / 100% 100% no-repeat;
  animation: stamp .5s 1s cubic-bezier(.3, 1.6, .5, 1) both;
}
@keyframes hero-in { from { opacity: 0; transform: translateY(8px); filter: blur(4px); } }
@keyframes stamp { from { opacity: 0; transform: rotate(3deg) scale(1.8); } }
@media (prefers-reduced-motion: reduce) { .hero-title, .hero-sub, .hero-seal { animation: none; } }
@media (prefers-color-scheme: dark) {
  .setup .hero { filter: brightness(.82) sepia(.2); }
}
@media (max-width: 640px) {
  .setup .hero { background-position: 18% top; padding-top: 18px; }
  .hero-title { font-size: 8.2vw; letter-spacing: .03em; }
  .hero-sub { font-size: 12px; letter-spacing: .06em; }
  .hero-seal { display: none; }
  .choice .chop { width: 42px; height: 42px; font-size: 25px; }
}

/* Massed companies: a block of squads in ranks (battle.js company()). */
.co.mass { aspect-ratio: var(--ar); }
.co-block { position: absolute; inset: 0; }
.squad { position: absolute; transform-origin: 50% 100%; }
.bf.melee .squad.lost { animation: squad-fall 1.6s calc(.8s + var(--i) * var(--fall-step, .45s)) ease-in forwards; }
.bf.rout .squad.lost, .bf.done .squad.lost { opacity: 0; }
@keyframes squad-fall { to { opacity: 0; transform: translateY(6%) scaleY(.6); } }
/* The scaled-down rout keeps the survivors where they stood instead of shrinking the block. */
.bf.rout .co.mass { transform: translate(-50%, -100%); }
/* Reserves massed towards the horizon, softened by haze; they stand still, mostly. */
.reserve { position: absolute; width: var(--w); transform: translate(-50%, -100%); opacity: .78;
  filter: saturate(.6) brightness(1.05) contrast(.85) blur(.3px); }
.reserve .sheet { animation: none !important; }
.bf-layer.def .reserve .co-art { transform: scaleX(-1); }
.bf-layer.reserves { will-change: auto; }
.bf.advance .bf-layer.reserves.atk { transform: translateX(6%); }
.bf.advance .bf-layer.reserves.def { transform: translateX(-6%); }
.bf.rout.atk-wins .bf-layer.reserves.def, .bf.rout.def-wins .bf-layer.reserves.atk { opacity: 0; }
/* A massed company's pennant keeps the size of a pennant, however wide the block. */
.co.mass .co-flag { width: clamp(16px, 2.1cqw, 30px); min-width: 0; left: 8%; bottom: 88%; }
.bf-layer.def .co.mass .co-flag { left: auto; right: 8%; }

/* Thế lực thiên hạ: the realm's land and soldiers shared out, under the map. */
.powers { margin-top: 10px; padding: 10px 14px 12px; background: var(--panel) var(--paper-noise); border: 1px solid var(--line);
  border-top: 3px solid var(--gold); border-radius: 6px; box-shadow: 0 6px 16px rgba(60, 35, 10, .1); }
.powers h3 { margin: 0 0 8px; font: 700 15px var(--font-title); letter-spacing: .06em; color: var(--accent); }
.power-row { display: grid; grid-template-columns: 38px 1fr; align-items: center; gap: 8px; margin: 5px 0; font-size: 13px; color: var(--muted); }
.power-bar { display: flex; height: 22px; border-radius: 3px; overflow: hidden; box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .15); }
.power-bar i { display: grid; place-items: center; min-width: 2px; background: var(--c); color: #fff6e0; font: 600 13px/1 "Noto Serif TC", serif; font-style: normal;
  background-image: linear-gradient(180deg, rgba(255, 255, 255, .18), transparent 55%, rgba(0, 0, 0, .12)); border-right: 1px solid rgba(255, 246, 224, .5);
  transition: flex 1.2s ease; }
.power-bar i:last-child { border-right: 0; }
.power-chops { display: flex; flex-wrap: wrap; gap: 8px 14px; margin-top: 10px; }
.power-chops span { display: grid; grid-template-columns: auto auto; grid-template-rows: auto auto; column-gap: 6px; align-items: center; }
.power-chops .chop { grid-row: span 2; width: 30px; height: 30px; font-size: 17px; }
.power-chops b { font-size: 13px; line-height: 1.1; }
.power-chops small { font-size: 11px; color: var(--muted); line-height: 1.1; }
.power-chops .me b { color: var(--accent); }

/* ---------- 3D-rendered scenery (static/img/scenery, tools/art/blender/scenery.py) ---------- */
/* Full-field overlays, cropped exactly like the backdrop under them. */
.bf-scene { position: absolute; inset: 0; pointer-events: none; }
.bf-scene i { position: absolute; inset: 0; background: var(--img) center / cover no-repeat; }
.bf-scene .tint { background: currentColor; mix-blend-mode: multiply; opacity: .9;
  -webkit-mask: var(--mask) center / cover no-repeat; mask: var(--mask) center / cover no-repeat; }
.bf.walled.rout.atk-wins .bf-scene.wall { filter: brightness(.72) saturate(.6); transition: filter 1.6s; }
/* On a tall phone field the backdrop shows only its middle: keep the wall and palace in sight. */
@container (max-aspect-ratio: 6 / 5) {
  .bf-scene.wall i, .bf-scene.palace i { background-size: auto 100%; background-position: 84% 50%;
    -webkit-mask-size: auto 100%; mask-size: auto 100%; -webkit-mask-position: 84% 50%; mask-position: 84% 50%; }
}

/* Waving banners: one row of frames, the cloth tinted with the realm's colour. */
.flag-art { position: absolute; inset: 0; overflow: hidden; }
.flag-art .sheet { animation: troop-frames 1.1s steps(var(--n)) var(--delay, 0s) infinite; }
.pennant .flag-art .sheet { animation-duration: .8s; }
.bf-layer.def .pennant .flag-art, .standard.def .flag-art { transform: scaleX(-1); }

.standard.rendered { top: 20%; height: 50%; aspect-ratio: var(--far); }
.standard.rendered.atk { left: 2.5%; }
.standard.rendered.def { right: 2.5%; }
.standard.rendered.def.walled { right: 1.5%; top: 14%; }
.standard.rendered span { left: calc(var(--x0) * 100% + 4%); top: calc(var(--y0) * 100% + 3%); width: calc((var(--x1) - var(--x0)) * 100% - 12%);
  height: calc((var(--y1) - var(--y0)) * 100% - 10%); background: none; box-shadow: none; clip-path: none; animation: none;
  font: 800 clamp(13px, 1.9vw, 26px)/1 var(--font-title); color: #fff6e0; text-shadow: 0 1px 2px rgba(0, 0, 0, .7), 0 0 6px rgba(0, 0, 0, .35); }
.standard.rendered.def span { left: calc((1 - var(--x1)) * 100% + 8%); right: auto; }
.standard.rendered small { left: 0; width: 100%; top: calc(var(--y1) * 100% + 1%); font-family: var(--font-brush); font-size: clamp(11px, 1.3vw, 17px); }

.co-flag.pennant { width: clamp(14px, 1.9cqw, 28px); aspect-ratio: var(--far); bottom: 78%; }
.co-flag.pennant span { left: calc(var(--x0) * 100%); top: calc(var(--y0) * 100%); width: calc((var(--x1) - var(--x0)) * 100%);
  height: calc((var(--y1) - var(--y0)) * 100%); display: grid; place-items: center; font: 700 clamp(7px, .75cqw, 11px)/1 var(--font-title); }
.bf-layer.def .co-flag.pennant span { left: calc((1 - var(--x1)) * 100%); }

/* Brush lettering for the flourishes. */
.skill-name, .hero-sub, .year-scroll small { font-family: var(--font-brush); font-weight: 700; letter-spacing: .01em; }

/* ---------- Siege: battered wall, siege works, the ram (static/img/scenery) ---------- */
/* The battered wall fades in over the whole one as the clash goes on, as far as the siege went. */
.bf-scene.damaged { opacity: 0; transition: opacity 7s ease-in; }
.bf.melee .bf-scene.damaged { opacity: var(--damage, 1); }
.bf-scene.siege { opacity: 0; transition: opacity 1.4s; }
.bf.advance .bf-scene.siege { opacity: 1; }
/* A crop laid over the field exactly as the full-field overlays are (cover, centred). */
.bf-frame { position: absolute; left: 50%; top: 50%; width: max(100cqw, 200cqh); aspect-ratio: 2 / 1; transform: translate(-50%, -50%); pointer-events: none; }
@container (max-aspect-ratio: 6 / 5) {
  .bf-frame.wall { width: 200cqh; left: calc((100cqw - 200cqh) * .84); transform: translateY(-50%); }
}
.bf-ram { position: absolute; overflow: hidden; opacity: 0; transform: translateX(-40%); transition: transform 2.6s cubic-bezier(.4, .1, .3, 1), opacity .8s; }
.bf.advance .bf-ram { opacity: 1; transform: none; }
.bf.melee .bf-ram .sheet { animation: troop-frames 1.1s steps(var(--n)) infinite; }
.bf.rout.def-wins .bf-ram { filter: brightness(.6); }

/* ---------- Dust and wind ---------- */
.puff { position: absolute; width: var(--w); aspect-ratio: 200 / 160; transform: translate(-50%, -70%); overflow: hidden; opacity: 0; pointer-events: none; transition: opacity 1s; }
.puff i, .kick i { position: absolute; left: 0; top: 0; width: 800%; height: 100%; background: url(/static/img/fx-puff.webp) 0 0 / 100% 100% no-repeat; }
.bf.melee .puff.clash { opacity: 1; }
.bf.melee .puff.clash i { animation: troop-frames 1.7s steps(8) var(--d) infinite; }
.bf.melee .puff.debris { opacity: .95; }
.bf.melee .puff.debris i { animation: troop-frames 1.25s steps(8) var(--d) infinite; }
.bf.done .puff { opacity: 0; }
/* Kicked up under each marching block, behind its men. */
.co .kick { position: absolute; left: var(--kx); bottom: -8%; width: 42%; aspect-ratio: 200 / 160; overflow: hidden; z-index: -1; opacity: 0; transition: opacity .8s; pointer-events: none; }
.bf.advance .co .kick { opacity: .85; }
.bf.melee .co .kick { opacity: .5; }
.bf.done .co .kick { opacity: 0; }
.bf.advance .co .kick i { animation: troop-frames .95s steps(8) var(--d) infinite; }
/* Wind: wisps of blown dust drifting across the field, harder in the thick of it. */
.bf-wind { position: absolute; inset: 0; overflow: hidden; pointer-events: none; }
.bf-wind i { position: absolute; left: -100%; width: 200%; background: url(/static/img/fx-wind.webp) 0 0 / 50% 100% repeat-x; opacity: .5;
  animation: wind-blow 12s linear infinite; }
.bf-wind .w1 { top: 46%; height: 16%; }
.bf-wind .w2 { top: 70%; height: 24%; animation-duration: 7.5s; opacity: .38; }
.bf.melee .bf-wind i { opacity: .75; }
@keyframes wind-blow { from { transform: translateX(0); } to { transform: translateX(50%); } }
@media (prefers-reduced-motion: reduce) { .bf-wind i, .puff i, .kick i { animation: none !important; } }

/* Company pennants are planted among the men, so they march and fight with their block. */
.co.mass .co-flag.pennant { left: 46%; bottom: 34%; }
.bf-layer.def .co.mass .co-flag.pennant { left: auto; right: 46%; }
/* The great standards now ride in the foot layer: they move with the host. */
.bf-push > .standard { z-index: 1; }

/* ---------- Weather (rec.weather, app/services/weather.py) ---------- */
.bf-place .bf-weather-name { display: block; margin-top: 4px; font: 700 clamp(11px, 1.2vw, 15px) var(--font-body); letter-spacing: .08em; color: #f3d27a; }
.bf-sky { position: absolute; inset: 0; pointer-events: none; opacity: 0; transition: opacity 2s; }
.bf-weather { position: absolute; inset: -10% -10% 0; pointer-events: none; overflow: hidden; }
.bf-weather i { position: absolute; inset: 0; }
/* Rain: a lowering grey sky, the sun gone, slanting streaks in three depths, the ground darkened. */
.bf.w-rain .bf-sky { opacity: 1; background: linear-gradient(180deg, rgba(40, 46, 58, .78), rgba(52, 58, 66, .55) 45%, rgba(30, 32, 36, .35)); }
.bf.w-rain .bf-rays, .bf.w-fog .bf-rays, .bf.w-snow .bf-rays { display: none; }
.bf.w-rain .bf-bg, .bf.w-rain .bf-scene { filter: saturate(.6) brightness(.78) hue-rotate(-8deg); }
.bf.w-rain .bf-weather i { background: repeating-linear-gradient(105deg, transparent 0 14px, rgba(210, 222, 236, .34) 14px 15px, transparent 15px 31px);
  background-size: 120px 120px; animation: rain-fall .5s linear infinite; }
.bf.w-rain .bf-weather i + i { background-size: 70px 70px; opacity: .6; animation-duration: .38s; }
.bf.w-rain .bf-weather i + i + i { background-size: 200px 200px; opacity: .45; animation-duration: .7s; filter: blur(1px); }
@keyframes rain-fall { from { background-position: 0 0; } to { background-position: -32px 120px; } }
.bf.w-rain .puff, .bf.w-rain .kick { filter: saturate(.3) brightness(.7); }
/* Snow: a pale sky, slow drifting flakes, a white cast over the ground. */
.bf.w-snow .bf-sky { opacity: 1; background: linear-gradient(180deg, rgba(196, 204, 214, .7), rgba(220, 224, 230, .35) 50%, rgba(240, 242, 246, .4)); }
.bf.w-snow .bf-bg, .bf.w-snow .bf-scene { filter: saturate(.45) brightness(1.08); }
.bf.w-snow .bf-weather i { background-image: radial-gradient(circle, rgba(255, 255, 255, .95) 0 1.6px, transparent 2.4px),
  radial-gradient(circle, rgba(255, 255, 255, .8) 0 1.1px, transparent 1.8px);
  background-size: 90px 90px, 53px 61px; background-position: 0 0, 27px 33px; animation: snow-fall 6s linear infinite; }
.bf.w-snow .bf-weather i + i { background-size: 140px 140px, 77px 83px; animation-duration: 9s; opacity: .7; }
.bf.w-snow .bf-weather i + i + i { background-size: 230px 230px, 120px 130px; animation-duration: 4s; filter: blur(1px); }
@keyframes snow-fall { from { background-position: 0 0, 27px 33px; } to { background-position: 40px 280px, 57px 313px; } }
/* Fog: a milky veil, thickest on the ground and in the distance; the far hosts all but lost. */
.bf.w-fog .bf-sky { opacity: 1; background: linear-gradient(180deg, rgba(228, 222, 210, .55), rgba(236, 230, 218, .75) 48%, rgba(226, 220, 206, .35) 75%, rgba(220, 214, 200, .2)); }
.bf.w-fog .bf-bg, .bf.w-fog .bf-scene { filter: saturate(.55) contrast(.8); }
.bf.w-fog .bf-layer.reserves { opacity: .35; }
.bf.w-fog .bf-weather i { background: url(/static/img/fx-wind.webp) 0 0 / 50% 100% repeat-x; left: -100%; width: 200%; top: 40%; height: 35%;
  opacity: .9; filter: brightness(1.6) saturate(.2) blur(3px); animation: wind-blow 40s linear infinite; }
.bf.w-fog .bf-weather i + i { top: 62%; height: 40%; animation-duration: 28s; opacity: .7; }
.bf.w-fog .bf-weather i + i + i { display: none; }
/* Wind: the wisps run hard and thick, from whichever side the wind is blowing. */
.bf.w-wind .bf-wind i { opacity: .85; animation-duration: 4.5s; }
.bf.w-wind .bf-wind .w2 { animation-duration: 3s; opacity: .7; }
.bf.w-wind.wind-east .bf-wind { transform: scaleX(-1); }
.bf.w-wind .bf-weather { display: none; }
/* Scorching sun: a hot, bleached light and a quivering haze over the ground. */
.bf.w-heat .bf-sky { opacity: 1; background: radial-gradient(ellipse at 76% 20%, rgba(255, 236, 190, .55), transparent 60%), linear-gradient(180deg, transparent 50%, rgba(255, 210, 140, .18)); mix-blend-mode: screen; }
.bf.w-heat .bf-bg { filter: saturate(1.15) brightness(1.08); }
.bf.w-heat .bf-rays { opacity: .9; }
.bf.w-heat .bf-weather { display: none; }
@media (prefers-reduced-motion: reduce) { .bf-weather i { animation: none !important; } }

/* The scouts' forecast on the muster screen. */
.mu-weather { margin: 0 0 8px; padding: 6px 10px; border-radius: 6px; background: rgba(255, 255, 255, .06); border-left: 3px solid #c9a24a; font-size: 13px; line-height: 1.45; color: #e8d8b4; }
.mu-weather b { display: block; color: #f3d27a; }
.mu-weather.w-rain, .mu-weather.w-snow, .mu-weather.w-fog { border-left-color: #8fa3b8; }
/* The weather lies over the troops too, so they stand in the same light as the field. */
.bf.w-rain .bf-weather { background: rgba(28, 34, 46, .2); }
.bf.w-snow .bf-weather { background: rgba(232, 236, 242, .12); }
.bf.w-fog .bf-weather { background: rgba(236, 230, 218, .2); }
.bf.w-snow .puff, .bf.w-snow .kick { filter: saturate(0) brightness(1.5); }

/* ---------- The real-3D battlefield (battle3d.js) ---------- */
.bf3d { position: absolute; inset: 0; width: 100%; height: 100%; display: block; touch-action: none; z-index: 5; cursor: grab; }
.bf3d:active { cursor: grabbing; }
/* Once the 3D field is up, the 2D pictures under it step aside; the place name stays. */
.bf.has-3d { transform: none !important; animation: none !important; }
.bf.has-3d > :not(.bf3d):not(.bf-place):not(.cam-hint) { visibility: hidden; }
.bf.has-3d .bf-place { z-index: 6; top: 17%; }
.cam-hint { position: absolute; left: 50%; bottom: 12px; transform: translateX(-50%); z-index: 7; display: flex; gap: 10px; align-items: center;
  padding: 5px 8px 5px 12px; border-radius: 999px; background: rgba(18, 12, 8, .62); color: #e8d6b0; font-size: 12px; white-space: nowrap; }
.cam-hint button { padding: 3px 10px; border-radius: 999px; border: 1px solid #c9a24a; background: transparent; color: #f3d27a; font: inherit; cursor: pointer; }
.bf:not(.has-3d) .cam-hint { display: none; }
.bf:not(.cam-free) .cam-hint .follow { opacity: .55; }
@media (max-width: 640px) { .cam-hint span { display: none; } }
/* The graphics level in the top bar. */
.topbar select.gfx { font: inherit; font-size: 13px; padding: 4px 6px; border-radius: 6px; background-color: transparent; color: #f3dfb0; border: 1px solid #6b4a2a; cursor: pointer; padding-right: 24px; }
.topbar select.gfx option { color: #2a1d14; background: #f3e6c8; }
@media (max-width: 640px) { .topbar select.gfx { font-size: 12px; max-width: 128px; } }
/* Graphics levels on the 2D field: the same men, lighter effects. */
.bf.gfx-low .bf-rays, .bf.gfx-low .co .kick, .bf.gfx-low .bf-wind .w2, .bf.gfx-low .bf-weather i + i + i, .bf.gfx-low .bf-dustbank img + img { display: none; }
.bf.gfx-low .puff.clash:nth-of-type(2n) { display: none; }
.bf.gfx-low .bf-weather i + i { opacity: .35; }
.bf.gfx-medium .bf-weather i + i + i, .bf.gfx-medium .puff.clash:nth-of-type(3n) { display: none; }
/* A broken host: the squads scatter, each its own way, at a run (the losing side's layers). */
.bf.rout.atk-wins .bf-layer.def, .bf.rout.def-wins .bf-layer.atk { transition: transform 1.8s cubic-bezier(.5, 0, .9, .6), opacity 1.8s ease-in .4s; }
.bf.rout.atk-wins .bf-layer.def .squad, .bf.rout.def-wins .bf-layer.atk .squad {
  transform: translate(var(--jx, 0), var(--jy, 0)) rotate(var(--jr, 0deg)); transition: transform 1.6s ease-out var(--jd, 0s); }
.bf.rout.def-wins .bf-layer.atk .squad { transform: translate(calc(var(--jx, 0) * -1), var(--jy, 0)) rotate(var(--jr, 0deg)); }
.bf.rout.atk-wins .bf-layer.def .co-art.sprite .sheet, .bf.rout.def-wins .bf-layer.atk .co-art.sprite .sheet { animation-duration: .42s; }

/* ---------- the map as a 3D model (board3d.js) ---------- */
.map3d { position: relative; width: 100%; aspect-ratio: 16 / 10; border-radius: 8px; overflow: hidden; background: #2b2119;
  border: 1px solid var(--line); box-shadow: 0 8px 22px rgba(60,35,10,.22); touch-action: none; user-select: none; }
.map3d-canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.map3d-labels { position: absolute; inset: 0; pointer-events: none; overflow: hidden; }
.map3d-labels span { position: absolute; left: 0; top: 0; white-space: nowrap; will-change: transform; color: #fff7e6;
  text-shadow: 0 1px 2px rgba(20,12,6,.9), 0 0 6px rgba(20,12,6,.6); }
.map3d-labels .realm { font-family: var(--font-title); letter-spacing: .3em; text-transform: uppercase; font-weight: 700;
  color: rgba(255,246,228,.92); }
.map3d-labels .capital { font-family: var(--font-body); font-size: 12px; font-weight: 700; padding: 1px 6px; border-radius: 3px;
  background: rgba(40,24,12,.55); }
.map3d-labels .army { font-size: 11px; font-weight: 700; padding: 0 5px 0 3px; border-radius: 3px; background: rgba(20,12,6,.6); color: #ffe7a8; }
.map3d-labels .army i { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 4px; box-shadow: 0 0 0 1px rgba(255,255,255,.5); }
.map3d-tip { position: absolute; left: 0; top: 0; pointer-events: none; padding: 3px 8px; border-radius: 4px; font-size: 12px;
  background: rgba(33,22,12,.88); color: #fbeacb; border: 1px solid rgba(243,210,122,.45); white-space: nowrap; }
.map3d-bar { position: absolute; top: 8px; right: 8px; display: flex; gap: 6px; }
.map3d-bar button { font: inherit; font-size: 12px; padding: 4px 9px; border-radius: 4px; cursor: pointer;
  background: rgba(33,22,12,.78); color: #fbeacb; border: 1px solid rgba(243,210,122,.4); }
.map3d-bar button:hover { background: rgba(70,44,20,.9); }
.map3d-hint { position: absolute; left: 8px; bottom: 8px; font-size: 11px; color: rgba(251,234,203,.8); pointer-events: none;
  background: rgba(33,22,12,.55); padding: 2px 7px; border-radius: 3px; }
.legend .map-mode { margin-left: auto; font-size: 12px; padding: 2px 10px; }
/* The flat map's way back to 3D on a phone (the key that holds it there is put away). */
.map3d-fab { display: none; font: inherit; font-size: 13px; padding: 5px 10px; border-radius: 6px; cursor: pointer; z-index: 6;
  background: rgba(33,22,12,.85); color: #fbeacb; border: 1px solid rgba(243,210,122,.5); box-shadow: 0 2px 6px rgba(0,0,0,.3); }
@media (max-width: 700px) {
  .map3d { aspect-ratio: 4 / 3.4; }
  .map3d-hint { display: none; }
}
#map[hidden], .map3d[hidden] { display: none !important; }

/* ---------- the battle in rounds: speed, the places of both hosts, the chronicle, the hồi dừng ---------- */
.battle .speeds { display: inline-flex; gap: 2px; margin-right: 8px; }
.battle .speed { padding: 3px 9px; font-size: 13px; }
.battle .speed[aria-pressed="true"] { background: #e2b45a; color: #120d09; border-color: #e2b45a; }
.bt-panel { position: absolute; right: 10px; top: 112px; width: min(330px, 36%); display: grid; gap: 6px; z-index: 60; pointer-events: auto; }
.bt-wings { display: grid; gap: 4px; padding: 6px 8px; border-radius: 8px; background: rgba(18,12,8,.72); color: #f2e4c6; font-size: 11px; }
.bt-host { display: grid; grid-template-columns: repeat(5, 1fr); gap: 3px; align-items: end; }
.bt-host > b { grid-column: 1 / -1; font: 700 12px var(--font-title); color: var(--c); filter: brightness(1.6); }
.bt-wing { display: grid; gap: 1px; }
.bt-wing.empty { opacity: .35; }
.bt-wing.out span::after { content: " ↻"; color: #f3d27a; }
.bt-wing span { color: #c9b08a; }
.bt-wing i { display: block; height: 4px; border-radius: 2px; background: rgba(255,255,255,.12); overflow: hidden; }
.bt-wing i em { display: block; height: 100%; width: 100%; transition: width var(--t, 1s) linear; }
.bt-wing .men em { background: var(--c, #c99a3a); filter: brightness(1.5); }
.bt-host.atk .bt-wing .men em, .bt-host.def .bt-wing .men em { background: currentColor; }
.bt-host .bt-wing { color: var(--c); }
.bt-wing .mor em { background: #e2b45a; }
.bt-wing small { color: #d9c7a4; font-size: 10px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bt-log { margin: 0; padding: 6px 8px 6px 22px; max-height: 26vh; max-height: 26dvh; overflow: auto; border-radius: 8px; background: rgba(18,12,8,.66); color: #eadbbd; font-size: 12px; line-height: 1.45; }
.bt-log b { color: #f3d27a; }
.stage .crisis-screen:not([hidden]) { opacity: 1; pointer-events: auto; }
.crisis-screen { position: absolute; inset: 0; display: grid; place-items: center; z-index: 80; background: rgba(10,6,3,.55); padding: 16px; }
.crisis-screen[hidden] { display: none; }
.cr-frame { width: min(860px, 100%); max-height: 100%; overflow: auto; padding: 16px 18px; border-radius: 10px; color: #f2e4c6;
  background: linear-gradient(180deg, #2c1a0e, #1d110a); border: 1px solid #7a5520; box-shadow: 0 20px 50px rgba(0,0,0,.6); display: grid; gap: 10px; }
.cr-frame h3 { margin: 0; font: 700 20px var(--font-title); color: #f3d27a; }
.cr-report { margin: 0; padding-left: 18px; font-size: 14px; color: #e8d6b2; }
.cr-court { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(240px, 100%), 1fr)); gap: 8px; }
.cr-counsel { display: flex; gap: 8px; padding: 8px; border-radius: 8px; background: #efe1bf; color: #2a1d12; }
.cr-counsel .portrait { width: 44px; flex: 0 0 44px; }
.cr-counsel b { font: 700 14px var(--font-title); }
.cr-counsel em { font-style: normal; font-size: 11px; color: #fff3d6; background: #6b3f1f; border-radius: 999px; padding: 0 7px; }
.cr-counsel q { display: block; font-style: italic; font-size: 13px; margin: 3px 0 5px; quotes: "«" "»"; }
.cr-adopt { padding: 3px 10px; font-size: 13px; }
.cr-options { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 6px; }
.cr-option { display: grid; gap: 2px; text-align: left; padding: 8px 10px; background: rgba(0,0,0,.3); color: #f2e4c6; border: 1px solid #7a5520; box-shadow: none; }
.cr-option:hover { border-color: #f3d27a; }
.cr-option b { font: 700 14px var(--font-title); }
.cr-option small { font-size: 12px; color: #c9b08a; }
.cr-option em { font-style: normal; font: 700 13px var(--font-title); color: #e2c98f; }
.cr-option em.good { color: #8fd09a; } .cr-option em.bad { color: #ff9c86; }
.cr-error { color: #ff9c86; margin: 0; }
.cr-error:empty { display: none; }
@media (max-width: 700px) {
  .bt-panel { position: static; width: auto; margin: 4px; }
  .battle .speeds { order: 9; }
}
/* The realms table is wider than a phone: it scrolls inside its panel, the page never does. */
@media (max-width: 700px) { table.nations { display: block; max-width: 100%; overflow-x: auto; } }

/* ---------- bảng quận: nội trị, quân sự, chiến sự of the province clicked on the map ---------- */
.province-info:has(.pp) { padding: 0; border: 0; background: none; }
.pp { border: 1px solid var(--line); border-top: 4px solid var(--c); border-radius: 8px; background: var(--panel); color: var(--ink); overflow: hidden; }
.pp-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 10px; padding: 8px 10px 4px; }
.pp-head > b { font: 700 19px var(--font-title); }
.pp-head > span { font-size: 13px; color: var(--muted); }
.pp-head em { font-style: normal; font-weight: 700; }
.pp-res, .pp-fort, .pp-people { font-style: normal; font-size: 12px; padding: 1px 8px; border-radius: 999px; border: 1px solid var(--line); }
.pp-res { background: rgba(120, 160, 60, .14); }
.pp-close { margin-left: auto; padding: 2px 8px; }
.pp-tabs { display: flex; gap: 2px; padding: 0 8px; border-bottom: 1px solid var(--line); }
.pp-tab { background: transparent; color: var(--muted); border: 0; border-bottom: 3px solid transparent; border-radius: 0; padding: 6px 10px; font: 700 14px var(--font-title); }
.pp-tab.on { color: var(--ink); border-bottom-color: var(--c); }
.pp-tab.hot { color: var(--bad); animation: pp-pulse 1.4s ease-in-out infinite; }
@keyframes pp-pulse { 50% { opacity: .55; } }
.pp-body { padding: 8px 10px 10px; display: grid; gap: 8px; }
.pp-body h4 { margin: 4px 0 0; font: 700 14px var(--font-title); }
.pp-body h4 small { font: 400 12px var(--font-body); color: var(--muted); margin-left: 6px; }
.pp-note { margin: 0; font-size: 13px; color: var(--muted); }
.pp-works { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; }
.pp-work { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; font-size: 14px; }
.pp-work .han, .pp-offer .han { font-family: "Noto Serif TC", "Noto Serif SC", serif; color: var(--accent); }
.pp-work .chip { margin-left: auto; }
.pp-offers { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(150px, 100%), 1fr)); gap: 6px; }
.pp-offer { display: grid; gap: 1px; text-align: left; padding: 6px 8px; background: var(--bg); color: var(--ink); border: 1px solid var(--line); border-radius: 6px; }
.pp-offer:hover:not(:disabled) { border-color: var(--c); }
.pp-offer:disabled { opacity: .5; cursor: not-allowed; }
.pp-offer b { font-size: 13.5px; }
.pp-offer small { font-size: 11.5px; color: var(--muted); }
.pp-units { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 2px 12px; font-size: 13px; }
.pp-units .sw { display: inline-block; width: 10px; height: 10px; border-radius: 2px; margin-right: 5px; }
.pp-units small { color: var(--muted); }
.pp-armies { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; font-size: 13.5px; }
.pp-armies li { border-left: 4px solid var(--c); padding-left: 6px; }
.pp-actions { display: flex; flex-wrap: wrap; gap: 6px; }
.chip.hot, .pp-battle.hot .chip { background: var(--bad); color: #fff; border-color: var(--bad); }
.pp-battle { border: 1px solid var(--line); border-radius: 6px; padding: 6px 8px; }
.pp-battle.hot { border-color: var(--bad); box-shadow: 0 0 0 2px rgba(155, 44, 31, .2); }
.pp-battle p { margin: 2px 0 6px; font-size: 13px; color: var(--muted); }
.pp-msg { margin: 0; padding: 0 10px 8px; color: var(--bad); font-size: 13px; }
.pp-msg:empty { display: none; }
/* Marks on the drawn map. */
#map .works-mark { font: 700 6.5px "Noto Serif TC", serif; fill: #3a2414; paint-order: stroke; stroke: rgba(240,228,200,.9); stroke-width: 1.6px; }
#map .war-mark circle { fill: #9b2c1f; stroke: #ffe7a8; stroke-width: 1; }
#map .war-mark text { font-size: 9px; text-anchor: middle; fill: #fff; }
#map .war-mark.hot { animation: war-pulse 1s ease-in-out infinite; }
@keyframes war-pulse { 50% { opacity: .4; } }
#map .trade-road { fill: none; stroke: #8a6a2a; stroke-width: 1.1; stroke-dasharray: 2 2.5; opacity: .7; }
#map .trade-road.mine { stroke: #c08a1a; stroke-width: 1.6; opacity: .9; }
#map .caravan circle { fill: #f3d27a; stroke: #5a3a14; stroke-width: .8; }
/* The same marks on the 3D board. */
.map3d-labels .works { font: 700 11px "Noto Serif TC", serif; color: #fff3d6; background: rgba(40, 24, 10, .55); padding: 0 4px; border-radius: 3px; }
.map3d-labels .battle { pointer-events: auto; cursor: pointer; font-size: 15px; width: 24px; height: 24px; display: grid; place-items: center;
  border-radius: 50%; background: #9b2c1f; color: #fff; box-shadow: 0 0 0 2px #ffe7a8, 0 2px 6px rgba(0,0,0,.5); }
.map3d-labels .battle.hot { animation: war-pulse 1s ease-in-out infinite; }
/* The battle over the map; ⛶ gives it the whole screen. */
.map-panel { position: relative; }
.battle.inmap { position: absolute; inset: 0 0 auto 0; height: max(100%, 78vh); height: max(100%, 78dvh); z-index: 30; border-radius: 10px; overflow: hidden; box-shadow: 0 12px 40px rgba(0,0,0,.5); }
.battle.inmap.wide { position: fixed; inset: 0; height: auto; border-radius: 0; z-index: 40; }
@media (max-width: 700px) { .battle.inmap { position: fixed; inset: 0; height: auto; border-radius: 0; } }
.regency { display: flex; gap: 6px; align-items: baseline; margin-top: 8px; font-weight: 700; font-size: 14px; cursor: pointer; }
.regency small { font-weight: 400; color: var(--muted); }
.regency input { accent-color: var(--accent); }

/* Thế cục: signs, good names, pacts. */
#statecraft h3 { font: 700 14px var(--font-title); margin: 8px 0 4px; }
.pacts { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; font-size: 13px; }
.pact { padding: 4px 8px; border-left: 3px solid var(--line); background: var(--bg); border-radius: 4px; }
.pact.mine { border-left-color: var(--gold); }
.pact.broken { border-left-color: var(--accent); }
.pact.kept { border-left-color: #5a8a3a; }
.pact small { display: block; color: var(--muted); font-size: 12px; }
.pact-kind { font-weight: 700; margin-right: 4px; }
.sc-nations { display: grid; gap: 4px; }
.sc-nation { border: 1px solid var(--line); border-left: 4px solid var(--c); border-radius: 6px; background: var(--panel); }
.sc-head { display: flex; align-items: center; gap: 8px; width: 100%; background: transparent; color: var(--ink); border: 0; padding: 6px 8px; text-align: left; }
.sc-head b { font: 700 15px var(--font-title); }
.sc-head .mood { font-size: 12px; padding: 1px 8px; border-radius: 999px; border: 1px solid var(--line); }
.sc-head .mood.bad { color: var(--accent); border-color: var(--accent); }
.sc-head .mood.warn { color: var(--gold); border-color: var(--gold); }
.sc-head .mood.good { color: #4c7d2e; border-color: #7aa65a; }
.sc-head .rep { margin-left: auto; font-size: 12px; color: var(--muted); }
.sc-body { padding: 0 10px 10px; display: grid; gap: 6px; }
.sc-body h4 { margin: 4px 0 0; font: 700 13.5px var(--font-title); }
.sc-body h4 small { font: 400 12px var(--font-body); color: var(--muted); margin-left: 6px; }
.sc-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 3px; font-size: 13px; }
.sc-list .sign i { font-style: normal; font-size: 11px; padding: 0 6px; border-radius: 999px; border: 1px solid var(--line); margin-right: 4px; }
.sc-list .sign.spy i { border-color: var(--gold); color: var(--gold); }
.sc-list .sign.rumor { color: var(--muted); }
.sc-list.mem .grudge::before { content: "✗ "; color: var(--accent); }
.sc-list.mem .favour::before { content: "✓ "; color: #5a8a3a; }
.sc-list.guard li::before { content: "🛡 "; }
.sc-actions { display: flex; flex-wrap: wrap; gap: 6px; }
.sc-form { display: grid; gap: 6px; padding: 8px; border: 1px dashed var(--line); border-radius: 6px; font-size: 13px; }
.sc-form h4 { margin: 0; }
.sc-form label { display: grid; gap: 2px; }
.sc-form select, .sc-form input { width: 100%; max-width: 100%; box-sizing: border-box; }
.sc-form-buttons { display: flex; gap: 6px; flex-wrap: wrap; }
.sc-world summary { cursor: pointer; font-size: 13px; color: var(--muted); margin-top: 6px; }
.guard-event .told { margin: 4px 0; font-size: 13.5px; }
.person .bonds { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 2px; }
.person .bonds i { font-style: normal; font-size: 11px; padding: 0 6px; border-radius: 999px; border: 1px solid var(--line); color: var(--muted); }
.person .bonds .tie.RIVAL, .person .bonds .tie.ENEMY { color: var(--accent); border-color: var(--accent); }
.person .bonds .tie.FRIEND { color: #4c7d2e; border-color: #7aa65a; }
.person .bonds .grief { color: #fff; background: var(--accent); border-color: var(--accent); }
.person .bonds .glory { color: var(--gold); border-color: var(--gold); }

/* A battle on the 3D board: the round, and each host's places as cards. */
.board-battle { position: absolute; inset: 0; pointer-events: none; display: flex; flex-direction: column; justify-content: space-between; z-index: 4; }
.board-battle .bb-top { pointer-events: auto; margin: 8px; padding: 6px 10px; background: rgba(31, 18, 11, .82); color: #f4e9d4; border: 1px solid #b8892e;
  border-radius: 8px; max-width: min(640px, calc(100% - 16px)); align-self: center; }
.board-battle .bb-top b { font: 700 16px var(--font-title); }
.board-battle .bb-phase { color: #e2b45a; font-weight: 700; }
.board-battle .bb-tools { float: right; display: inline-flex; gap: 4px; }
.board-battle .bb-tools button { padding: 1px 8px; font-size: 12px; }
.board-battle .bb-lines { margin: 4px 0 0; font-size: 13px; line-height: 1.35; }
.board-battle.done .bb-lines { color: #ffd98a; }
.board-battle .bb-cards { pointer-events: auto; display: grid; gap: 4px; margin: 8px; }
.bb-row { display: flex; align-items: stretch; gap: 4px; overflow-x: auto; }
.bb-side { flex: 0 0 auto; display: grid; align-content: center; padding: 2px 8px; border-radius: 6px; background: var(--c); color: #fff;
  font: 700 14px var(--font-title); text-shadow: 0 1px 2px rgba(0,0,0,.5); min-width: 76px; }
.bb-side small { font: 400 11px var(--font-body); opacity: .9; }
.bb-list { display: flex; gap: 4px; }
.bb-card { flex: 0 0 auto; width: 104px; display: grid; grid-template-columns: 26px 1fr; gap: 0 4px; padding: 3px 5px; border-radius: 6px;
  background: #f8f0de; color: #2a1d12; border: 1px solid var(--c); font-size: 11px; }
.bb-card i { grid-row: span 3; font: 600 20px "Noto Serif TC", serif; color: var(--c); font-style: normal; align-self: center; text-align: center; }
.bb-card b { font-size: 11.5px; }
.bb-card small { font-size: 10px; color: #6b5640; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bb-card .bb-men { font-weight: 700; }
.bb-card .bb-bar { grid-column: span 2; height: 4px; background: rgba(0,0,0,.15); border-radius: 2px; overflow: hidden; margin-top: 2px; }
.bb-card .bb-bar em { display: block; height: 100%; background: var(--c); }
.bb-card .bb-bar.morale em { background: #d9ab52; }
.bb-card.broken { background: #ddd3c1; color: #7a6a58; filter: grayscale(.7); }
.map3d.battling .map3d-hint { display: none; }
@media (max-width: 640px) {
  .bb-card { width: 92px; }
  .bb-side { min-width: 60px; }
}

/* =====================================================================
   The court as a game: HUD across the top, the dock of offices, one screen at a time.
   ===================================================================== */
.game { display: grid; grid-template-columns: 92px minmax(0, 1fr); grid-template-areas: "hud hud" "dock views";
  gap: 12px; padding: 10px 16px 16px; align-items: start; }
.glyph { font-family: "Noto Serif TC", "Noto Serif SC", serif; font-weight: 600; }
.glyph.big { font-size: 46px; color: var(--accent); opacity: .5; }

.hud { grid-area: hud; position: sticky; top: 0; z-index: 25; display: flex; align-items: center; gap: 10px;
  background: linear-gradient(#2b1a10, #1c100a); color: #f4e9d4; border: 1px solid #8a6326; border-radius: 12px;
  padding: 6px 8px 6px 10px; box-shadow: 0 6px 18px rgba(0,0,0,.25); }
.hud-main { flex: 1; min-width: 0; display: flex; align-items: center; gap: 12px; }
.hud-seal { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; }
.hud-seal .chop { width: 40px; height: 40px; font-size: 24px; }
.hud-seal b { display: block; font: 700 18px var(--font-title); color: #ffd98a; line-height: 1.1; }
.hud-seal small { font-size: 11.5px; color: #c9b38c; }
.hud-res { display: flex; gap: 4px; overflow-x: auto; scrollbar-width: none; min-width: 0; flex: 1; }
.hud-res::-webkit-scrollbar { display: none; }
.res { flex: 0 0 auto; display: grid; grid-template-columns: 26px auto; grid-template-rows: auto auto; column-gap: 5px; align-items: center;
  padding: 3px 9px 3px 4px; border-radius: 999px; background: rgba(255,255,255,.06); border: 1px solid rgba(226,180,90,.25); }
.res i { grid-row: span 2; width: 26px; height: 26px; display: grid; place-items: center; border-radius: 50%; background: #a3271c; color: #ffe9b8;
  font: 600 14px "Noto Serif TC", serif; font-style: normal; }
.res b { font-size: 14px; line-height: 1.1; }
.res small { font-size: 10px; color: #b89e74; line-height: 1; }
.res.low i { background: #5a1a12; animation: pp-pulse 1.4s ease-in-out infinite; }
.hud-regency { display: grid; justify-items: center; cursor: pointer; flex: 0 0 auto; padding: 0 4px; color: #c9b38c; }
.hud-regency input { position: absolute; opacity: 0; pointer-events: none; }
.hud-regency .glyph { width: 30px; height: 30px; display: grid; place-items: center; border-radius: 8px; border: 1px solid #6b5230; color: #8f7a58; }
.hud-regency input:checked + .glyph { background: #b8892e; color: #1c100a; border-color: #ffd98a; }
.hud-regency input:focus-visible + .glyph { outline: 2px solid #ffd98a; }
.hud-regency small { font-size: 10px; }
.gong { flex: 0 0 auto; display: grid; justify-items: center; gap: 0; padding: 4px 14px; border-radius: 10px;
  background: radial-gradient(circle at 50% 35%, #d9ab52, #8a5a1a); color: #1c100a; border: 1px solid #ffd98a; box-shadow: 0 0 0 2px #3a2412 inset; }
.gong-face { font: 700 22px "Noto Serif TC", serif; line-height: 1.1; }
.gong-label { font: 700 12.5px var(--font-title); white-space: nowrap; }
.gong:disabled { filter: grayscale(.7); opacity: .6; }
.gong.thinking .gong-face { animation: spin 2.4s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

.dock { grid-area: dock; position: sticky; top: 76px; display: flex; flex-direction: column; gap: 6px; }
.dock button { position: relative; display: grid; justify-items: center; gap: 0; width: 84px; padding: 8px 2px 6px; border-radius: 12px;
  background: var(--panel); color: var(--ink); border: 1px solid var(--line); box-shadow: none; }
.dock button .glyph { font-size: 26px; line-height: 1.1; color: var(--accent); }
.dock button .lbl { font: 700 12px var(--font-title); }
.dock button.on { background: linear-gradient(#a3271c, #7a1c14); color: #ffe9b8; border-color: #e2b45a; }
.dock button.on .glyph { color: #ffd98a; }
.dock button.hot:not(.on) { animation: pp-pulse 1.4s ease-in-out infinite; }
.badge-n { position: absolute; top: 3px; right: 5px; min-width: 18px; padding: 0 5px; border-radius: 999px; background: #d2553f; color: #fff;
  font: 700 11px/18px var(--font-body); font-style: normal; }
.views { grid-area: views; min-width: 0; }
.view[hidden] { display: none !important; }
.view { display: grid; gap: 12px; align-items: start; }
#view-hall { grid-template-columns: minmax(0, 1.55fr) minmax(300px, 1fr); }
#view-edict { grid-template-columns: minmax(0, 1.3fr) minmax(280px, 1fr); }
#view-map { grid-template-columns: minmax(0, 1.4fr) minmax(300px, 1fr); }
.map-side { position: sticky; top: 76px; max-height: calc(100vh - 90px); max-height: calc(100dvh - 90px); overflow-y: auto; }
.hall-side { display: grid; gap: 12px; }
.state-row, .realms-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; align-items: start; }
.realms-side { display: grid; gap: 12px; }
.table-scroll { overflow-x: auto; }
.card h2 .glyph { color: var(--accent); margin-right: 4px; }
.card h3 small, .card h3 small { font: 400 12px var(--font-body); color: var(--muted); margin-left: 6px; }
.empty-note { color: var(--muted); font-size: 13px; }

/* Triều đường: the throne hall. */
.hall { display: grid; gap: 10px; }
.hall-scene { position: relative; display: grid; grid-template-columns: 1fr minmax(150px, .8fr) 1fr; gap: 10px; padding: 18px 16px 34px;
  border-radius: 14px; overflow: hidden; color: #f4e9d4; min-height: 430px; border: 1px solid #8a6326;
  background:
    repeating-linear-gradient(90deg, transparent 0 12%, rgba(163,39,28,.55) 12% 13.4%, transparent 13.4% 25%),
    radial-gradient(ellipse at 50% 18%, rgba(255,215,130,.28), transparent 55%),
    linear-gradient(#1e110a 0, #3b2013 58%, #6a4527 58.4%, #3a2415 100%); }
/* The realm's own hall, painted, darkened under the court so the ministers' names read. */
.hall-scene.painted { background: linear-gradient(rgba(16,9,5,.55), rgba(16,9,5,.25) 30%, rgba(16,9,5,.55) 70%, rgba(16,9,5,.85)), var(--hall) center 30% / cover no-repeat, #1e110a; }
.hall-scene.painted .hall-banner { display: none; }
.hall-scene::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 42%; pointer-events: none;
  background: repeating-linear-gradient(90deg, rgba(0,0,0,.12) 0 2px, transparent 2px 70px), linear-gradient(rgba(0,0,0,0), rgba(0,0,0,.35)); }
.hall-banner { position: absolute; top: 0; width: 46px; height: 150px; display: grid; place-items: center; padding-top: 30px; z-index: 0;
  background: var(--c); color: #ffe9b8; font: 700 26px "Noto Serif TC", serif; clip-path: polygon(0 0, 100% 0, 100% 86%, 50% 100%, 0 86%);
  box-shadow: inset 0 0 0 3px rgba(226,180,90,.6); opacity: .92; }
.hall-banner.left { left: calc(50% - 118px); } .hall-banner.right { right: calc(50% - 118px); }
.throne { position: relative; z-index: 1; grid-column: 2; grid-row: 1; display: grid; justify-items: center; align-content: start; text-align: center; padding-top: 70px; }
.throne-seat { padding: 10px 14px 18px; border-radius: 12px 12px 4px 4px; background: linear-gradient(#d9ab52, #8a5a1a); box-shadow: 0 0 40px rgba(255,200,90,.45), inset 0 0 0 2px #ffe3a0; }
.throne-seat .portrait { width: 92px; flex: none; }
.throne b { margin-top: 8px; font: 700 16px var(--font-title); color: #ffd98a; }
.throne small { color: #c9b38c; font-size: 12px; }
.rank { position: relative; z-index: 1; display: grid; align-content: start; gap: 6px; }
.rank.civil { grid-column: 1; } .rank.martial { grid-column: 3; }
.rank h3 { margin: 0; font: 700 14px var(--font-title); color: #e2b45a; text-align: center; }
.rank h3 span { font-family: "Noto Serif TC", serif; font-size: 18px; color: #ffd98a; }
.rank-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(70px, 1fr)); gap: 6px; }
.minister { position: relative; display: grid; justify-items: center; gap: 2px; padding: 5px 3px 4px; border-radius: 10px; background: rgba(0,0,0,.28);
  border: 1px solid rgba(226,180,90,.3); color: #f4e9d4; box-shadow: none; transition: transform .15s, border-color .15s; }
.minister:hover { transform: translateY(-3px); border-color: #ffd98a; }
.minister.asking { border-color: #ffd98a; box-shadow: 0 0 0 2px #ffd98a, 0 0 18px rgba(255,215,130,.5); }
.minister .portrait { width: 54px; flex: none; box-shadow: 0 0 0 1.5px #e2b45a; }
.minister .mn { font-size: 11.5px; line-height: 1.15; text-align: center; }
.minister.wavering .portrait { box-shadow: 0 0 0 2px #d2553f; }
.minister .warn { position: absolute; top: 2px; right: 4px; width: 18px; height: 18px; border-radius: 50%; background: #d2553f; color: #fff;
  font: 700 12px/18px var(--font-body); font-style: normal; animation: pp-pulse 1.4s ease-in-out infinite; }
.rank .empty { color: #c9b38c; font-size: 12px; text-align: center; }
.hall-hint { position: absolute; left: 0; right: 0; bottom: 8px; margin: 0; text-align: center; font-size: 12px; color: #c9b38c; z-index: 1; }
.hall-stations { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 8px; }
.station { display: grid; grid-template-columns: 40px 1fr; grid-template-rows: auto auto; column-gap: 8px; align-items: center; text-align: left;
  padding: 8px 10px; border-radius: 10px; background: var(--panel); color: var(--ink); border: 1px solid var(--line); box-shadow: none; }
.station .glyph { grid-row: span 2; width: 40px; height: 40px; display: grid; place-items: center; border-radius: 10px; background: #a3271c; color: #ffe9b8; font-size: 22px; }
.station b { font: 700 14px var(--font-title); }
.station small { font-size: 11.5px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.station:hover { border-color: var(--accent); }
.station.hot .glyph { animation: pp-pulse 1.4s ease-in-out infinite; }
.council .consult-log { max-height: 260px; }
.ask-chips { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 6px; }
.turn-result[hidden] { display: none; }

/* Quốc sự: tiles, one-touch orders, provinces, the armoury, the armies. */
.tiles { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; margin-bottom: 8px; }
.tile { display: grid; justify-items: center; padding: 6px 4px; border-radius: 10px; background: var(--bg); border: 1px solid var(--line); }
.tile i { font: 600 18px "Noto Serif TC", serif; font-style: normal; color: var(--accent); }
.tile b { font-size: 16px; }
.tile small { font-size: 11px; color: var(--muted); }
.acts { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(130px, 100%), 1fr)); gap: 6px; margin-bottom: 8px; }
.act, .arm { display: grid; grid-template-columns: 32px 1fr; grid-template-rows: auto auto; column-gap: 6px; align-items: center; text-align: left;
  padding: 6px 8px; border-radius: 10px; background: var(--panel); color: var(--ink); border: 1px solid var(--line); box-shadow: none; }
.act .glyph, .arm .glyph { grid-row: span 2; width: 32px; height: 32px; display: grid; place-items: center; border-radius: 8px; background: var(--bg);
  border: 1px solid var(--line); color: var(--accent); font-size: 18px; }
.act b, .arm b { font-size: 13px; line-height: 1.15; }
.act small, .arm small { font-size: 10.5px; color: var(--muted); line-height: 1.2; }
.act:hover:not(:disabled), .arm:hover:not(:disabled) { border-color: var(--accent); }
.act.big { grid-column: 1 / -1; background: linear-gradient(#a3271c, #7a1c14); color: #ffe9b8; border-color: #e2b45a; }
.act.big .glyph { background: #ffd98a; color: #7a1c14; }
.act.big small { color: #f0d6a0; }
.arm.have { opacity: .7; border-color: #7aa65a; }
.arm.have .glyph { background: #7aa65a; color: #fff; }
.arms { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(140px, 100%), 1fr)); gap: 6px; margin-bottom: 8px; }
#economy h3, #army-actions h3 { font: 700 14px var(--font-title); margin: 10px 0 6px; }
.prov-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(130px, 100%), 1fr)); gap: 6px; }
.prov { display: grid; gap: 1px; text-align: left; padding: 6px 8px; border-radius: 8px; background: var(--bg); color: var(--ink); border: 1px solid var(--line); box-shadow: none; }
.prov.capital { border-color: var(--gold); }
.prov b { font-size: 13px; }
.prov small { font-size: 11px; color: var(--muted); }
.prov .wks { display: flex; gap: 3px; flex-wrap: wrap; min-height: 20px; }
.prov .wk { font: 600 14px "Noto Serif TC", serif; font-style: normal; color: var(--accent); }
.prov .wk sub { font-size: 9px; color: var(--muted); }
.prov .none { font-size: 11px; color: var(--muted); font-style: italic; }
.prov:hover { border-color: var(--accent); }
.chips-line { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 8px; }
.pill { font-size: 12px; padding: 1px 9px; border-radius: 999px; border: 1px solid var(--line); }
.pill.road { color: var(--gold); border-color: var(--gold); }
.pill.bad { color: var(--accent); border-color: var(--accent); }
.pill.good { color: #4c7d2e; border-color: #7aa65a; }
.army-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(220px, 100%), 1fr)); gap: 8px; }
.army-grid .army { display: grid; gap: 4px; padding: 8px 10px; border-radius: 10px; background: var(--bg); border: 1px solid var(--line); border-left: 4px solid var(--c); }
.army-head { display: flex; align-items: center; gap: 6px; }
.army-head .flag { color: var(--c); font-size: 18px; }
.army-head b { font: 700 14px var(--font-title); }
.army-head .men { margin-left: auto; font-weight: 700; }
.army-grid .units { display: flex; flex-wrap: wrap; gap: 4px; }
.army-grid .u { font-size: 12px; padding: 0 6px; border-radius: 999px; border: 1px solid var(--line); }
.army-grid .u i { font: 600 12px "Noto Serif TC", serif; font-style: normal; color: var(--accent); margin-right: 2px; }
.army-grid .march { justify-self: start; }

/* Tướng sĩ: a card for each great man. */
.person-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(250px, 100%), 1fr)); gap: 8px; }
.person-grid .person { display: grid; grid-template-columns: 58px 1fr; gap: 8px; align-items: start; padding: 8px; border-radius: 10px;
  background: var(--bg); border: 1px solid var(--line); border-top: 3px solid var(--c); margin: 0; }
.person-grid .person.child { margin-left: 0; }
.person-grid .person .portrait { width: 58px; flex: none; box-shadow: 0 0 0 1.5px var(--gold); }
.pinfo { display: grid; gap: 2px; min-width: 0; }
.pname { font: 700 15px var(--font-title); }
.ptitle { font-size: 11.5px; color: var(--muted); }
.sbars { display: grid; gap: 2px; margin: 2px 0; }
.sbar { display: grid; grid-template-columns: 34px 1fr 24px; align-items: center; gap: 4px; font-size: 11px; }
.sbar small { color: var(--muted); }
.sbar em { display: block; height: 5px; border-radius: 3px; background: var(--c); max-width: 100%; }
.sbar b { text-align: right; }
.person-grid .bonds { display: flex; flex-wrap: wrap; gap: 3px; }
.person-grid .bonds i { font-style: normal; font-size: 10.5px; padding: 0 6px; border-radius: 999px; border: 1px solid var(--line); color: var(--muted); }
.person-grid .bonds .trait { color: var(--ink); }
.person-grid .loyal { font-size: 11px; padding: 0 6px; border-radius: 999px; background: #4c7d2e; color: #fff; }
.person-grid .loyal.low { background: var(--accent); }
.person-grid .person.low-loyalty { border-color: var(--accent); }
.province-info { margin-top: 0; }
.pp-empty { display: grid; justify-items: center; padding: 30px 10px; color: var(--muted); }
.pp-cols { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0; }
.pp-cols > .pp-body + .pp-body { border-left: 1px solid var(--line); }
.pp-col-title { margin: 0 !important; color: var(--accent); }
.pp-war { padding: 8px 10px; border-bottom: 1px solid var(--line); background: rgba(163,39,28,.06); }
.pp-war h4 { margin: 0 0 6px; font: 700 14px var(--font-title); color: var(--accent); }
.map-side .pp-cols { grid-template-columns: 1fr; }
.map-side .pp-cols > .pp-body + .pp-body { border-left: 0; border-top: 1px solid var(--line); }
@media (min-width: 1280px) { .map-side .pp-cols { grid-template-columns: repeat(2, minmax(0, 1fr)); } .map-side .pp-cols > .pp-body + .pp-body { border-left: 1px solid var(--line); border-top: 0; } }

@media (max-width: 1100px) {
  #view-hall, #view-edict, #view-map { grid-template-columns: 1fr; }
  .map-side { position: static; max-height: none; }
  .map-side .pp-cols { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .map-side .pp-cols > .pp-body + .pp-body { border-left: 1px solid var(--line); border-top: 0; }
}
@media (max-width: 900px) {
  .game { grid-template-columns: 1fr; grid-template-areas: "hud" "views"; padding: 8px 8px 92px; }
  .dock { position: fixed; left: 0; right: 0; bottom: 0; top: auto; z-index: 30; flex-direction: row; gap: 2px; padding: 4px 4px calc(4px + env(safe-area-inset-bottom));
    background: #1c100a; border-top: 1px solid #8a6326; overflow-x: auto; }
  .dock button { flex: 1 0 64px; width: auto; padding: 5px 2px; background: transparent; color: #e8d6b2; border-color: transparent; }
  .dock button .glyph { font-size: 21px; color: #e2b45a; }
  .dock button .lbl { font-size: 10.5px; }
  .hud-seal span { display: none; }
  .res { grid-template-columns: 22px auto; padding: 2px 7px 2px 3px; }
  .res i { width: 22px; height: 22px; font-size: 12px; }
  .res small { display: none; }
  .state-row, .realms-row { grid-template-columns: 1fr; }
  .hall-scene { grid-template-columns: 1fr 1fr; padding: 12px 10px 30px; min-height: 0; }
  .throne { grid-column: 1 / -1; grid-row: 1; padding-top: 30px; }
  .rank.civil { grid-column: 1; grid-row: 2; } .rank.martial { grid-column: 2; grid-row: 2; }
  .hall-banner.left { left: calc(50% - 112px); } .hall-banner.right { right: calc(50% - 112px); }
  .rank-list { grid-template-columns: repeat(auto-fill, minmax(62px, 1fr)); }
  .minister .portrait { width: 46px; }
  .tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 560px) {
  .pp-cols, .map-side .pp-cols { grid-template-columns: 1fr; }
  .pp-cols > .pp-body + .pp-body, .map-side .pp-cols > .pp-body + .pp-body { border-left: 0; border-top: 1px solid var(--line); }
  .gong { padding: 4px 8px; }
}

/* Everything in Vietnamese: the old Chinese names of arrays, stratagems and works are not shown,
   and the realms' seals carry their Vietnamese names. */
.han { display: none !important; }
.choice::before { content: none !important; }
.chop { font: 700 12px/1 var(--font-title) !important; letter-spacing: 0; text-align: center; padding: 2px; }
.choice .chop, .hud-seal .chop, .realm-title .chop { font-size: 13px !important; }
.power-chops .chop { font-size: 9px !important; }
.hall-banner { writing-mode: vertical-rl; font: 700 20px var(--font-title) !important; letter-spacing: .1em; padding-top: 18px; }
.glyph, .res i, .tile i, .gong-face { font-family: "Noto Color Emoji", "Apple Color Emoji", "Segoe UI Emoji", var(--font-body) !important; font-weight: 400; }
.res i { background: rgba(163,39,28,.85); font-size: 14px; }
.hero-seal { font-family: var(--font-title) !important; font-size: 22px !important; line-height: 1.1 !important; }
/* Grid children may shrink below their content on a phone (long names wrap instead). */
.views, .view > *, .hall, .hall-main > *, .hall-scene > *, .rank, .rank-list, .hall-stations, .state-row > *, .realms-row > *, .hall-side > * { min-width: 0; }
.rank-list { grid-template-columns: repeat(auto-fill, minmax(min(62px, 100%), 1fr)); }
.minister .mn { overflow-wrap: anywhere; }
@media (max-width: 900px) {
  .hall-stations { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .hud { padding: 4px 6px; gap: 6px; }
  .hud-regency small { display: none; }
}
.hud, .dock { min-width: 0; }
@media (max-width: 900px) { .game { grid-template-columns: minmax(0, 1fr); } }
.realms-side > *, .powers, .power-row, .power-bar { min-width: 0; }
.power-chops { flex-wrap: wrap; }
@media (max-width: 900px) {
  .tiles { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 4px; }
  .tile { padding: 4px 2px; }
  .tile b { font-size: 13px; }
  .tile small { font-size: 10px; }
}
.pp-cols > .pp-body { align-content: start; }
/* Small portraits in the hall and the court roll: the realm is already plain, the face matters more. */
.minister .portrait .seal-mark, .person-grid .portrait .seal-mark, .mu-person .portrait .seal-mark, .mu-counsel .portrait .seal-mark { display: none; }

/* ---------- the guard's report: a card per realm, a line per matter ---------- */
#guard-events { display: grid; gap: 12px; }
.gr-head { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; font-size: 13.5px; color: var(--muted); }
.gr-head > span:first-child { margin-right: auto; font-weight: 600; color: var(--ink); }
.gr-chip { padding: 2px 8px; border-radius: 999px; border: 1px solid var(--line); background: var(--panel); white-space: nowrap; }
.gr-realm { border: 1px solid var(--line); border-left: 4px solid var(--c, var(--muted)); border-radius: 8px; padding: 10px 12px; display: grid; gap: 8px; background: var(--panel); min-width: 0; }
.gr-realm.war { border-left-color: var(--accent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 25%, transparent); }
.gr-realm.home { --c: var(--good); }
.gr-realm header { display: flex; align-items: center; gap: 10px; }
.gr-realm header b { display: block; font-family: var(--font-title); font-size: 16px; }
.gr-realm header small { color: var(--muted); font-size: 12.5px; }
.gr-seal { flex: none; width: 38px; height: 38px; border-radius: 6px; display: grid; place-items: center; background: var(--c, var(--muted)); color: #fff7e6;
  font: 700 11px/1 var(--font-title); text-align: center; box-shadow: 0 0 0 2px #e2b45a; }
.gr-realm.home .gr-seal { font-size: 18px; background: color-mix(in srgb, var(--good) 20%, var(--panel)); }
.gr-power { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 8px; font-size: 12.5px; font-variant-numeric: tabular-nums; }
.gr-side { font-weight: 600; white-space: nowrap; }
.gr-bar { display: flex; height: 8px; border-radius: 4px; overflow: hidden; background: var(--line); }
.gr-bar i { display: block; height: 100%; background: var(--c); }
.gr-bar i + i { opacity: .55; }
.gr-facts { font-size: 12.5px; color: var(--muted); }
.gr-facts span { opacity: .7; }
.gr-lines { list-style: none; margin: 0; padding: 0; display: grid; gap: 0; }
.gr-line { display: grid; gap: 4px; padding: 8px 0; border-top: 1px dashed var(--line); min-width: 0; }
.gr-line:first-child { border-top: 0; padding-top: 2px; }
.gr-what { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 8px; }
.gr-what small { color: var(--muted); font-size: 12.5px; }
.gr-ico { width: 1.4em; text-align: center; }
.gr-line .told { margin: 0; font-size: 13px; color: var(--ink); opacity: .85; }
.gr-notes { margin: 0; padding-left: 18px; font-size: 12.5px; color: var(--muted); }
.gr-rec { margin: 0; font-size: 12.5px; font-style: italic; color: var(--muted); }
.gr-acts { display: flex; flex-wrap: wrap; gap: 6px; }
.gr-acts button { padding: 4px 10px; font-size: 13px; }
.gr-acts button.ghost { background: transparent; color: var(--ink); border: 1px solid var(--line); }
.hall-main { display: grid; gap: 12px; align-content: start; }
.gr-grid { columns: 2 300px; column-gap: 12px; }
.gr-grid > .gr-realm { break-inside: avoid; margin-bottom: 12px; }
.hall-alert { position: absolute; left: 50%; bottom: 10px; transform: translateX(-50%); z-index: 2; white-space: nowrap; max-width: calc(100% - 24px);
  overflow: hidden; text-overflow: ellipsis; padding: 6px 14px; border-radius: 999px; font-size: 13px; background: #3a2414; color: #f3dfb0;
  border: 1px solid #e2b45a; box-shadow: 0 4px 14px rgba(0, 0, 0, .45); }
.hall-alert.war { background: var(--accent); color: #fff4dc; animation: hall-alert 1.6s ease-in-out infinite; }
@keyframes hall-alert { 50% { box-shadow: 0 0 0 4px rgba(226, 180, 90, .35), 0 4px 14px rgba(0, 0, 0, .45); } }
@media (prefers-reduced-motion: reduce) { .hall-alert.war { animation: none; } }

/* While a battle is played on the board, its own bar stands in for the map's buttons. */
.map3d-bar:has(~ .board-battle) { display: none; }
/* A battle watched over the map takes the whole width: the province panel waits beside it. */
#view-map:has(#battle:not([hidden])) { grid-template-columns: minmax(0, 1fr); }
#view-map:has(#battle:not([hidden])) .map-side { display: none; }
/* The place's name sits under the two commanders' cards, not behind them. */
.bf.has-3d .bf-place { top: max(21%, 104px); }

/* ---------- polish after the screenshot review ---------- */
/* One sheet of mulberry paper over the whole window: the repeated tile left a seam. */
body { background-size: cover, auto; background-attachment: fixed, scroll; }

@media (max-width: 700px) {
  /* The top bar in two short rows: the title with the tabs, then the small controls. */
  .topbar { flex-wrap: wrap; gap: 4px 6px; padding: 6px 10px; }
  .topbar h1 { font-size: 15px; white-space: nowrap; flex: 1 0 auto; }
  .topbar .tabs { display: flex; gap: 4px; }
  .topbar .tab, .topbar button.ghost, .topbar select.gfx { padding: 2px 8px; font-size: 12px; white-space: nowrap; }
  .topbar .sound-toggles { display: flex; gap: 4px; }
  .topbar .sound-toggles .lbl { display: none; }
  /* All seven rooms in the dock at once, none cut off. */
  .dock { overflow-x: visible; gap: 0; }
  .dock button { flex: 1 1 0; min-width: 0; padding: 5px 0 4px; }
  .dock button .glyph { font-size: 19px; }
  .dock button .lbl { font-size: 9px; letter-spacing: -.01em; line-height: 1.05; white-space: normal; text-align: center; max-width: 100%; }
  /* The resources scroll sideways, fading out at the edge so the cut reads as "more". */
  .hud-res { overflow-x: auto; scrollbar-width: none; -webkit-mask-image: linear-gradient(90deg, #000 82%, transparent); mask-image: linear-gradient(90deg, #000 82%, transparent); }
}
/* Numbers and short words that should not break over two lines. */
table.nations td:nth-child(2), table.nations td:nth-child(3), table.nations td:nth-child(5), table.nations th, .res b { white-space: nowrap; }
/* Labels of the court cards' bars and the map's place names, easier to read. */
.sbar small { color: var(--ink); opacity: 1; font-weight: 700; font-size: 11px; }

/* The page's ground reaches the bottom of the window even when the page is short. */
html, body { min-height: 100%; }
body { min-height: 100vh; min-height: 100dvh; }
/* The 2D map's place names, readable. */
#map text { font-size: 11px; stroke-width: 2.6px; }
#map text.cap { font-size: 14px; }
/* The seven realms as stacked cards on a phone, nothing cut off. */
@media (max-width: 700px) {
  table.nations, table.nations tbody { display: block; overflow: visible; }
  table.nations thead { display: none; }
  table.nations tr { display: grid; grid-template-columns: 1fr auto auto; gap: 2px 10px; padding: 8px 0; border-bottom: 1px solid var(--line); }
  table.nations td { border: 0; padding: 0; white-space: normal !important; }
  table.nations td:nth-child(1) { grid-column: 1 / -1; }
  table.nations td:nth-child(4) { grid-column: 1 / -1; font-size: 13px; color: var(--muted); }
  table.nations td:nth-child(4)::before { content: "Danh tướng: "; }
  table.nations td:nth-child(2)::after { content: " quận"; }
}
/* The battle watched over the map fits the window (its caption stays on screen). */
.battle.inmap { height: max(420px, min(max(100%, 78vh), calc(100vh - 170px))); height: max(420px, min(max(100%, 78dvh), calc(100dvh - 170px))); }
/* A battle on the board takes the map's whole width; the army chips give way to it. */
#view-map:has(.board-battle) { grid-template-columns: minmax(0, 1fr); }
#view-map:has(.board-battle) .map-side { display: none; }
.map3d-labels:has(~ .board-battle) .army, .board-battle ~ .map3d-labels .army { display: none; }
.board-battle .bb-top b { margin-right: 10px; }
.board-battle .bb-tools { margin-left: 8px; }
/* Unit cards slimmer, so the fight shows above them. */
.board-battle .bb-cards { gap: 3px; margin: 6px; }
.bb-card { width: 92px; padding: 2px 4px; font-size: 10.5px; }
.bb-card i { font-size: 16px; }
/* ---------- round three of the review ---------- */
/* The 3D map (and a battle on it, with its cards) never runs past the window. */
.map3d { max-height: calc(100vh - 170px); max-height: calc(100dvh - 170px); }
.bb-card b { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* While the close-up battle is open over the map, the map under it is not shown. */
.map-panel:has(> #battle:not([hidden])) > :not(#battle) { visibility: hidden; }
/* The province panel: the ✕ in its corner, not on a row of its own. */
.pp-head { position: relative; padding-right: 40px; }
.pp-head .pp-close { position: absolute; top: 6px; right: 6px; }
@media (max-width: 700px) {
  /* Every work's upgrade button on its own line under its name, all alike. */
  .pp-work .chip { flex-basis: 100%; justify-content: center; }
  /* Asking the court: whom to ask above, the question below, each full width. */
  .consult-form select { max-width: none; flex: 1 1 100%; }
  .consult-form input { flex: 1 1 0; min-width: 0; }
  /* All the realm's figures in view: the pills wrap onto a second row. */
  .hud-res { flex-wrap: wrap; overflow: visible; -webkit-mask-image: none; mask-image: none; row-gap: 4px; }
  #map text { font-size: 16px; stroke-width: 3px; }
  #map text.cap { font-size: 19px; }
}
/* ---------- round four ---------- */
/* Town, range and river names on the 2D map, readable at a glance (a light halo behind them). */
#map .terrain-name, #map .river-name { font-size: 8.5px; stroke-width: 2.6px; }
#map .capital-name { font-size: 8.5px; stroke-width: 2.8px; }
@media (max-width: 700px) {
  #map .terrain-name, #map .river-name { font-size: 12px; }
  #map .capital-name { font-size: 13px; }
}
/* Room under the 3D map for its legend and the 2D button. */
.map3d { max-height: calc(100vh - 230px); max-height: calc(100dvh - 230px); }
.bb-card { width: 100px; }
/* During a board battle the map's own labels (towns, battle marks) give way to the battle. */
.map3d-labels:has(~ .board-battle) { display: none; }

/* ---------- round seven ---------- */
/* The guard's report stands in the hall's side column, above the council: one card a row. */
.hall-side .gr-grid { columns: 1; }
.hall-side #guard { order: -1; }
/* The quick tiles under the hall: their notes may take two lines rather than be cut. */
.station small { white-space: normal; overflow: visible; text-overflow: clip; line-height: 1.25; }
.station b { line-height: 1.15; }
@media (max-width: 900px) {
  /* On a phone the guard's call sits under the court, not over the last ministers. */
  .hall-alert { position: static; transform: none; display: block; margin: 8px auto 0; grid-column: 1 / -1; }
}

/* ---------- the icon set (icons.js): one engraved line, the colour of the text around it ---------- */
.ic { display: inline-block; width: 1.15em; height: 1.15em; vertical-align: -.2em; flex: none; }
.glyph .ic, .res i .ic, .bb-card i .ic, .gr-ico .ic, .station .glyph .ic { width: 1em; height: 1em; vertical-align: middle; }
.res i .ic { width: 15px; height: 15px; }
.dock button .glyph .ic { width: 26px; height: 26px; }
@media (max-width: 900px) { .dock button .glyph .ic { width: 21px; height: 21px; } }

/* Icons: line drawn here so a context can make it heavier; sizes per place. */
.ic { fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.res i .ic { width: 17px; height: 17px; stroke-width: 1.9; }
@media (max-width: 900px) { .res i .ic { width: 15px; height: 15px; } }
.bb-card i { color: #3a2614; }
.bb-card i .ic { stroke-width: 2.2; }
h2 .ic, h3 .ic, h4 .ic { vertical-align: -.24em; }
.ic + .ic { margin-left: 3px; }
#map .works-mark use { fill: none; stroke: #2a1b10; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
#map .works-mark text { font: 700 6px var(--font-body); fill: #2a1b10; stroke: rgba(240,228,200,.9); stroke-width: 1.5px; paint-order: stroke; }
#map .war-mark use { fill: none; stroke: #fff; stroke-width: 2.4; stroke-linecap: round; }

h2 .glyph .ic, h3 .glyph .ic, h2 > .ic, h3 > .ic { vertical-align: -.3em; }

/* Full audit round: narrow power-bar bands lose their name on a phone (the legend below names them);
   seal characters heavier; the camera hint steps aside; the empty chronicle explains itself. */
@media (max-width: 640px) { .power-bar i.narrow { font-size: 0; } }
.chop { font-weight: 800 !important; text-shadow: 0 0 2px rgba(0, 0, 0, .75), 0 1px 1px rgba(0, 0, 0, .5); }
.power-chops .chop { width: 36px; height: 36px; font-size: 10.5px !important; }
.cam-hint { transition: opacity .6s; }
.cam-hint.dim { opacity: 0; }
.bf:hover .cam-hint.dim, .cam-hint.dim:focus-within { opacity: 1; }
.rel-self { color: var(--muted); font-style: italic; }
.chronicle-empty { list-style: none; margin-top: 14px; padding: 14px 16px; border: 1px dashed rgba(120, 80, 40, .35); border-radius: 8px; color: var(--muted); font-style: italic; }

/* Audit round 3: seal characters at a readable size, the home seal visible, phone header tighter. */
.chop { font-size: 13.5px !important; }
.power-chops .chop { width: 40px; height: 40px; font-size: 12px !important; }
.gr-seal { font-size: 13px; }
.gr-realm.home .gr-seal { background: color-mix(in srgb, var(--good) 75%, #3a2a1a); color: #fff7e6; }
@media (max-width: 480px) {
  /* Two rows, not three: the title with the sound and graphics buttons, then the tabs, the year and "Ván mới". */
  .topbar h1 { order: 0; }
  .topbar .sound-toggles { order: 1; margin-left: auto; }
  .topbar .tabs { order: 2; flex: 0 0 auto; }
  .topbar #year-badge { order: 3; margin-left: auto; padding: 1px 8px; font-size: 12px; }
  .topbar #new-game-btn { order: 4; }
}

/* The stations in the side column: one under another, the note on its own line. */
#station-card .hall-stations { grid-template-columns: 1fr; }
.gr-wait { margin: 4px 0 0; font-size: 12.5px; color: var(--muted); font-style: italic; }
@media (max-width: 480px) { .gr-head { gap: 4px; } .gr-chip { font-size: 11px; padding: 1px 6px; } }
/* The court's cards in a row stand the same height, a two-line name or not. */
.rank-list { grid-auto-rows: 1fr; }

/* =====================================================================
   The lobby is the sa bàn: the board of the realms fills the window and everything else floats on
   it (as in a strategy game's campaign map). Top: the title bar, then the realm's resources. Left:
   the rooms. Right: the guard's news and the chosen province. Foot: the main deeds; bottom right:
   the gong. A room opens as a panel over the board; ✕ or Esc goes back to it.
   ===================================================================== */
.game.lobby { display: block; padding: 0; }
body:has(.game.lobby:not([hidden])) { overflow: hidden; }
body:has(.game.lobby:not([hidden])) .topbar { position: fixed; top: 0; left: 0; right: 0; z-index: 24;
  background: linear-gradient(rgba(28, 16, 9, .94), rgba(28, 16, 9, .78)); backdrop-filter: blur(3px); }
/* (Centred with margins, not a transform: a transform would hold the gong inside it.) */
.game.lobby .hud { position: fixed; top: 64px; left: 0; right: 0; margin: 0 auto; width: min(1180px, calc(100vw - 32px));
  z-index: 23; background: linear-gradient(rgba(43, 26, 16, .93), rgba(28, 16, 10, .9)); }
/* The gong out of the bar, a great round bell at the board's corner. */
.game.lobby .gong { position: fixed; right: 18px; bottom: 18px; z-index: 23; width: 92px; height: 92px; border-radius: 50%;
  align-content: center; padding: 0; box-shadow: 0 0 0 3px #3a2412, 0 0 0 5px #d9ab52, 0 10px 24px rgba(0, 0, 0, .55); }
.game.lobby .gong .gong-face { font-size: 30px; }
.game.lobby .gong .gong-label { font-size: 13px; }

/* The board under everything. */
.game.lobby #view-map { position: fixed; inset: 0; z-index: 0; display: block; padding: 0; margin: 0; }
.game.lobby #view-map .map-panel { position: absolute; inset: 0; background: #2b2119; }
.game.lobby .map3d { position: absolute; inset: 0; width: 100%; height: 100%; max-height: none !important; aspect-ratio: auto; border-radius: 0; }
/* The flat map keeps clear of the bars over it (the 3D board runs under them, as a landscape). */
.game.lobby #map { position: absolute; top: 128px; left: 104px; right: 0; bottom: 84px; width: calc(100% - 104px); height: calc(100% - 212px); }
.game.lobby #view-map .map-panel:has(#map:not([hidden])) { background: #e9dcc0 url(/static/img/paper.webp) center / cover; }
.game.lobby .map3d-bar { top: 136px; bottom: auto; left: 0; right: 0; margin: 0 auto; width: max-content; flex-direction: row; z-index: 5; }
.game.lobby .map3d-hint { left: 50%; transform: translateX(-50%); bottom: 84px; }
.game.lobby .legend { position: absolute; left: 112px; bottom: 14px; z-index: 5; margin: 0; max-width: max(300px, min(calc(50vw - 380px), 640px)); padding: 6px 12px;
  border-radius: 10px; background: rgba(28, 18, 10, .78); color: #f1e3c4; font-size: 12px; }
.game.lobby .legend .map-mode { color: #f1e3c4; border-color: #8a6326; }

/* The rooms down the left, round lacquered buttons. */
.game.lobby .dock { position: fixed; left: 12px; top: 150px; z-index: 22; gap: 8px; }
.game.lobby .dock button { width: 84px; box-shadow: 0 4px 12px rgba(0, 0, 0, .35); }
.game.lobby .dock button:not(.on) { background: rgba(250, 240, 220, .94); }

/* The main deeds along the foot of the board. */
.lobby-bar { display: none; }
.game.lobby .lobby-bar { position: fixed; left: 50%; bottom: 14px; transform: translateX(-50%); z-index: 22; display: flex; gap: 6px;
  padding: 6px 10px; border-radius: 14px; background: linear-gradient(rgba(43, 26, 16, .94), rgba(28, 16, 10, .92));
  border: 1px solid #8a6326; box-shadow: 0 8px 22px rgba(0, 0, 0, .45); }
.lobby-bar button { position: relative; display: grid; justify-items: center; gap: 1px; min-width: 76px; padding: 6px 10px; border-radius: 10px;
  background: transparent; border: 1px solid transparent; color: #f3dfb0; cursor: pointer; font: inherit; }
.lobby-bar button:hover { border-color: #d9ab52; background: rgba(217, 171, 82, .12); }
.lobby-bar button .glyph { font-size: 22px; line-height: 1.1; color: #ffd98a; }
.lobby-bar button b { font: 700 12.5px var(--font-title); white-space: nowrap; }
.lobby-bar .badge-n { position: absolute; top: 2px; right: 6px; }

/* The guard's news and the chosen province on the right. */
.game.lobby .map-side { position: fixed; top: 150px; right: 14px; width: min(380px, 32vw); max-height: calc(100vh - 270px); max-height: calc(100dvh - 270px);
  overflow-y: auto; z-index: 21; display: grid; gap: 8px; align-content: start; background: none; scrollbar-width: thin; }
.game.lobby .province-info:has(.pp-empty) { display: none; }
.lobby-alerts { display: grid; gap: 6px; }
.lobby-alerts:empty { display: none; }
.lobby-alert { display: flex; align-items: center; gap: 8px; text-align: left; padding: 7px 10px; border-radius: 10px; cursor: pointer; font: inherit; font-size: 13px;
  background: rgba(250, 240, 220, .95); color: var(--ink); border: 1px solid var(--line); box-shadow: 0 4px 12px rgba(0, 0, 0, .3); }
.lobby-alert.war { border-color: #a3271c; box-shadow: inset 4px 0 0 #a3271c, 0 4px 12px rgba(0, 0, 0, .3); }
.lobby-alert .glyph { font-size: 18px; flex: none; }
.lobby-alert.more { justify-content: center; color: var(--muted); font-style: italic; }
.lobby-alert:hover { border-color: var(--accent); }

/* A room: a panel over the board, between the rooms and the right edge, under the resources. */
/* As tall as its content (up to the window), so a short room is a short panel over the board. */
.game.lobby .views > .view:not(#view-map) { position: fixed; top: 140px; left: 110px; right: 18px; bottom: auto; max-height: calc(100vh - 158px); max-height: calc(100dvh - 158px); z-index: 26;
  overflow-y: auto; padding: 48px 16px 16px; border-radius: 14px; background: #f4e9d2 url(/static/img/paper.webp) center / cover; border: 1px solid #b08a4a;
  box-shadow: 0 16px 48px rgba(0, 0, 0, .55); scrollbar-width: thin; }
.game.lobby.panel-open .lobby-bar, .game.lobby.panel-open .map-side, .game.lobby.panel-open .legend { visibility: hidden; }
.game.lobby.panel-open .gong { right: 24px; bottom: 24px; }
.panel-close { position: fixed; top: 148px; right: 30px; z-index: 27; padding: 5px 12px; border-radius: 999px; cursor: pointer;
  background: #7a1c14; color: #ffe9b8; border: 1px solid #e2b45a; font: 700 13px var(--font-title); box-shadow: 0 4px 12px rgba(0, 0, 0, .35); }
.panel-close[hidden] { display: none; }
/* The panel's own content leaves room for the close button and the gong. */
.game.lobby .views > .view:not(#view-map) { padding-bottom: 24px; }

/* A battle watched over the board takes the whole window; the board's own battle keeps the board
   clear of the side panels and the deeds. */
.game.lobby .battle.inmap { position: fixed; inset: 0; height: auto; border-radius: 0; z-index: 40; }
.game.lobby:has(.board-battle) .lobby-bar, .game.lobby:has(.board-battle) .map-side, .game.lobby:has(.board-battle) .dock,
.game.lobby:has(.board-battle) .legend, .game.lobby:has(.board-battle) .gong { visibility: hidden; }

@media (max-width: 700px) {
  /* On a phone: the title and resources on top, the board, the rooms in the dock at the foot. */
  body:has(.game.lobby:not([hidden])) .topbar { position: fixed; }
  .game.lobby .hud { top: 74px; width: calc(100vw - 12px); padding: 4px 6px; }
  .game.lobby .hud .hud-res { flex-wrap: nowrap; overflow-x: auto; }
  .game.lobby .dock { top: auto; left: 0; right: 0; bottom: 0; z-index: 30; }
  .game.lobby .dock button, .game.lobby .dock button:not(.on) { width: auto; background: none; box-shadow: none; }
  /* The deeds as a row of round buttons over the dock, clear of the gong. */
  .game.lobby .lobby-bar { left: 8px; right: 84px; bottom: 70px; transform: none; padding: 4px; gap: 2px; justify-content: space-around; }
  .lobby-bar button { min-width: 0; padding: 4px 2px; flex: 1; }
  .lobby-bar button b { font-size: 10px; }
  .lobby-bar button .glyph { font-size: 18px; }
  .game.lobby:has(.province-info .pp) .lobby-bar, .game.lobby:has(.province-info .pp) .gong { display: none; }
  .game.lobby #map { top: 132px; left: 0; bottom: 64px; width: 100%; height: calc(100% - 196px); }
  .game.lobby .gong { width: 66px; height: 66px; right: 10px; bottom: 74px; }
  .game.lobby .gong .gong-face { font-size: 22px; }
  .game.lobby .gong .gong-label { font-size: 11px; }
  .game.lobby .legend { display: none; }
  .game.lobby .map3d-fab { display: block; position: fixed; top: 170px; right: 6px; }
  .game.lobby .map-side { top: auto; bottom: 66px; left: 0; right: 0; width: auto; max-height: 46vh; max-height: 46dvh; padding: 0 8px 6px; }
  .game.lobby .lobby-alerts { display: none; }
  .game.lobby .views > .view:not(#view-map) { top: 0; left: 0; right: 0; bottom: 62px; max-height: none; border-radius: 0; padding: 48px 12px 12px; z-index: 29; }
  .panel-close { top: 8px; right: 10px; z-index: 31; }
  .game.lobby .map3d-bar { bottom: auto; top: 140px; right: auto; left: 8px; flex-direction: row; }
}
/* The board is a layer of its own under the floating controls: a battle opened on it hides them. */
body:has(#battle:not([hidden])) .topbar, .game.lobby:has(#battle:not([hidden])) .hud, .game.lobby:has(#battle:not([hidden])) .dock,
.game.lobby:has(#battle:not([hidden])) .lobby-bar, .game.lobby:has(#battle:not([hidden])) .map-side, .game.lobby:has(#battle:not([hidden])) .gong,
.game.lobby:has(#battle:not([hidden])) .legend, .game.lobby:has(#battle:not([hidden])) .panel-close { visibility: hidden; }
/* The board's own battle: its title under the resources, not under the title bar; the gong over any panel. */
.game.lobby .board-battle { top: 130px; }
.game.lobby .gong { z-index: 28; }
@media (max-width: 700px) { .game.lobby .board-battle { top: 132px; bottom: 64px; } }
.game.lobby .legend .map-mode { background: rgba(250, 240, 220, .12); color: #f1e3c4; }
.game.lobby.panel-open .map3d-hint, .game.lobby.panel-open .map3d-bar { visibility: hidden; }

/* Last touches to the lobby. A province's panel on the right puts the deeds and the gong away (as on a
   phone); the guard's news is a narrow stack at the right edge, one line each. */
/* (On a desktop the gong and the deeds stay with a province's panel open; a phone puts them away.) */
.game.lobby .lobby-alerts { justify-self: end; width: min(270px, 100%); }
.lobby-alert span:last-child { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
@media (max-width: 700px) {
  /* All nine resources at once, in two short rows. */
  .game.lobby .hud .hud-res { flex-wrap: wrap; overflow: visible; gap: 3px; -webkit-mask-image: none; mask-image: none; justify-content: center; }
  .game.lobby .hud .res { padding: 1px 6px 1px 2px; grid-template-columns: 18px auto; }
  .game.lobby .hud .res i { width: 18px; height: 18px; }
  .game.lobby .hud .res small { display: none; }
  .game.lobby .hud .res b { font-size: 11.5px; }
  .game.lobby #map { top: 160px; height: calc(100% - 224px); }
  .game.lobby .map3d-bar { top: 166px; }
  .game.lobby .board-battle { top: 160px; }
  /* A room's last row is not left under the dock: room to scroll it clear. */
  .game.lobby .views > .view:not(#view-map) { padding-bottom: 72px; }
}
/* Over the flat map the guard's news starts under its title sign; a card scrolled to in a panel stops
   under the close button; the camera hint goes with the deeds bar when a province is open. */
.game.lobby:has(#map:not([hidden])) .map-side { top: 210px; max-height: calc(100vh - 350px); max-height: calc(100dvh - 350px); }
.game.lobby .views .card { scroll-margin-top: 48px; }
.game.lobby:has(.province-info .pp) .map3d-hint { visibility: hidden; }

/* Battle title at the top left of the board, clear of the town and the van; the panels' scrollbar
   always shown (a sign there is more below); the hud (and its gong) above the room panels; the rows
   of a room packed at its top, not spread over a tall panel. */
.game.lobby .board-battle .bb-top { align-self: flex-start; margin-left: 12px; }
.game.lobby .views > .view:not(#view-map) { overflow-y: scroll; scrollbar-width: auto; scrollbar-color: #b08a4a rgba(0, 0, 0, .06); align-content: start; }
.game.lobby .hud { z-index: 27; }
/* With a room open the gong stands in its own strip beside the panel, never over its content. */
@media (min-width: 701px) { .game.lobby.panel-open .views > .view:not(#view-map) { right: 128px; } .panel-close { right: 140px; } }

/* A province open over the flat map: the map draws itself in what is left of the board, left of the
   panel, so no name at its right edge is under it. On a phone the close button is a bar of its own at
   the top of the room, with the room under it, so nothing scrolls beneath the button. */
@media (min-width: 701px) {
  .game.lobby:has(.province-info .pp) #map { width: calc(100% - 104px - min(400px, 34vw) - 28px); }
}
@media (max-width: 700px) {
  .game.lobby .views > .view:not(#view-map) { top: 46px; padding-top: 12px; }
  .panel-close { top: 0; left: 0; right: 0; height: 46px; border-radius: 0; border-width: 0 0 1px; text-align: right; padding: 0 16px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, .35); }
}

/* The flat map beside a column on the right (the guard's news, or a province) is drawn at its own
   shape at the top of what is left, so no empty bands above and below it; the news has its own
   column and lies over no town. A room open hides the flat map (only its paper shows past the
   panel's edge, not a cut strip of the map). */
@media (min-width: 701px) {
  .game.lobby:has(.lobby-alerts:not(:empty)) #map { width: calc(100% - 104px - 300px); }
  .game.lobby:has(#map:not([hidden])) .lobby-alerts { width: 280px; }
  .game.lobby.panel-open #map { visibility: hidden; }
}
/* On a phone the camera buttons are a narrow column of signs at the right edge. */
@media (max-width: 700px) {
  .game.lobby .map3d-bar { top: 170px; left: auto; right: 6px; flex-direction: column; gap: 4px; }
  .game.lobby .map3d-bar button { width: 38px; height: 34px; padding: 0; font-size: 15px; opacity: .9; }
  .game.lobby .map3d-bar button span { display: none; }
  .game.lobby .map3d-bar .flat { font-size: 12px; }
}
/* On a phone the camera signs are small and half see-through, tight to the edge. */
@media (max-width: 700px) {
  .game.lobby .map3d-bar { right: 3px; }
  .game.lobby .map3d-bar button { width: 32px; height: 30px; font-size: 13px; opacity: .72; }
}
/* Whatever is opened over the lobby stands over all of it: the war table, a watched battle,
   a short notice, the end of the game and the wait spinner over the hud, the gong and any room panel. */
.game.lobby ~ .muster, .muster { z-index: 60; }
.battle:not(.inmap) { z-index: 50; }
.toast { z-index: 70; }
.overlay { z-index: 66; }
.busy { z-index: 65; }
/* A notice over the lobby stands above the deeds bar, not on it. */
body:has(.game.lobby:not([hidden])) .toast { bottom: 96px; }
@media (max-width: 700px) { body:has(.game.lobby:not([hidden])) .toast { bottom: 140px; } }
/* The war table on a phone: its head scrolls away with the counsel, and its foot is one short row
   (a small gauge beside the orders), so the plans between them keep the screen. */
@media (max-width: 640px) {
  .mu-head { position: static; }
  .mu-foot { grid-template-columns: auto 1fr; justify-items: stretch; align-items: center; gap: 8px; padding: 6px 10px; }
  .mu-gauge svg { width: 96px; }
  .mu-gauge .mu-chance { margin-top: -6px; }
  .mu-gauge .mu-chance span { font-size: 9px; letter-spacing: .06em; }
  .mu-gauge b, .mu-gauge strong { font-size: 13px; }
  .mu-actions { justify-content: flex-end; flex-wrap: wrap; gap: 6px; }
  .mu-actions .mu-go { font-size: 15px; padding: 10px 14px; }
  .mu-actions .mu-error { flex-basis: 100%; margin: 0; font-size: 12px; }
}

/* ---------- accounts: the gate, the player's games, the rankings ---------- */
.auth-card { max-width: 420px; margin: 8px auto 32px; padding: 18px 20px 20px; }
.auth-tabs { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; margin-bottom: 14px; }
.auth-tab { padding: 9px; border-radius: 10px; border: 1px solid var(--line); background: transparent; color: var(--ink);
  font: 700 15px var(--font-title); cursor: pointer; }
.auth-tab.active { background: linear-gradient(#a3271c, #7a1c14); color: #ffe9b8; border-color: #e2b45a; }
.auth-form { display: grid; gap: 12px; }
.auth-form label, .pw-box label { display: grid; gap: 4px; font-size: 14px; color: var(--muted); text-align: left; }
.auth-form input, .pw-box input { font: inherit; font-size: 16px; padding: 9px 11px; border-radius: 8px; border: 1px solid var(--line);
  background: #fffaf0; color: var(--ink); }
.auth-form input:focus-visible, .pw-box input:focus-visible { outline: 2px solid #b08a4a; outline-offset: 1px; }
.auth-form button[type=submit], .pw-box button[type=submit] { padding: 11px; font-size: 16px; }
.auth-error { margin: 0; padding: 8px 10px; border-radius: 8px; background: #fbe4df; color: #8a2016; border: 1px solid #e3a99d; font-size: 14px; }
.auth-note { margin: 0; font-size: 12.5px; color: var(--muted); }

.account { position: relative; }
.account-menu { position: absolute; right: 0; top: calc(100% + 6px); z-index: 90; display: grid; min-width: 170px; padding: 6px;
  border-radius: 10px; background: #2b1d12; border: 1px solid #8a6326; box-shadow: 0 10px 24px rgba(0, 0, 0, .45); }
.account-menu button { text-align: left; background: transparent; border: 0; color: #f3dfb0; padding: 8px 10px; border-radius: 6px; cursor: pointer; font: inherit; }
.account-menu button:hover, .account-menu button:focus-visible { background: rgba(217, 171, 82, .16); }

.my-games { margin: 0 0 16px; padding: 12px 14px; border-radius: 12px; border: 1px solid var(--line); background: rgba(255, 250, 240, .7); }
.my-games h3 { margin: 0 0 8px; font: 700 17px var(--font-title); }
.my-games ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.my-games li { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; padding: 6px 0; border-top: 1px dashed var(--line); }
.my-games li:first-child { border-top: 0; }
.my-games li.done .mg-what { opacity: .75; }
.my-games small { display: block; color: var(--muted); font-size: 12.5px; }
.mg-acts { display: flex; gap: 6px; }

.dialog { z-index: 75; }
.dlg-close { position: absolute; top: 10px; right: 10px; }
.overlay-box { position: relative; }
.board-box { max-width: 760px; width: 100%; text-align: left; max-height: calc(100vh - 32px); max-height: calc(100dvh - 32px); display: flex; flex-direction: column; }
.lb-note, .lb-count, .lb-wait { color: var(--muted); font-size: 13.5px; margin: 4px 0 10px; }
.lb-scroll { overflow: auto; }
table.lb { width: 100%; border-collapse: collapse; font-size: 14px; }
table.lb th, table.lb td { padding: 7px 8px; border-bottom: 1px solid var(--line); text-align: left; white-space: nowrap; }
table.lb th { font: 700 13px var(--font-title); color: var(--muted); position: sticky; top: 0; background: var(--panel); }
table.lb .num { text-align: right; font-variant-numeric: tabular-nums; }
table.lb .rk { font-weight: 700; width: 2.5em; }
table.lb .sc { font-weight: 700; }
table.lb tr.me td { background: rgba(217, 171, 82, .22); }
table.lb tr.gap td { text-align: center; color: var(--muted); border-bottom: 0; }
.pw-box { display: grid; gap: 12px; width: 100%; max-width: 380px; text-align: left; }
@media (max-width: 700px) {
  #rank-btn .lbl, #account-btn .lbl { display: none; }
  .board-box { padding: 18px 12px; }
  table.lb th, table.lb td { padding: 6px 5px; font-size: 13px; }
}
/* The rankings by realm: the đệ nhất of each realm along the top, a tab per realm. */
.lb-champions { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 8px; margin: 2px 0 10px; }
.lb-champions:empty { display: none; }
.lb-champ { display: grid; gap: 1px; text-align: left; padding: 8px 10px; border-radius: 10px; cursor: pointer; font: inherit;
  background: #fffaf0; color: var(--ink); border: 1px solid var(--line); border-left: 5px solid var(--c); }
.lb-champ small { color: var(--muted); font-size: 11.5px; }
.lb-champ b { font: 700 15px var(--font-title); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lb-champ span { font-size: 12.5px; font-variant-numeric: tabular-nums; }
.lb-champ.me { background: rgba(217, 171, 82, .22); }
.lb-tabs { display: flex; gap: 4px; flex-wrap: wrap; margin: 0 0 8px; }
.lb-tab { padding: 4px 11px; border-radius: 999px; border: 1px solid var(--line); background: transparent; color: var(--ink); cursor: pointer; font: inherit; font-size: 13.5px; }
.lb-tab[style] { border-left: 4px solid var(--c); }
.lb-tab.on { background: linear-gradient(#a3271c, #7a1c14); color: #ffe9b8; border-color: #e2b45a; }
.board-box { overflow-y: auto; }
@media (max-width: 700px) { .lb-champions { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.bot-tag { font-size: 12px; opacity: .8; cursor: help; }
/* What each work raises, in a few words, on its line and its build button. */
.pp-effect { display: block; font-style: normal; font-size: 11.5px; color: #3f6b2a; font-weight: 600; }
.pp-work .pp-effect { display: inline; margin-left: 6px; }
.pp-offer:disabled .pp-effect { color: var(--muted); }
/* The first three of the rankings wear a medal. */
.medal { display: inline-grid; place-items: center; width: 22px; height: 22px; border-radius: 50%; font-weight: 800; font-size: 12px; color: #2a1a0c;
  box-shadow: inset 0 -2px 0 rgba(0, 0, 0, .2), 0 1px 2px rgba(0, 0, 0, .3); }
.medal.m1 { background: radial-gradient(circle at 35% 30%, #fff1b0, #d6a82e 70%); }
.medal.m2 { background: radial-gradient(circle at 35% 30%, #ffffff, #a9b0b8 70%); }
.medal.m3 { background: radial-gradient(circle at 35% 30%, #ffd9b0, #b8733a 70%); }
/* The king's face on his realm's card; the hero's seal in Vietnamese, cut bold like a real seal. */
.choice-face { float: left; width: 66px; height: 84px; object-fit: cover; object-position: top; border-radius: 8px; margin: 2px 12px 6px 0;
  border: 2px solid var(--c, #b08a4a); box-shadow: 0 3px 8px rgba(40, 20, 5, .3); background: #2a1a10; }
.hero-seal { font: 700 clamp(15px, 1.9vw, 21px)/1.1 var(--font-title); padding: 8px 10px; letter-spacing: .02em; text-align: center; }
@media (max-width: 700px) { .choice-face { width: 54px; height: 68px; } }
/* On a phone the account menu is a sheet under the title bar, over everything, not tucked among the buttons. */
@media (max-width: 700px) { .account-menu { position: fixed; top: 64px; right: 8px; left: auto; min-width: 200px; } }
/* The lie of the land on a province's panel, and what it does to each work. */
.pp-land { font-style: normal; font-size: 12px; padding: 1px 8px; border-radius: 999px; border: 1px solid var(--line); background: #f3ead6; cursor: help; }
.pp-land.land-QUAN_AI { background: #5a3a24; color: #ffe9b8; border-color: #3a2414; }
.pp-land.land-NUI { background: #e3d6bd; }
.pp-land.land-DONG_BANG { background: #dfe9c8; }
.pp-land.land-VEN_BIEN { background: #d3e4e6; }
.pp-land.land-THAO_NGUYEN { background: #ece3b4; }
.pp-land-fx { display: block; font-style: normal; font-size: 11px; font-weight: 700; }
.pp-land-fx.good { color: #2f6b2a; }
.pp-land-fx.bad { color: #9c3b22; }
.pp-work .pp-land-fx { display: inline; }
/* The guide: the first-year steps, the big tables folded away, the works' effect line readable. */
.guide .first-year { background: #fff6dc; border: 1px solid #d8b56a; border-left: 6px solid #a3271c; border-radius: 10px; padding: 10px 16px; margin: 14px 0; }
.guide .first-year h3 { margin: 4px 0 6px; }
.guide .first-year ol { margin: 0; padding-left: 20px; }
.guide details { margin: 6px 0 10px; }
.guide details > summary { cursor: pointer; font-weight: 700; color: #7a1c14; padding: 4px 0; }
.guide td small { font-size: 12px; color: #3f6b2a; font-weight: 600; }
/* A province's strength in defence, at the head of its army column. */
.pp-hold { margin: 0 0 8px; padding: 6px 8px; border-radius: 8px; background: #efe4cc; border-left: 4px solid #7a1c14; }
.pp-hold small { display: block; color: var(--muted); }
/* The realm cards: the king's name on one line beside his seal. */
.choice strong { font-size: 20px; }
.choice { padding-right: 70px; }
.game.lobby .map-side { scrollbar-width: auto; scrollbar-color: #b08a4a rgba(0, 0, 0, .1); }
/* The province's governor. */
.pp-gov { margin: 0 0 10px; padding: 8px 10px; border-radius: 8px; background: #f3ead6; border: 1px solid var(--line); }
.pp-gov p { margin: 2px 0; }
.pp-gov small { color: var(--muted); }
.pp-gov .bad { color: #9c2b22; }
.pp-warn { color: #8a3a12; font-size: 12.5px; }
.pp-gov-acts { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-top: 6px; }
.pp-gov-acts select { max-width: 100%; font: inherit; font-size: 13px; padding: 3px 6px; border-radius: 6px; border: 1px solid var(--line); background-color: #fffaf0; }
.pp-censor { font-size: 13px; display: inline-flex; gap: 4px; align-items: center; }
/* On a phone «Ván mới» lives in the account menu, not in the crowded title bar. */
@media (max-width: 700px) { #new-game-btn { display: none !important; } }
/* «Ván mới» lives in the account menu alone (the header's button is gone). */
/* The skill screen stands over the field and its labels; the general's name reads clearly. */
.skill-screen { z-index: 12; }
.stage[data-phase="skill"] .bf-place, .stage[data-phase="skill"] .bf-hud { visibility: hidden; }
.skill-screen .skill-by { color: #fff3d6; font-weight: 700; font-size: clamp(16px, 2.2vw, 22px); text-shadow: 0 2px 6px #000, 0 0 2px #000; opacity: 1; }
/* The great passes on the flat map. */
#map .pass-name { font: 700 7.5px var(--font-title); fill: #5a2a14; paint-order: stroke; stroke: rgba(255, 244, 220, .85); stroke-width: 2px; letter-spacing: .02em; }
/* A work that cannot go up here says why in a legible line. */
.pp-offer:disabled { opacity: .72; }
.pp-offer:disabled small { color: #8a3a12; font-weight: 600; }
@media (max-width: 700px) {
  /* Ten resources in two even rows of five on a phone. */
  .game.lobby .hud .hud-res { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); justify-items: stretch; gap: 3px; }
  .game.lobby .hud .res { justify-content: center; min-width: 0; }
}
/* The province panel at the side of the board is one column (home affairs, then the army): two
   narrow columns no longer fit the governor's line and the build buttons. */
.game.lobby .map-side .pp-cols { grid-template-columns: 1fr; }
.game.lobby .map-side .pp-cols > .pp-body + .pp-body { border-left: 0; border-top: 1px solid var(--line); }
.pp-body { min-width: 0; }
.pp-gov-acts select { width: 100%; min-width: 0; }
@media (min-width: 701px) { .game.lobby .map-side { width: min(400px, 34vw); } }
/* The king's name on his realm's card on a line of its own, never broken. */
.choice-king { display: block; font-size: 14px; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-top: 1px; }
.pp-hold-chip { font-style: normal; font-size: 12px; padding: 1px 8px; border-radius: 999px; background: #efe4cc; border: 1px solid var(--line); cursor: help; }

/* Review round 1. */
/* The battle's place and weather in the top-left corner on a dark plate, clear of the gate towers. */
.bf-place { left: 14px; top: 12px; transform: none; text-align: left; background: rgba(20, 12, 6, .62); padding: 4px 10px; border-radius: 8px; }
/* On a phone the hall's last row of cards scrolls clear of the dock. */
@media (max-width: 700px) { .game.lobby #view-hall { padding-bottom: 110px; } }
/* The sign-in page: a shorter hero, so the whole card fits the first screen. */
#auth .hero { height: clamp(180px, 20vw, 300px); }
/* The province panel shows there is more below: a soft fade at its foot. */
.game.lobby .map-side { -webkit-mask-image: linear-gradient(#000 calc(100% - 28px), transparent); mask-image: linear-gradient(#000 calc(100% - 28px), transparent); padding-bottom: 24px; }

/* The stations' painted icons. */
.station .glyph img { width: 46px; height: 46px; object-fit: contain; display: block; margin: 0 auto; filter: drop-shadow(0 2px 3px rgba(0,0,0,.35)); }
@media (max-width: 700px) { .station .glyph img { width: 34px; height: 34px; } }

/* The works' painted icons, on their cards in the province panel. */
.pp-offer .pp-work-ic { float: left; width: 40px; height: 40px; object-fit: contain; margin: 0 8px 2px 0; filter: drop-shadow(0 1px 2px rgba(0,0,0,.25)); }
.pp-work .pp-work-ic { width: 30px; height: 30px; object-fit: contain; vertical-align: middle; margin-right: 6px; }

/* A painting over a piece of news (a disaster, an envoy, an alliance). */
/* A small picture at the line's side, not a banner across it. */
.gr-line .gr-art { float: right; width: 96px; height: 64px; object-fit: cover; border-radius: 6px; margin: 0 0 4px 8px; border: 1px solid var(--line); }
.gr-line::after { content: ""; display: block; clear: both; }

/* Góp ý / báo lỗi, ủng hộ tác giả. */
.fb-box, .dn-box { max-width: 520px; width: calc(100vw - 32px); display: grid; gap: 10px; }
.fb-kinds { display: flex; gap: 16px; flex-wrap: wrap; }
.fb-kinds label { display: flex; align-items: center; gap: 6px; cursor: pointer; }
#fb-message { width: 100%; box-sizing: border-box; resize: vertical; min-height: 120px; font: inherit; padding: 8px; border-radius: 6px; border: 1px solid var(--line); background: #fffaf0; color: var(--ink); }
.fb-note { font-size: 12.5px; color: var(--muted); margin: 0; }
.fb-acts { display: flex; gap: 8px; flex-wrap: wrap; justify-content: space-between; }
.dn-bank { display: grid; grid-template-columns: auto 1fr; gap: 6px 14px; margin: 0; padding: 12px; border-radius: 8px; background: #fbf3e2; border: 1px solid var(--line); }
.dn-bank dt { color: var(--muted); } .dn-bank dd { margin: 0; font-weight: 600; }
#dn-acct { font-size: 1.15em; letter-spacing: .04em; }
.dn-copy { padding: 1px 8px; margin-left: 6px; font-size: 12px; }
.dn-thanks { text-align: center; font-style: italic; margin: 0; }
@media (max-width: 700px) { #feedback-btn .lbl { display: none; } }

/* The ending's painting over its words. */
.end-box { max-width: 640px; }
.end-art { display: block; width: 100%; max-height: 300px; object-fit: cover; border-radius: 8px; margin-bottom: 12px; border: 1px solid var(--line); }

/* The guide's annotated pictures: a box round each control, its number in a red seal, an arrow. */
.gd-fig { margin: 14px 0 22px; border: 1px solid var(--line); border-radius: 10px; overflow: hidden; background: #fbf5e8; }
.gd-pic { position: relative; line-height: 0; }
.gd-pic img { width: 100%; height: auto; display: block; }
.gd-pic svg { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.gd-box { fill: rgba(255, 214, 90, .10); stroke: #ffd54a; stroke-width: 2.5; stroke-dasharray: 7 4; }
.gd-arrow { stroke: #b3261e; stroke-width: 2.6; }
.gd-head { fill: #b3261e; }
.gd-seal circle { fill: #b3261e; stroke: #ffe9b8; stroke-width: 2.5; }
.gd-seal text { fill: #fff; font: 700 15px var(--font-title, serif); text-anchor: middle; }
.gd-fig figcaption { padding: 10px 14px 12px; line-height: 1.5; }
.gd-fig figcaption ol { margin: 6px 0 0; padding-left: 22px; }
.gd-fig figcaption li::marker { color: #b3261e; font-weight: 700; }
@media (max-width: 700px) { .gd-seal text { font-size: 20px; } .gd-seal circle { r: 18; } }

#new-game-btn { display: none !important; }
.write-edict { float: right; font-size: 13px; padding: 2px 10px; }
#tasks-state-card { grid-column: 1 / -1; }

/* The army card's own controls: thừa thắng, split, rename. */
.army .press-on { display: flex; align-items: center; gap: 8px; font-size: 13px; margin: 6px 0 2px; cursor: pointer; white-space: nowrap; color: var(--muted); }
/* The label stays on one line; the choice takes the rest of the card and cuts its text short if it must. */
.army .press-on select { flex: 1 1 auto; min-width: 0; width: 100%; min-height: 28px; padding-top: 2px; padding-bottom: 2px; font-size: 13px;
  text-overflow: ellipsis; overflow: hidden; color: var(--ink); }
.army-acts { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.army-acts select.chip { max-width: 100%; }
.army .army-acts { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 4px; }
.army-form { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.army-form input, .army-form select { flex: 1 1 140px; min-width: 0; padding: 4px 6px; border-radius: 6px; border: 1px solid var(--line); background-color: #fffaf0; color: var(--ink); font: inherit; }

/* The council's questions are gone (the hall shows the court; every order has its button). */
#consult-card { display: none !important; }

/* The guide's folded sections. */
#guide details.gd-sec { border-top: 1px solid var(--line); padding: 2px 0; }
#guide details.gd-sec > summary { cursor: pointer; list-style: none; font: 700 1.25em var(--font-title, serif); color: var(--accent, #9c2b22); padding: 10px 4px; display: flex; align-items: center; gap: 8px; }
#guide details.gd-sec > summary::-webkit-details-marker { display: none; }
#guide details.gd-sec > summary::before { content: "▸"; transition: transform .15s; display: inline-block; }
#guide details.gd-sec[open] > summary::before { transform: rotate(90deg); }
#guide details.gd-sec > summary:hover { background: rgba(156, 43, 34, .06); border-radius: 6px; }

/* The guide's two parts. */
#guide h2.gd-part { margin: 26px 0 8px; padding: 8px 12px; border-radius: 8px; background: #3b2418; color: #f4e3c2; font-size: 1.2em; }
#guide h2.gd-part small { display: block; font: 400 13px var(--font-body, serif); opacity: .8; margin-top: 2px; }
#guide .toc { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 10px; }
#guide .toc-part { display: flex; flex-wrap: wrap; gap: 4px 6px; align-content: flex-start; }
#guide .toc-part > b { flex-basis: 100%; }

/* Matters waiting: the gong shows it; the guard's report offers to settle them all. */
.gong.blocked { filter: saturate(.6) brightness(.95); outline: 2px dashed #b3261e; outline-offset: 3px; }
.gr-head .settle-all { margin-left: auto; padding: 4px 12px; border-radius: 999px; background: #b3261e; color: #fff; border: 0; font-weight: 700; cursor: pointer; }
.gr-head .settle-all:disabled { opacity: .6; }

/* The board's key, folded. */
.legend-fold > summary { cursor: pointer; font-weight: 700; list-style: none; }
.legend-fold > summary::-webkit-details-marker { display: none; }
.legend-fold:not([open]) { display: inline-block; }
.hall-stations:empty { display: none; }

/* Nothing waiting beside the hall (no report, no result): the hall takes the whole width. */
#view-hall:not(:has(.hall-side > :not([hidden]):not(#consult-card):not(:empty))) { grid-template-columns: minmax(0, 1fr); }
#view-hall:not(:has(.hall-side > :not([hidden]):not(#consult-card):not(:empty))) .hall-side { display: none; }

/* The HUD: five figures, the rest behind «⋯» (a low one shows anyway). */
.hud-res:not(.more) .res.extra:not(.low) { display: none; }
.hud-res .res-more { flex: 0 0 auto; align-self: center; border: 1px solid var(--line, #8a6326); background: rgba(255,255,255,.08); color: inherit; border-radius: 999px; padding: 2px 10px; font-weight: 700; cursor: pointer; }
.hud-res .res small { font-size: 10px; }

/* ⚙ Cài đặt: the sound, graphics and voice controls in one drop-down. */
.settings { position: relative; }
.settings-menu { position: absolute; right: 0; top: calc(100% + 6px); z-index: 60; display: grid !important; gap: 6px; min-width: 190px; padding: 10px;
  background: #2a1a10; border: 1px solid #8a6326; border-radius: 10px; box-shadow: 0 10px 30px rgba(0,0,0,.45); }
.settings-menu[hidden] { display: none !important; }
.settings-menu > * { width: 100%; justify-content: flex-start; }
.settings-menu .lbl { display: inline !important; }

/* Quân nghị: the best plan in full, the others folded. */
.mu-memorials.one { grid-template-columns: minmax(0, 1fr) !important; }
.mu-more { margin-top: 6px; }
.mu-more > summary { cursor: pointer; font-weight: 700; padding: 4px 0; color: #e8c88a; }

/* Tướng sĩ: one line of figures, the nature folded. */
.person .pstats { display: flex; flex-wrap: wrap; gap: 4px 10px; font-size: 13px; margin: 3px 0; align-items: center; }
.person .pstats span { white-space: nowrap; }
.person .pmore > summary { cursor: pointer; font-size: 12.5px; color: var(--muted, #7a6a58); list-style: none; }
.person .pmore > summary::-webkit-details-marker { display: none; }
.person .pmore > summary::before { content: "▸ "; }
.person .pmore[open] > summary::before { content: "▾ "; }
.settings-menu button, .settings-menu select { color: #f4e3c2 !important; background-color: rgba(255,255,255,.06) !important; border: 1px solid #8a6326 !important; opacity: 1 !important; padding: 6px 10px !important; font-size: 14px !important; border-radius: 8px; }
.settings-menu select option { color: #2a1a10; }
.settings-menu button[aria-pressed="false"] { opacity: .65 !important; }

.army .join-sel { max-width: 100%; padding: 3px 8px; border-radius: 999px; font: inherit; font-size: 13px; }

/* Trị tội in Tướng sĩ: his post, what he took, the six punishments. */
.person .pduty { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; font-size: 12.5px; margin-top: 3px; }
.person .pduty .skim { color: #b3261e; font-weight: 700; }
.punish-menu { display: grid; gap: 4px; margin-top: 6px; padding: 6px; border: 1px solid var(--line); border-radius: 8px; background: #fbf3e2; }
.punish-menu .chip { display: grid; text-align: left; justify-items: start; gap: 0; border-radius: 8px; }
.punish-menu .chip small { font-size: 11.5px; opacity: .8; }

/* Quốc sự: each province as signs at a glance. */
.prov { gap: 3px; }
.prov .prov-top { display: flex; align-items: center; gap: 6px; }
.prov .prov-war { margin-left: auto; color: #b3261e; font-style: normal; }
.prov.war { border-color: #b3261e; box-shadow: inset 0 0 0 1px rgba(179,38,30,.35); }
.prov .prov-signs { display: flex; gap: 6px; font-size: 15px; min-height: 18px; }
.prov .prov-signs i { font-style: normal; }
.prov .wks { display: flex; flex-wrap: wrap; gap: 3px; align-items: center; min-height: 26px; }
.prov .wk-ic { position: relative; display: inline-block; width: 26px; height: 26px; }
.prov .wk-ic img { width: 26px; height: 26px; object-fit: contain; }
.prov .wk-ic sub { position: absolute; right: -2px; bottom: -2px; font-size: 10px; font-weight: 700; background: #3b2418; color: #f4e3c2; border-radius: 6px; padding: 0 3px; }
.prov .prov-gov { font-size: 11.5px; color: var(--muted, #7a6a58); }
.prov .prov-gov.bad { color: #b3261e; font-weight: 700; }
.prov .prov-gov.none { font-style: italic; }
.prov-key { font-size: 12px; color: var(--muted, #7a6a58); margin: -4px 0 6px; }
.res-pill { font-style: normal; font-size: 11px; padding: 0 6px; border-radius: 999px; background: #e9d8b4; border: 1px solid #c9a86a; color: #5a3a1a; align-self: center; }

/* Every town named on both maps. */
#map .town-name { font: 600 5.2px var(--font-body); fill: #2a1b10; paint-order: stroke; stroke: rgba(240,228,200,.85); stroke-width: 1.6px; pointer-events: none; }
@media (min-width: 900px) { #map .town-name { font-size: 6.4px; } }
.map3d-labels .town { font: 600 11px var(--font-body, serif); color: #2a1b10; background: rgba(244, 233, 210, .78); padding: 0 5px; border-radius: 4px; white-space: nowrap; cursor: pointer; pointer-events: auto; }
.map3d-labels .battle { white-space: nowrap; font-weight: 700; }

/* A place named in the news: click to see it on the board. */
a.place { color: inherit; text-decoration: underline dotted; text-underline-offset: 2px; cursor: pointer; }
a.place:hover { color: #b3261e; }

/* A province's panel: its head (name, close) stays in sight as the panel scrolls; a clear close. */
.map-side .pp-head, .province-info .pp-head { position: sticky; top: 0; z-index: 3; background: var(--panel, #f6ecd6); border-bottom: 1px solid var(--line); }
.pp-head .pp-close { font-size: 15px; font-weight: 700; padding: 5px 12px; border-radius: 8px; background: #b3261e; color: #fff; border: 0; }
.pp-head .pp-close:hover { background: #8e1d17; }
/* (clip keeps the rounded corners without making the panel its own scroller, so the head can stick) */
.pp { overflow: clip; }

.raise-form { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; width: 100%; }
.raise-form input, .raise-form select { flex: 1 1 160px; min-width: 0; padding: 4px 6px; border-radius: 6px; border: 1px solid var(--line); background-color: #fffaf0; color: var(--ink); font: inherit; }
.raise-form small { flex-basis: 100%; color: var(--muted); font-size: 12px; }

.pmore .pfacts { margin: 4px 0 2px; padding-left: 16px; font-size: 12px; line-height: 1.5; }
.pmore .pfacts small { opacity: .75; }
.pmore .pfacts .low { color: #b23a2a; }
.pmore h5 { margin: 6px 0 0; font-size: 12px; opacity: .8; }

.pay-dials { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 10px; margin: 6px 0; }
.pay-dial { display: flex; flex-direction: column; gap: 4px; padding: 8px 10px; border: 1px solid rgba(120, 80, 40, .25); border-radius: 8px; background: rgba(255, 250, 240, .5); }
.pay-dial .pay-head { display: flex; align-items: center; gap: 6px; }
.pay-dial output { margin-left: auto; font-weight: 700; font-size: 16px; }
.pay-dial input[type=range] { width: 100%; accent-color: #8b2a1a; }
.pay-dial small .bad { color: #b23a2a; }
.pay-dial small .good { color: #2f7a3a; }

.minister.away { opacity: .45; filter: grayscale(.6); }
.minister.away:hover { opacity: .8; }
.minister .mw { font-size: 9.5px; line-height: 1; opacity: .9; }
.person.away { opacity: .6; }
.person.away:hover { opacity: 1; }
.pwhere { display: block; font-size: 11.5px; margin-top: 1px; }
.pwhere.here { color: #2f7a3a; }
.pwhere.away { color: #8a5a2a; }

.punish-menu .take { display: inline-block; margin-left: 6px; font-style: normal; font-weight: 700; color: #8b5a12; }

/* ---------- a phone held sideways (landscape, short screen): everything slim, the board wide ---------- */
@media (orientation: landscape) and (max-height: 540px) {
  .topbar { padding: 2px 8px !important; min-height: 0; gap: 4px; flex-wrap: nowrap; }
  .topbar h1 { font-size: 14px !important; white-space: nowrap; }
  .topbar h1::before { width: 22px !important; height: 22px !important; }
  .topbar button, .topbar .tab, .topbar select { padding: 2px 8px !important; font-size: 11.5px !important; white-space: nowrap; min-height: 0; }
  body:has(.game.lobby:not([hidden])) .topbar { position: fixed; left: 0; right: 0; top: 0; z-index: 35; }
  .game.lobby .hud { top: 34px !important; padding: 2px 6px; gap: 4px; }
  .game.lobby .hud .hud-res { flex-wrap: nowrap; overflow-x: auto; }
  .res { padding: 1px 6px 1px 2px; }
  .res small { display: none; }
  /* The rooms: a thin rail down the left. */
  .game.lobby .dock { position: fixed; left: 0; right: auto; top: 74px; bottom: 0; width: 58px; z-index: 30;
    flex-direction: column; gap: 2px; padding: 4px 3px calc(4px + env(safe-area-inset-bottom)); overflow-y: auto;
    background: rgba(28, 16, 10, .92); border-right: 1px solid #8a6326; border-top: 0; }
  .game.lobby .dock button, .game.lobby .dock button:not(.on) { flex: 0 0 auto; width: 52px; padding: 4px 0 3px; background: none; box-shadow: none; color: #e8d6b2; }
  .game.lobby .dock button.on { background: linear-gradient(#a3271c, #7a1c14); }
  .dock button .glyph, .dock button .glyph .ic { font-size: 18px; width: 18px; height: 18px; }
  .dock button .lbl { font-size: 9px; line-height: 1.05; white-space: normal; text-align: center; }
  /* A room: between the rail and the gong, under the resources. */
  .game.lobby .views > .view:not(#view-map) { top: 74px; left: 62px; right: 70px; bottom: 4px; max-height: none; border-radius: 10px; padding: 40px 10px 10px; z-index: 29; }
  .panel-close { top: 80px; right: 78px; z-index: 31; padding: 3px 10px; font-size: 12px; }
  .game.lobby .gong, .game.lobby.panel-open .gong { width: 58px; height: 58px; right: 6px; bottom: 6px; }
  .game.lobby .gong .gong-face { font-size: 20px; }
  .game.lobby .gong .gong-label { font-size: 10px; }
  /* The deeds along the foot, between the rail and the gong. */
  .game.lobby .lobby-bar { left: calc(50% + 29px); right: auto; bottom: 6px; transform: translateX(-50%); padding: 2px 4px; gap: 2px; justify-content: center; }
  .lobby-bar button { min-width: 0; padding: 2px 10px; }
  .lobby-bar button .glyph { font-size: 16px; }
  .lobby-bar button b { font-size: 10px; }
  .game.lobby:has(.province-info .pp) .lobby-bar { display: flex; }
  /* The chosen province and the guard's news on the right, as tall as the screen allows. */
  .game.lobby .map-side { top: 76px; bottom: 70px; right: 70px; left: auto; width: min(340px, 44vw); max-height: none; padding: 0; }
  .game.lobby #map { top: 74px; left: 58px; right: 0; bottom: 0; width: calc(100% - 58px); height: calc(100% - 74px); }
  /* The guard's news column is put away here: the flat map keeps the whole width. */
  .game.lobby:has(.lobby-alerts:not(:empty)) #map { width: calc(100% - 58px); }
  .game.lobby .map3d-bar { top: 80px; left: 66px; right: auto; margin: 0; }
  .game.lobby .map3d-hint, .game.lobby .legend { display: none; }
  .game.lobby .map3d-fab { display: block; position: fixed; top: 80px; right: 10px; }
  .game.lobby .board-battle { top: 74px; bottom: 0; }
  .game.lobby .lobby-alerts { display: none; }
  .game.lobby:has(#map:not([hidden])) .map-side { top: 76px; bottom: 70px; max-height: none; }
  .game.lobby:has(.province-info .pp) #map { width: calc(100% - 58px - min(340px, 44vw) - 76px); }
  /* The realm choice: a short banner, the realms in view at once. */
  .hero, .hero-art { max-height: 120px; }
}

/* Ván của bệ hạ: the games being played, and the record of finished ones (Thành tích). */
.mg-tabs { display: flex; gap: 6px; margin: 4px 0 8px; }
.mg-tabs button { padding: 4px 12px; border-radius: 999px; border: 1px solid var(--line); background: var(--panel); color: var(--ink); cursor: pointer; font: inherit; font-size: 13px; }
.mg-tabs button.on { background: #7a1c14; color: #ffe9b8; border-color: #e2b45a; }
.mg-tabs button i { font-style: normal; opacity: .75; margin-left: 2px; }
.mg-empty { color: var(--muted); font-size: 13px; margin: 4px 0; }
.mg-feats { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 6px; margin-bottom: 8px; }
.mg-feats > div { padding: 6px 8px; border: 1px solid var(--line); border-radius: 8px; background: var(--panel); display: grid; }
.mg-feats b { font: 700 18px var(--font-title); color: #8b2a1a; }
.mg-feats small { color: var(--muted); font-size: 11.5px; }
.mg-done li { display: flex; align-items: center; gap: 8px; }
.mg-done .mg-medal { font-size: 20px; }
.mg-done li.won em { color: #2f7a3a; font-style: normal; font-weight: 700; }
.mg-done li.lost em { color: #8a5a2a; font-style: normal; }
.mg-done .mg-what { flex: 1; text-align: left; }

.calm-line { margin: 8px 0; padding: 6px 10px; border: 1px solid var(--line); border-radius: 8px; background: var(--panel); }
.calm-line small { display: block; color: var(--muted); }
.calm-line .good { color: #2f7a3a; } .calm-line .bad { color: #b23a2a; }

/* The version in the title bar, and «Có gì mới». */
.ver-badge { margin-left: 4px; padding: 2px 9px; border-radius: 999px; border: 1px solid #6b4a2a; background: transparent; color: #cdb98f; font: 600 11.5px var(--font-body); cursor: pointer; }
.ver-badge.fresh { color: #1c100a; background: #e2b45a; border-color: #ffd98a; animation: pp-pulse 1.4s ease-in-out 3; }
.ver-badge[hidden] { display: none; }
.news-box { max-width: 620px; max-height: calc(100vh - 40px); max-height: calc(100dvh - 40px); overflow-y: auto; }
.news-rel h3 { margin: 12px 0 4px; font-size: 16px; }
.news-rel h3 small { color: var(--muted); font-weight: 400; font-size: 12px; }
.news-rel .news-now { font-style: normal; font-size: 11px; color: #fff; background: #2f7a3a; border-radius: 999px; padding: 1px 8px; }
.news-rel ul { margin: 0; padding-left: 18px; line-height: 1.5; }
.news-box { text-align: left; } .news-rel h3 { text-align: left; }

/* The keeper's announcement. */
.notice-box { max-width: 560px; text-align: left; }
.notice-body { line-height: 1.6; margin: 8px 0 14px; }
/* Every popup fits the screen: what does not fit scrolls inside the box (a phone held either way),
   with its buttons kept in sight at the bottom. */
.overlay.dialog .overlay-box { max-height: calc(100vh - 32px); max-height: calc(100dvh - 32px); overflow-y: auto;
  overscroll-behavior: contain; -webkit-overflow-scrolling: touch; box-sizing: border-box;
  scrollbar-width: thin; scrollbar-color: var(--gold, #b8892e) transparent; }
.overlay.dialog .overlay-box::-webkit-scrollbar { width: 8px; }
.overlay.dialog .overlay-box::-webkit-scrollbar-thumb { background: var(--gold, #b8892e); border-radius: 8px; border: 2px solid var(--panel); }
.notice-box .notice-acts { position: sticky; bottom: -24px; margin: 0 -24px -24px; padding: 12px 24px 16px;
  background: linear-gradient(to bottom, transparent, var(--panel) 30%); }
@media (max-width: 520px) {
  .overlay.dialog { padding: 10px; }
  .overlay.dialog .overlay-box { padding: 18px 16px; max-height: calc(100dvh - 20px); }
  .notice-box h2 { font-size: 21px; padding-right: 36px; }
  .notice-box .notice-acts { bottom: -18px; margin: 0 -16px -18px; padding: 10px 16px 14px; }
}
.notice-acts { display: flex; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }
#notice-dlg { z-index: 60; }
#ask-dlg { z-index: 80; }
.ask-box { max-width: 440px; width: calc(100% - 32px); text-align: left; }
.ask-box h2 { font-family: var(--font-title); font-size: 21px; margin: 0 0 6px; }
.ask-text { margin: 0 0 12px; line-height: 1.55; color: var(--ink); }
.ask-box input { width: 100%; margin: 0 0 14px; font-size: 15px; }
.ask-box button.danger { background: #8b1e14; }

.notice-own { padding: 8px 10px; margin-bottom: 10px; border-left: 3px solid #a3271c; background: rgba(163, 39, 28, .06); border-radius: 4px; }
.notice-ver { font-size: 15px; margin: 4px 0; }
.notice-ver small { color: var(--muted); font-weight: 400; font-size: 12px; }
.notice-body ul { margin: 0; padding-left: 18px; }
.notice-more { color: var(--muted); font-size: 12.5px; margin: 8px 0 0; }

/* The other boards (Chăm chơi, Góp ý). */
.lb-spans { display: flex; gap: 6px; margin: 4px 0 8px; flex-wrap: wrap; }
.lb-spans button { padding: 3px 12px; border-radius: 999px; border: 1px solid var(--line); background: var(--panel); color: var(--ink); cursor: pointer; font: inherit; font-size: 13px; }
.lb-spans button.on { background: #7a1c14; color: #ffe9b8; border-color: #e2b45a; }
.lb-thanks { padding: 8px 12px; border-left: 3px solid #2f7a3a; background: rgba(47, 122, 58, .08); border-radius: 4px; line-height: 1.55; margin: 4px 0 10px; }

a.ver-badge { text-decoration: none; display: inline-block; line-height: 1.4; }
a.ver-badge:hover { color: #ffe9b8; border-color: #d9ab52; }
.notice-more a { color: #8b2a1a; }

/* Bảng xếp hạng: the kind of board on top, the realms under «Hay nhất». */
.lb-modes { display: flex; gap: 0; margin: 4px 0 10px; border-bottom: 2px solid var(--line); }
.lb-mode { padding: 7px 16px; border: 0; border-bottom: 3px solid transparent; margin-bottom: -2px; background: none; color: var(--muted); cursor: pointer; font: 700 14px var(--font-title); }
.lb-mode.on { color: #8b2a1a; border-bottom-color: #8b2a1a; }
.lb-mode:hover { color: var(--ink); }
.lb-tabs[hidden], .lb-note[hidden] { display: none; }

/* Nhật ký cập nhật, a page under the title bar like the guide. */
.news-page h1 { font-size: 24px; margin: 8px 0 4px; }
.news-lead { color: var(--muted); }
.news-page .news-rel { background: var(--panel); border: 1px solid var(--line); border-radius: 10px; padding: 12px 16px; margin: 12px 0; }
.news-page .news-rel.now { border-left: 4px solid #8b2a1a; }
.news-page .news-rel h2 { font-size: 18px; margin: 0 0 6px; }
.news-page .news-rel ul { margin: 0; padding-left: 20px; line-height: 1.6; }

.lb-champ.heaven { --c: #b8860b; background: linear-gradient(135deg, rgba(226, 180, 90, .25), rgba(163, 39, 28, .08)); }
@media (min-width: 701px) { .lb-champions { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

/* Quốc sự: the realm's affairs on the left, the armies and the offices' work stacked on the right. */
@media (min-width: 901px) {
  #view-state .state-row { grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); }
  #view-state #economy-card { grid-column: 1; grid-row: 1 / span 2; }
  #view-state #army-card { grid-column: 2; grid-row: 1; }
  #view-state #tasks-state-card { grid-column: 2; grid-row: 2; }
}

.pay-help summary { cursor: pointer; color: var(--muted); font-size: 13px; margin: 4px 0; }

/* Under the gold and the grain: what waiting orders will take, and what just changed. */
.res { position: relative; }
.res small.res-due { color: #f0b27a; font-weight: 700; }
.res .res-delta { position: absolute; right: -4px; top: -12px; font: 700 11px/1 var(--font-body); font-style: normal; padding: 1px 5px; border-radius: 999px; white-space: nowrap;
  animation: res-flash 4s ease-out forwards; pointer-events: none; }
.res .res-delta.neg { background: #a3271c; color: #fff; }
.res .res-delta.pos { background: #2f7a3a; color: #fff; }
@keyframes res-flash { 0% { opacity: 0; transform: translateY(4px); } 10% { opacity: 1; transform: none; } 75% { opacity: 1; } 100% { opacity: 0; } }

/* Sổ thu chi. */
.ledger { margin: 8px 0; border: 1px solid var(--line); border-radius: 8px; background: var(--panel); padding: 6px 10px; }
.ledger summary { cursor: pointer; font: 700 14px var(--font-title); }
.ledger summary small { font: 400 12px var(--font-body); color: var(--muted); margin-left: 6px; }
.ledger .good { color: #2f7a3a; } .ledger .bad { color: #b23a2a; }
.ledger-years { display: flex; gap: 4px; flex-wrap: wrap; margin: 6px 0; }
.ledger-years button { padding: 2px 10px; border-radius: 999px; border: 1px solid var(--line); background: none; color: var(--ink); cursor: pointer; font: inherit; font-size: 12px; }
.ledger-years button.on { background: #7a1c14; color: #ffe9b8; border-color: #e2b45a; }
.ledger-t { width: 100%; border-collapse: collapse; font-size: 13px; }
.ledger-t th, .ledger-t td { padding: 3px 6px; border-bottom: 1px dashed var(--line); }
.ledger-t th { text-align: left; color: var(--muted); font-weight: 600; }
.ledger-t .num { text-align: right; white-space: nowrap; }
.ledger-t .lt-edge td { background: rgba(217, 171, 82, .12); }
.ledger-t .lt-sum td { font-weight: 600; }
.ledger-t .lt-due td { color: #b06a1a; }

/* Bày trận: the next move after the battle, and the relief when attacked. */
.mu-relief { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; font-size: 13px; }
.mu-relief label { display: inline-flex; align-items: center; gap: 4px; }
.mu-relief small { opacity: .8; }
.mu-relief .mu-call { padding: 3px 12px; }

/* The players' group, always shown in the notice. */
.notice-group { display: flex; gap: 12px; align-items: center; margin: 4px 0 12px; padding: 10px; border: 1px solid var(--line); border-radius: 10px; background: rgba(0, 132, 255, .06); }
.notice-group img { width: 120px; height: 120px; border-radius: 8px; background: #fff; flex: none; }
.notice-group p { margin: 4px 0 8px; font-size: 13px; line-height: 1.45; }
.notice-group small { display: block; color: var(--muted); margin-top: 4px; font-size: 12px; }
.notice-join { display: inline-block; padding: 5px 14px; border-radius: 999px; background: #0084ff; color: #fff !important; text-decoration: none; font-weight: 700; }
@media (max-width: 520px) { .notice-group img { width: 90px; height: 90px; } }

/* Boxes that keep their light parchment whatever the phone's theme (a dark-mode phone included):
   their words stay dark ink too, or they are light letters on light paper and cannot be read. */
.pp-res, .pp-land, .pp-fort, .pp-people, .pp-hold, .pp-hold-chip, .pp-gov, .pp-gov-acts select, .pp-gov label,
.army-form input, .army-form select, .raise-form input, .raise-form select,
.auth-form input, .pw-box input, .lb-champ, #fb-message, .dn-bank, .punish-menu, .gd-fig, .guide .first-year {
  color: #2a1d12;
}
.pp-gov small, .pp-hold small, .lb-champ small, .punish-menu small, .dn-bank small { color: #6b5a45; }
.pp-gov .bad { color: #9c2b22; }
.pp-res { background: #e4efcf; border-color: #9fbf72; }
.pp-fort, .pp-people { background: #f3ead6; }
body:has(#battle:not([hidden])) .map3d-fab { display: none !important; }

/* The war table on a phone held sideways (a short screen): the head scrolls away and the foot is
   one short row (a small gauge beside the orders), as on a phone held upright, so the plans show. */
@media (orientation: landscape) and (max-height: 540px) {
  .mu-head { position: static; }
  .mu-foot { grid-template-columns: auto 1fr; justify-items: stretch; align-items: center; gap: 8px; padding: 6px 10px; }
  .mu-gauge svg { width: 90px; }
  .mu-gauge .mu-chance { margin-top: -6px; }
  .mu-gauge .mu-chance span { font-size: 9px; letter-spacing: .06em; }
  .mu-gauge b, .mu-gauge strong { font-size: 13px; }
  .mu-notes { display: none; }
  .mu-actions { justify-content: flex-end; flex-wrap: wrap; gap: 6px; }
  .mu-actions .mu-go { font-size: 15px; padding: 8px 14px; }
  .mu-actions .mu-error { flex-basis: 100%; margin: 0; font-size: 12px; }
}

/* Sound and voice: on or off said in words, not by fading the button (a faded button looks broken). */
.settings-menu button[aria-pressed="false"] { opacity: 1 !important; color: #cdb791 !important; }
.settings-menu button[aria-pressed]::after { font-size: 12px; margin-left: 6px; }
.settings-menu button[aria-pressed="true"]::after { content: "· đang bật"; color: #9fd08f; }
.settings-menu button[aria-pressed="false"]::after { content: "· đang tắt"; color: #e0a090; }

/* Chợ hàng hóa */
.mk-stores { display: flex; flex-wrap: wrap; gap: 6px 12px; font-size: 13px; margin-bottom: 8px; }
.mk-stores span { padding: 2px 8px; border-radius: 999px; background: rgba(184,137,46,.12); border: 1px solid var(--line); }
.mk-stores .bad { background: rgba(163,39,28,.12); color: #9c2b22; }
.mk-form { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px 10px; font-size: 13px; }
.mk-form label { display: grid; gap: 3px; color: var(--muted); }
.mk-form .mk-price, .mk-form .mk-total, .mk-form .mk-acts { grid-column: 1 / -1; }
.mk-form .mk-price b { color: var(--ink); }
.mk-total { margin: 0; color: var(--ink); }
.mk-word { font-weight: 700; margin-left: 4px; }
.mk-word.good { color: #2f7a3a; }
.mk-word.bad { color: #9c2b22; }
.mk-unknown { color: var(--muted); font-style: italic; }
.mk-acts { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.mk-acts small { color: var(--muted); flex: 1 1 200px; }
@media (max-width: 560px) { .mk-form { grid-template-columns: 1fr; } }

/* Parchment boxes keep dark ink in a dark-mode phone (their notes too); the market's warnings read on the dark card. */
.pp-gov .pp-note, .pp-gov .pp-gov-effect, .pp-store .pp-note { color: #6b5a45; }
.pp-gov .pp-gov-effect { color: #2a1d12; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .pay-dial { background: rgba(255, 255, 255, .06); color: var(--ink); }
  :root:not([data-theme="light"]) .mk-word.bad, :root:not([data-theme="light"]) .mk-stores .bad { color: #ff8a7a; }
  :root:not([data-theme="light"]) .mk-word.good { color: #8fd28a; }
  :root:not([data-theme="light"]) #market-card .pp-warn { color: #ffb08a; }
}

/* The flat map takes the finger itself (drag to move, pinch to zoom: app.js flatView), not the page. */
.game.lobby #map { touch-action: none; cursor: grab; }

/* The side column over the board is only a frame: touches pass through it to the map, except on
   what it holds (the province's panel, the guard's news). */
.game.lobby .map-side, .game.lobby .map-side > #province-info { pointer-events: none; }
.game.lobby .map-side .pp, .game.lobby .map-side .lobby-alerts > *, .game.lobby .map-side button { pointer-events: auto; }
