/* sim.css — the Battle Simulator page only (battle-simulator/). Loaded after
   styles.css + events.css (the page's theme block lives there).
   The console: the mode rail that picks the fight, then hero gear's
   workspace — army cards (a tile per troop type, edited in a dialog) beside
   the answer — the OCR prefill, and one ruled output per mode — the bear ratio, your march against the bear,
   the Mystic Trial rooms, and the fight + mix sweep the last two share.

   DIRECTION CONTRACT (extension of the existing surface — one page, one
   world, one signal; no new palette, no new type, no new radii):
   THESIS      one ledger, four fights — the fight changes, the world doesn't.
   OWN-WORLD   the war-room night + antique gold already on this page; the
               rail borrows the .ev-switch recipe, the workspace, tiles and
               dialogs the hero gear planner's, the outputs the ruled
               .sim-head/.sim-row grammar.
   REFUSES     per-mode hue swaps, long input sheets, a hero portrait spine,
               invented brackets, spinners where an honest bench belongs.
   SIGNATURE   one report read once, then re-answered per fight; the mix
               triangle draws every march you could send on one ruled grid.
   STATES      first-run · importing · unreadable · sweeping · re-run after an edit ·
               no winning mix · language switch · 320px → desktop. */

/* ─── The model gloss — a community engine, said plainly ─ */
.draft-note {
  margin-top: var(--space-s);
  max-width: 34rem;
  font-size: var(--step--1);
  font-style: italic;
  color: var(--ink-dim);
}
.draft-note b {
  color: var(--ink);
  font-style: normal;
  font-weight: 700;
}

/* ─── The input rows — two labelled fields per troop type ──
   Each calc-row is "Infantry  [Attack %  input] [Lethality %  input]".
   On desktop the field group takes the same 55% the other calculators give
   their controls, so the label keeps the same rhythm. */
.sim-fields {
  display: flex;
  gap: 0.6rem;
  flex-wrap: wrap;
  min-width: 0;
}
.sim-field {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  min-width: 5.5rem;
}
.sim-field label {
  font-size: 0.82em;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-muted);
}
.sim-field input { width: 100%; }
/* A troop count with its unit (js/unit-input.js) keeps the box and the unit on one line. */
.sim-field:has(.unit-select) { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: 0.4rem; align-items: end; }
.sim-field:has(.unit-select) > span { grid-column: 1 / -1; }
.sim-field .unit-select { width: auto; min-width: 3.4rem; }
@media (min-width: 640px) {
  .calc-row .sim-fields { width: 55%; }
}

/* ─── The output table — ruled rows like the other calculators ──
   Troop | A factor | weight | ideal share. On narrow screens the weight
   column drops — the share is the point. */
.sim-out { margin: var(--space-m) 0; border-top: 1px solid rgba(157, 149, 127, 0.25); }
.sim-head, .sim-row {
  display: grid;
  grid-template-columns: 1fr 5.4rem 5.4rem 6rem;
  gap: 0.7rem;
  align-items: baseline;
  padding: 0.5rem 0;
  border-bottom: 1px solid rgba(157, 149, 127, 0.14);
  font-size: var(--step--1);
}
.sim-head { border-bottom-color: rgba(157, 149, 127, 0.25); }
.sim-head span {
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-muted);
  font-size: 0.9em;
  text-align: right;
}
.sim-head span:first-child { text-align: left; }
.sim-type { font-family: var(--display-2); font-weight: 700; color: var(--ink); }
.sim-a, .sim-w { text-align: right; color: var(--ink-dim); }
.sim-share { text-align: right; color: var(--amber); font-weight: 700; }
/* Every numeric cell is a single figure — never let a locale's grouping mark
   break it across two lines. */
.sim-a, .sim-w, .sim-share, .sim-n { white-space: nowrap; font-variant-numeric: tabular-nums; }
@media (max-width: 640px) {
  .sim-head, .sim-row { grid-template-columns: 1fr 4.6rem 5.4rem; }
  .sim-w { display: none; }
  /* The bare ratio table drops the weight CELL but still emits its header
     span, so the phone read "TROOP | A FACTOR | WEIGHT" with "ideal share"
     orphaned on a second line and the amber shares sitting under WEIGHT. The
     march and rooms tables already drop the matching header; this is the one
     that was missed. */
  .sim-out:not(.march-out):not(.rooms):not(.fight-out):not(.sweep-out) .sim-head span:nth-child(3) { display: none; }
}

