/* Beyond the Last Hearth, expanded demo (v19). Builds on the painted kit (assets/ui/kit.css, #t7435): only layout
   and the few pieces the kit has no class for. Phone portrait first (390 × 844); desktop is the same layout, centred. */
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; background: var(--hk-night); }
body { margin: 0; min-height: 100vh; min-height: 100dvh; overflow-x: hidden; touch-action: manipulation; -webkit-user-select: none; user-select: none; -webkit-tap-highlight-color: transparent; }
button { font: inherit; color: inherit; }
img { -webkit-user-drag: none; }
/* the page is exactly the screen: it never scrolls or moves under a swipe; every screen is laid out to fit, and #main
   scrolls on its own only as a last resort (the checks hold it at zero overflow) */
html, body { height: 100%; overflow: hidden; overscroll-behavior: none; }
#app { max-width: 640px; margin: 0 auto; height: 100dvh; display: flex; flex-direction: column; }
#main { flex: 1; min-height: 0; overflow: hidden auto; overscroll-behavior: contain; padding: 0 10px calc(14px + env(safe-area-inset-bottom)); }
.gl { width: 1.35em; height: 1.35em; flex: none; vertical-align: -0.3em; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
.gl.sm, .hk-icon.sm { width: 1em; height: 1em; vertical-align: -0.15em; }
.warn { color: var(--hk-amber-hi); } .danger { color: #e0705f; }   /* danger is red, never the warm amber of safety */

/* ---------- top bar ---------- */
#top { position: sticky; top: 0; z-index: 30; padding: calc(6px + env(safe-area-inset-top)) 10px 6px;
  background: linear-gradient(rgba(8, 9, 10, .94), rgba(8, 9, 10, .82)), url("assets/ui/textures/soot.webp?v=6d57833793de") 0 0 / 300px; box-shadow: 0 6px 14px rgba(0, 0, 0, .45); }
.bar1, .bar2 { display: flex; align-items: center; gap: 6px; }
.bar2 { gap: 4px; overflow-x: auto; scrollbar-width: none; height: 44px; }
.bar2::-webkit-scrollbar { display: none; }
.bar2 > * { flex: none; }
.spacer { flex: 1; }
.fsr { width: 44px; height: 44px; flex: none; }
.hpbox { flex: 1; min-width: 0; display: flex; align-items: center; gap: 6px; height: 44px; padding: 0 4px; background: none; border: 0; cursor: pointer; }
.hpbox .hpi { color: var(--hk-blood); width: 22px; height: 22px; }
.hpbox .hk-bar { flex: 1; height: 14px; min-width: 24px; }   /* a full top bar shortens the bar, never cuts the number */
.hpbox b { font: 700 17px/1 var(--hk-text); font-variant-numeric: tabular-nums; white-space: nowrap; }
.hpbox b small, .hk-chip small { font-size: 11px; color: var(--hk-bone-faint); font-weight: 500; }
button.hk-chip { border: 0; cursor: pointer; }
/* a top-bar control: a 44 × 44 px tap box (at least) around the painted chip */
.tb { flex: none; display: inline-flex; align-items: center; justify-content: center; min-width: 44px; height: 44px; padding: 0; border: 0; background: none; cursor: pointer; }
#top .hk-chip { padding: 0 8px 0 6px; }
#top .hk-iconbtn--sm, .hk-foot__close.hk-iconbtn--sm { width: 44px; height: 44px; }
/* close/back has one place on every sheet, window and reveal: the bottom-left corner of what is open, in thumb reach,
   18px in from its left edge and 16px up from its bottom. On a sheet it rides a bottom row that sticks to the sheet's
   foot (a sticky bottom counts from the content edge, so the row reaches over the sheet's padding), so it stays in reach
   while the sheet scrolls and nothing scrolls under it */
.hk-foot { display: flex; align-items: center; min-height: 44px; }
.hk-sheet > .hk-foot { position: sticky; bottom: calc(-14px - env(safe-area-inset-bottom)); z-index: 3; margin: 12px -16px calc(-14px - env(safe-area-inset-bottom));
  padding: 6px 12px calc(10px + env(safe-area-inset-bottom)); background: inherit; background-clip: border-box; box-shadow: 0 -8px 12px -6px rgba(0, 0, 0, .7); }
.hk-foot__close { flex: none; }
/* a sheet's action buttons (its action row, or a row of buttons in its text) stay in view just above that bottom row:
   when the sheet is longer than the screen lets it grow, the rest scrolls under them. Sticky 46px up from the content
   edge, where the row's top is (the row is 60px tall and reaches 14px over the padding); its own slate in the tone of
   the sheet's lower part, since its parent may be a block without one (a fight sheet's text). The Workbench's recipe
   list is its content, each row with its own button, and scrolls as content */
.hk-sheet .hk-sheet__actions:not(:has(.recipes)), .hk-sheet .mact { position: sticky; bottom: 46px; z-index: 2; margin: 12px -16px 0; padding: 0 16px;
  background: linear-gradient(rgba(13, 14, 16, .8), rgba(13, 14, 16, .8)), url("assets/ui/textures/slate.webp?v=77eaf512bb2d") 0 0 / 256px, var(--hk-stone); }
/* the fullscreen control shows only on a full screen, in its reserved place there: never over a sheet, window or reveal */
body.has-sheet:not(.rack-full) .demo-fs, body.is-rv .demo-fs, body:has(#modal:not([hidden]), .fu-sheet.is-open, .ru-detail.is-open) .demo-fs { display: none; }
/* a phone held upright: the Rack covers the board, which takes no hits while it is open */
body.rack-full #app { pointer-events: none; }
.hpbox .wmk { color: var(--hk-mana); width: 18px; height: 18px; margin-left: -4px; }
.chip-clock { height: 34px; }
.chip-clock .clk { font-variant-numeric: tabular-nums; }
.chip-clock.is-dusk { --hk-chip-c: var(--hk-amber-hi); color: var(--hk-amber-hi); }
.chip-clock.is-night { --hk-chip-c: var(--hk-fog-pale); color: var(--hk-fog-pale); }
.chip-clock.is-day { --hk-chip-c: var(--hk-amber); }
.chip-light { --hk-chip-c: var(--hk-amber); } .chip-light.is-unlit { --hk-chip-c: var(--hk-bone-dim); }
.chip-wp { --hk-chip-c: var(--hk-bone); }
/* the weapon chip gives way first when the top bar is full: its name wraps onto a second line at the same size (two lines
   of 15px/1 fit the 44px bar), and only a name too long for two lines shortens (…); its value always shows */
.bar2 > .tb:has(> .chip-wp:not(.is-own)) { flex: 0 1 auto; min-width: 44px; overflow: hidden; }
.chip-wp { max-width: 100%; box-sizing: border-box; }
.chip-wp .wn { min-width: 0; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; }
.chip-wp .wn + span { flex: none; margin-left: -4px; }   /* name and value stay one space apart, as when they were one line: the chip's 4px gap is taken back */
.chip-wp .wn + span::before { content: "\00a0"; }
.chip-wp small { margin-left: 2px; }
.chip-wp .crm { color: var(--hk-amber-hi); width: 15px; height: 15px; }
.chip-wp.is-own { opacity: .5; }
.chip-ward { --hk-chip-c: var(--hk-mana); }
.chip-pocket { --hk-chip-c: var(--hk-amber); }
.chip-cap { --hk-chip-c: var(--hk-blood); }
.stam { gap: 3px; }
.stam .sp { display: inline-block; width: 8px; height: 8px; border-radius: 50%; border: 1.5px solid var(--hk-stamina); opacity: .45; }
.stam .sp.on { background: var(--hk-stamina); opacity: 1; }
.gearmarks { display: flex; padding: 0 2px; }
.gm { width: 24px; height: 24px; flex: none; border-radius: 50%; overflow: hidden; border: 1.5px solid var(--hk-ash); display: grid; place-items: center; background: var(--hk-soot); }
.gm.is-hand { border-color: var(--hk-amber); }
.gm + .gm { margin-left: -7px; }
.gm img, .gm .glyph-art { width: 100%; height: 100%; object-fit: cover; }
.glyph-art { display: grid; place-items: center; width: 100%; height: 100%; color: var(--hk-bone-dim);
  background: radial-gradient(circle at 50% 40%, rgba(214, 156, 92, .18), transparent 65%), url("assets/ui/textures/slate.webp?v=77eaf512bb2d") center / 160px, var(--hk-stone); }
.glyph-art .hk-icon, .glyph-art .gl { width: 46%; height: 46%; }

/* ---------- the board ---------- */
.band { position: relative; height: clamp(110px, calc(100dvh - 640px), 210px); margin: 8px 0 8px; overflow: hidden; border: 5px solid transparent;
  border-image: url("assets/ui/frames/frame-ash.webp?v=e763be59fc5a") 16 / 5px / 0 round; background: var(--hk-soot); background-clip: padding-box; }
.band-art { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.band-shade { position: absolute; inset: 0; background: linear-gradient(transparent 35%, rgba(8, 9, 10, .85)); transition: background-color 1.2s; }
body[data-time="dusk"] .band-shade { background-color: rgba(120, 60, 20, .28); }
body[data-time="night"] .band-shade { background-color: rgba(6, 14, 30, .62); }
.band h1 { position: absolute; left: 10px; bottom: 6px; margin: 0; font: 600 20px/1.1 var(--hk-title); color: var(--hk-bone); text-shadow: 0 2px 6px #000; }
.band-key { position: absolute; right: 8px; bottom: 6px; width: 34px; height: 34px; border-radius: 50%; overflow: hidden; border: 2px solid var(--hk-amber); }
.band-key img { width: 100%; height: 100%; object-fit: cover; }
/* exploring is a tap on the place's band: an eye in its top corner, and one pip per find of this run beside the name */
.band.is-explore { cursor: pointer; }
.band.is-explore:focus-visible { outline: 2px solid var(--hk-amber-hi); outline-offset: 2px; }
.band-x { position: absolute; top: 6px; right: 6px; width: 40px; height: 40px; display: grid; place-items: center; border-radius: 50%;
  background: rgba(8, 9, 10, .7); border: 2px solid var(--hk-amber); color: var(--hk-amber-hi); box-shadow: 0 0 14px rgba(214, 156, 92, .45); }
.band-x .hk-icon { width: 24px; height: 24px; }
.band.is-off .band-x { border-color: var(--hk-bone-faint); color: var(--hk-bone-faint); box-shadow: none; }
/* every exploring mark (board.js marks): painted boot prints (a solid sole and heel) walking sideways along a trail, filled amber when
   reached, an empty print with a pale painted edge when not; a dark halo keeps both apart from a pale picture. A print
   keeps the drawing's own shape (22.6 by 10.6) at every size, and the gap leaves its halo clear of the next print */
.fps { display: inline-flex; flex-wrap: nowrap; align-items: center; gap: 2px; padding: 4px 2px; vertical-align: middle; }
.fp { flex: none; width: 14px; height: auto; aspect-ratio: 22.6 / 10.6; overflow: visible; filter: drop-shadow(0 0 .6px rgba(0, 0, 0, .95)) drop-shadow(0 .5px .8px rgba(0, 0, 0, .7)); }
.fp .b { fill: rgba(10, 8, 6, .62); stroke: rgba(232, 222, 204, .92); stroke-width: .9px; vector-effect: non-scaling-stroke; }
.fp .l { display: none; }
.fp.on .b { fill: var(--hk-amber); stroke: #ffe0a6; stroke-width: .7px; vector-effect: non-scaling-stroke; }
.fp.on .l { display: inline; fill: #ffe6b4; opacity: .85; }   /* the lit middle of a filled print */
.band h1 .xpips { margin-left: 8px; }
.hk-sheet__chips .fps { padding: 3px 4px; }
.hk-sheet__chips .fp { width: 11px; }   /* up to eleven steps in a phone sheet's chip row */
/* a place's picture on the map: one print and "3/7" on a small dark plate at the picture's top, clear of its corner mark */
.mp-pic .mp-pips { position: absolute; top: 3px; left: 50%; transform: translateX(-50%); gap: 4px; padding: 2px 6px 2px 4px; border-radius: 4px; background: rgba(14, 12, 10, .8); }
.mp-pips b { font: 700 12px/1 var(--hk-text); color: var(--hk-bone); font-variant-numeric: tabular-nums; white-space: nowrap; text-shadow: 0 1px 2px #000; }
.xmini.is-wait { border-image-source: url("assets/ui/frames/frame-amber.webp?v=0d3aaa1fa1a5"); }
.hrow { display: flex; gap: 8px; overflow-x: auto; overflow-y: hidden; padding: 4px 2px 8px; scroll-snap-type: x proximity; scrollbar-width: thin; }
.hrow > * { scroll-snap-align: start; }
.lbl { margin: 2px 0 0; font: 600 12px var(--hk-title); color: var(--hk-bone-faint); letter-spacing: .1em; }
.lbl .hk-icon { width: 16px; height: 16px; }
/* v21 (#t7511): the Hearth's four site cards fit a phone held upright, so none is cut at an edge; more cards (floor piles)
   still scroll sideways. Phone landscape and desktop set their own widths below. */
.sites { container-type: inline-size; }
.hk-card.site { --w: min(96px, calc((100cqw - 28px) / 4)); }
.hk-card .hk-card__name { font: 600 11px/1.15 var(--hk-title); white-space: normal; padding: 18px 4px 5px; display: flex; flex-direction: column; align-items: center; gap: 2px; }
.hk-card .sub { display: flex; align-items: center; justify-content: center; gap: 3px; font: 700 12px/1 var(--hk-text); color: var(--hk-bone-dim); letter-spacing: 0; text-transform: none; }
.hk-card .sub .hk-icon, .hk-card .sub .gl { width: 14px; height: 14px; }
.hk-card .sub .thumb { width: 16px; height: 16px; }
.hk-card .mv { font-style: normal; display: inline-grid; place-items: center; min-width: 18px; height: 18px; padding: 0 3px; border-radius: 9px; background: #5e2219; color: var(--hk-bone); font: 700 11px/1 var(--hk-text); }
.hk-card .fps { position: absolute; top: 0; left: 0; right: 0; justify-content: center; padding: 2px 0; }   /* a door's depth trail, above its name */
.hk-card .fp { width: 12px; }
/* a gathering spot's stock (board.js stockMarks): one tied sheaf per gather left, filled amber, an empty sheaf with a
   pale edge for each one gathered. In the name box, above the name: a name on two lines pushes it up, never under it */
.hk-card .stk { align-self: stretch; display: flex; justify-content: center; gap: 1.5px; margin: 0 -4px 5px; }
.sm { flex: 0 1 8px; min-width: 0; aspect-ratio: 10 / 14; overflow: visible; filter: drop-shadow(0 0 .6px rgba(0, 0, 0, .95)) drop-shadow(0 .5px .8px rgba(0, 0, 0, .7)); }
.sm .b { fill: rgba(10, 8, 6, .62); stroke: rgba(232, 222, 204, .92); stroke-width: .9px; vector-effect: non-scaling-stroke; stroke-linejoin: round; }
.sm .k { fill: rgba(232, 222, 204, .85); }   /* the tie round the sheaf's waist */
.sm.on .b { fill: var(--hk-amber); stroke: #ffe0a6; stroke-width: .7px; }
.sm.on .k { fill: #5a3618; }
.hk-card.site .nm { font-size: calc(11px * var(--fit, 1)); }   /* --fit: set by fitSiteNames when the widest word would be cut */
.hk-card.is-off { filter: grayscale(.8) brightness(.6); }
.hk-card.is-lead .glyph-art { color: var(--hk-amber); }
.hk-card.is-glow { box-shadow: 0 0 0 2px rgba(214, 156, 92, .5), 0 0 22px rgba(214, 156, 92, .55); }
.hk-card.is-floor { border-image-source: url("assets/ui/frames/frame-amber.webp?v=0d3aaa1fa1a5"); }
/* travel cards (v20, FEEDBACK 1): the place painting fills the card; name and time sit in one slim band at the foot.
   A grid, never a sideways row: every road shows at once. Two columns on a phone, three on a wide screen. The picture
   is cropped from the middle (object-fit: cover), so any painting from 2:1 to 3:2 keeps its centre. */
.roads { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; padding: 4px 2px 8px; align-items: start; }
.hk-card.road { width: 100%; aspect-ratio: 3 / 2; }
.hk-card.road .hk-card__name { flex-direction: row; justify-content: space-between; align-items: center; gap: 6px; padding: 3px 7px 4px; white-space: nowrap;
  font: 600 12px/1.25 var(--hk-title); text-align: left; background: rgba(10, 11, 12, .74); }
.hk-card.road .nm { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.hk-card.road .sub { flex: none; gap: 2px; font: 700 12px/1 var(--hk-text); }
.hk-card.road .sub .hk-icon, .hk-card.road .sub .gl { width: 13px; height: 13px; }
/* v20 (batch-1 gate): --fit (set by fitRoadNames on a card whose name would be cut) scales the band's type and marks */
.hk-card.road .hk-card__name { font-size: calc(12px * var(--fit, 1)); }
.hk-card.road .sub { font-size: calc(12px * var(--fit, 1)); }
.hk-card.road .sub .hk-icon, .hk-card.road .sub .gl { width: calc(13px * var(--fit, 1)); height: calc(13px * var(--fit, 1)); }
@media (min-width: 560px) and (min-height: 521px) { .roads { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.c-info { position: absolute; top: 0; right: 0; width: 44px; height: 44px; padding: 4px; border: 0; background: none; cursor: pointer; display: flex; align-items: flex-start; justify-content: flex-end; z-index: 3; }
.c-info::before { content: ""; position: absolute; top: 3px; right: 3px; width: 28px; height: 28px; border-radius: 50%; background: rgba(10, 11, 12, .78); box-shadow: 0 0 0 1px rgba(236, 228, 212, .35); }
.c-info .hk-icon { position: relative; width: 18px; height: 18px; margin: 2px 2px 0 0; color: var(--hk-bone); }
.thumb { display: inline-block; width: 22px; height: 22px; border-radius: 4px; overflow: hidden; vertical-align: middle; background: var(--hk-soot); flex: none; }
.thumb img, .thumb .glyph-art { width: 100%; height: 100%; object-fit: cover; display: block; }
/* v20 (FEEDBACK 21): the pack row's slots are larger (--slot); the row stays one line and scrolls sideways inside itself
   when it holds more than fits, so the page never scrolls sideways and nothing else on the screen shrinks */
.pack { --slot: 64px; display: flex; flex-wrap: nowrap; gap: 4px; margin-top: 10px; overflow: auto hidden; overscroll-behavior-x: contain; scrollbar-width: none; }
.pack::-webkit-scrollbar { display: none; }
/* v20 (FEEDBACK 25): the board is a column with the pack as its own strip along the bottom edge of the screen; the
   places stay right under the place's own cards. */
body[data-view="board"] #main { display: flex; flex-direction: column; }
body[data-view="board"] #main > * { flex: none; }   /* the place band, its cards and the pack keep their full size */
body[data-view="board"] .pack { margin-top: auto; padding-top: 10px; }
/* more places than fit: the place cards scroll in their own area (here and in the landscape column), never the page,
   and nothing around them shrinks. 140px keeps one row of cards in view on the shortest phone. */
body[data-view="board"] .roads { min-height: 0; overflow-y: auto; overscroll-behavior: contain; align-content: start; grid-auto-rows: max-content; }
body[data-view="board"] #main > .roads { flex: 1 1 auto; min-height: min(140px, 100%); }
.slot { position: relative; flex: 0 0 var(--slot, 44px); width: var(--slot, 44px); height: var(--slot, 44px); padding: 0; border: 2px solid #2b2d2e; border-radius: 3px; overflow: hidden; background: var(--hk-soot); cursor: pointer; }
.slot img, .slot .glyph-art { width: 100%; height: 100%; object-fit: cover; display: block; }
.slot b { position: absolute; right: 2px; bottom: 1px; font: 700 14px/1 var(--hk-text); color: var(--hk-bone); text-shadow: 0 1px 2px #000, 0 0 4px #000; }
.pack .slot b { right: 3px; bottom: 3px; padding: 2px 5px; border-radius: 4px; font-size: 18px; background: rgba(8, 9, 10, .72); }   /* the stack count on the larger slot */
.slot.is-use { border-color: var(--hk-amber); }
.slot.is-armed { box-shadow: 0 0 0 2px var(--hk-amber-hi), 0 0 14px rgba(243, 197, 130, .6); }
.slot.is-empty { border: 1.5px dashed #3a3c3d; background: rgba(0, 0, 0, .25); cursor: default; }
.slot.is-off { filter: grayscale(1) brightness(.6); }
/* drag between the pack and the floor (board.js, drag.js): pan sideways scrolls the row, any other move lifts; the ghost
   follows the pointer, the stack lifted greys, and where it would land lights up (amber: it lands, ash: refused) */
#pack .slot[data-item], #sites .hk-card.is-floor { touch-action: pan-x; -webkit-user-select: none; user-select: none; }
#pack .slot.is-lifted, #sites .hk-card.is-lifted { opacity: .3; }
.pk-ghost { position: fixed; z-index: 80; margin: 0; pointer-events: none; transition: none; transform-origin: 0 0; opacity: .94; box-shadow: 0 18px 32px rgba(0, 0, 0, .75); }
#main.is-dragging, #main.is-dragging * { cursor: grabbing !important; }
#pack .slot.is-drop-ok, #pack.is-drop-ok { box-shadow: 0 0 0 2px var(--hk-amber-hi), 0 0 14px rgba(243, 197, 130, .6); }
#pack .slot.is-drop-no { box-shadow: 0 0 0 2px #6b6f72; filter: brightness(.7); }
/* a floor stack held for a swap (board.js hold): the card lifts and glows, and each pack tile it can replace carries the swap mark */
#sites .hk-card.is-floor.is-held { transform: translateY(-6px); box-shadow: 0 0 0 2px var(--hk-amber-hi), 0 0 20px rgba(243, 197, 130, .65); }
#pack .slot.is-swapto { border-color: var(--hk-amber-hi); box-shadow: 0 0 10px rgba(243, 197, 130, .55); }
.slot-swap { position: absolute; top: 2px; left: 2px; width: 20px; height: 20px; display: grid; place-items: center; border-radius: 50%; background: rgba(14, 12, 10, .8); }
.slot-swap .hk-icon { width: 15px; height: 15px; color: var(--hk-amber-hi); }
#sites.is-drop-ok { outline: 2px dashed rgba(214, 156, 92, .75); outline-offset: 4px; border-radius: 10px; }
.slot.is-pocket { display: grid; place-items: center; color: var(--hk-amber); background: url("assets/ui/textures/umber.webp?v=d5e58909ddf9") center / 80px, #3a2c22; }
.slot.is-pocket .gl { width: 55%; height: 55%; }

/* ---------- sheets ---------- */
.hk-sheet__art { display: block; overflow: hidden; }
.hk-sheet__art img, .hk-sheet__art .glyph-art { width: 100%; height: 100%; object-fit: cover; display: block; }
.hk-sheet__art > .hk-icon { width: 100%; height: 100%; }
.hk-sheet__head .hd { min-width: 0; flex: 1; }
.hk-sheet__actions { margin-top: 12px; }
.hk-btn[aria-disabled="true"] { cursor: default; filter: grayscale(1) brightness(.6); color: var(--hk-bone-faint); }
.hk-btn .why { font: 700 12px/1 var(--hk-text); text-transform: none; letter-spacing: 0; opacity: .85; display: inline-flex; align-items: center; gap: 2px; }
.hk-btn .why .hk-icon, .hk-btn .why .gl { width: 14px; height: 14px; }
a.hk-btn { text-decoration: none; }
.hk-sheet__chips .hk-chip .thumb { width: 18px; height: 18px; }
.chip-wake { --hk-chip-c: var(--hk-bone-faint); color: var(--hk-bone-dim); }
.minis { display: flex; flex-wrap: wrap; gap: 5px; align-items: center; }
.minis .sep { color: var(--hk-fog-pale); }
.mini { position: relative; width: 40px; height: 56px; border-radius: 5px; overflow: hidden; border: 2px solid #3a3c3d; background: var(--hk-soot); flex: none; }
.mini img, .mini .glyph-art { width: 100%; height: 100%; object-fit: cover; display: block; }
.mini b { position: absolute; left: 0; right: 0; bottom: 0; text-align: center; font: 700 13px/1.2 var(--hk-text); background: rgba(10, 11, 12, .78); }
.mini b .gl, .mini b .hk-icon { width: 12px; height: 12px; }
.mini.is-mon { border-color: #5e2219; }
.mini.is-boss { border-color: var(--hk-bone-dim); }
.mini.is-prize { border-color: var(--hk-amber); }
.mini.is-top { border-color: var(--hk-amber-hi); }
.lbl2 { margin-top: 6px; display: flex; align-items: center; gap: 6px; color: var(--hk-bone-faint); }
.warnline { display: flex; align-items: center; gap: 6px; margin: 0 0 6px; color: var(--hk-amber-hi); font-weight: 700; }
/* the Workbench's tabs: painted plates, each its icon over a short word, never cut: a tab is at least
   as wide as its word, the row wraps if the sheet is too narrow, and seven tabs or more on a phone stand in even rows of
   at most four (--cols, screens/workbench.js) */
.wb-tabs { display: flex; flex-wrap: wrap; gap: 3px; width: 100%; margin: 2px 0 4px; }
.wb-tabs .wb-tab { min-width: max-content; }
@media (max-width: 599px) { .wb-tabs.is-many { display: grid; grid-template-columns: repeat(var(--cols), minmax(0, 1fr)); } }
.wb-tab { flex-direction: column; gap: 1px; padding: 4px 2px; font-size: 11px; }
.wb-tab .hk-icon, .wb-tab .gl { width: 18px; height: 18px; flex: none; }
/* the "makeable/known" count under the label: room above and below, so the plate's ragged edge never clips icon or count */
.wb-tabs .wb-tab { gap: 2px; padding-top: 6px; padding-bottom: 7px; }
.wb-tab .wb-n { font: 700 11px/1 var(--hk-text); font-variant-numeric: tabular-nums; white-space: nowrap; opacity: .9; }
.recipes { width: 100%; display: flex; flex-direction: column; gap: 6px; }
.recipe { display: grid; grid-template-columns: 40px minmax(0, 1fr) auto auto; align-items: center; gap: 8px; padding: 4px 0; border-top: 1px solid rgba(122, 128, 128, .25); }
.recipe .rart { width: 40px; height: 40px; border-radius: 6px; overflow: hidden; display: grid; place-items: center; color: var(--hk-bone-faint); background: var(--hk-soot); }
.recipe .rart img, .recipe .rart .glyph-art { width: 100%; height: 100%; object-fit: cover; }
.recipe .rmid { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.recipe .rmid b { font: 600 14px/1.1 var(--hk-title); }
.recipe .ins { display: flex; flex-wrap: wrap; gap: 6px; font: 700 13px/1 var(--hk-text); color: var(--hk-bone-dim); align-items: center; }
.recipe .in { display: inline-flex; align-items: center; gap: 2px; }
.recipe .in .thumb { width: 18px; height: 18px; }
.recipe .ins { font-weight: 600; }
.recipe .in.is-miss { opacity: .4; }
.recipe .in .own { margin-left: 3px; font-weight: 500; color: var(--hk-bone-dim); opacity: .85; }   /* owned, pack and chest */
.recipe .rt { font: 600 12px var(--hk-text); color: var(--hk-bone-faint); white-space: nowrap; }
.recipe .hk-btn { min-width: 96px; padding: 0 12px; flex: none; }
.recipe.is-off .rmid b { color: var(--hk-bone-faint); }
.recipe[data-act] { cursor: pointer; min-height: 48px; }
.hk-sheet__body .learn { display: inline-flex; align-items: center; gap: 4px; color: var(--hk-bone-dim); }
.howto.tip { text-align: left; margin: 8px 0 12px; }
.hk-sheet__actions .recipes .hk-btn { flex: none; }
.tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(74px, 1fr)); gap: 6px; }
.tiles.big { grid-template-columns: repeat(2, 1fr); }
.tile { position: relative; display: flex; flex-direction: column; align-items: center; gap: 3px; padding: 4px; min-height: 74px; border: 2px solid #2b2d2e; border-radius: 8px; background: var(--hk-soot); cursor: pointer; }
.tile img, .tile .glyph-art { width: 46px; height: 46px; object-fit: cover; border-radius: 5px; }
.tiles.big .tile img, .tiles.big .tile .glyph-art { width: 90px; height: 90px; }
.tile b { position: absolute; top: 4px; right: 6px; font: 700 15px var(--hk-text); text-shadow: 0 1px 2px #000; }
.tile span { font: 600 11px/1.1 var(--hk-title); text-align: center; }
.tile.is-on { border-color: var(--hk-amber); box-shadow: 0 0 12px rgba(214, 156, 92, .4); }
.sh3 { display: flex; align-items: center; gap: 6px; margin: 10px 0 6px; font: 600 13px var(--hk-title); color: var(--hk-bone-faint); }
.empty { color: var(--hk-bone-faint); margin: 0; }
.note { font-size: 14px; color: var(--hk-bone-faint); }
.gslots { display: grid; gap: 6px; margin-top: 10px; }
.gslot { display: grid; grid-template-columns: 22px 34px minmax(0, 1fr); align-items: center; gap: 6px; font-size: 13px; }
.gslot img, .gslot .glyph-art { width: 34px; height: 34px; border-radius: 6px; object-fit: cover; }
.gslot b { grid-column: 3; font: 600 13px var(--hk-title); }
.gslot small { grid-column: 3; color: var(--hk-bone-faint); }
.gslot > small:only-of-type { grid-column: 2 / 4; }
.howto { list-style: none; padding: 0; margin: 4px 0 0; display: grid; gap: 6px; }
.howto li { display: flex; gap: 8px; align-items: center; }
.howto .hk-icon, .howto .gl { color: var(--hk-amber); flex: none; }

/* ---------- receipt and modal ---------- */
#toast { top: calc(150px + env(safe-area-inset-top)); }
#toast.is-top { top: calc(4px + env(safe-area-inset-top)); }   /* the run's goal: clear of the place picture */
#receipt { position: fixed; z-index: 45; left: 50%; top: calc(98px + env(safe-area-inset-top)); transform: translate(-50%, -12px); opacity: 0; pointer-events: none; transition: opacity .2s, transform .2s; max-width: min(94vw, 520px); }
#receipt.is-in { opacity: 1; transform: translate(-50%, 0); }
.rc { display: flex; flex-wrap: wrap; gap: 6px 10px; align-items: center; justify-content: center; padding: 6px 12px; }
.rci { display: inline-flex; align-items: center; gap: 4px; font: 700 15px var(--hk-text); }
.rci .hk-icon, .rci .gl { color: var(--hk-amber); width: 18px; height: 18px; }
.rci.is-floor { color: var(--hk-amber-hi); }
.rci.is-floor b::after { content: " ↓"; }
.rci.is-bonus b { color: var(--hk-amber-hi); }
.rci.is-left { color: var(--hk-bone-faint); }
.rci.is-left img { filter: grayscale(1) brightness(.7); }   /* a room weapon carried home but not kept */
#modal { position: fixed; inset: 0; z-index: 60; display: grid; place-items: center; padding: 16px; background: rgba(5, 6, 7, .72); }
#modal[hidden] { display: none; }
.mbox { width: min(440px, 100%); max-height: 90dvh; overflow: auto; text-align: center; padding: 16px; }
.mt { margin: 0 0 8px; font: 600 20px/1.2 var(--hk-title); display: flex; flex-direction: column; align-items: center; gap: 8px; }
.ml { margin: 6px 0; display: flex; align-items: center; justify-content: center; gap: 6px; flex-wrap: wrap; color: var(--hk-bone-dim); }
.ml.big { font: 600 16px var(--hk-title); color: var(--hk-amber-hi); }
.rcs { display: flex; flex-wrap: wrap; gap: 8px 12px; justify-content: center; margin: 10px 0; }
.mact { display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; margin-top: 12px; }
.mact .hk-btn { flex: 1 1 140px; max-width: 240px; }
/* a window's buttons stay in view at its bottom when it is longer than the screen (short landscape paints the row, below) */
.mbox > .mact { position: sticky; bottom: 0; z-index: 2; }
.endart { width: 120px; height: 120px; object-fit: cover; border-radius: 8px; }
.keyart { width: 34px; height: 34px; border-radius: 50%; object-fit: cover; }
.boons { display: flex; gap: 8px; justify-content: center; }
.hk-card.boon { --w: 104px; border: 4px solid transparent; border-image: url("assets/ui/frames/frame-amber.webp?v=0d3aaa1fa1a5") 16 / 4px / 0 round; }
.boon .glyph-art { position: absolute; inset: 0; color: var(--hk-amber-hi); }
.boon .hk-card__name { font-size: 13px; }

/* ---------- the room screen ---------- */
body[data-view="room"] #main { display: flex; flex-direction: column; }
.rm { position: relative; flex: 1; display: flex; flex-direction: column; gap: 8px; padding-top: 6px; }
.rm > .rm-row, .rm > .stair { margin-top: auto; }
.rm > .rm-pack { margin-bottom: 4px; }
/* one painting per place behind everything (assets/bg via assets.js); fixed, so it never adds page height or moves */
/* the body is see-through so the painting shows; the page root keeps the night colour where none is set */
html { background: var(--hk-night); }
body.hk-table { background: transparent; }
/* body is the stacking root (rain-fx needs one): the backdrop and the rain in it (z -1) sit under all content */
body { position: relative; z-index: 0; }
#backdrop { position: fixed; inset: 0; z-index: -1; overflow: hidden; pointer-events: none; background: var(--hk-night); }
#backdrop picture { display: contents; }
#backdrop img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: var(--bg-x, 50%) var(--bg-y, 40%); }
/* #backdrop is a .tod-scene: daylight.css lights the painting by the clock (board.js daylight()) */
/* a shade keeps cards and text readable; by day it thins to an edge vignette (--tod-shade), a room keeps the light on
   the cards at every hour */
#backdrop::after { content: ""; position: absolute; inset: 0; opacity: var(--tod-shade, 1); transition: opacity var(--tod-fade) linear;
  background: radial-gradient(ellipse at 50% 45%, rgba(6, 7, 9, .45), rgba(6, 7, 9, .8) 85%); }
body[data-view="room"] #backdrop::after { opacity: 1; background: radial-gradient(ellipse at 50% 40%, rgba(214, 156, 92, .06), transparent 62%), radial-gradient(ellipse at 50% 45%, rgba(6, 7, 9, .55), rgba(6, 7, 9, .88) 80%); }
.rm-head { display: flex; align-items: center; gap: 8px; min-height: 44px; }
.rm-head h1 { flex: 1; min-width: 0; margin: 0; font: 600 14px/1.2 var(--hk-title); color: var(--hk-bone-dim); }
.rdots { display: flex; gap: 4px; }
.rm-head .chip-cap { flex: none; }
.chip-won { --hk-chip-c: var(--hk-amber-hi); } .rm-head .chip-won { flex: none; }   /* v20 (FEEDBACK 9): the spoils step */
.noheal { flex: none; display: inline-flex; align-items: center; gap: 2px; font: 700 12px/1 var(--hk-text); font-style: normal; color: #f0a090; white-space: nowrap; }
.noheal .hk-icon { width: 14px; height: 14px; opacity: .8; }
.so-h .noheal { margin-left: 6px; }
.mini.is-known { border-color: var(--hk-bone-faint); filter: grayscale(.7) brightness(.8); }
.rd { width: 10px; height: 10px; border-radius: 50%; border: 2px solid var(--hk-bone-faint); }
.rd.on { background: var(--hk-bone-dim); border-color: var(--hk-bone-dim); }
.pilebtn { display: flex; align-items: center; gap: 4px; min-height: 44px; min-width: 44px; padding: 2px 8px; border: 0; border-radius: 8px; cursor: pointer;
  background: url("assets/ui/textures/slate.webp?v=77eaf512bb2d") center / 160px, var(--hk-stone); }
.pilebtn > b { font: 700 16px var(--hk-text); }
.pilebtn .pl-boss { display: inline-flex; flex-direction: column; align-items: center; gap: 1px; }
.pilebtn .pl-boss small { font: 600 10px/1 var(--hk-text); color: var(--hk-bone-dim); white-space: nowrap; }
.pilebtn .mini { width: 28px; height: 40px; }
.pilebtn .mini b { font-size: 11px; }
.rm-row { --cw: min(calc((min(100vw, 640px) - 20px - 18px) / 4), 150px); display: grid; grid-template-columns: repeat(4, var(--cw)); gap: 6px; justify-content: center; min-height: calc(var(--cw) * 1.4); }
.hk-card.rc { --w: var(--cw); }
.rc .hk-card__name { font-size: calc(var(--w) * .12); padding: calc(var(--w) * .2) 3px 4px; gap: 3px; }
.rc .foot { display: flex; align-items: center; justify-content: center; gap: 4px; min-height: 18px; }
.rc .cost { display: inline-flex; align-items: center; gap: 1px; font: 700 calc(var(--w) * .15) / 1 var(--hk-text); }
.rc .cost .hk-icon, .rc .cost .gl { width: calc(var(--w) * .15); height: calc(var(--w) * .15); }
.rc .cost.is-hurt { color: #f0a090; }
.rc .cost.is-free { color: #b9d8a0; }
.rc .cost.is-blk { color: var(--hk-bone); }
/* the unused Buckler: the hit it takes away, struck through (it takes only the first hit of the room) */
.rc .blk, .rc .edg { display: inline-flex; align-items: center; gap: 1px; font: 700 12px/1 var(--hk-text); color: var(--hk-bone-dim); }
.rc .blk s { text-decoration-thickness: 2px; text-decoration-color: rgba(240, 160, 144, .8); }
.rc .blk .hk-icon, .rc .edg .hk-icon { width: 13px; height: 13px; }
.rc .edg { color: var(--hk-amber-hi); }
/* a tap that kills: a red skull on the card, and one "Sure?" before it acts */
.rc .lethal { position: absolute; left: 4px; top: 4px; z-index: 2; display: grid; place-items: center; width: 24px; height: 24px; border-radius: 50%; background: rgba(60, 8, 6, .85); box-shadow: 0 0 0 1px #f0a090; }
.rc .lethal .hk-icon { width: 16px; height: 16px; color: #ff9f8c; }
.rc.is-lethal { box-shadow: 0 0 0 2px rgba(220, 60, 40, .8), 0 6px 16px rgba(0, 0, 0, .55); }
.rc.is-ask { box-shadow: 0 0 0 3px #ff6a50, 0 0 18px rgba(255, 90, 60, .55); }
.rc .stc { color: var(--hk-stamina); font: 700 13px/1 var(--hk-text); letter-spacing: -1px; }
.rc .mnc { display: inline-flex; align-items: center; color: var(--hk-mana); font: 700 12px/1 var(--hk-text); }
.rc .hk-card__badge { min-width: calc(var(--w) * .3); height: calc(var(--w) * .3); font-size: calc(var(--w) * .17); }
.rc .react { position: absolute; left: 3px; top: calc(var(--w) * .34); display: inline-flex; align-items: center; gap: 1px; padding: 2px 4px; border-radius: 8px;
  background: rgba(10, 11, 12, .78); color: var(--hk-bone-dim); font: 700 12px/1 var(--hk-text); }
.rc .react .gl { width: 13px; height: 13px; }
.rc .react.is-lunge { color: #f0a090; }
.rc .react.is-soon { color: var(--hk-amber-hi); box-shadow: 0 0 0 1px var(--hk-amber); }
.rc .react.is-spent { opacity: .45; }
.rc .growpips { position: absolute; left: calc(var(--w) * .3 + 6px); top: 8px; display: flex; gap: 2px; }
.rc .growpips i { width: 7px; height: 7px; border-radius: 50%; background: #f0a090; box-shadow: 0 0 4px #000; }
.rc .risen-note { position: absolute; left: 3px; top: calc(var(--w) * .34); display: inline-flex; align-items: center; gap: 1px; padding: 2px 4px; border-radius: 8px; background: rgba(10, 11, 12, .78); font: 700 12px/1 var(--hk-text); color: var(--hk-amber-hi); }
.rc .risen-note .gl, .rc .risen-note .hk-icon { width: 13px; height: 13px; }
.rc .lootmark { position: absolute; right: 4px; top: 44px; }
.rc .lootmark .thumb { width: 20px; height: 20px; border: 1px solid rgba(236, 228, 212, .4); }
.rc.is-dim { opacity: .42; }
.rc.is-warn { box-shadow: 0 0 0 2px rgba(240, 120, 100, .55), 0 6px 16px rgba(0, 0, 0, .55); }
.rc .lw .gl { width: calc(var(--w) * .15); height: calc(var(--w) * .15); }
.rc .react.is-lunge.is-soon { color: #ffb4a4; box-shadow: 0 0 0 1px #f0a090; }
.rc.is-off:not(.is-dim) { filter: grayscale(.7) brightness(.7); }
.rc.is-acting { transform: translateY(-6px); transition: transform .12s; }
.rc.is-grown .hk-card__badge { animation: grown .7s ease-out; }
@keyframes grown { 0% { transform: scale(1.5); } 100% { transform: none; } }
.rm-floor { display: flex; align-items: center; gap: 6px; padding: 4px 6px; border: 1.5px dashed var(--hk-amber); border-radius: 8px; color: var(--hk-amber); }
.rm-floor .slot { flex: 0 0 44px; }
.rm-verbs { display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; align-content: flex-start; min-height: 94px; }
.vchip { padding: 0 12px; gap: 4px; font-size: 12px; }
.vchip small { font: 700 12px/1 var(--hk-text); text-transform: none; display: inline-flex; align-items: center; }
.vchip small .hk-icon { width: 13px; height: 13px; }
.vchip .stc { color: var(--hk-stamina); letter-spacing: -1px; }
.vchip.is-armed .stc { color: #5a3a10; }
.rm-line { height: 46px; overflow: hidden; font: 14px/22px var(--hk-text); color: var(--hk-bone-dim); text-align: center; }
.rm-line p { margin: 0; height: 23px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rm-line p > * { vertical-align: middle; }
.rm-line p:first-child:not(:last-child) { opacity: .55; }
.rm-line .hk-icon, .rm-line .gl { width: 16px; height: 16px; }
.rm-line .thumb { width: 18px; height: 18px; }
.rm-line .bad { font-style: normal; color: #f0a090; font-weight: 700; display: inline-flex; align-items: center; gap: 1px; }
.rm-pack { margin-top: 0; }
.stair { display: flex; flex-direction: column; gap: 8px; }
.stair-head { display: flex; align-items: center; gap: 10px; }
.stair-art { width: 64px; height: 64px; object-fit: cover; border-radius: 8px; }
.stair-head span { display: flex; flex-direction: column; gap: 3px; }
.stair-head b { font: 600 16px var(--hk-title); }
.stair-head small { display: flex; align-items: center; gap: 4px; color: var(--hk-bone-dim); font-size: 14px; }
.stairopt { display: flex; flex-direction: column; gap: 6px; align-items: stretch; text-align: left; padding: 10px 12px; min-height: 56px; cursor: pointer; border: 5px solid transparent;
  border-image: url("assets/ui/frames/frame-ash.webp?v=e763be59fc5a") 16 / 5px / 0 round; background: linear-gradient(rgba(20, 22, 24, .55), rgba(12, 13, 15, .78)), url("assets/ui/textures/slate.webp?v=77eaf512bb2d") 0 0 / 256px, var(--hk-stone); background-clip: padding-box; }
.stairopt .so-h { display: flex; align-items: center; gap: 8px; }
.stairopt .so-h b { font: 600 16px var(--hk-title); }
.stairopt .so-h small { margin-left: auto; color: var(--hk-bone-faint); font-size: 13px; text-align: right; }
.stairopt .so-h .hk-icon, .stairopt .so-h .gl { width: 22px; height: 22px; color: var(--hk-amber); }
.stairopt.is-dark { border-image-source: url("assets/ui/frames/frame-bone.webp?v=e97db8e9bfad"); }
.stairopt.is-dark .so-h .gl { color: #f0a090; }
.stairopt.is-confirm { border-image-source: url("assets/ui/frames/frame-amber.webp?v=0d3aaa1fa1a5"); box-shadow: 0 0 18px rgba(214, 156, 92, .45); }
.stairopt.is-confirm .so-h b { color: var(--hk-amber-hi); }

/* ---------- intro ---------- */
.intro { position: relative; height: 100%; display: grid; place-items: center; }
.intro-art { position: fixed; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: .5; z-index: -1; pointer-events: none; }
.intro-box { text-align: center; width: min(420px, 100%); padding: 18px; }
.intro-box h1 { margin: 0; font: 600 28px/1.1 var(--hk-title); }
.intro-box .sub { margin: 4px 0 12px; font: italic 16px var(--hk-text); color: var(--hk-bone-faint); }
.intro-box .goal { display: flex; align-items: center; justify-content: center; gap: 6px; color: var(--hk-bone-dim); }
.intro-box .oldsave { display: flex; align-items: center; justify-content: center; gap: 6px; margin: 8px 0 0; color: var(--hk-ember, #d9a066); }

/* ---------- phone landscape: everything above the fold ---------- */
@media (orientation: landscape) and (max-height: 520px) {
  #app { max-width: none; }
  #top { padding-top: 4px; padding-bottom: 4px; }
  #top { display: flex; gap: 8px; align-items: center; }
  .bar1 { flex: 0 0 auto; width: 46%; }
  .bar2 { margin-top: 0; flex: 1; }
  /* v20 (FEEDBACK 25): the places move up into the right column, level with the banner (the map mark that stood
     there gives way); the pack is its own strip across the whole width along the bottom edge */
  body[data-view="board"] #main { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); grid-template-rows: auto auto minmax(0, 1fr) auto;
    column-gap: 12px; align-content: stretch; }
  body[data-view="board"] .band { height: 72px; grid-column: 1; grid-row: 1; margin: 6px 0; }
  body[data-view="board"] .sites { grid-column: 1; grid-row: 2; }
  body[data-view="board"] .lbl { display: none; }
  /* more roads than fit beside the pack: the road column scrolls on its own, so the pack strip never covers a road */
  body[data-view="board"] .roads { grid-column: 2; grid-row: 1 / span 3; align-self: stretch; padding-top: 6px;
    grid-auto-rows: minmax(72px, 1fr); }   /* rows share the column down to 72px; more roads than that scroll */
  body[data-view="board"] #main > .roads { min-height: 0; }
  body[data-view="board"] .pack { grid-column: 1 / -1; grid-row: 4; margin-top: 0; padding-top: 6px; align-self: end; }
  .sites .hk-card.site { --w: min(82px, calc((100cqw - 28px) / 4)); }   /* beats the desktop width (this screen is wider than 760): four site cards fit the left column */
  /* the rows share the column's height and a road card is never taller than its row (16:9 where it has room), so three
     rows (five roads, the most a place has) fit beside the pack; a card taller than its row lay over the next one */
  .hk-card.road { aspect-ratio: 16 / 9; max-height: min(100%, calc((100dvh - 168px) / 2)); }
  #main { padding-bottom: calc(6px + env(safe-area-inset-bottom)); }
  /* the right column holds 7 pack slots a row (13 at most: 10 with the Satchel, 3 pocketed heals) */
  .rm { container-type: inline-size; display: grid; grid-template-columns: minmax(0, 1fr) 320px; column-gap: 12px; row-gap: 8px; align-items: start; align-content: start;
    grid-template-areas: "head head" "row verbs" "floor pack" "line pack"; }
  .rm[data-phase="stair"] { grid-template-areas: "head head" "stair line" "stair pack"; }
  .rm > .rm-row, .rm > .stair { margin-top: 0; }
  .rm-head { grid-area: head; min-height: 36px; }
  .rm-row { grid-area: row; } .rm-floor { grid-area: floor; } .stair { grid-area: stair; }
  .rm-verbs { grid-area: verbs; } .rm-line { grid-area: line; } .rm-pack { grid-area: pack; }
  .rm .rm-row { --cw: min(calc((100cqw - 332px - 18px) / 4), calc((100dvh - 232px) * 5 / 7)); justify-content: start; }
  .rm-verbs { justify-content: flex-start; min-height: 0; }
  .rm[data-phase="stair"] .rm-line { text-align: left; }
  /* Leave keeps its own width; Down and the Dark way share the rest, so their cards wrap less */
  .stair { display: flex; flex-direction: row; flex-wrap: wrap; gap: 8px; align-items: flex-start; }
  .stair-head { flex: 0 0 100%; }
  .stairopt { flex: 1 1 0; min-width: 0; }
  .stairopt[data-act="stair:leave"] { flex: 0 0 auto; max-width: 96px; }   /* Down and Dark way keep 4 small cards a row: 8 at most, 2 rows */
  .stairopt .mini { width: 34px; height: 48px; }
  .stair-art { width: 44px; height: 44px; }
  .stairopt { min-height: 48px; padding: 6px 10px; }
  .stairopt .so-h { flex-wrap: wrap; row-gap: 2px; }
  .stairopt .so-h small { flex-basis: 100%; margin-left: 0; text-align: left; }
}
/* ---------- desktop ---------- */
@media (min-width: 760px) {
  .hk-card.site { --w: 108px; }
  .band { height: 150px; }
  .rm-row { --cw: 140px; }
}
/* v20 (FEEDBACK 21): desktop has room to wrap, so every slot shows (not a phone held sideways, which keeps one row) */
@media (min-width: 760px) and (min-height: 521px) { .pack { --slot: 72px; flex-wrap: wrap; overflow: visible; } }
@media (prefers-reduced-motion: reduce) { .rc.is-grown .hk-card__badge { animation: none; } }

/* =====================================================================================================
   v21: THE FIGHT SCREEN (#t7458), from the approved mock-up design/feedback-v20/combat/mockup/fight.html.
   Phone portrait: one column. Phone landscape: the room on the left, the moves on the right. The pack strip stays
   along the bottom edge (v20 FEEDBACK 25).
   ===================================================================================================== */
.rm.is-fight { display: flex; flex-direction: column; gap: 8px; min-height: 0; }
.fc-room, .fc-act { display: flex; flex-direction: column; gap: 8px; min-height: 0; }
.rm.is-fight > .rm-pack { flex: none; }
/* a full room (the boss's Reaping panel): the cards above scroll rather than the moves; the move area keeps its title,
   one full row of moves, the cue and End the round (reading test point 6) */
.rm.is-fight > .fc-room { flex: 0 1000 auto; overflow: hidden auto; min-height: 330px; }   /* gives way first: its cards' paintings shrink (below), never their lines */
/* a short room: the paintings give the height back, the panels and every card line keep theirs (all in view, nothing
   scrolled away inside the room) */
.rm.is-fight .fc-room > :not(.fc-cards) { flex-shrink: 0; }
.rm.is-fight .fc-cards { flex: 0 1 auto; min-height: 0; grid-template-rows: minmax(0, max-content); grid-auto-rows: minmax(0, max-content); }
.rm.is-fight .fc-card { min-height: 0; }
.rm.is-fight .fc-card > :not(.fc-art) { flex-shrink: 0; }
.rm.is-fight .fc-card .fc-art { aspect-ratio: auto; height: auto; flex: 1 1 var(--art, 125cqi); min-height: 28px; }
.rm.is-fight > .fc-act { flex: 1 1 0; overflow: hidden; min-height: 250px; }   /* the space left under the room part: a longer or shorter move list scrolls inside it, never resizes the room (v21 gate finding 3) */
/* reading test point 6: the moves scroll in their own list; End the round is a footer under it, never over a move, and
   the cue under the list counts the moves below its edge */
.fc-verbs { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; gap: 6px; }
.fc-verbs > .fc-list { flex: 0 1 auto; min-height: 56px; overflow: hidden auto; overscroll-behavior: contain; grid-auto-rows: max-content; padding-bottom: 2px; }
.fc-verbs > .fc-endbar { flex: none; }
.fc-more { flex: none; margin-top: -4px; text-align: center; font: 600 13px var(--hk-text); color: var(--hk-amber-hi); }
.fc-more[hidden] { display: none; }

.fc-top { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline; gap: 2px 8px; }
.fc-top h1 { margin: 0; font: 600 14px var(--hk-title); letter-spacing: .04em; }
.fc-top small { font: 13px var(--hk-text); color: var(--hk-bone-dim); }

.fc-stats { display: grid; grid-template-columns: 1.4fr 1fr 1fr; gap: 6px; }
.fc-stat { background: rgba(26, 28, 30, .85); border: 1px solid var(--hk-stone); border-radius: 6px; padding: 5px 7px; }
.fc-stat b { display: flex; justify-content: space-between; font: 700 13px var(--hk-text); }
.fc-stat.is-hp { --c: var(--hk-blood); }
.fc-stat.is-st { --c: var(--hk-stamina); }
.fc-stat.is-mp { --c: var(--hk-mana); }
.fc-stat .bar, .fc-wrath .bar { display: block; margin-top: 5px; height: 7px; border-radius: 4px; background: rgba(8, 9, 10, .85); overflow: hidden; }
.fc-stat .bar i, .fc-wrath .bar i { display: block; height: 100%; width: calc(var(--v) * 100%); background: var(--c); }

.fc-threat { display: flex; justify-content: space-between; align-items: center; gap: 8px; padding: 7px 10px; border-radius: 6px;
  background: rgba(94, 34, 25, .55); border: 1px solid #7a2a1d; font: 600 15px var(--hk-text); }
.fc-threat small { display: block; font: 13px var(--hk-text); color: var(--hk-bone-dim); }
.fc-threat strong { font: 700 20px var(--hk-text); color: #f0a08a; white-space: nowrap; }
.fc-threat.is-dead { border-color: #c0392b; background: rgba(140, 30, 20, .7); }
.fc-threat.is-won { background: rgba(26, 28, 30, .85); border-color: var(--hk-amber); color: var(--hk-amber-hi); }

/* the boss: the Reaping, its Break bar and the Wrath */
.fc-reap { display: grid; gap: 5px; padding: 7px 10px; border-radius: 6px; background: rgba(26, 28, 30, .88); border: 1px solid var(--hk-bone-dim); }
.fc-reap.is-owed { border-color: #c0392b; background: rgba(70, 20, 30, .7); }
.fc-reap.is-broken { border-color: var(--hk-amber); }
.fc-rh b { font: 700 15px var(--hk-text); }
.fc-rh small { display: block; font: 13px var(--hk-text); color: var(--hk-bone-dim); }
.fc-break b { font: 600 13px var(--hk-text); color: var(--hk-amber-hi); }
.fc-break small { display: block; font: 12px var(--hk-text); color: var(--hk-bone-dim); }
.fc-break.is-out small { color: #f0a090; font-weight: 700; }
.fc-wrath { --c: #9b5bd1; display: grid; grid-template-columns: auto 1fr; align-items: center; gap: 2px 8px; font: 13px var(--hk-text); }
.fc-wrath .bar { margin-top: 0; }
.fc-wrath small { grid-column: 1 / -1; color: var(--hk-bone-dim); }
/* a Break bar: --a is what this round already took, --b what the move would reach */
.bk { display: block; position: relative; height: 7px; margin-top: 4px; border-radius: 4px; background: rgba(8, 9, 10, .85); overflow: hidden; }
.bk::before, .bk::after { content: ""; position: absolute; inset: 0 auto 0 0; }
.bk::before { width: calc(var(--b) * 100%); background: rgba(214, 156, 92, .45); }
.bk::after { width: calc(var(--a) * 100%); background: var(--hk-amber-hi); }

/* the room cards */
/* a card is never wider than a quarter of the row: when monsters die the last ones keep their size (centred) instead of
   growing to fill the row and pushing the moves off the screen */
.fc-cards { display: grid; grid-template-columns: repeat(var(--n), minmax(0, calc((100% - 18px) / 4))); justify-content: center; gap: 6px; }
.fc-card { appearance: none; padding: 0; margin: 0; text-align: left; color: inherit; font: inherit; cursor: pointer; min-width: 0;
  background: rgba(26, 28, 30, .92); border: 2px solid var(--hk-stone); border-radius: 8px; overflow: hidden; display: flex; flex-direction: column; }
.fc-card.is-sel { border-color: var(--hk-amber); box-shadow: 0 0 14px rgba(214, 156, 92, .45); }
.fc-card.is-boss { border-color: var(--hk-bone-dim); }
.fc-card.is-boss.is-sel { border-color: var(--hk-amber-hi); }
.fc-card.is-off .fc-art { filter: grayscale(.8) brightness(.7); }
.fc-card .fc-art { width: 100%; aspect-ratio: 4 / 5; object-fit: cover; display: block; }
.fc-cap { padding: 4px 5px 6px; display: flex; flex-direction: column; gap: 2px; }
.fc-card { container-type: inline-size; }
/* a name wraps only between words; on a narrow card it shrinks so its longest word ("Ghostlight") fits whole */
.fc-cap .nm { font: 700 min(13px, 13.5cqi)/1.15 var(--hk-title); letter-spacing: .02em; }
.fc-cap .l1, .fc-cap .l2 { font: 13px/1.2 var(--hk-text); }
.fc-cap .l1 { color: var(--hk-bone-dim); }
.fc-cap .l2.hit { color: #f0a08a; font-weight: 700; }
.fc-cap .l2.calm { color: var(--hk-fog-pale); }
.fc-cap .l2.use { color: var(--hk-amber-hi); }
.fc-cap .l2.why { color: var(--hk-bone-faint); }
.fc-cap .tag { align-self: flex-start; margin-top: 2px; padding: 1px 5px; border-radius: 4px; background: rgba(8, 9, 10, .7); border: 1px solid var(--hk-stone);
  font: 600 12px/1.2 var(--hk-text); color: var(--hk-amber-hi); }

/* the moves */
.fc-aim { display: flex; justify-content: space-between; align-items: center; gap: 8px; font: 600 14px var(--hk-title); letter-spacing: .03em; }
.fc-info { appearance: none; min-height: 44px; min-width: 44px; padding: 0 12px; border-radius: 6px; border: 1px solid var(--hk-slate, var(--hk-stone));
  background: rgba(26, 28, 30, .9); color: var(--hk-bone); font: 600 13px var(--hk-text); cursor: pointer; }
.fc-moves { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.fc-moves .mv { appearance: none; margin: 0; text-align: left; cursor: pointer; min-height: 56px; padding: 6px 9px; border-radius: 8px;
  border: 1px solid var(--hk-slate, var(--hk-stone)); background: linear-gradient(rgba(255, 236, 200, .06), rgba(0, 0, 0, .25)), #2a2421;
  color: var(--hk-bone); display: flex; flex-direction: column; gap: 2px; font: 14px/1.2 var(--hk-text); }
.fc-moves .mv b { font: 700 14px/1.15 var(--hk-text); }
.fc-moves .mv span { color: var(--hk-bone-dim); }
.fc-moves .mv em { font-style: normal; color: var(--hk-stamina); font-size: 13px; }
.fc-moves .mv.end { grid-column: 1 / -1; min-height: 48px; flex-direction: row; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 2px 10px;
  border-color: #7a2a1d; background: linear-gradient(rgba(255, 236, 200, .06), rgba(0, 0, 0, .25)), #4a1d16; }
.fc-moves .mv.quiet { background: rgba(26, 28, 30, .9); }
.fc-moves .fc-note { grid-column: 1 / -1; margin: 0; padding: 6px 9px; border-radius: 8px; border: 1px dashed var(--hk-bone-faint); color: var(--hk-bone-dim); font: 13px var(--hk-text); }
.fc-moves .mv.is-lethal { border-color: #c0392b; }
.fc-moves .mv.is-ask { border-color: #e74c3c; box-shadow: 0 0 0 2px rgba(231, 76, 60, .45); }
.fc-moves.is-sheet { margin-top: 10px; }

@media (max-width: 559px) {
  .fc-card .fc-art { aspect-ratio: 1 / 1; } .rm.is-fight .fc-card { --art: 100cqi; }
  .fc-moves { gap: 5px; }
  .fc-moves .mv { padding: 5px 8px; gap: 1px; }
  /* the pile beside the title and the room-ends line, as in landscape; the log keeps its newest line: room for the moves */
  .fc-top { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; column-gap: 8px; }
  .fc-top h1 { grid-area: 1 / 1; } .fc-top small { grid-area: 2 / 1; } .fc-top .pilebtn { grid-area: 1 / 2 / 3 / 3; }
  /* the pile grows a mini for each known card and narrows the title: its second line is kept, so nothing below moves (v21 gate finding 3) */
  .rm.is-fight .fc-top h1 { line-height: 19px; min-height: 38px; display: flex; align-items: center; }
  .rm.is-fight .rm-line { height: 23px; }
  .rm.is-fight .rm-line p:first-child:not(:last-child) { display: none; }
  /* the boss's room holds the Reaping panel too: its panel and the stat boxes are as slim as in landscape, so every card
     line and one whole row of moves stay in view */
  .rm.is-fight:has(#reap) .fc-reap { gap: 3px; padding: 5px 8px; }
  .rm.is-fight:has(#reap) .fc-rh b { font-size: 13px; } .rm.is-fight:has(#reap) .fc-rh small, .rm.is-fight:has(#reap) .fc-break b { font-size: 12px; }
  .rm.is-fight:has(#reap) .fc-stat { padding: 3px 7px; } .rm.is-fight:has(#reap) .fc-stat .bar, .rm.is-fight:has(#reap) .fc-wrath .bar { margin-top: 3px; height: 5px; }
}
/* phone landscape: the room on the left at full height (its cards stay in view); the moves on the right, the pack strip under them */
@media (orientation: landscape) and (max-height: 500px) {
  .rm.is-fight { display: grid; grid-template-columns: 1.05fr 1fr; grid-template-rows: minmax(0, 1fr) auto; grid-template-areas: none; align-content: stretch; align-items: stretch; gap: 8px 10px; }
  .rm.is-fight > .fc-room { grid-area: 1 / 1 / 3 / 2; } .rm.is-fight > .fc-act { grid-area: 1 / 2; min-height: 0; }
  .rm.is-fight .rm-pack { grid-area: 2 / 2 / 3 / 3; }
  .fc-room { overflow: auto; }   /* the moves scroll in their own list (.fc-list), End stays under it */
  .fc-card .fc-art { aspect-ratio: 5 / 2; object-position: center 30%; } .rm.is-fight .fc-card { --art: 40cqi; }
  /* the pile stands beside the title and the room-ends line instead of on its own line: the room cards keep their
     bottom lines (the hit, the guard, the tag) in view */
  .fc-top { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; column-gap: 8px; }
  .fc-top h1 { grid-area: 1 / 1; } .fc-top small { grid-area: 2 / 1; } .fc-top .pilebtn { grid-area: 1 / 2 / 3 / 3; }
  .rm.is-fight .rm-pack { --slot: 52px; }
  .fc-room, .fc-act { gap: 6px; }
  .fc-moves { grid-template-columns: 1fr 1fr; gap: 5px; }   /* two, not three: a long move (Burn on the boss) stays shorter than the list */
  .fc-moves .mv { min-height: 44px; padding: 3px 7px; font-size: 13px; gap: 1px; }
  .fc-moves .mv b { font-size: 13px; }
  .fc-moves .mv em { font-size: 12px; }
  .fc-moves .mv.end { min-height: 44px; }   /* a full-width footer (as upright): the moves scroll above it, none half hidden under it */
  .fc-cap .l1, .fc-cap .l2 { font-size: 12px; }
  .fc-threat { padding: 5px 9px; font-size: 13px; }
  .fc-threat strong { font-size: 17px; }
  /* the screen is short: the boss panel and the damage panel share one row, the stat boxes are slimmer, so the room
     cards (the boss among them) stay in view under them */
  .fc-room { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-content: start; }
  .rm.is-fight .fc-room { grid-template-rows: auto auto auto minmax(0, max-content); }   /* the title, the stats, the panels' row, then the cards (they give way) */
  .fc-room > * { grid-column: 1 / -1; }
  .fc-room > .fc-reap { grid-column: 1; } .fc-room > .fc-reap + .fc-threat { grid-column: 2; }
  /* two cards or one: each lies on its side, the picture left and the lines right, half the row wide at most */
  .fc-cards:not(:has(> .fc-card:nth-child(3))) { grid-template-columns: repeat(var(--n), minmax(0, calc((100% - 6px) / 2))); }
  .fc-cards:not(:has(> .fc-card:nth-child(3))) .fc-card { flex-direction: row; }
  .fc-cards:not(:has(> .fc-card:nth-child(3))) .fc-art { width: 38%; flex: none; aspect-ratio: auto; height: auto; min-height: 64px; }
  .fc-cards:not(:has(> .fc-card:nth-child(3))) .fc-cap { flex: 1 1 0; min-width: 0; }
  .fc-reap { gap: 3px; padding: 5px 8px; }
  .fc-rh b { font-size: 13px; } .fc-rh small, .fc-break b { font-size: 12px; }
  .fc-stat { padding: 3px 7px; } .fc-stat .bar, .fc-wrath .bar { margin-top: 3px; height: 5px; }
}
/* desktop: one column as in v20, kept to a readable width */
@media (min-width: 900px) and (min-height: 501px) {
  .rm.is-fight { max-width: 760px; margin: 0 auto; width: 100%; }
  .rm.is-fight > .fc-act { min-height: 330px; }   /* one full row of the taller desktop moves (the boss's: 130 px), the cue and End the round */
  .fc-moves { grid-template-columns: 1fr 1fr 1fr; }
}

/* =====================================================================================================
   EXPLORING (the explore mock-up's look): corner plates, the Explore card, its sheet, the reveal and the region map.
   Landscape phone = (orientation: landscape) and (max-height: 520px); desktop = (min-width: 900px) and (min-height: 501px).
   ===================================================================================================== */
.xi-eye, .xi-paw, .xi-hidden, .xi-fight, .xi-sun, .xi-dawn, .xi-leaf, .xi-den, .xi-find, .xi-trail, .xi-arrow, .xi-you, .xi-page, .xi-check, .xi-dark, .xi-moon, .xi-more { background: currentColor; -webkit-mask: var(--xi) center / contain no-repeat; mask: var(--xi) center / contain no-repeat; }
.xi-eye { --xi: url("assets/ui/xicons/eye.svg?v=620d5d2223ae"); } .xi-paw { --xi: url("assets/ui/xicons/paw.svg?v=bc715aec8307"); } .xi-sun { --xi: url("assets/ui/xicons/sun.svg?v=dd9d64cf9c3b"); } .xi-dawn { --xi: url("assets/ui/xicons/dawn.svg?v=893f1497f021"); }
.xi-leaf { --xi: url("assets/ui/xicons/leaf.svg?v=6e8bfa58d981"); } .xi-den { --xi: url("assets/ui/xicons/den.svg?v=9d6a888c65f1"); } .xi-find { --xi: url("assets/ui/xicons/find.svg?v=b8966a805263"); } .xi-trail { --xi: url("assets/ui/xicons/trail.svg?v=26906f621d37"); }
.xi-arrow { --xi: url("assets/ui/xicons/arrow.svg?v=49b62db7c500"); } .xi-you { --xi: url("assets/ui/xicons/you.svg?v=135f0be3c6c1"); } .xi-page { --xi: url("assets/ui/xicons/page.svg?v=8871f13b8678"); } .xi-check { --xi: url("assets/ui/xicons/check.svg?v=89c0d33275df"); }
.xi-dark { --xi: url("assets/ui/xicons/dark.svg?v=86d6c4049b1e"); } .xi-moon { --xi: url("assets/ui/xicons/moon.svg?v=12cccaa53b7c"); } .xi-more { --xi: url("assets/ui/xicons/more.svg?v=59630ff6f36b"); } .xi-hidden { --xi: url("assets/ui/xicons/hidden.svg?v=ce9f40424b45"); } .xi-fight { --xi: url("assets/ui/xicons/fight.svg?v=1a354fdad9ae"); }

/* a value in a card corner: icon plus number on a painted plate */
.cn { position: absolute; z-index: 2; height: var(--c); min-width: var(--c); box-sizing: border-box; padding: 0 4px 0 2px; display: inline-flex; align-items: center; justify-content: center; gap: 0;
  font: 800 calc(var(--c) * .64) / 1 var(--hk-text); color: var(--hk-bone); font-variant-numeric: tabular-nums; pointer-events: none;
  background: url("assets/ui/textures/umber.webp?v=d5e58909ddf9") center / 80px, #2a211b; background-blend-mode: soft-light;
  -webkit-mask: url("assets/ui/masks/plate.webp?v=70bbb975dac7") center / 100% 100% no-repeat; mask: url("assets/ui/masks/plate.webp?v=70bbb975dac7") center / 100% 100% no-repeat; }
.cn .hk-icon { width: max(18px, calc(var(--c) * .62)); height: max(18px, calc(var(--c) * .62)); }
.cn b { white-space: nowrap; }
.cn-tl { top: 2px; left: 2px; } .cn-tr { top: 2px; right: 2px; } .cn-bl { bottom: 2px; left: 2px; } .cn-br { bottom: 2px; right: 2px; }
.cn.is-mark { padding: 0; width: var(--c); background-color: #1d2226; }
.cn.is-mark .hk-icon { width: max(18px, calc(var(--c) * .78)); height: max(18px, calc(var(--c) * .78)); color: var(--hk-bone); }
.cn-br .hk-icon { color: var(--hk-blood); }
.cn .sl { font-style: normal; font-weight: 600; margin: 0 .02em; opacity: .85; }
.cn-tl .hk-icon, .cn.is-count .hk-icon { color: var(--hk-bone-dim); }
.cn.is-hit { background-color: #6e2a20; } .cn.is-hit .hk-icon { color: #f1c9b8; }
.cn.is-hit.is-night { background-color: #8d1f14; }
.cn.is-calm { background-color: #2a3a33; } .cn.is-calm .hk-icon { color: #bfe0c8; }
.cn.is-light { background-color: #4a3317; } .cn.is-light .hk-icon { color: var(--hk-amber-hi); }

/* the Explore card: the board card with four corner plates, its name on two lines rather than cut */
.hk-card.xc { --c: clamp(29px, calc(var(--w) * .3), 40px); }   /* 29 px: the corner number stays at 18 px or more */
.hk-card.xc .cn { padding: 0 3px 0 1px; }
.hk-card.xc .cn-tl { top: 1px; left: 1px; } .hk-card.xc .cn-tr { top: 1px; right: 1px; } .hk-card.xc .cn-bl { bottom: 1px; left: 1px; } .hk-card.xc .cn-br { bottom: 1px; right: 1px; }
.hk-card.xc .cn.is-mark { padding: 0; }
.hk-card.xc .cn-tl, .hk-card.xc .cn-bl { flex-direction: row-reverse; padding: 0 1px 0 3px; }   /* the number on the outer edge, as in the right corners: on a narrow phone card it stays in the corner */
.hk-card.xc .hk-card__art { object-position: 50% 45%; }
.hk-card.xc .hk-card__name { padding-top: calc(var(--c) * .55); padding-bottom: calc(var(--c) + 2px); }
.hk-card.xc .nm { white-space: normal; overflow-wrap: anywhere; line-height: 1.05; }
.hk-card.xc.is-off .hk-card__art { filter: grayscale(.8) brightness(.55); }
.xmark { position: absolute; z-index: 2; left: 50%; top: 44%; transform: translate(-50%, -50%); width: 48px; height: 48px; display: grid; place-items: center; pointer-events: none;
  background: url("assets/ui/textures/slate.webp?v=77eaf512bb2d") center / 120px, #1d2226;
  -webkit-mask: url("assets/ui/masks/plate.webp?v=70bbb975dac7") center / 100% 100% no-repeat; mask: url("assets/ui/masks/plate.webp?v=70bbb975dac7") center / 100% 100% no-repeat; }
.xmark .hk-icon { width: 30px; height: 30px; color: var(--hk-bone); }

/* the Explore sheet: short rows of icon chips */
.sh-why { display: flex; gap: 8px; align-items: flex-start; margin: 10px 0; padding: 8px 10px; font: 600 16px/1.35 var(--hk-text); color: var(--hk-bone); background: rgba(69, 80, 86, .55); }
.sh-why .hk-icon { flex: none; width: 20px; height: 20px; margin-top: 1px; }
.xrows { display: grid; gap: 6px; margin: 10px 0 12px; }
.xrow { display: grid; grid-template-columns: 100px minmax(0, 1fr); gap: 8px; align-items: center; }   /* the label column holds the longest fight name (Plague-dead) */
.xrow__k { display: inline-flex; align-items: center; gap: 6px; font: 600 14px/1.15 var(--hk-text); color: var(--hk-bone-faint); min-width: 0; }
.xrow__k span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.xrow__k .hk-icon { width: 18px; height: 18px; flex: none; }
.xrow__v { display: flex; flex-wrap: wrap; gap: 5px; align-items: center; min-width: 0; }
.xrow__v .hk-chip .thumb { width: 18px; height: 18px; display: inline-block; }
.xrow__v .hk-chip .thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.hk-chip.is-now { color: var(--hk-amber-hi); }
.xmini { position: relative; display: inline-block; width: 44px; height: 44px; flex: none; box-sizing: border-box; border: 3px solid transparent; border-image: url("assets/ui/frames/frame-ash.webp?v=e763be59fc5a") 16 / 3px / 0 round; background: var(--hk-soot); }
.xmini img, .xmini .hk-icon { width: 100%; height: 100%; object-fit: cover; display: block; }
.xmini b { position: absolute; right: -3px; bottom: -3px; min-width: 20px; height: 20px; padding: 0 3px; box-sizing: border-box; display: grid; place-items: center; font: 800 15px/1 var(--hk-text); color: var(--hk-bone); background: #2a211b; }
.xmini.is-mon b { background: #1d2226; color: #ffd9cc; }

/* the reveal: one large painting, its name and what it holds; one tap goes on */
#reveal { position: fixed; inset: 0; z-index: 46; display: none; overflow-y: auto; overscroll-behavior: contain; background: radial-gradient(ellipse at 50% 42%, rgba(30, 26, 20, .9), rgba(6, 7, 9, .97) 75%); }
#reveal.is-open { display: block; animation: rvin .28s ease-out both; }
@keyframes rvin { from { opacity: 0; } to { opacity: 1; } }
.rv { appearance: none; border: 0; background: none; margin: 0; padding: calc(16px + env(safe-area-inset-top)) 16px calc(16px + env(safe-area-inset-bottom)); box-sizing: border-box; width: 100%; min-height: 100%;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 14px; color: var(--hk-bone); cursor: pointer; font: inherit; }
.rv-enc { cursor: default; }
.rv-art { --c: 40px; position: relative; flex: none; width: min(82vw, 50vh, 460px); aspect-ratio: 1; border: 8px solid transparent; box-sizing: border-box;
  border-image: url("assets/ui/frames/frame-amber.webp?v=0d3aaa1fa1a5") 16 / 8px / 0 round; background: var(--hk-soot); box-shadow: 0 0 40px rgba(214, 156, 92, .3), 0 16px 40px rgba(0, 0, 0, .7);
  animation: rvart .5s cubic-bezier(.2, .8, .2, 1) both; }
.rv-art img, .rv-art .glyph-art, .rv-art > .hk-icon { width: 100%; height: 100%; object-fit: cover; display: block; }
.rv-art.is-foe { border-image-source: url("assets/ui/frames/frame-ash.webp?v=e763be59fc5a"); box-shadow: 0 0 0 2px #8d1f14, 0 0 40px rgba(170, 30, 20, .45); }
.rv-art.is-won img { filter: grayscale(.85) brightness(.55); }
@keyframes rvart { from { transform: scale(.86); opacity: 0; } to { transform: none; opacity: 1; } }
.rv-side { display: flex; flex-direction: column; align-items: center; gap: 12px; min-width: 0; max-width: 100%; }
.rv-name { font: 600 28px/1.1 var(--hk-title); letter-spacing: .04em; text-align: center; text-shadow: 0 2px 6px #000; overflow-wrap: anywhere; }
.rv-need { display: inline-flex; align-items: center; gap: 6px; font: 600 17px/1.2 var(--hk-text); color: var(--hk-bone-dim); }
.rv-need .hk-icon { width: 22px; height: 22px; color: var(--hk-amber); }
.rv-items { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; }
.xtile { --c: 30px; position: relative; display: inline-block; width: 72px; height: 72px; border: 4px solid transparent; box-sizing: border-box;
  border-image: url("assets/ui/frames/frame-ash.webp?v=e763be59fc5a") 16 / 4px / 0 round; background: var(--hk-soot); }
.xtile img, .xtile .glyph-art, .xtile > .hk-icon { width: 100%; height: 100%; object-fit: cover; display: block; }
.xtile .cn-br { right: -4px; bottom: -4px; }
.xtile.is-plain { background: transparent; border: 0; width: auto; min-width: 72px; display: inline-grid; place-items: center; }
.xtile.is-plain .cn { position: static; --c: 40px; }
.xtile.is-plain .cn .hk-icon { color: var(--hk-amber-hi); }
.xtile.is-plain .cn.is-calm .hk-icon { color: #bfe0c8; }
.xtile.is-recipe .cn-br .hk-icon, .xtile .cn.is-mark .hk-icon { color: var(--hk-bone); }
.rv-next { width: 52px; height: 52px; display: grid; place-items: center; color: #23170e;
  background: url("assets/ui/textures/umber.webp?v=d5e58909ddf9") center / 120px, var(--hk-amber); background-blend-mode: soft-light;
  -webkit-mask: url("assets/ui/masks/plate.webp?v=70bbb975dac7") center / 100% 100% no-repeat; mask: url("assets/ui/masks/plate.webp?v=70bbb975dac7") center / 100% 100% no-repeat; }
.rv-next .hk-icon { width: 28px; height: 28px; }
/* the controls of a find and of the recipe window are buttons: the go-on arrow, the picture and tiles that open a sheet */
button.rv-next, button.rv-art, button.rv-card, button.xtile { appearance: none; padding: 0; margin: 0; font: inherit; color: inherit; cursor: pointer; }
button.rv-next { border: 0; }
button.rv-card { border: 0; background: none; }
/* a sheet opened from the reveal shows over it; back from it returns to the reveal */
body.rv-look #scrim { z-index: 47; }
body.rv-look #sheet { z-index: 48; }
.rv-acts { display: flex; gap: 10px; }
.rv-acts .hk-btn { min-height: 52px; min-width: 128px; font-size: 15px; }
/* a recipe learned: the card turns over; the level-up: its choices as tiles, the one tapped shown large */
.rv-art.is-recipe { animation: rvturn .6s cubic-bezier(.2, .8, .2, 1) both; }
@keyframes rvturn { from { transform: perspective(900px) rotateY(90deg) scale(.9); opacity: .2; } to { transform: none; opacity: 1; } }
.rv-kind { display: inline-flex; align-items: center; gap: 6px; font: 700 13px/1 var(--hk-text); letter-spacing: .14em; text-transform: uppercase; color: var(--hk-amber-hi); }
.rv-kind .hk-icon { width: 18px; height: 18px; }
.rv-say { font: 600 17px/1.25 var(--hk-text); color: var(--hk-bone-dim); text-align: center; max-width: 30ch; }
.rv-level { cursor: default; }
/* a teacher met: a smaller picture, then the technique's move card beside what it does and what learning costs */
.rv-teacher { cursor: default; gap: 12px; }
.rv-teacher .rv-art { width: min(64vw, 32vh, 340px); }
.rv-teacher .rv-side { gap: 8px; }
.rv-teach { display: flex; align-items: center; gap: 12px; max-width: min(100%, 460px); }
.rv-teach .fu.fu-wmrow { margin: 0; flex: none; --ru-gw: clamp(84px, min(24vw, 20vh), 110px); }
.rv-teach__v { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; min-width: 0; }
.rv-teach__do { font: 600 15px/1.25 var(--hk-text); color: var(--hk-bone-dim); }
.rv-teach .rv-items { justify-content: flex-start; }
.rv-teach .xtile { width: 56px; height: 56px; }
.rv-teach .rv-need { font-size: 15px; }
/* a teacher's offer on its spot's sheet: the move card, the price beside it */
.tc-offer { display: flex; align-items: center; gap: 16px; }
.tc-offer .fu.fu-wmrow { flex: none; margin: 4px 0; }
.tc-offer .xrows { flex: 1; min-width: 0; margin: 0; }
.xtile.is-short { filter: saturate(.5) brightness(.75); }
/* the recipe window: one card at a time, a close button, the arrows and the dots under it; a tap outside the card closes */
.rv-deck { position: relative; cursor: default; touch-action: pan-y; }
.rv-card { display: flex; flex-direction: column; align-items: center; gap: 14px; min-width: 0; max-width: 100%; }
.rv-close { position: absolute; left: calc(18px + env(safe-area-inset-left)); bottom: calc(16px + env(safe-area-inset-bottom)); }
.rv-nav { display: flex; align-items: center; gap: 18px; }
.rv-arrow { appearance: none; border: 0; padding: 0; cursor: pointer; }
.rv-arrow.is-prev .hk-icon { transform: scaleX(-1); }
.rv-arrow:disabled { opacity: .3; cursor: default; }
.rv-dots { display: flex; gap: 8px; }
.rv-dot { width: 10px; height: 10px; border-radius: 50%; background: rgba(232, 220, 200, .3); }
.rv-dot.is-on { background: var(--hk-amber-hi); box-shadow: 0 0 8px rgba(214, 156, 92, .7); }
.lv-opts { gap: 8px; }
.lv-opt { appearance: none; border: 0; background: none; padding: 0; margin: 0; width: 76px; display: flex; flex-direction: column; align-items: center; gap: 4px; color: var(--hk-bone-dim); cursor: pointer; font: inherit; }
.lv-opt b { font: 600 12px/1.1 var(--hk-text); text-align: center; overflow-wrap: anywhere; }
.lv-opt .xtile.is-skill { border-image-source: url("assets/ui/frames/frame-amber.webp?v=0d3aaa1fa1a5"); }
.lv-opt.is-sel { color: var(--hk-bone); }
.lv-opt.is-sel .xtile { box-shadow: 0 0 0 2px var(--hk-amber-hi), 0 0 18px rgba(214, 156, 92, .55); }
/* the top bar's level: the number, then an XP bar (core.js xpChip) with this level's XP and what it needs on it. The
   number and the bar have fixed widths (two digits, the widest numbers on the bar), so the chip keeps one size at
   every level and XP and the bar only fills */
.hk-chip--xp .lvn { font: 700 17px/1 var(--hk-title); color: var(--hk-amber-hi); width: 20px; flex: none; text-align: center; }
.hk-bar--xp { --hk-bar-c: var(--hk-amber); }
.barn { position: relative; display: inline-flex; flex: none; }
.hk-chip--xp { padding-right: 7px; }   /* the bar ends the chip, so it needs no wider right edge than the left */
.barn .hk-bar { width: 52px; min-width: 0; height: 17px; }
.barn b { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font: 700 11px/1 var(--hk-text); font-variant-numeric: tabular-nums;
  color: var(--hk-bone); text-shadow: 0 0 2px #000, 0 0 3px #000, 0 1px 1px #000; white-space: nowrap; pointer-events: none; }
/* a waiting level-up choice: the chip's plate is a mask that clips its own shadows, so the glow sits on its button as a
   drop-shadow, which follows the plate's painted edge; a thin amber rim stays lit while the outer glow pulses */
.tb:has(> .hk-chip--xp.is-due) { filter: drop-shadow(0 0 1px var(--hk-amber-hi)) drop-shadow(0 0 1px var(--hk-amber-hi)) drop-shadow(0 0 7px rgba(214, 156, 92, .85)); animation: lvdue 1.6s ease-in-out infinite; }
@keyframes lvdue { 50% { filter: drop-shadow(0 0 1px var(--hk-amber-hi)) drop-shadow(0 0 1px var(--hk-amber-hi)) drop-shadow(0 0 3px rgba(214, 156, 92, .35)); } }

/* the world map */
#map { position: fixed; inset: 0; z-index: 35; display: none; box-sizing: border-box; padding: calc(6px + env(safe-area-inset-top)) 10px calc(10px + env(safe-area-inset-bottom));
  background: linear-gradient(rgba(12, 13, 15, .78), rgba(12, 13, 15, .9)), url("assets/ui/textures/slate.webp?v=77eaf512bb2d") 0 0 / 256px, var(--hk-soot); }
#map.is-open { display: grid; grid-template-rows: auto minmax(0, 1fr) auto; gap: 8px; }
.mp-head { display: flex; align-items: center; justify-content: flex-end; gap: 8px; min-width: 0; }
.mp-foot { padding: 0 0 6px 8px; }
.wb-tab { appearance: none; border: 0; cursor: pointer; position: relative; flex: 1 1 0; min-width: 0; min-height: 44px; padding: 0 4px; display: inline-flex; align-items: center; justify-content: center; gap: 4px;
  font: 600 13px/1.05 var(--hk-text); letter-spacing: -.01em; color: var(--hk-bone-dim); background: rgba(45, 47, 48, .7);
  -webkit-mask: url("assets/ui/masks/plate.webp?v=70bbb975dac7") center / 100% 100% no-repeat; mask: url("assets/ui/masks/plate.webp?v=70bbb975dac7") center / 100% 100% no-repeat; }
.wb-tab span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wb-tab.is-on { color: #23170e; background: url("assets/ui/textures/umber.webp?v=d5e58909ddf9") center / 160px, var(--hk-amber); background-blend-mode: soft-light; }
/* the map's body is a window on the world: the painting and its fog (.mp-world) move as one, drawn by the view's
   transform (screens/exploring.js placeMap, panzoom.js), and each card sits on its place's world point (--ax, --ay)
   under that view at its own size (--k below the opening zoom). Past the world's edge its fog goes on */
.mp-body { position: relative; min-height: 0; min-width: 0; overflow: clip; touch-action: none; user-select: none; -webkit-user-select: none; cursor: grab; --z: 1; --tx: 0; --ty: 0; --k: 1; }
.mp-world { position: absolute; left: 0; top: 0; transform-origin: 0 0; will-change: transform; }
.mp-roads { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; overflow: visible; }
.mp-shade { fill: rgba(12, 13, 15, .42); }
.mp-fog { opacity: 1; }
.mp-fogshade { fill: rgba(16, 19, 24, .15); }
.mp-trails path { fill: none; stroke-linecap: round; }
.mp-trail-edge { stroke: rgba(14, 10, 6, .8); }
.mp-road { stroke: #d2ab72; }
.mp-node { --c: 28px; appearance: none; border: 0; background: none; padding: 0; margin: 0; cursor: pointer; position: absolute; left: 0; top: 0; width: var(--nw); display: flex; flex-direction: column; align-items: center; gap: 3px; color: var(--hk-bone);
  transform-origin: calc(var(--cx) * 1px) calc(var(--cy) * 1px); transform: translate(calc((var(--ax) * var(--z) + var(--tx) - var(--cx)) * 1px), calc((var(--ay) * var(--z) + var(--ty) - var(--cy)) * 1px)) scale(var(--k)); }
.mp-body.is-far .mp-name { visibility: hidden; }
.mp-pic { position: relative; width: var(--pic); height: var(--pic); flex: none; box-sizing: border-box; border: 4px solid transparent;
  border-image: url("assets/ui/frames/frame-ash.webp?v=e763be59fc5a") 16 / 4px / 0 round; background: var(--hk-soot); box-shadow: 0 6px 14px rgba(0, 0, 0, .6); }
.mp-pic img, .mp-pic .glyph-art, .mp-pic > .hk-icon { width: 100%; height: 100%; object-fit: cover; display: block; }
.mp-pic .cn-tr { top: -8px; right: -12px; } .mp-pic .cn-bl { bottom: -8px; left: -12px; }
.mp-node.is-here .mp-pic { border-image-source: url("assets/ui/frames/frame-amber.webp?v=0d3aaa1fa1a5"); box-shadow: 0 0 0 2px var(--hk-amber-hi), 0 0 22px rgba(214, 156, 92, .6); }
.mp-you { background-color: #6b4a1e; } .mp-you .hk-icon { color: var(--hk-amber-hi) !important; }
/* a place known but not yet visited: its picture dimmed and misted with the map's own fog painting, its name readable */
.mp-node.is-veiled .mp-pic img { filter: saturate(.4) brightness(.75) blur(.5px); }
.mp-node.is-veiled .mp-pic::after { content: ""; position: absolute; inset: 0; pointer-events: none; background: var(--mp-mist) center / 300% auto; opacity: .45; }
.mp-node.is-veiled .mp-name { color: var(--hk-bone-faint); font-style: italic; }
/* a road out of the region: a small round painted fingerpost at the map's edge, a board with the region and the place */
.mp-name { max-width: 100%; box-sizing: border-box; padding: 1px 5px 2px; border-radius: 4px; background: rgba(14, 12, 10, .74); font: 600 var(--nf, 13px)/1.05 var(--hk-text); text-align: center; text-shadow: 0 1px 3px #000, 0 0 2px #000; overflow-wrap: break-word; }

@media (orientation: landscape) and (max-height: 520px) {
  .xrows { margin: 6px 0 8px; gap: 4px; } .sh-why { margin: 6px 0; padding: 6px 8px; }
  .rv { flex-direction: row; gap: 28px; }
  .rv-art { width: min(78vh, 46vw); }
  .rv-side { max-width: 46vw; }
  .rv-deck { flex-direction: column; gap: 10px; }
  .rv-card { flex-direction: row; gap: 28px; }
  .rv-deck .rv-art { width: min(66vh, 42vw); }
  .lv-opt { width: 62px; } .lv-opt .xtile { width: 58px; height: 58px; }
  .rv-level .rv-side { gap: 8px; } .rv-level .rv-name { font-size: 24px; }
  .rv-teacher .rv-art { width: min(64vh, 30vw); }
  .rv-teacher .rv-side { gap: 6px; max-width: 58vw; } .rv-teacher .rv-name { font-size: 24px; }
  .rv-teacher .rv-say { font-size: 15px; max-width: 40ch; }
  #map.is-open { grid-template-columns: auto minmax(0, 1fr); grid-template-rows: minmax(0, 1fr); padding-left: calc(10px + env(safe-area-inset-left)); padding-right: calc(10px + env(safe-area-inset-right)); }
  .mp-head { flex-direction: column; align-items: stretch; }
  /* a toast must not cover an open sheet: it moves to the top edge and the sheet starts below it */
  body.has-sheet #toast { top: calc(4px + env(safe-area-inset-top)); }
  body.has-sheet #sheet, .mbox { max-height: calc(100vh - 64px); max-height: calc(100dvh - 64px); }
  /* a window starts below the top bar, as the sheet does, and its buttons stay pinned at its bottom while the rest
     scrolls under them (sticky, as the kit's .hk-dock; the row reaches over the window's bottom padding) */
  #modal { padding: 60px 16px 4px; }
  .mbox > .mact { position: sticky; bottom: -16px; z-index: 2; margin: 12px -16px -16px; padding: 10px 16px 16px; background: inherit; box-shadow: 0 -8px 12px -6px rgba(0, 0, 0, .7); }
}
@media (orientation: landscape) and (max-height: 520px) and (min-width: 760px) {
  body.has-sheet #sheet { top: calc(50% + 28px); }   /* the centred sheet */
}
/* short landscape: the Explore sheet in two columns (picture and title left, rows and Explore right), so its button stays on screen */
@media (orientation: landscape) and (max-height: 520px) {
  #sheet[data-kind="explore"] { display: grid; grid-template-columns: 150px minmax(0, 1fr); grid-template-rows: auto auto 1fr; column-gap: 16px; row-gap: 8px; align-content: start; }
  #sheet[data-kind="explore"] .hk-sheet__head { display: contents; }
  #sheet[data-kind="explore"] > .hk-foot { grid-column: 1 / -1; }
  #sheet[data-kind="explore"] .hk-sheet__art { grid-column: 1; grid-row: 1; width: 100%; max-width: none; box-sizing: border-box; }
  #sheet[data-kind="explore"] .hk-sheet__head .hd { grid-column: 1; grid-row: 2 / span 2; }
  #sheet[data-kind="explore"] .xrows { grid-column: 2; grid-row: 1 / span 2; margin: 0; padding-right: 44px; align-self: start; }
  #sheet[data-kind="explore"] .hk-sheet__actions { grid-column: 2; grid-row: 3; align-self: end; }
  /* a greyed Explore's reason: above the rows, where a long line has the room, not under the picture */
  #sheet[data-kind="explore"] > .sh-why { grid-column: 2; grid-row: 1; margin: 0; align-self: start; }
  #sheet[data-kind="explore"]:has(> .sh-why) .xrows { grid-row: 2; }
}
@media (orientation: landscape) and (max-height: 520px) and (min-width: 760px) {
  #sheet[data-kind="explore"] { width: min(720px, 94vw); }
}
@media (min-width: 900px) and (min-height: 501px) {
  .rv-art { width: min(56vh, 520px); }
  .rv-name { font-size: 34px; }
  #map.is-open { padding: 16px max(16px, calc((100vw - 1100px) / 2)) 20px; }
}
@media (prefers-reduced-motion: reduce) { #reveal.is-open, .rv-art, .rv-art.is-recipe, .tb:has(> .hk-chip--xp.is-due) { animation: none; } }

/* the card fight screen (fightui.js) is a full-screen layer with no background of its own: while it is up, the room
   screen under it is hidden and the scene backdrop shows through */
body.is-fu #app { visibility: hidden; }

/* ---------- v22 content: the fight screen's keyword and tool icons outside a fight (game.js ic("fi:…")) ----------
   The mask is set whole on each class: a url() put into --hk-icon would resolve from kit.css's folder. */
.hk-icon[class*="gi-"] { -webkit-mask: var(--gi) center / contain no-repeat; mask: var(--gi) center / contain no-repeat; }
.gi-plate { --gi: url("fightui/icons/plate.webp?v=e3d65d256a91"); } .gi-swap { --gi: url("fightui/icons/swap.webp?v=69a846800b7c"); } .gi-weight { --gi: url("fightui/icons/weight.webp?v=7f7f90a482e7"); }
.gi-raid { --gi: url("fightui/icons/raid.webp?v=bc91b2e17103"); } .gi-bleed { --gi: url("fightui/icons/bleed.webp?v=439437581e37"); }
.gi-venom { --gi: url("fightui/icons/venom.webp?v=09174a6d109b"); } .gi-chill { --gi: url("fightui/icons/chill.webp?v=477464948cb4"); }
.hk-icon.sm { width: 1em; height: 1em; vertical-align: -0.15em; }

/* level-up: the skills offered beside the three boons; one skill's picture and words before Take */
.lv-or { margin: 12px 0 6px; display: flex; align-items: center; justify-content: center; gap: 6px; font: 600 13px var(--hk-title); color: var(--hk-bone-faint); }
.boons.skills { flex-wrap: wrap; }
.hk-card.boon.is-skill { --w: 96px; }
.lv-skill { display: grid; grid-template-columns: 120px minmax(0, 1fr); gap: 12px; align-items: center; text-align: left; }
.lv-skill .lv-art { width: 120px; height: 120px; object-fit: cover; border-radius: 8px; }
.lv-skill h3 { margin: 0 0 4px; font: 600 18px var(--hk-title); color: var(--hk-amber-hi); }
.lv-skill .ml { justify-content: flex-start; }

/* the weapon sheet: a carried piece is a button that opens its sheet */
button.gslot { width: 100%; padding: 4px; border: 0; border-radius: 6px; background: none; color: inherit; text-align: left; cursor: pointer; }
button.gslot:active { background: rgba(255, 255, 255, .06); }
.raid-mons .thumb, .raid-mons img { width: 40px; height: 40px; }

/* v22 raids: the Hearth's flames (lit and out) and a raid report in the losses window */
.flames { display: inline-flex; gap: 4px; }
.flames .flm { width: 22px; height: 22px; color: var(--hk-amber-hi); fill: currentColor; }
.flames .flm.is-out { color: var(--hk-bone-faint); fill: none; opacity: .55; }
.raid-rep { margin: 8px 0; padding: 6px 0; border-top: 1px solid rgba(232, 220, 196, .12); }
.raid-rep:first-of-type { border-top: 0; }
.chip-raid { color: #e0705f; }
