/* The game's own face: title, hero slots, making a hero, conversations, and Lastheat's camp screens.
   Forged iron, banked ember and worn brass. Cut corners instead of rounded ones; nothing glows without a fire under it. */
:root {
  --iron: #221f18;
  --plate: #2e2a20;
  --seam: #3a352a;
  --ember: #d08a2e;
  --ember-hi: #e09a3a;
  --ember-lo: #a9651a;
  --brass: #e6bf72;
  --blood: #b8432f;
  --verdigris: #7fa58c;
  --display: "Cinzel", "Trajan Pro", "Palatino Linotype", Georgia, serif;
  --body: "Alegreya Sans", "Gill Sans", "Trebuchet MS", system-ui, sans-serif;
  --cut: polygon(8px 0, calc(100% - 8px) 0, 100% 8px, 100% calc(100% - 8px), calc(100% - 8px) 100%, 8px 100%, 0 calc(100% - 8px), 0 8px);
}

.logo {
  margin: 0; font-family: var(--display); font-weight: 700; text-transform: uppercase; letter-spacing: 0.12em; line-height: 1;
  font-size: clamp(34px, 10.5vw, 76px); color: var(--brass);
  background: linear-gradient(#f0cf8a 8%, #c9993f 48%, #8a5a1c 92%); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
  filter: drop-shadow(0 2px 0 #000);
}
#gate .panel { text-align: center; }
#gate .sub { font-family: var(--body); color: var(--muted); }

/* ---------------- shared pieces ---------------- */
.front { position: fixed; inset: 0; z-index: 14; background: #0f0d0a; color: var(--text); font: 17px/1.45 var(--body); overflow: hidden; -webkit-user-select: none; user-select: none; touch-action: manipulation; }
.front[hidden] { display: none; }
.front h1 { margin: 0; font-family: var(--display); font-weight: 600; font-size: clamp(26px, 6vw, 40px); line-height: 1.15; letter-spacing: 0.03em; color: var(--brass); }
.front h2 { margin: 0; font-family: var(--display); font-weight: 600; font-size: calc(22px * var(--ts, 1)); letter-spacing: 0.03em; }
.front p { margin: 0; }
.front .muted { color: var(--muted); }
.front .warn { color: #f1b2a8; }
.front .eyebrow, .camp .eyebrow { font-family: var(--body); font-size: calc(13px * var(--ts, 1)); font-weight: 700; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ember-hi); margin: 0; }
svg.rule { display: block; width: 160px; height: 12px; margin: 10px auto 0; fill: var(--brass); stroke: var(--brass); stroke-width: 1.5; opacity: 0.85; }

.forged {
  position: relative; display: grid; gap: 2px; justify-items: center; align-content: center; min-height: 56px; min-width: 44px; padding: 8px 22px;
  font: 700 18px/1.2 var(--body); letter-spacing: 0.04em; color: var(--text); cursor: pointer;
  background: linear-gradient(#383327, #262219); border: 0; clip-path: var(--cut);
  box-shadow: inset 0 0 0 2px #4a4334, inset 0 3px 0 rgba(255, 255, 255, 0.07), inset 0 -4px 0 rgba(0, 0, 0, 0.45);
}
.forged b { font-family: var(--display); font-weight: 700; font-size: calc(19px * var(--ts, 1)); letter-spacing: 0.08em; text-transform: uppercase; }
.forged span { font-weight: 500; font-size: calc(14px * var(--ts, 1)); letter-spacing: 0; opacity: 0.85; }
.forged.primary { color: #1b1408; background: linear-gradient(var(--ember-hi), var(--ember-lo)); box-shadow: inset 0 0 0 2px #6b4212, inset 0 3px 0 rgba(255, 235, 190, 0.35), inset 0 -4px 0 rgba(60, 30, 0, 0.45); }
.forged.quiet { background: transparent; box-shadow: inset 0 0 0 1px var(--seam); font-weight: 500; min-height: 48px; }
.forged:active { transform: translateY(2px); box-shadow: inset 0 0 0 2px #4a4334, inset 0 1px 0 rgba(0, 0, 0, 0.4); }
.forged.primary:active { box-shadow: inset 0 0 0 2px #6b4212, inset 0 1px 0 rgba(60, 30, 0, 0.5); }
.forged:focus-visible { outline: none; box-shadow: inset 0 0 0 3px var(--brass), inset 0 0 0 5px #16140f; }
.forged[disabled] { opacity: 0.5; cursor: default; }

/* ---------------- the hall behind the title: one low crucible, seal moulds on chains ---------------- */
.front .hall { position: absolute; inset: 0; overflow: hidden; background:
  linear-gradient(#0b0a08 0, #14110c 58%, #1d160d 78%, #0d0b08 100%); }
.front .hall::before { content: ""; position: absolute; left: -10%; right: -10%; top: 58%; height: 46%;
  background: repeating-linear-gradient(90deg, rgba(0, 0, 0, 0.35) 0 2px, transparent 2px 9%), linear-gradient(#2a2014, #0d0b08 85%); transform: perspective(420px) rotateX(58deg); transform-origin: 50% 0; }
.front .hall::after { content: ""; position: absolute; inset: 0; background: radial-gradient(ellipse 62% 30% at 50% 63%, rgba(208, 138, 46, 0.16), transparent 70%); }
.front .crucible { position: absolute; left: 50%; top: 50%; width: min(34vw, 190px); aspect-ratio: 19 / 12; transform: translateX(-50%);
  background: linear-gradient(#3b3327, #17130e); clip-path: polygon(0 0, 100% 0, 84% 100%, 16% 100%); }
.front .crucible::before { content: ""; position: absolute; left: 7%; right: 7%; top: 0; height: 13%; background: linear-gradient(90deg, #5c2c0c, #a3561a 50%, #5c2c0c); }
.front .crucible.lit::before { background: linear-gradient(90deg, #b3561a, #f4b24a 50%, #b3561a); animation: banked 5.5s ease-in-out infinite; }
.front .chain { position: absolute; top: -4%; width: 2px; background: repeating-linear-gradient(#4a4132 0 5px, #1a1611 5px 9px); transform-origin: 50% 0; animation: sway 9s ease-in-out infinite; }
.front .chain::after { content: ""; position: absolute; left: 50%; bottom: -30px; width: 30px; height: 34px; transform: translateX(-50%); background: linear-gradient(#3a3226, #1b1711);
  clip-path: polygon(50% 0, 100% 24%, 100% 76%, 50% 100%, 0 76%, 0 24%); }
.front .chain.c1 { left: 22%; height: 34%; animation-duration: 11s; }
.front .chain.c2 { left: 71%; height: 27%; animation-delay: -3s; }
.front .chain.c3 { left: 86%; height: 44%; animation-duration: 13s; animation-delay: -6s; }
@keyframes sway { 0%, 100% { transform: rotate(-1.1deg); } 50% { transform: rotate(1.1deg); } }
@keyframes banked { 0%, 100% { filter: brightness(0.82); } 50% { filter: brightness(1.12); } }
@media (prefers-reduced-motion: reduce) { .front .chain, .front .crucible.lit::before { animation: none; } .forged:active { transform: none; } }

/* ---------------- title: a night camp by the forge fire, the name small at the top, the menu as words down the left ----------------
   The scene is the stage the hero screens use (hero-preview.js forgeStage, its 'camp' framing) from edge to edge. `#fFocus`
   is the part of it the hero is framed in: everything right of the menu on a desk and on a phone on its side, the upper
   part of the screen on a phone held upright, where the menu is a short list in the lower third over a scrim. Until the
   stage is there the page is dark (.waiting); without one the hall is the backdrop as before (body.title-live), or the drawn one. */
.front.title { display: grid; --pad: clamp(18px, 3.2vw, 64px); --menu-w: clamp(18rem, 31vw, 30rem);
  grid-template-columns: var(--menu-w) minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr) auto; }
.front.title[hidden] { display: none; }
.front.title > * { position: relative; z-index: 1; min-width: 0; min-height: 0; }
.front.title > .hall, .front.title > .scene { position: absolute; inset: 0; z-index: 0; }
.front.title.staged > .hall, .front.title.waiting > .hall { display: none; }
.front.title > .scene { overflow: hidden; opacity: 0; }
.front.title.staged > .scene { opacity: 1; transition: opacity 0.7s ease-out; }
/* The dark at the edges of the firelight, and a deeper dark down the side the words are on. */
.front.title.staged > .scene::after { content: ""; position: absolute; inset: 0; pointer-events: none; background:
  linear-gradient(90deg, rgba(11, 9, 7, 0.92) 0, rgba(11, 9, 7, 0.62) calc(var(--menu-w) * 0.8), rgba(11, 9, 7, 0) calc(var(--menu-w) * 1.55)),
  linear-gradient(180deg, rgba(11, 9, 7, 0.82) 0, rgba(11, 9, 7, 0) 24%),
  linear-gradient(0deg, rgba(11, 9, 7, 0.9) 0, rgba(11, 9, 7, 0) 20%),
  radial-gradient(ellipse 80% 78% at 62% 54%, transparent 46%, rgba(6, 5, 4, 0.7) 100%); }
.front.title .t-focus { grid-area: 1 / 2 / -1 / -1; z-index: 1; cursor: grab; touch-action: none; }
.front.title .t-focus.turning { cursor: grabbing; }
.front.title:not(.staged) .t-focus { pointer-events: none; }

.front.title .t-head { grid-area: 1 / 1 / 2 / -1; justify-self: center; text-align: center; pointer-events: none; padding: calc(clamp(14px, 4.4vh, 44px) + var(--safe-t)) 16px 0; }
.front.title .t-name { margin: 0; font: 600 calc(clamp(21px, 2.1vw + 8px, 40px)) / 1.1 var(--display); letter-spacing: 0.26em; margin-right: -0.26em; text-transform: uppercase; color: var(--brass); text-shadow: 0 2px 0 #000, 0 0 22px rgba(11, 9, 7, 0.9); }
.front.title .t-head .rule { width: 132px; margin-top: 9px; }
.front.title .tagline { margin-top: 8px !important; font-size: calc(clamp(14px, 0.5vw + 11px, 17px) * var(--ts, 1)); text-shadow: 0 1px 0 #000, 0 0 12px rgba(11, 9, 7, 0.9); }

.front.title .t-menu { grid-area: 2 / 1 / 3 / 2; align-self: center; padding: 0 0 4vh calc(var(--pad) + var(--safe-l)); overflow-y: auto; scrollbar-width: none; max-height: 100%; }
.front.title .t-menu::-webkit-scrollbar { display: none; }
.front.title .t-menu ul { list-style: none; margin: 0; padding: 0; display: grid; gap: clamp(0px, 0.6vh, 8px); justify-items: start; }
/* An item is its word, large, with room kept at its left for the ember that marks the one in hand. */
.front .t-item { display: grid; grid-template-columns: 30px minmax(0, 1fr); column-gap: 10px; align-items: center; min-height: 48px; max-width: 100%; margin: 0; padding: 4px 14px 4px 0; border: 0; background: none; cursor: pointer; text-align: left;
  font: 600 calc(clamp(22px, 1.5vw + 9px, 36px) * var(--ts, 1)) / 1.15 var(--display); letter-spacing: 0.07em; color: #b3a88f; text-shadow: 0 2px 0 #000, 0 0 16px rgba(11, 9, 7, 0.9); }
.front .t-item .t-mark { grid-row: 1; width: 26px; height: 26px; justify-self: center; fill: none; stroke: var(--ember-hi); stroke-width: 1.6; stroke-linejoin: miter; visibility: hidden; }
.front .t-item .t-mark .core { fill: var(--ember-hi); stroke: none; }
.front .t-item .t-word { grid-column: 2; }
.front .t-item .t-sub { grid-column: 2; font: 500 calc(15px * var(--ts, 1)) / 1.3 var(--body); letter-spacing: 0; color: #a59c86; overflow-wrap: anywhere; }
.front .t-item:hover, .front .t-item:focus { outline: none; color: #f8ecc9; }
.front .t-item:hover .t-mark, .front .t-item:focus .t-mark { visibility: visible; }
.front .t-item:hover .t-sub, .front .t-item:focus .t-sub { color: #dcd3bb; }
.front .t-item:focus .t-word { text-decoration: underline; text-decoration-color: var(--ember); text-decoration-thickness: 2px; text-underline-offset: 0.26em; }
.front .t-item[aria-disabled=true] { cursor: default; color: #7d7563; }
.front .t-item[aria-disabled=true] .t-mark { stroke: #7d7563; } .front .t-item[aria-disabled=true] .t-mark .core { fill: none; }
.front .t-item[aria-disabled=true]:hover, .front .t-item[aria-disabled=true]:focus { color: #9a9079; }

.front.title .credit { grid-area: 3 / 1 / 4 / -1; justify-self: start; margin: 0; padding: 8px 16px calc(12px + var(--safe-b)) calc(var(--pad) + var(--safe-l)); font: calc(13px * var(--ts, 1)) / 1.3 var(--body); color: #8f8672; text-shadow: 0 1px 0 #000; }
.front.title .build { grid-area: 3 / 2 / 4 / -1; justify-self: end; align-self: end; margin: 0 !important; padding: 8px calc(var(--pad) + var(--safe-r)) calc(12px + var(--safe-b)) 0; font-size: calc(12px * var(--ts, 1)); color: #6f6857; }
/* Without the stage the crucible would sit under the words: it steps to the right of them. */
.front.title:not(.staged) .crucible { left: 64%; }
.front.title:not(.staged) .hall::after { background: radial-gradient(ellipse 46% 30% at 64% 63%, rgba(208, 138, 46, 0.16), transparent 70%); }
@media (prefers-reduced-motion: reduce) { .front.title.staged > .scene { transition: none; } }

@media (max-width: 700px) and (orientation: portrait) {
  /* A phone held upright: the scene fills the screen with the hero in its upper part, the name at the top, the menu a short list in the lower third. */
  .front.title { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr) auto auto; --pad: 20px; }
  .front.title .t-focus { grid-area: 2 / 1 / 3 / -1; margin: 6px 0 -3svh; } /* from under the name down to the menu: the head clears the words above, and the fire at their feet shows beside the first of the list */
  .front.title .t-menu { grid-area: 3 / 1; align-self: end; padding: 0 16px 0 calc(14px + var(--safe-l)); max-height: 46svh; }
  .front.title .t-menu ul { gap: 0; }
  .front .t-item { min-height: 46px; font-size: calc(clamp(21px, 6.2vw, 27px) * var(--ts, 1)); }
  .front.title .credit { grid-area: 4 / 1; padding: 6px 16px calc(10px + var(--safe-b)) calc(20px + var(--safe-l)); font-size: calc(12px * var(--ts, 1)); }
  .front.title .build { display: none; }
  .front.title.staged > .scene::after { background:
    radial-gradient(ellipse 120% 52% at 0% 100%, rgba(11, 9, 7, 0.97) 34%, rgba(11, 9, 7, 0.6) 66%, rgba(11, 9, 7, 0) 100%),
    linear-gradient(0deg, rgba(11, 9, 7, 0.82) 0, rgba(11, 9, 7, 0) 38%),
    linear-gradient(180deg, rgba(11, 9, 7, 0.86) 0, rgba(11, 9, 7, 0) 22%),
    radial-gradient(ellipse 90% 60% at 50% 40%, transparent 50%, rgba(6, 5, 4, 0.6) 100%); }
  .front.title:not(.staged) .crucible { left: 50%; top: 34%; }
  .front.title:not(.staged) .hall::after { background: radial-gradient(ellipse 62% 26% at 50% 44%, rgba(208, 138, 46, 0.16), transparent 70%); }
}
@media (orientation: landscape) and (max-height: 520px) {
  /* A phone on its side: the menu down the left, the scene on the right, the name small over both. */
  .front.title { --menu-w: clamp(15rem, 40vw, 21rem); --pad: 18px; }
  .front.title .t-head { padding-top: calc(8px + var(--safe-t)); }
  .front.title .t-name { font-size: 19px; }
  .front.title .t-head .rule { display: none; }
  .front.title .tagline { margin-top: 2px !important; font-size: calc(13px * var(--ts, 1)); }
  .front.title .t-menu { padding-bottom: 0; align-self: center; }
  .front.title .t-menu ul { gap: 0; }
  .front .t-item { min-height: 44px; padding-top: 2px; padding-bottom: 2px; font-size: calc(21px * var(--ts, 1)); }
  .front .t-item .t-sub { font-size: calc(13px * var(--ts, 1)); }
  .front.title .credit { padding-bottom: calc(6px + var(--safe-b)); padding-top: 2px; font-size: calc(11.5px * var(--ts, 1)); }
  .front.title .build { display: none; }
}

/* ---------------- pages: the notice ---------------- */
.front .page { position: absolute; inset: 0; overflow-y: auto; -webkit-overflow-scrolling: touch; touch-action: pan-y; display: grid; align-content: start; gap: 14px;
  padding: calc(14px + var(--safe-t)) max(calc(18px + var(--safe-r)), calc(50vw - 300px)) calc(22px + var(--safe-b)) max(calc(18px + var(--safe-l)), calc(50vw - 300px)); }
.front .foot { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 10px; margin-top: 4px; }

/* ---------------- choosing a hero and making one: the forge floor from edge to edge, the controls laid over it ----------------
   One grid for both screens. `.scene` holds the 3D canvas (hero-preview.js forgeStage) and lies under everything; the other
   cells sit over it. `#fFocus` is the part of the scene no panel covers: the figure is framed inside it and a drag across it
   turns the figure. Three shapes: a desk (panels down both edges, the figure between), a phone held upright (the scene on
   top with the figure filling it and a turn button at each side, then the heading, the controls scrolling under it, and
   the main button on its own row at the foot) and a phone on its side (the scene on the left, the controls on the right). Without the stage (.staged is absent) the same cells are the words on the plain page. */
.front .lay { position: absolute; inset: 0; display: grid; --pad: clamp(12px, 1.5vw, 28px); --scene-h: 52svh;
  grid-template-columns: minmax(0, 1fr) auto; grid-template-rows: var(--scene-h) auto minmax(0, 1fr) auto; }
.front:not(.staged) .lay { --scene-h: auto; }
.front .lay > * { position: relative; z-index: 1; min-width: 0; min-height: 0; }
.front .lay > .scene { z-index: 0; grid-area: 1 / 1 / 2 / -1; overflow: hidden; }
.front .scene .stage3d { position: absolute; inset: 0; display: block; width: 100%; height: 100%; }
.front.staged .scene::after { content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(15, 13, 10, 0.78) 0, rgba(15, 13, 10, 0) 26%), linear-gradient(0deg, #0f0d0a 0, rgba(15, 13, 10, 0) 16%); }

.front .lay-head { grid-area: 2 / 1 / 3 / -1; align-self: start; justify-self: start; pointer-events: none;
  padding: 8px calc(var(--pad) + var(--safe-r)) 0 calc(var(--pad) + var(--safe-l)); text-align: left; }
.front:not(.staged) .lay-head { padding-top: 4px; }
.front .lay-head h1 { font-size: calc(clamp(22px, 2.7vw, 46px) * var(--ts, 1)); text-shadow: 0 2px 0 #000, 0 0 18px #0f0d0a; }
.front .lay-back { grid-area: 1 / 1 / 2 / -1; align-self: start; justify-self: start; padding: calc(10px + var(--safe-t)) 0 0 calc(var(--pad) + var(--safe-l)); }
.front .lay-back .forged { min-height: 48px; padding: 6px 18px; font-size: calc(16px * var(--ts, 1)); background: rgba(22, 19, 14, 0.82); }

.front .lay-focus { grid-area: 1 / 1 / 2 / -1; display: grid; grid-template-rows: minmax(0, 1fr) auto; }
/* Upright, the figure has the whole scene: the strip lies over it, a turn button at each side at the figure's waist, and on the heroes screen the name along the foot (the figure stops short of it). */
.front #fFocus { grid-area: 1 / 1 / -1 / -1; }
.front.heroes #fFocus { margin-bottom: calc(34px * var(--ts, 1)); }
.front .strip { grid-area: 1 / 1 / -1 / -1; grid-template-rows: minmax(0, 1fr) auto minmax(0, 1fr) auto; }
.front .strip .caption { display: none; }
.front .strip .who p { display: none; }
.front .strip .who #fWhoNote:not([hidden]) { display: block; font-size: calc(13px * var(--ts, 1)); } /* said wherever the figure is a stand-in, even where there is no room for the line under the name */
.front:not(.staged) .lay-focus { display: none; }
.front #fFocus { min-height: 0; cursor: grab; touch-action: none; }
.front #fFocus.turning { cursor: grabbing; }
.front .strip { display: grid; grid-template-columns: 48px minmax(0, 1fr) 48px; align-items: center; gap: 10px; padding: 0 8px; pointer-events: none; }
.front .strip > * { pointer-events: auto; }
.front .strip .who { grid-column: 1 / -1; grid-row: 4; padding-bottom: 6px; pointer-events: none; }
.front .strip .caption { grid-column: 2; grid-row: 1; text-align: center; font-size: calc(15px * var(--ts, 1)); line-height: 1.25; color: var(--brass); text-shadow: 0 1px 0 #000, 0 0 10px #0f0d0a; pointer-events: none; }
.front .lay.vacant .strip .forged { visibility: hidden; } /* nobody to turn */
.front .strip #fTurnL { grid-column: 1; grid-row: 2; }
.front .strip #fTurnR { grid-column: 3; grid-row: 2; }
.front .forged.icon { min-width: 48px; min-height: 48px; padding: 8px; }
.front .forged.quiet.icon { background: rgba(22, 19, 14, 0.82); }
.front .forged.big { min-height: 60px; }
.front .forged.big b { font-size: calc(20px * var(--ts, 1)); }
.front .glyph { display: block; width: 24px; height: 24px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: square; stroke-linejoin: miter; }
.front .glyph .dot { fill: currentColor; stroke: none; }
.front .sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* The controls under the scene: one scrolling column on a phone. On a desk this box steps aside and its two halves take the edges. */
.front .lay-body { grid-area: 3 / 1 / 4 / -1; overflow-y: auto; -webkit-overflow-scrolling: touch; touch-action: pan-y; scrollbar-width: none; display: grid; align-content: start; gap: 14px;
  padding: 12px calc(var(--pad) + var(--safe-r)) 14px calc(var(--pad) + var(--safe-l)); }
.front .lay-body::-webkit-scrollbar, .front .lay-left::-webkit-scrollbar, .front .origin-panel::-webkit-scrollbar, .front .roster::-webkit-scrollbar { display: none; }
.front .more-below { -webkit-mask-image: linear-gradient(#000 calc(100% - 40px), transparent); mask-image: linear-gradient(#000 calc(100% - 40px), transparent); }
/* Under the scene the two halves give up their boxes, so the order can be the reading order: the choices, what the chosen one means, then appearance. */
.front .lay-left, .front .lay-right { display: contents; }
.front .origin-panel { order: 2; } .front .looks { order: 3; }
@media (min-width: 640px) { .front.create .lay-body { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); column-gap: 18px; } .front .origins { grid-column: 1; } .front .looks { grid-column: 1; grid-row: 2; } .front .origin-panel { grid-column: 2; grid-row: 1 / span 2; } }

/* The foot: the main thing to do, on a row of its own, so nothing ever scrolls beneath it. */
.front .lay-main { grid-area: 4 / 1 / 5 / -1; display: flex; flex-wrap: wrap; gap: 8px 10px; justify-content: center; align-items: end;
  padding: 10px calc(var(--pad) + var(--safe-r)) calc(12px + var(--safe-b)) calc(var(--pad) + var(--safe-l)); background: #0f0d0a; box-shadow: 0 -1px 0 var(--seam); }
.front.heroes .lay-main { grid-column: 1; padding-right: 10px; }
.front .lay-corner { grid-area: 4 / 2; padding: 10px calc(var(--pad) + var(--safe-r)) calc(12px + var(--safe-b)) 0; background: #0f0d0a; box-shadow: 0 -1px 0 var(--seam); align-self: stretch; display: grid; align-content: end; }
.front .lay-corner .forged { min-height: 60px; }
.front .lay-corner [hidden] { display: none; }
.front .lay-main .warn { position: absolute; left: calc(var(--pad) + var(--safe-l)); right: calc(var(--pad) + var(--safe-r)); bottom: 100%; margin: 0 0 6px !important; padding: 8px 12px; text-align: center;
  font-size: calc(16px * var(--ts, 1)); background: #2a1613; box-shadow: inset 0 0 0 1px #7a3b31; clip-path: var(--cut); }
.front .lay-main .warn[hidden] { display: none; }
.front .name-row { flex: 1 1 15rem; max-width: 26rem; display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px; }
.front .lay-main .primary { flex: 1 1 13rem; max-width: 26rem; }
.front .name-row .forged.icon { min-width: 56px; min-height: 56px; }
.front input[type=text], .front #fName { min-height: 56px; padding: 8px 14px; font: 500 calc(20px * var(--ts, 1)) var(--body); color: var(--text); background: #14110d; border: 0; box-shadow: inset 0 0 0 2px var(--seam); clip-path: var(--cut);
  -webkit-user-select: text; user-select: text; }
.front #fName { min-width: 0; width: 100%; box-sizing: border-box; }
.front #fName::placeholder { color: #8f8672; }
.front #fName:focus { outline: none; box-shadow: inset 0 0 0 2px var(--brass); }
.front .who { display: grid; gap: 2px; text-align: center; min-width: 0; }
.front .who h2 { font-size: calc(clamp(24px, 2.5vw, 40px) * var(--ts, 1)); line-height: 1.1; color: var(--brass); overflow-wrap: anywhere; text-shadow: 0 2px 0 #000, 0 0 18px #0f0d0a; }
.front .who p { font-size: calc(16px * var(--ts, 1)); color: #dcd3bb; text-shadow: 0 1px 0 #000, 0 0 10px #0f0d0a; }

/* A choice in a list (an origin, a hero): a cut plate with a diamond that is hollow until it is the one chosen. */
.front .origins { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; min-width: 0; }
.front .roster { display: grid; gap: 8px; min-width: 0; }
.front .origin, .front .hero-row { display: grid; grid-template-columns: 22px minmax(0, 1fr); gap: 10px; align-items: center; width: 100%; min-height: 48px; padding: 8px 12px; margin: 0; border: 0; cursor: pointer; text-align: left;
  font: inherit; font-size: calc(16px * var(--ts, 1)); line-height: 1.3; color: var(--text); background: rgba(27, 24, 18, 0.94); clip-path: var(--cut); box-shadow: inset 0 0 0 1px var(--seam); }
.front .origin .mark, .front .hero-row .mark { width: 16px; height: 16px; margin: 0 3px; transform: rotate(45deg); box-shadow: inset 0 0 0 2px #6a6150; }
.front .origin.on, .front .hero-row.on { background: linear-gradient(#2f2a1f, #231f17); box-shadow: inset 0 0 0 2px var(--brass); }
.front .origin.on .mark, .front .hero-row.on .mark { background: var(--ember); box-shadow: inset 0 0 0 2px var(--brass), inset 0 0 0 4px #231f17; }
/* Focus is a pale line inside the plate, so it is never mistaken for the brass edge of the one chosen. */
.front .origin:focus-visible, .front .hero-row:focus-visible { outline: 2px solid #f3ead2; outline-offset: -7px; }
.front .origin b, .front .hero-row b { font-family: var(--display); font-weight: 600; letter-spacing: 0.04em; }
.front .origin-line { display: none; }
.front .hero-row { align-items: start; padding: 12px 14px; }
.front .hero-row .mark { margin-top: 5px; }
.front .hero-text { display: grid; gap: 2px; min-width: 0; font-size: calc(15px * var(--ts, 1)); }
.front .hero-text b { font-size: calc(19px * var(--ts, 1)); color: var(--brass); overflow-wrap: anywhere; }
.front .hero-row.empty b { color: var(--text); }
.front .hero-row.empty { background: rgba(23, 20, 15, 0.9); }

/* The chosen origin: who you were, then three facts, each with its mark. */
.front .origin-panel { display: grid; gap: 10px; align-content: start; padding: 16px 18px; background: rgba(28, 25, 19, 0.94); clip-path: var(--cut); box-shadow: inset 0 0 0 1px var(--seam), inset 0 3px 0 rgba(255, 255, 255, 0.04);
  -webkit-user-select: text; user-select: text; }
.front .origin-panel h2 { color: var(--brass); font-size: calc(clamp(22px, 1.9vw, 28px) * var(--ts, 1)); }
.front .origin-panel .about { font-size: calc(17px * var(--ts, 1)); line-height: 1.45; max-width: 62ch; }
.front .facts { list-style: none; margin: 2px 0 0; padding: 10px 0 0; display: grid; gap: 10px; border-top: 1px solid var(--seam); }
.front .facts li { display: grid; grid-template-columns: 24px minmax(0, 1fr); gap: 12px; align-items: start; }
.front .facts .glyph { margin-top: 1px; color: var(--ember-hi); }
.front .facts h3 { margin: 0; font: 700 calc(15px * var(--ts, 1)) / 1.3 var(--body); color: var(--brass); }
.front .facts p { margin-top: 1px; font-size: calc(16px * var(--ts, 1)); line-height: 1.4; color: #cfc6ae; max-width: 62ch; }
.front .more { justify-self: start; min-height: 44px; margin: -4px 0 -8px -8px; padding: 6px 8px; background: none; border: 0; cursor: pointer; font: 700 calc(15px * var(--ts, 1)) var(--body); color: var(--brass); text-decoration: underline; text-underline-offset: 4px; }
.front .more:focus-visible { outline: 2px solid var(--brass); outline-offset: -2px; }

/* Appearance: a row a part of the hero, a step left and a step right, and between them its name over the choice, said in words beside its swatch. */
.front .looks { display: grid; gap: 6px; padding: 12px 12px 10px; background: rgba(27, 24, 18, 0.94); clip-path: var(--cut); box-shadow: inset 0 0 0 1px var(--seam); }
.front .looks[hidden] { display: none; }
.front .looks h2 { font-size: calc(17px * var(--ts, 1)); color: var(--brass); }
.front .look-row { display: grid; grid-template-columns: 44px minmax(0, 1fr) 44px; gap: 6px; align-items: center; }
.front .look-name { font-weight: 700; font-size: calc(13px * var(--ts, 1)); line-height: 1.2; color: var(--muted); }
.front .look-row .forged.icon { min-width: 44px; min-height: 44px; padding: 6px; background: transparent; }
.front .look-value { display: grid; justify-items: center; gap: 1px; min-width: 0; font-size: calc(15px * var(--ts, 1)); line-height: 1.25; }
.front .look-pick { display: flex; gap: 8px; align-items: center; white-space: nowrap; }
.front .swatch { flex: none; width: 16px; height: 16px; transform: rotate(45deg); box-shadow: 0 0 0 1px #000, 0 0 0 2px #6a6150; }

@media (orientation: landscape) and (max-height: 520px) {
  /* A phone on its side: the scene down the left, the controls on the right. */
  .front .lay { grid-template-columns: minmax(0, 40%) minmax(0, 1fr) auto; grid-template-rows: auto minmax(0, 1fr) auto; }
  .front #fFocus, .front.heroes #fFocus { grid-area: auto; margin: 0; } .front .strip { grid-area: auto; grid-template-rows: none; } .front .strip .who { grid-column: 2; grid-row: 1; padding: 0; } .front .strip #fTurnL, .front .strip #fTurnR { grid-row: 1; }
  .front:not(.staged) .lay { grid-template-columns: 0 minmax(0, 1fr) auto; }
  .front .lay > .scene { grid-area: 1 / 1 / -1 / 2; }
  .front.staged .scene::after { background: linear-gradient(270deg, #0f0d0a 0, rgba(15, 13, 10, 0) 22%), linear-gradient(0deg, rgba(15, 13, 10, 0.85) 0, rgba(15, 13, 10, 0) 24%); }
  .front .lay-focus { grid-area: 1 / 1 / -1 / 2; }
  .front .lay-back { grid-area: 3 / 1; align-self: end; padding: 0 0 calc(10px + var(--safe-b)) calc(12px + var(--safe-l)); }
  .front:not(.staged) .lay-back { grid-area: 1 / 2; align-self: center; padding: calc(8px + var(--safe-t)) 0 0 12px; }
  .front .lay-head { grid-area: 1 / 2 / 2 / -1; justify-self: end; text-align: right; padding: calc(10px + var(--safe-t)) calc(14px + var(--safe-r)) 0 12px; }
  .front .lay-head h1 { font-size: calc(22px * var(--ts, 1)); }
  .front .lay-body { grid-area: 2 / 2 / 3 / -1; padding: 8px calc(14px + var(--safe-r)) 10px 12px; }
  .front.create .lay-body { grid-template-columns: minmax(0, 1fr); } .front .origins, .front .looks, .front .origin-panel { grid-column: 1; grid-row: auto; }
  .front .lay-main { grid-area: 3 / 2 / 4 / -1; padding: 8px calc(14px + var(--safe-r)) calc(8px + var(--safe-b)) 12px; flex-wrap: nowrap; }
  .front .lay-main .warn { left: 12px; right: calc(14px + var(--safe-r)); }
  .front.heroes .lay-main { grid-area: 3 / 2 / 4 / 3; padding-right: 8px; }
  .front.heroes .who h2 { font-size: calc(20px * var(--ts, 1)); }
  .front .lay-corner { grid-area: 3 / 3; padding: 8px calc(14px + var(--safe-r)) calc(8px + var(--safe-b)) 0; }
  .front .forged.big, .front .lay-corner .forged { min-height: 52px; }
  .front .strip { grid-template-columns: 48px minmax(0, 1fr) 48px; padding: 0 10px calc(10px + var(--safe-b)) calc(98px + var(--safe-l)); }
  .front .forged.big b { font-size: calc(17px * var(--ts, 1)); letter-spacing: 0.05em; } .front .name-row { flex: 1 1 11rem; } .front .lay-main .primary { flex: 1 1 11rem; }
}

@media (min-width: 900px) and (min-height: 521px) {
  /* A desk, a laptop, an ultrawide: the scene is the whole screen. The list hugs one edge and the panel the other, each
     only as wide as it needs, and everything between them is the figure's. */
  .front .lay { --lw: clamp(16rem, 21vw, 22rem); --rw: clamp(21rem, 30vw, 33rem); grid-template-columns: var(--lw) minmax(0, 1fr) var(--rw); grid-template-rows: auto minmax(0, 1fr) auto; }
  .front .lay > .scene { grid-area: 1 / 1 / -1 / -1; }
  .front #fFocus, .front.heroes #fFocus { grid-area: auto; margin: 0; } .front .strip { grid-area: auto; grid-template-rows: none; grid-template-columns: 48px minmax(0, 24rem) 48px; justify-content: center; padding: 0 12px 4px; }
  .front .strip .caption { display: block; } .front .strip .who { grid-column: 2; grid-row: 1; padding: 0; } .front .strip #fTurnL, .front .strip #fTurnR { grid-row: 1; } .front .strip .who p:not([hidden]) { display: block; }
  .front.staged .scene::after { background:
    linear-gradient(90deg, rgba(15, 13, 10, 0.9) 0, rgba(15, 13, 10, 0.55) calc(var(--lw) * 0.85), rgba(15, 13, 10, 0) calc(var(--lw) * 1.5)),
    linear-gradient(270deg, rgba(15, 13, 10, 0.9) 0, rgba(15, 13, 10, 0.6) calc(var(--rw) * 0.9), rgba(15, 13, 10, 0) calc(var(--rw) * 1.4)),
    linear-gradient(0deg, rgba(15, 13, 10, 0.94) 0, rgba(15, 13, 10, 0) 24%), linear-gradient(180deg, rgba(15, 13, 10, 0.8) 0, rgba(15, 13, 10, 0) 20%); }
  .front.heroes.staged .scene::after { background:
    linear-gradient(270deg, rgba(15, 13, 10, 0.9) 0, rgba(15, 13, 10, 0.6) calc(var(--rw) * 0.9), rgba(15, 13, 10, 0) calc(var(--rw) * 1.4)),
    linear-gradient(0deg, rgba(15, 13, 10, 0.94) 0, rgba(15, 13, 10, 0) 26%), linear-gradient(180deg, rgba(15, 13, 10, 0.8) 0, rgba(15, 13, 10, 0) 20%); }
  .front .lay-head { grid-area: 1 / 1 / 2 / -1; justify-self: start; text-align: left; padding: calc(var(--pad) + var(--safe-t)) calc(var(--pad) + var(--safe-r)) 12px calc(var(--pad) + var(--safe-l)); }
  .front .lay-focus { grid-area: 1 / 2 / 3 / 3; }
  .front .lay-body { display: contents; }
  .front .lay-left { grid-area: 2 / 1; display: grid; align-content: start; gap: 14px; overflow-y: auto; scrollbar-width: none; padding: 2px 0 2px calc(var(--pad) + var(--safe-l)); }
  .front .lay-right { grid-area: 2 / 3; display: flex; flex-direction: column; padding: 2px calc(var(--pad) + var(--safe-r)) 2px 0; }
  .front .origins, .front .looks, .front .origin-panel { grid-column: auto; grid-row: auto; }
  .front .origin-panel, .front .roster { flex: 0 1 auto; min-height: 0; overflow-y: auto; scrollbar-width: none; }
  .front .origins { grid-template-columns: 1fr; }
  .front .origin { min-height: 56px; padding: 10px 14px; }
  .front .lay-back { grid-area: 3 / 1; align-self: end; padding: 12px 0 calc(var(--pad) + var(--safe-b)) calc(var(--pad) + var(--safe-l)); }
  .front .lay-back .forged, .front .lay-corner .forged { min-height: 56px; padding: 8px 26px; background: rgba(22, 19, 14, 0.82); }
  .front .lay-main, .front.heroes .lay-main { grid-area: 3 / 2; padding: 10px 12px calc(var(--pad) + var(--safe-b)); background: none; box-shadow: none; }
  .front.heroes .lay-main .primary { flex: none; width: min(22rem, 100%); }
  .front .lay-corner { grid-area: 3 / 3; justify-self: end; align-self: end; padding: 12px calc(var(--pad) + var(--safe-r)) calc(var(--pad) + var(--safe-b)) 0; background: none; box-shadow: none; }
  .front .forged.big { min-height: 64px; }
  /* Without the stage there is no figure to leave room for: the list and the panel sit side by side from the left. */
  .front:not(.staged) .lay { grid-template-columns: var(--lw) minmax(0, 46rem) minmax(0, 1fr); }
  .front:not(.staged) .lay-right { grid-area: 2 / 2; padding: 2px 0 2px 18px; }
  .front:not(.staged) .lay-main { grid-area: 3 / 2; }
  .front:not(.staged).heroes .lay { grid-template-columns: minmax(0, 40rem) minmax(0, 1fr) auto; }
  .front:not(.staged).heroes .lay-right { grid-area: 2 / 1; padding: 2px 0 2px calc(var(--pad) + var(--safe-l)); }
  .front:not(.staged).heroes .lay-main { grid-area: 3 / 2; align-items: start; }
}
@media (min-width: 900px) and (min-height: 800px) {
  /* Room to say a line about each origin under its name. */
  .front .origin-line { display: block; font-size: calc(15px * var(--ts, 1)); }
  .front .origin { align-items: start; } .front .origin .mark { margin-top: 4px; }
}

/* ---------------- conversations (talk.js): whoever speaks is shown speaking ----------------
   The scene stays up behind, dimmed. The speaker stands at the lower left, in front of the left end of a wide box; their
   name and what they are sit on a plate on the box's top edge; one beat of the line is up at a time. --ph and --pw are
   the portrait's height and width, --lap how far it stands in front of the box: the words begin past it, so nothing is
   ever written under the figure. Three shapes: a desk (below), a phone held upright (the portrait stands on the box's top
   edge, the box across the foot) and a phone on its side (the portrait down the left, the box beside it). */
.talk { position: fixed; inset: 0; z-index: 38; color: var(--text); font: 17px/1.45 var(--body); touch-action: manipulation; -webkit-user-select: none; user-select: none; cursor: default;
  --pad: clamp(12px, 1.6vw, 28px); --ph: clamp(280px, 56vh, 660px); --pw: calc(var(--ph) * 0.66); --lap: calc(var(--pw) * 0.4);
  background: linear-gradient(0deg, rgba(9, 8, 6, 0.95) 0, rgba(9, 8, 6, 0.72) 42%, rgba(9, 8, 6, 0.58) 100%); }
.talk[hidden] { display: none; }
/* While somebody speaks, the quest line and the Menu button step aside (talk.js sets body.talking); they are back as it closes. */
body.talking #objective, body.talking #menuBtn { visibility: hidden; }
/* Narration of what came before is told over a darker hall; it lifts when somebody speaks. */
.talk::before { content: ""; position: absolute; inset: 0; background: #090806; opacity: 0; transition: opacity 0.6s ease; pointer-events: none; }
.talk.deep::before { opacity: 0.66; }
.talk-stage { position: absolute; left: max(calc(var(--pad) + var(--safe-l)), calc(50vw - 44rem)); bottom: calc(var(--pad) + var(--safe-b));
  width: min(calc(100vw - 2 * var(--pad) - var(--safe-l) - var(--safe-r)), calc(var(--pw) - var(--lap) + 58rem)); }

.talk-portrait { position: absolute; left: 0; bottom: 0; z-index: 1; width: var(--pw); height: var(--ph); pointer-events: none; }
.talk.no-figure .talk-portrait { display: none; }
/* The dark the figure stands out of, and the forge's light low behind it (nothing glows here without a fire under it). */
.talk-portrait::before { content: ""; position: absolute; inset: 6% -12% 0; background:
  radial-gradient(ellipse 52% 46% at 50% 100%, rgba(208, 138, 46, 0.3), transparent 72%), radial-gradient(ellipse 58% 62% at 50% 62%, rgba(9, 8, 6, 0.6), transparent 74%); }
.talk-portrait .portrait3d { position: absolute; inset: 0; display: block; width: 100%; height: 100%; }
/* Nobody to show (no model pack, models off, no WebGL): a cut plate in their colour, a head and shoulders, their initial. */
.talk-sil { position: absolute; left: 8%; right: 20%; bottom: 0; height: 60%; clip-path: var(--cut); background: linear-gradient(#2a251b, #14110d); background: linear-gradient(color-mix(in srgb, var(--tint) 22%, #1d1912), #14110d);
  box-shadow: inset 0 0 0 2px var(--seam), inset 0 3px 0 rgba(255, 255, 255, 0.05); }
.talk-sil .talk-bust { position: absolute; left: 6%; right: 6%; bottom: 0; width: 88%; height: 82%; fill: #3a352a; fill: color-mix(in srgb, var(--tint) 46%, #14110d); }
.talk-sil b { position: absolute; left: 12px; top: 8px; font: 700 calc(clamp(26px, 4.6vh, 46px)) / 1 var(--display); color: var(--tint, var(--brass)); text-shadow: 0 2px 0 #000; }

.talk-box { position: relative; margin-left: calc(var(--pw) - var(--lap)); }
.talk-panel { display: grid; gap: 10px; padding: 30px 22px 16px calc(var(--lap) + 26px); background: linear-gradient(#27231a, #191610); clip-path: var(--cut);
  box-shadow: inset 0 0 0 2px var(--seam), inset 0 4px 0 rgba(255, 255, 255, 0.05), inset 0 -5px 0 rgba(0, 0, 0, 0.4); }
.talk.no-figure .talk-panel { padding-left: 30px; }
/* The plate: brass-edged iron riveted over the box's top edge, the name in the display face and what they are under it. */
.talk-plate { position: absolute; z-index: 2; left: calc(var(--lap) + 12px); bottom: calc(100% - 18px); max-width: calc(100% - var(--lap) - 28px); display: grid; gap: 1px; padding: 7px 22px 8px 18px;
  background: linear-gradient(#3b3324, #231f16); clip-path: var(--cut); box-shadow: inset 0 0 0 2px #8a7550, inset 0 3px 0 rgba(255, 235, 190, 0.1); }
.talk-plate[hidden] { display: none; }
.talk-plate b { font: 700 calc(clamp(18px, 0.5vw + 14px, 25px) * var(--ts, 1)) / 1.15 var(--display); letter-spacing: 0.05em; color: var(--brass); overflow-wrap: anywhere; }
.talk-plate span { font: 500 italic calc(15px * var(--ts, 1)) / 1.25 var(--body); color: #cbbf9f; }
.talk-plate span[hidden] { display: none; }
.talk.no-figure .talk-plate { left: 18px; max-width: calc(100% - 36px); }
.talk-plate.quiet { box-shadow: inset 0 0 0 1px var(--seam); background: #1f1b14; }
.talk-plate.quiet b { font-weight: 600; font-size: calc(16px * var(--ts, 1)); color: #cbbf9f; }

.talk-body { min-width: 0; max-height: min(44vh, calc(13.5rem * var(--ts, 1))); overflow-y: auto; -webkit-overflow-scrolling: touch; touch-action: pan-y; scrollbar-width: none; }
.talk-body::-webkit-scrollbar { display: none; }
.talk.reading .talk-body, .talk.choosing .talk-body { max-height: min(62vh, 30rem); }
.talk-body.more-below { -webkit-mask-image: linear-gradient(#000 calc(100% - 34px), transparent); mask-image: linear-gradient(#000 calc(100% - 34px), transparent); }
.talk-line { margin: 0; max-width: 46rem; min-height: calc(3 * 1.45em); font: 500 calc(clamp(19px, 0.55vw + 13.5px, 24px) * var(--ts, 1)) / 1.45 var(--body); text-wrap: pretty; -webkit-user-select: text; user-select: text; }
.talk-line[hidden], .talk-ask[hidden], .talk-notes[hidden], .talk-choices[hidden], .talk-log[hidden], .talk-foot [hidden] { display: none; }
.talk-line .rest { color: transparent; } /* the rest of the beat keeps its place while it is written out, so no word jumps to a new line */
.talk.narr .talk-line { font-style: italic; color: #d9cfb6; }

.talk-foot { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; min-width: 0; } /* (wraps where large text and a narrow phone leave no room for three buttons in a row) */
.talk .forged { grid-auto-flow: column; gap: 8px; align-items: center; font-size: calc(17px * var(--ts, 1)); }
.talk-tool { min-height: 44px; padding: 6px 14px 6px 10px; font-size: calc(15px * var(--ts, 1)) !important; color: #cfc6ae; }
.talk-count { margin-left: auto; padding: 0 6px; font-size: calc(14px * var(--ts, 1)); color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.talk-next { min-height: 48px; min-width: 9.5rem; padding: 8px 14px 8px 20px; }
.talk-count[hidden] + .talk-next { margin-left: auto; }
.talk-glyph { display: block; width: 20px; height: 20px; flex: none; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: square; stroke-linejoin: miter; }
.talk.writing .talk-next .talk-glyph { opacity: 0.35; } /* it comes up full when the beat is all there (the words on the button never change) */

/* Your turn: what they are saying still stands, the plain facts are set smaller under it, then each thing to do is a plate of its own. */
.talk-line.talk-ask { min-height: 0; margin-bottom: 8px; }
.talk-notes { display: grid; gap: 3px; margin-bottom: 10px; max-width: 46rem; }
.talk-notes p { margin: 0; font-size: calc(15px * var(--ts, 1)); line-height: 1.4; color: var(--muted); }
.talk.narr .talk-notes p { font-size: calc(17px * var(--ts, 1)); color: #d9cfb6; }
.talk-notes small { display: block; margin-top: 2px; font-size: calc(14px * var(--ts, 1)); color: var(--muted); }
.talk-choices { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr)); gap: 8px; }
.talk-choices.column { grid-template-columns: minmax(0, 1fr); }
.talk-choice { display: grid; gap: 4px; align-content: center; min-height: 52px; margin: 0; padding: 10px 18px; text-align: left; border: 0; cursor: pointer; color: var(--text); font: 500 calc(16px * var(--ts, 1)) / 1.35 var(--body);
  background: linear-gradient(#383327, #262219); clip-path: var(--cut); box-shadow: inset 0 0 0 2px #4a4334, inset 0 3px 0 rgba(255, 255, 255, 0.07), inset 0 -4px 0 rgba(0, 0, 0, 0.45); }
.talk-choice b { font: 700 calc(18px * var(--ts, 1)) / 1.25 var(--body); letter-spacing: 0.02em; color: var(--brass); }
.talk-choice span { color: #cfc6ae; }
.talk-choice .why { color: #f1b2a8; }
.talk-choice.primary { color: #1b1408; background: linear-gradient(var(--ember-hi), var(--ember-lo)); box-shadow: inset 0 0 0 2px #6b4212, inset 0 3px 0 rgba(255, 235, 190, 0.35), inset 0 -4px 0 rgba(60, 30, 0, 0.45); }
.talk-choice.primary b, .talk-choice.primary span { color: #1b1408; }
.talk-choice[disabled] { opacity: 0.5; cursor: default; }
/* Focus is a pale line inside the plate (as on the hero screens), so it reads on the ember plate and the iron ones alike. */
.talk-choice:focus-visible { outline: 2px solid #f3ead2; outline-offset: -6px; }
.talk-choice:active { transform: translateY(2px); }

/* History: everything said in this conversation, and before it, oldest first. */
.talk-log { list-style: none; margin: 0; padding: 0 0 4px; display: grid; gap: 12px; max-width: 46rem; }
.talk-log b { font: 700 calc(14px * var(--ts, 1)) / 1.2 var(--display); letter-spacing: 0.06em; color: var(--brass); }
.talk-log p { margin: 2px 0 0; font-size: calc(17px * var(--ts, 1)); line-height: 1.4; -webkit-user-select: text; user-select: text; }
.talk-log .narr p { font-style: italic; color: #d9cfb6; }
.talk-log .sep { padding-bottom: 4px; border-bottom: 1px solid var(--seam); font: 700 calc(13px * var(--ts, 1)) var(--body); color: var(--muted); }
.talk-sr { position: absolute; width: 1px; height: 1px; margin: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

.talk.up .talk-box { animation: talkUp 0.22s ease-out both; }
.talk.up .talk-portrait { animation: talkUp 0.32s ease-out both; }
@keyframes talkUp { from { opacity: 0; transform: translateY(14px); } }
@media (prefers-reduced-motion: reduce) { .talk.up .talk-box, .talk.up .talk-portrait { animation: none; } .talk::before { transition: none; } .talk-choice:active { transform: none; } }

@media (max-width: 700px) and (orientation: portrait) {
  /* A phone held upright: the box across the foot, the portrait standing on its top edge at about a third of the screen, the plate beside the portrait. */
  .talk { --ph: 33svh; --pw: calc(var(--ph) * 0.7); --lap: 0px; }
  .talk-stage { left: calc(8px + var(--safe-l)); right: calc(8px + var(--safe-r)); bottom: calc(8px + var(--safe-b)); width: auto; }
  .talk-portrait { bottom: calc(100% - 12px); }
  .talk-box { margin-left: 0; }
  .talk-panel, .talk.no-figure .talk-panel { padding: 24px 14px 12px; }
  .talk-plate { left: calc(var(--pw) + 2px); max-width: calc(100% - var(--pw) - 6px); bottom: calc(100% - 10px); padding: 6px 14px 7px 12px; }
  .talk.no-figure .talk-plate { left: 12px; max-width: calc(100% - 24px); }
  .talk-plate b { font-size: calc(17px * var(--ts, 1)); }
  .talk-plate span { font-size: calc(14px * var(--ts, 1)); }
  .talk-line { font-size: calc(19px * var(--ts, 1)); line-height: 1.42; min-height: calc(4 * 1.42em); }
  .talk-body { max-height: 34svh; }
  .talk.reading .talk-body, .talk.choosing .talk-body { max-height: calc(60svh - 80px); }
  .talk-choices { grid-template-columns: minmax(0, 1fr); }
  .talk-choice { min-height: 48px; padding: 8px 14px; }
  .talk-tool { padding: 6px 10px 6px 6px; }
  .talk-next { min-width: 8rem; }
}
@media (max-width: 420px) and (orientation: portrait) { .talk-count { display: none; } .talk-next { margin-left: auto; } }
@media (orientation: landscape) and (max-height: 520px) {
  /* A phone on its side: the portrait down the left edge, the box to its right, nothing under the figure. */
  .talk { --ph: calc(100svh - 12px - var(--safe-t) - var(--safe-b)); --pw: calc(var(--ph) * 0.6); --lap: 0px; }
  .talk-stage { left: calc(6px + var(--safe-l)); right: calc(8px + var(--safe-r)); bottom: calc(6px + var(--safe-b)); width: auto; }
  .talk-box { margin-left: var(--pw); }
  .talk-panel, .talk.no-figure .talk-panel { padding: 24px 16px 10px 18px; gap: 8px; }
  .talk-plate, .talk.no-figure .talk-plate { left: 12px; max-width: calc(100% - 24px); bottom: calc(100% - 16px); padding: 5px 16px 6px 12px; }
  .talk-plate b { font-size: calc(18px * var(--ts, 1)); }
  .talk-plate span { font-size: calc(14px * var(--ts, 1)); }
  .talk-line { font-size: calc(19px * var(--ts, 1)); line-height: 1.4; min-height: calc(3 * 1.4em); }
  .talk-body, .talk.reading .talk-body, .talk.choosing .talk-body { max-height: calc(100svh - 136px - var(--safe-t) - var(--safe-b)); }
  .talk-choice { min-height: 46px; padding: 6px 14px; }
  .talk-notes { margin-bottom: 6px; } .talk-notes p { font-size: calc(15px * var(--ts, 1)); }
  .talk-next { min-height: 44px; }
}

/* A passing remark over the hall (talk.js bark): a face in a seal mould, the name and the line. It holds nothing and goes by itself. */
.bark { display: grid; grid-template-columns: 54px minmax(0, 1fr) 44px; gap: 10px; align-items: center; width: 100%; box-sizing: border-box; padding: 6px 2px 6px 8px; pointer-events: none; /* only its Dismiss takes a touch: a thumb starting the move stick under it goes through */
  background: rgba(22, 19, 14, 0.94); clip-path: var(--cut); box-shadow: inset 0 0 0 1px var(--seam), inset 3px 0 0 var(--ember); font: 500 calc(16px * var(--ts, 1)) / 1.35 var(--body); color: var(--text); }
.bark[hidden] { display: none; }
.bark-face { position: relative; display: grid; place-items: center; width: 54px; height: 60px; overflow: hidden; background: linear-gradient(#3a3226, #1b1711); clip-path: polygon(50% 0, 100% 24%, 100% 76%, 50% 100%, 0 76%, 0 24%); }
.bark-face .portrait3d { position: absolute; inset: 0; display: block; width: 100%; height: 100%; }
.bark-face b { font: 700 26px/1 var(--display); color: var(--tint, var(--brass)); }
.bark-words { display: grid; gap: 1px; min-width: 0; }
.bark-words b { font: 700 calc(14px * var(--ts, 1)) / 1.2 var(--display); letter-spacing: 0.06em; color: var(--brass); }
.bark-close { display: grid; place-items: center; width: 44px; height: 44px; padding: 0; pointer-events: auto; background: none; border: 0; color: var(--muted); cursor: pointer; }
.bark-close:focus-visible { outline: 2px solid var(--brass); outline-offset: -6px; }
.bark .talk-glyph { width: 18px; height: 18px; }

/* ---------------- Lastheat: the camp screens in the same hand ---------------- */
.camp { font-family: var(--body); font-size: calc(17px * var(--ts, 1)); }
.camp h1, .camp h2 { font-family: var(--display); font-weight: 600; letter-spacing: 0.03em; }
.camp h1 { color: var(--brass); }
.camp .primary { font-family: var(--display); letter-spacing: 0.08em; text-transform: uppercase; background: linear-gradient(var(--ember-hi), var(--ember-lo)); border-color: #6b4212; color: #1b1408; border-radius: 4px; min-height: 54px; }
.camp .seal { font-family: var(--display); }
.camp .section-head { margin: 6px 0 10px; font-size: calc(18px * var(--ts, 1)); color: var(--muted); }
.camp .quest { width: 100%; text-align: left; display: grid; gap: 4px; border-color: #6b5a34; background: linear-gradient(#2c2619, #201c14); }
.camp .people { display: grid; gap: 8px; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); }
.camp .person { display: grid; grid-template-columns: 44px 1fr auto; gap: 12px; align-items: center; text-align: left; padding: 10px 12px; }
.camp .person .seal { width: 44px; height: 52px; font-size: 22px; }
.camp .new { display: inline-block; margin-left: 6px; padding: 1px 8px; font-size: calc(12px * var(--ts, 1)); font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: #10160f; background: var(--verdigris); border-radius: 3px; }
.camp .news { display: grid; gap: 8px; padding: 12px 14px; border-left: 3px solid var(--ember); background: #231e15; }
.camp .news p { font-size: calc(16px * var(--ts, 1)); }
.camp .said { display: grid; gap: 10px; }
.camp .said p { padding: 10px 14px; border-left: 3px solid var(--seam); background: #1c1913; font-size: calc(18px * var(--ts, 1)); line-height: 1.4; color: #cfc6ae; }
.camp .said p.fresh { border-left-color: var(--ember); color: var(--text); }
.camp .quest-steps { margin: 0; padding: 0; list-style: none; display: grid; gap: 8px; counter-reset: q; }
.camp .quest-steps li { position: relative; padding: 10px 14px 10px 46px; border: 1px solid var(--line); background: var(--panel); counter-increment: q; }
.camp .quest-steps li::before { content: counter(q); position: absolute; left: 14px; top: 10px; font-family: var(--display); color: var(--muted); }
.camp .quest-steps .state { float: right; font-size: calc(12px * var(--ts, 1)); font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); }
.camp .quest-steps .open { border-color: var(--brass); }
.camp .quest-steps .open .state { color: var(--brass); }
.camp .quest-steps .done { opacity: 0.8; }
.camp .quest-steps .later { opacity: 0.45; }
.camp .tally { margin: 8px 0 0; display: grid; gap: 4px; }
.camp .tally div { display: flex; justify-content: space-between; gap: 10px; border-bottom: 1px solid rgba(255, 255, 255, 0.06); padding: 3px 0; }
.camp .tally dt { color: var(--muted); } .camp .tally dd { margin: 0; font-variant-numeric: tabular-nums; }

/* The run's last panel: what the descent changed at Lastheat. */
.story-end { display: grid; gap: 8px; margin: 8px 0 12px; }
.story-end:empty { display: none; }
.story-end p { margin: 0; padding: 10px 12px; border-left: 3px solid var(--ember); background: #231e15; font: 17px/1.4 var(--body); text-align: left; }
.story-end .quest-done { border-left-color: var(--brass); }

/* ---------------- Lastheat as a room (hall.js): no bars, no combat buttons; the quest, a prompt and the Menu button ---------------- */
body.in-hall .bars, body.in-hall #timer, body.in-hall #attackBtn, body.in-hall #dodgeBtn, body.in-hall .orb, body.in-hall #routeMap, body.in-hall #actionBar { display: none; }
body.in-hall #hudStack { top: calc(10px + var(--safe-t)); }
body.in-hall #objective { font: 500 15px/1.3 var(--body); max-width: min(62vw, 460px); padding: 8px 12px; background: rgba(22, 19, 14, 0.9); border-left: 3px solid var(--ember); color: var(--text); }
body.in-hall .act.interact {
  left: 50%; right: auto; transform: translateX(-50%); bottom: calc(92px + var(--safe-b)); width: auto; height: auto; min-height: 52px; min-width: 200px; max-width: min(440px, calc(100vw - 32px));
  padding: 10px 22px; border-radius: 0; border: 0; clip-path: var(--cut); font: 700 17px var(--body); color: #1b1408;
  background: linear-gradient(var(--ember-hi), var(--ember-lo)); box-shadow: inset 0 0 0 2px #6b4212, inset 0 3px 0 rgba(255, 235, 190, 0.35), inset 0 -4px 0 rgba(60, 30, 0, 0.45);
}
body.in-hall #menuBtn { min-height: 48px; min-width: 48px; }
body.in-hall .label3d .mini { display: none; }
body.in-hall .label3d { font: 700 14px var(--body); color: var(--brass); text-shadow: 0 1px 2px #000, 0 0 6px #000; }
#cardBody .eyebrow { font: 700 13px var(--body); letter-spacing: 0.16em; text-transform: uppercase; color: var(--ember-hi); margin: 0; }
#cardBody .said { display: grid; gap: 8px; }
#cardBody .said p { margin: 0; padding: 10px 14px; border-left: 3px solid var(--ember); background: #1c1913; font: 18px/1.4 var(--body); text-align: left; }
#cardBody .story-end p b { color: var(--brass); }

/* Combat style on a weapon's card: which style it fights in, marked when equipping it would change yours. */
.style-line { margin: 6px 0; font-size: calc(14px * var(--ts, 1)); color: var(--muted); }
.style-line b { color: var(--brass); }
.style-line.own-rule { margin-top: -2px; }
.style-line.change { padding: 6px 10px; border-left: 3px solid var(--ember); background: #231e15; color: var(--text); }

/* Skills in the journal: the level as a number, the bar as a picture of the same thing, never the bar alone. */
.camp .skills { list-style: none; margin: 10px 0 0; padding: 0; display: grid; gap: 10px; }
.camp .skills li { display: grid; grid-template-columns: 1fr auto; gap: 2px 12px; align-items: end; }
.camp .sk-name b { display: block; font-family: var(--display); letter-spacing: 0.05em; }
.camp .sk-name small { display: block; }
.camp .sk-level { font: 700 26px var(--display); color: var(--brass); font-variant-numeric: tabular-nums; }
.camp .sk-level small { font-size: calc(13px * var(--ts, 1)); color: var(--muted); }
.camp .sk-bar { grid-column: 1 / -1; height: 8px; background: #14110d; box-shadow: inset 0 0 0 1px var(--seam); }
.camp .sk-bar i { display: block; height: 100%; background: linear-gradient(var(--ember-hi), var(--ember-lo)); }
.camp .sk-xp { grid-column: 1 / -1; font-variant-numeric: tabular-nums; }
.camp .sk-head { margin: 16px 0 6px; font-family: var(--display); }
.camp .prov { list-style: none; margin: 0 0 8px; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; }
.camp .prov li { padding: 4px 10px; border: 1px solid var(--line); background: #1c1913; font-size: calc(15px * var(--ts, 1)); }
.camp .prov b { color: var(--brass); margin-left: 4px; }
.story-end .xp { border-left-color: var(--verdigris); font-size: calc(15px * var(--ts, 1)); font-variant-numeric: tabular-nums; }

.gate-line { margin: 6px 0; font-weight: 700; }

/* Camp and front pages scroll by touch, wheel and keys; the bar itself is hidden (owner: the pale bar on the dark page is bad). */
#campMain, .front .page { scrollbar-width: none; -ms-overflow-style: none; }
#campMain::-webkit-scrollbar, .front .page::-webkit-scrollbar { display: none; }

/* The fan-project notice before the title. */
.front.notice .page { align-content: center; max-width: 100%; }
.front .notice-text { display: grid; gap: 12px; }
.front .notice-text p { font-size: calc(18px * var(--ts, 1)); line-height: 1.45; }
.front .notice-text p:first-child { padding: 12px 14px; border-left: 3px solid var(--ember); background: #1c1913; color: var(--text); }
.front .notice-text p:not(:first-child) { color: #cfc6ae; }

/* Cloud save: the recovery code is read off a screen and typed on another, so it is large, spaced and selectable. */
.camp .code { margin: 8px 0; padding: 12px; font: 700 clamp(15px, 4.4vw, 22px)/1.5 ui-monospace, "Cascadia Mono", Consolas, monospace; letter-spacing: 0.06em; text-align: center; word-break: break-all;
  color: var(--brass); background: #14110d; box-shadow: inset 0 0 0 1px var(--seam); -webkit-user-select: all; user-select: all; }
.camp .code-entry { margin-top: 10px; }
.camp .code-entry input { width: 100%; font: 600 17px ui-monospace, Consolas, monospace; text-transform: uppercase; -webkit-user-select: text; user-select: text; }
.camp .good { color: #a9dbb2; }
.camp details > summary { cursor: pointer; min-height: 44px; display: flex; align-items: center; color: var(--brass); }
.two-saves { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)) !important; }
.two-saves .card { padding: 12px; text-align: left; }
.two-saves ul { margin: 6px 0 0; padding-left: 18px; }
.two-saves li { margin: 6px 0; }

/* The hall is dark until its models and room have arrived, so nothing pops in. */
#hallLoading { position: fixed; inset: 0; z-index: 12; display: grid; place-content: center; justify-items: center; gap: 6px; background: #0f0d0a; color: var(--muted); font: 16px var(--body); }
#hallLoading[hidden] { display: none; }
#hallLoading p { margin: 0; font: 700 28px var(--display); letter-spacing: 0.1em; text-transform: uppercase; color: var(--brass); }

/* What the hero carries to eat, on the inventory. */
.inv-food { margin: 0; padding: 6px 10px; font: 15px/1.3 var(--body); border-left: 3px solid var(--verdigris); background: #1c1913; }
.inv-food b { color: var(--brass); margin-right: 4px; }

/* Cinematics: bars close in, one line at a time, a quiet note on how to skip. A guardian's name is set large. */
#cine { position: fixed; inset: 0; z-index: 11; pointer-events: none; }
#cine[hidden] { display: none; }
#cine .bar { position: absolute; left: 0; right: 0; height: max(9vh, calc(34px + var(--safe-t))); background: #0b0a08; animation: cineBar 0.35s ease-out both; }
#cine .bar.top { top: 0; transform-origin: 50% 0; }
#cine .bar.bottom { bottom: 0; height: max(9vh, calc(34px + var(--safe-b))); transform-origin: 50% 100%; }
@keyframes cineBar { from { transform: scaleY(0); } to { transform: scaleY(1); } }
.cine-line { position: absolute; left: 50%; bottom: calc(max(9vh, 34px) + 18px + var(--safe-b)); transform: translateX(-50%); width: min(640px, calc(100vw - 32px)); text-align: center; }
.cine-line p { margin: 0; font: 500 clamp(18px, 4.6vw, 24px)/1.35 var(--body); color: var(--text); text-shadow: 0 1px 2px #000, 0 0 12px #000; }
#cineWho { display: block; font: 700 13px var(--display); letter-spacing: 0.14em; text-transform: uppercase; color: var(--ember-hi); text-shadow: 0 1px 2px #000; }
#cineWho:empty { display: none; }
#cine.title .cine-line { bottom: auto; top: 22%; }
#cine.title .cine-line p { font: 700 clamp(26px, 8vw, 46px)/1.1 var(--display); letter-spacing: 0.1em; text-transform: uppercase; color: var(--brass); }
.cine-skip { position: absolute; right: calc(14px + var(--safe-r)); bottom: calc(8px + var(--safe-b)); font: 12px var(--body); color: #7d7563; }
@media (prefers-reduced-motion: reduce) { #cine .bar { animation: none; } }

/* The title over the live hall (hall.js backdrop): the drawn backdrop steps aside, the game's own controls stay hidden,
   and the top and bottom are darkened so the name and the menu read against the room. */
body.title-live .front.title { background: linear-gradient(rgba(11, 10, 8, 0.86) 0, rgba(11, 10, 8, 0.25) 34%, rgba(11, 10, 8, 0.2) 52%, rgba(11, 10, 8, 0.9) 100%); }
body.title-live .front.title .hall { display: none; }
body.title-live #hud, body.title-live #touch, body.title-live #actionBar, body.title-live .orb, body.title-live #interactBtn { display: none !important; }

/* The dark at the edge of the light: over the view, under everything else, and gone in the plain lab. */
#vignette { position: fixed; inset: 0; z-index: 1; pointer-events: none; background: radial-gradient(ellipse 78% 72% at 50% 50%, transparent 52%, rgba(6, 5, 4, 0.5) 100%); }
body[data-mood="lab"] #vignette, body:not([data-mood]) #vignette { display: none; }

/* lab.css has a .bar of its own (the health bars): the scene's bars take nothing from it. */
#cine .bar { display: block; margin: 0; }

/* The contract board: three rows, each with what it asks, what it pays and a button; the one in hand is marked in words and by its edge. */
#cardBody .contract-list { display: grid; gap: 8px; text-align: left; }
#cardBody .contract-row { display: grid; grid-template-columns: 1fr auto; gap: 10px; align-items: center; padding: 10px 12px; background: #1b1812; box-shadow: inset 0 0 0 1px var(--seam); font: 16px/1.3 var(--body); }
#cardBody .contract-row.on { box-shadow: inset 0 0 0 2px var(--brass); background: #262117; }
#cardBody .contract-row b { color: var(--brass); }
#cardBody .contract-row small { display: block; margin-top: 2px; color: var(--muted); }
#cardBody .contract-row .contract-state { display: inline; margin-left: 6px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--verdigris); }
#cardBody .contract-row .contract-caveat { color: #f1b2a8; }
#cardBody .contract-row button { min-height: 44px; min-width: 84px; }
.story-end .contract-line { border-left-color: var(--verdigris); font-variant-numeric: tabular-nums; }

/* The anvil's choice: each way to settle the last ward is a button with its sentence under it. */
#cardBody .ending-choice { display: grid; gap: 6px; }
#cardBody .ending-choice .big { width: 100%; min-width: 0; }

/* The journal's three acts: the one in hand in full, the ones ahead dimmed. */
.camp .journal-act { display: grid; gap: 8px; }
.camp .journal-act.later h2 { color: var(--muted); }

/* Settings rows: what it is on the left, what it is set to on the right, in words. */
.camp .option-row { width: 100%; display: grid; grid-template-columns: 1fr auto; gap: 12px; align-items: center; text-align: left; padding: 12px 14px; }
.camp .option-state { min-width: 92px; padding: 6px 10px; text-align: center; font-weight: 700; border: 1px solid var(--line); color: var(--muted); }
.camp .option-state.on { border-color: var(--brass); color: var(--brass); }

#cardBody .bond-line { margin: 10px 0 4px; }
#cardBody .bond-line small { color: var(--muted); }

/* The journal's bestiary. */
.camp .foes { list-style: none; margin: 0 0 6px; padding: 0; display: grid; gap: 8px; }
.camp .foes li { padding: 8px 12px; border-left: 3px solid var(--seam); background: #1c1913; font-size: calc(16px * var(--ts, 1)); line-height: 1.4; }
.camp .foes b { font-family: var(--display); letter-spacing: 0.04em; color: var(--brass); }

/* Oaths at Hesk: each vow a row with what it asks and its weight; the sworn ones marked in words and by their edge. */
#cardBody .oath-list { display: grid; gap: 8px; text-align: left; }
#cardBody .oath-row { display: grid; grid-template-columns: 1fr auto; gap: 10px; align-items: center; padding: 10px 12px; background: #1b1812; box-shadow: inset 0 0 0 1px var(--seam); }
#cardBody .oath-row.on { box-shadow: inset 0 0 0 2px var(--brass); background: #262117; }
#cardBody .oath-row b { color: var(--brass); }
#cardBody .oath-row small { display: block; margin-top: 2px; color: var(--muted); }
#cardBody .oath-row small.warn { color: #f1b2a8; font-weight: 700; } /* a warning beside an oath: said in words, and marked */
#cardBody .oath-row .oath-state { margin-left: 6px; font-size: calc(12px * var(--ts, 1)); font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text); }
#cardBody .oath-row button { min-height: 44px; min-width: 96px; }
/* The works at Odra: the same rows. Why a rank cannot be built is written under it; a Build that is off also looks off. */
#cardBody .work-row .work-why { color: var(--text); }
/* Tempering at the forge (hall.js): the piece as it is beside the piece as it will be; one column on a phone. */
#cardBody .temper-pair { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 10px; text-align: left; margin: 8px 0; }
#cardBody .temper-pair h3 { margin: 0 0 4px; font-size: calc(14px * var(--ts, 1)); letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); }
#cardBody .temper-gain { margin: 6px 0 0; color: var(--text); font-weight: 700; }
#cardBody .temper-why { margin: 8px 0; padding: 8px 12px; border-left: 3px solid var(--brass); background: #231e15; text-align: left; }
#cardBody #hTemper { min-height: 48px; }
#cardBody .work-row button:disabled { opacity: 0.5; cursor: default; }

/* ---------------- the menu (camp.js): one pause menu, tabs along the top ----------------
   Three bands: the tab bar, the tab's panel, and a strip of hints along the foot. The panel is a list down the left
   (the tab's sections, or the bag on Gear) and the chosen thing beside it. Three shapes: a desk, a phone held upright
   (the bar scrolls sideways, the sections are a row under it, and the chosen one fills the rest) and a phone on its
   side (two columns, slimmer). Key caps are shown to a keyboard, the controller's buttons while one is in use, and
   neither to a finger. */
.hub.camp { --pad: clamp(14px, 2vw, 36px); background: #0f0d0a; touch-action: manipulation; }
.hub.camp > #campMain { flex: 1; min-height: 0; max-width: none; width: 100%; margin: 0; padding: 0; overflow: hidden; }
.menu-bar { display: flex; align-items: stretch; gap: 4px; min-height: 58px; padding: var(--safe-t) calc(var(--pad) + var(--safe-r) - 8px) 0 calc(var(--pad) + var(--safe-l) - 8px); background: linear-gradient(#1a1711, #13110d); box-shadow: inset 0 -1px 0 var(--seam); }
.menu-bar .tabs { display: flex; min-width: 0; overflow-x: auto; scrollbar-width: none; }
.menu-bar .tabs::-webkit-scrollbar { display: none; }
.hub.camp .tab { position: relative; flex: none; min-height: 58px; min-width: 44px; padding: 0 clamp(12px, 1.5vw, 26px) 8px; border: 0; border-radius: 0; background: none; cursor: pointer; white-space: nowrap;
  font: 600 calc(clamp(15px, 0.6vw + 10px, 21px) * var(--ts, 1)) / 1.1 var(--display); letter-spacing: 0.1em; color: #a59c86; }
/* The tab in view: brass and heavier, on an ember bar with a diamond set in it (never the colour alone). */
.hub.camp .tab[aria-selected=true] { color: var(--brass); font-weight: 700; }
.hub.camp .tab .tab-mark { position: absolute; left: 8px; right: 8px; bottom: 5px; height: 3px; background: var(--ember); visibility: hidden; } /* (inside the tab: the bar scrolls sideways, which clips anything hung below it) */
.hub.camp .tab .tab-mark::after { content: ""; position: absolute; left: 50%; bottom: -3px; width: 9px; height: 9px; margin-left: -5px; transform: rotate(45deg); background: var(--ember-hi); box-shadow: 0 0 0 2px #13110d; }
/* A row that scrolls sideways fades at an end that has more beyond it (camp.js marks the ends). */
.hub.camp .more-right { -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 36px), transparent); mask-image: linear-gradient(90deg, #000 calc(100% - 36px), transparent); }
.hub.camp .more-left { -webkit-mask-image: linear-gradient(270deg, #000 calc(100% - 36px), transparent); mask-image: linear-gradient(270deg, #000 calc(100% - 36px), transparent); }
.hub.camp .more-left.more-right { -webkit-mask-image: linear-gradient(90deg, transparent, #000 36px, #000 calc(100% - 36px), transparent); mask-image: linear-gradient(90deg, transparent, #000 36px, #000 calc(100% - 36px), transparent); }
.hub.camp .tab[aria-selected=true] .tab-mark { visibility: visible; }
.hub.camp .tab[aria-disabled=true] { color: #7d7563; cursor: default; }
.hub.camp .tab[aria-disabled=true] .tab-word { text-decoration: line-through; text-decoration-thickness: 1px; }
.hub.camp .tab:focus-visible, .hub.camp .menu-close:focus-visible, .hub.camp .side-item:focus-visible { outline: 2px solid #f3ead2; outline-offset: -6px; }
.bar-hint { display: flex; align-items: center; padding: 0 4px; }
.bar-state { margin-left: auto; display: flex; align-items: center; gap: 6px; min-width: 0; }
.hub.camp .bar-state .badge { margin: 0; border-radius: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hub.camp .menu-close { flex: none; align-self: center; display: grid; place-items: center; width: 44px; height: 44px; min-height: 44px; padding: 0; margin-left: 6px; border: 0; border-radius: 0; cursor: pointer; color: var(--text);
  background: linear-gradient(#383327, #262219); clip-path: var(--cut); box-shadow: inset 0 0 0 2px #4a4334; }
.m-glyph { display: block; width: 22px; height: 22px; flex: none; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: square; stroke-linejoin: miter; }

/* Key caps and controller buttons: one or the other, by what is in use (gamepad.js sets body.pad-on). */
.hub.camp kbd, #menuBtn kbd { display: inline-grid; place-items: center; min-width: 24px; height: 24px; padding: 0 6px; font: 700 calc(12px * var(--ts, 1)) / 1 var(--body); letter-spacing: 0.02em; color: var(--brass); background: #1c1913; box-shadow: inset 0 0 0 1px #6a6150; }
.hub.camp .caps { display: inline-flex; gap: 3px; } .hub.camp .pads { display: none; gap: 2px; }
body.pad-on .hub.camp .caps { display: none; } body.pad-on .hub.camp .pads { display: inline-flex; }
.hub.camp .pads .padicon { width: 24px; height: 24px; }
#campFooter { padding: 7px calc(var(--pad) + var(--safe-r)) calc(7px + var(--safe-b)) calc(var(--pad) + var(--safe-l)); border-top: 0; background: #0b0a08; box-shadow: inset 0 1px 0 var(--seam); }
.hint-strip { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 6px clamp(14px, 2vw, 30px); }
.hint { display: inline-flex; align-items: center; gap: 8px; font: 500 calc(14px * var(--ts, 1)) / 1.2 var(--body); color: #cfc6ae; white-space: nowrap; }
@media (pointer: coarse) { body:not(.pad-on) #campFooter, body:not(.pad-on) .bar-hint { display: none; } body:not(.pad-on) .hub.camp > #campMain { padding-bottom: var(--safe-b); } }

.menu-toast { position: absolute; left: 50%; bottom: calc(54px + var(--safe-b)); transform: translateX(-50%); z-index: 3; max-width: min(34rem, calc(100% - 32px)); padding: 9px 16px; pointer-events: none; text-align: center;
  font: 600 calc(16px * var(--ts, 1)) / 1.3 var(--body); color: var(--text); background: #2a251b; clip-path: var(--cut); box-shadow: inset 0 0 0 2px #6b5a34; }
.menu-toast[hidden] { display: none; }

/* The panel: the sections down the side, the chosen one beside them. */
.menu-body { height: 100%; display: grid; grid-template-columns: clamp(13rem, 20vw, 19rem) minmax(0, 1fr); }
.menu-body.full { grid-template-columns: minmax(0, 1fr); }
.menu-side { min-height: 0; overflow-y: auto; scrollbar-width: none; display: flex; flex-direction: column; gap: 4px; padding: clamp(12px, 2.4vh, 24px) 12px 18px calc(var(--pad) + var(--safe-l) - 8px); box-shadow: inset -1px 0 0 var(--seam); }
.menu-side::-webkit-scrollbar, .menu-detail::-webkit-scrollbar, .menu-gear::-webkit-scrollbar, .hub.camp .inv-body > section::-webkit-scrollbar { display: none; }
.hub.camp .side-item { flex: none; display: grid; grid-template-columns: 20px minmax(0, 1fr); gap: 10px; align-items: center; width: 100%; min-height: 48px; padding: 8px 12px 8px 10px; border: 0; border-radius: 0; background: none; cursor: pointer; text-align: left;
  font: 500 calc(17px * var(--ts, 1)) / 1.25 var(--body); color: #cfc6ae; }
.hub.camp .side-item small { display: block; font-size: calc(14px * var(--ts, 1)); color: var(--muted); }
.side-mark { width: 12px; height: 12px; margin: 0 4px; transform: rotate(45deg); box-shadow: inset 0 0 0 2px #6a6150; }
.hub.camp .side-item[aria-current=true] { color: var(--brass); font-weight: 700; background: linear-gradient(#2c271d, #211d16); clip-path: var(--cut); box-shadow: inset 3px 0 0 var(--ember); }
.hub.camp .side-item[aria-current=true] .side-mark { background: var(--ember-hi); box-shadow: inset 0 0 0 2px var(--brass); }
.menu-detail { min-height: 0; overflow-y: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none; padding: clamp(14px, 3vh, 30px) calc(var(--pad) + var(--safe-r)) 28px clamp(16px, 2.4vw, 44px); }
.menu-body.full > .menu-detail { padding-left: calc(var(--pad) + var(--safe-l)); }
.menu-detail > .stack, .menu-detail > .notice { max-width: 56rem; }
/* Rows that stand on their own (settings, the bestiary, skills) run in two columns where the screen is wide enough for both. */
.menu-detail > .stack:has(> .options, > .card > .foes, > .card > .skills) { max-width: 92rem; }
.hub.camp .options, .hub.camp .foes, .hub.camp .skills { grid-template-columns: repeat(auto-fit, minmax(min(100%, 27rem), 1fr)); }
.hub.camp .skills { column-gap: 32px; }
.hub.camp .menu-detail p { max-width: 74ch; }
.hub.camp h1 { font-size: calc(clamp(24px, 1.4vw + 12px, 36px) * var(--ts, 1)); line-height: 1.15; }
.hub.camp h1:focus, .hub.camp h2:focus { outline: none; }
.hub.camp .hero-origin { margin-top: 2px; font-style: italic; color: #cbbf9f; }
.hub.camp .menu-detail .back { display: inline-flex; align-items: center; gap: 6px; min-height: 44px; margin: -6px 0 10px -10px; padding: 6px 14px 6px 6px; border: 0; background: none; color: var(--brass); font-weight: 700; }
.menu-action { position: sticky; bottom: -28px; z-index: 2; margin-top: 14px; padding: 12px 0 18px; background: linear-gradient(rgba(15, 13, 10, 0), #0f0d0a 34%); }
.menu-action .primary { width: min(100%, 24rem); }

/* What is in the panel wears the forge's hand: square plates with a seam, the rows cut at the corners. */
.hub.camp .card { border: 0; border-radius: 0; background: #1b1812; box-shadow: inset 0 0 0 1px var(--seam); }
.hub.camp .card.blocker { box-shadow: inset 0 0 0 2px #a07a3a; }
.hub.camp .menu-detail button { border-radius: 0; }
.hub.camp .menu-detail button:not(.card):not(.quiet):not(.link):not(.primary):not(.back):not(.choice) { border: 0; background: linear-gradient(#383327, #262219); clip-path: var(--cut); box-shadow: inset 0 0 0 2px #4a4334; }
.hub.camp .menu-detail .primary { border: 0; border-radius: 0; clip-path: var(--cut); box-shadow: inset 0 0 0 2px #6b4212, inset 0 3px 0 rgba(255, 235, 190, 0.35), inset 0 -4px 0 rgba(60, 30, 0, 0.45); }
.hub.camp .menu-detail button.card { clip-path: var(--cut); cursor: pointer; }
.hub.camp .menu-detail button.card b { font-family: var(--display); font-weight: 600; letter-spacing: 0.04em; color: var(--brass); }
.hub.camp .menu-detail button.option-row b, .hub.camp .menu-detail button.person b { font-family: var(--body); font-weight: 700; letter-spacing: 0; color: var(--text); }
.hub.camp .menu-detail button:focus-visible, .hub.camp .menu-detail summary:focus-visible, .hub.camp .inv button:focus-visible { outline: 2px solid #f3ead2; outline-offset: -5px; }
body.pad-on .hub.camp button:focus, body.pad-on .hub.camp summary:focus { outline: 3px solid #91d1bd; outline-offset: -5px; }
.hub.camp details { border: 0; border-radius: 0; box-shadow: inset 0 0 0 1px var(--seam); }
.hub.camp .option-state { border-radius: 0; }
.hub.camp .option-state.on { box-shadow: inset 0 -3px 0 var(--ember); }
.hub.camp .seal { border-radius: 0; clip-path: polygon(50% 0, 100% 24%, 100% 76%, 50% 100%, 0 76%, 0 24%); border: 0; background: linear-gradient(#3a3226, #1b1711); }
.hub.camp .keys { display: block; overflow-x: auto; }
.hub.camp .said p { -webkit-user-select: text; user-select: text; }

/* Hero, Overview: the words on the left, the hero standing on the right where there is room for them. */
.overview { display: grid; grid-template-columns: minmax(0, 36rem) minmax(12rem, 1fr); gap: 0 clamp(16px, 3vw, 48px); align-items: start; }
.overview .hero-stand { position: sticky; top: 0; height: min(64vh, 620px); min-height: 240px; background: radial-gradient(ellipse 60% 16% at 50% 92%, rgba(0, 0, 0, 0.55), transparent 70%); }
.overview .hero-stand[hidden] { display: none; }
.overview .hero-stand .hero3d { position: absolute; inset: 0; display: block; width: 100%; height: 100%; }
.hub.camp .hero-facts { margin: 0; max-width: 30rem; }
.hub.camp .hero-facts dd { color: var(--brass); font-weight: 700; text-align: right; }
@media (max-width: 899px), (max-height: 520px) { .overview { grid-template-columns: minmax(0, 1fr); } .overview .hero-stand { display: none; } }

/* ---------------- Gear: the bag on the left, the chosen item beside it, the hero standing on the right ----------------
   campaign.js renderInventory draws it (the same markup as ever); here it is laid out for the menu. The filters are
   icon and word on a cut chip; a fifth (Buy back) has its mark ready. */
.menu-gear > .notice { flex: none; margin: 0 0 8px; }
.gear-box { flex: 1 1 auto; min-height: 0; }
.menu-gear { display: flex; flex-direction: column; height: 100%; min-height: 0; padding: clamp(10px, 2vh, 20px) calc(var(--pad) + var(--safe-r)) 12px calc(var(--pad) + var(--safe-l)); }
.hub.camp .inv, .hub.camp .inv.in-camp { height: 100%; gap: 8px; --tile: clamp(54px, 3.2vw + 16px, 80px); }
.hub.camp .inv-head h2 { font: 600 calc(clamp(22px, 1.2vw + 11px, 32px) * var(--ts, 1)) / 1.15 var(--display); letter-spacing: 0.03em; color: var(--brass); }
.hub.camp .inv-head .muted, .hub.camp .inv-head .gold { font-size: calc(16px * var(--ts, 1)); }
.hub.camp .inv-head .gold { color: var(--brass); font-weight: 700; margin-left: auto; }
.hub.camp .inv-head #gBack { display: none; } /* the menu closes from its corner */
.hub.camp .inv-status { padding: 6px 10px; border-left: 3px solid var(--seam); background: #1c1913; font-size: calc(15px * var(--ts, 1)); }
.hub.camp .inv-status.good { border-left-color: var(--verdigris); } .hub.camp .inv-status.warn { border-left-color: var(--blood); }
.hub.camp .inv-body { grid-template-columns: minmax(0, 1fr) clamp(17rem, 27vw, 26rem) clamp(15rem, 25vw, 26rem); grid-template-rows: minmax(0, 1fr) auto; grid-template-areas: "bag detail char" "bag stats stats"; gap: 10px clamp(10px, 1.6vw, 28px); }
.hub.camp .inv-body > section { border: 0; border-radius: 0; background: none; padding: 0; scrollbar-width: none; }
.hub.camp .inv-body > .inv-bag { grid-area: bag; padding: 3px; }
.hub.camp .inv-body > .inv-detail { grid-area: detail; padding: 14px 16px; background: #1b1812; box-shadow: inset 0 0 0 1px var(--seam); font-size: calc(15px * var(--ts, 1)); align-self: start; max-height: 100%; }
.hub.camp .inv-detail .detail-head b { font: 600 calc(19px * var(--ts, 1)) / 1.2 var(--display); letter-spacing: 0.03em; color: var(--brass); }
/* The hero's own section gives up its box: the figure with what is worn takes the right-hand column to its full height, and the numbers run along the foot. */
.hub.camp .inv-body > .inv-char { display: contents; }
.hub.camp .doll { grid-area: char; min-height: 0; height: 100%; grid-template-columns: var(--tile) minmax(0, 1fr) var(--tile); grid-template-rows: 1fr 1fr; background: radial-gradient(ellipse 46% 9% at 50% 95%, rgba(0, 0, 0, 0.6), transparent 72%); }
/* The figure has the whole column; what is worn is set over its edges, the weapon at the left and the amulet and armor at the right. */
.hub.camp .doll .hero-slot { grid-column: 1 / -1; grid-row: 1 / -1; height: 100%; align-self: stretch; }
.hub.camp .doll .hero-slot { position: relative; }
.hub.camp .doll .hero-slot .hero3d { position: absolute; inset: 0; }
.hub.camp .doll .eq { z-index: 1; }
.hub.camp .doll .hero-slot .hero { height: min(100%, 300px); }
.hub.camp .doll .eq.weapon { align-self: center; } .hub.camp .doll .eq.amulet { align-self: end; } .hub.camp .doll .eq.chest { align-self: start; }
.hub.camp .inv-stats { grid-area: stats; margin: 0; padding: 8px 14px; background: #1b1812; box-shadow: inset 0 0 0 1px var(--seam); font-size: calc(14px * var(--ts, 1)); grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); gap: 3px 16px; }
.hub.camp .bag-grid { grid-template-columns: repeat(auto-fill, var(--tile)); gap: 8px; padding: 3px; }
.hub.camp .tile { width: var(--tile); height: var(--tile); min-width: 0; min-height: 0; padding: 0; border-radius: 0; }
.hub.camp .tile.large { width: 64px; height: 64px; min-width: 64px; }
.hub.camp .tile img.osrs-icon { width: 82%; }
.hub.camp .tile svg { width: 56%; height: 56%; }
.hub.camp .tile.selected { box-shadow: 0 0 0 3px var(--brass), inset 0 0 0 2px #16140f; }
.hub.camp .inv-bag .chips { margin: 0 0 10px; padding: 3px; gap: 6px; }
.hub.camp .inv .chip { border-radius: 0; font: 600 calc(15px * var(--ts, 1)) / 1.2 var(--body); cursor: pointer; }
.hub.camp .inv-bag .chips .chip { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 6px 14px 6px 10px; border: 0; background: #1b1812; color: #cfc6ae; clip-path: var(--cut); box-shadow: inset 0 0 0 1px var(--seam); }
.hub.camp .inv-bag .chips .chip::before { content: ""; flex: none; width: 20px; height: 20px; background: currentColor; -webkit-mask: var(--icon) center / contain no-repeat; mask: var(--icon) center / contain no-repeat; }
.hub.camp .inv-bag .chips .chip.on { color: var(--brass); font-weight: 700; background: #262117; box-shadow: inset 0 0 0 2px var(--brass), inset 0 -5px 0 var(--ember); }
.hub.camp .inv-bag .chip { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.9'%3E%3Cpath d='M4 4h7v7H4zM13 4h7v7h-7zM4 13h7v7H4zM13 13h7v7h-7z'/%3E%3C/svg%3E"); }
.hub.camp .inv-bag .chip[data-filter=weapon] { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.9'%3E%3Cpath d='M5 19L17 7l2-4-4 2L3 17z'/%3E%3Cpath d='M7 13l4 4M4 20l2-2'/%3E%3C/svg%3E"); }
.hub.camp .inv-bag .chip[data-filter=chest] { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.9'%3E%3Cpath d='M8 3l4 2 4-2 4 3-2 4v10H6V10L4 6z'/%3E%3Cpath d='M12 5v15'/%3E%3C/svg%3E"); }
.hub.camp .inv-bag .chip[data-filter=amulet] { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.9'%3E%3Cpath d='M7 3c0 5 2 8 5 9 3-1 5-4 5-9'/%3E%3Ccircle cx='12' cy='16' r='3.2'/%3E%3C/svg%3E"); }
.hub.camp .inv-bag .chip[data-filter=buyback] { --icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.9'%3E%3Ccircle cx='14' cy='13' r='6.5'/%3E%3Cpath d='M9 4L4.5 7.5 9 11M5 7.5h6'/%3E%3C/svg%3E"); }
/* Buy back (buy-back.js): a row a sold item, its tile the bag's size, what it is beside it and the one button at the end of the row. */
.hub.camp .buy-back .bb-note { font-size: calc(15px * var(--ts, 1)); margin: 0 3px 10px; }
.hub.camp .buy-back .bb-list { padding: 3px; }
.hub.camp .buy-back .bb-row { grid-template-columns: var(--tile) minmax(0, 1fr) minmax(11rem, auto); gap: 6px 14px; align-items: center; padding: 10px 12px; border: 0; border-radius: 0; background: #1b1812; box-shadow: inset 0 0 0 1px var(--seam); }
.hub.camp .buy-back .bb-row .tile.static { cursor: default; }
.hub.camp .buy-back .bb-what { font-size: calc(15px * var(--ts, 1)); }
.hub.camp .buy-back .bb-what > b { font: 600 calc(17px * var(--ts, 1)) / 1.2 var(--display); letter-spacing: 0.03em; color: var(--brass); }
.hub.camp .buy-back .bb-lines, .hub.camp .buy-back .bb-trait, .hub.camp .buy-back .bb-why { font-size: calc(14px * var(--ts, 1)); }
.hub.camp .buy-back .bb-act { grid-column: auto; }
.hub.camp .buy-back .bb-act button { width: 100%; min-height: 44px; padding: 6px 16px; border: 0; color: var(--text); background: linear-gradient(#383327, #262219); clip-path: var(--cut); box-shadow: inset 0 0 0 2px #6b5a34; }
@media (max-width: 1100px) { .hub.camp .buy-back .bb-row { grid-template-columns: var(--tile) minmax(0, 1fr); } .hub.camp .buy-back .bb-act { grid-column: 1 / -1; } }
.hub.camp .inv-detail .chips .chip { min-height: 44px; padding: 6px 16px; border: 0; background: linear-gradient(#383327, #262219); clip-path: var(--cut); box-shadow: inset 0 0 0 2px #4a4334; }
.hub.camp .inv-detail .chips .chip.strong { color: #1b1408; font-weight: 700; background: linear-gradient(var(--ember-hi), var(--ember-lo)); box-shadow: inset 0 0 0 2px #6b4212, inset 0 3px 0 rgba(255, 235, 190, 0.35); }
.hub.camp .inv-detail .chips .chip[disabled] { opacity: 0.5; cursor: default; }

/* The Menu button in the hall and in a descent: three drawn lines, named Menu; a keyboard is shown its key, a controller its button. */
#menuBtn .menu-glyph { display: none; width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: square; }
#menuBtn .menu-key { display: none; }
#menuBtn.glyph { display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-width: 44px; min-height: 44px; padding: 0 11px; border: 0; border-radius: 0; cursor: pointer; color: var(--text);
  background: linear-gradient(#383327, #262219); clip-path: var(--cut); box-shadow: inset 0 0 0 2px #4a4334, inset 0 3px 0 rgba(255, 255, 255, 0.07); }
#menuBtn.glyph .menu-glyph { display: block; } #menuBtn.glyph .menu-word { display: none; }
#menuBtn.glyph:focus-visible { outline: none; box-shadow: inset 0 0 0 3px var(--brass), inset 0 0 0 5px #16140f; }
@media (hover: hover) and (pointer: fine) { body:not(.pad-on) #menuBtn.glyph .menu-key { display: inline-grid; } }
body.pad-on #menuBtn.glyph::before { margin-right: 0; }

@media (max-width: 700px) and (orientation: portrait) {
  /* A phone held upright: the bar scrolls sideways, the sections are a row under it, the chosen one fills the rest. */
  .hub.camp { --pad: 14px; }
  .menu-bar { min-height: 50px; padding-left: calc(4px + var(--safe-l)); padding-right: calc(8px + var(--safe-r)); }
  .hub.camp .tab { min-height: 50px; padding-left: 13px; padding-right: 13px; font-size: calc(15px * var(--ts, 1)); letter-spacing: 0.08em; }
  .bar-hint { display: none; }
  .bar-state .badge:not(.warn) { display: none; } .hub.camp .bar-state .badge.warn { max-width: 7rem; }
  .menu-body { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr); }
  .menu-body.full { grid-template-rows: minmax(0, 1fr); }
  .menu-side { flex-direction: row; gap: 6px; overflow-x: auto; overflow-y: hidden; padding: 8px calc(12px + var(--safe-r)) 8px calc(12px + var(--safe-l)); box-shadow: inset 0 -1px 0 var(--seam); }
  .hub.camp .side-item { flex: none; width: auto; grid-template-columns: minmax(0, 1fr); min-height: 44px; padding: 6px 14px; white-space: nowrap; font-size: calc(16px * var(--ts, 1)); box-shadow: inset 0 0 0 1px var(--seam); clip-path: var(--cut); }
  .hub.camp .side-item .side-mark, .hub.camp .side-item small { display: none; }
  .hub.camp .side-item[aria-current=true] { box-shadow: inset 0 0 0 2px var(--brass), inset 0 -5px 0 var(--ember); }
  .menu-detail, .menu-body.full > .menu-detail { padding: 14px calc(14px + var(--safe-r)) 24px calc(14px + var(--safe-l)); }
  .menu-action { bottom: -24px; }
  /* Gear: what is worn in a row, the bag (three rows, then it scrolls), the chosen item under it, the numbers last. No figure. */
  .menu-gear { overflow-y: auto; scrollbar-width: none; padding: 10px calc(12px + var(--safe-r)) 16px calc(12px + var(--safe-l)); }
  .hub.camp .inv, .hub.camp .inv.in-camp { height: auto; --tile: 52px; }
  .hub.camp .inv-body { display: flex; flex-direction: column; gap: 10px; }
  .hub.camp .inv-body > section { overflow: visible; }
  .hub.camp .doll { order: 1; flex: none; min-height: 0; height: auto; display: flex; gap: 12px; justify-content: flex-start; background: none; }
  .hub.camp .doll .hero-slot { display: none; }
  .hub.camp .doll .eq { min-width: 56px; }
  .hub.camp .doll .eq.weapon { order: -1; }
  .hub.camp .inv-body > .inv-bag { order: 2; }
  .hub.camp .bag-grid { max-height: calc(var(--tile) * 3 + 24px); overflow-y: auto; scrollbar-width: none; }
  .hub.camp .inv-body > .inv-detail { order: 3; max-height: none; align-self: stretch; }
  .hub.camp .inv-stats { order: 4; }
  .hub.camp .inv-bag .chips { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; margin-bottom: 6px; }
  .hub.camp .inv-bag .chips .chip { flex: none; padding: 6px 12px 6px 9px; }
}
@media (orientation: landscape) and (max-height: 520px) {
  /* A phone on its side: two columns, slimmer bands. On Gear the bag and what is worn on the left, the chosen item on the right, no figure. */
  .hub.camp { --pad: 14px; }
  .menu-bar { min-height: 46px; }
  .hub.camp .tab { min-height: 46px; font-size: calc(15px * var(--ts, 1)); padding-left: 14px; padding-right: 14px; }
  .menu-body { grid-template-columns: clamp(10.5rem, 24vw, 14rem) minmax(0, 1fr); }
  .menu-side { padding-top: 8px; gap: 2px; }
  .hub.camp .side-item { min-height: 44px; padding: 5px 10px 5px 8px; font-size: calc(16px * var(--ts, 1)); }
  .menu-detail { padding-top: 12px; padding-bottom: 20px; }
  .menu-action { bottom: -20px; }
  #campFooter { padding-top: 4px; padding-bottom: calc(4px + var(--safe-b)); }
  .menu-gear { overflow-y: auto; scrollbar-width: none; padding-top: 8px; }
  .hub.camp .inv, .hub.camp .inv.in-camp { height: auto; --tile: 52px; }
  .hub.camp .inv-body { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); grid-template-areas: "doll detail" "bag detail" "bag stats"; grid-template-rows: auto auto 1fr; gap: 8px 14px; }
  .hub.camp .inv-body > section { overflow: visible; }
  .hub.camp .doll { grid-area: doll; min-height: 0; height: auto; display: flex; gap: 12px; justify-content: flex-start; background: none; }
  .hub.camp .doll .hero-slot { display: none; }
  .hub.camp .doll .eq { min-width: 56px; } .hub.camp .doll .eq.weapon { order: -1; }
  .hub.camp .inv-bag .chips { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; margin-bottom: 6px; }
  .hub.camp .inv-bag .chips .chip { flex: none; padding: 6px 12px 6px 9px; }
  .hub.camp .inv-stats { grid-area: stats; align-self: start; }
  .hub.camp .inv-body > .inv-detail { max-height: none; }
}
@media (prefers-reduced-motion: reduce) { .hub.camp * { transition: none !important; animation: none !important; } }
/* ---------------- the way below (descent.js): the stair's card as the whole screen ----------------
   Three tall pictures, one a place, each a window into it (descent-art.js draws them; without it the pane is the drawn
   one below, in the place's own light, with its emblem). The one chosen is lit, larger and brass-edged, with a filled
   diamond and the word; one that is open but not chosen is dimmer and still in color; one that is shut is gray and
   dark under a lock, with the words that say what opens it. Beside them what is known of the place looked at, then a
   plate for each thing this hero can take or set, and along the foot the one button, which says where it leads.
   Four shapes: a desk (pictures left, the words down the right), an ultrawide (pictures, the place, the preparation),
   a phone held upright (pictures across the top third, the rest scrolling under them, the button on its own bar) and a
   phone on its side (pictures left, the rest scrolling right, the buttons along the foot). */
#card[data-kind=descent] { inset: 0; left: 0; top: 0; transform: none; width: auto; max-height: none; overflow: hidden; border: 0; border-radius: 0; box-shadow: none; text-align: left; background: #0f0d0a; }
#card[data-kind=descent] .card-art { display: none; }
#card[data-kind=descent] #cardBody { display: block; padding: 0; height: 100%; }
.descent { position: absolute; inset: 0; display: grid; box-sizing: border-box; min-width: 0; color: var(--text); font: calc(16px * var(--ts, 1)) / 1.4 var(--body); touch-action: manipulation; -webkit-user-select: none; user-select: none;
  --pad: clamp(12px, 1.5vw, 28px); --gap: clamp(8px, 1vw, 18px);
  padding: calc(var(--pad) * 0.6 + var(--safe-t)) calc(var(--pad) + var(--safe-r)) calc(var(--pad) * 0.6 + var(--safe-b)) calc(var(--pad) + var(--safe-l));
  grid-template-columns: minmax(0, 1fr); grid-template-rows: auto auto minmax(0, 1fr) auto; grid-template-areas: "head" "stages" "side" "foot"; gap: 10px var(--gap);
  background: radial-gradient(ellipse 70% 42% at 30% 112%, rgba(208, 138, 46, 0.13), transparent 70%), linear-gradient(#0b0a08, #14110c 70%, #0f0d0a); }
.descent *, .descent *::before, .descent *::after { box-sizing: border-box; }
.descent [hidden] { display: none !important; }
.descent .ds-sr { position: absolute; width: 1px; height: 1px; margin: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.descent .ds-glyph { display: block; flex: none; width: 1.25em; height: 1.25em; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: square; stroke-linejoin: miter; }
.descent .ds-glyph .fill { fill: currentColor; stroke: none; }
.descent .ds-emblem { width: 100%; height: 100%; stroke-width: 2.4; }
.descent .ds-seal .ds-emblem { width: calc(var(--seal) * 0.64); height: calc(var(--seal) * 0.64); }
.descent .ds-diamond { display: inline-block; flex: none; width: 0.62em; height: 0.62em; transform: rotate(45deg); box-shadow: inset 0 0 0 2px #6a6150; }

.descent .ds-head { grid-area: head; display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 18px; min-width: 0; }
#cardBody .descent h1 { margin: 0; font: 600 calc(clamp(22px, 2.3vw, 38px) * var(--ts, 1)) / 1.15 var(--display); letter-spacing: 0.03em; color: var(--brass); }
#cardBody .descent .ds-head p { margin: 0; font-size: calc(16px * var(--ts, 1)); font-style: italic; color: #cbbf9f; }

/* ----- the pictures */
.descent .ds-stages { grid-area: stages; display: flex; align-items: stretch; justify-content: center; gap: var(--gap); min-width: 0; min-height: 0; height: min(calc(clamp(12rem, 34svh, 18rem) * var(--ts, 1)), 39svh); container: stages / size; }
.descent .ds-stage { position: relative; flex: 1 1 0; min-width: 0; max-width: 30rem; max-width: 64cqh; margin: 0; padding: 0; border: 0; overflow: hidden; cursor: pointer; display: grid; grid-template-rows: auto minmax(0, 1fr) auto; text-align: center;
  font: inherit; color: var(--text); background: #14110d; --cut-l: 14px;
  clip-path: polygon(var(--cut-l) 0, calc(100% - var(--cut-l)) 0, 100% var(--cut-l), 100% calc(100% - var(--cut-l)), calc(100% - var(--cut-l)) 100%, var(--cut-l) 100%, 0 calc(100% - var(--cut-l)), 0 var(--cut-l));
  --glow: 255, 138, 58; --tone: #e09a3a; --deep: #2a1a0e; }
.descent .ds-stage[data-art=wilds] { --glow: 150, 224, 80; --tone: #a9c964; --deep: #16240f; }
.descent .ds-stage[data-art=frost] { --glow: 143, 200, 255; --tone: #a8ccf0; --deep: #101c2c; }
.descent .ds-stage[aria-checked=true] { flex-grow: 1.9; max-width: 34rem; max-width: 74cqh; }
/* The frame: iron for a place not chosen, brass over a dark seam for the one that is. Drawn over the picture, so it is never hidden by it. */
.descent .ds-stage::after { content: ""; position: absolute; inset: 0; pointer-events: none; box-shadow: inset 0 0 0 2px #4a4334, inset 0 0 0 4px #16140f; }
.descent .ds-stage[aria-checked=true]::after { box-shadow: inset 0 0 0 3px var(--brass), inset 0 0 0 6px #16140f, inset 0 0 0 7px rgba(230, 191, 114, 0.4); }
.descent .ds-stage[data-state=locked]::after { box-shadow: inset 0 0 0 2px #3a352a, inset 0 0 0 4px #110f0b; }
/* Focus, and a place being looked at without being chosen (a shut one that was tapped), is a pale line inside the frame, never mistaken for the brass of the one chosen. */
.descent .ds-stage:focus-visible { outline: none; }
.descent .ds-stage.looked::after, .descent .ds-stage:focus-visible::after { box-shadow: inset 0 0 0 2px #4a4334, inset 0 0 0 4px #16140f, inset 0 0 0 8px #16140f, inset 0 0 0 10px #f3ead2; }
.descent .ds-stage[aria-checked=true]:focus-visible::after { box-shadow: inset 0 0 0 3px var(--brass), inset 0 0 0 6px #16140f, inset 0 0 0 9px #16140f, inset 0 0 0 11px #f3ead2; }

.descent .ds-pane { position: absolute; inset: 0; overflow: hidden; filter: brightness(0.74) saturate(0.85);
  background: radial-gradient(ellipse 74% 30% at 50% 70%, rgba(var(--glow), 0.5), transparent 72%), radial-gradient(ellipse 120% 60% at 50% 100%, var(--deep), transparent 75%), linear-gradient(#090806, var(--deep) 62%, #0b0907); }
.descent .ds-stage[aria-checked=true] .ds-pane { filter: none; }
.descent .ds-stage[data-state=locked] .ds-pane { filter: grayscale(1) brightness(0.36) contrast(1.08); }
.descent .ds-drawn { position: absolute; left: 50%; top: 44%; width: min(52%, 11rem); aspect-ratio: 1; transform: translate(-50%, -50%); color: var(--tone); opacity: 0.55; }
.descent .ds-stage.painted .ds-drawn { display: none; }
.descent .ds-art { position: absolute; left: -4%; top: -3%; width: 108%; height: 106%; object-fit: cover; object-position: 50% 50%; opacity: 0; }
.descent .ds-stage.painted .ds-art { opacity: 1; transition: opacity 0.45s ease; }
/* The place's own light, low in the picture: it breathes on the one chosen and is still on the others. */
.descent .ds-light { position: absolute; inset: 0; opacity: 0.5; mix-blend-mode: screen; background: radial-gradient(ellipse 66% 30% at 50% 66%, rgba(var(--glow), 0.26), transparent 72%); }
.descent .ds-stage[aria-checked=true] .ds-light { animation: dsEmber 4.4s ease-in-out infinite; }
.descent .ds-stage[aria-checked=true][data-art=wilds] .ds-light { animation-duration: 6.4s; }
.descent .ds-stage[aria-checked=true][data-art=frost] .ds-light { animation: dsCold 8s ease-in-out infinite; }
.descent .ds-stage[aria-checked=true].painted .ds-art { animation: dsDrift 30s ease-in-out infinite alternate; }
@keyframes dsEmber { 0%, 100% { opacity: 0.55; } 18% { opacity: 0.95; } 31% { opacity: 0.7; } 52% { opacity: 1; } 68% { opacity: 0.62; } 84% { opacity: 0.9; } }
@keyframes dsCold { 0%, 100% { opacity: 0.45; } 50% { opacity: 0.95; } }
@keyframes dsDrift { from { transform: translate(1.6%, 1%) scale(1.02); } to { transform: translate(-1.6%, -1%) scale(1.02); } }

.descent .ds-act { position: relative; grid-row: 1; padding: 16px 10px 22px; font: 600 calc(clamp(13px, 1.1vw + 4px, 19px) * var(--ts, 1)) / 1.1 var(--display); letter-spacing: 0.14em; color: #cbbf9f; text-shadow: 0 1px 0 #000;
  background: linear-gradient(rgba(11, 9, 7, 0.9), rgba(11, 9, 7, 0)); }
.descent .ds-stage[aria-checked=true] .ds-act { color: var(--brass); }
.descent .ds-says { display: contents; }
.descent .ds-plate { position: relative; grid-row: 3; display: grid; justify-items: center; gap: 6px; min-width: 0; padding: 34px 12px 18px; background: linear-gradient(rgba(11, 9, 7, 0), rgba(11, 9, 7, 0.88) 40%, rgba(11, 9, 7, 0.97)); }
/* The emblem sits in a seal mould, as the moulds on the title's chains: six-sided iron, the mark in the place's color. */
.descent .ds-seal { --seal: calc(clamp(40px, 4.4vw, 68px) * var(--ts, 1)); display: grid; place-items: center; flex: none; width: var(--seal); height: calc(var(--seal) * 1.11); color: #cbbf9f; background: linear-gradient(#3a3226, #1b1711);
  clip-path: polygon(50% 0, 100% 24%, 100% 76%, 50% 100%, 0 76%, 0 24%); }
.descent .ds-stage[aria-checked=true] .ds-seal { color: var(--tone); background: linear-gradient(#4a3f2c, #231d14); }
.descent .ds-stage[data-state=locked] .ds-seal { color: #a59c86; }
.descent .ds-name { max-width: 100%; font: 600 calc(clamp(15px, 1.15vw + 7px, 27px) * var(--ts, 1)) / 1.15 var(--display); letter-spacing: 0.04em; color: #dcd3bb; text-shadow: 0 2px 0 #000; text-wrap: balance; overflow-wrap: anywhere; }
.descent .ds-stage[aria-checked=true] .ds-name { color: var(--brass); }
.descent .ds-stage[data-state=locked] .ds-name { color: #a59c86; }
.descent .ds-marks { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 4px 12px; min-height: 1.3em; max-width: 100%; font-size: calc(14px * var(--ts, 1)); line-height: 1.3; color: #cfc6ae; }
.descent .ds-mark { display: inline-flex; align-items: center; gap: 6px; font-weight: 700; white-space: nowrap; }
.descent .ds-mark.chosen { color: var(--brass); }
.descent .ds-mark.chosen .ds-diamond, .descent .ds-status.on .ds-diamond { background: var(--ember); box-shadow: inset 0 0 0 2px var(--brass); }
.descent .ds-mark.cleared { color: #b9d3c0; }
.descent .ds-mark.cleared .ds-glyph { width: 1em; height: 1em; stroke-width: 3; }
.descent .ds-mark.locked { color: #dcd3bb; }
.descent .ds-needs { flex: 1 1 100%; font-weight: 500; color: #cfc6ae; text-wrap: balance; }

/* A narrow picture (a phone, or the two not chosen beside the chosen one): its mark stays at the top and its name and what
   it says run down it like the spine of a book. */
@container stages (max-width: 640px) {
  .descent .ds-stage:not([aria-checked=true]) { grid-template-rows: auto minmax(0, 1fr); }
  .descent .ds-stage:not([aria-checked=true]) .ds-act { padding: 12px 2px 6px; font-size: calc(12px * var(--ts, 1)); letter-spacing: 0.08em; }
  .descent .ds-stage:not([aria-checked=true]) .ds-plate { grid-row: 2; grid-template-rows: auto minmax(0, 1fr); align-content: stretch; gap: 6px; padding: 2px 5px 12px; background: linear-gradient(rgba(11, 9, 7, 0.45), rgba(11, 9, 7, 0.88)); }
  .descent .ds-stage:not([aria-checked=true]) .ds-seal { --seal: calc(30px * var(--ts, 1)); }
  .descent .ds-stage:not([aria-checked=true]) .ds-says { display: block; writing-mode: vertical-rl; min-width: 0; min-height: 0; max-width: 100%; overflow: hidden; text-align: left; }
  .descent .ds-stage:not([aria-checked=true]) .ds-name { display: block; margin-left: 3px; font-size: calc(13px * var(--ts, 1)); line-height: 1.15; text-wrap: wrap; }
  .descent .ds-stage:not([aria-checked=true]) .ds-marks { display: block; min-height: 0; font-size: calc(12px * var(--ts, 1)); line-height: 1.22; }
  .descent .ds-stage:not([aria-checked=true]) .ds-mark { display: block; }
  .descent .ds-stage:not([aria-checked=true]) .ds-mark .ds-glyph { display: inline-block; vertical-align: middle; margin-bottom: 4px; }
  .descent .ds-stage:not([aria-checked=true]) .ds-mark.locked, .descent .ds-stage:not([aria-checked=true]) .ds-needs { display: inline; white-space: normal; text-wrap: wrap; }
  .descent .ds-stage:not([aria-checked=true]) .ds-mark.locked::after { content: ". "; }
  .descent .ds-stage[aria-checked=true] { flex-grow: 1.9; }
  .descent .ds-stage[aria-checked=true] .ds-plate { padding: 22px 8px 12px; gap: 4px; }
  .descent .ds-stage[aria-checked=true] .ds-act { padding: 12px 6px 14px; }
  .descent .ds-stage { --cut-l: 10px; }
}

/* A browser without container queries: no spines. Small panels keep their names across, set small enough to fit, and
   give up the seal of a place not chosen; nothing runs down the panel and nothing is cut off. */
@supports not (container-type: size) {
  @media (max-width: 899px), (max-height: 520px) {
    .descent .ds-stages { height: auto; min-height: 13.5rem; }
    .descent .ds-stage { --cut-l: 10px; }
    .descent .ds-stage[aria-checked=true] { flex-grow: 1.5; }
    .descent .ds-stage:not([aria-checked=true]) .ds-seal { display: none; }
    .descent .ds-act { padding: 12px 4px 10px; font-size: calc(12px * var(--ts, 1)); letter-spacing: 0.08em; }
    .descent .ds-plate { padding: 16px 5px 12px; gap: 4px; }
    .descent .ds-name { font-size: calc(12.5px * var(--ts, 1)); letter-spacing: 0; -webkit-hyphens: auto; hyphens: auto; }
    .descent .ds-marks { gap: 2px 8px; font-size: calc(12px * var(--ts, 1)); }
    .descent .ds-mark { white-space: normal; }
  }
}

/* ----- the place looked at, and what goes down */
.descent .ds-side { grid-area: side; min-width: 0; min-height: 0; display: flex; flex-direction: column; gap: 12px; overflow-y: auto; -webkit-overflow-scrolling: touch; touch-action: pan-y; scrollbar-width: none; padding-bottom: 6px; }
.descent .ds-side::-webkit-scrollbar, .descent .ds-prep::-webkit-scrollbar, .descent .ds-detail::-webkit-scrollbar { display: none; }
.descent .more-below { -webkit-mask-image: linear-gradient(#000 calc(100% - 44px), transparent); mask-image: linear-gradient(#000 calc(100% - 44px), transparent); }
.descent .ds-detail { flex: none; min-width: 0; display: grid; gap: 6px; align-content: start; -webkit-user-select: text; user-select: text; }
.descent .ds-detail:focus-visible { outline: 2px solid #f3ead2; outline-offset: 2px; }
#cardBody .descent .ds-detail p { margin: 0; }
.descent .ds-where { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 14px; font: 600 calc(14px * var(--ts, 1)) / 1.2 var(--display); letter-spacing: 0.14em; color: #cbbf9f; }
.descent .ds-status { display: inline-flex; align-items: center; gap: 7px; font: 700 calc(14px * var(--ts, 1)) / 1.2 var(--body); letter-spacing: 0; color: #cfc6ae; }
.descent .ds-status.on { color: var(--brass); }
#cardBody .descent h2 { margin: 0; font: 600 calc(clamp(21px, 1.5vw + 8px, 32px) * var(--ts, 1)) / 1.15 var(--display); letter-spacing: 0.03em; color: var(--brass); }
.descent .ds-premise { max-width: 62ch; font-size: calc(18px * var(--ts, 1)); line-height: 1.4; font-style: italic; color: #dcd3bb; text-wrap: pretty; }
.descent .ds-fact { max-width: 62ch; font-size: calc(16px * var(--ts, 1)); color: #cfc6ae; }
.descent .ds-quest { max-width: 62ch; padding: 8px 12px; border-left: 3px solid var(--ember); background: #231e15; font-size: calc(16px * var(--ts, 1)); line-height: 1.35; }
.descent .ds-shut { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 12px; align-items: center; max-width: 62ch; padding: 10px 14px; background: #1c1913; box-shadow: inset 0 0 0 1px var(--seam); clip-path: var(--cut); font-size: calc(17px * var(--ts, 1)); }
.descent .ds-shut .ds-glyph { width: 2em; height: 2em; color: #cbbf9f; }
.descent .ds-shut b { color: var(--text); }
.descent .ds-warnings { list-style: none; margin: 2px 0 0; padding: 0; display: grid; gap: 6px; max-width: 62ch; }
.descent .ds-warnings li, .descent .ds-caveat { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 10px; align-items: start; padding: 8px 12px; background: #2a1613; box-shadow: inset 0 0 0 1px #7a3b31; clip-path: var(--cut); font-size: calc(15px * var(--ts, 1)); line-height: 1.35; color: #f5cdc5; }
.descent .ds-warnings .ds-glyph, .descent .ds-caveat .ds-glyph { margin-top: 1px; color: #f1b2a8; }

/* (the groups run down columns, each as tall as it needs: a short one never waits beside a long one) */
.descent .ds-prep { flex: none; min-width: 0; }
.descent .ds-groups { columns: 17rem 2; column-gap: 8px; }
.descent .ds-group { display: grid; gap: 6px; align-content: start; min-width: 0; margin: 0 0 8px; break-inside: avoid; padding: 10px 12px 12px; background: rgba(27, 24, 18, 0.94); clip-path: var(--cut); box-shadow: inset 0 0 0 1px var(--seam); }
#cardBody .descent h3 { margin: 0; font: 700 calc(14px * var(--ts, 1)) / 1.25 var(--body); color: var(--muted); }
#cardBody .descent .ds-group p { margin: 0; }
.descent .ds-line { font-size: calc(15px * var(--ts, 1)); line-height: 1.35; }
.descent .ds-line b { color: var(--brass); }
.descent .ds-line.none { color: var(--muted); } .descent .ds-line.none b { color: #cfc6ae; }
.descent .ds-fine { font-size: calc(14px * var(--ts, 1)); line-height: 1.35; color: var(--muted); }
.descent .ds-fine b { color: #cfc6ae; }
.descent .ds-caveat { margin-top: 2px; }

/* More below: over the foot of whichever list scrolls, a real button (a press scrolls on); it goes at the end of the list. */
.descent .ds-more { grid-area: side; align-self: end; justify-self: center; z-index: 2; display: inline-flex; align-items: center; gap: 8px; min-height: 44px; margin: 0 0 4px; padding: 6px 18px 6px 12px; border: 0; cursor: pointer;
  font: 700 calc(15px * var(--ts, 1)) var(--body); color: var(--text); background: linear-gradient(#383327, #262219); clip-path: var(--cut);
  box-shadow: inset 0 0 0 2px #8a7550, inset 0 3px 0 rgba(255, 255, 255, 0.07), inset 0 -3px 0 rgba(0, 0, 0, 0.4); }
.descent .ds-more .ds-glyph { color: var(--brass); stroke-width: 2.6; }
.descent .ds-more:focus-visible { outline: 2px solid #f3ead2; outline-offset: -6px; }

/* A thing to pick (food, a keepsake): a plate with a diamond that is hollow until it is the one. A thing to take or leave: a box with a drawn tick, and the word. */
.descent .ds-choices { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr)); gap: 6px; }
.descent .ds-choice, .descent .ds-toggle { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 10px; align-items: center; width: 100%; min-height: 48px; margin: 0; padding: 7px 12px; border: 0; cursor: pointer; text-align: left;
  font: inherit; color: var(--text); background: #1b1812; clip-path: var(--cut); box-shadow: inset 0 0 0 1px #4a4334; }
.descent .ds-choice[data-act=keepsake] { grid-template-columns: minmax(0, 1fr) auto; }
.descent .ds-toggle { grid-template-columns: auto minmax(0, 1fr); }
.descent .ds-choice.still { cursor: default; grid-template-columns: auto minmax(0, 1fr); box-shadow: inset 0 0 0 1px var(--seam); }
.descent .ds-choice.on, .descent .ds-toggle.on { background: linear-gradient(#2f2a1f, #231f17); box-shadow: inset 0 0 0 2px var(--brass); }
.descent .ds-choice.on .ds-diamond { background: var(--ember); box-shadow: inset 0 0 0 2px var(--brass); }
.descent .ds-choice .ds-diamond { width: 13px; height: 13px; margin: 0 4px; }
.descent .ds-icon { width: calc(26px * var(--ts, 1)); height: calc(26px * var(--ts, 1)); color: #cbbf9f; stroke-width: 1.7; }
.descent .ds-choice.on .ds-icon { color: var(--ember-hi); }
.descent .ds-words { display: grid; gap: 1px; min-width: 0; }
.descent .ds-words b { font-size: calc(16px * var(--ts, 1)); line-height: 1.25; color: var(--text); }
.descent .on > .ds-words b { color: var(--brass); }
.descent .ds-words small { font-size: calc(14px * var(--ts, 1)); line-height: 1.3; color: #bdb49d; }
.descent .ds-box { display: grid; place-items: center; width: 24px; height: 24px; color: #1b1408; box-shadow: inset 0 0 0 2px #6a6150; }
.descent .ds-box.on { background: var(--ember); box-shadow: inset 0 0 0 2px var(--brass); }
.descent .ds-box .ds-glyph { width: 16px; height: 16px; stroke-width: 3.2; }
.descent .ds-choice:focus-visible, .descent .ds-toggle:focus-visible, .descent .ds-step:focus-visible { outline: 2px solid #f3ead2; outline-offset: -6px; }

/* Depth: a step either way, the depth between them, and under it every depth there is: cleared ones filled, the ones that pay an oathmark as diamonds. */
.descent .ds-top { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 2px 12px; min-width: 0; }
.descent .ds-stepper { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 8px; align-items: center; }
.descent .ds-stepper .ds-track { grid-column: 1 / -1; }
.descent .ds-step { min-height: 44px; min-width: 0; margin: 0; padding: 6px 12px; border: 0; cursor: pointer; font: 700 calc(15px * var(--ts, 1)) var(--body); color: var(--text); background: linear-gradient(#383327, #262219); clip-path: var(--cut);
  box-shadow: inset 0 0 0 2px #4a4334, inset 0 3px 0 rgba(255, 255, 255, 0.07), inset 0 -3px 0 rgba(0, 0, 0, 0.4); }
.descent .ds-step[disabled] { opacity: 0.45; cursor: default; }
.descent .ds-depth { font: 600 calc(17px * var(--ts, 1)) / 1.2 var(--display); letter-spacing: 0.04em; color: var(--brass); }
.descent .ds-track { display: flex; align-items: center; justify-content: center; gap: 5px; min-width: 0; padding: 2px 0; }
.descent .ds-track i { flex: 0 1 20px; min-width: 4px; height: 6px; background: #14110d; box-shadow: inset 0 0 0 1px #6a6150; }
.descent .ds-track i.shut { opacity: 0.4; }
.descent .ds-track i.done { background: #8a7550; box-shadow: none; }
.descent .ds-track i.mark { flex: none; width: 9px; height: 9px; transform: rotate(45deg); }
.descent .ds-track i.on { background: var(--ember-hi); box-shadow: 0 0 0 2px #16140f, 0 0 0 3px var(--brass); }

.descent .ds-oaths { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; }
.descent .ds-oaths li { flex: 1 1 12rem; display: grid; gap: 1px; padding: 6px 12px 7px; background: #1b1812; box-shadow: inset 3px 0 0 var(--brass), inset 0 0 0 1px var(--seam); }
.descent .ds-oaths b { font-size: calc(15px * var(--ts, 1)); color: var(--brass); }
.descent .ds-oaths small { font-size: calc(14px * var(--ts, 1)); line-height: 1.3; color: #bdb49d; }

/* ----- the foot: Not yet at the left, the one button, and under it what a descent is */
.descent .ds-foot { grid-area: foot; position: relative; display: grid; grid-template-columns: auto minmax(0, 1fr); grid-template-areas: "why why" "stay go"; gap: 6px 10px; align-items: start; min-width: 0;
  margin: 0 calc(-1 * (var(--pad) + var(--safe-r))) calc(-1 * (var(--pad) * 0.6 + var(--safe-b))) calc(-1 * (var(--pad) + var(--safe-l)));
  padding: 10px calc(var(--pad) + var(--safe-r)) calc(10px + var(--safe-b)) calc(var(--pad) + var(--safe-l)); background: #0f0d0a; box-shadow: 0 -1px 0 var(--seam); }
/* (lab.css has a .forged of its own on the rune card, a label: these are the front end's forged buttons) */
#cardBody .descent .forged { font-size: calc(17px * var(--ts, 1)); font-weight: 700; color: var(--text); }
#cardBody .descent .forged.primary { color: #1b1408; }
.descent #hStay { grid-area: stay; min-height: 56px; padding: 8px 16px; }
.descent .ds-go { grid-area: go; display: grid; gap: 5px; min-width: 0; }
.descent #hGo { width: 100%; min-height: 56px; padding: 7px 14px; }
.descent #hGo b { font-size: calc(clamp(18px, 1.2vw + 8px, 24px) * var(--ts, 1)); }
.descent #hGo span { font: 700 calc(15px * var(--ts, 1)) / 1.2 var(--body); letter-spacing: 0.01em; opacity: 1; text-wrap: balance; }
.descent #hGo[disabled] { opacity: 0.45; }
#cardBody .descent .ds-note { margin: 0; font-size: calc(13px * var(--ts, 1)); line-height: 1.3; color: var(--muted); text-align: center; text-wrap: balance; }
#cardBody .descent .ds-why { grid-area: why; margin: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; padding: 8px 12px; background: #2a1613; box-shadow: inset 0 0 0 1px #7a3b31; clip-path: var(--cut); font-size: calc(15px * var(--ts, 1)); line-height: 1.35; color: #f5cdc5; }
.descent .ds-why span { flex: 1 1 12rem; }
.descent .ds-why .forged { min-height: 44px; padding: 6px 16px; }

@media (prefers-reduced-motion: reduce) {
  .descent .ds-light, .descent .ds-art { animation: none !important; }
  .descent .ds-stage.painted .ds-art { transition: none; }
}
.descent.calm .ds-light, .descent.calm .ds-art { animation: none !important; }

@media (max-width: 700px) and (orientation: portrait) {
  /* A phone held upright: the heading is one line, and the words under the pictures are set a little closer, so a new hero sees their food without scrolling. */
  .descent { gap: 8px var(--gap); }
  #cardBody .descent .ds-head p { display: none; }
  .descent .ds-detail { gap: 4px; }
  .descent .ds-premise { font-size: calc(17px * var(--ts, 1)); line-height: 1.32; }
  .descent .ds-foot { padding-top: 8px; }
  .descent .ds-foot.refused .ds-note { display: none; }
}
@media (orientation: landscape) and (max-height: 520px) {
  /* A phone on its side: the pictures down the left, everything else scrolling on the right, the buttons along the foot. */
  .descent { grid-template-columns: minmax(0, 46%) minmax(0, 1fr); grid-template-rows: minmax(0, 1fr) auto; grid-template-areas: "stages side" "foot foot"; gap: 8px 12px; padding-top: calc(8px + var(--safe-t)); }
  .descent .ds-head { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .descent .ds-stages { height: auto; gap: 6px; }
  /* (a short row, with large text or a reason in the foot: the chosen picture keeps its name and marks and gives up its seal) */
  @container stages (max-height: 285px) {
    .descent .ds-stage[aria-checked=true] .ds-seal { display: none; }
    .descent .ds-stage[aria-checked=true] .ds-plate { padding-top: 14px; }
  }
  .descent .ds-foot { grid-template-columns: auto minmax(0, 0.8fr) minmax(0, 1.6fr); grid-template-areas: "stay go why"; align-items: center; padding-top: 6px; padding-bottom: calc(6px + var(--safe-b)); }
  .descent .ds-go { grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr); align-items: center; gap: 10px; }
  .descent #hStay, .descent #hGo { min-height: 46px; }
  #cardBody .descent .ds-note { text-align: left; }
  #cardBody .descent .ds-why { flex-wrap: nowrap; padding: 6px 10px; font-size: calc(14px * var(--ts, 1)); line-height: 1.25; }
  .descent .ds-why span { flex: 1 1 auto; }
  .descent .ds-why .forged { flex: none; }
  .descent .ds-foot.refused .ds-go { grid-template-columns: minmax(0, 1fr); }
  .descent .ds-foot.refused .ds-note { display: none; }
  .descent .ds-foot:not(.refused) { grid-template-columns: auto minmax(0, 1fr); grid-template-areas: "stay go"; }
}

@media (min-width: 900px) and (min-height: 521px) {
  /* A desk or a laptop: the pictures fill the left from head to foot, the place and the preparation run down the right. */
  .descent { grid-template-columns: minmax(0, 1.5fr) minmax(21rem, 1fr); grid-template-rows: auto minmax(0, 1fr) auto; grid-template-areas: "head head" "stages side" "foot foot"; gap: 10px clamp(14px, 1.6vw, 30px); }
  .descent .ds-stages { height: auto; }
  .descent .ds-stage { margin: 2.4cqh 0; }
  .descent .ds-stage[aria-checked=true] { flex-grow: 1.24; margin: 0; }
  .descent .ds-side { overflow: visible; padding-bottom: 0; gap: 14px; }
  .descent .ds-detail { max-height: 48%; overflow-y: auto; scrollbar-width: none; }
  .descent .ds-prep { flex: 1 1 0; min-height: 0; overflow-y: auto; scrollbar-width: none; touch-action: pan-y; padding-bottom: 4px; }
  .descent .ds-foot { grid-template-columns: minmax(0, 1fr) minmax(0, 34rem) minmax(0, 1fr); grid-template-areas: "stay go why"; align-items: start; gap: 6px 18px; margin: 0; padding: 4px 0 0; background: none; box-shadow: none; }
  .descent #hStay { justify-self: start; min-height: 60px; padding: 8px 26px; background: rgba(22, 19, 14, 0.82); }
  .descent #hGo { min-height: 64px; }
  .descent #hGo span { font-size: calc(16px * var(--ts, 1)); }
  #cardBody .descent .ds-why { align-self: start; }
}
@media (min-width: 2100px) and (min-height: 521px) {
  /* An ultrawide: three columns, so nothing is stretched: the pictures, the place, the preparation. */
  .descent { grid-template-columns: minmax(0, 1.25fr) minmax(20rem, 0.5fr) minmax(24rem, 0.75fr); grid-template-areas: "head head head" "stages detail prep" "foot foot foot"; }
  .descent .ds-side { display: contents; }
  .descent .ds-detail { grid-area: detail; max-height: none; }
  .descent .ds-prep { grid-area: prep; }
  .descent .ds-more { grid-area: prep; }
}

/* ---------------- the camp's screens (camp-frame.js): the drill yard, the coals, the forge, the contract board ----------------
   Each is the page's card as the whole screen, in the way below's own language: a heading in the display face, a
   picture of the place in a cut-corner frame (camp-art.js draws it; without it the pane is the drawn one below, in
   firelight, with the place's mark), plates for what is held, one button that says what it does, Leave at the bottom
   left. This block is what the four share; each has its own block after it.
   Four shapes: a desk (the picture left, the work right), an ultrawide (the same, the work in more columns), a phone
   held upright (the picture a band across the top, the rest scrolling under it, the buttons on their own bar) and a
   phone on its side (the picture left, the rest scrolling right, the buttons along the foot). */
#card[data-kind=camp] { inset: 0; left: 0; top: 0; transform: none; width: auto; max-height: none; overflow: hidden; border: 0; border-radius: 0; box-shadow: none; text-align: left; background: #0f0d0a; }
#card[data-kind=camp] .card-art { display: none; }
#card[data-kind=camp] #cardBody { display: block; padding: 0; height: 100%; }
.camp-screen { position: absolute; inset: 0; display: grid; box-sizing: border-box; min-width: 0; color: var(--text); font: calc(16px * var(--ts, 1)) / 1.4 var(--body); touch-action: manipulation; -webkit-user-select: none; user-select: none;
  --pad: clamp(12px, 1.5vw, 28px); --gap: clamp(8px, 1vw, 18px); --glow: 255, 138, 58;
  padding: calc(var(--pad) * 0.6 + var(--safe-t)) calc(var(--pad) + var(--safe-r)) calc(var(--pad) * 0.6 + var(--safe-b)) calc(var(--pad) + var(--safe-l));
  grid-template-columns: minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr) auto; grid-template-areas: "head" "body" "foot"; gap: 10px var(--gap);
  background: radial-gradient(ellipse 70% 42% at 24% 112%, rgba(208, 138, 46, 0.13), transparent 70%), linear-gradient(#0b0a08, #14110c 70%, #0f0d0a); }
.camp-screen *, .camp-screen *::before, .camp-screen *::after { box-sizing: border-box; }
.camp-screen [hidden] { display: none !important; }
.camp-screen .cs-sr { position: absolute; width: 1px; height: 1px; margin: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.camp-screen .cs-glyph { display: block; flex: none; width: 1.25em; height: 1.25em; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: square; stroke-linejoin: miter; }
.camp-screen .cs-glyph .fill { fill: currentColor; stroke: none; }
.camp-screen .cs-emblem { width: 100%; height: 100%; stroke-width: 2.4; }
.camp-screen .cs-diamond { display: inline-block; flex: none; width: 0.62em; height: 0.62em; transform: rotate(45deg); box-shadow: inset 0 0 0 2px #6a6150; }
#cardBody .camp-screen p, #cardBody .camp-screen ul, #cardBody .camp-screen dl, #cardBody .camp-screen dd, #cardBody .camp-screen figure { margin: 0; }
#cardBody .camp-screen ul { list-style: none; padding: 0; }

/* ----- the head: the place's name, what is done there, and the skill it trains */
.camp-screen .cs-head { grid-area: head; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px 24px; min-width: 0; }
.camp-screen .cs-title { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 18px; min-width: 0; }
#cardBody .camp-screen h1 { margin: 0; font: 600 calc(clamp(22px, 2.3vw, 38px) * var(--ts, 1)) / 1.15 var(--display); letter-spacing: 0.03em; color: var(--brass); }
#cardBody .camp-screen .cs-title p { font-size: calc(16px * var(--ts, 1)); font-style: italic; color: #cbbf9f; max-width: 70ch; }
#cardBody .camp-screen h2 { margin: 0; font: 600 calc(clamp(16px, 0.6vw + 11px, 21px) * var(--ts, 1)) / 1.2 var(--display); letter-spacing: 0.04em; color: var(--brass); }
#cardBody .camp-screen h3 { margin: 0; font: 600 calc(16px * var(--ts, 1)) / 1.25 var(--display); letter-spacing: 0.03em; color: #dcd3bb; }
#cardBody .camp-screen h4 { margin: 0 0 4px; font: 700 calc(14px * var(--ts, 1)) / 1.25 var(--body); color: var(--muted); }
/* A skill: its level struck on a six-sided plate, a bar, and under the bar the same in numbers. */
.camp-screen .cs-skill { flex: 0 1 24rem; min-width: min(100%, 15rem); }
.camp-screen .cs-meter { display: grid; grid-template-columns: auto minmax(0, 1fr); grid-template-areas: "level bar" "level xp"; gap: 3px 12px; align-items: center; }
.camp-screen .cs-level { grid-area: level; display: grid; justify-items: center; align-content: center; width: calc(58px * var(--ts, 1)); height: calc(62px * var(--ts, 1)); background: linear-gradient(#4a3f2c, #231d14); clip-path: polygon(50% 0, 100% 22%, 100% 78%, 50% 100%, 0 78%, 0 22%); }
.camp-screen .cs-level small { font: 700 calc(10.5px * var(--ts, 1)) / 1 var(--body); color: #cbbf9f; }
.camp-screen .cs-level b { font: 700 calc(24px * var(--ts, 1)) / 1.05 var(--display); color: var(--brass); font-variant-numeric: lining-nums; }
.camp-screen .cs-bar { grid-area: bar; align-self: end; display: block; height: 10px; background: #14110d; box-shadow: inset 0 0 0 1px #6a6150; }
.camp-screen .cs-bar i { display: block; height: 100%; min-width: 2px; background: linear-gradient(var(--ember-hi), var(--ember-lo)); box-shadow: inset 0 0 0 1px #16140f; }
.camp-screen .cs-xp { grid-area: xp; align-self: start; font-size: calc(14px * var(--ts, 1)); color: #cfc6ae; font-variant-numeric: tabular-nums; }

/* ----- the body: the picture, and beside or under it what scrolls */
.camp-screen .cs-body { grid-area: body; min-width: 0; min-height: 0; display: grid; grid-template-columns: minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr); gap: 10px var(--gap); }
.camp-screen .cs-pic { position: relative; min-width: 0; min-height: 0; height: clamp(5.5rem, 19svh, 11rem); overflow: hidden; background: #14110d; --cut-l: 14px;
  clip-path: polygon(var(--cut-l) 0, calc(100% - var(--cut-l)) 0, 100% var(--cut-l), 100% calc(100% - var(--cut-l)), calc(100% - var(--cut-l)) 100%, var(--cut-l) 100%, 0 calc(100% - var(--cut-l)), 0 var(--cut-l)); }
.camp-screen .cs-pic::after { content: ""; position: absolute; inset: 0; pointer-events: none; box-shadow: inset 0 0 0 2px #4a4334, inset 0 0 0 4px #16140f; }
.camp-screen .cs-pane { position: absolute; inset: 0; overflow: hidden;
  background: radial-gradient(ellipse 74% 30% at 50% 72%, rgba(var(--glow), 0.5), transparent 72%), radial-gradient(ellipse 120% 60% at 50% 100%, #2a1a0e, transparent 75%), linear-gradient(#090806, #2a1a0e 62%, #0b0907); }
.camp-screen .cs-drawn { position: absolute; left: 50%; top: 46%; width: min(46%, 10rem); aspect-ratio: 1; transform: translate(-50%, -50%); color: #e09a3a; opacity: 0.55; }
.camp-screen .cs-pane.painted .cs-drawn { display: none; }
.camp-screen .cs-art { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; }
.camp-screen .cs-pane.painted .cs-art { opacity: 1; transition: opacity 0.45s ease; }
/* The fire's own light, low in the picture: it breathes, and is still for anyone who asked for less motion. */
.camp-screen .cs-light { position: absolute; inset: 0; opacity: 0.5; mix-blend-mode: screen; background: radial-gradient(ellipse 66% 30% at 50% 68%, rgba(var(--glow), 0.24), transparent 72%); animation: csEmber 4.4s ease-in-out infinite; }
@keyframes csEmber { 0%, 100% { opacity: 0.55; } 18% { opacity: 0.95; } 31% { opacity: 0.7; } 52% { opacity: 1; } 68% { opacity: 0.62; } 84% { opacity: 0.9; } }
@media (prefers-reduced-motion: reduce) { .camp-screen .cs-light { animation: none; } .camp-screen .cs-pane.painted .cs-art { transition: none; } }
.camp-screen.calm .cs-light { animation: none; }

.camp-screen .cs-main { min-width: 0; min-height: 0; display: flex; flex-direction: column; gap: 10px; }
.camp-screen .cs-scroll { overflow-y: auto; -webkit-overflow-scrolling: touch; touch-action: pan-y; scrollbar-width: none; padding-bottom: 6px; }
.camp-screen .cs-scroll::-webkit-scrollbar { display: none; }
.camp-screen .more-below { -webkit-mask-image: linear-gradient(#000 calc(100% - 44px), transparent); mask-image: linear-gradient(#000 calc(100% - 44px), transparent); }
.camp-screen .cs-more { grid-area: body; align-self: end; justify-self: start; z-index: 2; display: inline-flex; align-items: center; gap: 8px; min-height: 44px; margin: 0 0 4px; padding: 6px 18px 6px 12px; border: 0; cursor: pointer;
  font: 700 calc(15px * var(--ts, 1)) var(--body); color: var(--text); background: linear-gradient(#383327, #262219); clip-path: var(--cut);
  box-shadow: inset 0 0 0 2px #8a7550, inset 0 3px 0 rgba(255, 255, 255, 0.07), inset 0 -3px 0 rgba(0, 0, 0, 0.4); }
.camp-screen .cs-more .cs-glyph { color: var(--brass); stroke-width: 2.6; }
.camp-screen .cs-more:focus-visible { outline: 2px solid #f3ead2; outline-offset: -6px; }

/* What a press came to: a band with a mark on its left, in words. Nothing is there until something has happened. */
.camp-screen .cs-result { flex: none; display: none; gap: 6px; }
.camp-screen .cs-result.shown { display: grid; }
.camp-screen .cs-result p { padding: 9px 14px; border-left: 4px solid var(--ember); background: #231e15; font-size: calc(17px * var(--ts, 1)); line-height: 1.35; -webkit-user-select: text; user-select: text; }
.camp-screen .cs-result[data-tone=good] p { border-left-color: var(--brass); }
.camp-screen .cs-result[data-tone=bad] p:first-child { border-left-color: var(--blood); background: #2a1613; color: #f5cdc5; }
.camp-screen .cs-result p.more { border-left-color: var(--brass); font-weight: 700; color: var(--brass); }

/* A plate of things held, and the things on it as tiles: a drawn mark, how many in the display face, its name, and what it is good for. */
.camp-screen .cs-plate { flex: none; display: grid; gap: 8px; align-content: start; min-width: 0; padding: 12px 14px 14px; background: rgba(27, 24, 18, 0.94); clip-path: var(--cut); box-shadow: inset 0 0 0 1px var(--seam); }
.camp-screen .cs-tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 13.5rem), 1fr)); gap: 8px; }
.camp-screen .cs-tile { display: grid; gap: 2px; align-content: start; min-width: 0; padding: 10px 12px 11px; background: #1b1812; clip-path: var(--cut); box-shadow: inset 0 0 0 1px #4a4334; }
.camp-screen .cs-tile.next { background: linear-gradient(#2f2a1f, #231f17); box-shadow: inset 0 0 0 2px var(--brass); }
.camp-screen .cs-tile.none { opacity: 0.62; }
.camp-screen .cs-tile-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.camp-screen .cs-tile-icon { width: calc(34px * var(--ts, 1)); height: calc(34px * var(--ts, 1)); color: #cbbf9f; stroke-width: 1.6; }
.camp-screen .cs-tile.next .cs-tile-icon { color: var(--ember-hi); }
.camp-screen .cs-count { font: 700 calc(30px * var(--ts, 1)) / 1 var(--display); color: var(--text); font-variant-numeric: lining-nums tabular-nums; }
.camp-screen .cs-tile b { font-size: calc(17px * var(--ts, 1)); line-height: 1.25; color: var(--text); }
.camp-screen .cs-tile.next b { color: var(--brass); }
.camp-screen .cs-tile small { display: flex; gap: 6px; align-items: baseline; font-size: calc(14px * var(--ts, 1)); line-height: 1.3; color: #bdb49d; }
.camp-screen .cs-tile small .cs-glyph { align-self: center; width: 1.05em; height: 1.05em; }
.camp-screen .cs-tile small.risk { color: #f1b2a8; }
.camp-screen .cs-flag { display: inline-flex; align-items: center; gap: 6px; font: 700 calc(14px * var(--ts, 1)) / 1.2 var(--body); color: var(--ember-hi); }
.camp-screen .cs-flag .cs-glyph { width: 1.1em; height: 1.1em; }
.camp-screen .cs-row { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 12px; align-items: start; }
.camp-screen .cs-row-icon { width: calc(30px * var(--ts, 1)); height: calc(30px * var(--ts, 1)); margin-top: 2px; color: var(--ember-hi); stroke-width: 1.6; }
.camp-screen .cs-row b { color: var(--brass); font-size: calc(17px * var(--ts, 1)); }
.camp-screen .cs-row p { font-size: calc(15px * var(--ts, 1)); line-height: 1.35; }
.camp-screen .cs-fine { color: var(--muted); font-size: calc(14px * var(--ts, 1)); }
.camp-screen .cs-quiet { color: #bdb49d; font-size: calc(15px * var(--ts, 1)); line-height: 1.35; }
.camp-screen .cs-lede { max-width: 78ch; font-size: calc(16px * var(--ts, 1)); line-height: 1.4; color: #cfc6ae; text-wrap: pretty; }
.camp-screen .cs-caveat { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 10px; align-items: start; padding: 8px 12px; background: #2a1613; box-shadow: inset 0 0 0 1px #7a3b31; clip-path: var(--cut); font-size: calc(15px * var(--ts, 1)); line-height: 1.35; color: #f5cdc5; }
.camp-screen .cs-caveat .cs-glyph { margin-top: 1px; color: #f1b2a8; }
.camp-screen .cs-mark { display: inline-flex; align-items: center; gap: 6px; font: 700 calc(14px * var(--ts, 1)) / 1.2 var(--body); white-space: nowrap; color: #cfc6ae; }
.camp-screen .cs-mark.on { color: #b9d3c0; }
.camp-screen .cs-mark .cs-glyph { width: 1.05em; height: 1.05em; stroke-width: 2.6; }
/* Nothing held: a drawing of where it comes from, and one line that says how to get some. */
.camp-screen .cs-empty { display: grid; justify-items: center; gap: 8px; padding: 14px 10px 10px; text-align: center; }
.camp-screen .cs-empty-art { width: min(100%, 13rem); height: auto; aspect-ratio: 2; color: #8a7550; stroke-width: 1.6; }
.camp-screen .cs-empty p { max-width: 44ch; font-size: calc(17px * var(--ts, 1)); color: #dcd3bb; text-wrap: balance; }

/* A set of choices where one is chosen (how many): a hollow diamond that fills, a brass edge, and aria says which. */
.camp-screen .cs-qty { display: flex; flex-wrap: wrap; gap: 6px; }
.camp-screen .cs-choice { display: inline-flex; align-items: center; gap: 9px; min-height: 46px; min-width: 44px; margin: 0; padding: 6px 14px 6px 12px; border: 0; cursor: pointer; font: 700 calc(15px * var(--ts, 1)) var(--body); color: var(--text); background: #1b1812; clip-path: var(--cut); box-shadow: inset 0 0 0 1px #4a4334; }
.camp-screen .cs-choice.on { background: linear-gradient(#2f2a1f, #231f17); box-shadow: inset 0 0 0 2px var(--brass); color: var(--brass); }
.camp-screen .cs-choice.on .cs-diamond { background: var(--ember); box-shadow: inset 0 0 0 2px var(--brass); }
.camp-screen .cs-choice[disabled] { opacity: 0.45; cursor: default; }
.camp-screen .cs-choice:focus-visible { outline: 2px solid #f3ead2; outline-offset: -6px; }

/* ----- the foot: Leave at the left, then what this place does */
.camp-screen .cs-foot { grid-area: foot; position: relative; display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 6px 10px; align-items: end; min-width: 0;
  margin: 0 calc(-1 * (var(--pad) + var(--safe-r))) calc(-1 * (var(--pad) * 0.6 + var(--safe-b))) calc(-1 * (var(--pad) + var(--safe-l)));
  padding: 10px calc(var(--pad) + var(--safe-r)) calc(10px + var(--safe-b)) calc(var(--pad) + var(--safe-l)); background: #0f0d0a; box-shadow: 0 -1px 0 var(--seam); }
/* (lab.css has a .forged of its own on the rune card, a label: these are the front end's forged buttons) */
#cardBody .camp-screen .forged { font-size: calc(17px * var(--ts, 1)); font-weight: 700; color: var(--text); }
#cardBody .camp-screen .forged.primary { color: #1b1408; }
#cardBody .camp-screen .forged[disabled] { opacity: 0.45; cursor: default; }
.camp-screen #hBye { min-height: 56px; padding: 8px 16px; }
.camp-screen .cs-go { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 6px 10px; min-width: 0; }
.camp-screen .cs-go .forged { flex: 1 1 11rem; min-height: 56px; padding: 7px 14px; }
.camp-screen .cs-go .forged.primary { flex: 2 1 13rem; }
.camp-screen .cs-go .forged b { font-size: calc(clamp(18px, 1.2vw + 8px, 24px) * var(--ts, 1)); }
.camp-screen .cs-go .forged span { font: 700 calc(15px * var(--ts, 1)) / 1.2 var(--body); letter-spacing: 0.01em; opacity: 1; text-wrap: balance; }
.camp-screen .cs-go .cs-qty { flex: 1 1 100%; justify-content: flex-end; }
#cardBody .camp-screen .cs-note { flex: 1 1 100%; font-size: calc(13px * var(--ts, 1)); line-height: 1.3; color: var(--muted); text-align: right; text-wrap: balance; }
#cardBody .camp-screen .cs-note:empty { display: none; }
/* A button that spends gold: ember-edged and never the screen's main one. */
#cardBody .camp-screen .forged.pay { display: inline-flex; align-items: center; justify-content: center; gap: 10px; color: var(--ember-hi); box-shadow: inset 0 0 0 2px var(--ember), inset 0 3px 0 rgba(255, 255, 255, 0.07), inset 0 -4px 0 rgba(0, 0, 0, 0.45); }
#cardBody .camp-screen .forged.pay:focus-visible { box-shadow: inset 0 0 0 3px var(--brass), inset 0 0 0 5px #16140f; }

@media (max-width: 700px) and (orientation: portrait) {
  .camp-screen { gap: 8px var(--gap); }
  #cardBody .camp-screen .cs-title p { display: none; }
  .camp-screen .cs-skill { flex-basis: 100%; }
  .camp-screen .cs-level { width: calc(46px * var(--ts, 1)); height: calc(50px * var(--ts, 1)); }
  .camp-screen .cs-level b { font-size: calc(20px * var(--ts, 1)); }
  .camp-screen .cs-foot { padding-top: 8px; }
  #cardBody .camp-screen .cs-note { text-align: left; }
}
@media (orientation: landscape) and (max-height: 520px) {
  /* A phone on its side: the picture down the left, everything else scrolling on the right, the buttons along the foot. */
  .camp-screen { gap: 6px 12px; padding-top: calc(6px + var(--safe-t)); }
  #cardBody .camp-screen h1 { font-size: calc(19px * var(--ts, 1)); }
  #cardBody .camp-screen .cs-title p { display: none; }
  .camp-screen .cs-skill { flex: 0 1 19rem; }
  .camp-screen .cs-level { width: calc(40px * var(--ts, 1)); height: calc(42px * var(--ts, 1)); }
  .camp-screen .cs-level small { display: none; }
  .camp-screen .cs-level b { font-size: calc(19px * var(--ts, 1)); }
  .camp-screen .cs-meter { gap: 1px 10px; }
  .camp-screen .cs-xp { font-size: calc(13px * var(--ts, 1)); }
  .camp-screen .cs-body { grid-template-columns: minmax(0, 30%) minmax(0, 1fr); grid-template-rows: minmax(0, 1fr); }
  .camp-screen .cs-pic { height: auto; }
  .camp-screen .cs-foot { padding-top: 6px; padding-bottom: calc(6px + var(--safe-b)); align-items: center; }
  .camp-screen #hBye, .camp-screen .cs-go .forged { min-height: 46px; }
  .camp-screen .cs-go { flex-wrap: nowrap; }
  .camp-screen .cs-go .cs-qty { flex: 0 1 auto; flex-wrap: nowrap; }
  .camp-screen .cs-go .forged { flex: 0 1 auto; }
  .camp-screen .cs-go .forged.primary { flex: 1 1 12rem; max-width: 22rem; }
  #cardBody .camp-screen .cs-note { flex: 0 1 14rem; order: -1; text-align: left; }
  .camp-screen .cs-choice { min-height: 44px; }
}
@media (min-width: 900px) and (min-height: 521px) {
  /* A desk or a laptop: the picture fills the left from head to foot, the work is on the right. */
  .camp-screen { gap: 12px clamp(14px, 1.6vw, 30px); }
  .camp-screen .cs-body { grid-template-columns: minmax(0, 0.72fr) minmax(0, 1.6fr); grid-template-rows: minmax(0, 1fr); gap: 12px clamp(14px, 1.6vw, 30px); }
  .camp-screen .cs-pic { height: auto; }
  .camp-screen .cs-main { gap: 12px; }
  .camp-screen .cs-foot { grid-template-columns: auto minmax(0, 1fr); align-items: center; margin: 0; padding: 4px 0 0; background: none; box-shadow: none; }
  .camp-screen #hBye { min-height: 60px; padding: 8px 26px; background: rgba(22, 19, 14, 0.82); }
  .camp-screen .cs-go { flex-wrap: nowrap; }
  .camp-screen .cs-go .cs-qty { flex: 0 1 auto; flex-wrap: nowrap; }
  .camp-screen .cs-go .forged { flex: 0 1 15rem; min-height: 64px; }
  .camp-screen .cs-go .forged.primary { flex: 0 1 26rem; }
  #cardBody .camp-screen .cs-note { flex: 0 1 22rem; order: -1; }
}

/* ---------------- the drill yard (yard-screen.js) ----------------
   Who stands in the yard as three tall panels, each a window onto one picture of the yard, with the kind's mark in a
   seal, its name, and what it does in a bout. They show and are not pressed. Beside them the style in hand as a sheet
   of its skills, its rule, and three marked lines for what a bout is. */
.camp-screen .yd-group { min-width: 0; min-height: 0; display: grid; grid-template-rows: minmax(0, 1fr) auto; gap: 8px; }
.camp-screen .yd-panels { display: flex; align-items: stretch; justify-content: center; gap: var(--gap); min-width: 0; min-height: 0; height: min(calc(clamp(10rem, 28svh, 15rem) * var(--ts, 1)), 34svh); container: yard / size; }
.camp-screen .yd-panel { position: relative; flex: 1 1 0; min-width: 0; max-width: 30rem; overflow: hidden; display: grid; grid-template-rows: auto minmax(0, 1fr) auto; text-align: center; background: #14110d; --cut-l: 14px;
  clip-path: polygon(var(--cut-l) 0, calc(100% - var(--cut-l)) 0, 100% var(--cut-l), 100% calc(100% - var(--cut-l)), calc(100% - var(--cut-l)) 100%, var(--cut-l) 100%, 0 calc(100% - var(--cut-l)), 0 var(--cut-l)); }
.camp-screen .yd-panel::after { content: ""; position: absolute; inset: 0; pointer-events: none; box-shadow: inset 0 0 0 2px #8a7550, inset 0 0 0 4px #16140f; }
.camp-screen .yd-panel .cs-drawn { top: 40%; width: min(44%, 8rem); }
.camp-screen .yd-count { position: relative; grid-row: 1; padding: 14px 8px 20px; font: 600 calc(clamp(12px, 0.9vw + 5px, 17px) * var(--ts, 1)) / 1.1 var(--display); letter-spacing: 0.1em; color: #dcd3bb; text-shadow: 0 1px 0 #000; background: linear-gradient(rgba(11, 9, 7, 0.9), rgba(11, 9, 7, 0)); }
.camp-screen .yd-plate { position: relative; grid-row: 3; display: grid; justify-items: center; gap: 5px; min-width: 0; padding: 30px 12px 16px; background: linear-gradient(rgba(11, 9, 7, 0), rgba(11, 9, 7, 0.9) 38%, rgba(11, 9, 7, 0.97)); }
.camp-screen .yd-seal { --seal: calc(clamp(36px, 3.8vw, 60px) * var(--ts, 1)); display: grid; place-items: center; flex: none; width: var(--seal); height: calc(var(--seal) * 1.11); color: #e09a3a; background: linear-gradient(#4a3f2c, #231d14); clip-path: polygon(50% 0, 100% 24%, 100% 76%, 50% 100%, 0 76%, 0 24%); }
.camp-screen .yd-seal .cs-emblem { width: calc(var(--seal) * 0.62); height: calc(var(--seal) * 0.62); }
.camp-screen .yd-name { max-width: 100%; font: 600 calc(clamp(14px, 1vw + 7px, 25px) * var(--ts, 1)) / 1.15 var(--display); letter-spacing: 0.04em; color: var(--brass); text-shadow: 0 2px 0 #000; text-wrap: balance; overflow-wrap: anywhere; }
.camp-screen .yd-role { font-size: calc(15px * var(--ts, 1)); line-height: 1.3; font-weight: 700; color: #dcd3bb; text-wrap: balance; }
.camp-screen .yd-lore { font-size: calc(14px * var(--ts, 1)); line-height: 1.3; font-style: italic; color: #bdb49d; text-wrap: pretty; }
.camp-screen .yd-groupline { font-size: calc(15px * var(--ts, 1)); line-height: 1.35; color: #cfc6ae; text-wrap: pretty; }
.camp-screen .yd-roles { display: none; }
@container yard (max-width: 620px) {
  /* Narrow panels (a phone): the mark and the name stay; what each does is listed under the row. */
  .camp-screen .yd-role, .camp-screen .yd-lore { display: none; }
  .camp-screen .yd-count { padding: 10px 2px 8px; font-size: calc(11.5px * var(--ts, 1)); letter-spacing: 0.04em; }
  .camp-screen .yd-plate { padding: 18px 4px 10px; }
  .camp-screen .yd-seal { --seal: calc(32px * var(--ts, 1)); }
  .camp-screen .yd-panel { --cut-l: 10px; }
}
@container yard (max-height: 420px) { .camp-screen .yd-lore { display: none; } }
.camp-screen .yd-sheet { flex: none; display: grid; gap: 6px; }
#cardBody .camp-screen .yd-sheet h2 { font-size: calc(clamp(15px, 0.5vw + 10px, 19px) * var(--ts, 1)); }
.camp-screen .yd-skills { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 17rem), 1fr)); gap: 6px; }
.camp-screen .yd-skill { display: grid; gap: 2px; align-content: start; min-width: 0; padding: 6px 12px 7px; background: rgba(27, 24, 18, 0.94); clip-path: var(--cut); box-shadow: inset 0 0 0 1px var(--seam); }
.camp-screen .yd-skill-top { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 4px 10px; }
.camp-screen .yd-skill-top b { font: 600 calc(17px * var(--ts, 1)) / 1.2 var(--display); letter-spacing: 0.03em; color: var(--brass); }
.camp-screen .yd-key { display: inline-flex; align-items: center; gap: 4px; padding: 2px 8px; font: 700 calc(13px * var(--ts, 1)) / 1.4 var(--body); color: #dcd3bb; background: #14110d; box-shadow: inset 0 0 0 1px #6a6150; }
.camp-screen .yd-skill p { font-size: calc(14.5px * var(--ts, 1)); line-height: 1.25; color: #dcd3bb; }
.camp-screen .yd-skill .yd-strokes { font-style: italic; color: #bdb49d; }
.camp-screen .yd-skill dl { display: flex; flex-wrap: wrap; gap: 0 14px; font-size: calc(13.5px * var(--ts, 1)); line-height: 1.3; }
.camp-screen .yd-skill dl div { display: flex; gap: 5px; min-width: 0; }
.camp-screen .yd-skill dt { color: var(--muted); }
.camp-screen .yd-skill dd { color: #cfc6ae; }
.camp-screen .yd-rule { gap: 2px; padding: 8px 14px 9px; }
.camp-screen .yd-rule-top { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 4px 14px; }
.camp-screen .yd-rule p { font-size: calc(15px * var(--ts, 1)); line-height: 1.35; color: #cfc6ae; }
.camp-screen .yd-facts { flex: none; display: flex; flex-wrap: wrap; gap: 2px 20px; }
.camp-screen .yd-facts li { display: flex; align-items: center; gap: 8px; font-size: calc(15px * var(--ts, 1)); font-weight: 700; color: #dcd3bb; }
.camp-screen .yd-facts .cs-glyph { width: 1.05em; height: 1.05em; color: #b9d3c0; stroke-width: 3; }
/* The drill yard: one line about the combat controls setting (assist-plan.js), under the facts of a bout. */
.camp-screen .yd-controls { flex: none; margin: 6px 0 0; font-size: calc(14px * var(--ts, 1)); color: #cfc6ad; }
.camp-screen .yd-controls b { color: #f0c27a; }
@media (max-width: 899px) {
  #cardBody .camp-screen .yd-roles { display: grid; gap: 4px; font-size: calc(15px * var(--ts, 1)); line-height: 1.3; color: #cfc6ae; }
  .camp-screen .yd-roles b { color: var(--text); }
  .camp-screen .yd-groupline { display: none; }
}
@media (orientation: landscape) and (max-height: 520px) {
  .camp-screen[data-screen=yard] .cs-body { grid-template-columns: minmax(0, 42%) minmax(0, 1fr); }
  .camp-screen .yd-panels { height: auto; gap: 6px; }
}
@media (min-width: 900px) and (min-height: 521px) {
  .camp-screen[data-screen=yard] .cs-body { grid-template-columns: minmax(0, 1.3fr) minmax(22rem, 1fr); }
  .camp-screen .yd-panels { height: auto; }
}

/* ---------------- the coals (cook-screen.js) ----------------
   The raw fish, the larder and what goes down next as plates of tiles; how many to cook beside the one button. */
.camp-screen #ckMain { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 24rem), 1fr)); gap: 10px; align-items: start; }
.camp-screen #ckMain > .cs-plate:first-child { grid-column: 1 / -1; }

/* ---------------- the forge (forge-screen.js) ----------------
   Two stations as tabs: the wheel (ore by kind, and what a whetstone of each takes and does) and tempering (the
   hero's pieces down the left, the one looked at beside them as it is now and as it would be). */
.camp-screen .fg-tabs { flex: none; display: flex; gap: 6px; box-shadow: inset 0 -2px 0 var(--seam); }
.camp-screen .fg-tab { position: relative; flex: 0 1 15rem; min-height: 48px; margin: 0; padding: 8px 18px 10px; border: 0; cursor: pointer; font: 600 calc(17px * var(--ts, 1)) / 1.2 var(--display); letter-spacing: 0.05em; color: #cbbf9f; background: #1b1812;
  clip-path: polygon(8px 0, calc(100% - 8px) 0, 100% 8px, 100% 100%, 0 100%, 0 8px); box-shadow: inset 0 0 0 1px #4a4334; }
.camp-screen .fg-tab.on { color: var(--brass); background: linear-gradient(#2f2a1f, #231f17); box-shadow: inset 0 0 0 2px var(--brass), inset 0 -5px 0 var(--ember); }
.camp-screen .fg-tab:focus-visible { outline: 2px solid #f3ead2; outline-offset: -7px; }
.camp-screen .fg-panel { flex: 1 1 0; min-height: 0; display: flex; flex-direction: column; gap: 10px; container: forge / inline-size; outline: none; }
.camp-screen .fg-panel > * { flex: none; }
.camp-screen .fg-ore small.fg-held { margin-top: 4px; color: #dcd3bb; font-weight: 700; }
.camp-screen .fg-temper { display: grid; grid-template-columns: minmax(0, 1fr); gap: 10px; align-items: start; }
.camp-screen .fg-list { display: grid; gap: 6px; min-width: 0; }
.camp-screen .fg-gold, .camp-screen .fg-cost, .camp-screen .fg-need { display: flex; align-items: center; gap: 8px; font-size: calc(16px * var(--ts, 1)); font-weight: 700; color: #dcd3bb; font-variant-numeric: tabular-nums; }
.camp-screen .fg-gold .cs-glyph, .camp-screen .fg-cost .cs-glyph { color: var(--brass); }
.camp-screen .fg-need { font-weight: 500; }
.camp-screen .fg-need.warn { padding: 8px 12px; background: #2a1613; box-shadow: inset 0 0 0 1px #7a3b31; clip-path: var(--cut); color: #f5cdc5; font-weight: 700; }
.camp-screen .fg-pieces { display: grid; gap: 6px; }
.camp-screen .fg-piece { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 12px; align-items: center; width: 100%; min-height: 56px; margin: 0; padding: 8px 12px; border: 0; cursor: pointer; text-align: left; font: inherit; color: var(--text); background: #1b1812; clip-path: var(--cut); box-shadow: inset 0 0 0 1px #4a4334; }
.camp-screen .fg-piece.on { background: linear-gradient(#2f2a1f, #231f17); box-shadow: inset 0 0 0 2px var(--brass); }
.camp-screen .fg-piece.on .cs-diamond { background: var(--ember); box-shadow: inset 0 0 0 2px var(--brass); }
.camp-screen .fg-piece .cs-diamond { width: 13px; height: 13px; margin: 0 4px; }
.camp-screen .fg-piece:focus-visible { outline: 2px solid #f3ead2; outline-offset: -6px; }
.camp-screen .fg-icon { width: calc(40px * var(--ts, 1)); height: calc(40px * var(--ts, 1)); object-fit: contain; image-rendering: pixelated; }
.camp-screen .fg-icon.drawn { padding: 6px; color: #cbbf9f; stroke-width: 1.6; }
.camp-screen .fg-words { display: grid; gap: 1px; min-width: 0; }
.camp-screen .fg-words b { font-size: calc(16px * var(--ts, 1)); line-height: 1.25; }
.camp-screen .fg-piece.on .fg-words b { color: var(--brass); }
.camp-screen .fg-words small { display: flex; align-items: center; gap: 6px; font-size: calc(14px * var(--ts, 1)); line-height: 1.3; color: #bdb49d; }
.camp-screen .fg-words small .cs-glyph { width: 1em; height: 1em; stroke-width: 3; }
.camp-screen .fg-state.ok { color: #b9d3c0; font-weight: 700; }
/* A piece's rank as pips: one for Common up to four for Epic, beside the word. */
.camp-screen .fg-pips { display: inline-flex; flex: none; gap: 2px; }
.camp-screen .fg-pips i { width: 7px; height: 7px; transform: rotate(45deg); margin: 0 1px; box-shadow: inset 0 0 0 1px #6a6150; }
.camp-screen .fg-pips i.on { background: var(--pip, #bdb6a6); box-shadow: none; }
.camp-screen .fg-pips[data-rank=uncommon] { --pip: #6fbf73; }
.camp-screen .fg-pips[data-rank=rare] { --pip: #5b8fd9; }
.camp-screen .fg-pips[data-rank=epic] { --pip: #e6bf72; }
.camp-screen .fg-detail { gap: 8px; -webkit-user-select: text; user-select: text; }
#cardBody .camp-screen .fg-name { font: 600 calc(clamp(18px, 0.8vw + 11px, 24px) * var(--ts, 1)) / 1.2 var(--display); color: var(--brass); }
#cardBody .camp-screen .temper-pair { margin: 0; }
.camp-screen .item { border-radius: 0; border-color: #4a4334; background: #1b1812; font-size: calc(15px * var(--ts, 1)); }
#cardBody .camp-screen .item ul { margin: 6px 0 4px; padding-left: 18px; list-style: disc; }
#cardBody .camp-screen .temper-why { margin: 0; font-size: calc(16px * var(--ts, 1)); }
.camp-screen .diff { width: auto; margin: 0; font-size: calc(15px * var(--ts, 1)); }
.camp-screen .diff td { padding: 2px 18px 2px 0; }
@container forge (min-width: 52rem) {
  .camp-screen .fg-temper { grid-template-columns: minmax(17rem, 0.8fr) minmax(0, 1.3fr); }
}

/* ---------------- the contract board (board-screen.js) ----------------
   A corkboard in a wooden frame. The cork's grain is noise the browser draws (an inline SVG filter), the wood is two
   gradients, each notice is a paper slip under a drawn pin, turned a little (--tilt), with its title in the display
   face in ink. The one being read is lifted and says so; the one taken carries a stamp with the word. At a phone's
   width, and for anyone who asked for less motion, the slips sit straight in a column. Beside the board (under it on
   a phone) the notice being read, as a sheet. */
.camp-screen[data-screen=board] .cs-body { grid-template-columns: minmax(0, 1fr); grid-template-rows: minmax(0, 1fr); }
.camp-screen[data-screen=board] .cs-main { display: grid; grid-template-columns: minmax(0, 1fr); grid-auto-rows: max-content; gap: 12px; align-content: start; }
.camp-screen .bd-top { display: grid; gap: 6px; min-width: 0; }
.camp-screen .bd-top:not(:has(.shown, .bd-missed:not([hidden]))) { display: none; }
.camp-screen .bd-frame { min-width: 0; padding: clamp(8px, 1vw, 14px);
  background: repeating-linear-gradient(92deg, rgba(0, 0, 0, 0.16) 0 2px, transparent 2px 9px, rgba(255, 220, 160, 0.05) 9px 10px, transparent 10px 23px), linear-gradient(#5b3d22, #3d2814 55%, #4a301a);
  box-shadow: inset 0 0 0 2px #2a1b0e, inset 0 2px 0 3px rgba(255, 220, 160, 0.12); clip-path: var(--cut); }
.camp-screen .bd-board { position: relative; min-width: 0; height: 100%; background: radial-gradient(ellipse 90% 70% at 30% 20%, #a9814f, #8c6a40 60%, #775936); box-shadow: inset 0 0 0 2px #2a1b0e, inset 0 10px 18px rgba(0, 0, 0, 0.45), inset 0 -4px 10px rgba(0, 0, 0, 0.25); }
.camp-screen .bd-cork { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.camp-screen .bd-slips { position: relative; display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: center; gap: clamp(16px, 2.2vw, 34px) clamp(14px, 2vw, 34px); padding: clamp(20px, 2.6vw, 40px) clamp(12px, 2vw, 34px) clamp(18px, 2.2vw, 34px); }
.camp-screen .bd-slip { position: relative; flex: 1 1 14.5rem; max-width: 24rem; min-height: clamp(9rem, 30svh, 17rem); display: grid; gap: 8px; align-content: start; margin: 0; padding: 30px 18px 18px; border: 0; cursor: pointer; text-align: left; font: inherit; color: #2a2016;
  background: linear-gradient(175deg, #efe3c6, #dccba4 70%, #cdb98c); transform: rotate(var(--tilt, 0deg)); box-shadow: 0 1px 0 #f6eeda inset, 3px 5px 0 rgba(0, 0, 0, 0.38); }
.camp-screen .bd-slip:nth-child(even) { background: linear-gradient(183deg, #eadbb8, #d6c398 70%, #c6b184); margin-top: clamp(0px, 1.6vw, 22px); }
.camp-screen .bd-slip.on { transform: rotate(0deg) translateY(-6px); box-shadow: 0 0 0 3px #16140f, 0 0 0 6px var(--brass), 6px 12px 0 rgba(0, 0, 0, 0.4); z-index: 1; }
.camp-screen .bd-slip:focus-visible { outline: 3px solid #f3ead2; outline-offset: 7px; }
.camp-screen .bd-pin { position: absolute; left: 50%; top: -9px; width: 30px; height: 30px; transform: translateX(-50%); }
.camp-screen .bd-pin .shade { fill: rgba(0, 0, 0, 0.35); }
.camp-screen .bd-pin .head { fill: #b8432f; }
.camp-screen .bd-pin .rim { fill: none; stroke: #3d1410; stroke-width: 1.6; }
.camp-screen .bd-pin .shine { fill: none; stroke: #f3c9b9; stroke-width: 1.8; stroke-linecap: round; }
.camp-screen .bd-slip[data-pin="1"] .bd-pin .head { fill: #c9993f; }
.camp-screen .bd-slip[data-pin="1"] .bd-pin .rim { stroke: #4a3210; }
.camp-screen .bd-slip[data-pin="1"] .bd-pin .shine { stroke: #f8e6b8; }
.camp-screen .bd-slip[data-pin="2"] .bd-pin .head { fill: #6f7f72; }
.camp-screen .bd-slip[data-pin="2"] .bd-pin .rim { stroke: #1f2a22; }
.camp-screen .bd-slip[data-pin="2"] .bd-pin .shine { stroke: #d5e3d8; }
.camp-screen .bd-title { font: 700 calc(clamp(18px, 0.9vw + 11px, 26px) * var(--ts, 1)) / 1.15 var(--display); letter-spacing: 0.02em; color: #2a1c0e; text-wrap: balance; }
.camp-screen .bd-goal { font-size: calc(17px * var(--ts, 1)); line-height: 1.3; color: #33271a; text-wrap: pretty; }
.camp-screen .bd-pay { display: grid; gap: 3px; margin-top: auto; padding-top: 7px; border-top: 1px dashed #8a7550; }
.camp-screen .bd-pay > span { display: flex; align-items: center; gap: 7px; font-size: calc(15px * var(--ts, 1)); line-height: 1.25; font-weight: 700; color: #3a2a14; }
.camp-screen .bd-pay .cs-glyph { width: 1.1em; height: 1.1em; color: #7a4a10; stroke-width: 2.2; }
.camp-screen .bd-flag { display: flex; align-items: center; gap: 7px; font-size: calc(14px * var(--ts, 1)); line-height: 1.25; font-weight: 700; color: #7c2318; }
.camp-screen .bd-flag .cs-glyph { width: 1.1em; height: 1.1em; }
.camp-screen .bd-reading { display: inline-flex; align-items: center; gap: 7px; margin-top: 2px; font: 700 calc(13px * var(--ts, 1)) / 1.2 var(--body); color: #5a3a12; }
.camp-screen .bd-reading .cs-diamond { background: #a9651a; box-shadow: inset 0 0 0 2px #5a3a12; }
/* The stamp: struck across the corner in red ink, a double rule round the word. */
.camp-screen .bd-stamp { position: absolute; right: 8px; top: 12px; padding: 2px 9px 1px; font: 700 calc(15px * var(--ts, 1)) / 1.3 var(--display); letter-spacing: 0.16em; text-transform: uppercase; color: #8e2f22; border: 2px solid #8e2f22; outline: 1px solid #8e2f22; outline-offset: 2px; transform: rotate(-9deg); background: rgba(239, 227, 198, 0.82); }
.camp-screen .bd-slip.taken { padding-top: 50px; }
.camp-screen .bd-slip { grid-auto-rows: max-content; grid-template-rows: auto auto 1fr; }
.camp-screen .bd-detail { min-width: 0; display: grid; gap: 8px; align-content: start; }
.camp-screen .bd-sheet { position: relative; display: grid; gap: 8px; padding: 18px; color: #2a2016; background: linear-gradient(178deg, #efe3c6, #dccba4 75%, #cdb98c); box-shadow: 0 1px 0 #f6eeda inset, 4px 6px 0 rgba(0, 0, 0, 0.38); -webkit-user-select: text; user-select: text; }
#cardBody .camp-screen .bd-sheet h2 { font: 700 calc(clamp(20px, 1vw + 12px, 28px) * var(--ts, 1)) / 1.15 var(--display); color: #2a1c0e; text-wrap: balance; }
.camp-screen .bd-sheet.taken h2 { padding-right: 6.5rem; }
#cardBody .camp-screen .bd-sheet h3 { font: 700 calc(14px * var(--ts, 1)) / 1.2 var(--body); letter-spacing: 0; color: #5a4526; margin-top: 2px; }
.camp-screen .bd-ask { font-size: calc(18px * var(--ts, 1)); line-height: 1.35; color: #2a2016; }
.camp-screen .bd-facts { display: grid; gap: 5px; padding: 8px 0; border-top: 1px dashed #8a7550; border-bottom: 1px dashed #8a7550; }
.camp-screen .bd-facts li { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 9px; align-items: start; font-size: calc(15.5px * var(--ts, 1)); line-height: 1.3; color: #33271a; }
.camp-screen .bd-facts .cs-glyph { margin-top: 1px; color: #7a4a10; }
.camp-screen .bd-sheet .bd-pay { border-top: 0; padding-top: 0; margin-top: 0; }
@media (prefers-reduced-motion: reduce) { .camp-screen .bd-slip, .camp-screen .bd-slip.on { transform: none; } }
.camp-screen.calm .bd-slip, .camp-screen.calm .bd-slip.on { transform: none; }
@media (max-width: 700px) {
  .camp-screen .bd-slips { flex-direction: column; align-items: stretch; gap: 18px; }
  .camp-screen .bd-slip, .camp-screen .bd-slip.on { transform: none; max-width: none; min-height: 0; flex: none; margin-top: 0; }
}
@media (orientation: landscape) and (max-height: 520px) {
  .camp-screen[data-screen=board] .cs-main { grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); }
  .camp-screen .bd-top { grid-column: 1 / -1; }
  .camp-screen .bd-slip { min-height: 0; padding-bottom: 12px; }
}
@media (min-width: 900px) and (min-height: 521px) {
  .camp-screen[data-screen=board] .cs-main { grid-template-columns: minmax(0, 1.75fr) minmax(19rem, 1fr); grid-template-rows: auto minmax(0, 1fr); gap: 12px clamp(14px, 1.6vw, 30px); overflow: visible; padding-bottom: 0; }
  .camp-screen .bd-top { grid-column: 1 / -1; }
  .camp-screen .bd-frame { grid-column: 1; grid-row: 2; }
  .camp-screen .bd-board { display: grid; align-content: center; container: board / inline-size; }
  /* (on a big board the notices are big: their words grow with the cork) */
  .camp-screen .bd-slip { flex: 1 1 26%; max-width: 31%; min-height: clamp(9rem, 34svh, 24rem); padding: clamp(28px, 3.2cqw, 44px) clamp(14px, 2cqw, 28px) clamp(14px, 2cqw, 26px); }
  .camp-screen .bd-slip.taken { padding-top: clamp(50px, 5cqw, 66px); }
  .camp-screen .bd-slips[data-count="4"] .bd-slip { flex-basis: 20%; max-width: 23.5%; padding-left: clamp(12px, 1.4cqw, 22px); padding-right: clamp(12px, 1.4cqw, 22px); }
  .camp-screen .bd-slips[data-count="4"] { gap: clamp(12px, 1.6cqw, 26px) clamp(10px, 1.2cqw, 20px); padding-left: clamp(10px, 1.2cqw, 22px); padding-right: clamp(10px, 1.2cqw, 22px); }
  .camp-screen .bd-slips[data-count="4"] .bd-title { font-size: calc(clamp(16px, 1.9cqw, 27px) * var(--ts, 1)); }
  .camp-screen .bd-title { font-size: calc(clamp(18px, 2.3cqw, 31px) * var(--ts, 1)); }
  .camp-screen .bd-goal { font-size: calc(clamp(16px, 1.65cqw, 22px) * var(--ts, 1)); }
  .camp-screen .bd-slip .bd-pay > span, .camp-screen .bd-flag { font-size: calc(clamp(14px, 1.4cqw, 19px) * var(--ts, 1)); }
  .camp-screen .bd-detail { grid-column: 2; grid-row: 2; min-height: 0; overflow-y: auto; scrollbar-width: none; padding: 4px 8px 12px 2px; }
  .camp-screen .bd-detail::-webkit-scrollbar { display: none; }
}

/* Cards and sheets scroll by touch, wheel and keys; the pale bar is hidden here too (owner: it is bad on the dark page). */
.center-card, .sheet, .screen.run { scrollbar-width: none; -ms-overflow-style: none; }
.center-card::-webkit-scrollbar, .sheet::-webkit-scrollbar, .screen.run::-webkit-scrollbar { display: none; }
/* ---------------- Lastheat: names over things, the small map and the full map (hall-map.js) ---------------- */
/* The hall names its people and things on plates of its own, so the plain actor labels are not drawn there. */
body.in-hall #labels > .label3d { display: none !important; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
/* A plate: dark behind pale text with a hairline, so it reads over a firelit floor as well as over the dark. */
.plate3d {
  position: absolute; transform: translate(-50%, -100%); display: none; white-space: nowrap; pointer-events: none;
  padding: 2px 8px 3px; font: 600 calc(13px * var(--ts, 1)) / 1.25 var(--body); letter-spacing: 0.02em; color: #f3ead2;
  background: rgba(15, 13, 10, 0.9); box-shadow: inset 0 0 0 1px #6b5a36, 0 1px 3px rgba(0, 0, 0, 0.7);
}
.plate3d.person { color: var(--brass); }
.plate3d.on { color: #fff3cf; background: rgba(15, 13, 10, 0.96); box-shadow: inset 0 0 0 2px var(--brass), 0 1px 4px rgba(0, 0, 0, 0.8); font-weight: 700; }
.plate3d .pl-new, .hm-tag .pl-new { display: inline-block; width: 0.62em; height: 0.62em; margin-right: 5px; vertical-align: 0.02em; fill: var(--ember-hi); stroke: #1b1408; stroke-width: 1; }
body.talking .plate3d { display: none !important; }

/* The small map: top right, under the menu button. A button: a press opens the full map. */
.hall-mini {
  position: absolute; right: calc(12px + var(--safe-r)); top: calc(66px + var(--safe-t)); padding: 0; border: 0; border-radius: 0; cursor: pointer; pointer-events: auto;
  background: rgba(15, 13, 10, 0.82); box-shadow: inset 0 0 0 1px #5a4d33, 0 2px 6px rgba(0, 0, 0, 0.5); color: var(--text); line-height: 0;
}
.hall-mini[hidden] { display: none; }
.hall-mini:focus-visible { outline: none; box-shadow: inset 0 0 0 2px var(--brass), 0 2px 6px rgba(0, 0, 0, 0.5); }
body:not(.in-hall) .hall-mini { display: none; }
.hall-map-svg { display: block; max-width: 100%; height: auto; }
.hall-map-svg .hm-floor polygon { fill: #4a4233; stroke: #4a4233; stroke-width: 0.6; stroke-linejoin: round; }
.hall-map-svg .hm-well { fill: #1d1a14; }
.hall-map-svg .hm-step { stroke: #6f6450; stroke-width: 1; }
.hall-map-svg .hm-wall { stroke: #8a7c5f; stroke-width: 1; stroke-linecap: square; }
.hall-map-svg .hm-wall.far { stroke: #d6c8a4; stroke-width: 1.6; }
.hall-map-svg.full .hm-wall { stroke-width: 1.4; }
.hall-map-svg.full .hm-wall.far { stroke-width: 2.6; }
.hall-map-svg .hm-rail { stroke: #d6c8a4; stroke-width: 1.2; stroke-dasharray: 3 2.5; }
.hall-map-svg .hm-path { fill: none; stroke: #f0c27a; stroke-width: 1.6; stroke-dasharray: 4 3; stroke-linecap: round; stroke-linejoin: round; }
.hall-map-svg .hm-plate { fill: #16130e; stroke: #cdbd96; stroke-width: 1; }
.hall-map-svg .hm-place.person .hm-plate { stroke: var(--brass); }
.hall-map-svg .hm-dot { fill: #f3ead2; stroke: #16130e; stroke-width: 1; }
.hall-map-svg .hm-place.person .hm-dot { fill: var(--brass); }
.hall-map-svg .hm-glyph { fill: none; stroke: #f3ead2; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.hall-map-svg .hm-place.person .hm-glyph { stroke: var(--brass); }
.hall-map-svg .hm-new { fill: var(--ember-hi); stroke: #1b1408; stroke-width: 1; }
.hall-map-svg .hm-sel { fill: none; stroke: #fff3cf; stroke-width: 2; }
.hall-map-svg .hm-dest { fill: none; stroke: #f0c27a; stroke-width: 1.6; }
.hall-map-svg .hm-dest.two { stroke-width: 1; transform-box: fill-box; transform-origin: center; animation: hm-pulse 1.4s ease-out infinite; }
@keyframes hm-pulse { from { transform: scale(0.8); opacity: 1; } to { transform: scale(1.25); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .hall-map-svg .hm-dest.two { animation: none; } }
.hall-map-svg .hm-hero path { fill: #fff3cf; stroke: #16130e; stroke-width: 1.4; stroke-linejoin: round; }
.hall-map-svg .hm-room { fill: #b9ad90; font-family: var(--body); font-weight: 600; letter-spacing: 0.08em; text-anchor: middle; }
.hall-map-svg .hm-name rect { fill: rgba(15, 13, 10, 0.92); stroke: #6b5a36; stroke-width: 1; }
.hall-map-svg .hm-name text { fill: #f3ead2; font-family: var(--body); font-weight: 600; text-anchor: middle; }
.hall-map-svg .hm-name.on rect { stroke: var(--brass); stroke-width: 2; }
.hall-map-svg.full .hm-place { cursor: pointer; }

/* The full map: the page's card in a wider shape, the drawing first, then what the chosen place is for, then every place as a button. */
#card[data-kind=map] { width: min(900px, calc(100vw - 16px)); max-height: calc(100dvh - 16px); text-align: left; }
#card[data-kind=map] .card-art { display: none; }
#card[data-kind=map] #cardBody { display: block; padding: 14px 16px 16px; }
.hall-map h2 { margin: 2px 0 8px; }
.hall-map [hidden] { display: none !important; }
.hall-map .hm-frame { display: grid; justify-items: center; background: #14110d; box-shadow: inset 0 0 0 1px var(--seam); overflow: hidden; }
.hall-map .hm-about { min-height: calc(2.7em * var(--ts, 1)); margin: 10px 0 8px; font-size: calc(17px * var(--ts, 1)); line-height: 1.35; }
.hall-map .hm-about b { color: var(--brass); font-weight: 600; }
.hall-map .hm-acts { justify-content: flex-start; flex-wrap: wrap; }
.hall-map .hm-head { margin: 14px 0 6px; font: 700 calc(13px * var(--ts, 1)) var(--body); letter-spacing: 0.16em; text-transform: uppercase; color: var(--ember-hi); }
.hall-map .hm-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 210px), 1fr)); gap: 6px; }
.hall-map .hm-row {
  display: flex; align-items: center; gap: 8px; min-height: 44px; padding: 6px 10px; border: 0; border-radius: 0; cursor: pointer; text-align: left;
  font: 600 calc(16px * var(--ts, 1)) / 1.2 var(--body); color: var(--text); background: #1c1913; box-shadow: inset 0 0 0 1px var(--seam);
}
.hall-map .hm-row span { flex: 1; }
.hall-map .hm-row.on { box-shadow: inset 0 0 0 2px var(--brass); background: #262117; }
.hall-map .hm-row:focus-visible { outline: none; box-shadow: inset 0 0 0 3px var(--brass); }
.hall-map .hm-icon { flex: none; width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.hall-map .hm-tag { flex: none; padding: 2px 6px; font: 700 calc(12px * var(--ts, 1)) var(--body); letter-spacing: 0.06em; text-transform: uppercase; color: #f3ead2; box-shadow: inset 0 0 0 1px #6b5a36; }
.hall-map .hm-tag.go { color: #1b1408; background: var(--ember-hi); box-shadow: none; }
.hall-map .hm-keys { margin: 12px 0 0; font-size: calc(14px * var(--ts, 1)); }
/* (what the keys do is said only where there are keys: .by-key, at the foot of this file) */

/* ---------------- Phone polish: one face, and the pieces that met on a small screen ---------------- */
/* The HUD, the cards, the notices and the pause screen were set in the system's own font while the title, the menu and
   the camp screens were in the game's two faces. Everything now reads in the same two. */
html, body { font-family: var(--body); font-size: 16px; }
.panel h1, .sheet h2, #cardBody h2, .screen.run h1, .screen.run h2 { font-family: var(--display); font-weight: 600; letter-spacing: 0.03em; }
/* What is typed is in the same face as what is read. */
.sheet input, .sheet textarea, .sheet select, .bench select { font-family: var(--body); font-size: calc(16px * var(--ts, 1)); }
#paused { background: rgba(11, 10, 8, 0.96); }
#paused .panel h1 { color: var(--brass); }
#paused .panel .sub { font-size: calc(17px * var(--ts, 1)); }
#paused .big:focus-visible, #gate .big:focus-visible { outline: 3px solid var(--brass); outline-offset: 3px; }

/* Words for one kind of input: a sentence about keys is shown where there are keys, one about tapping where there are none. */
.by-touch { display: none; }
@media (hover: none), (pointer: coarse) { .by-touch { display: inline; } .by-key { display: none; } }

/* A tip in a descent: on a narrow column its words take a row of their own and its two buttons share the next, so
   neither button breaks into a word a line. */
#hudStack #tip { flex-wrap: wrap; }
#hudStack #tip #tipText { flex: 1 1 12rem; min-width: 0; }
@media (max-width: 560px) { #hudStack #tip #tipText { flex-basis: 100%; } }
#hudStack #tip button { flex: 0 0 auto; min-height: 44px; white-space: nowrap; }
/* What was picked up: the words give way, the button keeps its size inside the frame. */
#hudStack #pickup #pickupText { flex: 1 1 auto; min-width: 0; }
#hudStack #pickup button { flex: none; min-height: 44px; }
/* The column under the top left corner stops short of the menu button, with a gap between them. */
@media (max-width: 899px) { #hudStack { width: min(440px, calc(100vw - 32px - 80px - var(--safe-l) - var(--safe-r))); } }
/* The line that says what the chamber asks: on a phone held upright it may take a third line before it is cut. */
@media (max-width: 560px) and (orientation: portrait) { #hudStack #objective { -webkit-line-clamp: 3; } }

/* The new version notice. On a phone held upright the title's menu fills the foot of the screen, so the notice sits under
   the game's name there. It is said at the title and in the hall only: making a hero, a conversation and a cinematic
   are not interrupted by it. */
@media (max-width: 700px) and (orientation: portrait) { #front.title:not([hidden]) ~ #updateNote { top: calc(128px * var(--ts, 1) + var(--safe-t)); bottom: auto; } }
#front:not([hidden]):not(.title) ~ #updateNote, #talk:not([hidden]) ~ #updateNote, #cine:not([hidden]) ~ #updateNote { display: none; }
/* A phone held upright: what someone says in the hall is set beside the small map, not under it (its Dismiss was
   beneath the map and could not be pressed), and the notice sits at the foot, above the button that names what is in
   reach, so it never lies across those words. */
@media (max-width: 700px) and (orientation: portrait) {
  body.in-hall:has(#hallMini:not([hidden])) #hudStack > .bark { width: calc(100vw - 32px - min(160px, 30vw) - var(--safe-l) - var(--safe-r)); grid-template-columns: 44px minmax(0, 1fr) 44px; gap: 6px; }
  body.in-hall:has(#hallMini:not([hidden])) #hudStack > .bark .bark-face { width: 44px; height: 50px; }
  #updateNote { top: auto; bottom: calc(160px + var(--safe-b)); }
}
/* A phone on its side is too short for the notice to sit under the small map: there it would cover the hero. It sits at
   the foot of the hall instead, under the button that names what is in reach, between the two thumbs. */
@media (orientation: landscape) and (max-height: 520px) { #updateNote { top: auto; bottom: calc(8px + var(--safe-b)); } }

/* What someone said, kept on the hero's page until it is dismissed: its button is tall enough to press. */
#dismissNotices { min-height: 44px; }
/* Links in the menu's small print (Privacy, Terms): a line tall enough to press. */
#campMain p a { display: inline-block; padding: 13px 6px; margin: 0 -6px; }

/* The way below on a narrow row: a place that is shut keeps its lock, its name and the word Locked down its spine. The
   sentence that says what opens it is not set sideways: pressing the place says it in full under the row. */
@container stages (max-width: 640px) {
  .descent .ds-stage:not([aria-checked=true]) .ds-needs { display: none; }
  .descent .ds-stage:not([aria-checked=true]) .ds-mark.locked::after { content: none; }
}
/* How to skip a cinematic: small, but it has to be readable on the dark bar. */
.cine-skip { font-size: calc(13px * var(--ts, 1)); color: #a59c86; }

/* A screen over the whole page (loading, paused, the end of a descent) keeps clear of a notch and the home bar. */
.screen { padding: calc(16px + var(--safe-t)) calc(16px + var(--safe-r)) calc(16px + var(--safe-b)) calc(16px + var(--safe-l)); }
/* A card and a sheet do too: a tall one (the map of the camp, a comparison with every stat open) stops short of them. */
.center-card { max-width: calc(100vw - 32px - var(--safe-l) - var(--safe-r)); max-height: calc(100dvh - 32px - var(--safe-t) - var(--safe-b)); }
#card[data-kind=map] { max-width: calc(100vw - 16px - var(--safe-l) - var(--safe-r)); max-height: calc(100dvh - 16px - var(--safe-t) - var(--safe-b)); }
/* (the camp's screens and the way below fill the page and pad themselves) */
#card[data-kind=camp], #card[data-kind=descent] { max-width: none; max-height: none; }
/* A card's own button, held at its foot: in the middle of the card, not at its left edge. */
#cardBody > .chips:last-child { justify-content: center; }
.sheet { max-height: calc(100% - 20px - var(--safe-t) - var(--safe-b)); }

/* The end of a descent (expedition.js finish). The fight's HUD does not show through its words; what someone at the
   forge says has their name on a line of its own (the HUD's own .bark is a three-column strip, and is not this); and
   the buttons sit in the middle, the main one first. */
.screen.run { background: rgba(11, 10, 8, 0.96); }
.screen.run .panel { font-size: calc(17px * var(--ts, 1)); line-height: 1.4; }
.screen.run .panel h1 { margin-bottom: 10px; color: var(--brass); text-wrap: balance; }
.story-end p.bark { display: block; width: auto; padding: 10px 12px; pointer-events: auto; }
.story-end p.bark > b { display: block; margin-bottom: 2px; font: 700 calc(14px * var(--ts, 1)) / 1.2 var(--display); letter-spacing: 0.06em; color: var(--brass); }
.screen.run .panel > .chips { justify-content: center; margin-top: 14px; }
.screen.run .panel > .chips > .big { flex: 1 1 220px; max-width: 360px; margin-top: 0; }
.screen.run .panel > p:has(> .chip) { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; }
.screen.run .big:focus-visible, .screen.run .chip:focus-visible { outline: 3px solid var(--brass); outline-offset: 2px; }

/* ---------------- Phone follow-ups ---------------- */
/* The Map button (hall-map.js): where the small map was while that is turned off, under the menu button, so a hand with
   no M key can still open the map of the camp. A word on a plate, as tall and wide as a thumb needs. */
.hall-map-btn {
  position: absolute; right: calc(12px + var(--safe-r)); top: calc(66px + var(--safe-t)); min-width: 48px; min-height: 44px; padding: 0 12px; border: 0; border-radius: 0; cursor: pointer; pointer-events: auto;
  font: 700 calc(15px * var(--ts, 1)) / 1 var(--body); letter-spacing: 0.04em; color: var(--text); background: rgba(22, 19, 14, 0.92); box-shadow: inset 0 0 0 1px #6b5a36, 0 2px 6px rgba(0, 0, 0, 0.5);
}
.hall-map-btn[hidden], body:not(.in-hall) .hall-map-btn, body.talking .hall-map-btn { display: none; }
.hall-map-btn:focus-visible { outline: none; box-shadow: inset 0 0 0 3px var(--brass), 0 2px 6px rgba(0, 0, 0, 0.5); }

/* Making a hero on a phone (either way up): the choices, one line about the chosen one, then Appearance, then the long
   text about that origin. Appearance was under the long text and easy to miss. Wider screens keep the columns they
   had, where the line is not needed (the panel is beside the choices). */
.front .origin-brief { display: none; margin: 0; padding: 0 2px; font-size: calc(16px * var(--ts, 1)); line-height: 1.35; color: var(--text); }
@media (max-width: 639px), (orientation: landscape) and (max-height: 520px) {
  .front .origin-brief { display: block; order: 2; margin-top: -4px; } .front .looks { order: 3; } .front .origin-panel { order: 4; }
}

/* The tester's notes sheet: the line that opens the optional fields and the fields themselves are tall enough to press.
   So is the line that opens the time by chamber at the end of a descent. */
#sheetBody details > summary, .screen.run details > summary { padding: 11px 0; cursor: pointer; }
.screen.run details > summary:focus-visible { outline: 3px solid var(--brass); outline-offset: 2px; }
/* The summary's first column: where there is room, a row's name stays on one line. */
@media (min-width: 600px) { .screen.run .summary:not(.rooms) td:first-child { white-space: nowrap; } }
#sheetBody input:not([type=checkbox]):not([type=radio]) { min-height: 44px; box-sizing: border-box; }

/* Safe chambers: the stall's offers and an event's choices, on the centred card (safe-rooms.js). */
#cardBody .stall-gold, #cardBody .event-purse { font: 700 15px var(--body); color: var(--muted); }
#cardBody .stall-gold b, #cardBody .event-purse b { color: var(--brass); font-variant-numeric: tabular-nums; }
#cardBody .stall-offers { display: grid; gap: 10px; }
#cardBody .stall-offer { display: grid; gap: 8px; padding: 10px 12px; text-align: left; background: #1b1812; box-shadow: inset 0 0 0 1px var(--seam); }
#cardBody .stall-offer .item { border: none; padding: 0; background: none; }
#cardBody .stall-offer details { font-size: calc(13px * var(--ts, 1)); }
#cardBody .stall-offer .wide { width: 100%; min-height: 48px; font-size: calc(16px * var(--ts, 1)); }
#cardBody .stall-offer button[disabled] { opacity: 0.45; cursor: default; }
#cardBody .stall-offer.is-sold { opacity: 0.6; }
#cardBody .stall-name { font: 700 17px var(--body); color: var(--brass); }
#cardBody .stall-sold { font: 700 13px var(--body); letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted); }
#cardBody .event-choices { display: grid; gap: 8px; }
#cardBody .event-choice { display: grid; gap: 4px; width: 100%; min-height: 56px; padding: 10px 14px; text-align: left; background: #1b1812; border: 0; box-shadow: inset 0 0 0 1px var(--seam); color: inherit; font: 16px/1.3 var(--body); cursor: pointer; }
#cardBody .event-choice b { color: var(--brass); }
#cardBody .event-choice span { color: var(--muted); font-size: calc(14px * var(--ts, 1)); }
#cardBody .event-choice span.warn { color: #f1b2a8; }
#cardBody .event-choice[disabled] { opacity: 0.5; cursor: default; }
#cardBody .event-choice:focus-visible { box-shadow: inset 0 0 0 2px var(--brass); }