/* ─── OCR prefill — button + status ───────────────────── */
.sim-ocr {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-bottom: var(--space-s);
}
.sim-ocr button {
  font-family: var(--body);
  font-size: var(--step--1);
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--amber);
  background: transparent;
  border: 1px solid var(--signal-line);
  border-radius: 2px;
  padding: 0.35rem 0.7rem;
  cursor: pointer;
  transition: color 0.3s cubic-bezier(0.16, 1, 0.3, 1), border-color 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}
.sim-ocr button:hover,
.sim-ocr button:focus-visible {
  color: var(--ink);
  border-color: var(--amber);
}
.sim-ocr-hint {
  font-size: var(--step--1);
  color: var(--ink-muted);
  font-style: italic;
}
.sim-ocr-status {
  display: block;
  margin: var(--space-s) 0;
  font-size: var(--step--1);
  color: var(--ink-dim);
}
.sim-ocr-status.ok { color: var(--amber); }
.sim-ocr-status.busy { color: var(--amber-dim); }
.sim-ocr-status.bad { color: var(--ink-dim); }


/* ─── The mode rail — one fight at a time ──
   The .ev-switch recipe, page-scoped: uppercase body-serif chips, inactive
   recede to ink-muted, the active one takes the signal + a ❧. A bench chip
   carries the italic marginal gloss ("bench") instead of a badge — the
   honest roadmap, not a broken tab. The rail wraps rather than scrolls:
   every fight stays visible, and a horizontal drag on it can't be mistaken
   for the page-swipe gesture. */
.mode-rail {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
  margin: var(--space-s) 0 var(--space-m);
}
.mode-rail a {
  font-family: var(--body);
  font-size: var(--step--1);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--ink-muted);
  padding: 0.3rem 0.55rem;
  border: 1px solid transparent;
  border-radius: 2px;
  transition: color 0.3s cubic-bezier(0.16, 1, 0.3, 1), border-color 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}
.mode-rail a:hover { color: var(--ink-dim); }
.mode-rail a[aria-current="true"] {
  color: var(--amber);
  border-color: var(--signal-line);
}
.mode-rail a[aria-current="true"]::before { content: "❧ "; color: var(--amber-dim); }
.rail-tag {
  font-size: 0.85em;
  font-weight: 400;
  font-style: italic;
  letter-spacing: 0.02em;
  text-transform: none;
  color: var(--ink-muted);
}

/* ─── The loadout: one report sheet, shared by every fight ──
   The twelve Bonus Details values as a ruled sheet. On a bear report the
   left column is the lead's shared stats, so this is the report as read —
   and it stays a form: every cell is editable, the OCR only prefills. */
.load { margin-top: var(--space-s); }

/* The shared sheet ends above; each mode's panel opens its own block, so it
   takes the larger step — more air above the title than below it. */
.sim-panel { margin-top: var(--space-l); }

/* ─── The march verdict — your split against the lead's optimum ──
   Troop | troops | your share | ideal share. The count column drops on
   narrow screens (you typed it); the two shares never do. */
.sim-out.march-out .sim-head, .sim-out.march-out .sim-row { grid-template-columns: 1fr 6.4rem 5.4rem 5.4rem; }
.sim-out.march-out .sim-n { text-align: right; color: var(--ink-dim); font-variant-numeric: tabular-nums; }
@media (max-width: 660px) {
  .sim-out.march-out .sim-head, .sim-out.march-out .sim-row { grid-template-columns: 1fr 5rem 5.4rem; }
  .sim-out.march-out .sim-n,
  .sim-out.march-out .sim-head span:nth-child(2) { display: none; }
}

/* ─── The Mystic rooms — one row a room ──
   Room (+ its weekday gloss) | what it checks | starting ratio | first
   alternate. Rooms open today take the ❧ and the signal; the rest stay ink.
   On a phone the checks line drops under the name and spans the row. */
