/* ══════════════════════════════════════════════════════════════════════════
   src/styles/windows.css — the alpha windows: Inventory (the paper doll beside
   the bag), Storage, Hunts, Skills and Shop (ledgers), Hunt prep (WORLD_SHELL §4,
   ART_DIRECTION §7, §8, §9, §12). Tokens only, not one colour literal.
   Pockets and slots are SUNK into the window, never framed; gear pockets carry
   their rarity as a 2 px border plus rank pips (colour is never the only cue);
   the selection is a neutral --ink outline (gold is the primary action).
   Item icons render at ×1 in 36 px pockets (Tyler 10-18); ledgers keep 32 px.
   One text style (§10): --f-label headings, --f-ui body, never under --t-micro.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── The window objects ── */
/* A well inside a window is the Forged Steel well (tokens.css §8): one art px deep, shadow up-left, lit lip down-right. */
.hs-win { --hw-well: var(--steel-well); }
.hs-win .hh-empty.is-on { display: block; margin: 8px 2px; font-size: var(--t-micro); }
.hw-pane { display: none; }
.hw-pane.is-on { display: block; }

/* ── Shared: tabs, the capacity line, ledgers, the primary action, confirmations ── */
.hw-tabs { display: flex; gap: 2px; margin-bottom: 8px; border-bottom: 2px solid var(--steel-sep); }
/* The Shop's tabs stay whole and in reach however far its body is scrolled (newcomer panel 2026-11-03: sliced under the coach card). */
/* ...up to the body's edge: stuck below its padding, the row it had scrolled past read on above the tabs (door panel 2026-11-04). */
.hw-shop > .hw-tabs { position: sticky; top: -10px; margin-top: -10px; padding-top: 10px; z-index: 1; background: var(--bg-1); }
.hw-tab { margin-bottom: -2px; border: 0; background: none; padding: 4px 10px; min-height: 32px; font-family: var(--f-label); font-weight: 700; font-size: var(--t-micro); letter-spacing: .04em; color: var(--ink-3); cursor: pointer; border-bottom: 2px solid transparent; }
.hw-tab:hover { color: var(--ink); }
.hw-tab[aria-selected="true"] { color: var(--gold-2); border-bottom-color: var(--gold); }
.hw-tab:focus-visible, .hw-cat:focus-visible, .hw-mi:focus-visible { outline: 2px solid var(--aqua-2); outline-offset: -2px; }
.hw-cap { display: flex; justify-content: space-between; gap: 8px; margin: 0 2px 8px; font-size: var(--t-micro); color: var(--ink-3); font-variant-numeric: lining-nums tabular-nums; }
.hw-cap:empty { display: none; }
.hw-ico { width: 64px; height: 64px; display: grid; place-items: center; flex: none; }
.hw-ico .hh-icon { width: 64px; height: 64px; }
.hw-ico .hh-icon.is-glyph .hs-glyph { width: 32px; height: 32px; }
.hw-ledger { margin: 0 0 6px; padding: 0; list-style: none; }
/* Shown (.is-on), it is a Forged Steel section head (shell.css). */
.hw-ledger-head { display: none; margin: 10px 2px 4px; }
.hw-cap.hw-buy-note { display: none; margin-bottom: 6px; }
.hw-cap.hw-buy-note.is-on { display: block; }
.hw-line { display: flex; align-items: center; gap: 8px; min-height: 52px; padding: 2px 0; border-top: 2px solid var(--steel-sep); }
.hw-line .hw-ico { width: 40px; height: 40px; }
.hw-line .hw-ico .hh-icon { width: 32px; height: 32px; }
.hw-line-name { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.hw-line-name b { font-weight: 700; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hw-line-name small { font-size: var(--t-micro); color: var(--ink-2); font-variant-numeric: lining-nums tabular-nums; }
/* The Shop's lines (Buy, Sell, Services) take the bag's treatment, not 2x (Tyler 10-25: "Shop is too big"): the same
   1x art in the bag's well size and the price at the supporting size from 1280; a phone keeps today's line. */
.hw-shop .hw-line { min-height: round(down, clamp(52px, 52px + (100vw - 1024px) / 64, 56px), 2px); }
.hw-shop .hw-line .hw-ico { width: round(down, clamp(40px, 40px + (100vw - 1024px) / 64, 44px), 2px); height: round(down, clamp(40px, 40px + (100vw - 1024px) / 64, 44px), 2px); background: var(--bg-1); box-shadow: var(--hw-well); }
/* A long name wraps rather than clips beside the count and the price (667 wide, a wide fallback font). */
.hw-shop .hw-line-name b { white-space: normal; line-height: 1.15; }
.hw-shop .hw-line-name small { font-size: clamp(var(--t-micro), var(--t-micro) + (100vw - 1024px) / 170, var(--t-small)); }
/* The one primary: the gold plate (shell.css, Forged Steel). Here only when it shows. */
/* The Game Master window (windows/game-master-body.js): plain rows under Forged Steel section heads. */
.gm-part { margin-bottom: 12px; }
.gm-row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 4px 0; }
.gm-field { flex: 1 1 8em; min-width: 0; width: auto; box-sizing: border-box; }
.gm-why, .gm-grant-why { display: block; width: 100%; margin: 4px 0; }
.gm-list, .gm-more { margin: 4px 0; padding: 0; list-style: none; max-height: 16em; overflow-y: auto; }
.gm-pick { width: 100%; text-align: left; }
.gm-facts { margin: 4px 0; color: var(--ink); }
.gm-more { color: var(--ink-2); font-size: var(--t-micro); }
.gm-confirm { margin-top: 6px; }
.gm-ask { margin: 4px 0; color: var(--gold-2); }
.gm-said { min-height: 1.4em; margin: 0; color: var(--gold-2); }
.gm-none.is-on { display: block; }
.hw-primary { display: none; white-space: nowrap; cursor: pointer; }
.hw-primary.is-on { display: inline-block; }
.hw-primary:focus-visible { outline: 2px solid var(--aqua-2); outline-offset: 2px; }
.hw-tools, .hw-bulk { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 8px; }
.hw-bulk { display: none; padding: 6px 8px; background: var(--bg-1); box-shadow: var(--hw-well); }
.hw-bulk.is-on { display: flex; }
.hw-burying { display: none; align-items: center; gap: 6px; margin-top: 8px; padding: 6px 8px; background: var(--bg-1); box-shadow: var(--hw-well); }
.hw-burying.is-on { display: flex; }
/* While a stack burns its line takes the row Dispatch loot stood on: at a laptop's height the two ran off the window's foot together. */
.hw-inv:has(.hw-burying.is-on) .hw-tools { display: none; }
.hw-burying-q { flex: 1; }
/* "Equip upgrades": what the press puts on, in words, beside the button (src/shell/widgets/upgrade-line.js). */
.hw-upgrade { display: none; flex-wrap: wrap; align-items: center; gap: 4px 8px; margin-top: 8px; padding: 6px 8px; background: var(--bg-1); box-shadow: var(--hw-well); }
.hw-upgrade.is-on { display: flex; }
.hw-upgrade-q { flex: 1; min-width: 0; margin: 0; color: var(--ink-2); }
.hw-upgrade .hw-primary { display: inline-block; flex: none; }
/* A gear control's own words (gear-gate.js, the press's answer): on the line it was pressed on, never only at the
   window's foot (Tyler 2026-10-24: an Equip refused off-screen read as "nothing happened"). */
.hw-why { flex-basis: 100%; margin: 4px 0 0; font-size: var(--t-micro); color: var(--ink); }
.hw-why:empty { display: none; }
.hw-upgrade .hw-why { margin: 0; }
.hw-amt { display: flex; align-items: center; gap: 4px; padding: 4px 0; }
.hw-amt-n { width: 6em; }
.hw-selcount { flex: 1; font-weight: 700; font-variant-numeric: lining-nums tabular-nums; }
.hw-tools [data-hs-act="sell-cat"] { display: none; }
.hw-tools [data-hs-act="sell-cat"].is-on { display: inline-block; }
/* Its well and gold bar are the Forged Steel confirmation's (shell.css). */
.hw-confirm { display: none; margin-top: 8px; padding: 8px 10px; }
.hw-confirm.is-on { display: block; }
.hw-confirm-q { margin: 0; font-weight: 700; color: var(--ink); }
.hw-confirm-note { margin: 2px 0 0; font-size: var(--t-micro); color: var(--ink-2); }
.hw-confirm-note:empty { display: none; }
.hw-sell-note { margin: 6px 0 0; font-size: var(--t-micro); color: var(--ink-2); }
.hw-sell-note:empty { display: none; }
.hw-confirm-do { display: flex; gap: 6px; margin-top: 8px; }
.hw-confirm-do .hw-primary { display: inline-block; }
.hw-pane:has(.hw-confirm.is-on) .hw-pick .hw-primary { display: none; }
/* The answer to a press stays in view wherever the window is scrolled, in the confirmation's well (shell.css), not
   small grey text under the last row (Tyler 2026-11-01: "it was hard to see"). */
.hs-win .hh-intent-msg:where(:not(.ca-msg)) { margin-top: 6px; font-size: var(--t-small); color: var(--ink); }
.hs-win .hh-intent-msg:not(:empty, .ca-msg) { position: sticky; bottom: 0; z-index: 1; padding: 6px 10px; }
.is-pending .hh-intent-msg { color: var(--ink-2); }
/* Tempering's answer takes its question's place, in the flow: stuck to a phone sheet's foot it lay over the note on where the material comes from. */
.hw-temper-msg { margin: 6px 0 0; padding: 6px 10px; font-size: var(--t-small); color: var(--ink); }
.hw-temper-msg:empty { display: none; }
/* A sunk field (shell.css, Forged Steel), its magnifier inside. */
.hw-search { flex: 1; display: flex; align-items: center; gap: 6px; padding-left: 8px; color: var(--ink-3); }
.hw-search .hs-glyph { width: 16px; height: 16px; }
.hw-search .hw-q { flex: 1; width: auto; min-width: 0; border: 0; background: none; }

/* ── The item grid ── */
.hw-find { display: flex; gap: 6px; align-items: center; margin-bottom: 6px; }
.hw-sort { display: flex; align-items: center; gap: 4px; font-size: var(--t-micro); color: var(--ink-3); }
.hw-cats { display: flex; flex-wrap: wrap; margin-bottom: 8px; background: var(--bg-1); box-shadow: var(--hw-well); }
.hw-cat { min-height: 30px; padding: 0 8px; border: 0; border-bottom: 2px solid transparent; background: none; font-family: var(--f-ui); font-weight: 700; font-size: var(--t-micro); color: var(--ink-2); cursor: pointer; }
.hw-cat:hover { color: var(--ink); }
.hw-cat[aria-pressed="true"] { color: var(--gold-2); background: var(--bg-3); border-bottom-color: var(--gold); }
/* Pockets and slots: the 32 px pixel icon at ×1 inside a sunk rim (Tyler 10-18: "the items are far too big";
   Huntera-like density, our own iron and slate). Tyler 10-25 ("photo 2 bag icons are perfect", the C mock in
   art/review/window-icons-2026-10-25): the WELL grows, never the art. Sized like the action bar (hunt.css .hb-slots),
   by the viewport and not a new media query: 36 px at 1024 wide and under (every phone, unchanged), 44 px from 1280
   (Steam), snapped to even px between. The art stays 32 px: 1x is the only sharp size under 64. */
.hw-pockets { display: grid; grid-template-columns: repeat(auto-fill, round(down, clamp(36px, 36px + (100vw - 1024px) / 32, 44px), 2px)); gap: round(down, clamp(2px, 2px + (100vw - 1024px) / 128, 4px), 1px); margin: 0; padding: 0; list-style: none; }
.hw-pocket .hw-ico, .hw-slot .hw-ico { width: 32px; height: 32px; }
.hw-pocket .hw-ico .hh-icon, .hw-slot .hw-ico .hh-icon { width: 32px; height: 32px; }
.hw-pocket .hw-ico .hh-icon.is-glyph .hs-glyph, .hw-slot .hw-ico .hh-icon.is-glyph .hs-glyph { width: 20px; height: 20px; }
.hw-pocket {
  position: relative; padding: 0;
  width: round(down, clamp(36px, 36px + (100vw - 1024px) / 32, 44px), 2px); height: round(down, clamp(36px, 36px + (100vw - 1024px) / 32, 44px), 2px);
  display: grid; place-items: center;
  background: var(--bg-1); box-shadow: var(--hw-well);
  border: 2px solid transparent; border-radius: 0;
  cursor: pointer; user-select: none;
}
.hw-pocket:hover { background: var(--bg-2); }
.hw-pocket:focus-visible { outline: 2px solid var(--aqua-2); outline-offset: 1px; }
.hw-pocket.is-cur { outline: 2px solid var(--ink); outline-offset: 1px; }
.hw-pocket[aria-selected="true"] { background: var(--gold-bg); box-shadow: inset 0 0 0 2px var(--ink); }
.hw-pocket.is-drop, .hw-slot.is-drop { border-color: var(--gold-2); }
/* An equip in flight (inventory/actions.js wear): the slot and the stack moving carry the press ring
   (shell.css .is-sending) from the press until the server's envelope lands. Nothing else changes early. */
.hw-pocket.is-wearing, .hw-doll .hw-slot.is-wearing { cursor: progress; outline: 2px solid var(--gold-2); outline-offset: 1px; animation: hs-sending 900ms ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) { .hw-pocket.is-wearing, .hw-doll .hw-slot.is-wearing { animation: none; } }
.rar-common { --pocket-rar: var(--rar-common); }
.rar-uncommon { --pocket-rar: var(--rar-uncommon); }
.rar-rare { --pocket-rar: var(--rar-rare); }
.rar-epic { --pocket-rar: var(--rar-epic); }
.rar-legendary { --pocket-rar: var(--rar-legendary); }
.rar-mythic { --pocket-rar: var(--rar-mythic); }
.rar-unique { --pocket-rar: var(--rar-unique); }
.hw-pocket.is-gear, .hw-slot[class*="rar-"] { border-color: var(--pocket-rar, var(--line-soft)); }
.hw-pocket.rar-mythic, .hw-pocket.rar-unique, .hw-slot.rar-mythic, .hw-slot.rar-unique { border-style: double; border-width: 3px; }
.hw-pips { position: absolute; left: 1px; bottom: 1px; display: flex; gap: 1px; }
.hw-pips i { width: 2px; height: 2px; background: var(--pocket-rar, var(--ink-3)); }
/* The count: the floor size on a phone's 36 px well, the supporting size (16 px) in the 44 px well, off the art's corner. */
.hw-count {
  position: absolute; right: clamp(0px, (100vw - 1024px) / 128, 2px); bottom: clamp(-1px, -1px + (100vw - 1024px) / 128, 1px);
  font-size: clamp(var(--t-micro), var(--t-micro) + (100vw - 1024px) / 170, var(--t-small)); font-weight: 800; line-height: 1; font-variant-numeric: lining-nums tabular-nums; color: var(--ink);
  paint-order: stroke fill; -webkit-text-stroke: 3px var(--bg-0); pointer-events: none;
}
.hw-new { display: none; position: absolute; right: 1px; top: 1px; width: 6px; height: 6px; background: var(--gold-2); box-shadow: 0 0 0 1px var(--bg-0); }
.hw-pocket.is-new .hw-new { display: block; }
.hw-pocket[aria-selected="true"] .hw-new { display: none; }
.hw-lock { display: none; position: absolute; left: 1px; bottom: 3px; color: var(--ink-2); }
.hw-lock .hs-glyph { width: 12px; height: 12px; }
.hw-pocket.is-locked .hw-lock { display: block; }
.hw-barkey { position: absolute; left: 1px; top: -1px; font-size: var(--t-micro); font-weight: 700; line-height: 1; color: var(--gold-2); paint-order: stroke fill; -webkit-text-stroke: 3px var(--bg-0); }
.hw-barkey:empty { display: none; }
.hw-pick { display: none; align-items: center; gap: 8px; min-height: 56px; margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--line-soft); }
.hw-pick.is-on { display: flex; }
.hw-pick-ico { width: 40px; height: 40px; display: grid; place-items: center; }
.hw-pick-name { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.hw-pick-name b { color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hw-pick-name small { font-size: var(--t-micro); color: var(--ink-2); font-variant-numeric: lining-nums tabular-nums; }
.hw-keys { margin: 8px 2px 0; font-size: var(--t-micro); color: var(--ink-3); line-height: 1.35; }
.hw-loot { margin: 0; padding: 0; list-style: none; }
.hw-loot-row { display: flex; align-items: center; gap: 8px; min-height: 52px; border-top: 1px solid var(--line-soft); }
.hw-loot-row .hw-ico { width: 40px; height: 40px; }
.hw-loot-row .hw-ico .hh-icon { width: 32px; height: 32px; }
.hw-loot-name { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.hw-loot-name small { font-size: var(--t-micro); color: var(--ink-2); font-variant-numeric: lining-nums tabular-nums; }
.hw-loot-note { margin: 8px 2px 0; font-size: var(--t-micro); color: var(--ink-3); }

/* ── The context menu: a plain list beside the stack ── */
/* Its frame and floor are the Forged Steel popup's (shell.css). */
.hw-menu {
  display: none; position: fixed; z-index: 40; min-width: 200px; padding: 2px;
  font-family: var(--f-ui); font-size: var(--t-small); color: var(--ink);
  box-shadow: 0 8px 22px color-mix(in srgb, var(--world-shadow) 55%, transparent);
}
.hw-menu.is-on { display: flex; flex-direction: column; }
.hw-menu-title { padding: 4px 8px 6px; font-family: var(--f-label); font-size: var(--t-micro); letter-spacing: .04em; color: var(--ink-3); border-bottom: 1px solid var(--line-soft); }
.hw-mi { min-height: 34px; padding: 0 10px; text-align: left; border: 0; border-radius: 0; background: none; font-family: var(--f-ui); font-size: var(--t-small); color: var(--ink); cursor: pointer; }
.hw-mi:hover:not(:disabled) { background: var(--surf-panel); }
.hw-mi:disabled { color: var(--ink-3); cursor: default; }
.hw-mi[aria-pressed="true"] { color: var(--gold-2); }
/* Why the entry above is off, in words (say-why: a title alone never reaches a phone). */
.hw-mi-why { max-width: 280px; padding: 0 10px 6px; font-size: var(--t-micro); color: var(--ink-2); }
.hw-menu-sub { padding: 6px 8px 2px; font-size: var(--t-micro); color: var(--ink-3); border-top: 1px solid var(--line-soft); }
.hw-menu-rules { display: flex; flex-direction: column; }

/* ── The tooltip ── */
/* Its frame and floor are the Forged Steel popup's (shell.css). */
.hw-tip {
  display: none; position: fixed; z-index: 50; width: 280px; padding: 6px 8px; pointer-events: none;
  box-shadow: 0 8px 22px color-mix(in srgb, var(--world-shadow) 55%, transparent);
  font-family: var(--f-ui); font-size: var(--t-micro); color: var(--ink-2); line-height: 1.35;
}
.hw-tip.is-on { display: block; }
.hw-tip-name { display: block; font-size: var(--t-small); color: var(--ink); }
.hw-tip-name[class*="rar-"] { color: var(--pocket-rar); }
.hw-tip-kind { display: block; color: var(--ink-3); }
.hw-tip-flavour { display: block; margin-top: 4px; color: var(--ink-2); }
.hw-tip-stats { display: grid; grid-template-columns: 1fr auto; gap: 0 8px; margin: 6px 0 0; }
.hw-tip-stats dt { color: var(--ink-2); }
.hw-tip-stats dd { margin: 0; font-weight: 700; color: var(--ink); text-align: right; font-variant-numeric: lining-nums tabular-nums; }
.hw-tip-cmp { margin: 6px 0 0; color: var(--ink-3); }
.hw-tip-delta { margin: 0; padding: 0; list-style: none; font-weight: 700; font-variant-numeric: lining-nums tabular-nums; }
.hw-tip-delta .is-gain { color: var(--green); }
.hw-tip-delta .is-loss { color: var(--red); }
.hw-tip-need { margin: 6px 0 0; color: var(--ink-2); }
.hw-tip-need.is-short { color: var(--red); }
.hw-tip-line { margin: 6px 0 0; }
.hw-tip-line small { display: block; font-family: var(--f-label); font-weight: 700; letter-spacing: .04em; color: var(--ink-3); }

/* ── The Inventory (src/shell/windows/inventory/*): the doll beside the grid, one iron-and-slate window ── */
.hw-inv { outline: none; }
/* THE FOOT STAYS IN VIEW (newcomer panel 2026-11-01: spaces, gold and Dispatch loot under the fold at 1366x768): the doll and the bag scroll between the toolbar and it; whatever else opens scrolls the whole. */
.hs-win[data-hs-win="inventory"] .hs-win-body { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; overflow: hidden; }
[data-hs-win="inventory"] .hw-inv { flex: 1; min-height: 0; display: flex; flex-direction: column; overflow-y: auto; }
[data-hs-win="inventory"] .hw-inv > * { flex: none; }
[data-hs-win="inventory"] .hw-inv > .hw-inv-scroll { flex: 1 1 auto; min-height: 96px; overflow-y: auto; }
[data-hs-win="inventory"] .hw-cats { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
/* The tabs and the search share a line: at 1366x768 the bag kept 97 px between its toolbar and its foot, two rows beside a cut doll (door panel 2026-11-04). */
[data-hs-win="inventory"] .hw-inv-head { display: flex; align-items: flex-end; gap: 10px; margin-bottom: 6px; }
[data-hs-win="inventory"] .hw-inv-head > .hw-tabs { flex: none; margin-bottom: 0; }
[data-hs-win="inventory"] .hw-inv-head > .hw-find { flex: 1 1 0; min-width: 0; margin-bottom: 0; }
[data-hs-win="inventory"] .hw-cat { flex: none; padding: 0 6px; }
.hw-inv:focus-visible { outline: 1px dashed var(--aqua-2); outline-offset: 2px; }
.hw-inv-cols { display: flex; align-items: flex-start; gap: 10px; }
.hw-inv-grid { flex: 1; min-width: 0; min-height: 186px; padding: 4px; background: var(--surf-sunken); box-shadow: var(--hw-well); }
.hw-cats.is-off, .hw-tools.is-off { display: none; }
/* The worn set's armor weights, under both columns (doll.js patchWeights): a label, then one plain line. */
.hw-weights { display: none; margin: 6px 0 0; font-size: var(--t-micro); color: var(--ink-2); font-variant-numeric: lining-nums tabular-nums; cursor: help; }
.hw-weights.is-on { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 12px; }
.hw-weights span { white-space: nowrap; }
.hw-weights span:empty { display: none; }
.hw-weights small { font-family: var(--f-label); font-weight: 700; letter-spacing: .04em; color: var(--ink-3); }
.hw-inv-foot { display: flex; align-items: center; gap: 10px; margin-top: 6px; font-size: var(--t-micro); color: var(--ink-2); }
.hw-capacity { display: none; flex: 1; min-width: 0; align-items: center; gap: 6px; }
.hw-capacity.is-on { display: flex; }
.hw-capbar { position: relative; flex: 1; height: 6px; background: var(--bg-1); box-shadow: var(--hw-well); }
.hw-capfill { position: absolute; top: 0; left: 0; bottom: 0; width: 0; background: var(--gold-3); }
.hw-capacity.is-full .hw-capfill { background: var(--red); }
.hw-captext { font-size: var(--t-micro); white-space: nowrap; font-variant-numeric: lining-nums tabular-nums; }
.hw-adv-toggle { display: flex; align-items: center; gap: 4px; white-space: nowrap; cursor: pointer; }
.hw-gold { margin-left: auto; color: var(--gold-2); font-weight: 800; white-space: nowrap; font-variant-numeric: lining-nums tabular-nums; }
.hw-tools .hw-value { margin-left: auto; font-size: var(--t-micro); color: var(--ink-3); font-variant-numeric: lining-nums tabular-nums; }
.hw-elsewhere { display: none; margin-top: 6px; }
.hw-elsewhere.is-on { display: block; }
.hw-advanced { display: none; margin-top: 8px; padding-top: 4px; border-top: 1px solid var(--line-soft); }
.hw-advanced.is-on { display: block; }
.hw-imbue { display: none; }
.hw-imbue.is-on { display: block; }

/* The paper doll: three across, five down, in the shape of a body. The worn set reads a step above the bag (Tyler 10-25:
   the 2x doll was "a bit" big): the same 1x art in a roomier well, 36 px on a phone, 52 px from 1280 (the bag's 44 + 8). */
.hw-doll { flex: none; display: grid; grid-template-columns: repeat(3, round(down, clamp(36px, 36px + (100vw - 1024px) / 16, 52px), 2px)); grid-auto-rows: round(down, clamp(36px, 36px + (100vw - 1024px) / 16, 52px), 2px); gap: round(down, clamp(4px, 4px + (100vw - 1024px) / 128, 6px), 1px); padding: round(down, clamp(4px, 4px + (100vw - 1024px) / 128, 6px), 1px); background: var(--surf-sunken); box-shadow: var(--hw-well); }
.hw-slot {
  position: relative; padding: 0;
  width: round(down, clamp(36px, 36px + (100vw - 1024px) / 16, 52px), 2px); height: round(down, clamp(36px, 36px + (100vw - 1024px) / 16, 52px), 2px);
  display: grid; place-items: center;
  background: var(--bg-1); box-shadow: var(--hw-well);
  border: 2px solid transparent; border-radius: 0; cursor: pointer;
}
.hw-slot:hover { background: var(--bg-2); }
.hw-slot.is-empty { background: var(--bg-0); }
.hw-slot:focus-visible { outline: 2px solid var(--aqua-2); outline-offset: 1px; }
.hw-slot.is-open { outline: 2px solid var(--ink); outline-offset: 1px; }
.hw-ghost { display: none; color: var(--ink-3); opacity: .45; }
.hw-ghost .hs-glyph { width: round(down, clamp(18px, 18px + (100vw - 1024px) / 64, 22px), 2px); height: round(down, clamp(18px, 18px + (100vw - 1024px) / 64, 22px), 2px); }
.hw-slot.is-empty .hw-ghost { display: block; }
.hw-slot.is-empty .hw-ico { display: none; }
.hw-role { margin: 4px 2px 0; font-weight: 700; color: var(--ink); }
.hw-totals { display: flex; justify-content: space-between; margin: 6px 2px 0; }
.hw-totals div { display: flex; flex-direction: column; }
.hw-totals dt { font-size: var(--t-micro); color: var(--ink-3); }
.hw-totals dd { margin: 0; font-weight: 800; color: var(--ink); font-variant-numeric: lining-nums tabular-nums; }
.hw-slotline { display: none; margin-top: 8px; padding-top: 6px; border-top: 1px solid var(--line-soft); }
.hw-slotline.is-on { display: block; }
.hw-slothead { margin: 0 2px 4px; }
.hw-worn { display: none; align-items: center; gap: 8px; min-height: 40px; }
.hw-worn.is-on { display: flex; }
.hw-worn .hw-ico, .hw-fit .hw-ico { width: 36px; height: 36px; }
.hw-worn .hw-ico .hh-icon, .hw-fit .hw-ico .hh-icon { width: 32px; height: 32px; }
.hw-worn-name { flex: 1; font-weight: 700; color: var(--ink); }
.hw-fits { margin: 0; padding: 0; list-style: none; }
.hw-fit { display: flex; align-items: center; gap: 8px; min-height: 44px; border-top: 1px solid var(--line-soft); }
.hw-fit-name { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.hw-fit-delta { font-size: var(--t-micro); font-weight: 700; color: var(--ink-2); font-variant-numeric: lining-nums tabular-nums; }
.hw-fit-delta .is-gain { color: var(--green); }
.hw-fit-delta .is-loss { color: var(--red); }
.hw-fit-need { font-size: var(--t-micro); color: var(--red); }
.hw-fit-need:empty { display: none; }

/* ── Storage (src/shell/windows/storage.js): the same pockets, two grids ── */
.hw-store .hw-pockets { min-height: round(down, clamp(36px, 36px + (100vw - 1024px) / 32, 44px), 2px); padding: 4px; background: var(--surf-sunken); box-shadow: var(--hw-well); }
.hw-store.is-off .hw-pocket { cursor: default; opacity: .6; }
.hw-store-n { font-family: var(--f-ui); font-weight: 400; letter-spacing: 0; color: var(--ink-3); }
.hw-store-note { margin: 0 2px 4px; }

/* ── Hunts (src/shell/windows/hunts.js): the grounds as lines, the picked one's page beside them ──
   FORGED STEEL (Tyler approved 2026-10-24): two panels in steel, the list and the page. The window does not scroll:
   the list scrolls in its panel, the page in its own (.hw-hd-page), and Enter stands at the page's foot OUTSIDE
   that scroller, so the lineup and the drops never slide under it. */
.hs-win[data-hs-win="hunts"] .hs-win-body { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; overflow: hidden; }
.hw-hunts { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.hw-hunts-now, .hw-hunts-reco { margin: 0 2px 8px; }
.hw-hunts-cols { flex: 1; min-height: 0; display: grid; grid-template-columns: 286px minmax(0, 1fr); grid-template-rows: minmax(0, 1fr); column-gap: 12px; }
/* The list: a steel panel of lines, one a ground; the picked one is lifted, outlined in gold, a gold bar at its left. */
.hw-hunt-list { min-height: 0; overflow: auto; margin: 0; padding: 0; list-style: none; background: var(--fill-1); border: 2px solid var(--steel-edge); }
.hw-hunt { position: relative; display: flex; align-items: flex-start; gap: 10px; padding: 10px 10px 11px 14px; border-bottom: 2px solid var(--steel-sep); cursor: pointer; }
.hw-hunt:last-child { border-bottom: 0; }
.hw-hunt:hover { background: var(--fill-2); }
.hw-hunt.is-picked { background: var(--fill-3); box-shadow: inset 0 0 0 2px var(--gold), inset 6px 0 0 var(--gold), inset 8px 4px 0 var(--fill-0); }
.hw-hunt:focus-visible { outline: 2px solid var(--aqua-2); outline-offset: -2px; }
.hw-hunt-glyph { flex: none; display: grid; place-items: center; width: 24px; height: 24px; margin-top: 1px; color: var(--ink-3); }
.hw-hunt-glyph .hs-glyph { width: 22px; height: 22px; }
.hw-hunt.is-picked .hw-hunt-glyph { color: var(--ink-2); }
.hw-hunt-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.hw-hunt-name { font-size: var(--t-body); font-weight: 700; color: var(--ink); }
.hw-hunt-band, .hw-hd-band { font-size: var(--t-micro); color: var(--ink-2); font-variant-numeric: lining-nums tabular-nums; }
.hw-hunt-fit:not(:empty)::before { content: ' · '; color: var(--ink-3); }
/* The band against the Level: words always, the tone a second cue (in range / above / far above / below). */
.hw-hunt-fit[data-tone="in"] { color: var(--green); }
.hw-hunt-fit[data-tone="above"], .hw-hunt-fit[data-tone="far"] { color: var(--red); }
.hw-hunt-sub { display: block; font-size: var(--t-micro); color: var(--ink-2); font-variant-numeric: lining-nums tabular-nums; }
.hw-hunt-fits { font-weight: 700; color: var(--gold-2); }
/* The separator keeps to the line it ends: a wrapped line never starts with a dot (the narrow list, 2026-11-04). */
.hw-hunt-fits:not(:empty) + .hw-hunt-bestline:not(:empty)::before { content: '\00a0· '; font-weight: 400; color: var(--ink-3); }
.hw-hunt-fits:empty, .hw-hunt-bestline:empty { display: none; }
/* The page: a steel panel, its left edge in dim gold toward the list; its text scrolls, its foot stays. */
.hw-hunt-detail { min-width: 0; min-height: 0; display: flex; flex-direction: column; background: var(--fill-1); border: 2px solid var(--steel-edge); border-left-color: var(--steel-rule); }
.hw-hunt-detail[hidden] { display: none; }
.hw-hd-page { flex: 1 1 auto; min-height: 0; overflow: auto; padding: 8px 18px 12px; }
.hw-hd-back { display: none; }
.hw-hd-head { margin-bottom: 8px; }
/* The ground's name, as a place is named: Cinzel in gold (ART_DIRECTION §10). */
.hw-hd-name { margin: 0; font-family: var(--f-display); font-size: calc(var(--t-h2) * 1.2); font-weight: 700; line-height: 1.15; letter-spacing: .05em; color: var(--gold-2); }
/* Under the level line, a dim gold rule with the small diamond at its middle (assets/ui/steel-diamond.png, x2). */
.hw-hd-band { position: relative; margin: 2px 0 0; padding-bottom: 22px; font-size: var(--t-small); }
.hw-hd-band::after { content: ''; position: absolute; left: -2px; right: -2px; bottom: 10px; height: 2px; background: var(--steel-rule); }
.hw-hd-band::before { content: ''; position: absolute; z-index: 1; left: calc(50% - 7px); bottom: 4px; width: 14px; height: 14px;
  background: url('../../assets/ui/steel-diamond.png') 0 0 / 14px 14px no-repeat; image-rendering: pixelated; }
.hw-hd-who { margin: 0; font-size: var(--t-small); color: var(--ink-2); }
.hw-hunt-warn { margin: 1px 0 0; font-size: var(--t-micro); color: var(--red); }
.hw-hunt-warn:empty { display: none; }
.hw-hd-theme { margin: 2px 0 0; font-size: var(--t-small); line-height: 1.45; color: var(--ink); }
/* Each section head is a Forged Steel head (shell.css): Cinzel in gold over a rule. */
.hw-hd-h { margin: 18px 0 10px; }
/* Who lives here: each creature as the world draws it (x2), in even columns, all standing at the tallest one's
   height (--stand-h, set from the drawn art) on a pixel ground shadow (assets/ui/ground-shadow.png, x2), its name
   and how common it is under it. */
.hw-hd-lineup { display: grid; grid-template-columns: repeat(auto-fill, minmax(124px, 1fr)); row-gap: 14px; column-gap: 6px; margin: 0; padding: 0; list-style: none; }
.hw-hd-mon { display: flex; flex-direction: column; align-items: center; padding: 0; text-align: center; min-width: 0; }
.hw-hd-stand { display: flex; align-items: flex-end; justify-content: center; align-self: stretch; height: calc(var(--stand-h, 45px) + 6px); padding: 0 0 4px;
  background: url('../../assets/ui/ground-shadow.png') 50% 100% / 48px 10px no-repeat; image-rendering: pixelated; }
.hw-hd-mon-name { margin-top: 6px; padding: 0 4px; max-width: 100%; overflow: hidden; text-overflow: ellipsis; font-size: var(--t-small); font-weight: 700; line-height: 1.2; color: var(--ink); white-space: nowrap; }
.hw-hd-mon-how { padding: 0 4px; font-size: var(--t-micro); line-height: 1.25; color: var(--ink-3); white-space: nowrap; }
.hw-hd-sprite { display: block; image-rendering: pixelated; }
.hw-hd-mon:not(.is-drawn) .hw-hd-sprite { width: 0; height: 0; }
.hw-hd-mon[data-band="common"] .hw-hd-mon-how { color: var(--ink-2); }
.hw-hd-mon.is-carrier .hw-hd-mon-name { color: var(--rar-rare); }
/* What drops here: the hourly gear a line a tier (the lines' words in ink, what they cover muted), then each Rare and
   Trophy as its own pixel icon at x1 in a sunk well, its name in its rarity colour and its carrier under it. */
.hw-hd-sets, .hw-hd-rares, .hw-hd-mats { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 6px; }
.hw-hd-set { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: 8px; align-items: baseline; font-size: var(--t-small); color: var(--ink-2); }
.hw-hd-set-lines { font-weight: 700; color: var(--ink); }
/* The chance per kill (hunt-detail.js): one right-hand column, figures aligned. */
.hw-hd-per { font-family: var(--f-ui); font-weight: 400; letter-spacing: 0; color: var(--ink-3); }
.hw-hd-odds { font-size: var(--t-small); font-weight: 700; color: var(--ink); text-align: right; white-space: nowrap; font-variant-numeric: lining-nums tabular-nums; }
.hw-hd-rare .hw-hd-odds { grid-column: 3; grid-row: 1 / 3; }
.hw-hd-rare-name, .hw-hd-rare-by { grid-column: 2; }
.hw-hd-rare { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; grid-template-rows: auto auto; column-gap: 10px; align-items: center; }
.hw-hd-rare .hw-ico { grid-row: 1 / 3; width: 40px; height: 40px; background: var(--bg-0); box-shadow: var(--hw-well); }
.hw-hd-rare .hw-ico .hh-icon { width: 32px; height: 32px; }
.hw-hd-rare-name { font-weight: 700; color: var(--rar-rare); }
.hw-hd-rare.is-trophy .hw-hd-rare-name { color: var(--rar-legendary); }
.hw-hd-rare-by { font-size: var(--t-micro); color: var(--ink-2); }
.hw-hd-h:has(+ .hw-hd-sets:empty), .hw-hd-h:has(+ .hw-hd-rares:empty), .hw-hd-h:has(+ .hw-hd-mats:empty) { display: none; }
.hw-hunt-party { margin: 8px 0 0; font-size: var(--t-micro); color: var(--ink-2); }
.hw-hd-best { margin: 0; font-size: var(--t-small); color: var(--ink-2); font-variant-numeric: lining-nums tabular-nums; }
.hw-hd-best[hidden], .hw-hunt-party[hidden], .hw-hd-bests[hidden] { display: none; }
/* Each pull: what the ground spawns at this pick, and the step beside it. */
.hw-pull { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 12px; }
.hw-hunt-facts { flex: 1 1 auto; margin: 0; font-size: var(--t-micro); color: var(--ink-2); font-variant-numeric: lining-nums tabular-nums; }
.hw-tiers { display: none; align-items: center; gap: 8px; }
.hw-tiers.is-on { display: flex; }
.hw-tiers .hh-seg { min-height: 36px; padding: 0 12px; }
.hw-tiers .hh-seg[hidden] { display: none; }
.hw-tiers .hh-segs:not(:has(.hh-seg:not([hidden]))) { display: none; }
.hw-tier-read:empty { display: none; }
.hw-tier-note { margin: 2px 0 0; font-size: var(--t-micro); color: var(--ink-3); }
.hw-tier-note:empty { display: none; }
.hw-hunt-pack { margin: 8px 0 0; font-size: var(--t-micro); color: var(--ink-2); }
.hw-hunt-pack:empty { display: none; }
/* Go as: the setups as lines, chosen the way a ground is (lifted, outlined in gold, the gold bar): the weapon's own
   icon, the name, the role it plays, and the bar's first four actions for the setup that is on. */
.hw-go-list { display: flex; flex-direction: column; gap: 2px; }
.hw-go { display: flex; align-items: center; gap: 8px; width: 100%; min-height: 48px; padding: 4px 8px 4px 12px; border: 0; border-radius: 0; background: none; color: inherit; font: inherit; text-align: left; cursor: pointer; }
.hw-go:hover:not(:disabled) { background: var(--fill-2); }
.hw-go.is-picked { background: var(--fill-3); box-shadow: inset 0 0 0 2px var(--gold), inset 6px 0 0 var(--gold); }
.hw-go:disabled { cursor: default; }
.hw-go:disabled:not(.is-picked) { opacity: .55; }
.hw-go:focus-visible { outline: 2px solid var(--aqua-2); outline-offset: -2px; }
.hw-go .hw-go-weapon { width: 36px; height: 36px; background: var(--bg-0); box-shadow: var(--hw-well); }
.hw-go .hw-go-weapon .hh-icon { width: 32px; height: 32px; }
.hw-go-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.hw-go-name { font-weight: 700; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hw-go-what { font-size: var(--t-micro); color: var(--ink-3); }
.hw-go-bar { flex: none; display: flex; gap: 2px; }
.hw-go-bar .hh-icon { width: 32px; height: 32px; }
.hw-go-note { margin: 4px 0 0; font-size: var(--t-micro); color: var(--ink-2); }
.hw-go-note:empty { display: none; }
/* Before you go: plain lines, what the bar spends and what it costs; a line that stops the hunt reads red. */
.hw-before { margin: 0; padding: 0; list-style: none; }
.hw-before-line { padding: 1px 0; font-size: var(--t-micro); line-height: 1.35; color: var(--ink-2); font-variant-numeric: lining-nums tabular-nums; }
.hw-before-line.is-short { color: var(--red); }
.hw-hd-h:has(+ .hw-before:empty) { display: none; }
/* With a party: the way to one, from the ground that wants one. */
.hw-hd-party[hidden] { display: none; }
.hw-hd-party-why { margin: 0 0 6px; font-size: var(--t-micro); color: var(--ink-2); }
.hw-hd-party-do { display: flex; flex-wrap: wrap; gap: 6px; }
.hw-hd-party-do .hh-tool { min-height: 36px; padding: 0 10px; background: var(--bg-0); box-shadow: var(--hw-well); }
.hw-bring { display: contents; }
.hw-bring-none { margin: 6px 0 0; font-size: var(--t-micro); color: var(--ink-3); }
.hw-bring-none:empty { display: none; }
/* The one primary at the page's foot, below its scroller (never over the page); the server's answer beside it.
   Solid at any window opacity: it is the press that matters most. Enter goes somewhere: a dark arrow follows it. */
/* Call out on a ground's page (boss-call-pane.js): the press, then its warning in the confirmation's well. */
.hw-hd-call[hidden] { display: none; }
.hw-call-line { margin: 0 0 6px; font-size: var(--t-micro); color: var(--ink-2); }
.hw-call-line:empty { display: none; }
.hw-call-press { min-height: 36px; padding: 0 10px; background: var(--bg-0); box-shadow: var(--hw-well); }
.hw-call-press[hidden] { display: none; }
.hw-hd-foot { flex: none; display: flex; align-items: center; gap: 10px; padding: 6px 18px 8px; border-top: 2px solid var(--steel-sep); background: var(--bg-1); }
.hw-hd-foot .hh-intent-msg { flex: 1; min-width: 0; margin: 0; }
.hw-enter-why { flex: 1; min-width: 0; margin: 0; font-size: var(--t-small); color: var(--ink); }
.hw-enter-why:empty { display: none; }
.hw-hd-foot [data-hs-act="leave-party"] { flex: none; }
.hw-hd-foot [data-hs-act="leave-party"][hidden] { display: none; }
.hw-hd-foot .hw-primary { flex: none; margin-left: auto; min-height: 44px; padding: 0 16px 0 20px; font-size: var(--t-body); letter-spacing: .1em; }
.hw-hunt-enter::after { content: ''; display: inline-block; width: 6px; height: 10px; margin-left: 10px; vertical-align: 1px;
  background: url('../../assets/ui/steel-arrow.png') 0 0 / 6px 10px no-repeat; image-rendering: pixelated; }

/* ── The skills: two ledgers, two compact entries to a row ── */
.hw-skill-group { margin-bottom: 2px; }
.hw-skill-head { margin: 2px 2px 1px; }
.hw-skill-list { display: grid; grid-template-columns: 1fr; gap: 0 12px; margin: 0; padding: 0; list-style: none; }
/* ONE LINE A SKILL, THEN ITS UNLOCK (2026-10-22: the XP to go on a line of its own cost Gathering and crafting
   ~130 px at 1440x900, where the docked window stops above the bar and must not scroll, AW-17): glyph, name, the
   progress bar, the XP to go and the level on the first line; the unlock under the name. 2px/3px a row (v0.2.64: the
   Leather Belt wrapped Crafting's unlock to two lines and the window grew 7 px past its 516). */
.hw-skill { min-width: 0; display: grid; grid-template-columns: 18px max-content minmax(24px, 1fr) minmax(0, auto) auto; grid-template-areas: "glyph name bar xp lv" ". next next next next";
  align-items: center; column-gap: 6px; row-gap: 1px; padding: 2px 0 3px; border-top: 1px solid var(--line-soft); }
.hw-skill-top, .hw-skill-mid { display: contents; }
.hw-skill-glyph { grid-area: glyph; }
.hw-skill-name { grid-area: name; }
.hw-skill-bar { grid-area: bar; }
.hw-skill-xp { grid-area: xp; }
.hw-skill-lv { grid-area: lv; min-width: 30px; text-align: right; }
.hw-skill-next { grid-area: next; }
.hw-skill-glyph { flex: none; display: grid; place-items: center; width: 18px; color: var(--ink-2); }
.hw-skill-glyph .hs-glyph { width: 16px; height: 16px; }
.hw-skill-name { flex: 1; min-width: 0; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hw-skill-lv { color: var(--gold-2); font-variant-numeric: lining-nums tabular-nums; }
.hw-skill-bar { position: relative; display: block; flex: 1; min-width: 24px; height: 4px; background: var(--bg-1); box-shadow: var(--hw-well); }
.hw-skill-fill { position: absolute; top: 0; left: 0; bottom: 0; width: 0; background: var(--gold-3); }
.hw-skill-xp { flex: none; min-width: 0; }   /* the name never clips ("Inner Flame"); the XP line yields first */
.hw-skill-xp, .hw-skill-next { font-size: var(--t-micro); line-height: 1.2; color: var(--ink-3); font-variant-numeric: lining-nums tabular-nums; overflow: hidden; text-overflow: ellipsis; }
.hw-skill-xp { white-space: nowrap; }
.hw-skill-next { white-space: normal; color: var(--ink-2); }
.hw-skill-next:empty { display: none; }

/* ── Gathering and crafting: a skill is a door to its work (src/shell/windows/work.js) ── */
.hw-trade .hw-work-now { margin: 0 0 8px; }
.hw-trade-ledger.is-off { display: none; }
.hw-skill[data-hs-act] { cursor: pointer; }
.hw-skill[data-hs-act]:hover, .hw-skill[data-hs-act]:focus-visible { background: var(--surf-panel); }
.hw-skill[data-hs-act]:focus-visible { outline: 2px solid var(--aqua-2); outline-offset: -2px; }
.hw-skill.is-working .hw-skill-name { color: var(--gold-2); }
.hw-skill[data-hs-act] .hw-skill-lv::after { content: ' ›'; color: var(--ink-3); }
.hw-work-hint { margin-bottom: 4px; }
.hw-work { display: none; }
.hw-work.is-on { display: block; }
.hw-work-head { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; }
.hw-work-title { flex: 1; min-width: 0; color: var(--ink); }
/* The open skill's own bar beside its title (the ledger's, src/shell/windows/skills.js), once the server's level is read:
   the title keeps its own width, the bar takes what is left (up to a ledger bar's length), the level stays at the edge. */
.hw-work-head.has-xp .hw-work-title { flex: none; white-space: nowrap; }
.hw-work-head .hw-skill-bar { flex: 1 1 24px; max-width: 160px; }
.hw-work-head .hw-skill-lv { margin-left: auto; }
.hw-work-head:not(.has-xp) .hw-skill-bar, .hw-work-head:not(.has-xp) .hw-skill-xp { display: none; }
/* TOWN WORK BETWEEN PAYOUTS (src/shell/town-ticker.js): what the server's engine has certainly done and not yet paid
   reads as pending, never as a control: italic in a quieter ink, and a translucent segment after a bar's fill. */
.hw-skill-ahead { position: absolute; top: 0; bottom: 0; left: 0; width: 0; background: var(--line-strong); }
.hw-burying-q .is-ahead, .hw-count.is-ahead { font-style: italic; color: var(--ink-2); }
.hw-skill-xp.is-ahead { font-style: italic; }
.hw-work-row .hw-line-name small { white-space: normal; }
.hw-work-why { color: var(--ink-3); }
.hw-work-why:empty, .hw-work-fee:empty, .hw-work-end:empty { display: none; }
.hw-work-fee { color: var(--ink-3); }
.hw-work-row.is-on .hw-line-name b, .hw-work-row.is-on .hw-work-why { color: var(--gold-2); }
.hw-work-row.is-locked .hw-ico { opacity: .5; }
/* "Make N": the amount sits under the row's words, a quiet well (hunt.css .hh-segs); a locked row has none. */
.hw-work-n { align-self: flex-start; margin-top: 4px; }
.hw-work-n .hh-seg { min-width: 32px; min-height: 24px; padding: 0 6px; }
.hw-work-row.is-locked .hw-work-n { display: none; }

/* ── The shop and hunt prep ── */
.hw-qty { width: 64px; }
.hw-add { display: flex; gap: 6px; align-items: center; margin-top: 8px; }
.hw-slot-buy { margin-top: 8px; }
.hw-slot-buy[hidden], .hw-title .hh-tool[hidden] { display: none; }
.hw-add .hh-select { flex: 1; min-width: 0; }
.hw-add .hw-preset-name { flex: 1; width: auto; }
.hw-ready { margin: 0 0 6px; padding: 0; list-style: none; }
.hw-ready-row { padding: 6px 0 8px; border-top: 1px solid var(--line-soft); }
.hw-ready-line { margin: 0; color: var(--red); }
.hw-ready-row.is-ready .hw-ready-line { color: var(--green); }
.hw-checks { margin: 4px 0 0; padding: 0 0 0 14px; font-size: var(--t-micro); color: var(--ink-2); }
.hw-check.is-short { color: var(--red); }
.hw-use { color: var(--gold-2); }
/* A setup's Delete asks once: "Delete it?" in red with Keep beside it, in the place Save here and Use stood. */
.hw-keep { display: none; }
.hw-setup.is-arming .hw-keep { display: inline-block; }
.hw-setup.is-arming .hw-del { color: var(--red); }
.hw-setup.is-arming [data-hs-act="save-over"], .hw-setup.is-arming .hw-use { display: none; }
/* The setup the hero is on: "In use" in gold, and no Delete (its place kept so the rows line up). */
.hw-setup.is-current small, .hw-title.is-current small { color: var(--gold-2); }
.hw-setup.is-current .hw-del { visibility: hidden; }
.hw-town-only { display: none; }
.hw-town-only.is-on { display: block; }

/* ── Phone, landscape: the one sheet; the same density, tighter rhythm ── */
@media (max-width: 540px), (max-height: 540px) and (max-width: 1024px) {
  .hw-shop > .hw-tabs { top: -8px; margin-top: -8px; padding-top: 8px; }   /* the sheet's body padding */
  /* A Shop row on the half-wide sheet: the icon and name on one line, the count and the price under them (the name had 23 px and read "C…"). */
  .hw-shop .hw-line { flex-wrap: wrap; justify-content: flex-end; }
  .hw-shop .hw-line-name { flex: 1 1 calc(100% - 52px); }
  /* The phone sheet scrolls as one, its foot under the list. */
  .hs-win[data-hs-win="inventory"] .hs-win-body { display: block; overflow: auto; }
  [data-hs-win="inventory"] .hw-inv { display: block; overflow-y: visible; }
  [data-hs-win="inventory"] .hw-inv > .hw-inv-scroll { overflow-y: visible; }
  [data-hs-win="inventory"] .hw-inv-head { display: contents; }
  [data-hs-win="inventory"] .hw-inv-head > .hw-tabs { margin-bottom: 8px; }
  [data-hs-win="inventory"] .hw-inv-head > .hw-find { margin-bottom: 6px; }
  .hw-keys { display: none; }
  .hw-tab { min-height: 36px; }
  .hw-cat { min-height: 36px; flex: none; }
  .hw-cats { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
  /* The phone has no height to spare: two skills to a row; the XP to go and the unlock share one line
     (all of the unlock in the tooltip). */
  .hw-skill-list { grid-template-columns: 1fr 1fr; }
  .hw-skill { display: grid; grid-template-columns: auto minmax(0, 1fr); grid-template-areas: none; column-gap: 6px; row-gap: 2px; }
  .hw-skill-top { display: flex; align-items: center; gap: 6px; }
  .hw-skill-glyph, .hw-skill-name, .hw-skill-bar, .hw-skill-xp, .hw-skill-lv, .hw-skill-next { grid-area: auto; }
  .hw-skill-top, .hw-skill-bar { grid-column: 1 / -1; }
  .hw-skill-mid { display: contents; }
  .hw-skill-next { display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical; overflow: hidden; }
  .hw-mi { min-height: 40px; }
  /* THE TOOLTIP ON A SHORT SCREEN (QA 10-24: an iron helm's was 411 px on a 390 px screen, its foot cut off): it
     runs wide, in two columns, and never past the screen's height. */
  .hw-tip { width: 460px; columns: 2; column-gap: 16px; max-height: calc(100vh - 8px); overflow: hidden; }
  .hw-tip > * { break-inside: avoid; }
  /* On touch it stands in the World beside the sheet (item-tip.js). */
  :root.is-touch .hw-tip { box-sizing: border-box; width: min(460px, calc(52vw - 16px)); columns: 150px; }
  /* This hunt on the sheet: the plan's menu under the item's name (playtest 2026-10-29: beside it, the name read one
     word a line). */
  .hw-loot-row { flex-wrap: wrap; padding: 4px 0; }
  .hw-loot-row > .hh-select { flex: 1 0 100%; min-height: 40px; }
  /* THE PICKED ITEM STAYS IN REACH (QA 10-24: Equip sat under 42 stacks, a scroll away): its line pins to the
     sheet's foot while the bag scrolls, on the sheet's own floor. */
  .hw-pick.is-on { position: sticky; bottom: -10px; z-index: 1; margin: 8px -10px 0; padding: 6px 10px 8px; background: var(--bg-1); border-top: 2px solid var(--steel-sep); }
  .hw-work-row .hh-tool, .hw-work-head .hh-tool, .hw-work-now .hh-tool, .hw-work-n .hh-seg { min-height: 40px; }
  .hw-work-hint { display: none; }
  /* Hunts on the sheet: the list first; a pick opens the ground's page in its place, with the way back on top. */
  .hw-hunts-cols { display: flex; flex-direction: column; }
  .hw-hunt-list { flex: 1 1 auto; }
  .hw-hunt { min-height: 44px; }
  .hw-hunt-detail { display: none; }
  /* A ground's page has the sheet to itself: the list's notes wait on the list. */
  .hw-hunts.is-paged .hw-hunt-list, .hw-hunts.is-paged .hw-hunts-now, .hw-hunts.is-paged .hw-hunts-reco { display: none; }
  .hw-hunts.is-paged .hw-hunt-detail:not([hidden]) { display: flex; flex: 1 1 auto; }
  .hw-hd-back { display: inline-flex; align-items: center; min-height: 40px; margin: 0 0 4px -6px; }
  .hw-hd-foot .hw-hd-back { margin: 0; }
  .hw-hd-page { padding: 8px 12px 10px; }
  /* THE PAGE GETS THE SHEET (phone panel v0.2.83: 104 px of a 1501 px page, about 14 swipes to the drops): no second frame
     or padding round it; only the sheet's head and the foot (the way back, Enter) stand outside its scroller. */
  [data-hs-win="hunts"]:has(.is-paged) .hs-win-body { padding: 0; }
  .hw-hunts.is-paged .hw-hunt-detail:not([hidden]) { border: 0; }
  .hw-hunt-detail .hw-hd-h { margin: 12px 0 6px; }
  .hw-hd-name { font-size: var(--t-h2); }
  /* A refusal gets the foot's width, on its own line over the press (panel 2026-11-01: one word per line in 45 px). */
  .hw-hd-foot { flex-wrap: wrap; padding: 6px 12px 8px; }
  .hw-hd-foot .hh-intent-msg:not(:empty), .hw-hd-foot .hw-enter-why:not(:empty) { flex: 1 0 100%; }
  .hw-pick.is-on { flex-wrap: wrap; }
  .hw-pick.is-on .hw-pick-name { flex: 1 1 80px; }
  .hw-upgrade-q { flex: 1 0 100%; }
  /* The search gives way and the sort keeps its select, in every window that has them (panel: Sort cut at the sheet's edge). */
  .hw-find .hw-search { flex: 1 1 0; min-width: 0; }
  .hw-find .hw-sort { flex: none; }
  .hw-find .hw-sort > span { display: none; }
  /* THUMB-SIZED IN EVERY SHEET (panel 2026-11-01: Plant, Search, Add friend, the selects at 30 px; the close at 32). */
  .hs-win .hh-tool, .hs-win .hh-select, .hs-win .hh-seg, .hs-win .hh-num, .hs-win .hw-search, .hs-win .hf-name, .hs-win .st-search, .hs-win .hs-close { min-height: 40px; }
  .hs-win .hs-close { min-width: 40px; }
  .hs-win .hw-tab, .hs-win .hw-cat { min-height: 40px; }
  .hs-win input[type="checkbox"] { width: 20px; height: 20px; }
}

/* ── The Party window (src/shell/windows/party.js): invites and the finder; role glyphs ── */
.hw-roleglyph { width: 32px; height: 32px; display: grid; place-items: center; flex: none; color: var(--ink-2); background: var(--bg-1); box-shadow: var(--hw-well); }
.hw-roleglyph .hs-glyph { width: 20px; height: 20px; }
.hw-find-party .hh-select { flex: 1 1 0; }
.hw-found-roles { display: flex; gap: 2px; }
.hw-found-roles .hw-roleglyph { width: 24px; height: 24px; }
.hw-found-roles .hw-roleglyph .hs-glyph { width: 14px; height: 14px; }
/* Your party (party-roster.js): one ledger row per seat, the leader's crown beside the name, where it is on the right. */
.hw-seat-name { overflow: hidden; text-overflow: ellipsis; }
.hw-seat-lead { display: inline-flex; vertical-align: -2px; margin-left: 6px; color: var(--gold-2); }
.hw-seat-lead[hidden] { display: none; }
.hw-seat-lead .hs-glyph { width: 14px; height: 14px; }
.hw-seat-state { flex: none; font-size: var(--t-micro); color: var(--ink-2); }
.hw-seat.is-away { opacity: .7; }
/* The window's answer stands under its presses, never over Leave party and Disband. */
.hs-win .hw-party > .hh-intent-msg:not(:empty) { position: static; }
/* The Hunt summary's answer stands right under its presses, so it is in view with them. Stuck to the window's foot it lay on them, with the foot of the
   gold "Next:" plate showing under it: the half-filled bar the party panel read as a stuck progress line (2026-11-03). */
.hs-win .hsum-foot > .hh-intent-msg:not(:empty) { position: static; }
.hw-party-acts { flex-wrap: wrap; }
.hw-party-next { margin: 8px 0 0; }
.hw-party-class { margin: 4px 0 0; }
.hw-party-acts .hw-primary { margin-right: auto; }
.hw-party-acts [hidden] { display: none; }
/* Who to invite, under the Party window's tabs (party.js): off on Find a party, which has its own way. */
.hw-list-party[hidden], .hw-invite-how:empty { display: none; }
.hw-invite-name { display: none; margin: 0 0 8px; }
.hw-invite-name.is-on { display: flex; }
.hw-invite-name .hh-num { flex: 1; min-width: 0; text-align: left; }

/* ── The command centre (src/shell/windows/characters.js): one ledger row per character ── */
.hw-chars { margin: 0; padding: 0; list-style: none; }
.hw-char { display: flex; align-items: flex-start; gap: 8px; padding: 8px 0; border-top: 1px solid var(--line-soft); }
.hw-char.is-shown .hw-roleglyph { color: var(--gold-2); }
.hw-char-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.hw-char-line { display: flex; align-items: baseline; gap: 8px; margin: 0; }
.hw-char-name { font-weight: 700; color: var(--ink); white-space: nowrap; }
.hw-char-doing { flex: 1; min-width: 0; font-size: var(--t-micro); color: var(--ink-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hw-badge { display: none; min-width: 18px; height: 18px; padding: 0 5px; border-radius: 9px; background: var(--red); color: var(--bg-0); font-size: var(--t-micro); font-weight: 700; line-height: 18px; text-align: center; }
.hw-badge.is-on { display: inline-block; }
.hw-char-gauges { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; }
.hw-char-gauges .hh-gauge { height: 16px; }
.hw-char-gauges .hh-gauge-text { line-height: 16px; }
.hw-char-facts { display: flex; flex-wrap: wrap; gap: 2px 12px; margin: 0; font-size: var(--t-micro); color: var(--ink-3); font-variant-numeric: lining-nums tabular-nums; }
.hw-char-ready { color: var(--green); }
.hw-char-ready.is-short { color: var(--red); }
.hw-command .hw-tools .hw-primary:not(.is-on) { display: none; }
.hw-char-do { display: flex; flex-direction: column; gap: 4px; }
/* The phone's routes in this sheet (characters.js): an Invite on each other hero, the icons by name, Character list and
   Sign out. The desktop has the strip, the tooltips and the right-click, and shows none of them. */
.hw-phone-only, .hw-char-invite { display: none; }
.hw-char-waits, .hw-phone-word { display: none; }
/* The rename panel (Tyler 10-22: a new name costs gold): shown only for the hero whose Rename was pressed. */
.hw-rename { display: none; margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--line-soft); }
.hw-rename.is-on { display: block; }
.hw-rename .hw-add .hh-num { flex: 1; min-width: 0; }
.hw-alert-kinds { display: grid; grid-template-columns: 1fr 1fr; gap: 2px 12px; margin: 0; padding: 0; list-style: none; }
.hw-alert-kinds .hs-glyph { width: 16px; height: 16px; vertical-align: -3px; }

/* ── The alert lines (src/shell/widgets/alerts.js): newest on top; with none, not there at all ── */
.hs-widget.is-alerts:has(.hw-alerts.is-empty) { pointer-events: none; }
.hw-alerts.is-empty { display: none; }
.hw-alert-list { display: flex; flex-direction: column; gap: 4px; margin: 0; padding: 0; list-style: none; width: var(--hs-alert-w, 360px); max-width: calc(100vw - 24px); max-height: var(--hs-room, none); overflow-y: auto; }
/* Each alert is a HUD plate in the thin steel frame; its kind is the 4 px bar inside its left edge (gold a rare
   find, red a fall, steel the rest). */
.hw-alert {
  display: flex; flex-wrap: wrap; align-items: center; gap: 2px 8px;
  padding: 2px 2px 2px 12px;
  background: var(--hud-fill); border: 6px solid transparent;
  border-image: url('../../assets/ui/steel-frame-thin.png') 3 / 6px stretch; image-rendering: pixelated;
  box-shadow: inset 4px 0 0 var(--ink-3);
  font-size: var(--t-small); color: var(--ink);
}
.hw-alert[data-kind="rare"] { box-shadow: inset 4px 0 0 var(--gold); }
.hw-alert[data-kind="fall"] { box-shadow: inset 4px 0 0 var(--red); }
.hw-alert-glyph { display: grid; place-items: center; flex: none; color: var(--ink-2); }
.hw-alert[data-kind="rare"] .hw-alert-glyph { color: var(--gold-2); }
.hw-alert-glyph .hs-glyph { width: 18px; height: 18px; }
/* The words take the first row beside the glyph; the buttons sit under them, right-aligned. */
.hw-alert-text { flex: 1 1 calc(100% - 34px); min-width: 0; margin: 0; }
.hw-alert-do { flex: none; margin-left: auto; color: var(--gold-2); }
.hw-alert-share { flex: none; }
.hw-alert-x { flex: none; }
.hw-alert-x .hs-glyph { width: 14px; height: 14px; }
@media (max-width: 540px), (max-height: 540px) and (max-width: 1024px) {
  .hw-alert-list { width: 300px; }
  /* ONE CARD, SOLID (phone playtest 2026-10-31: two see-through alerts over a tip, none of them readable): the newest
     alert alone, on the coach card's own fill, and a count of what waits behind it; closing it shows the next. */
  .hw-alert { font-size: var(--t-micro); padding: 0 0 0 10px; background: var(--bg-2); }
  .hw-alert-list > .hw-alert:not(:first-child) { display: none; }
  .hw-alerts-more:not(:empty) { display: block; }
  .hw-alert-do, .hw-alert-no, .hw-alert-share { min-height: 40px; }
  .hw-alert-x { width: 40px; height: 40px; }
  /* The analyzer is the player's ask, as a window is (hunt.css): the alert waits till it closes, the strip's count says so. */
  .app:has(.hs-widget.is-analyzer) .hs-widget.is-alerts { visibility: hidden; }
  /* All characters: Invite under Rename, the icons by name in two columns of thumb-sized presses, the account at the foot. */
  .hw-phone-only { display: block; }
  .hw-phone-word { display: inline; }
  .hw-desk-word { display: none; }
  /* What a hero's red count is waiting for, in words on its row. */
  .hw-char-waits:not(:empty) { display: block; margin: 0; font-size: var(--t-micro); color: var(--gold-2); }
  /* The party's presses wrap inside the sheet (panel: Leave party and Disband ran off its edge at every phone size). */
  .hw-party-acts { flex-wrap: wrap; }
  .hw-party-acts .hw-primary { flex: 1 0 100%; margin-right: 0; }
  .hw-party-acts .hh-tool { flex: 1 1 0; }
  .hw-char-invite:not([hidden]) { display: inline-grid; place-items: center; min-height: 40px; }
  .hw-char { flex-wrap: wrap; }
  .hw-char-do { flex: 1 0 100%; flex-direction: row; justify-content: flex-end; }
  .hw-char-do .hh-tool { min-height: 40px; }
  .hw-icon-names { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 2px 8px; margin: 0 0 8px; padding: 0; list-style: none; }
  .hw-icon-name { display: flex; align-items: center; gap: 8px; width: 100%; min-height: var(--tap); padding: 0 4px; border: 0; background: none; color: var(--ink-2); font: inherit; font-size: var(--t-micro); text-align: left; cursor: pointer; }
  .hw-icon-name .hs-glyph { flex: none; }
  .hw-account { display: flex; justify-content: space-between; gap: 8px; margin-top: 10px; padding-top: 10px; border-top: 2px solid var(--steel-sep); }
  .hw-account .hh-tool { min-height: var(--tap); }
}
/* What waits behind the one alert a phone shows (above): a quiet count on the card's top edge. */
.hw-alerts-more { display: none; position: absolute; bottom: 100%; right: 0; margin: 0; padding: 0 6px; background: var(--bg-2); font-size: var(--t-micro); color: var(--ink-2); }

/* ── Report a problem (src/shell/windows/report.js): one text box, the details ride along ── */
.rp { display: flex; flex-direction: column; gap: 8px; }
.rp-text { box-sizing: border-box; width: 100%; min-height: 128px; resize: vertical; padding: 8px; color: var(--ink); font-family: var(--f-ui); font-size: var(--t-small); line-height: 1.4; }
.rp-text:focus { outline: 2px solid var(--gold); outline-offset: -1px; }
.rp-text::placeholder { color: var(--ink-3); }
.rp-shot { display: flex; align-items: center; gap: 6px; font-size: var(--t-small); color: var(--ink-2); }
.rp-shot[hidden] { display: none; }
.rp-shot input { accent-color: var(--gold); }
.rp-what { margin: 0; }
/* Sticky at the sheet's foot: the answer line is on screen however tall the box is (v0.2.24 gate, 922x423). */
.rp-foot { position: sticky; bottom: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 10px; padding: 6px 0; background: var(--bg-1); }
.rp-said { flex: 1; min-width: 0; margin: 0; font-size: var(--t-small); color: var(--ink-2); }
.rp[data-state="sent"] .rp-said { color: var(--green); }
.rp[data-state="failed"] .rp-said { color: var(--red); }
@media (max-width: 540px), (max-height: 540px) and (max-width: 1024px) {
  .rp-text { height: 96px; min-height: 96px; }
}

/* ── The Farm (src/shell/windows/farm.js): a row of soil plots, sunk into the window, crops at ×2 ── */
.hw-field { display: flex; flex-wrap: wrap; gap: 12px; margin: 4px 0 10px; padding: 0; list-style: none; }
.hw-plot { width: 104px; display: flex; flex-direction: column; align-items: stretch; gap: 4px; }
.hw-soil { width: 104px; height: 88px; display: grid; place-items: center; padding: 0; border: 0; border-radius: 0; background: var(--scene-furrow); box-shadow: var(--hw-well); cursor: pointer; }
.hw-soil:focus-visible { outline: 2px solid var(--aqua-2); outline-offset: 2px; }
.hw-plot.is-picked .hw-soil { outline: 2px solid var(--ink); outline-offset: 2px; }
.hw-plot:not(.is-empty) .hw-soil { cursor: default; }
.hw-crop .hh-icon { width: 64px; height: 64px; image-rendering: pixelated; }
.hw-grow { display: block; height: 4px; background: var(--bg-0); }
.hw-grow i { display: block; height: 100%; background: var(--green); }
.hw-plot.is-ready .hw-grow i { background: var(--gold); }
.hw-plot.is-empty .hw-grow { visibility: hidden; }
.hw-plot-say { display: flex; flex-direction: column; font-size: var(--t-micro); color: var(--ink-2); font-variant-numeric: lining-nums tabular-nums; white-space: nowrap; }
.hw-plot-say b { color: var(--ink); font-weight: 700; }
.hw-plot-say b:empty { display: none; }
.hw-plot.is-ready .hw-plot-say span { color: var(--gold-2); font-weight: 700; }
.hw-plot-by { font-size: var(--t-micro); color: var(--ink-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hw-plot-by:empty { display: none; }
.hw-plot.is-extra .hw-plot-by { white-space: normal; color: var(--gold-2); }
.hw-plot .hh-tool { white-space: normal; }
.hw-harvest { display: none; }
.hw-harvest.is-on { display: block; }
.hw-plot-do.is-off { visibility: hidden; }
.hw-sow { display: none; margin-bottom: 8px; }
.hw-sow.is-on { display: block; }
.hw-sow [data-hs-act="shop"] { display: none; }
.hw-sow [data-hs-act="shop"].is-on { display: inline-block; }
.hw-sow-none:empty { display: none; }
.hw-sow-all { display: none; }
.hw-sow-all.is-on { display: inline-block; }
.hw-seeds .hw-line.is-locked .hw-line-name b { color: var(--ink-3); }
.hw-farm.is-off .hw-tier, .hw-farm.is-off [data-hs-act="upgrade"] { display: none; }
@media (max-width: 540px), (max-height: 540px) and (max-width: 1024px) {
  .hw-field { gap: 8px; }
  .hw-plot, .hw-soil { width: 88px; }
  .hw-soil { height: 76px; }
}
/* ── The House (src/shell/windows/house.js): the account's estate ledger, read like a deed.
   The numeral column is the deed's schedule; a held line is quiet, the next one carries
   its cost as a plain list (what is short reads in the cost colour), a locked room sits
   back. One primary: the confirmation's Pay. ── */
.hw-house-head { display: flex; flex-direction: column; gap: 2px; margin: 0 2px 6px; }
.hw-house-name { font-size: var(--t-lead); font-weight: 700; color: var(--ink); }
.hw-house-note { font-size: var(--t-micro); color: var(--ink-2); }
.hw-chest-n { font-family: var(--f-ui); font-weight: 400; letter-spacing: 0; color: var(--ink-3); font-variant-numeric: lining-nums tabular-nums; }
.hw-estate { align-items: flex-start; padding: 6px 0; }
.hw-estate-n { flex: none; width: 28px; padding-top: 1px; font-family: var(--f-label); font-weight: 700; font-size: var(--t-micro); color: var(--ink-3); text-align: center; }
.hw-estate .hw-line-name small { white-space: normal; }
.hw-estate > .hh-tool { display: none; flex: none; align-self: center; }
.hw-estate > .hh-tool.is-on { display: inline-block; }
.hw-estate.is-held .hw-line-name b { color: var(--ink-2); }
.hw-estate.is-next .hw-estate-n { color: var(--gold-2); }
.hw-estate.is-locked .hw-line-name b, .hw-estate.is-locked .hw-line-name small { color: var(--ink-3); }
.hw-mats { display: flex; flex-wrap: wrap; gap: 0 12px; margin: 2px 0 0; padding: 0; list-style: none; font-size: var(--t-micro); color: var(--ink-2); font-variant-numeric: lining-nums tabular-nums; }
.hw-mats:empty { display: none; }
.hw-mat.is-short { color: var(--red); }
.hw-mat-where { display: block; color: var(--ink-2); font-size: var(--t-micro); }
.hw-mat-where:empty { display: none; }
/* The ask and the server's answer stay on screen wherever the ledger is scrolled (the report window's foot). */
.hw-house-foot { position: sticky; bottom: 0; background: var(--bg-1); }
.hw-house-foot .hh-intent-msg { padding: 4px 2px; }
@media (max-width: 540px), (max-height: 540px) and (max-width: 1024px) {
  .hw-estate-n { width: 20px; }
  .hw-estate > .hh-tool { min-height: 36px; }
}
/* ── The Roll of Honor (src/shell/windows/honor.js): a town's roll, not a table. A place, a hero's name and the
   number that earned it, on ruled lines; first place in gold; the viewed hero marked by a gold rule at its edge. ── */
/* THE HAVORA WINDOW: what gold buys in town. A pick of three powders, the one action under it, what the server says of the day, stuck to the window's foot. */
.hv-top { display: flex; flex-wrap: wrap; align-items: flex-end; column-gap: 8px; margin-bottom: 8px; border-bottom: 2px solid var(--steel-sep); }
.hv-top .hw-tabs { margin-bottom: -2px; border-bottom: 0; }
.hv-gold { margin-left: auto; padding: 0 2px 6px; font-size: var(--t-micro); color: var(--ink-3); font-variant-numeric: lining-nums tabular-nums; white-space: nowrap; }
/* flush with the window's foot: over the body's 12 px of bottom padding, or the pane's next line shows in that strip under it */
.hv-foot { position: sticky; bottom: -12px; margin-bottom: -12px; padding: 6px 0 12px; border-top: 2px solid var(--steel-sep); background: var(--bg-1); }
.hv-foot .hw-cap { margin-bottom: 4px; }
.hv-count:not(.is-on) { display: none; }
@media (max-width: 540px), (max-height: 540px) and (max-width: 1024px) {
  .hv-foot { bottom: -10px; margin-bottom: -10px; padding-bottom: 10px; }
}
.hv-lead { margin: 0 2px 10px; color: var(--ink-2); }
.hv-why { margin: 0 2px 6px; }
.hv-powders { display: flex; gap: 6px; margin: 0 0 10px; }
.hv-powder { display: flex; flex: 1; align-items: center; justify-content: center; gap: 6px; min-width: 0; min-height: 36px; padding: 0 6px; border: 1px solid var(--steel-sep); background: var(--bg-0); color: var(--ink); font-family: var(--f-label); font-weight: 700; cursor: pointer; }
.hv-powder:hover { color: var(--gold-2); }
.hv-powder[aria-checked="true"] { outline: 2px solid var(--gold); outline-offset: -2px; color: var(--gold-2); }
.hv-powder:focus-visible { outline: 2px solid var(--aqua-2); outline-offset: -2px; }
.hv-swatch { flex: none; width: 12px; height: 12px; }
.hv-powder.is-cinnabar .hv-swatch { background: var(--powder-cinnabar); }
.hv-powder.is-quicklime .hv-swatch { background: var(--powder-quicklime); }
.hv-powder.is-borax .hv-swatch { background: var(--powder-borax); }
.hv-buy { display: block; width: 100%; min-height: 40px; margin-bottom: 8px; }
/* The Works tab: where the build stands, what to give, the plaque (src/shell/windows/havora/works.js) */
.hv-works-stage { margin: 0 2px 4px; font-weight: 700; color: var(--ink); font-variant-numeric: lining-nums tabular-nums; }
.hv-works-bar { position: relative; display: block; height: 8px; margin: 0 2px 4px; background: var(--bg-1); box-shadow: var(--hw-well); }
.hv-works-fill { position: absolute; top: 0; left: 0; bottom: 0; width: 0; background: var(--gold-3); }
.hv-works-gifts { display: flex; flex-wrap: wrap; gap: 6px; margin: 10px 0 6px; }
.hv-works-gifts .hv-buy { flex: 1 1 140px; width: auto; margin: 0; }
.hv-works-gifts .hv-buy[hidden] { display: none; }
.hv-works-typed { display: flex; align-items: center; gap: 6px; margin: 0 0 8px; }
.hv-works-typed input { flex: 1; min-width: 0; min-height: 36px; padding: 0 8px; color: var(--ink); background: var(--bg-0); border: 1px solid var(--steel-sep); font: inherit; font-variant-numeric: lining-nums tabular-nums; }
.hv-works-typed input:focus-visible { outline: 2px solid var(--aqua-2); outline-offset: -2px; }
.hv-works-head { margin: 10px 2px 0; font-family: var(--f-label); font-weight: 700; font-size: var(--t-small); letter-spacing: .04em; color: var(--gold-2); }
.hv-works-plaque { margin: 4px 0 0; padding: 0; list-style: none; }
.hv-works-plaque .hr-line { min-height: 32px; grid-template-columns: 32px minmax(0, 1fr) auto; }
.hv-works-plaque .is-mine .hr-name b { color: var(--gold-2); }
.hr-pick { display: flex; align-items: center; gap: 8px; margin: 0 2px 10px; font-family: var(--f-label); font-weight: 700;
  font-size: var(--t-micro); letter-spacing: .04em; color: var(--ink-3); }
.hr-pick .hh-select { flex: 1; min-width: 0; }
.hr-head { display: flex; align-items: center; gap: 10px; margin: 0 2px 6px; }
.hr-glyph { display: grid; place-items: center; width: 32px; height: 32px; flex: none; color: var(--gold-2); }
.hr-glyph .hs-glyph { width: 32px; height: 32px; fill: currentColor; }
.hr-head-words { display: flex; flex-direction: column; min-width: 0; }
.hr-title { font-family: var(--f-label); font-weight: 700; font-size: var(--t-lead); color: var(--ink); }
.hr-why { font-size: var(--t-micro); color: var(--ink-2); }
.hr-roll { margin: 0 0 6px; padding: 0; list-style: none; }
.hr-line { display: grid; grid-template-columns: 52px minmax(0, 1fr) auto; align-items: center; gap: 8px; min-height: 44px;
  padding: 4px 4px 4px 8px; border-top: 2px solid var(--steel-sep); }
.hr-place { font-family: var(--f-label); font-weight: 700; color: var(--ink-3); font-variant-numeric: lining-nums tabular-nums; }
.hr-name { display: flex; flex-direction: column; min-width: 0; }
.hr-name b { font-weight: 700; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hr-name small:empty, .hr-val small:empty { display: none; }
.hr-name small, .hr-val small { font-size: var(--t-micro); color: var(--ink-3); }
.hr-val { display: flex; flex-direction: column; align-items: flex-end; text-align: right; font-variant-numeric: lining-nums tabular-nums; }
.hr-val b { font-weight: 700; color: var(--ink); white-space: nowrap; }
.hr-line.is-first .hr-place, .hr-line.is-first .hr-name b { color: var(--gold-2); }
.hr-line.is-mine .hr-name small { color: var(--ink-2); }
.hr-line.is-viewed { box-shadow: inset 3px 0 0 var(--gold); }
.hr-line.is-viewed .hr-name small { color: var(--gold-2); }
.hr-you { display: none; margin-top: 12px; }
.hr-you.is-on { display: block; }
.hr-you-line, .hr-you-next { margin: 0 2px 6px; font-size: var(--t-small); line-height: 1.4; color: var(--ink-2); }
.hr-you-next:empty, .hr-near:empty { display: none; }
@media (max-width: 540px), (max-height: 540px) and (max-width: 1024px) {
  .hr-line { grid-template-columns: 44px minmax(0, 1fr) auto; min-height: 40px; padding: 2px 2px 2px 6px; }
  .hr-pick .hh-select { min-height: 40px; }
}
/* ── Tamsin's tally (src/shell/windows/tally.js): a keeper's board, not a card grid. Her name, then the
   hero's tallies as notched sticks (.ht-stick, shell.css), her pick (weight, slot order), her board. ── */
.ht-keeper { display: flex; flex-direction: column; gap: 2px; margin: 0 2px 8px; }
.ht-keeper b { font-family: var(--f-label); font-weight: 700; font-size: var(--t-lead); color: var(--ink); }
.ht-keeper small { font-size: var(--t-micro); color: var(--ink-3); }
.ht-keeper .hs-note { margin: 4px 0 0; color: var(--ink-2); }
.ht-take-why { display: none; align-items: center; gap: 8px; color: var(--gold-2); }
.ht-take-why.is-on { display: flex; }
.ht-take-why > span { flex: 1; min-width: 0; }
.ht-take-why > button { flex: none; }
.ht-tally .hw-line-name small { white-space: normal; }
.ht-tally.is-done .hw-line-name b { color: var(--gold-2); }
.ht-keep { display: flex; align-items: center; gap: 4px; flex: none; font-size: var(--t-micro); color: var(--ink-2); white-space: nowrap; }
.ht-weights { display: flex; gap: 2px; margin: 4px 2px; }
.ht-order { display: flex; flex-wrap: wrap; gap: 4px; margin: 4px 2px 8px; padding: 0; list-style: none; counter-reset: ht-slot; }
.ht-slot { display: flex; align-items: center; gap: 4px; padding: 2px 2px 2px 6px; background: var(--bg-1); box-shadow: var(--hw-well);
  font-size: var(--t-micro); color: var(--ink-2); counter-increment: ht-slot; }
.ht-slot::before { content: counter(ht-slot) "."; color: var(--ink-3); font-variant-numeric: lining-nums tabular-nums; }
.ht-offer .hw-line-name small { white-space: normal; }
.hw-hunt-tally { font-size: var(--t-micro); color: var(--gold-2); font-variant-numeric: lining-nums tabular-nums; }
.hw-hunt-tally:empty { display: none; }
@media (max-width: 540px), (max-height: 540px) and (max-width: 1024px) {
  .ht-tally, .ht-offer { flex-wrap: wrap; }
  .ht-tally > .hh-tool, .ht-offer > .hh-tool { min-height: 36px; }
}
