/* Hold workspace chrome on the Deep Ledger tokens (hold-theme.css, loaded first; app.css second).
   Geometry: Services/WorkspaceLayout.cs and DESIGN.md §2 with the 2026-10-05 layout revision — full-width 56 px top bar,
   map panel (top 56, 316×192) and outliner (top 254 to bottom 58) in the right column, alert orbs at left 4 / top 62,
   tool bar bottom-left, ledger bar bottom-right. The map fills the viewport; every panel floats over it.
   Spacing follows the mock literally where the scale allows (6 px panel padding, 2 px row gaps, 46 px tools, 40 px orbs).
   Layers: map 0 (the map host isolates the renderer's nameplates, map.css) · readout/banners 4–5 · panels 10–11 ·
   top bar 12 · ledger scrim/window 30 · ledger bar 32 · error notice 40 · tooltip 50 (.dh-tip). */

.workspace-layout { position: fixed; inset: 0; height: 100dvh; overflow: hidden; background: var(--ink-1); }
.hold-game { position: absolute; inset: 0; overflow: hidden; --cover-left: 0px; --cover-top: 0px; --cover-right: 0px; --cover-bottom: 0px; }
.hold-game [hidden] { display: none !important; }

/* UI symbols come from the "Pixelify Sans" family too: its Unifont face (hold-theme.css) covers exactly the glyphs Pixelify
   lacks, so no symbol falls back to a system font. */
.dh-glyph { line-height: 1; }
/* The selected-row outline (0,2,0) must not hide the keyboard focus ring. */
.dh-row:focus-visible { outline: 2px solid var(--warn); outline-offset: 2px; }
.dh-tool:disabled { background: var(--slot); color: var(--text-3); cursor: not-allowed; }

/* ---------------------------------------------------------------- map, readout, banners */
.workspace-body { position: absolute; inset: 0; overflow: hidden; }
.workspace-map, .hold-game .map-shell, .hold-game .map-host { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; overflow: hidden; }
.workspace-map.covered { visibility: hidden; pointer-events: none; }
.hold-game .map-diagnostic { top: 62px; left: 52px; z-index: 1; }
.hold-game .map-shell > .notice { position: absolute; z-index: 3; top: 62px; left: 20%; right: 20%; }

/* Hover/selection readout: centred on the uncovered map (the --cover-* vars TerrainMap sets from WorkspaceLayout), 4 px
   above the bottom cover and under the editing banner; on-map colours in both themes (map overlays stay dark). */
.hold-game .map-footer { position: absolute; z-index: 4; left: calc(var(--cover-left) + 4px); right: calc(var(--cover-right) + 4px); bottom: calc(var(--cover-bottom) + 4px);
  display: flex; justify-content: center; padding: 0; border: 0; background: none; pointer-events: none; }
.is-desktop .map-footer > span:first-child { display: none; }
.hold-game .map-footer .queued-action { pointer-events: auto; }
.hold-game .selection-info { max-width: 100%; padding: var(--s-1) var(--s-5); background: var(--onmap-bg); color: #f4f0e0; text-shadow: 1px 1px 0 #000;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.editing-banner { position: absolute; z-index: 5; bottom: calc(var(--cover-bottom) + 31px); left: calc(var(--cover-left) + (100% - var(--cover-left) - var(--cover-right)) / 2);
  transform: translateX(-50%); max-width: calc(100% - var(--cover-left) - var(--cover-right) - 8px);
  display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: var(--s-4); }
.editing-banner > span { color: var(--warn); overflow-wrap: anywhere; }
.editing-banner > button { white-space: nowrap; }

.paused-banner { position: absolute; z-index: 5; top: 56px; left: calc(var(--cover-left) + (100% - var(--cover-left) - var(--cover-right)) / 2);
  transform: translateX(-50%); padding: var(--s-1) var(--s-8); background: var(--ink-0); border: 2px solid var(--gold); border-top: 0;
  color: var(--bad); font-size: var(--fs-xl); white-space: nowrap; pointer-events: none; }

.hold-game > .workspace-alert { position: absolute; z-index: 40; top: 90px; left: calc(var(--cover-left) + 8px); right: calc(var(--cover-right) + 8px);
  max-height: 110px; overflow: auto; margin: 0; pointer-events: none; }
.workspace-empty { position: absolute; z-index: 12; top: 80px; left: 50%; transform: translateX(-50%); width: min(500px, 90%); padding: var(--s-8); }

/* ---------------------------------------------------------------- top bar */
.workspace-header { position: absolute; z-index: 12; top: 0; left: 0; right: 0; height: 56px; display: flex; align-items: stretch; padding: 0; }
.hold-back { display: flex; flex-direction: column; justify-content: center; min-width: 0; max-width: 260px; padding: 0 var(--s-6);
  flex-shrink: 1; line-height: 1.1; color: var(--text); border-right: 1px solid var(--gold-dark); }