.sim-out.rooms .sim-head, .sim-out.rooms .sim-row { grid-template-columns: 9.5rem 1fr 5rem 5rem; gap: 0.6rem; }
.sim-out.rooms .sim-head span:nth-child(2) { text-align: left; }
.sim-out.rooms .room-name { grid-column: 1; }
.sim-out.rooms .room-checks { grid-column: 2; }
.sim-out.rooms .room-ratio { grid-column: 3; }
.sim-out.rooms .room-alt { grid-column: 4; }
.room-name { font-family: var(--display-2); font-weight: 700; color: var(--ink); }
.room-days {
  display: block;
  font-family: var(--body);
  font-size: 0.78em;
  font-weight: 400;
  font-style: italic;
  letter-spacing: 0;
  color: var(--ink-muted);
}
.room-checks { color: var(--ink-dim); }
.room-ratio, .room-alt { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
/* The ratio cells are the tightest thing in any table here — an unbreakable
   "55 / 15 / 30" has to clear a phone, so they step down a size below 660px. */
@media (max-width: 660px) {
  .room-ratio, .room-alt { font-size: 0.85em; }
}
.room-ratio { color: var(--amber); font-weight: 700; }
.room-alt { color: var(--ink-dim); }
.sim-out.rooms .sim-row.today .room-name { color: var(--amber); }
.sim-out.rooms .sim-row.today .room-name::before { content: "❧ "; color: var(--amber-dim); }
.room-today {
  display: block;
  font-family: var(--body);
  font-size: 0.78em;
  font-weight: 700;
  font-style: normal;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--amber);
}
@media (max-width: 660px) {
  .sim-out.rooms .sim-head { grid-template-columns: 1fr 4.4rem 4.4rem; }
  .sim-out.rooms .sim-head span:nth-child(2) { display: none; }
  .sim-out.rooms .sim-row { grid-template-columns: 1fr 4.4rem 4.4rem; row-gap: 0; }
  .sim-out.rooms .room-name { grid-column: 1; grid-row: 1; }
  .sim-out.rooms .room-ratio { grid-column: 2; grid-row: 1; }
  .sim-out.rooms .room-alt { grid-column: 3; grid-row: 1; }
  .sim-out.rooms .room-checks { grid-column: 1 / -1; grid-row: 2; }
}

/* ─── Bench modes — the missing piece, said plainly ──
   Not a spinner and not a disabled tab: the rubrication red this page
   already uses for proof marks, on the one note that names what the mode
   is waiting for. */
.note.bench { color: var(--rubric); }
.note.bench b { color: var(--ink); }

.mode-rail a { display: inline-flex; align-items: center; min-height: 44px; gap: 0.35rem; }
.sim-ocr button, .sim-field input, .sim-field select { min-height: 44px; }
.sim-field input:focus-visible, .sim-field select:focus-visible { outline: 2px solid var(--amber); outline-offset: 3px; }
.sim-row > span, .sim-head > span { min-width: 0; overflow-wrap: anywhere; }
.sim-head span:first-child { text-align: start; }
.sim-a, .sim-w, .sim-share, .sim-n { text-align: end; }

/* Ratios keep infantry / cavalry / archer order in every reading direction.
   Font-sized tracks accommodate localized digits and align headers with rows. */
.room-ratio, .room-alt { direction: ltr; unicode-bidi: isolate; }
.sim-out.rooms .sim-head, .sim-out.rooms .sim-row {
  grid-template-columns: 9.5rem minmax(0, 1fr) 5.3em 5.3em;
}
@media (max-width: 660px) {
  .sim-out.rooms .sim-head, .sim-out.rooms .sim-row {
    grid-template-columns: minmax(0, 1fr) 4.4em 4.4em;
  }
}

.sim-out.rooms .sim-head span:nth-child(2) { text-align: start; }

/* ─── The fight — the battle half of the console ──
   Same ruled grammar as the other tables. Nothing here takes a new colour;
   the opponent's numbers stay ink, yours take the signal. */
.sim-total { margin-top: var(--space-s); }
.mix { direction: ltr; unicode-bidi: isolate; white-space: nowrap; font-variant-numeric: tabular-nums; }

.fight { margin-top: var(--space-l); }
.fight .calc-title + .calc-out { margin-top: var(--space-s); }
.fight .sim-out + .calc-title { margin-top: var(--space-l); }

/* The fight: troop | you | left | them | left. Your survivors in the signal,
   theirs in ink; the total row closes the ledger with a heavier rule. */
.sim-out.fight-out .sim-head, .sim-out.fight-out .sim-row { grid-template-columns: minmax(6.5rem, 1fr) repeat(4, minmax(3.4rem, 5.2em)); }
.sim-left-foe { text-align: end; color: var(--ink); white-space: nowrap; font-variant-numeric: tabular-nums; }
.sim-out .sim-n { text-align: end; color: var(--ink-dim); }
.sim-row.sim-sum { border-top: 1px solid rgba(157, 149, 127, 0.25); }
.sim-row.sim-sum .sim-type { color: var(--ink-dim); }
/* Narrow: the starting counts are on the sheets just above, so the table
   keeps only who is left — "you" and "them" head the two survivor columns. */
@media (max-width: 560px) {
  .sim-out.fight-out .sim-head, .sim-out.fight-out .sim-row { grid-template-columns: minmax(0, 1fr) 6em 6em; }
  .sim-out.fight-out .sim-row > .sim-n,
  .sim-out.fight-out .sim-head span:nth-child(3),
  .sim-out.fight-out .sim-head span:nth-child(5) { display: none; }
}

