/* The Fellowship of the Quest: crawler prototype. Plain CSS, no build. */
/* Text font for the whole game: the IBM VGA 8x16 ROM font (Oldschool PC Font Pack v2.2, CC BY-SA 4.0; see
   assets/fonts/LICENSE-oldschool-pc-font-pack.txt). A bitmap font: every size below is 16px (1x) or 32px (2x),
   line-height 1 (16/32px) or 1.25 (20px) so each glyph pixel lands on a device pixel. Single weight (400);
   there is no bold or italic, so synthesis is off. No letter-spacing, no transform scaling. */
@font-face {
  font-family: "IBM VGA 8x16";
  src: url(assets/fonts/WebPlus_IBM_VGA_8x16.woff) format("woff");
  font-weight: 400; font-style: normal; font-display: block;
}
:root {
  --black: #0a090c; --void: #16141c;
  --s0: #2a2731; --s1: #423e4a; --s2: #5e5966; --s3: #7f7984; --s4: #a59e9d; --s5: #cdc4b4;
  --amber: #c4741f; --flame: #f2ae3c; --core: #fde9a2;
  --parch: #e8d6a4; --parchd: #b89862; --ink: #2a1c10;
  --navy: #1f2a5e; --navyl: #3b5098; --yellow: #e2b33a; --yellowd: #a87c1c;
  --green: #2d5f31; --greenl: #5f9445; --red: #b3362c;
  --pixel: "IBM VGA 8x16", ui-monospace, Menlo, Consolas, monospace;   /* chrome and body share one font, like a 1991 DOS game */
  --mono: "IBM VGA 8x16", ui-monospace, Menlo, Consolas, monospace;
  --serif: "Libre Baskerville", Georgia, "Times New Roman", serif;
  --sys: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  color-scheme: dark;
}
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
html { -webkit-text-size-adjust: 100%; }
body {
  background: var(--black); color: var(--s5);
  font: 16px/1.25 var(--mono);
  overflow-x: hidden; min-height: 100vh;
}
[hidden] { display: none !important; }
button { font: inherit; color: inherit; cursor: pointer; }
img { max-width: 100%; }
.sr-only {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
:focus-visible { outline: 3px solid var(--flame); outline-offset: 2px; }
.screen { min-height: 100vh; min-height: 100dvh; }

/* ------------------------------------------------------------ shared chrome */
.bevel, .btn-chunky, .viewport-frame, .log-frame, .party-card, .dlg-frame, .sheet {
  /* stepped stone bevel: light top-left, dark bottom-right */
  box-shadow:
    inset 2px 2px 0 var(--s3), inset -2px -2px 0 var(--black),
    inset 4px 4px 0 var(--s2), inset -4px -4px 0 var(--s0);
}
.btn-chunky {
  font-family: var(--pixel); font-size: 16px; line-height: 1; letter-spacing: 0;
  background: var(--s1) url(assets/ui-stone.png) repeat; background-size: 128px;
  image-rendering: pixelated;
  color: var(--core); border: 2px solid var(--black);
  padding: 12px 14px; min-height: 44px; text-transform: uppercase;
  text-shadow: 2px 2px 0 var(--black);
}
.btn-chunky:hover { color: #fff; }
.btn-chunky:active, .btn-chunky[aria-pressed="true"] {
  box-shadow: inset 2px 2px 0 var(--black), inset -2px -2px 0 var(--s3), inset 4px 4px 0 var(--s0);
}
.btn-chunky.primary { background: var(--navy); color: var(--yellow); }
.btn-chunky.sm { padding: 8px 10px; min-height: 36px; font-size: 16px; }

/* Plain, high-contrast, never animated. Booking and schedule live here. */
.btn-plain {
  font: 400 16px/1 var(--mono);
  background: var(--parch); color: var(--black);
  border: 3px solid var(--black); outline: 2px solid var(--parch);
  padding: 12px 16px; min-height: 48px; text-align: center;
  animation: none !important; transition: none !important;
}
.btn-plain:hover { background: #fff; }
.btn-plain.sm { font-size: 16px; padding: 8px 10px; min-height: 40px; outline-width: 1px; }

/* ------------------------------------------------------------ title screen */
.title { position: relative; overflow: hidden; display: grid; place-items: center; padding: 24px 16px 32px; }
.title-bg { position: absolute; inset: 0; width: 100%; height: 100%; image-rendering: pixelated; }
.title-vignette {
  position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(ellipse at center, transparent 55%, rgba(0,0,0,.75) 100%);
}
.title-inner { position: relative; z-index: 1; width: 100%; max-width: 560px; display: flex; flex-direction: column; align-items: center; gap: 18px; text-align: center; }
.title-stage { display: flex; align-items: center; justify-content: center; gap: 12px; }
.torch {
  width: 32px; height: 80px; flex: none;
  background: url(assets/torch.png) 0 0 / 128px 80px no-repeat; image-rendering: pixelated;
  animation: torch .5s steps(4) infinite;
}
@keyframes torch { to { background-position: -128px 0; } }
.plaque {
  background: var(--parch) url(assets/parchment.png) repeat; background-size: 128px; image-rendering: pixelated;
  padding: 14px 16px; border: 4px solid var(--black);
  box-shadow:
    0 0 0 4px var(--yellowd), 0 0 0 8px var(--black),
    inset 3px 3px 0 #f6ebc8, inset -3px -3px 0 var(--parchd),
    0 0 60px 10px rgba(242, 174, 60, .25);
}
.logo-pixel { display: block; width: 210px; height: auto; image-rendering: pixelated; }
@media (min-width: 700px) { .logo-pixel { width: 315px; } .torch { width: 40px; height: 100px; background-size: 160px 100px; } @keyframes torch { to { background-position: -160px 0; } } }
.title-tag { font: 400 16px/1.25 var(--mono); color: var(--parch); margin: 0; text-shadow: 2px 2px 0 var(--black); max-width: 32em; }
.title-menu { display: flex; flex-direction: column; gap: 6px; align-items: stretch; min-width: 240px; }
.menu-item {
  font: 400 32px/1 var(--pixel); background: none; border: 0; color: var(--parch);
  padding: 12px 12px 12px 40px; text-align: left; position: relative; text-shadow: 3px 3px 0 var(--black);
}
.menu-item::before { content: ""; position: absolute; left: 8px; top: 12px; }
.menu-item.on, .menu-item:hover, .menu-item:focus-visible { color: var(--flame); outline: none; }
.menu-item.on::before { content: ">"; color: var(--flame); animation: blink-cur 1s steps(2) infinite; }
@keyframes blink-cur { 50% { opacity: 0; } }
.plain-buttons { display: flex; flex-direction: column; gap: 12px; width: 100%; max-width: 380px; }
.link-small { background: none; border: 0; color: var(--s5); text-decoration: underline; font: 16px/1 var(--mono); padding: 12px 8px; }
.link-small:hover { color: #fff; }
.copyright { font: 16px/1.25 var(--pixel); color: var(--s3); margin: 0; }

/* ------------------------------------------------------------ character creation */
.create { padding: 16px 16px 100px; background: var(--void); }
.create-inner { max-width: 1180px; margin: 0 auto; }
.create-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px; }
.create-head h1 { font: 400 32px/1 var(--pixel); color: var(--yellow); margin: 8px 0; text-shadow: 3px 3px 0 var(--black); }
.dice { display: flex; gap: 6px; }
.die {
  width: 34px; height: 34px; display: grid; place-items: center;
  background: var(--bone, #efe6cf); color: var(--black); font: 16px/1 var(--pixel);
  border: 2px solid var(--black); box-shadow: inset -3px -3px 0 var(--s4);
}
.dice.rolling .die { animation: tumble .12s steps(2) infinite; }
.dice.rolling .die:nth-child(2) { animation-delay: -.05s; }
.dice.rolling .die:nth-child(3) { animation-delay: -.08s; }
@keyframes tumble { 0% { transform: rotate(-20deg) translateY(-4px); } 100% { transform: rotate(25deg) translateY(3px); } }
.create-dm { font: 16px/1.25 var(--mono); color: var(--core); background: var(--black); border: 2px solid var(--s1); padding: 10px 12px; min-height: 60px; }
.who { color: var(--flame); }
.sheets { display: grid; grid-template-columns: 1fr; gap: 12px; }
@media (min-width: 640px) { .sheets { grid-template-columns: 1fr 1fr; } }
/* desktop (900px+): the whole screen scales with one unit --cu (pixels per unit; text is 8 units = 16px at 2px, line 10 units), so it fills the viewport without scrolling.
   Layout at 1 unit: 492u + 16px wide, 204u + 8px tall, plus the 86px actions-bar reserve. --cu snaps down to 0.5px steps (font 16/20/24/28/32px, whole-pixel lines and glyph widths)
   and never goes under 2px (16px text). Portraits are whole multiples of the 32px sprite (64/96/128...). Slot five is a one-line strip, not a fifth card. */
@media (min-width: 900px) {
  .create {
    --cu: 2px; --cp: 64px;
    display: flex; flex-direction: column; padding: calc(var(--cu) * 4) calc(var(--cu) * 4) 86px;
  }
  .create-inner { width: 100%; max-width: calc(var(--cu) * 492 + 16px); margin: auto; }   /* auto margins centre it between the top and the actions bar */
  .create-head { gap: calc(var(--cu) * 6); }
  .create-head h1 { font-size: calc(var(--cu) * 16); margin: calc(var(--cu) * 2) 0; }
  .dice { gap: calc(var(--cu) * 3); }
  .die { width: calc(var(--cu) * 17); height: calc(var(--cu) * 17); font-size: calc(var(--cu) * 8); }
  .create-dm { font-size: calc(var(--cu) * 8); padding: calc(var(--cu) * 5) calc(var(--cu) * 6); min-height: calc(var(--cu) * 30); margin: 0 0 calc(var(--cu) * 4); }
  .sheets { grid-template-columns: repeat(4, 1fr); gap: calc(var(--cu) * 4); }
  .sheets .sheet { padding: calc(var(--cu) * 4) calc(var(--cu) * 3); min-width: 0; font-size: calc(var(--cu) * 8); }
  .sheets .sheet h3, .sheets .sheet .gs-abil, .sheets .sheet .gs-hands { font: calc(var(--cu) * 8) / 1.25 var(--mono); }
  .sheets .sheet h3 { margin: 0 0 calc(var(--cu) * 2); }
  .sheets .sheet .inst { font-size: calc(var(--cu) * 8); }
  .sheets .sheet .gs-abil { margin: calc(var(--cu) * 3) 0; }
  .sheets .sheet-top { gap: calc(var(--cu) * 5); }
  .sheets .gs-hands { grid-template-columns: max-content minmax(0, 1fr); column-gap: 1ch; }   /* 28ch line (Right hand: + Violin bow (1d6)) fits a card at 1000px; narrower, the value wraps */
  .sheets .empty-slot { grid-column: 1 / -1; display: flex; align-items: baseline; gap: calc(var(--cu) * 6); padding: calc(var(--cu) * 3) calc(var(--cu) * 6); }
  .sheets .empty-slot p, .sheets .empty-slot .note { margin: 0; }
  .sheets .empty-slot .slot-n { font: calc(var(--cu) * 8) / 1.25 var(--mono); color: var(--yellow); }
  .sheets .sheet-top .portrait { width: var(--cp); height: var(--cp); background-size: calc(var(--cp) * 2) var(--cp); animation-name: blinkp; }
  @keyframes blinkp { 0%, 95% { background-position-x: 0; } 96%, 100% { background-position-x: 100%; } }
}
@supports (width: round(down, 1px, 1px)) {
  @media (min-width: 900px) {
    .create, #sheet-dlg {
      --cu: max(2px, round(down, min((100vw - 16px) / 492, (100vh - 94px) / 204), 0.5px));
      --cp: max(64px, round(down, calc(var(--cu) * 32), 32px));
    }
  }
}
.sheets.shuffle .sheet { animation: shuf .35s steps(3) 1; }
@keyframes shuf { 0% { opacity: .2; transform: translateY(6px); } 100% { opacity: 1; transform: none; } }
.create-actions {
  position: fixed; left: 0; right: 0; bottom: 0; display: flex; gap: 10px; justify-content: center;
  padding: 12px 16px calc(12px + env(safe-area-inset-bottom)); background: rgba(10,9,12,.94); border-top: 2px solid var(--s1);
}

/* 1991 character sheet */
.sheet {
  background: var(--s1) url(assets/ui-stone.png) repeat; background-size: 128px; image-rendering: pixelated;
  color: var(--s5); border: 2px solid var(--black); padding: 12px;
  text-shadow: 2px 2px 0 var(--black);
  font: 16px/1.25 var(--mono);
}
/* in game the dialog holds the party screen's four cards at the party screen's size, wrapped to fit them */
#sheet-dlg .dlg-body { padding: 0; background: none; }
@media (min-width: 900px) { #sheet-dlg { width: fit-content; max-width: calc(100vw - 24px); } #sheet-dlg .sheets { width: calc(var(--cu) * 492); max-width: 100%; } }
.sheet-top { display: flex; gap: 12px; align-items: flex-start; }
.sheet-top .portrait { flex: none; }
.sheet h3 { font: 400 16px/1.25 var(--mono); color: var(--yellow); margin: 0 0 4px; }
.sheet .cls { color: var(--core); margin: 0; }
.sheet .hpac { color: var(--s4); margin: 0; }
/* sheet text stays at the card's 16px/1.25; the dialog's .gsheet sizing and desktop .gs-abil margin do not apply here */
.sheet .gs-abil { margin: 10px 0; }
.sheet .gs-abil, .sheet .gs-hands { font: 16px/1.25 var(--mono); }
.sheet .inst { color: var(--s4); margin: 0; font-size: 16px; }
.stats { list-style: none; margin: 10px 0 6px; padding: 0; display: grid; gap: 3px; }
.stats li { display: grid; grid-template-columns: 3.2em 2em 1fr; align-items: center; gap: 6px; font-size: 16px; }
.stats .k { font: 16px/1.25 var(--pixel); color: var(--s4); }
.stats .v { text-align: right; color: var(--core); }
.bar { height: 10px; background: var(--black); border: 1px solid var(--s1); position: relative; }
.bar i { position: absolute; left: 0; top: 0; bottom: 0; background: repeating-linear-gradient(90deg, var(--greenl) 0 6px, var(--green) 6px 8px); }
.bar.hi i { background: repeating-linear-gradient(90deg, var(--yellow) 0 6px, var(--yellowd) 6px 8px); }
.bar.lo i { background: repeating-linear-gradient(90deg, var(--red) 0 6px, #6c1d24 6px 8px); }
.sheet .note { margin: 6px 0 0; color: var(--s5); }
.sheet .note b { color: var(--flame); }

/* Monster Manual block for Tim */
.mm {
  background: #f1e3bd url(assets/parchment.png); background-size: 128px; color: #2a1a10;
  font: 14px/1.45 var(--serif); padding: 14px; border-top: 4px solid #8a2b1f; border-bottom: 4px solid #8a2b1f;
  box-shadow: 4px 4px 0 var(--black);
}
.mm h3, .dlg-body .mm h3 { font: 700 20px/1.2 var(--serif); color: #6c1d24; margin: 0; font-variant: small-caps; letter-spacing: .02em; }
.mm .tag { font-style: italic; margin: 0 0 8px; }
.mm hr { border: 0; height: 3px; background: linear-gradient(90deg, #8a2b1f, transparent); margin: 8px 0; }
.mm p { margin: 4px 0; }
.mm .b { color: #6c1d24; font-weight: 700; }
.mm .abil { display: grid; grid-template-columns: repeat(6, 1fr); text-align: center; font-size: 12px; gap: 2px; }
.mm .abil b { display: block; color: #6c1d24; }
.mm h4 { font: 700 15px var(--serif); color: #6c1d24; border-bottom: 1px solid #6c1d24; margin: 10px 0 4px; font-variant: small-caps; }
.mm .warn { font-weight: 700; color: #6c1d24; }
.mm .portrait { float: right; margin: 0 0 6px 10px; }
.sheets .mm { grid-column: 1 / -1; }   /* Tim's entry under the band's cards once he has joined */
@media (min-width: 900px) { .sheets .mm { columns: 2; column-gap: 32px; } .sheets .mm h4 { break-after: avoid; } }

/* ------------------------------------------------------------ portraits (pixel art) */
.portrait {
  display: inline-block; vertical-align: top; width: 64px; height: 64px; /* 2x of a 32x32 frame; always an integer multiple of 32 */
  background-size: 128px 64px; background-repeat: no-repeat; background-position: 0 0;
  image-rendering: pixelated; border: 0; outline: 2px solid var(--s2);
  animation: blink 5s steps(1) infinite;
}
.portrait.x1 { width: 64px; height: 64px; background-size: 128px 64px; }
/* 3x (96px) for the big ones on wide screens: the character sheet and the tavern bench */
@media (min-width: 640px) {
  .sheet-top .portrait, .bench-seat .portrait { width: 96px; height: 96px; background-size: 192px 96px; }
  @keyframes blink3 { 0%, 95% { background-position-x: 0; } 96%, 100% { background-position-x: -96px; } }
  .sheet-top .portrait, .bench-seat .portrait { animation-name: blink3; }
}
@keyframes blink { 0%, 95% { background-position-x: 0; } 96%, 100% { background-position-x: -64px; } }

/* ------------------------------------------------------------ game layout */
.game { display: flex; flex-direction: column; background: var(--black); }
.topbar {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 8px 12px; background: var(--void); border-bottom: 2px solid var(--s1);
  position: sticky; top: 0; z-index: 20;
}
.brand { display: flex; align-items: center; gap: 8px; background: none; border: 0; padding: 0; text-align: left; }
.brand img { width: 40px; height: 39px; background: var(--parch); border-radius: 50%; padding: 2px; flex: none; }
.brand span { font: 16px/1 var(--pixel); color: var(--parch); }
.topbar-exit { white-space: nowrap; }
@media (max-width: 420px) { .brand span { display: none; } }
.game-grid { width: 100%; max-width: 1240px; margin: 0 auto; padding: 10px 12px 24px; display: grid; gap: 12px; grid-template-columns: minmax(0, 1fr); }
.eob, .col-log, .strip { display: flex; flex-direction: column; gap: 12px; min-width: 0; }

.viewport-frame { background: var(--s1); padding: 8px; border: 2px solid var(--black); }
.viewport {
  position: relative; width: 100%; aspect-ratio: 3 / 2; background: var(--black); overflow: hidden;
  touch-action: none; user-select: none; -webkit-user-select: none; cursor: crosshair;
}
#view { display: block; width: 100%; height: 100%; image-rendering: pixelated; image-rendering: crisp-edges; }
.vp-label {
  position: absolute; left: 8px; top: 8px; margin: 0; padding: 4px 6px;
  font: 16px/1 var(--pixel); color: var(--core); background: rgba(10,9,12,.75); pointer-events: none;
}
.vp-loading { position: absolute; inset: 0; display: grid; place-items: center; margin: 0; font: 16px/1 var(--pixel); color: var(--s4); }
.scene-overlay { position: absolute; inset: 0; pointer-events: none; }
.scene-overlay > * { pointer-events: auto; }
.bench-wrap { position: absolute; left: 8%; right: 8%; bottom: 6%; height: 52%; }
.bench { position: absolute; left: 0; right: 0; bottom: 0; height: 20%; background: url(assets/bench.png) center bottom / 100% 100% no-repeat; image-rendering: pixelated; }
.bench-seat { position: absolute; bottom: 14%; left: 0; right: 0; display: flex; justify-content: space-around; align-items: flex-end; }
.bench-seat button { background: none; border: 0; padding: 0; display: flex; flex-direction: column; align-items: center; gap: 2px; animation: bob 2.4s steps(2) infinite; }
.bench-seat button:nth-child(2) { animation-delay: -.6s; } .bench-seat button:nth-child(3) { animation-delay: -1.2s; }
.bench-seat button:nth-child(4) { animation-delay: -1.8s; } .bench-seat button:nth-child(5) { animation-delay: -.3s; }
.bench-seat span:not(.portrait) { font: 16px/1 var(--pixel); color: var(--core); background: rgba(10,9,12,.8); padding: 2px 3px; }
@keyframes bob { 50% { transform: translateY(-2px); } }
@keyframes bobface { 50% { background-position-y: 2px; } }

.log-frame { background: var(--s1); padding: 6px; border: 2px solid var(--black); }
.log {
  background: var(--black); color: #f3ead2; font: 16px/20px var(--mono);
  height: 136px; overflow-y: auto; padding: 8px 10px; user-select: text; -webkit-user-select: text; cursor: text;
}
.log p { margin: 0 0 4px; }
.log p.old { color: #b5ad9c; }
.log .who { color: var(--flame); }
.log .sys { color: var(--greenl); }
.log .bad { color: #f07a6a; }
.log .good { color: var(--yellow); }
/* Act 4: the V8 race covers the 3D view: the yard frozen behind the five, full length (40x64 frames, scaled up crisp) */
.race-view { position: absolute; inset: 0; z-index: 3; background: var(--black) center / 100% 100% no-repeat; image-rendering: pixelated; }
.race-row { position: absolute; left: 0; right: 0; bottom: 1%; display: flex; justify-content: center; }
.racer { width: 22%; aspect-ratio: 40 / 64; background: transparent 0 0 / 500% 100% no-repeat; image-rendering: pixelated; }
.racer + .racer { margin-left: -3.5%; }   /* frames have empty sides; overlap them so five fit at this size */
.race-can { position: absolute; background: url(assets/sprites/v8can.png) 0 0 / 100% 100% no-repeat; image-rendering: pixelated; }
.race-can.down { background-image: url(assets/sprites/v8can_down.png); }

/* party bar */
.party { display: flex; gap: 2px; }
.party-card { flex: 1 1 0; }
.party-card {
  background: var(--s1); border: 2px solid var(--black); padding: 2px 0 3px; display: flex; flex-direction: column; align-items: center; gap: 1px;
  text-align: center; min-width: 0;
}
.party-card .portrait { width: 64px; height: 64px; background-size: 128px 64px; outline-width: 1px; background-color: #1e1a18; animation: blink 5s steps(1) infinite, bobface 3s steps(2) infinite; }
.party-card:nth-child(2) .portrait { animation-delay: -1.3s, -.7s; } .party-card:nth-child(3) .portrait { animation-delay: -2.6s, -1.4s; }
.party-card:nth-child(4) .portrait { animation-delay: -3.7s, -2.1s; } .party-card:nth-child(5) .portrait { animation-delay: -.6s, -.3s; }
.party-card .nm { font: 16px/1 var(--pixel); color: var(--core); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }
.party-card .cl { font: 400 16px/1 var(--mono); color: var(--s5); }
.hp { width: 100%; height: 6px; background: var(--black); border: 1px solid var(--black); }
.hp i { display: block; height: 100%; background: var(--greenl); }
.hp.low i { background: var(--red); }
.party-card .hpn { font: 16px/1 var(--mono); color: var(--s4); min-height: 32px; padding: 0 2px; }   /* a two-line status ("Out on chores") must not change the strip height, or the view scale */
.party-card.hit { animation: hit .3s steps(2) 2; }
@keyframes hit { 50% { background: var(--red); } }

/* controls */
.controls { display: flex; flex-direction: column; gap: 10px; }
.toolbar { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
.tool.flash { animation: flash .5s steps(2) 2; }
.tool.tool-gap { visibility: hidden; pointer-events: none; } /* keeps the old Journal slot so the toolbar does not shift */
@keyframes flash { 50% { background: var(--yellowd); color: var(--black); } }
.tool { padding: 8px 2px; font-size: 16px; }
.tool.d20 { padding: 4px; background: #0e2a17; box-shadow: inset 2px 2px 0 #36a256, inset -3px -3px 0 #071a0d; }
.tool.d20:hover { background: #123a1f; }
.d20-icon { display: inline-grid; place-items: center; width: 48px; height: 48px; padding-top: 3px; background: url(assets/d20.png) center / 100% no-repeat; image-rendering: pixelated; }
.d20-icon span { font: 16px/1 var(--pixel); color: #fff; text-shadow: 1px 1px 0 #0b3a1c, -1px 0 0 #0b3a1c; }
.d20.rolling .d20-icon { animation: tumble .1s steps(2) infinite; }
.nav-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.compass {
  width: 84px; height: 84px; flex: none; position: relative; border-radius: 50%;
  background: radial-gradient(circle, var(--s2) 0 40%, var(--s0) 41% 100%); border: 3px solid var(--black);
  box-shadow: inset 0 0 0 2px var(--s3), 0 0 0 2px var(--yellowd);
}
.compass-disc { position: absolute; inset: 0; transition: transform .18s steps(3); }
.compass-disc span { position: absolute; font: 16px/16px var(--pixel); color: var(--parch); width: 16px; text-align: center; left: calc(50% - 8px); top: calc(50% - 8px); }
.compass-disc .cn { transform: translateY(-28px); color: var(--flame); }
.compass-disc .cs { transform: translateY(28px); }
.compass-disc .ce { transform: translateX(28px); }
.compass-disc .cw { transform: translateX(-28px); }
.compass-pointer { position: absolute; left: calc(50% - 5px); top: -2px; width: 0; height: 0; border-left: 5px solid transparent; border-right: 5px solid transparent; border-top: 9px solid var(--yellow); }
.dpad { display: grid; grid-template-columns: repeat(3, 64px); grid-template-rows: repeat(2, 60px); gap: 6px; }
.pad {
  background: var(--s2); border: 2px solid var(--black); display: grid; place-items: center; padding: 0;
  box-shadow: inset 2px 2px 0 var(--s4), inset -3px -3px 0 var(--s0);
  touch-action: manipulation;
}
.pad svg { width: 30px; height: 30px; fill: var(--core); filter: drop-shadow(2px 2px 0 var(--black)); }
.pad:active, .pad.on { background: var(--s1); box-shadow: inset 3px 3px 0 var(--s0), inset -2px -2px 0 var(--s3); }
.keys-hint { margin: 0; font-size: 16px; line-height: 1.25; color: var(--s4); }
/* the scene's Leave button sits after the d-pad; on the narrowest phones it wraps under it instead of widening the page */
/* the fixture button (SIT, REST, TALK...) sits above Leave in the same column; hidden it still holds its slot, so nothing moves */
.ctx-col { display: flex; flex-direction: column; gap: 6px; align-self: center; }
.ctx-col .tool { min-width: 64px; }
.tool.ctx[hidden] { display: block; visibility: hidden; }
.viewport.usable:not(.edge) { cursor: pointer; }
@media (max-width: 380px) { .dpad { grid-template-columns: repeat(3, 58px); grid-template-rows: repeat(2, 56px); } .compass { width: 72px; height: 72px; } .compass-disc .cn { transform: translateY(-23px); } .compass-disc .cs { transform: translateY(23px); } .compass-disc .ce { transform: translateX(23px); } .compass-disc .cw { transform: translateX(-23px); } }
/* layout. Phone and tablet: one stack (view, party, log, controls, pad at the bottom).
   The script moves the log between the stack and the frame's message cell. */
.log { height: calc(6 * 20px + 16px); display: flex; flex-direction: column; }
.log > p:first-child { margin-top: auto; }
@media (max-width: 899px) {
  .col-log { display: none; }
  .game-grid { padding: 6px 10px 16px; gap: 8px; }
  .eob, .strip, .controls { gap: 8px; }
  .dpad { grid-template-rows: repeat(2, 54px); }
  .tool.d20 { padding: 2px; } .d20-icon { width: 44px; height: 44px; }
  .keys-hint { text-align: center; }
}
/* Desktop: one fixed Eye of the Beholder style frame, 320x192 logical units (1 unit = 1 canvas pixel).
   The script sets --u (pixels per unit, fractional) so the frame fits under the top bar with the keys hint below.
     view 192x128      | party 128x128 (2 x 3 slots of 64 x 42.67)
     DM text 192x64    | controls 128x64 (compass, d-pad, Leave; tool buttons under them)
   Large text is the VGA font at 8x16 units (font-size 16u); small labels are 8 units tall (font-size 8u). */
@media (min-width: 900px) {
  .game { --u: 3px; }
  .game-grid { max-width: none; display: flex; flex-direction: column; align-items: center; gap: 0; padding: 12px 16px; }
  .eob {
    display: grid; gap: 0; flex: none;
    grid-template-columns: calc(var(--u) * 192) calc(var(--u) * 128); grid-template-rows: calc(var(--u) * 128) calc(var(--u) * 64);
    width: calc(var(--u) * 320); height: calc(var(--u) * 192);
    background: var(--s1); box-shadow: 0 0 0 2px var(--black);
  }
  .strip { display: contents; }

  /* view: the canvas fills its cell */
  .eob-view { grid-area: 1 / 1; padding: 0; border: 0; box-shadow: none; }
  .viewport { width: 100%; height: 100%; aspect-ratio: auto; }

  /* party: portrait at the left of each slot, name, class and HP to its right */
  .eob-party { grid-area: 1 / 2; display: grid; grid-template-columns: repeat(2, 1fr); grid-template-rows: repeat(3, 1fr); gap: 0; background: var(--s0); }
  .party-card {
    display: grid; grid-template-columns: calc(var(--u) * 32) 1fr; grid-template-rows: repeat(4, auto); align-content: center; align-items: start;
    gap: 0; padding: 0; border: 0; text-align: left; min-width: 0;
    box-shadow: inset calc(var(--u) * 1) calc(var(--u) * 1) 0 var(--s3), inset calc(var(--u) * -1) calc(var(--u) * -1) 0 var(--black);
  }
  .party-card .portrait {
    grid-row: 1 / 5; align-self: center; width: calc(var(--u) * 32); height: calc(var(--u) * 32); background-size: calc(var(--u) * 64) calc(var(--u) * 32);
    outline: calc(var(--u) * .5) solid var(--s2); outline-offset: calc(var(--u) * -.5); background-color: #1e1a18; animation-name: blink-u, bobface-u;
  }
  /* 8 glyphs of 4 units fill the 32-unit text column exactly ("Geoffrey"), so no ellipsis */
  .party-card .nm, .party-card .cl, .party-card .hpn { font-size: calc(var(--u) * 8); line-height: calc(var(--u) * 8); }
  .party-card .nm { overflow: visible; text-overflow: clip; }
  .party-card .hp { height: calc(var(--u) * 2); border: 0; margin: calc(var(--u) * 1) 0; }
  .party-card .hpn { min-height: 0; padding: 0; overflow-wrap: anywhere; }

  /* DM text: 4 lines of 16 units, newest at the bottom */
  .eob-msg { grid-area: 2 / 1; min-width: 0; min-height: 0; }
  .log-frame { flex: 1 1 auto; min-height: 0; display: flex; padding: 0; border: 0; box-shadow: none; }
  .log {
    flex: 1; height: 100%; min-height: 0; padding: 0 calc(var(--u) * 2); scrollbar-width: none;
    font-size: calc(var(--u) * 7); line-height: calc(var(--u) * 10);   /* 21px text on 30px lines at the 3px unit: 6 lines of ~54 columns in the 192x64 message cell */
    box-shadow: inset calc(var(--u) * 1) calc(var(--u) * 1) 0 var(--s3), inset calc(var(--u) * -1) calc(var(--u) * -1) 0 var(--s0);
  }
  .log p { margin: 0; }

  /* controls: compass, d-pad and Leave on top; the tool buttons in one row under them */
  .eob-ctl {
    grid-area: 2 / 2; display: grid; grid-template-rows: calc(var(--u) * 40) calc(var(--u) * 16); align-content: center;
    gap: calc(var(--u) * 2); padding: 0 calc(var(--u) * 2); min-width: 0;
    box-shadow: inset calc(var(--u) * 1) calc(var(--u) * 1) 0 var(--s3), inset calc(var(--u) * -1) calc(var(--u) * -1) 0 var(--s0);
  }
  .eob-ctl .nav-row { grid-row: 1; justify-content: flex-start; gap: calc(var(--u) * 2); }
  .ctx-col { gap: calc(var(--u) * 2); }
  .ctx-col .tool { min-width: calc(var(--u) * 22); }
  .eob-ctl .toolbar { grid-row: 2; display: flex; justify-content: space-between; gap: 0; }
  .eob-ctl .tool {
    min-height: 0; height: calc(var(--u) * 16); padding: 0 calc(var(--u) * .5); flex: none;
    font-size: calc(var(--u) * 8); line-height: calc(var(--u) * 8); border-width: calc(var(--u) * .5);
    text-shadow: calc(var(--u) * .5) calc(var(--u) * .5) 0 var(--black);
    box-shadow: inset calc(var(--u) * .5) calc(var(--u) * .5) 0 var(--s3), inset calc(var(--u) * -.5) calc(var(--u) * -.5) 0 var(--black);
  }
  .eob-ctl .tool:active { box-shadow: inset calc(var(--u) * .5) calc(var(--u) * .5) 0 var(--black), inset calc(var(--u) * -.5) calc(var(--u) * -.5) 0 var(--s3); }
  .eob-ctl .tool.d20 { width: calc(var(--u) * 16); padding: 0; display: grid; place-items: center; box-shadow: inset calc(var(--u) * .5) calc(var(--u) * .5) 0 #36a256, inset calc(var(--u) * -.5) calc(var(--u) * -.5) 0 #071a0d; }
  .d20-icon { width: calc(var(--u) * 14); height: calc(var(--u) * 14); padding-top: calc(var(--u) * 1); }
  .d20-icon span { font-size: calc(var(--u) * 8); line-height: calc(var(--u) * 8); }
  .compass {
    width: calc(var(--u) * 40); height: calc(var(--u) * 40); border-width: calc(var(--u) * 1);
    box-shadow: inset 0 0 0 calc(var(--u) * 1) var(--s3), 0 0 0 calc(var(--u) * 1) var(--yellowd);
  }
  .compass-disc span { font-size: calc(var(--u) * 8); line-height: calc(var(--u) * 8); width: calc(var(--u) * 8); left: calc(50% - var(--u) * 4); top: calc(50% - var(--u) * 4); }
  .compass-disc .cn { transform: translateY(calc(var(--u) * -13)); } .compass-disc .cs { transform: translateY(calc(var(--u) * 13)); }
  .compass-disc .ce { transform: translateX(calc(var(--u) * 13)); } .compass-disc .cw { transform: translateX(calc(var(--u) * -13)); }
  .compass-pointer { left: calc(50% - var(--u) * 2.5); top: calc(var(--u) * -1); border-left-width: calc(var(--u) * 2.5); border-right-width: calc(var(--u) * 2.5); border-top-width: calc(var(--u) * 4.5); }
  .dpad { grid-template-columns: repeat(3, calc(var(--u) * 16)); grid-template-rows: repeat(2, calc(var(--u) * 16)); gap: calc(var(--u) * 2); }
  .pad { border-width: calc(var(--u) * .5); box-shadow: inset calc(var(--u) * 1) calc(var(--u) * 1) 0 var(--s4), inset calc(var(--u) * -1) calc(var(--u) * -1) 0 var(--s0); }
  .pad:active, .pad.on { box-shadow: inset calc(var(--u) * 1) calc(var(--u) * 1) 0 var(--s0), inset calc(var(--u) * -1) calc(var(--u) * -1) 0 var(--s3); }
  .pad svg { width: calc(var(--u) * 10); height: calc(var(--u) * 10); }

  /* keys hint: one plain line under the frame, outside it */
  .keys-hint { max-width: 100%; line-height: 20px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
}
@keyframes blink-u { 0%, 95% { background-position-x: 0; } 96%, 100% { background-position-x: calc(var(--u) * -32); } }
@keyframes bobface-u { 50% { background-position-y: calc(var(--u) * 1); } }

/* ------------------------------------------------------------ the site: a printed PC game manual, c. 1991
   Laid out like a Sierra On-Line manual of 1990-91: bright white paper, a yellow "Chapter" sticker over a
   color-graded title bar that bleeds off the right edge (one color per chapter), a row of inventory icons in
   white boxes, Times body set justified, condensed poster caps (Anton) for the heads, peach panels behind the
   photos and tips, and an illuminated drop cap on the cover. Nothing animates. Every size is 16px or more. */
.no-js .screen:not(#plain) { display: none !important; }
.no-js #plain[hidden] { display: block !important; }
.no-js .js-only { display: none !important; }
.site {
  --paper: #fffef9; --paper2: #fff8ef; --ink: #1a1a1a; --ink2: #4a4642; --rule: #cfc8bd; --spot: #c8102e; --desk: #3b3e46; --ok: #2f6b2c;
  --peach: #f8d3b5; --sticker: #ffd400; --illum: #1f7a3a;
  --ch-a: #5b2a8c; --ch-b: #8a5cc4;   /* the chapter's color grade; each chapter sets its own below */
  --m-body: "Tinos", "Times New Roman", Times, serif;
  --m-disp: "Anton", Impact, "Arial Narrow", sans-serif;
  --pad: 22px;   /* the page's side margin, so bars can bleed off the right edge */
  color-scheme: light;
  background: var(--desk); color: var(--ink);
  font: 400 18px/1.5 var(--m-body); font-variant-numeric: lining-nums;
  padding: 0 0 24px;
}
@media (min-width: 700px) { .site { font-size: 19px; padding: 32px 24px 40px; --pad: 60px; } }
#photos { --ch-a: #b8155f; --ch-b: #d94c8a; }
#shows { --ch-a: #b84a0e; --ch-b: #d9711f; }
#songs { --ch-a: #0e6a73; --ch-b: #1a9aa3; }
#contact { --ch-a: #2a4f9a; --ch-b: #4f7fd0; }
.site *, .site *::before, .site *::after { animation: none !important; transition: none !important; }
.site :focus-visible { outline: 3px solid var(--spot); outline-offset: 3px; }
.site [tabindex="-1"]:focus { outline: none; }
.site a { color: #1d4f9c; text-decoration-thickness: 1px; text-underline-offset: 3px; }
.site a:hover { color: var(--spot); }
.site p { margin: 0 0 12px; }
@media (min-width: 700px) { .chapter > p:not([class]) { text-align: justify; hyphens: auto; } }
.site img { display: block; height: auto; }
.site .skip { position: absolute; left: 16px; top: -100px; z-index: 5; background: var(--paper2); padding: 10px 14px; border: 2px solid var(--ink); }
.site .skip:focus { top: 12px; }

/* a page: one sheet of clean white stock, no frame */
.m-page { position: relative; max-width: 860px; margin: 0 auto 8px; padding: 28px var(--pad) 24px; background: var(--paper); overflow: hidden; }
@media (min-width: 700px) { .m-page { margin-bottom: 32px; padding-top: 48px; padding-bottom: 32px; box-shadow: 0 14px 30px rgba(0, 0, 0, .45); } }
.runhead { display: none; }
.folio { display: flex; justify-content: flex-end; margin: 28px 0 0 !important; border-top: 1px solid var(--rule); padding-top: 8px; }
.folio-n { font: italic 400 16px/1 var(--m-body); color: var(--ink2); }
.folio-n::before { content: "Page "; }

/* the cover */
.m-cover { text-align: center; padding-bottom: 34px; }
.cover-band {
  display: flex; justify-content: space-between; gap: 6px 16px; flex-wrap: wrap;
  background: linear-gradient(90deg, var(--ch-a), var(--ch-b)); color: #fff; text-shadow: 2px 2px 0 rgba(0, 0, 0, .45);
  margin: -28px calc(-1 * var(--pad)) 28px !important; padding: 10px var(--pad);
  font: 400 18px/1.3 var(--m-disp); letter-spacing: .06em; text-transform: uppercase;
}
@media (min-width: 700px) { .cover-band { margin-top: -48px !important; } }
.cover-logo { margin: 0 auto 22px; max-width: 420px; }
.cover-logo img { width: 100%; }
.cover-lede { font-size: 21px; line-height: 1.45; text-align: left; max-width: 26em; margin: 0 auto 22px !important; }
@media (min-width: 700px) { .cover-lede { font-size: 24px; } }
/* the illuminated capital */
.cover-lede::first-letter {
  float: left; font: 400 62px/1 var(--m-disp); color: #fff; background: var(--illum); text-shadow: 2px 2px 0 #0b3a19;
  padding: 6px 12px 8px; margin: 6px 12px 0 0; border: 4px double var(--sticker);
}
.cover-who { display: inline-block; margin: 0 !important; font: 400 20px/1.4 var(--m-disp); letter-spacing: .05em; text-transform: uppercase; color: var(--ink); }
.cover-who::before, .cover-who::after { content: "\2726"; color: var(--spot); margin: 0 .6em; font-size: 16px; vertical-align: .15em; }

/* contents */
.m-label {
  font: 400 34px/1.15 var(--m-disp); letter-spacing: .03em; text-transform: uppercase; color: #fff; text-shadow: 2px 2px 0 rgba(0, 0, 0, .45);
  background: linear-gradient(90deg, var(--ch-a), var(--ch-b)); margin: 0 calc(-1 * var(--pad)) 14px 0; padding: 8px var(--pad) 8px 16px;
}
.toc { list-style: none; margin: 0 0 28px; padding: 0; }
.toc a { display: flex; align-items: baseline; gap: 4px 12px; flex-wrap: wrap; padding: 9px 0; text-decoration: none; min-height: 44px; color: var(--ink); }
.toc-n { font: 400 18px/1.3 var(--m-disp); letter-spacing: .04em; text-transform: uppercase; color: var(--spot); width: 6em; flex: none; }
.toc-t { flex: 1; display: flex; align-items: baseline; gap: 8px; font: 700 21px/1.3 var(--m-body); min-width: 9em; }
.toc-t::after { content: ""; flex: 1; border-bottom: 2px dotted var(--ink); min-width: 1em; }
.toc-p { font-weight: 700; }
.toc a:hover .toc-t { color: var(--spot); }

/* the one VGA "screen" callout: a screenshot pasted into the manual */
.screen-box { background: #0000a8; color: #a8a8a8; font: 16px/20px "IBM VGA 8x16", ui-monospace, Menlo, monospace; border: 6px solid #111; outline: 1px solid var(--ink); outline-offset: 3px; max-width: 560px; }
.screen-box * { font-weight: 400 !important; }
.screen-bar { background: #a8a8a8; color: #0000a8; padding: 2px 8px; margin: 0 !important; }
.screen-body { padding: 12px 16px 4px; }
.screen-body h3 { font: inherit; color: #fefe54; margin: 0 0 8px; }
.screen-body p { margin: 0 0 12px; text-align: left !important; }
.screen-btn { font: inherit; background: #a8a8a8; color: #000; border: 0; padding: 12px 16px; min-height: 44px; box-shadow: 4px 4px 0 #000; }
.screen-btn::before { content: "\25BA  "; }
.screen-btn:hover, .screen-btn:focus-visible { background: #fefefe; }
.site .screen-btn:focus-visible { outline: 3px solid #fefe54; }

/* chapters: a yellow sticker over a color-graded title bar that runs off the page, then a row of icons */
.ch-head { margin: 0 0 22px; }
.ch-n {
  position: relative; z-index: 1; display: inline-block; transform: rotate(-3deg);
  font: 400 19px/1.2 var(--m-disp); letter-spacing: .05em; text-transform: uppercase; color: var(--ink);
  background: var(--sticker); padding: 5px 14px 4px; box-shadow: 3px 3px 0 var(--ink); margin: 0 0 -8px 10px !important;
}
.ch-head h2 {
  font: 400 40px/1.1 var(--m-disp); letter-spacing: .02em; text-transform: uppercase; color: #fff; text-shadow: 3px 3px 0 rgba(0, 0, 0, .45);
  background: linear-gradient(90deg, var(--ch-a) 30%, var(--ch-b)); margin: 0 calc(-1 * var(--pad)) 0 0; padding: 16px var(--pad) 10px 16px;
}
@media (min-width: 700px) { .ch-head h2 { font-size: 56px; } }
.icon-bar {
  display: flex; gap: 10px; width: max-content; max-width: calc(100% + var(--pad)); margin: 0 calc(-1 * var(--pad)) 24px auto !important;
  padding: 8px var(--pad) 8px 10px; background: linear-gradient(90deg, #0e6a73, #2a4f9a);
}
.m-ico {
  width: 56px; height: 56px; flex: none; background: #fff url(assets/items.png) no-repeat; border: 2px solid var(--ink);
  background-size: 384px 192px; background-position: calc(var(--x) * -48px + 2px) calc(var(--y) * -48px + 2px);
  image-rendering: pixelated; box-shadow: inset 0 0 0 2px #fff;
}
@media (max-width: 359px) { .site .m-ico { width: 48px; height: 48px; background-position: calc(var(--x) * -48px - 2px) calc(var(--y) * -48px - 2px); } }
.sub { font: 700 23px/1.25 var(--m-body); margin: 30px 0 12px; }
.sub::before { content: ""; display: block; width: 56px; height: 5px; background: var(--spot); margin-bottom: 8px; }

/* figures and captions: photos on a peach panel, in a black keyline */
.fig { margin: 22px 0; background: var(--peach); padding: 12px; }
.fig img, .roster img { width: 100%; border: 2px solid var(--ink); background: #fff; }
.fig figcaption, .fig-cap-solo, .roster figcaption, .tbl-cap, .gig-tbl caption { font-size: 16px; line-height: 1.4; font-style: italic; color: var(--ink2); }
.fig figcaption { margin-top: 8px; color: var(--ink); }
.fig-n { font-style: normal; font-weight: 700; color: var(--spot); margin-right: .4em; }
.roster { list-style: none; margin: 0 0 8px; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; background: var(--peach); padding: 12px; }
@media (min-width: 520px) { .roster { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 760px) { .roster { grid-template-columns: repeat(5, minmax(0, 1fr)); } }
.roster figure { margin: 0; }
.roster figcaption { font-style: normal; margin-top: 6px; color: var(--ink); }
.roster figcaption b { display: block; font: 400 20px/1.25 var(--m-disp); letter-spacing: .03em; text-transform: uppercase; }
.fig-cap-solo { margin: 0 0 8px !important; }
.fig-tall { max-width: 420px; margin-inline: auto; }

/* sidebars: a peach box with a bold red head */
.note, .tip { background: var(--peach); padding: 14px 18px 4px; margin: 24px 0; border: 2px solid var(--ink); box-shadow: 4px 4px 0 var(--ink); }
.note-h, .tip-h { font: 400 19px/1.3 var(--m-disp); letter-spacing: .06em; text-transform: uppercase; color: var(--spot); margin: 0 0 4px !important; }
.note a, .tip a { color: #183f80; }

/* live shows: a ruled table, the head in the chapter's color */
.gig-box { margin: 18px 0 8px; }
.gig-status { border-top: 2px solid var(--ink); border-bottom: 2px solid var(--ink); padding: 12px 0; }
.gig-tbl { width: 100%; border-collapse: collapse; margin: 0 0 16px; border: 2px solid var(--ink); }
.gig-tbl caption { text-align: left; padding-bottom: 6px; caption-side: top; }
.gig-tbl th { text-align: left; font: 400 17px/1.2 var(--m-disp); letter-spacing: .06em; text-transform: uppercase; padding: 8px 10px 6px; background: var(--ch-a); color: #fff; }
.gig-tbl td { padding: 9px 10px; border-top: 1px solid var(--ink); vertical-align: top; }
.gig-tbl tbody tr:nth-child(even) td { background: #fdeee2; }
.gig-tbl td:first-child { font-weight: 700; white-space: nowrap; }
.gig-tbl abbr { text-decoration: none; color: var(--ink2); font-style: italic; }
@media (max-width: 599px) {
  .gig-tbl thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  .gig-tbl, .gig-tbl tbody, .gig-tbl tr, .gig-tbl td { display: block; }
  .gig-tbl { border: 0; }
  .gig-tbl tbody { border: 2px solid var(--ink); }
  .gig-tbl caption { display: block; }
  .gig-tbl tr { padding: 10px 12px; border-top: 1px solid var(--ink); }
  .gig-tbl tr:first-child { border-top: 0; }
  .gig-tbl tbody tr:nth-child(even) { background: #fdeee2; }
  .gig-tbl tbody tr:nth-child(even) td { background: none; }
  .gig-tbl td { padding: 0; border: 0; white-space: normal !important; }
  .gig-tbl td:not(:first-child)::before { content: attr(data-label) ": "; font-variant: small-caps; letter-spacing: .06em; color: var(--ink2); }
}
.gig-past { margin: 8px 0 16px; }
.gig-past summary { cursor: pointer; font-weight: 700; min-height: 44px; display: flex; align-items: center; }
.gig-past summary::marker, .gig-past summary::-webkit-details-marker { color: var(--spot); }

/* buttons: yellow stickers with a hard shadow */
.buy, .m-btn {
  display: inline-flex; align-items: center; justify-content: center; min-height: 44px; padding: 6px 14px;
  font: 400 18px/1.1 var(--m-disp); letter-spacing: .05em; text-transform: uppercase; color: var(--ink) !important; text-decoration: none !important;
  background: var(--sticker); border: 2px solid var(--ink); border-radius: 0; box-shadow: 3px 3px 0 var(--ink); cursor: pointer;
}
.site .buy:hover, .m-btn:hover { background: var(--ink); color: #fff !important; }
.buy:active, .m-btn:active { transform: translate(2px, 2px); box-shadow: 1px 1px 0 var(--ink); }

/* songs: a track listing, the numbers in boxes of the chapter's color */
.tbl-cap { margin: 26px 0 6px !important; }
.tracks-m { list-style: none; margin: 0 0 8px; padding: 0; border-top: 3px solid var(--ink); border-bottom: 3px solid var(--ink); }
.tracks-m li { padding: 12px 0; border-bottom: 1px solid var(--rule); }
.tracks-m li:last-child { border-bottom: 0; }
.tm-row { display: grid; grid-template-columns: 2em minmax(0, 1fr) auto; gap: 0 12px; align-items: baseline; margin: 0 !important; }
.tm-n { font: 400 19px/1.5 var(--m-disp); background: var(--ch-a); color: #fff; text-align: center; align-self: start; margin-top: 2px; }
.tm-t b { display: block; font: 700 21px/1.25 var(--m-body); }
.tm-k { display: block; font-size: 16px; font-style: italic; color: var(--ink2); }
.tm-len { font-weight: 700; font-variant-numeric: tabular-nums; }
.tm-act { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 16px; margin: 10px 0 0 calc(2em + 12px); }
.tm-act audio { width: 100%; max-width: 320px; height: 40px; }
.buy::after { content: "\2192"; margin-left: .5em; }
@media (max-width: 459px) { .tm-act { margin-left: 0; } }

/* the contact form: the mail-in registration card, inside a dashed cut line */
.m-form { margin: 26px 0 8px; max-width: 660px; position: relative; border: 2px dashed var(--ink); background: var(--paper2); padding: 26px 18px 6px; }
.m-form::before { content: "\2702"; position: absolute; top: -17px; left: 18px; font-size: 24px; line-height: 1; background: var(--paper); padding: 2px 6px; }
@media (min-width: 600px) { .m-form { padding: 30px 28px 10px; } }
.m-form .field { display: grid; gap: 4px; margin: 0 0 18px; }
.m-form label { font: 700 17px/1.3 var(--m-body); }
.m-form .opt { font: italic 400 16px var(--m-body); color: var(--ink2); }
.m-form input, .m-form textarea {
  font: 400 19px/1.4 var(--m-body); color: var(--ink); background: transparent;
  border: 0; border-bottom: 2px solid var(--ink); border-radius: 0; padding: 8px 2px; min-height: 46px; width: 100%;
}
.m-form textarea { resize: vertical; min-height: 9em; border: 2px solid var(--ink); padding: 8px 10px; line-height: 32px;
  background: repeating-linear-gradient(transparent 0 31px, var(--rule) 31px 32px) 0 8px / 100% 32px local; }
.m-form input::placeholder { color: #7d756a; font-style: italic; }
.m-form [aria-invalid="true"] { border-color: var(--spot); box-shadow: 0 2px 0 var(--spot); }
.field-row { display: grid; gap: 0 20px; }
@media (min-width: 600px) { .field-row { grid-template-columns: 1fr 1fr; } }
.field-err { color: var(--spot); font-weight: 700; font-size: 16px; margin: 0 !important; }
.hp { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }
.m-btn { font-size: 20px; padding: 10px 22px; min-height: 50px; }
.m-btn:disabled { opacity: .6; cursor: progress; }
.form-status { border-left: 4px solid var(--ink); padding: 8px 12px; background: var(--paper); font-weight: 700; }
.form-status.err { border-color: var(--spot); color: var(--spot); }
.form-status.ok { border-color: var(--ok); color: var(--ok); }
.social { font-size: 18px; margin-top: 20px !important; }

/* the back cover */
.m-foot { text-align: center; color: #e2e2e6; max-width: 860px; margin: 0 auto; padding: 16px 16px 8px; font-size: 16px; }
.m-foot p { margin: 0 0 10px; }
.site .m-foot a, .m-foot .link-btn { color: #fff; }
.ornament { font-size: 28px; color: var(--sticker); margin-bottom: 4px !important; }
.link-btn { background: none; border: 0; padding: 0; font: inherit; text-decoration: underline; text-underline-offset: 3px; min-height: 44px; }
.link-btn:hover { color: var(--sticker); }
.m-small { color: #c9c9cf; }
.site .m-small a { color: #e2e2e6; }

/* ------------------------------------------------------------ dialogs */
.dlg { padding: 0; border: 0; background: transparent; color: var(--s5); max-width: min(720px, calc(100vw - 24px)); width: 100%; max-height: calc(100dvh - 24px); }
.dlg::backdrop { background: rgba(10, 9, 12, .78); }
.dlg-frame { background: var(--s1); border: 2px solid var(--black); padding: 8px; }
.dlg-head { display: flex; justify-content: space-between; align-items: center; gap: 8px; padding: 4px 4px 8px; }
.dlg-head h2 { font: 400 16px/1.25 var(--pixel); color: var(--yellow); margin: 0; }
.dlg-body { background: var(--black); padding: 12px; max-height: calc(100dvh - 120px); overflow: auto; }
.map-note { margin: 0 0 10px; font-size: 16px; }
.map-grid { display: grid; gap: 2px; margin: 0 auto; width: min(100%, 440px); }
.map-grid .mc { aspect-ratio: 1; background: var(--black); border: 0; padding: 0; position: relative; font: 16px/1 var(--pixel); color: var(--black); }
.map-grid .mc.floor { background: var(--s2); }
.map-grid .mc.floor.seen { background: var(--s4); }
.map-grid .mc.room { background: #2a2433; color: var(--s3); outline: 2px dashed var(--s2); outline-offset: -4px; }
.map-grid .mc.room.lit { background: var(--flame); color: var(--black); outline: 2px solid var(--black); box-shadow: 0 0 12px var(--amber); }
.map-grid .mc.room span { position: absolute; inset: 0; display: grid; place-items: center; text-align: center; word-break: break-word; padding: 1px; }
.map-grid .mc.chest::after { content: ""; position: absolute; inset: 30%; background: var(--wl, #9b6a3a); border: 2px solid var(--black); }
.map-grid .mc .me {
  position: absolute; inset: 18%; display: grid; place-items: center; color: var(--navy); font: 16px/1 var(--pixel);
  background: var(--yellow); border: 2px solid var(--black); z-index: 1;
}
.map-legend { list-style: none; padding: 0; margin: 12px 0 0; display: flex; flex-wrap: wrap; gap: 6px 14px; font-size: 16px; }
/* the Prop Room's weapon upgrade (Act 3): one button per member */
.pick-list { list-style: none; padding: 0; margin: 12px 0 0; display: grid; gap: 8px; }
.pick-list .btn-chunky { width: 100%; text-align: left; }
.map-legend i { display: inline-block; width: 12px; height: 12px; margin-right: 6px; vertical-align: -1px; border: 1px solid var(--black); }

/* ------------------------------------------------------------ story: clock, death banner, banner overlay */
.vp-clock {
  position: absolute; right: 8px; top: 8px; margin: 0; padding: 4px 6px; pointer-events: none;
  font: 16px/1 var(--pixel); color: var(--core); background: rgba(10,9,12,.75);
}
.vp-clock.late { color: #f07a6a; }
.vp-death {
  position: absolute; left: 0; right: 0; top: 38%; margin: 0; padding: 10px 12px; text-align: center; pointer-events: none;
  font: 16px/20px var(--pixel); color: #fff; background: rgba(110, 18, 12, .86); border-top: 2px solid var(--black); border-bottom: 2px solid var(--black);
}
.banner-ov {
  position: absolute; left: 14%; right: 14%; top: 6%; padding: 6px 10px 8px;
  background: var(--parch) url(assets/parchment.png); background-size: 96px; color: var(--ink);
  border: 3px solid var(--black); box-shadow: inset 0 0 0 2px var(--parchd); animation: unroll .6s steps(6);
}
.banner-ov .bn-h { margin: 0 0 4px; font: 16px/1 var(--pixel); color: var(--red); text-align: center; }
.banner-ov ul { list-style: none; margin: 0; padding: 0; columns: 2; column-gap: 12px; font: 400 16px/1 var(--mono); }
.banner-ov b { display: inline-block; min-width: 6em; }
@keyframes unroll { from { clip-path: inset(0 0 100% 0); } to { clip-path: inset(0 0 0 0); } }
@media (max-width: 520px) { .banner-ov { left: 4%; right: 4%; } }

/* party cards: out on chores, respawning */
.party-card.away { opacity: .45; filter: grayscale(1); }
.party-card.dead .portrait { filter: grayscale(1) brightness(.6); }
.party-card.dead .hpn { color: #f07a6a; }

/* ------------------------------------------------------------ prologue */
.prologue { display: grid; place-items: center; padding: 16px; background: var(--black); }
.pro-inner { width: min(640px, 100%); display: flex; flex-direction: column; gap: 12px; }
.pro-panel { margin: 0; background: var(--s1); padding: 8px; border: 2px solid var(--black); box-shadow: inset 2px 2px 0 var(--s3), inset -2px -2px 0 var(--black); }
.pro-panel img { display: block; width: 100%; height: auto; aspect-ratio: 8 / 5; image-rendering: pixelated; background: var(--black); }
.pro-panel figcaption { background: var(--black); color: #f3ead2; padding: 12px 14px; font: 16px/20px var(--mono); min-height: 84px; }
.pro-panel.in img { animation: pro-in .6s steps(6); }
.pro-panel.vow img { display: none; }
.pro-panel.vow figcaption { min-height: 10em; display: grid; place-items: center; text-align: center; font: 16px/24px var(--pixel); color: var(--core); }
@keyframes pro-in { from { opacity: 0; } }
.pro-count { margin: 0; text-align: center; font: 16px/1 var(--pixel); color: var(--s4); }
.pro-actions { display: flex; justify-content: space-between; gap: 10px; }
/* Act 4: the ending reuses the prologue's cards and panel styles; the last card is the tally */
.ending .pro-panel.vow figcaption { white-space: pre-line; }

/* ------------------------------------------------------------ dialogs: tabs, encounter, Tim, bag, journal, end card */
.btn-chunky.ghost { background: var(--s0); }
.tabs { display: flex; gap: 4px; margin: 0 0 10px; flex-wrap: wrap; }
.tabs [role="tab"] { font: 16px/1 var(--pixel); padding: 8px 10px; min-height: 36px; background: var(--s0); color: var(--s4); border: 2px solid var(--black); }
.tabs [role="tab"][aria-selected="true"] { background: var(--yellowd); color: var(--black); }
.dlg-body .muted { color: var(--s4); }
.dlg-body h3 { font: 400 16px/1.25 var(--pixel); color: var(--flame); margin: 16px 0 8px; }
.dlg-body .ph {
  display: inline-block; font: 400 16px/1.25 var(--mono); letter-spacing: 0; text-transform: uppercase;
  color: var(--flame); border: 1px solid currentColor; padding: 0 4px; vertical-align: 1px;
}
.radio { display: flex; gap: 8px; align-items: baseline; padding: 4px 0; cursor: pointer; }
.radio input { accent-color: var(--yellow); }
.enc-btns { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 12px 0 0; }
/* encounters happen in the frame: the d20 lights while a roll waits */
.tool.d20.lit { background: #2c6e22; box-shadow: inset 0 0 0 2px var(--flame); animation: d20-lit 1s steps(2) infinite; }
@keyframes d20-lit { 50% { background: #123a1f; } }
@media (min-width: 900px) {
  .eob-ctl .tool.d20.lit { box-shadow: inset 0 0 0 calc(var(--u) * 1) var(--flame); }
}
/* Skip on Tim's speech: over the bottom-right of the 3D view, hard on/off blink (reduced motion turns every animation off) */
.skip-btn { position: absolute; right: 8px; bottom: 8px; z-index: 2; min-width: 0; min-height: 36px; border-radius: 0; animation: skip-blink 1s steps(1) infinite; }
@keyframes skip-blink { 50% { opacity: 0; } }
@media (min-width: 900px) {
  .btn-chunky.skip-btn {
    right: calc(var(--u) * 4); bottom: calc(var(--u) * 4); min-height: 0; height: calc(var(--u) * 16); padding: 0 calc(var(--u) * 4);
    font-size: calc(var(--u) * 8); line-height: calc(var(--u) * 8); border-width: calc(var(--u) * .5);
    text-shadow: calc(var(--u) * .5) calc(var(--u) * .5) 0 var(--black);
    box-shadow: inset calc(var(--u) * .5) calc(var(--u) * .5) 0 var(--s3), inset calc(var(--u) * -.5) calc(var(--u) * -.5) 0 var(--black);
  }
  .btn-chunky.skip-btn:active { box-shadow: inset calc(var(--u) * .5) calc(var(--u) * .5) 0 var(--black), inset calc(var(--u) * -.5) calc(var(--u) * -.5) 0 var(--s3); }
}
/* the bag panel: covers the 3D view's frame box and nothing else (the party, DM text and controls stay in view) */
.viewport-frame { position: relative; }
.dlg.bag-panel { position: absolute; inset: -2px; z-index: 5; margin: 0; width: auto; height: auto; max-width: none; max-height: none; }
.bag-panel .dlg-frame { height: 100%; display: flex; flex-direction: column; padding: 6px; }
.bag-panel .dlg-head { flex: none; padding: 0 0 6px; flex-wrap: nowrap; }
.bag-panel .dlg-head h2 { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bag-panel .tabs { margin: 0; flex-wrap: nowrap; }
.bag-panel .dlg-body { flex: 1; min-height: 0; max-height: none; padding: 8px; display: flex; flex-direction: column; overflow: hidden; }
.bag-panel .bag-grid { flex: none; margin: 0 0 8px; grid-template-columns: repeat(auto-fill, minmax(40px, 1fr)); }
.bag-panel .slot { aspect-ratio: auto; height: 40px; }
.bag-panel .bag-detail, .bag-panel .bag-scroll { flex: 1 1 auto; min-height: 0; overflow: auto; }
.bag-panel .bag-detail { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: 8px; align-content: start; }
.bag-panel .bag-detail > p { grid-column: 1; margin: 0 0 4px; }
.bag-panel .bag-detail .enc-btns { grid-column: 2; grid-row: 1 / span 2; margin: 0; align-self: start; }   /* Use stays in view beside the name */
@media (max-width: 520px) { .bag-panel .dlg-head h2 { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); } .bag-panel .dlg-head { justify-content: space-between; } }
@media (min-width: 900px) { .dlg.bag-panel { inset: 0; } }
.bag-grid { list-style: none; margin: 0 0 12px; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(52px, 1fr)); gap: 4px; }
.slot { position: relative; width: 100%; aspect-ratio: 1; display: grid; place-items: center; padding: 0; background: var(--void); border: 2px solid var(--s0); }
.slot.on { border-color: var(--yellow); background: var(--s0); }
.slot.empty { display: block; }
.slot .q { position: absolute; right: 2px; bottom: 1px; font: 16px/1 var(--pixel); color: var(--core); text-shadow: 1px 1px 0 var(--black); }
.ico {
  display: grid; place-items: center; width: 32px; height: 32px; image-rendering: pixelated;
  background-image: url(assets/items.png), linear-gradient(var(--s2), var(--s2)); background-size: 256px auto, 0 0;
  background-position: calc(var(--ix) * -32px) calc(var(--iy) * -32px); background-repeat: no-repeat;
}
.ico i { font: 16px/1 var(--pixel); font-style: normal; color: var(--core); opacity: 0; }
.no-items .ico { background: var(--s1); } .no-items .ico i { opacity: 1; }
.bag-detail { background: var(--void); padding: 10px 12px; border: 2px solid var(--s0); }
.bag-detail .tr-title { margin: 0 0 4px; color: var(--core); }
.quest-card { background: var(--void); padding: 10px 12px; border: 2px solid var(--s0); margin: 0 0 8px; }
.quest-card p { margin: 0 0 4px; }
.quest-card .tr-title { color: var(--core); }
.quest-gold { margin: 12px 0 0; color: var(--core); }
.bag-detail a { color: var(--flame); }
.songbook { padding-left: 1.6em; margin: 0; }
.songbook li { margin: 0 0 12px; }
.songbook .unknown { color: var(--s3); }
.songbook .song-card a, .dlg-body a { color: var(--flame); }
.jr-list { margin: 0; padding-left: 1.6em; }
.jr-list li { margin: 0 0 4px; }
.jr-list .done { color: #f3ead2; }
.jr-list .done::marker { color: var(--yellow); }
.jr-list .todo { color: var(--s3); }
.end-arr { font-size: 16px; color: var(--core); }
.end-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 6px 12px; margin: 0 0 14px; }
.end-stats div { background: var(--void); padding: 6px 10px; border: 2px solid var(--s0); }
.end-stats dt { font: 16px/1.25 var(--pixel); color: var(--flame); }
.end-stats dd { margin: 2px 0 0; }
.end-btns { display: flex; flex-wrap: wrap; gap: 8px; }
.end-btns a { text-decoration: none; }
.btn-chunky.red { background: var(--red); color: #fff; }

/* character creation: the empty slot's number */
.empty-slot .slot-n { font: 700 32px/1 var(--book); margin: 0 0 6px; }

/* ------------------------------------------------------------ reduced motion */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
  .torch { background-position: -32px 0; }
}

/* ------------------------------------------------------------ game text font (IBM VGA 8x16)
   The site (#plain) has its own rules and never matches these selectors. */
/* in-game character sheet: openSheet copies the game's --u onto the dialog, so the desktop size matches the DM text (7u/10u) */
.gsheet { font: 16px/20px var(--mono); color: var(--s5); }
.gsheet h3 { font: inherit; color: var(--yellow); margin: 0; }
.gsheet p { margin: 0; }
.gs-abil { display: grid; grid-template-columns: 4ch 3ch 3ch; column-gap: 2ch; margin: 20px 0; width: max-content; }
.gs-abil .n { text-align: right; }
.gs-hands { display: grid; grid-template-columns: max-content 1fr; column-gap: 2ch; }
@media (min-width: 900px) { .gsheet { font-size: calc(var(--u, 3px) * 7); line-height: calc(var(--u, 3px) * 10); } .gs-abil { margin: calc(var(--u, 3px) * 10) 0; } }

/* One weight, one style: the bitmap face has no bold or italic. Browsers would fake them, so synthesis is off, and
   anything that asked for bold or italic is set to regular here. The Monster Manual keeps its
   own printed-page serif face. */
.title, .create, .game, .prologue, .dlg { font-synthesis: none; font-kerning: none; font-variant-ligatures: none; }
.mm { font-synthesis: initial; font-kerning: auto; font-variant-ligatures: normal; }
:is(.title, .create, .game, .prologue, .dlg) :is(b, strong, th, dt, legend, label, h1, h2, h3, h4, .who, .v, .tot, .t):not(.mm *) { font-weight: 400; }
:is(.title, .create, .game, .prologue, .dlg) :is(i, em):not(.mm *) { font-style: normal; }