.hold-back h1 { margin: 0; font-size: var(--fs-lg); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hold-back:hover { color: var(--warn); }
.hold-world { font-size: var(--fs-sm); color: var(--text-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.header-states { display: flex; align-items: center; gap: var(--s-6); padding: 0 var(--s-6); flex-shrink: 0; }
.header-count { display: flex; flex-direction: column; align-items: center; gap: var(--s-1); line-height: 1; }
.header-number { font-size: var(--fs-lg); font-variant-numeric: tabular-nums; }
.header-stocks { display: flex; align-items: center; padding: 0 var(--s-4); flex-shrink: 0; }
.header-stocks > .dh-btn { padding: var(--s-1) var(--s-6); }

/* Only whole readouts show: they wrap onto hidden lines instead of being clipped mid-glyph. */
.header-resources { flex: 1; min-width: 0; height: 54px; display: flex; flex-wrap: wrap; align-content: flex-start; gap: 0 var(--s-1);
  padding: 0 var(--s-4); overflow: hidden; }
.header-resource { height: 54px; min-width: 48px; max-width: 112px; flex-shrink: 0; display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 0 var(--s-2); background: none; border: 0; box-shadow: none; color: var(--text); line-height: 1; cursor: help; }
.header-resource:hover { background: var(--row-sel); color: var(--text); }
.header-resource__label { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.header-resource__value { font-size: var(--fs-lg); font-variant-numeric: tabular-nums; }

.header-people { display: flex; align-items: center; padding: 0 var(--s-6); border-left: 1px solid var(--gold-dark); flex-shrink: 0; cursor: help; }
.header-standing { display: flex; align-items: center; gap: var(--s-6); padding: 0 var(--s-6); border-left: 1px solid var(--gold-dark); flex-shrink: 0; cursor: help; }
.header-standing--create { cursor: auto; }
.header-clock { display: flex; align-items: center; gap: var(--s-4); padding: 0 var(--s-6) 0 var(--s-5); border-left: 1px solid var(--gold-dark); flex-shrink: 0; }
.clock-controls { position: relative; display: flex; align-items: center; gap: var(--s-2); }
.clock-play { width: 28px; height: 28px; padding: 0; display: grid; place-items: center; }
.clock-step { height: 28px; padding: 0 var(--s-3); }
.clock-advance, .clock-error { position: absolute; top: calc(100% + 16px); left: 0; margin: 0; padding: var(--s-1) var(--s-4); white-space: nowrap;
  background: var(--ink-0); border: 1px solid var(--gold-dark); font-size: var(--fs-sm); }
.clock-advance { color: var(--info); } .clock-error { color: var(--bad); }
/* The moon is world art, not chrome: same pale disc in both themes, with the orb bevel. */
.header-moon { width: 30px; height: 30px; flex-shrink: 0; border-radius: var(--r-round); background: #dcd8cc; box-shadow: inset -4px -4px 0 #0005, 0 0 0 1px #000; }
.world-time { display: flex; flex-direction: column; justify-content: center; line-height: 1; white-space: nowrap; }
.world-time__time { font-size: var(--fs-xl); font-variant-numeric: tabular-nums; }
.world-time__mode.is-running { color: var(--ok); } .world-time__mode.is-paused { color: var(--bad); }
.world-time__catch { font-size: var(--fs-xs); color: var(--warn); }

.connection-badge { align-self: center; display: block; max-width: 320px; min-width: 0; flex-shrink: 1; padding: 0 var(--s-5);
  color: var(--ok); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.connection-badge.stale { color: var(--warn); }
.connection-badge__light { display: inline-block; width: 8px; height: 8px; margin-right: var(--s-2); background: currentColor; box-shadow: 0 0 0 1px #000; }
.is-narrow .connection-badge:not(.stale) { max-width: 170px; }

.session-menu { position: relative; display: flex; align-items: center; flex-shrink: 0; border-left: 1px solid var(--gold-dark); }
.session-menu > summary { list-style: none; cursor: pointer; padding: var(--s-4) var(--s-6); font-size: var(--fs-xl); }
.session-menu > summary::-webkit-details-marker { display: none; }
.session-menu > .session, .session-menu > p { position: absolute; z-index: 1; right: 0; top: 54px; width: 260px; margin: 0; padding: var(--s-6);
  background: var(--ink-0); border: 2px solid var(--gold); box-shadow: 0 0 0 1px #000, inset 0 0 0 2px var(--ink-0), inset 0 0 0 3px var(--gold-dark);
  display: flex; flex-direction: column; align-items: stretch; gap: var(--s-6); }

/* ---------------------------------------------------------------- alerts (left edge; orbs stay dark in both themes) */
.alert-column { position: absolute; z-index: 10; left: 4px; top: 62px; display: flex; flex-direction: column; gap: var(--s-3); }
[data-theme="light"] .dh-alert { --gold: #c9a43a; --ok: #55ff55; --warn: #f4d03a; --info: #55ffff; --idle: #c0c0c0; --bad: #ff5555; }
.dh-alert { display: grid; place-items: center; }

/* ---------------------------------------------------------------- map panel (hangs from the top bar) */
.map-panel { position: absolute; z-index: 10; top: 56px; right: 0; width: 316px; height: 192px; border-top: 0; border-right: 0;
  padding: var(--s-3) var(--s-2) var(--s-3) var(--s-3); display: flex; flex-direction: column; gap: var(--s-2); }
.map-panel.is-covered { visibility: hidden; }
.map-panel__body { display: flex; gap: var(--s-2); }
.map-panel__modes { display: flex; flex-direction: column; justify-content: space-between; }
.map-mode { width: 32px; height: 34px; min-height: 0; padding: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--s-1);
  background: var(--control); border: 1px solid var(--slot-edge); box-shadow: inset 1px 1px 0 var(--control-hi); color: var(--text); line-height: 1; cursor: pointer; }
.map-mode[aria-pressed="true"] { background: var(--row-sel); border-color: var(--warn); color: var(--warn); }
.map-mode__swatch { width: 18px; height: 8px; box-shadow: 0 0 0 1px #000; }
.map-mode__key { font-size: var(--fs-xs); }
/* 268 × 148 outer (border-box) with a 2 px frame: the renderer's 264 × 144 canvas fills the content box exactly. */
.map-panel__minimap { width: 268px; height: 148px; flex-shrink: 0; border: 2px solid var(--gold-dark); background: var(--ink-1); overflow: hidden; }
.map-panel__minimap canvas { display: block; image-rendering: pixelated; }
/* The floor list keeps its whole name. The row runs under the mode buttons too, since the seven buttons beside the list
   leave too little room in the minimap's width alone. */
.map-panel__zoom { display: flex; align-items: center; justify-content: space-between; gap: var(--s-2); white-space: nowrap; }
.map-panel__floor { display: flex; align-items: center; gap: var(--s-2); min-width: 0; overflow: hidden; }
.map-panel__floor > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.hold-game .map-panel__floor > select { width: auto; height: 24px; padding: 0 var(--s-2); font-size: var(--fs-sm); flex-shrink: 0; }
.map-panel__buttons { display: flex; gap: var(--s-1); flex-shrink: 0; }
.map-panel__buttons > .dh-btn { height: 24px; min-width: 24px; padding: 0 var(--s-2); }

/* ---------------------------------------------------------------- outliner */
.outliner { position: absolute; z-index: 10; top: 254px; right: 0; bottom: 58px; width: 316px; border-right: 0; display: flex; flex-direction: column; }
.outliner__scroll { flex: 1; min-height: 0; overflow: auto; }
.outliner__requests, .outliner__gates { margin-top: var(--s-3); }
.outliner__empty { margin: var(--s-1) 0 0; padding: var(--s-1) var(--s-4); color: var(--text-2); font-size: var(--fs-sm); }
.outliner-row .dh-row__body { padding: var(--s-1) var(--s-4) 3px; }
.outliner-row__line { display: flex; justify-content: space-between; gap: var(--s-3); min-width: 0; }
.outliner-row__name { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.outliner-row__time, .outliner-row__amount { flex-shrink: 0; white-space: nowrap; }
.outliner-row__time { color: var(--text-on-row); }
.outliner-row__sub { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.outliner-request__reason { color: var(--warn); }

/* ---------------------------------------------------------------- inspector frame (position from WorkspaceLayout) */
.workspace-inspector { position: absolute; z-index: 11; display: flex; flex-direction: column; overflow: hidden; visibility: hidden; container-type: inline-size; }
.workspace-inspector.open { visibility: visible; }
.window-header { display: flex; align-items: center; justify-content: space-between; gap: var(--s-4); padding: 0 0 var(--s-3); flex-shrink: 0; }
.window-header h2 { margin: 0; min-width: 0; font-size: var(--fs-xl); color: var(--text-name); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.window-header > div { display: flex; gap: var(--s-2); flex-shrink: 0; }
.window-header .dh-btn { width: 22px; height: 22px; min-height: 22px; padding: 0; line-height: 1; }
.window-body { flex: 1; min-height: 0; overflow: auto; overscroll-behavior: contain; padding-top: var(--s-3); }

/* Panel content (building sheet, management tools) until the sheet restyle. */
.hold-game h3 { font-size: var(--fs-lg); color: var(--gold); margin: var(--s-7) 0 var(--s-5); }
.hold-game h3.dh-head { margin: 0 0 var(--s-3); font-size: var(--fs-md); color: #f4f0e0; text-shadow: 1px 1px 0 #000; }
.hold-game p { font-size: var(--fs-sm); line-height: 1.45; overflow-wrap: anywhere; }
.hold-game label { margin: var(--s-5) 0; font-size: var(--fs-sm); }
.hold-game input, .hold-game select, .hold-game textarea { min-width: 0; width: 100%; }
.hold-game input[type=checkbox] { width: auto; }
.hold-game details { margin: var(--s-6) 0; } .hold-game summary { cursor: pointer; }
.hold-game table { width: 100%; border-collapse: collapse; font-size: var(--fs-xs); margin: var(--s-5) 0; }
.hold-game th, .hold-game td { padding: var(--s-3) var(--s-1); border-bottom: 1px solid var(--gold-dark); text-align: left; overflow-wrap: anywhere; }
.hold-game td input { padding: var(--s-1) var(--s-2); min-width: 40px; }
.hold-game progress { width: 100%; accent-color: var(--warn); }
.hold-game .preview-controls { gap: var(--s-4); margin: var(--s-5) 0; }
.hold-game .source-editor { height: 240px; }
.hold-game .graph-host { position: relative; height: 330px; }
.workspace-inspector.expanded .graph-host { height: 420px; }
.hold-game .graph-host[aria-busy=true]::before { content: 'Laying out behavior…'; position: absolute; z-index: 1; inset: var(--s-6); color: var(--text-2); font-size: var(--fs-sm); }
.hold-game .graph-shell .map-toolbar { position: static; white-space: normal; padding: var(--s-4); border: 0; gap: var(--s-4); }
.hold-game .graph-shell .map-toolbar > div { display: flex; flex-wrap: wrap; justify-content: end; gap: var(--s-2); }
.hold-game .graph-shell .map-toolbar > span { min-width: 60px; overflow-wrap: anywhere; font-size: var(--fs-xs); }
.hold-game .trace-list { max-height: 200px; }
.tools-roads > p, .tools-terrain > p, .hold-game .tools-note { margin: var(--s-3) 0; }
/* Build menu (PlacementControls): tabs that wrap rather than clip, building cards with their sprite on the portrait
   checker, structures as rows. A chosen card or row is marked like a selected row. */
.build-tabs { flex-wrap: wrap; row-gap: var(--s-1); }
.build-tabs .dh-tab { flex: 1 0 auto; }
.build-panel { margin-bottom: var(--s-6); }
.build-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: var(--s-2); margin: var(--s-4) 0; }
.build-card { display: flex; flex-direction: column; align-items: center; gap: var(--s-1); min-width: 0; padding: var(--s-3) var(--s-2);
  background: var(--row); border: 0; border-top: 1px solid var(--row-hi); border-bottom: 1px solid var(--row-lo); color: var(--text);
  font: inherit; cursor: pointer; }
.build-card:hover:not(:disabled), .build-card[aria-pressed="true"] { background: var(--row-sel); }
.build-card[aria-pressed="true"] { outline: 1px solid var(--warn); outline-offset: -1px; }
.build-card:disabled { color: var(--text-3); cursor: not-allowed; }
.build-card canvas { display: block; width: 64px; height: 64px; image-rendering: pixelated; border: 1px solid var(--slot-edge); box-shadow: 0 0 0 1px var(--slot-ring);
  background: repeating-conic-gradient(#2b2836 0 25%, #322e3e 0 50%) 0 0 / 28px 28px; }
.build-card__name { max-width: 100%; text-align: center; overflow-wrap: anywhere; }
.build-card__sub { font-size: var(--fs-sm); color: var(--text-2); }
.build-structures { margin: var(--s-4) 0; }
.build-structure[aria-pressed="true"] { background: var(--row-sel); outline: 1px solid var(--warn); outline-offset: -1px; }
button.build-structure:disabled { color: var(--text-3); cursor: not-allowed; }
.hold-game .tools-note { color: var(--text-2); }

/* ---------------------------------------------------------------- building sheet (BuildingSheetHeader + HoldSimulationPanel)
   Mock inspector section, spacing copied literally where the scale allows (6 px under the header, 10 px beside the portrait,
   2 px row gaps, 3×8 row padding, 8 px before section heads); the mock's 5 px cell paddings use --s-2. */
.building-sheet, .building-inspector-content { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.hold-game .sheet-empty { margin: 0; }

.sheet-header { display: flex; gap: var(--s-5); padding-bottom: var(--s-3); flex-shrink: 0; }
/* The portrait is map art, dark in both themes: a plain 14 px checker until the renderer's portrait() draws over it. */
.sheet-portrait { box-sizing: content-box; width: 84px; height: 84px; flex-shrink: 0; border: 1px solid var(--slot-edge); box-shadow: 0 0 0 1px var(--slot-ring);
  background: repeating-conic-gradient(#2b2836 0 25%, #322e3e 0 50%) 0 0 / 28px 28px; }
.sheet-portrait canvas { display: block; width: 84px; height: 84px; image-rendering: pixelated; }
.sheet-identity { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.sheet-name-line { display: flex; justify-content: space-between; align-items: flex-start; gap: var(--s-3); }
.sheet-name { min-width: 0; font-size: var(--fs-xl); color: var(--text-name); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sheet-window { display: flex; gap: var(--s-2); flex-shrink: 0; }
.sheet-window > .dh-btn { width: 22px; height: 22px; min-height: 22px; padding: 0; line-height: 1; }
.sheet-window > .sheet-expand { width: auto; padding: 0 var(--s-3); }
.sheet-definition, .sheet-status { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sheet-definition { color: var(--text-2); }
/* Definition and status on the left; "Steward" or "Owner" over the name on the right, two lines tall like they are. */
.sheet-facts { display: flex; gap: var(--s-4); min-width: 0; }
.sheet-facts__text { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.sheet-owner { margin: 0; min-width: 0; max-width: 50%; display: flex; flex-direction: column; align-items: flex-end; }
.sheet-owner > dt { font-size: var(--fs-sm); color: var(--text-2); }
.sheet-owner > dd { margin: 0; max-width: 100%; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sheet-actions { display: flex; flex-wrap: wrap; gap: var(--s-2); margin-top: auto; padding-top: var(--s-1); }

/* Trapezoid tabs (theme .dh-tabs/.dh-tab): grow to fill but never shrink below their label, so no label clips. Narrow sheets
   (content ≤ 400 px: 340–416 px docks and phones) trim the side padding to 4 px (glyphs stay clear of the 6 px slants); the
   340 px dock (324 px content) also drops to 13 px so a farm's six tabs fit. The face stretches when tabs are 44 px tall. */
.sheet-tabs { flex-shrink: 0; }
.sheet-tabs > .dh-tab { flex: 1 0 auto; display: flex; }
.sheet-tabs > .dh-tab > span { flex: 1; display: flex; align-items: center; justify-content: center; }
@container (max-width: 400px) { .sheet-tabs > .dh-tab > span { padding-left: var(--s-2); padding-right: var(--s-2); } }
@container (max-width: 340px) { .sheet-tabs > .dh-tab > span { font-size: var(--fs-xs); } }
.sheet-body { flex: 1; min-height: 0; overflow: auto; overscroll-behavior: contain; border-top: 2px solid var(--gold); padding-top: var(--s-3); }
.hold-game .sheet-body > .notice, .hold-game .sheet-panel > .notice { margin: 0 0 var(--s-3); }
.hold-game .sheet-panel h3.dh-head, .sheet-head { margin: var(--s-4) 0 0; }
.hold-game .sheet-panel > h3.dh-head:first-child, .hold-game .sheet-panel > h3.dh-visually-hidden + .sheet-head { margin-top: 0; }
.hold-game .sheet-note, .hold-game .policy-note { margin: var(--s-2) 0; color: var(--text-2); font-size: var(--fs-sm); }
/* A claim's latest bids, newest first: plain lines under the claim's standing. */
.hold-game .auction-bids { list-style: none; margin: var(--s-2) 0; padding: 0; color: var(--text-2); font-size: var(--fs-sm); }
.hold-game .bid-problem, .placement-controls .bid-problem { color: var(--warn); }
.sheet-row__text, .stage-row__name { flex: 1; min-width: 0; align-self: center; padding: 3px var(--s-4); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sheet-row > .dh-row__meta, .stage-row > .dh-row__meta { align-self: center; }

/* Overview: warehouse capacity box, batch panel, stage list, road and identity lines. */
.sheet-box { padding: var(--s-3) var(--s-4); border: 1px solid var(--gold-dark); }
.sheet-box__title { font-size: var(--fs-xl); color: var(--info); }
.sheet-box__line { color: var(--text-2); }
.batch-panel { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); border: 1px solid var(--gold-dark); }
.batch-panel__stage { min-width: 0; padding: var(--s-2) var(--s-4); border-right: 1px solid var(--gold-dark); }
.batch-panel__time { min-width: 0; padding: var(--s-2) var(--s-4); display: flex; flex-direction: column; align-items: flex-end; text-align: right; }
.batch-panel__note { color: var(--text-2); }
.batch-panel__name { font-size: var(--fs-xl); color: var(--info); overflow-wrap: anywhere; }
.batch-panel__remain { font-size: var(--fs-stat); line-height: 1; color: var(--warn); font-variant-numeric: tabular-nums; }
.batch-panel__progress { grid-column: 1 / 3; padding: var(--s-2) var(--s-4) var(--s-3); border-top: 1px solid var(--gold-dark); }
.batch-panel__progress > .dh-stagebar { margin-top: var(--s-2); }
/* A construction site's sheet: the work bar sits between its two lines; a lodge's sites are rows that open the site. */
.sheet-box > .site-work { margin: var(--s-2) 0; }
.sheet-controls > .site-priority { align-self: center; }
button.lodge-site { width: 100%; text-align: left; }
.batch-panel__io { grid-column: 1 / 3; display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2) var(--s-4); padding: var(--s-2) var(--s-4); border-top: 1px solid var(--gold-dark); }
.batch-panel__arrow { color: var(--gold); }
.stage-row--active { background: var(--row-sel); }
.hold-game .sheet-road { margin: var(--s-4) 0 0; font-size: var(--fs-md); }
.hold-game .sheet-state { margin: 0; color: var(--text-2); }
.hold-game .sheet-footer { margin: 0; color: var(--text-3); }

/* Stock: the building-stocks table drawn as bevelled rows (2 px gaps) under an umber head, with per-commodity meters. */
.hold-game .dh-table { width: 100%; margin: 0; border-collapse: separate; border-spacing: 0 var(--s-1); font-size: var(--fs-md); }
.hold-game .dh-table th { padding: 3px var(--s-5); background: var(--umber); border: 0; border-top: 1px solid var(--umber-hi); border-bottom: 1px solid var(--umber-lo);
  color: #f4f0e0; text-shadow: 1px 1px 0 #000; font-size: var(--fs-sm); vertical-align: bottom; }
.hold-game .dh-table td { padding: 3px var(--s-4); background: var(--row); border: 0; border-top: 1px solid var(--row-hi); border-bottom: 1px solid var(--row-lo);
  vertical-align: middle; overflow-wrap: normal; }
.hold-game .dh-table td.stock-table__commodity { position: relative; padding-left: calc(var(--slot-w) + var(--s-4)); }
.stock-table__slot { position: absolute; left: 0; top: 0; bottom: 0; width: var(--slot-w); display: grid; place-items: center; background: var(--slot); border-right: 2px solid var(--slot-edge); }
.dh-table .dh-meter--stock { display: block; margin-top: var(--s-1); min-width: 48px; }
.dh-meter--stock > i { box-shadow: none; }
.hold-game .sheet-controls { margin: var(--s-4) 0 0; }

/* Policies: .dh-check boxes over native checkboxes (the input lies transparent on top: it keeps focus, clicks and its label). */
.dh-checkbox { position: relative; display: inline-grid; flex-shrink: 0; width: 24px; height: 22px; }
.hold-game .dh-checkbox > input[type=checkbox] { position: absolute; inset: 0; width: 100%; height: 100%; min-height: 0; margin: 0; padding: 0; opacity: 0; cursor: pointer; }
.dh-checkbox > .dh-check { display: grid; place-items: center; line-height: 1; color: transparent; text-shadow: none; }
.dh-checkbox > input:checked + .dh-check { background: var(--gold-fill); color: var(--text-on-gold); }
.hold-game .dh-checkbox > input[type=checkbox]:disabled { cursor: not-allowed; }
/* Disabled toggles and the read-only marks observers see share the locked look: dashed box, muted ✓. */
.dh-checkbox > input:disabled + .dh-check, .dh-check.is-readonly { border-style: dashed; }
.dh-checkbox > input:checked:disabled + .dh-check, .dh-check.is-readonly.is-on { background: var(--control); color: var(--text-2); }
.dh-checkbox > input:focus-visible + .dh-check { outline: 2px solid var(--warn); outline-offset: 2px; }
/* Forced colours (Windows High Contrast) repaint all text in CanvasText, so the transparent ✓ of every unchecked box and
   "off" read-only mark would read as ticked. The drawn boxes opt out and paint themselves in system colours: the tick only
   when checked or on (Highlight fill), GrayText for disabled toggles and read-only marks. */
@media (forced-colors: active) {
  .dh-checkbox > .dh-check { forced-color-adjust: none; background: Canvas; border-color: CanvasText; color: transparent; }
  .dh-checkbox > input:checked + .dh-check { background: Highlight; color: HighlightText; }
  .dh-checkbox > input:disabled + .dh-check, .dh-checkbox > .dh-check.is-readonly { border-color: GrayText; }
  .dh-checkbox > input:checked:disabled + .dh-check, .dh-checkbox > .dh-check.is-readonly.is-on { background: Canvas; color: GrayText; }
  .dh-checkbox > input:focus-visible + .dh-check { outline-color: Highlight; }
}
.hold-game .policy-check { display: inline-flex; align-items: center; gap: var(--s-3); margin: 0; color: var(--text-on-row); font-size: var(--fs-sm); cursor: pointer; }
.hold-game .policy-check.is-readonly { cursor: default; }
.hold-game .policy-controls { margin: var(--s-3) 0; }
.hold-game .policy-controls > label, .hold-game .sheet-controls > label { flex: 1 1 160px; margin: 0; }
.hold-game .policy-entry { margin-top: var(--s-1); padding: 3px var(--s-4) var(--s-3); background: var(--row); border: 0; border-top: 1px solid var(--row-hi); border-bottom: 1px solid var(--row-lo); }
.hold-game .policy-entry__title { display: flex; align-items: center; gap: var(--s-4); margin: 0; font-size: var(--fs-md); font-weight: 500; color: var(--text); }
.hold-game .policy-entry__line, .hold-game .policy-entry .policy-note { margin: var(--s-1) 0 0; color: var(--text-on-row); font-size: var(--fs-sm); }
.hold-game .policy-checks { gap: var(--s-2) var(--s-6); margin: var(--s-2) 0 0; }
.hold-game .policy-numbers { gap: var(--s-2) var(--s-4); margin: var(--s-2) 0 0; }
.hold-game .policy-numbers > label { flex: 1 1 88px; margin: 0; color: var(--text-on-row); }
.hold-game .policy-numbers input { display: block; max-width: none; margin-top: var(--s-1); padding: var(--s-1) var(--s-3); }
.hold-game .policy-actions { gap: var(--s-2); margin: var(--s-3) 0 0; }
/* A dwelling's needs: one row each with its word, opened for the pantry, what was eaten and what it takes. */
.hold-game .need-details, .hold-game .module-details { margin: 0; }
.hold-game .need-details > summary, .hold-game .module-details > summary { list-style: none; cursor: pointer; }
.hold-game .need-details > summary::-webkit-details-marker, .hold-game .module-details > summary::-webkit-details-marker { display: none; }
.hold-game .need-details > summary:hover, .hold-game .module-details > summary:hover { background: var(--row-sel); }
.need-details > summary .sheet-row__text::before, .module-details > summary .sheet-row__text::before { content: "▸"; margin-right: var(--s-2); }
.need-details[open] > summary .sheet-row__text::before, .module-details[open] > summary .sheet-row__text::before { content: "▾"; }
.hold-game .module-details__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-3); padding: 0 var(--s-4) var(--s-3) calc(var(--slot-w) + var(--s-4)); }
.hold-game .module-details__actions > .sheet-note { margin: 0; }
.hold-game .need-details__lines, .hold-game .module-details__lines { list-style: none; margin: 0; padding: var(--s-2) var(--s-4) var(--s-2) calc(var(--slot-w) + var(--s-4)); color: var(--text-2); font-size: var(--fs-sm); }
.hold-game .supply-controls { margin: var(--s-4) 0 0; }
.hold-game .supply-controls > summary { list-style: none; justify-content: flex-start; }
.hold-game .supply-controls > summary::-webkit-details-marker { display: none; }
.supply-controls > summary::before { content: "▸"; margin-right: var(--s-2); }
.supply-controls[open] > summary::before { content: "▾"; }
.recipe-head { margin-top: var(--s-4); }
.recipe-row.is-off { background: color-mix(in srgb, var(--row) 70%, var(--slot)); }
.recipe-row.is-off .recipe-row__name { color: var(--text-3); }
.hold-game .recipe-row__toggle { margin: 0; cursor: pointer; }
.recipe-row__body { flex: 1; min-width: 0; padding: 3px var(--s-4); display: flex; flex-direction: column; }
.recipe-row__io { font-size: var(--fs-sm); color: var(--text-on-row); }
.recipe-row__priority { display: flex; align-items: center; gap: var(--s-1); padding-right: var(--s-3); }
.hold-game .recipe-row__label { margin: 0; }
.hold-game .recipe-row__priority input { width: 44px; padding: var(--s-1); text-align: center; }
.dh-btn--plus:disabled, .dh-btn--minus:disabled { background: var(--control); color: var(--text-3); cursor: not-allowed; }

/* Fields and Behavior: restyled frames around the unchanged plant list, graphs and source viewer. */
.hold-game .sheet-fields > p { margin: var(--s-2) 0; }
.hold-game .sheet-view-label { margin: var(--s-3) 0; }
.hold-game .sheet-source { margin: var(--s-3) 0 var(--s-2); display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2) var(--s-4); }
.dh-btn[aria-pressed="true"] { background: var(--row-sel); border-color: var(--warn); color: var(--warn); }
/* Code viewer: Plex Mono 13 in --ok on the panel ink, unwrapped with 21 px lines so focusSource's (line − 3) × 21 scroll lands exactly. */
.hold-game .source-editor.dh-code { height: 240px; padding: var(--s-3) var(--s-4); background: var(--ink-0); border: 1px solid var(--gold-dark); line-height: 21px; white-space: pre; resize: vertical; }

/* Log: newest first, the time in --text-3, the verb or object coloured. */
.hold-game .dh-log { margin: 0; padding: var(--hair) 0; font-size: var(--fs-md); line-height: 1.25; }
.dh-log__time { color: var(--text-3); }

/* ---------------------------------------------------------------- tool bar and ledger bar (bottom corners) */
.tool-bar { position: absolute; z-index: 10; left: 0; bottom: 0; display: flex; gap: var(--s-1); padding: var(--s-2) var(--s-3) var(--s-2) var(--s-2);
  border-left: 0; border-bottom: 0; }
.tool-bar .dh-glyph { font-size: var(--fs-xl); }
.ledger-bar { position: absolute; z-index: 32; right: 0; bottom: 0; display: flex; gap: var(--s-1); padding: var(--s-2) var(--s-2) var(--s-2) var(--s-3);
  border-right: 0; border-bottom: 0; }
.ledger-button { width: auto; min-width: 46px; padding: 0 var(--s-3); gap: var(--s-1); }
.ledger-button.is-active { background: var(--row-sel); border-color: var(--warn); }
.ledger-button__top { display: flex; align-items: baseline; gap: var(--s-1); font-size: var(--fs-xl); }
.ledger-button__count { font-size: var(--fs-xs); color: var(--text-2); }

/* ---------------------------------------------------------------- ledger window (desktop modal) */
.ledger-layer { position: absolute; inset: 0; z-index: 30; }
.ledger-scrim { position: absolute; inset: 0; }
.ledger-window { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); display: flex; flex-direction: column; padding-top: 30px; }
.ledger-tabs { position: absolute; top: 0; left: 44px; right: 20px; height: 30px; display: flex; align-items: flex-end; }
.ledger-tab { width: auto; min-width: 138px; flex: 0 1 auto; height: 26px; margin-right: -8px; padding: 1px 1px 0; background: var(--gold); border: 0; cursor: pointer;
  clip-path: polygon(12px 0, calc(100% - 12px) 0, 100% 100%, 0 100%); }
.ledger-tab[aria-selected="true"] { height: 30px; position: relative; z-index: 1; }
.ledger-tab > span { display: flex; align-items: center; justify-content: center; height: 100%; padding: 0 var(--s-7); background: var(--ink-0); color: var(--text);
  white-space: nowrap; clip-path: polygon(12px 0, calc(100% - 12px) 0, 100% 100%, 0 100%); }
.ledger-tab[aria-selected="true"] > span { background: var(--gold-fill); color: var(--text-on-gold); text-shadow: none; }
/* clip-path clips outlines, so trapezoid tabs (.ledger-tab, the theme's .dh-tab) draw their focus ring inside the shape:
   the 1px outer layer turns --warn, the face gets a 3px --warn ring with a black keyline for contrast on gold, and the
   label is underlined so focus never relies on colour alone (--warn and --gold are close in parchment). */
.ledger-tab:focus-visible, .dh-tab:focus-visible { outline: none; background: var(--warn); }
.ledger-tab:focus-visible > span, .dh-tab:focus-visible > span { box-shadow: inset 0 0 0 3px var(--warn), inset 0 0 0 4px #000;
  text-decoration: underline; text-underline-offset: 3px; }
/* Forced colours drop box-shadow (and repaint the --warn layer), so a focused tab gives up its trapezoid clip, which would
   clip an outline, and takes a plain inset outline above its neighbours instead. They also repaint the gold fill that
   marks the selected tab, so its label opts out and takes the Highlight colours (and drops the --warn focus box-shadow,
   which opting out would otherwise keep: the outline carries focus). */
@media (forced-colors: active) {
  .ledger-tab:focus-visible, .dh-tab:focus-visible { position: relative; z-index: 2; clip-path: none; outline: 2px solid CanvasText; outline-offset: -2px; }
  .ledger-tab[aria-selected="true"] > span, .dh-tab[aria-selected="true"] > span { forced-color-adjust: none; background: Highlight; color: HighlightText; box-shadow: none; }
}
.ledger-frame { position: relative; flex: 1; min-height: 0; display: flex; flex-direction: column; }
.ledger-knot--left { left: -9px; } .ledger-knot--right { right: -9px; }
.ledger-title { display: flex; justify-content: space-between; align-items: center; gap: var(--s-6); padding: 0 var(--s-2) var(--s-5); }
.ledger-title h2 { margin: 0; font-size: var(--fs-lg); }
.ledger-title__meta { display: flex; align-items: center; gap: var(--s-6); white-space: nowrap; }
.ledger-body { flex: 1; min-height: 0; overflow: auto; padding-right: var(--s-1); }

/* Ledger sections (HoldLedger). */
.ledger-content > .dh-head:first-child, .ledger-content > .ledger-search + .ledger-list > .dh-head:first-child,
.ledger-content > .ledger-mine + .ledger-list > .dh-head:first-child { margin-top: 0; }
.ledger-content .dh-head { margin-top: var(--s-5); }
.ledger-content .ledger-group:first-child { margin-top: var(--s-2); }
.ledger-stats { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--s-3); }
.ledger-stat { display: flex; flex-direction: column; padding: var(--s-3) var(--s-5); background: var(--ink-0); border: 1px solid var(--gold-dark); color: var(--text-2); }
.ledger-stat__number { font-size: var(--fs-hero); line-height: 1; color: var(--text); }
.ledger-record { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-4) var(--s-6); margin-top: var(--s-5); }
.ledger-rename { flex: 1; min-width: 280px; display: flex; align-items: center; gap: var(--s-4); }
.hold-game .ledger-rename label { margin: 0; white-space: nowrap; }
.hold-game .ledger-rename input { flex: 1; width: auto; }
.ledger-rename button { margin: 0; width: auto; }
.ledger-row { align-items: stretch; }
.ledger-cell { display: flex; align-items: center; padding: 3px var(--s-5); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ledger-cell--grow { flex: 1; min-width: 0; display: block; align-self: center; }
.ledger-cell--quiet { color: var(--text-on-row); }
.ledger-cell--amount { width: 130px; flex-shrink: 0; justify-content: flex-end; }
.ledger-cell--state { width: 220px; flex-shrink: 1; min-width: 0; display: block; align-self: center; }
.ledger-cell--pos { width: 90px; flex-shrink: 0; color: var(--text-on-row); }
.ledger-cell--time { width: 60px; flex-shrink: 0; color: var(--text-on-row); }
.ledger-cell--phase { width: 110px; flex-shrink: 0; }
.ledger-cell--eta { width: 70px; flex-shrink: 0; }
.ledger-columns > span:not(.ledger-cell--grow) { flex-shrink: 0; }
.ledger-columns > .ledger-cell--phase, .ledger-columns > .ledger-cell--eta { padding-left: var(--s-5); }
.ledger-go { display: flex; align-items: center; padding-right: var(--s-3); }
.ledger-go > .dh-btn { display: flex; align-items: center; height: 24px; }
.ledger-stock > span:not(.ledger-cell--grow):not(.dh-row__slot) { width: 104px; flex-shrink: 0; }
.ledger-stock > span.ledger-cell:nth-child(3) { width: 200px; }
.ledger-stock.dh-head > span:nth-child(2) { width: 200px; }
.ledger-legend { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-1); margin-top: var(--s-1); }
.ledger-legend__item { display: flex; align-items: center; gap: var(--s-4); min-width: 0; padding: 3px var(--s-4); background: var(--row);
  border-top: 1px solid var(--row-hi); border-bottom: 1px solid var(--row-lo); }
.ledger-legend__item > span:last-child { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ledger-legend .swatch { flex-shrink: 0; }
.ledger-empty { margin: var(--s-1) 0 0; padding: var(--s-1) var(--s-4); color: var(--text-2); }
.ledger-biography { margin: var(--s-4) 0 0; padding: var(--s-1) var(--s-4); white-space: pre-line; overflow-wrap: anywhere; }
.ledger-dwarf { display: flex; flex-direction: column; gap: var(--s-3); max-width: 560px; }
.hold-game .ledger-dwarf label { margin: var(--s-3) 0 0; }
.hold-game .ledger-dwarf textarea { resize: vertical; }
.ledger-dwarf__problem { margin: 0; color: var(--warn); }
.ledger-dwarf button { align-self: flex-start; width: auto; }
.ledger-search { display: flex; align-items: center; gap: var(--s-4); }
.ledger-mine { display: flex; align-items: center; gap: var(--s-3); margin-top: var(--s-3); width: fit-content; }
.hold-game .ledger-search { margin: 0; }
.hold-game .ledger-search input { flex: 1; width: auto; }
.ledger-note { color: var(--text-2); }
.shipment-detail p { margin: var(--s-2) 0; }
.shipment-detail .text-button { color: var(--warn); }

/* ---------------------------------------------------------------- tooltip (.dh-tip from the theme)
   HoldTooltip renders it; Map/workspace.ts positions it (measured and clamped) and then shows it, so it never flashes at the
   corner. Labels that carry a value read as --text-2 like the mock's rows; a sentence line keeps its own colour. */
.hold-tooltip-host { display: contents; }
.hold-tooltip { left: 0; top: 0; visibility: hidden; color: var(--text); }
.dh-tip__line > span:first-child { min-width: 0; white-space: pre-wrap; overflow-wrap: anywhere; }
.dh-tip__line:not(.dh-tip__line--text) > span:first-child { color: var(--text-2); }
.dh-tip__value { flex-shrink: 0; max-width: 62%; text-align: right; overflow-wrap: anywhere; }
.dh-tip__note { margin-top: var(--s-2); padding-top: var(--s-1); border-top: 1px solid var(--gold-dark); color: var(--text-3); font-size: var(--fs-xs); }
/* Tooltips over the map stay dark in both themes (README §3): the map tip re-scopes the tokens to the dark palette. */
[data-theme="light"] .dh-tip--map { --ink-0: #000000; --gold: #c9a43a; --gold-dark: #6e5a1e; --text: #f4f0e0; --text-2: #c0c0c0; --text-3: #a19eaa;
  --ok: #55ff55; --warn: #f4d03a; --info: #55ffff; --idle: #c0c0c0; --bad: #ff5555; color: var(--text); text-shadow: 1px 1px 0 #000; }
.is-mobile .hold-tooltip { display: none; }

/* ---------------------------------------------------------------- mobile (< 768 px, or coarse and ≤ 600 px tall):
   the full-screen Map / Ledger / Building / Tools views from planning/map-workspace-ui.md, on the tokens. No floating desktop
   panels; every target at least 44 px; inputs 16 px. Bars: header 78 px (44 px identity row over a 22 px clock row, clear
   of the bottom frame), bottom navigation 58 px (44 px glyph-over-label buttons), both plus the safe-area insets. */
.is-mobile .workspace-header { height: calc(78px + env(safe-area-inset-top, 0px)); display: grid; grid-template-columns: minmax(0, 1fr) auto auto;
  grid-template-rows: 44px 22px; row-gap: var(--s-1); align-content: start; align-items: center;
  padding: calc(var(--s-1) + env(safe-area-inset-top, 0px)) max(var(--s-2), env(safe-area-inset-right, 0px)) 0 max(var(--s-4), env(safe-area-inset-left, 0px)); }
.is-mobile .hold-back { grid-area: 1 / 1; max-width: none; height: 44px; padding: 0 var(--s-4) 0 0; border: 0; }
.is-mobile .header-resources, .is-mobile .header-standing, .is-mobile .header-people { display: none; }
/* The badge may take two lines on phones ("Live · Public observation — read-only.") instead of clipping. */
.is-mobile .connection-badge { grid-area: 1 / 2; max-width: 56vw; padding: 0 var(--s-2); font-size: var(--fs-xs); line-height: 1.2; white-space: normal;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; }
.is-mobile .session-menu { grid-area: 1 / 3; border: 0; }
.is-mobile .session-menu > summary { min-width: 44px; min-height: 44px; display: grid; place-items: center; padding: 0; }
.is-mobile .session-menu > .session, .is-mobile .session-menu > p { top: 44px; width: min(260px, calc(100vw - 16px)); }
.is-mobile .session-menu a { display: inline-flex; align-items: center; min-height: 44px; }
.is-mobile .header-clock { grid-area: 2 / 1 / 3 / 4; height: 22px; padding: 0; border: 0; overflow: hidden; }
.is-mobile .world-time { flex-direction: row; align-items: baseline; gap: var(--s-2); }
.is-mobile .world-time__time { font-size: var(--fs-md); }
.is-mobile .workspace-body { top: calc(78px + env(safe-area-inset-top, 0px)); bottom: calc(58px + env(safe-area-inset-bottom, 0px)); }
.is-mobile .workspace-empty { top: calc(96px + env(safe-area-inset-top, 0px)); }
.hold-game.is-mobile > .workspace-alert { top: auto; left: var(--s-4); right: var(--s-4); bottom: calc(150px + env(safe-area-inset-bottom, 0px)); font-size: var(--fs-xs); }

/* Map view: TerrainMap's zoom bar on top, the readout at the bottom, the selected-building chip (left) and the Road tools
   (right) just above the readout, the editing banner under the zoom bar. */
.is-mobile .map-shell > .map-toolbar { position: absolute; z-index: 2; top: var(--s-4); left: var(--s-4); right: var(--s-4); padding: var(--s-2) var(--s-2) var(--s-2) var(--s-4);
  gap: var(--s-3); background: var(--ink-0); border: 2px solid var(--gold); box-shadow: 0 0 0 1px #000, inset 0 0 0 2px var(--ink-0), inset 0 0 0 3px var(--gold-dark); }
.is-mobile .map-shell > .map-toolbar > span { min-width: 0; color: var(--text-2); font-size: var(--fs-xs); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.is-mobile .map-shell > .map-toolbar > span > select { width: auto; max-width: 100%; padding: 0 var(--s-2); }
.is-mobile .map-shell > .map-toolbar > div { display: flex; gap: var(--s-1); flex-shrink: 0; }
.is-mobile .map-shell > .map-toolbar button { min-width: 44px; min-height: 44px; margin: 0; padding: var(--s-1) var(--s-3); font-size: var(--fs-xs); line-height: 1.1; }
.is-mobile .map-shell > .map-toolbar button:nth-child(3) { max-width: 85px; white-space: normal; }
.is-mobile .map-shell > .map-toolbar button:nth-child(4) { max-width: 66px; white-space: normal; }
.is-mobile .map-footer { left: var(--s-4); right: var(--s-4); bottom: var(--s-4); }
.is-mobile .map-footer > span:first-child { display: none; }
.is-mobile .map-diagnostic { display: none; }
.is-mobile .editing-banner { top: 76px; bottom: auto; left: var(--s-4); right: var(--s-4); max-width: none; transform: none; justify-content: flex-start; }
.is-mobile .editing-banner > span { flex: 1; min-width: 90px; }
.is-mobile .editing-banner > button { min-height: 44px; }
/* Selected building: a framed chip with the status dot and word over the name ("Inspect Brewery" stays its name). */
.selected-map-chip { position: absolute; z-index: 3; left: var(--s-4); bottom: 40px; max-width: calc(100% - 16px); min-height: 44px; padding: var(--s-1) var(--s-4) var(--s-1) var(--s-3);
  display: grid; grid-template-columns: auto minmax(0, 1fr); grid-template-areas: "dot status" "dot text"; column-gap: var(--s-3); align-items: center;
  color: var(--text); text-align: left; cursor: pointer; line-height: 1.2; }
.selected-map-chip > .dh-dot { grid-area: dot; }
.selected-map-chip__text { grid-area: text; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text-2); font-size: var(--fs-xs); }
.selected-map-chip__name { color: var(--text-name); font-size: var(--fs-md); }
.selected-map-chip__status { grid-area: status; font-size: var(--fs-xs); }
.selected-map-chip:active { background: var(--row-sel); }
/* Beside the Road tools (operators) the chip leaves their 158 px plus the gaps. */
.selected-map-chip:has(~ .mobile-road-tools) { max-width: calc(100% - 186px); }
/* Road tools: glyph over word, like the desktop tool bar (aria-pressed marks the active one). */
.mobile-road-tools { position: absolute; z-index: 3; right: var(--s-4); bottom: 40px; display: flex; gap: var(--s-2); padding: var(--s-2); }
.mobile-road-tools > .dh-tool { gap: var(--s-1); font-size: var(--fs-xs); }
.mobile-road-tools > .dh-tool > .dh-glyph { font-size: var(--fs-xl); }

/* Bottom navigation: three 44 px buttons, glyph over label; the current view is marked like a pressed tool. */
.mobile-navigation { position: absolute; z-index: 15; left: 0; right: 0; bottom: 0; height: calc(58px + env(safe-area-inset-bottom, 0px)); display: flex; gap: var(--s-2);
  padding: var(--s-3) max(var(--s-4), env(safe-area-inset-right, 0px)) calc(var(--s-3) + env(safe-area-inset-bottom, 0px)) max(var(--s-4), env(safe-area-inset-left, 0px));
  background: var(--ink-0); border-top: 2px solid var(--gold); box-shadow: 0 -1px 0 #000, inset 0 2px 0 var(--ink-0), inset 0 3px 0 var(--gold-dark); }
.mobile-navigation > .dh-tool { flex: 1; width: auto; height: 44px; min-height: 44px; gap: var(--s-1); color: var(--text-2); font-size: var(--fs-xs); }
.mobile-navigation > .dh-tool > .dh-glyph { color: var(--text); font-size: var(--fs-xl); }
.mobile-navigation > .dh-tool.active { background: var(--row-sel); border-color: var(--warn); color: var(--warn); }
.mobile-navigation > .dh-tool.active > .dh-glyph { color: var(--warn); }

/* Full-screen Building and Tools views. */
.is-mobile .workspace-inspector { inset: 0; width: auto; padding: 0; border: 0; box-shadow: none; }
.is-mobile .window-header { min-height: 56px; padding: var(--s-2) max(var(--s-4), env(safe-area-inset-right, 0px)) var(--s-2) max(var(--s-6), env(safe-area-inset-left, 0px));
  border-bottom: 2px solid var(--gold); }
.is-mobile .window-header .dh-btn { width: 44px; height: 44px; }
.is-mobile .sheet-header { padding: var(--s-4) max(var(--s-4), env(safe-area-inset-right, 0px)) var(--s-3) max(var(--s-6), env(safe-area-inset-left, 0px)); }
.is-mobile .sheet-window > .dh-btn { width: 44px; height: 44px; }
.is-mobile .sheet-actions > .dh-btn { min-height: 44px; }
.is-mobile .sheet-tabs { padding: 0 max(var(--s-4), env(safe-area-inset-right, 0px)) 0 max(var(--s-4), env(safe-area-inset-left, 0px)); }
.is-mobile .sheet-tabs > .dh-tab { min-height: 44px; }
.is-mobile .sheet-body { padding: var(--s-6) max(var(--s-6), env(safe-area-inset-right, 0px)) var(--s-8) max(var(--s-6), env(safe-area-inset-left, 0px)); }
.is-mobile .dh-btn--plus, .is-mobile .dh-btn--minus { width: 44px; height: 44px; }
.is-mobile .recipe-row__toggle { width: 44px; }
.is-mobile .policy-check { min-height: 44px; }
.is-mobile .window-body { padding: var(--s-6) max(var(--s-6), env(safe-area-inset-right, 0px)) var(--s-8) max(var(--s-6), env(safe-area-inset-left, 0px)); }
.is-mobile .window-header .dh-btn, .is-mobile .sheet-window > .dh-btn { font-size: var(--fs-xl); }
.is-mobile .mobile-clock { margin-bottom: var(--s-6); }
.is-mobile .mobile-clock .clock-controls { gap: var(--s-2); }
.is-mobile .mobile-clock .clock-play { width: 44px; height: 44px; }
.is-mobile .mobile-clock .clock-step { height: 44px; padding: 0 var(--s-5); }
.is-mobile .graph-host { height: 340px; }
.is-mobile .graph-shell .map-toolbar { flex-direction: column; align-items: stretch; gap: var(--s-2); }
.is-mobile .graph-shell .map-toolbar > span { display: none; }
.is-mobile .graph-shell .map-toolbar > div { flex-wrap: nowrap; justify-content: stretch; gap: var(--s-1); }
.is-mobile .graph-shell .map-toolbar button { flex: 1; min-height: 44px; padding: var(--s-2) var(--s-3); font-size: var(--fs-xs); white-space: normal; }
.is-mobile .building-behavior > h3 { display: none; }
.is-mobile .building-behavior > label { margin-top: 0; }
.is-mobile .preview-controls > label { flex: 1; min-width: 100px; }
.is-mobile .preview-controls input { max-width: none; }
/* Every control a finger can hit is at least 44 px tall; text fields are 16 px so phones never zoom into them. */
.is-mobile .dh-btn, .is-mobile button.dh-row, .is-mobile .text-button, .is-mobile summary, .is-mobile .session-menu button { min-height: 44px; }
.is-mobile details > summary:not(.dh-head):not([aria-label]) { padding-top: var(--s-5); }
.is-mobile .trace-row { padding: var(--s-6) var(--s-1); }
.is-mobile .shipment-detail .text-button { display: inline-flex; align-items: center; }
.is-mobile input, .is-mobile select, .is-mobile textarea { min-height: 44px; font-size: 16px; }
.is-mobile input[type=checkbox] { min-height: 24px; width: 24px; }
.is-mobile .stock-table thead { display: none; }
.is-mobile .stock-table tr { display: grid; grid-template-columns: 1fr 1fr; margin-top: var(--s-1); background: var(--row); border-top: 1px solid var(--row-hi); border-bottom: 1px solid var(--row-lo); }
.is-mobile .stock-table td { min-width: 0; padding: var(--s-2) var(--s-4); background: none; border: 0; font-size: var(--fs-sm); }
.is-mobile .stock-table td:first-child { grid-column: 1 / -1; }
.is-mobile .stock-table td[data-label]::before { content: attr(data-label); display: block; margin-bottom: var(--s-1); color: var(--text-2); font-size: var(--fs-xs); }

/* Full-screen Ledger view: title bar, the "Ledger section" picker, then the section. */
.is-mobile .ledger-window { inset: 0; transform: none; padding-top: 0; }
.is-mobile .ledger-frame { border: 0; box-shadow: none; background: var(--ink-0);
  padding: var(--s-2) max(var(--s-4), env(safe-area-inset-right, 0px)) var(--s-8) max(var(--s-6), env(safe-area-inset-left, 0px)); }
.is-mobile .ledger-title { min-height: 52px; padding: 0 0 var(--s-2); border-bottom: 2px solid var(--gold); }
.is-mobile .ledger-title__time { color: var(--text-2); font-size: var(--fs-sm); }
.is-mobile .ledger-title .dh-btn { min-width: 44px; }
.is-mobile .mobile-ledger-picker { padding: var(--s-4) 0; border-bottom: 1px solid var(--gold-dark); margin-bottom: var(--s-4); }
.is-mobile .mobile-ledger-picker label { display: flex; flex-direction: column; gap: var(--s-2); margin: 0; color: var(--text-2); font-size: var(--fs-sm); }
.is-mobile .mobile-ledger-picker select { width: 100%; padding: var(--s-2) var(--s-4); background: var(--slot); color: var(--text); border: 1px solid var(--slot-edge);
  box-shadow: 0 0 0 1px var(--slot-ring); }
.is-mobile .ledger-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.is-mobile .ledger-legend { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.is-mobile .ledger-row { flex-wrap: wrap; }
.is-mobile .ledger-row > .ledger-cell--grow { flex-basis: calc(100% - 32px); }
.is-mobile .ledger-row > .ledger-cell:not(.ledger-cell--grow) { width: auto; padding-left: 40px; }
.is-mobile .ledger-columns > span:not(.ledger-cell--grow), .is-mobile .ledger-cell--pos, .is-mobile .ledger-go { display: none; }
.is-mobile .ledger-stock > .ledger-cell:not(.ledger-cell--grow):empty { display: none; }
.is-mobile .ledger-stock > .ledger-cell[data-label]:not(:empty)::before { content: attr(data-label); margin-right: var(--s-2); color: var(--text-2); }
.is-mobile .ledger-rename { min-width: 0; flex-wrap: wrap; }
.is-mobile .ledger-search { flex-wrap: wrap; }

/* Coarse pointers (README §8): 16 px inputs must beat the workspace input rules above, on tablets in the desktop layout too. */
@media (pointer: coarse) {
  .hold-game input, .hold-game select, .hold-game textarea { font-size: 16px; }
  .is-desktop .map-panel { height: auto; min-height: 192px; }
}
@media (max-width: 767px), (pointer: coarse) and (max-height: 600px) { .workspace-layout { overscroll-behavior: none; } }
@media (max-width: 767px) {
  .app-header { min-height: 68px; height: auto; padding: var(--s-6); gap: var(--s-6); flex-wrap: wrap; }
  .app-header .session { gap: var(--s-6); flex-wrap: wrap; font-size: var(--fs-xs); }
  .login-card { padding: var(--s-8); margin: var(--s-8) auto; }
}

/* ---------------------------------------------------------------- queued orders
   A confirming button carries the countdown of its queued order; the smaller button reverts it. */
.queued-action { display: inline-flex; align-items: center; gap: var(--s-3); flex-wrap: wrap; }
.queued-action .order-countdown { font-variant-numeric: tabular-nums; }
.queued-action.queued > button:first-child, .queued-action.applying > button:first-child { color: var(--warn); }
.queued-action.applied > button:first-child { border-color: var(--ok); }
.queued-action .order-revert, .order-item .order-revert { padding: var(--s-1) var(--s-3); }
.order-rejected, .draft-notice { flex-basis: 100%; color: var(--bad); }
.orders-waiting { color: var(--warn); font-size: inherit; padding: 0; margin-left: .35em; }
.order-item { cursor: default; }
.order-item.rejected { border-color: var(--bad); }
.order-item.applied { opacity: .75; }
.order-item.cancelled { opacity: .55; }
.editing-banner .queued-action > button:first-child { white-space: nowrap; }
.world-time__next { font-size: var(--fs-xs); color: var(--text-2); }
.world-time .orders-waiting { min-height: 0; }

/* ---------------------------------------------------------------- realm screen (Pages/Realm.razor, DESIGN.md "Realm screen")
   The realm map fills the viewport like a hold's; the top bar, the holds panel (left, top 56, 316 wide), the map panel
   (bottom right) and the info card float over it. The card is placed beside the selected site by Map/realm.ts; on a world
   without a realm map it docks beside the holds panel, on phones it is a bottom sheet over the navigation. */
.realm-header .realm-title { cursor: default; }
.realm-header .realm-title:hover { color: var(--text); }
.realm-world { display: flex; align-items: center; padding: 0 var(--s-6); border-left: 1px solid var(--gold-dark); flex-shrink: 0; }
.hold-game .realm-world > select { width: auto; max-width: 240px; height: 28px; padding: 0 var(--s-2); }
.realm-header__fill { flex: 1; min-width: 0; }
.realm-header__model { display: flex; align-items: center; padding: 0 var(--s-6); border-left: 1px solid var(--gold-dark); flex-shrink: 0; }
.realm-header__model > .dh-btn { display: inline-flex; align-items: center; height: 28px; color: var(--text); text-decoration: none; }
.realm-session { display: flex; align-items: center; padding: 0 var(--s-6); border-left: 1px solid var(--gold-dark); flex-shrink: 0; }
.realm-session > .session { flex-wrap: nowrap; white-space: nowrap; }

.realm-holds { position: absolute; z-index: 10; top: 56px; left: 0; width: 316px; max-height: calc(100% - 56px); border-top: 0; border-left: 0;
  display: flex; flex-direction: column; }
.realm-holds__scroll { min-height: 0; overflow: auto; }
.hold-game .realm-holds__title { margin: 0; font-size: var(--fs-md); }
.realm-holds__empty { margin: var(--s-3) 0 0; padding: 0 var(--s-4); color: var(--text-2); }
.realm-holds .notice { margin: var(--s-3) 0 0; }
.hold-card .dh-row__body { padding: var(--s-1) var(--s-4) 3px; }
.hold-card__name { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hold-card__sub { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.realm-map-panel { top: auto; bottom: 0; height: auto; border-top: 2px solid var(--gold); border-bottom: 0; }

.site-card { position: absolute; z-index: 11; left: 0; top: 0; width: 340px; max-height: calc(100% - 72px); overflow: auto; margin: 0; }
.site-card--docked { left: 324px; top: 64px; }
.site-card__close { position: absolute; top: var(--s-3); right: var(--s-3); width: 24px; padding: 0; }
.hold-game .site-card__title { margin: 0 var(--s-8) var(--s-1) 0; font-size: var(--fs-lg); color: var(--text); overflow-wrap: anywhere; }
.hold-game .site-card p { margin: 0 0 var(--s-3); }
.site-card__site, .site-card__description { color: var(--text-2); }
.site-card__access { color: var(--info); }
.site-card__head { margin-top: var(--s-4); }
.site-card__roads { list-style: none; margin: var(--s-3) 0 var(--s-5); padding: 0 var(--s-4); font-size: var(--fs-sm); }
.site-card__roads > li { padding: var(--s-1) 0; }
.site-card__roads > li.is-closed { color: var(--bad); }
.site-card__enter { display: flex; align-items: center; justify-content: center; min-height: 32px; text-decoration: none; }
.site-card__denied { color: var(--text-2); }
/* Trade on the realm screen: a GM's open/close order on each road row, the realm ledger button and window. */
.site-card__roads > li.site-card__road { display: flex; align-items: center; gap: var(--s-4); }
.site-card__road-text { flex: 1; min-width: 0; }
.site-card__road-pending { color: var(--warn); }
.site-card__road-toggle { flex-shrink: 0; width: auto; min-height: 24px; padding: 0 var(--s-4); }
.realm-header__ledger { display: flex; align-items: center; padding: 0 var(--s-6); border-left: 1px solid var(--gold-dark); flex-shrink: 0; }
.realm-header__ledger > .dh-btn { width: auto; height: 28px; }
/* The world clock on the realm screen: the hold top bar's clock group (time, run or pause, the next tick now); on phones a
   row at the top of the holds screen with 44px buttons. */
.realm-holds__clock { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--s-4); padding: var(--s-3) var(--s-4); border-bottom: 1px solid var(--gold-dark); }
.realm-holds__clock .world-time { flex-direction: row; align-items: baseline; gap: var(--s-2); }
.realm-holds__clock .clock-play { width: 44px; height: 44px; }
.realm-holds__clock .clock-step { height: 44px; padding: 0 var(--s-5); }
.realm-ledger__label { width: 110px; flex-shrink: 0; }
.realm-ledger .dh-table { margin-top: var(--s-2); }
.realm-ledger > .dh-btn { width: auto; margin-top: var(--s-4); }
/* Trade tabs of the building sheet: each row's orders sit on a line under it. */
.hold-game .trade-controls { margin: var(--s-1) 0 var(--s-3); }
.hold-game .trade-controls .dh-btn { width: auto; }

.is-mobile .realm-header { height: calc(56px + env(safe-area-inset-top, 0px)); grid-template-columns: minmax(0, 1fr) auto auto; grid-template-rows: 44px; }
.is-mobile .realm-world { grid-area: 1 / 2; padding: 0 var(--s-2); border: 0; }
.is-mobile .realm-header__fill, .is-mobile .realm-header__model { display: none; }
.realm-screen.is-mobile .workspace-body { top: calc(56px + env(safe-area-inset-top, 0px)); }
.is-mobile .realm-holds { position: absolute; inset: 0; width: auto; max-height: none; border: 0; }
.is-mobile .hold-card { min-height: 44px; }
.is-mobile .site-card { left: 0 !important; right: 0; top: auto !important; bottom: 0; width: auto; max-height: 60%; opacity: 1 !important; border-bottom: 0; }
.is-mobile .site-card__close { width: 44px; height: 44px; }
.is-mobile .site-card__enter { min-height: 44px; }
.is-mobile .site-card__road-toggle { min-height: 44px; }
.is-mobile .realm-ledger__label { width: 80px; }
.is-mobile .realm-ledger .dh-table { font-size: var(--fs-sm); }
.is-mobile .realm-ledger .dh-table td, .is-mobile .realm-ledger .dh-table th { padding: var(--s-1) var(--s-2); overflow-wrap: anywhere; }

/* ---------------------------------------------------------------- terrain editor (Pages/TerrainEditor.razor, its own window)
   The bar across the top, the tools down the left and the map in the rest. The map stays dark in both themes: its
   canvas paints the void itself (Map/terrain-editor.ts). */
.terrain-editor { position: fixed; inset: 0; display: grid; grid-template-columns: 280px minmax(0, 1fr); grid-template-rows: auto auto minmax(0, 1fr) auto;
  grid-template-areas: "bar bar" "notice notice" "tools map" "footer footer"; gap: var(--s-2); padding: var(--s-2); background: var(--ink-1); }
.terrain-editor__bar { grid-area: bar; display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-4) var(--s-7); padding: var(--s-3) var(--s-6); }
.terrain-editor__title { margin: 0; font-size: var(--fs-lg); font-weight: 500; color: var(--text); }
.terrain-editor__floor, .terrain-editor__zoom, .terrain-editor__history, .terrain-editor__actions { display: inline-flex; align-items: center; gap: var(--s-2); }
.terrain-editor__state { color: var(--text-2); font-size: var(--fs-sm); }
.terrain-editor__actions { margin-left: auto; }
.terrain-editor__notice { grid-area: notice; margin: 0; }
.terrain-editor__empty { grid-area: tools / tools / map / map; align-self: start; }
.terrain-editor__tools { grid-area: tools; display: flex; flex-direction: column; gap: var(--s-3); min-height: 0; overflow: hidden; }
.terrain-editor__toolrow { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s-2); }
.terrain-editor__toolrow .dh-btn { padding: 1px var(--s-2); }
.terrain-editor .dh-btn[aria-pressed="true"] { background: var(--row-sel); border-color: var(--warn); color: var(--warn); }
.terrain-editor__key { color: var(--text-3); font-size: var(--fs-xs); }
.terrain-editor__size { display: flex; align-items: center; justify-content: space-between; gap: var(--s-4); color: var(--text-2); font-size: var(--fs-sm); }
.terrain-editor__palette { flex: 1; min-height: 0; overflow-y: auto; }
.terrain-editor__group { margin: var(--s-4) 0 0; color: var(--text-2); font-size: var(--fs-xs); }
.terrain-editor__material { width: 100%; text-align: left; border: 1px solid transparent; }
.terrain-editor__material[aria-pressed="true"] { background: var(--row-sel); border-color: var(--warn); }
.terrain-editor__material img { display: block; image-rendering: pixelated; }
.terrain-editor__map { grid-area: map; position: relative; min-width: 0; min-height: 0; overflow: hidden; border: 2px solid var(--gold); background: var(--ink-1); }
.terrain-editor__canvas { display: block; cursor: crosshair; touch-action: none; }
.terrain-editor__canvas:focus-visible { outline: 1px solid var(--warn); outline-offset: -1px; }
.terrain-editor__footer { grid-area: footer; display: flex; justify-content: space-between; gap: var(--s-7); padding: 0 var(--s-4); color: var(--text-2); font-size: var(--fs-sm); }
/* The editor needs a pointer and room: on a phone the page says so instead (TerrainEditor's narrow notice). */
.terrain-editor__narrow { display: none; }
@media (max-width: 767px) {
  .terrain-editor > :not(.terrain-editor__narrow) { display: none; }
  .terrain-editor { display: block; }
  .terrain-editor__narrow { display: block; margin: var(--s-7); }
}