/* The sweep settings — six small fields that wrap, three to a phone row. */
.sweep-set {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(6.4rem, 1fr));
  gap: 0.6rem 0.9rem;
  margin: var(--space-s) 0;
}
.sweep-set .sim-field { min-width: 0; }
.sweep-set select {
  width: 100%;
  padding: 0.35rem 0;
  font-family: var(--body);
  font-size: var(--step-0);
  color: var(--ink);
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--ink-muted);
  border-radius: 0;
}
.sweep-set select:focus { border-bottom-color: var(--amber); outline: none; }
.sweep-set option { background: var(--void-2); color: var(--ink); }
.sweep-set input { text-align: end; font-variant-numeric: tabular-nums; }
.sim-ocr button:disabled { color: var(--ink-muted); border-color: rgba(157, 149, 127, 0.25); cursor: not-allowed; }

/* The triangle — every mix on one ruled grid. Square rule cells in the
   signal, opacity for the win chance; the best mix gets a ruled frame and
   the ❧, the picked room's starting ratio a hairline ring. */
.tri { margin: var(--space-m) 0 var(--space-s); }
.tri svg { display: block; width: 100%; max-width: 26rem; height: auto; margin: 0 auto; overflow: visible; }
.tri-frame { fill: none; stroke: var(--ink-muted); stroke-width: 1; stroke-opacity: 0.5; }
.tri-cell { fill: var(--amber); }
.tri-best { fill: none; stroke: var(--ink); stroke-width: 1.2; }
.tri-room { fill: none; stroke: var(--ink-dim); stroke-width: 1; stroke-dasharray: 2 2; }
.tri-fleuron { fill: var(--ink); font-size: 14px; }
.tri-label {
  fill: var(--ink-muted);
  font-family: var(--body);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.tri figcaption {
  max-width: 34rem;
  margin: var(--space-s) auto 0;
  font-size: var(--step--1);
  font-style: italic;
  color: var(--ink-dim);
  text-align: center;
}
.tri figcaption b { color: var(--ink); font-style: normal; }

/* Top mixes: mix | win chance | left standing. */
.sim-out.sweep-out .sim-head, .sim-out.sweep-out .sim-row { grid-template-columns: minmax(0, 1fr) 6.4em 7em; }
.sim-out.sweep-out .mix { color: var(--ink); font-family: var(--display-2); font-weight: 700; }

/* The rooms are buttons now — tap one to test its starting ratio. They keep
   the room-name type; only the focus ring and the picked state are new. */
.room-pick {
  font: inherit;
  color: inherit;
  text-align: start;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  text-decoration: underline;
  text-decoration-color: rgba(157, 149, 127, 0.35);
  text-underline-offset: 0.2em;
}
.room-pick:hover, .room-pick:focus-visible { text-decoration-color: var(--amber); }
.room-pick:focus-visible { outline: 2px solid var(--amber); outline-offset: 3px; }
.sim-out.rooms .sim-row.picked .room-name { color: var(--ink); }
.sim-out.rooms .sim-row.picked .room-pick { text-decoration-color: var(--amber); text-decoration-thickness: 2px; }


/* ─── Your troops — the troop-roster module ───────────── */
/* A dialog off your card: one fieldset per type, one row per tier you own
   (tier, TG, count, remove). Rows are cloned from a <template> and keyed by
   their ledger id. */
.roster-type { border: 0; padding: 0; margin: var(--space-s) 0 0; min-width: 0; }
.roster-type > legend { font-family: var(--display-2); font-weight: 700; color: var(--ink); padding: 0; }
.roster-rows { list-style: none; margin: 0; padding: 0; }
.roster-row {
  display: grid;
  grid-template-columns: 4.4rem 4rem minmax(0, 1fr) 2.75rem;
  gap: 0.5rem;
  align-items: end;
  padding-block: 0.35rem;
  border-bottom: 1px solid rgba(157, 149, 127, 0.15);
}
.roster-row .sim-field { min-width: 0; }
.roster-row .sim-field > span {
  font-size: 0.72em;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-muted);
}
.roster-row input,
.roster-row select {
  width: 100%;
  padding: 0.35rem 0;
  font-family: var(--body);
  font-size: var(--step-0);
  font-variant-numeric: tabular-nums;
  text-align: right;
  color: var(--ink);
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--ink-muted);
  border-radius: 0;
}
.roster-row input::placeholder { color: var(--ink-muted); opacity: 1; }
.roster-row option { background: var(--void-2); color: var(--ink); }
.roster-row input:focus-visible,
.roster-row select:focus-visible { outline: 2px solid var(--amber); outline-offset: 3px; }
.roster-add,
.roster-remove {
  min-height: 44px;
  font-family: var(--body);
  font-weight: 700;
  color: var(--amber);
  background: transparent;
  border: 1px solid var(--signal-line);
  border-radius: 2px;
  cursor: pointer;
}
.roster-add { margin-top: 0.5rem; padding: 0.35rem 0.7rem; font-size: var(--step--1); letter-spacing: 0.06em; }
.roster-remove { font-size: var(--step-0); }
.roster-add:hover, .roster-add:focus-visible,
.roster-remove:hover, .roster-remove:focus-visible { color: var(--ink); border-color: var(--amber); }
.roster-total { display: block; margin-top: var(--space-s); font-size: var(--step--1); color: var(--ink-muted); font-style: italic; }

