:root{--bg:#121417;--surface:#1b1f24;--surface2:#242a31;--text:#e8e4da;--muted:#9a9a94;--accent:#e0a33a;--accent-ink:#1a1305;--danger:#e26d5c;--ok:#7bc47f;--line:#2e353d;--foe:#8fa3d6;
--serif:"Iowan Old Style",Georgia,serif;--sans:system-ui,-apple-system,"Segoe UI",Roboto,sans-serif}
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{margin:0;background:var(--bg);color:var(--text);font:1rem/1.5 var(--sans);overflow-wrap:anywhere}
main,.bar{max-width:42rem;margin:0 auto;padding:0 16px}
main{padding-bottom:4rem}
h1,h2,h3{font-family:var(--serif);font-weight:600;line-height:1.2}
h1{font-size:1.6rem;margin:1.2rem 0 .8rem}h2{font-size:1.2rem;margin:1.6rem 0 .6rem}
a{color:var(--accent)}
.prose,.prose p{font-family:var(--serif);font-size:1.05rem;line-height:1.65}
.muted{color:var(--muted)}.err{color:var(--danger)}.ok{color:var(--ok)}
header{border-bottom:1px solid var(--line);background:var(--surface);position:sticky;top:0;z-index:5}
.bar{display:flex;align-items:center;gap:4px;min-height:52px}
.brand{flex:1;font-family:var(--serif);font-size:1.1rem;color:var(--text);text-decoration:none;padding:8px 4px}
.icon-btn{min-width:44px;min-height:44px;display:inline-flex;align-items:center;justify-content:center;background:none;border:0;color:var(--text);font-size:1.2rem;text-decoration:none;cursor:pointer}
.btn,button.btn{display:inline-flex;align-items:center;justify-content:center;min-height:44px;padding:0 18px;border-radius:8px;border:1px solid var(--line);background:var(--surface2);color:var(--text);font:inherit;font-weight:600;text-decoration:none;cursor:pointer}
.btn.primary{background:var(--accent);border-color:var(--accent);color:var(--accent-ink)}
.btn:disabled{opacity:.5;cursor:default}
.btn.block{display:flex;width:100%}
input,select,textarea{width:100%;min-height:44px;padding:8px 12px;border-radius:8px;border:1px solid var(--line);background:var(--bg);color:var(--text);font:inherit}
label{display:block;margin:1rem 0 .3rem;color:var(--muted);font-size:.9rem}
.stack>*+*{margin-top:12px}
.card{background:var(--surface);border:1px solid var(--line);border-radius:12px;overflow:hidden}
.card .body{padding:12px 16px}
.adv{display:flex;gap:12px;padding:12px;align-items:stretch}
.adv img,.adv .nocover{width:72px;height:96px;object-fit:cover;border-radius:6px;background:var(--surface2);flex:none}
.adv .info{flex:1;min-width:0;display:flex;flex-direction:column;gap:6px}
.adv h3{margin:0;font-size:1.1rem}
.badge{align-self:flex-start;font-size:.75rem;padding:2px 8px;border-radius:99px;background:var(--surface2);color:var(--muted);text-transform:uppercase;letter-spacing:.04em}
.badge.ready{color:var(--ok)}.badge.error{color:var(--danger)}.badge.importing{color:var(--accent)}
.drop{border:2px dashed var(--line);border-radius:12px;padding:24px 16px;text-align:center;color:var(--muted)}
.drop.over{border-color:var(--accent);color:var(--text)}
.row{display:flex;gap:8px;flex-wrap:wrap}.row>*{flex:1 1 9rem}
.group summary{min-height:44px;display:flex;align-items:center;cursor:pointer}
.group ul{margin:0 0 8px;padding-left:1.2rem;font-size:.85rem;color:var(--muted)}
progress{width:100%;height:12px;accent-color:var(--accent)}
.table-wrap{overflow-x:auto}table{border-collapse:collapse}td,th{border:1px solid var(--line);padding:4px 8px;text-align:left}
dl.stats{display:grid;grid-template-columns:1fr auto;gap:6px 12px;margin:0}dl.stats dd{margin:0;font-weight:600;text-align:right}
.warn{font-size:.9rem;color:var(--accent)}
.vh{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.btn:focus-within{outline:2px solid var(--accent);outline-offset:2px}
.sticky-note{margin:12px 0}
.abil{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;text-align:center}
.abil div{background:var(--surface);border:1px solid var(--line);border-radius:8px;padding:8px 4px}
.abil b{display:block;font-size:1.3rem}.abil small{display:block;color:var(--muted);text-transform:uppercase}
.cols{columns:2 9rem;column-gap:16px;margin:0;padding:0;list-style:none}.cols li{break-inside:avoid;padding:2px 0}
.pill{display:inline-block;margin:0 6px 6px 0;padding:2px 10px;border-radius:99px;background:var(--surface2)}
.card.adv .nocover{display:flex;align-items:center;justify-content:center;font-size:2rem;color:var(--muted)}
[hidden]{display:none!important}
input[type=range]{accent-color:var(--accent);border:0;padding:0;background:none}
/* play page */
.play header{padding-top:env(safe-area-inset-top)}
.play .bar{gap:0}
.hp{flex:1;font-weight:700;padding:8px 4px;white-space:nowrap;transform-origin:left}.hp.low{color:var(--danger)}
#hp.hurt{animation:hp-hurt 1.4s ease-out}#hp.heal{animation:hp-heal 1.4s ease-out} /* bar() in play.js: HP just changed */
@keyframes hp-hurt{0%,35%{color:var(--danger);transform:scale(1.15)}}@keyframes hp-heal{0%,35%{color:var(--ok);transform:scale(1.1)}}
/* ♪: filled accent with a pulsing dot while the audio really plays; struck through and muted when it doesn't */
#music{position:relative;border-radius:50%}
#music[aria-pressed=true]{background:var(--accent);color:var(--accent-ink);box-shadow:inset 0 0 0 5px var(--surface)}
#music[aria-pressed=true]::after{content:"";position:absolute;top:7px;right:7px;width:8px;height:8px;border-radius:50%;background:var(--ok);border:2px solid var(--surface);animation:pulse 1.6s ease-in-out infinite}
#music[aria-pressed=false]{color:var(--muted)}
#music[aria-pressed=false]::before{content:"";position:absolute;width:22px;height:2px;background:currentColor;transform:rotate(-45deg)}
@keyframes pulse{50%{opacity:.3}}
.resume{position:fixed;z-index:6;top:calc(60px + env(safe-area-inset-top));right:12px;border-radius:99px;box-shadow:0 2px 10px rgba(0,0,0,.6)}
.play{display:flex;flex-direction:column;min-height:100vh;min-height:100dvh;padding-bottom:var(--kb,0px)} /* --kb: an iOS keyboard (play-scroll.js) */
.play main{flex:1;width:100%;padding-bottom:4rem} /* 4rem: the story's end (its choices) scrolls clear of the bug icon */
.blk{padding-top:.4rem}.blk+.blk{border-top:1px solid var(--line);margin-top:1rem}
details.fold{border-bottom:1px solid var(--line)}
details.fold>summary{min-height:44px;display:flex;align-items:center;color:var(--muted);cursor:pointer}
.chap{display:flex;align-items:center;gap:12px;margin:1.4rem 0 .2rem;color:var(--muted);font:600 .75rem/1 var(--sans);letter-spacing:.14em;text-transform:uppercase}
.chap::before,.chap::after{content:"";flex:1;height:1px;background:var(--line)}
/* the story (play-view.js): the book in serif; the DM's narration italic on an accent bar; an answer to the player's question
   in sans after "DM:"; the player's words in a bubble; rolls as compact lines (player amber, foes blue); chips */
.ev{margin:.6rem 0}
.ev.dm{border-left:3px solid var(--accent);padding:1px 0 1px 12px}
.ev.dm,.ev.dm p{font-family:var(--serif);font-style:italic;font-size:1.05rem;line-height:1.6;color:#d9d1c1}
.ev.dm p,.ev.ans p{margin:.4rem 0}
.ev.ans{background:var(--surface);border:1px solid var(--line);border-radius:10px;padding:4px 12px;line-height:1.5}
.ev.ans>:first-child::before{content:"DM: ";font-weight:700;color:var(--accent)}
.ev.you{width:fit-content;max-width:85%;margin-left:auto;padding:8px 12px;border-radius:14px 14px 4px 14px;background:var(--surface2)}
.ev.rolls{list-style:none;padding:0;display:grid;gap:4px}
.r{padding:5px 10px;border-left:3px solid var(--line);border-radius:0 8px 8px 0;background:var(--surface);font-size:.88rem;line-height:1.45;font-variant-numeric:tabular-nums}
.r.me{border-left-color:var(--accent)}.r.foe{border-left-color:var(--foe)}
.r .lbl{font-weight:600}.r .x{color:var(--muted)}
.r .nat{padding:0 6px;border:1px solid currentColor;border-radius:99px;font-size:.75rem;font-weight:700;white-space:nowrap}
.r.crit{background:rgba(224,163,58,.14)}.r.crit .nat{color:var(--accent)}.r.fumble .nat{color:var(--danger)}
.out{font-weight:700}.out.good{color:var(--ok)}.out.bad{color:var(--danger)}.out.meh{color:var(--muted)}
.void{color:var(--muted);text-decoration:line-through}
.chip{display:inline-block;margin:0 6px 6px 0;padding:3px 10px;border-radius:99px;background:var(--surface2);font-size:.9rem}
.chip.hurt{background:rgba(226,109,92,.16);box-shadow:inset 0 0 0 1px rgba(226,109,92,.55);color:var(--danger);font-weight:700}
.chip.heal{color:var(--ok)}.chip.foe{color:var(--foe)}
/* story images: a tap opens the lightbox (lightbox.js); a stat block is a card showing its top */
.pic{display:block;width:100%;margin:12px 0;padding:0;border:0;background:none;color:inherit;font:inherit;cursor:zoom-in}
.pic img{display:block;max-width:100%;max-height:55vh;height:auto;margin:0 auto;border-radius:8px;object-fit:contain}
.pic.sb-maybe img,.pic.sb img{width:100%;height:132px;max-height:none;object-fit:cover;object-position:top;border-radius:0}
.pic.sb{border:1px solid var(--line);border-radius:12px;overflow:hidden;background:var(--surface)}
.sb-label{display:none}
.pic.sb .sb-label{display:flex;justify-content:space-between;align-items:center;min-height:44px;padding:0 14px;border-top:1px solid var(--line);font-weight:600}
.sb-label small{color:var(--muted);font-weight:400;font-size:.85rem}
.ov-body:has(>.lb){padding:0;overflow:hidden}
.lb{width:100%;height:100%;overflow:hidden;touch-action:none;background:#000;cursor:grab}
.lb img{display:block;width:100%;height:100%;object-fit:contain;transform-origin:0 0;user-select:none;-webkit-user-select:none}
.card.end{margin:1rem 0}.card.end h2{margin-top:0}.card.end .row{margin-top:12px}.card.end .btn{white-space:nowrap}
footer.act{position:sticky;bottom:var(--kb,0px);z-index:5;background:var(--surface);border-top:1px solid var(--line);padding:8px max(16px,env(safe-area-inset-right)) calc(8px + env(safe-area-inset-bottom)) max(16px,env(safe-area-inset-left))}
footer.act .inner{max-width:42rem;margin:0 auto;display:grid;grid-template-columns:minmax(0,1fr);gap:8px} /* minmax: the chip row scrolls inside, never widens the page */
#thinking,#unsent{margin:0;display:flex;flex-wrap:wrap;align-items:center;gap:0 6px}
#thinking{color:var(--accent);font-style:italic}#thinking .link{font-style:normal}
.link{min-height:44px;padding:0 8px;background:none;border:0;color:var(--accent);font:inherit;text-decoration:underline;cursor:pointer}
/* choices sit at the story's end, never in a scroll box of their own */
#choices{display:grid;gap:8px;margin:1rem 0}#choices:empty{display:none}
#choices .btn{justify-content:flex-start;text-align:left;padding:10px 14px;font-weight:500}
#rollbar{display:grid;gap:6px;justify-items:center}#rollbar:empty{display:none}
/* combat strip (play-combat.js): each foe's HP; quick actions fill the text box */
#combat:empty{display:none}
.foes{display:grid;grid-template-columns:repeat(auto-fit,minmax(9.5rem,1fr));gap:6px 14px}
.enemy{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:2px 8px;font-size:.85rem}
.enemy .nm{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:600}
.enemy .n{grid-row:1;grid-column:2;color:var(--muted);font-variant-numeric:tabular-nums}
.hpbar{grid-column:1/-1;height:6px;border-radius:3px;background:var(--surface2);overflow:hidden}
.hpbar i{display:block;height:100%;border-radius:3px;background:var(--foe)}
.enemy.down{opacity:.5}.enemy.down .nm{text-decoration:line-through}
.qa{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px} /* wraps: every quick action stays visible (a hidden-scrollbar row cut them off) */
.qchip{flex:none;min-height:44px;padding:0 12px;border:1px solid var(--line);border-radius:99px;background:var(--surface2);color:var(--text);font:inherit;font-size:.9rem;white-space:nowrap;cursor:pointer}
.qchip:disabled{opacity:.5;cursor:default}
.btn.roll{min-height:56px;padding:10px 14px;font-size:1.1rem}
#latest{position:absolute;left:50%;bottom:calc(100% + 12px);transform:translateX(-50%);border-radius:99px;box-shadow:0 2px 10px rgba(0,0,0,.6);white-space:nowrap}
.say{display:flex;gap:8px;align-items:flex-end}
.say textarea{flex:1;resize:none;min-height:44px;max-height:calc(5.6em + 18px);line-height:1.4} /* grows to 4 lines (play.js), then scrolls */
.say .btn{flex:none}
/* overlay (overlay.js): side panel, full screen on phones and when .wide */
dialog.ov{padding:0;margin:0 0 0 auto;width:100%;max-width:28rem;height:100dvh;max-height:100dvh;border:0;border-left:1px solid var(--line);background:var(--bg);color:var(--text)}
dialog.ov[open]{display:flex;flex-direction:column;animation:ov-in .18s ease-out}
dialog.ov.wide{max-width:none;border:0}
dialog.ov::backdrop{background:rgba(0,0,0,.6)}
@media (max-width:600px){dialog.ov{max-width:none;border:0}}
@keyframes ov-in{from{transform:translateX(40px);opacity:.3}}
@media (prefers-reduced-motion:reduce){dialog.ov[open],#music::after,#hp{animation:none!important}}
:root:has(dialog.ov[open]){overflow:hidden}
.ov-head{display:flex;align-items:center;gap:8px;min-height:52px;padding:env(safe-area-inset-top) 4px 0 16px;border-bottom:1px solid var(--line);background:var(--surface)}
.ov-head h2{flex:1;margin:0;font-size:1.15rem}
.ov-body{flex:1;overflow-y:auto;overscroll-behavior:contain;padding:12px 16px calc(24px + env(safe-area-inset-bottom))}
.ov-body:has(>iframe){padding:0;overflow:hidden}
.ov-body>iframe{display:block;width:100%;height:100%;border:0}
.ov-body>.btn+.btn{margin-top:8px}
.embed #top,.embed main>h1:first-child{display:none}
.mhead{font:600 .75rem/1.2 var(--sans);text-transform:uppercase;letter-spacing:.06em;color:var(--muted);margin:1.2rem 0 .5rem}
.ov-body>.mhead:first-child{margin-top:.2rem}
.mgrid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}
.mgrid .btn{padding:8px 12px;text-align:center}
.btn.track[aria-current=true]{border-color:var(--accent);color:var(--accent)}
/* character sheet (sheet.js) */
.sheet h2.nm{margin:0;font-size:1.25rem}
.sheet h3{font-size:1rem;margin:1rem 0 .2rem}
.note{background:var(--surface);border:1px solid var(--line);border-radius:8px;padding:8px 12px;display:flex;gap:8px;align-items:center;flex-wrap:wrap}
details.sec{border-bottom:1px solid var(--line)}
details.sec>summary{min-height:52px;display:flex;align-items:center;font:600 1.05rem var(--serif);cursor:pointer;list-style:none}
details.sec>summary::-webkit-details-marker{display:none}
details.sec>summary::after{content:"\25BE";margin-left:auto;color:var(--muted);transition:transform .15s}
details.sec:not([open])>summary::after{transform:rotate(-90deg)}
.sec-body{padding:0 0 12px}
.line{display:flex;flex-wrap:wrap;align-items:flex-start;gap:8px;border-top:1px solid var(--line)}
.line:first-of-type{border-top:0}
.line>.desc{flex:1 1 9rem;min-width:0} /* the buttons wrap to their own line before the name gets narrower than 9rem (phones) */
.desc>summary,div.desc{min-height:44px;display:flex;align-items:center;gap:6px;flex-wrap:wrap;cursor:pointer}
div.desc{cursor:default}
.desc>summary{list-style:none}.desc>summary::-webkit-details-marker{display:none}
.desc>summary::after{content:"\25B8";color:var(--muted);font-size:.8rem}
.desc[open]>summary::after{content:"\25BE"}
.dtext{white-space:pre-line;font-size:.92rem;color:var(--muted);padding:0 0 10px}
.ctl{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:4px;flex:none;max-width:100%;margin-left:auto}
.mini{min-width:44px;min-height:44px;border-radius:8px;border:1px solid var(--line);background:var(--surface2);color:var(--text);font:inherit;font-weight:700;cursor:pointer}
.mini:disabled{opacity:.35;cursor:default}
.mini[aria-pressed=true]{background:var(--accent);color:var(--accent-ink)}
.inl{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin:8px 0}
.inl label,.inl .lbl{margin:0;width:6.5rem;flex:none;color:var(--muted);font-size:.95rem}
.inl input{flex:1 1 4rem;min-width:0;width:auto}.inl input.qty{flex:0 1 5rem}.inl select{flex:0 1 5rem;width:auto}
.inl .n{min-width:2ch;text-align:center}.inl .btn{padding:0 12px}
.inl .chip{display:inline-flex;align-items:center;gap:2px;margin:0;padding:0 0 0 10px}
.inl .chip .mini{border:0;background:none;min-width:36px}
.sheet .row{margin:8px 0}.sheet .foot{margin-top:20px}
.sh-status{position:sticky;bottom:0;margin:0;padding:8px 0;background:var(--bg);border-top:1px solid var(--line);color:var(--accent)}.sh-status:empty{display:none}
.btn.rw{justify-content:flex-start;text-align:left;padding:8px 14px;font-weight:400}
/* AI log */
pre{white-space:pre-wrap;overflow-wrap:anywhere;font-size:.8rem;background:var(--bg);border:1px solid var(--line);border-radius:6px;padding:8px;margin:4px 0;max-height:60vh;overflow-y:auto}
details.turn>summary{min-height:44px;padding:10px 16px;cursor:pointer}
.call{padding:8px 16px;border-top:1px solid var(--line)}
.call h3{font-size:.95rem;margin:.6rem 0 .2rem}.call ul{padding-left:1.2rem;margin:0}
details.raw>summary{min-height:44px;display:flex;align-items:center;cursor:pointer;color:var(--muted)}
.models{margin:8px 0 0;padding-left:1.2rem;color:var(--muted);font-size:.9rem}

.rwrow{margin:0 0 6px}.rwask{margin:0 0 6px}
.row>.del{flex:0 0 auto;margin-left:auto;color:var(--danger);text-decoration:none;font-size:.9rem}
/* bug widget (bug.js): a round icon bottom right, lifted over a page's bottom bar (--bug-lift: its height, safe area included) and an iOS keyboard (--kb) */
.bug-btn{position:fixed;z-index:6;right:max(12px,env(safe-area-inset-right));bottom:calc(12px + max(var(--bug-lift,0px),env(safe-area-inset-bottom)) + var(--kb,0px));width:44px;height:44px;padding:0;border-radius:50%;display:flex;align-items:center;justify-content:center;border:1px solid var(--line);background:var(--surface2);color:var(--muted);box-shadow:0 2px 10px rgba(0,0,0,.5);cursor:pointer}
.bug-btn:hover,.bug-btn:focus-visible{color:var(--text)}.bug-btn[aria-busy=true]{cursor:progress;opacity:.6}
dialog.bugd{width:min(32rem,calc(100% - 24px));max-height:calc(100dvh - 24px);padding:16px;border:1px solid var(--line);border-radius:12px;background:var(--surface);color:var(--text)}
dialog.bugd::backdrop{background:rgba(0,0,0,.6)}
.bugd h2{margin:0 0 .4rem}
.bugd .chk{display:flex;align-items:center;gap:10px;min-height:44px;margin:.4rem 0 0;color:var(--text);font-size:1rem;cursor:pointer}
.bugd .chk input{width:20px;height:20px;min-height:0;margin:0;accent-color:var(--accent)}
.bugd img{display:block;max-width:100%;max-height:6rem;border:1px solid var(--line);border-radius:6px}
.bug-auto{margin:0;padding-left:1.2rem;color:var(--muted);font-size:.9rem}
.bug-msg{margin:12px 0 0}.bug-msg:empty{display:none}
.bugd .row{margin-top:12px}
/* admin page (admin.html, js/admin/): a left menu on wide screens, a top bar on a phone; the banners on top of every page */
.bar .adm-link{font-size:.95rem;padding:0 8px}
.adm main{max-width:56rem}
.side{display:flex;gap:4px;overflow-x:auto;padding:6px 16px;border-bottom:1px solid var(--line);background:var(--surface)}
.side a{flex:none;min-height:44px;display:flex;align-items:center;padding:0 14px;border-radius:8px;color:var(--text);text-decoration:none}
.side a[aria-current=page]{background:var(--surface2);color:var(--accent);font-weight:600}
@media (min-width:760px){
.adm{display:grid;grid-template-columns:11rem minmax(0,1fr);align-items:start}
.adm main{margin:0;width:100%}
.side{flex-direction:column;position:sticky;top:53px;min-height:calc(100vh - 53px);padding:16px 8px;border:0;border-right:1px solid var(--line);background:none}
}
.banners:not(:empty){display:grid;gap:6px;margin-top:12px}
.banner{display:block;padding:10px 14px;border-radius:8px;border-left:4px solid var(--accent);background:var(--surface);color:var(--text);text-decoration:none}
.banner.alert{border-left-color:var(--danger)}.banner.more{margin:0;color:var(--muted)}
.metrics{display:grid;grid-template-columns:repeat(auto-fit,minmax(14rem,1fr));gap:12px}
.metric h2{margin:0 0 .5rem;font-size:1.05rem}.metric dt{white-space:nowrap}.metric .warn{margin:.5rem 0 0}
.item h3{margin:.3rem 0}.item .tags{margin:0}.item.shut{opacity:.7}
a.card.link{display:block;color:var(--text);text-decoration:none}
dl.ctx{display:grid;grid-template-columns:minmax(5rem,max-content) minmax(0,1fr);gap:4px 12px;margin:0}dl.ctx dt{color:var(--muted)}dl.ctx dd{margin:0}
.txt{white-space:pre-wrap}
.shot{display:block;max-width:100%;max-height:70vh;border:1px solid var(--line);border-radius:8px}
.comments{list-style:none;padding:0}.comments li{border-top:1px solid var(--line);padding:4px 0}.comments p{margin:.3rem 0}