/* ─── The workspace — hero gear's shape: armies | answer ──
   The console widens to the hero gear planner's 74rem; prose sections keep
   the 46rem measure. Wide, the armies sit beside the answer, ruled apart by
   one hairline. Narrow, a two-tab view rail shows one side at a time. */
.sim-main { max-width: 74rem; }
.sim-main > .section:not(.sim-console) { max-width: 46rem; }
.sim-heading .lede { max-width: 46rem; }
.sim-workspace {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 2.5rem;
  align-items: start;
}
.sim-answer { border-inline-start: 1px solid var(--signal-line); padding-inline-start: 1.5rem; }
.sim-answer > .sim-panel:first-child,
.sim-answer > .sim-panel:not([hidden]) { margin-top: 0; }
.sim-answer > .fight { margin-top: var(--space-m); }
.sim-views { display: none; }

/* The rail and the dialog tabs: the hero gear tab recipe — muted labels,
   the selected one underlined in the signal. */
.sim-views,
.sim-tabs { gap: 0.4rem; border-bottom: 1px solid var(--signal-line); margin: 0.35rem 0 var(--space-s); }
.sim-tabs { display: flex; }
.sim-views button,
.sim-tabs button {
  flex: 1;
  min-width: 0;
  min-height: 44px;
  font: 700 var(--step--1) var(--body);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-muted);
  background: transparent;
  border: 0;
  border-bottom: 2px solid transparent;
  cursor: pointer;
}
.sim-views button[aria-selected="true"],
.sim-tabs button[aria-selected="true"] { color: var(--amber); border-bottom-color: var(--amber); }
.sim-views button:focus-visible,
.sim-tabs button:focus-visible { outline: 2px solid var(--amber); outline-offset: 3px; }

/* ─── An army card: a heading, then a tile per troop type ── */
.army { margin-top: var(--space-m); }
.army[hidden] { display: none; }
.army-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.2rem 0.8rem; margin-bottom: 0.3rem; }
.army-head h3 { margin: 0; font-family: var(--display-2); font-size: var(--step-1); color: var(--ink); }
.army-head small { font-size: var(--step--1); font-style: italic; color: var(--ink-muted); }
.army-vs {
  margin: var(--space-m) 0 0;
  font-family: var(--display-2);
  font-size: var(--step--1);
  letter-spacing: 0.3em;
  text-transform: uppercase;
  text-align: center;
  color: var(--amber-dim);
}
.army-vs::before, .army-vs::after { content: " ❧ "; color: var(--signal-line); }
.army-tiles { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0 1rem; }
.army-tile {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.15rem;
  width: 100%;
  min-width: 0;
  min-height: 44px;
  padding: 0.6rem 0 0.7rem;
  font: inherit;
  text-align: start;
  color: var(--ink-dim);
  background: transparent;
  border: 0;
  border-bottom: 1px solid rgba(157, 149, 127, 0.18);
  cursor: pointer;
}
.army-tile:hover { border-bottom-color: var(--signal-line); }
.army-tile:hover .army-name { color: var(--amber); }
.army-tile:focus-visible { outline: 2px solid var(--amber); outline-offset: 3px; }
.army-tile[data-empty] .army-art { opacity: 0.4; }
.army-tile[data-empty] .army-count b { color: var(--ink-muted); font-weight: 400; font-style: italic; }
.army-art { display: block; width: 3.6rem; height: auto; aspect-ratio: 1; object-fit: contain; border-radius: 2px; margin-bottom: 0.3rem; }
.army-body { display: flex; flex-direction: column; gap: 0.15rem; min-width: 0; width: 100%; }
.army-name { font-family: var(--display-2); font-weight: 700; color: var(--ink); overflow-wrap: anywhere; }
.army-count { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 0.5rem; }
.army-count[hidden] { display: none; }
.army-count b { font-size: var(--step-1); line-height: 1.2; color: var(--amber); font-variant-numeric: tabular-nums; }
.army-tier { font-size: var(--step--1); color: var(--ink-dim); direction: ltr; unicode-bidi: isolate; white-space: nowrap; }
.army-stats { display: grid; grid-template-columns: repeat(2, max-content); gap: 0 0.7rem; font-size: var(--step--1); color: var(--ink-muted); }
.army-stat { white-space: nowrap; }
.army-stat[hidden] { display: none; }
.army-stat b { font-weight: 400; color: var(--ink-dim); font-variant-numeric: tabular-nums; }

/* Phones see one side at a time: the answer's headline peeks in under the
   armies, and a tap on it opens the answer. */
.sim-peek { display: none; }

/* The player save sits under your card: three margin prompts and a line. */
.sim-ledger { margin-top: var(--space-s); }
.sim-ledger[hidden] { display: none; }
.sim-ledger-actions { display: flex; flex-wrap: wrap; gap: 0 1rem; }
.sim-ledger-actions button,
.sim-dialog-head button {
  min-height: 44px;
  padding: 0.35rem 0.1rem;
  font: 700 var(--step--1) var(--body);
  letter-spacing: 0.04em;
  color: var(--amber);
  background: transparent;
  border: 0;
  border-bottom: 1px solid transparent;
  cursor: pointer;
}
.sim-ledger-actions button:hover,
.sim-dialog-head button:hover { color: var(--ink); border-bottom-color: var(--signal-line); }
.sim-ledger-actions button:disabled { color: var(--ink-muted); cursor: default; border-bottom-color: transparent; }
.sim-ledger-actions button:focus-visible,
.sim-dialog-head button:focus-visible { outline: 2px solid var(--amber); outline-offset: 3px; }
.sim-ledger output { display: block; }

/* ─── The edit dialogs — the hero gear dialog recipe ──── */
.sim-dialog {
  position: fixed;
  inset: 0;
  margin: auto;
  width: min(34rem, calc(100% - 2rem));
  max-height: calc(100vh - 2rem);
  max-height: calc(100dvh - 2rem);
  overflow: auto;
  overscroll-behavior: contain;
  padding: 1.2rem;
  color: var(--ink);
  background: var(--void-2);
  border: 1px solid var(--signal-line);
  border-radius: 2px;
  font: 1rem/1.45 var(--body);
}
.sim-dialog::backdrop { background: rgba(11, 14, 22, 0.82); }
.sim-dialog-head { display: flex; align-items: center; justify-content: space-between; gap: 1rem; }
.sim-dialog-head h2 { margin: 0; font-family: var(--display-2); font-size: var(--step-1); }
.sim-dialog-head h2::before { display: none; }
.sim-gloss { margin: 0.4rem 0 0.6rem; font-size: var(--step--1); color: var(--ink-dim); }
.sim-gloss b { color: var(--ink); }
.sim-dialog .note { font-size: var(--step--1); }
.sim-troop { display: grid; grid-template-columns: 5rem minmax(0, 1fr); gap: 0.4rem 1rem; align-items: start; }
.sim-troop[hidden] { display: none; }
.sim-troop > .army-art { grid-row: span 2; }
.sim-troop fieldset {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.6rem 1rem;
  min-width: 0;
  margin: 0;
  padding: 0 0 0.8rem;
  border: 0;
}
.sim-troop fieldset[hidden] { display: none; }
.sim-troop legend {
  padding: 0 0 0.3rem;
  font-size: 0.82em;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--amber-dim);
}
.sim-troop .sim-count { grid-column: 1 / -1; }
.sim-troop .sim-field { min-width: 0; }
.sim-troop .sim-field[hidden] { display: none; }
.sim-troop .sim-field > span { font-size: 0.82em; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-muted); }
.sim-troop input,
.sim-troop select {
  width: 100%;
  padding: 0.35rem 0;
  font-family: var(--body);
  font-size: var(--step-0);
  font-variant-numeric: tabular-nums;
  text-align: end;
  color: var(--ink);
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--ink-muted);
  border-radius: 0;
}
.sim-troop input:focus, .sim-troop select:focus { border-bottom-color: var(--amber); outline: none; }
.sim-troop input:focus-visible, .sim-troop select:focus-visible { outline: 2px solid var(--amber); outline-offset: 3px; }
.sim-troop input::placeholder { color: var(--ink-muted); opacity: 1; }
.sim-troop option { background: var(--void-2); color: var(--ink); }

/* The answer's glosses fold away: the figure first, the why on request. */
.sim-why { margin: var(--space-s) 0; }
.sim-why > summary,
.sim-ledger > summary {
  min-height: 44px;
  display: flex;
  align-items: center;
  gap: 0.4rem;
  cursor: pointer;
  font-size: var(--step--1);
  font-style: italic;
  color: var(--amber);
}
.sim-why > summary::marker,
.sim-ledger > summary::marker { color: var(--amber-dim); }
.sim-why > summary:focus-visible,
.sim-ledger > summary:focus-visible { outline: 2px solid var(--amber); outline-offset: 3px; }
.sim-why[hidden] { display: none; }

/* Narrow: one side at a time, picked on the view rail, and the console
   starts within the first screen. The hero keeps its title, the model
   gloss and its die; the two ledes give way, since the tiles and the
   screenshot button say the same thing by being there. */
@media (max-width: 860px) {
  .sim-main .hero { padding: var(--space-m) 0 var(--space-s); }
  .sim-main .hero h1 { font-size: clamp(2rem, 9vw, 2.6rem); }
  .sim-main .hero .lede,
  .sim-main .hero .chips,
  .sim-heading .lede { display: none; }
  .sim-heading h2 {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }
  .sim-console { padding-top: 0; }

  /* The four fights as one row of tabs, like the view rail below them. */
  .mode-rail { flex-wrap: nowrap; gap: 0; margin: 0.4rem 0 0.5rem; border-bottom: 1px solid var(--signal-line); }
  .mode-rail a {
    flex: 1;
    min-width: 0;
    justify-content: center;
    text-align: center;
    padding: 0.3rem 0.15rem;
    font-size: 0.78rem;
    letter-spacing: 0.03em;
    line-height: 1.15;
    overflow-wrap: anywhere;
    hyphens: auto;
    border: 0;
    border-bottom: 2px solid transparent;
    border-radius: 0;
  }
  .mode-rail a[aria-current="true"] { border-bottom-color: var(--amber); }
  .mode-rail a[aria-current="true"]::before { content: none; }

  .sim-workspace { display: block; }
  .sim-answer { border-inline-start: 0; padding-inline-start: 0; }
  .sim-views { display: flex; margin-top: 0; border: 1px solid var(--signal-line); }
  .sim-views button[aria-selected="true"] { background: color-mix(in srgb, var(--amber) 8%, transparent); }
  #console[data-view="armies"] .sim-answer,
  #console[data-view="answer"] .sim-armies { display: none; }

  .sim-ocr { margin-bottom: 0.2rem; }
  #sim-load > .sim-ocr .sim-ocr-hint { display: none; }
  .army { margin-top: var(--space-s); }
  .army-vs { margin-top: var(--space-s); }

  /* The answer's headline rides along the bottom of the screen while the
     armies are edited; a tap opens the full answer. */
  .sim-peek {
    position: sticky;
    bottom: 0;
    z-index: 2;
    display: block;
    width: 100%;
    margin-top: var(--space-s);
    padding: 0.55rem 0.8rem;
    font: inherit;
    font-size: var(--step--1);
    line-height: 1.35;
    text-align: start;
    color: var(--ink-dim);
    background: color-mix(in srgb, var(--amber) 9%, var(--void-2));
    border: 1px solid var(--signal-line);
    border-radius: 2px;
    cursor: pointer;
  }
  .sim-peek b { color: var(--amber); }
  .sim-peek:focus-visible { outline: 2px solid var(--amber); outline-offset: 3px; }
  .sim-peek-go { display: block; margin-top: 0.15rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--amber); }
}

@media (max-width: 360px) {
  .mode-rail a { font-size: 0.7rem; letter-spacing: 0; }
}

/* Phones: a tile is one row, the art beside two lines — name and count,
   then the stats — so a whole army fits in a third of the screen. */
@media (max-width: 560px) {
  .army-tiles { grid-template-columns: minmax(0, 1fr); }
  .army-tile {
    display: grid;
    grid-template-columns: 2.6rem minmax(0, 1fr);
    column-gap: 0.7rem;
    align-items: center;
    padding: 0.4rem 0;
  }
  .army-art { width: 100%; margin: 0; }
  .army-body { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 0 0.6rem; align-items: baseline; }
  .army-name { grid-column: 1; grid-row: 1; }
  .army-count { grid-column: 2; grid-row: 1; justify-content: flex-end; }
  .army-count b { font-size: var(--step-0); }
  .army-stats { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 0 0.8rem; }
  .sim-troop { grid-template-columns: minmax(0, 1fr); }
  .sim-troop > .army-art { display: none; }

  /* The six rooms as a two-up grid of cards: name, days, starting ratio,
     what the room checks. The first fallback stays on wide screens. */
  .sim-out.rooms { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 1rem; }
  .sim-out.rooms .sim-head { display: none; }
  .sim-out.rooms .sim-row { display: flex; flex-direction: column; align-items: flex-start; gap: 0.1rem; padding: 0.5rem 0; }
  .sim-out.rooms .room-name { order: 1; }
  .sim-out.rooms .room-ratio { order: 2; text-align: start; }
  .sim-out.rooms .room-checks { order: 3; font-size: 0.9em; color: var(--ink-muted); }
  .sim-out.rooms .room-alt,
  .sim-out.rooms .room-today { display: none; }
}
.sim-peek[hidden] { display: none; }
.sim-ocr-status[hidden] { display: none; }
/* The answer tab scrolls into view below the sticky contents bar. */
.sim-views { scroll-margin-top: 7rem; }

.sim-main .hero { padding: var(--space-m) 0 var(--space-s); }
.sim-main .hero h1 { font-size: clamp(2rem, 5vw, 2.6rem); }
.sim-main .hero .lede, .sim-main .hero .chips, .sim-heading { display: none; }
.sim-console { padding-top: 0; }
.sim-main .hero .draft-note { max-width: 46rem; margin-bottom: 0; }
.sim-main .hero .ascii-motif-rail { margin-top: 0.35rem; }
.sim-run-metrics { display: block; font-size: var(--step--1); font-variant-numeric: tabular-nums; color: var(--ink-dim); }
.sim-run-metrics[hidden], #sim-sweep-progress[hidden] { display: none; }
#sim-sweep-progress { display: block; width: 100%; height: 0.5rem; margin: 0.6rem 0; accent-color: var(--amber); }
#sim-sweep-progress::-webkit-progress-bar { background: var(--void-2); }
#sim-sweep-progress::-webkit-progress-value { background: var(--amber); }
#sim-sweep-progress::-moz-progress-bar { background: var(--amber); }
@media (max-width: 860px) {
  .sim-workspace .sim-why { margin-block: 0.25rem; }
  .sim-workspace .fight { margin-top: 0.5rem; }
}

/* The answer reads as one calm column: the panels' "try it" titles are for
   screen readers, the two section labels sit in sentence case, and the folds
   are quiet lines under the figures rather than a stack of headings. */
.sim-panel-title {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}
.sim-answer .calc-title {
  margin: var(--space-m) 0 0.2rem;
  font-size: var(--step-0);
  letter-spacing: 0.02em;
  text-transform: none;
  color: var(--ink);
}
.sim-answer .fight > .calc-title:first-child { margin-top: 0; }
.sim-label { margin: var(--space-s) 0 0.1rem; font-size: var(--step--1); color: var(--ink-dim); }
.sim-workspace .sim-why > summary,
.sim-workspace .sim-ledger > summary {
  padding: 0;
  font-weight: 400;
  font-style: normal;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-muted);
}
.sim-workspace .sim-why[open] > summary,
.sim-workspace .sim-ledger[open] > summary { color: var(--ink-dim); }

/* The run meter sits under the button: the bar, then the live line with the
   forge working beside it while the sweep runs. */
.sim-run { display: flex; flex-wrap: wrap; align-items: center; gap: 0 0.6rem; }
.sim-run #sim-sweep-progress { flex: 1 1 100%; margin-bottom: 0.3rem; }
.sim-run .sim-run-metrics { flex: 1 1 auto; min-width: 0; }
#console[data-run="running"] .sim-run .ascii-hammer-loader { display: inline-block; }
/* The last answer stays up, dimmed, while the next one is fought. */
.sweep-result[data-stale] { opacity: 0.45; }

@media (max-width: 560px) {
  /* The six rooms as chips: name and starting ratio, the whole chip the
     button. What each room checks is in the notes below. */
  .sim-out.rooms { gap: 0.4rem; margin: 0.3rem 0 0; border-top: 0; }
  .sim-out.rooms .sim-row {
    position: relative;
    gap: 0;
    min-height: 44px;
    padding: 0.35rem 0.6rem;
    border: 1px solid var(--signal-line);
    border-radius: 2px;
  }
  .sim-out.rooms .room-name { font-size: 0.92em; }
  .sim-out.rooms .sim-row.today { border-color: var(--amber-dim); }
  .sim-out.rooms .sim-row.today .room-name::before { content: none; }
  .sim-out.rooms .room-checks,
  .sim-out.rooms .room-days { display: none; }
  .sim-out.rooms .sim-row.picked { border-color: var(--amber); background: color-mix(in srgb, var(--amber) 10%, transparent); }
  .sim-out.rooms .room-pick { text-decoration: none; }
  .sim-out.rooms .room-pick::after { content: ""; position: absolute; inset: 0; }
  .tri svg { max-width: 18rem; }
}
