/* ===== Dungeon Crawler: Floor One — UI theme (dark metal + gold, painterly) ===== */
:root {
  --gold: #d4a94a; --gold-2: #f3d389; --gold-d: #7a5a1e; --ink: #0b0908; --panel: rgba(16, 12, 10, 0.92); --panel-2: rgba(28, 22, 18, 0.95);
  --text: #efe6d6; --muted: #a99d8a; --hp: #c8312e; --hp2: #ff6b5a; --mp: #2f6fd6; --mp2: #6aa8ff; --xp: #b78cff;
  --safe-t: env(safe-area-inset-top, 0px); --safe-b: env(safe-area-inset-bottom, 0px); --safe-l: env(safe-area-inset-left, 0px); --safe-r: env(safe-area-inset-right, 0px);
  --r-common: #d6d3cf; --r-uncommon: #4ade80; --r-rare: #60a5fa; --r-epic: #c084fc; --r-legendary: #fb923c; --r-celestial: #f472b6;
  --serif: 'Cinzel', 'Trajan Pro', Georgia, 'Times New Roman', serif; --sans: 'Inter', -apple-system, 'SF Pro Text', system-ui, sans-serif;
}
* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body { margin: 0; height: 100%; background: #050407; color: var(--text); font-family: var(--sans); overflow: hidden; overscroll-behavior: none; touch-action: none; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }
/* QA P0-4: kill double-tap zoom without swallowing taps (replaces the old touchend preventDefault hack) */
button, a, label, input, select, textarea, .btn, .choice, .act, .unit, .tab { touch-action: manipulation; }
button { font: inherit; color: inherit; }
#app { position: fixed; inset: 0; overflow: hidden; }
canvas#world { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.vignette { position: absolute; inset: 0; pointer-events: none; background: radial-gradient(ellipse at center, transparent 45%, rgba(0,0,0,0.55) 80%, rgba(0,0,0,0.9) 100%); }
.grain { position: absolute; inset: 0; pointer-events: none; opacity: .06; mix-blend-mode: overlay; background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>"); }
.hidden { display: none !important; }

/* ---------- ornate frame ---------- */
.frame { position: relative; background: linear-gradient(180deg, rgba(34,27,22,.96), rgba(12,9,8,.96)); border: 1px solid #000; border-radius: 10px;
  box-shadow: 0 0 0 1px var(--gold-d), 0 0 0 2px #1a130d, 0 0 0 3px rgba(212,169,74,.55), 0 10px 30px rgba(0,0,0,.7), inset 0 1px 0 rgba(255,230,180,.08), inset 0 0 30px rgba(0,0,0,.6); }
.frame::before, .frame::after { content: ''; position: absolute; width: 14px; height: 14px; border: 2px solid var(--gold); transform: rotate(45deg); background: #120d09; top: -8px; left: calc(50% - 7px); box-shadow: 0 0 8px rgba(212,169,74,.5); }
.frame::after { top: auto; bottom: -8px; }
.frame.nocap::before, .frame.nocap::after { display: none; }
.title-font { font-family: var(--serif); letter-spacing: .04em; }
.gold { color: var(--gold-2); text-shadow: 0 0 12px rgba(212,169,74,.35), 0 2px 0 #000; }

/* ---------- HUD ---------- */
#hud { position: absolute; inset: 0; pointer-events: none; }
#hud > * { pointer-events: auto; }
/* QA2 P1-1: decorative / transient HUD layers never take touches (the id rule above would otherwise beat their own class rule) */
#hud > .regiontitle, #hud > .roomname, #hud > .syslog, #hud > .syslog *, #hud > .banner, #hud .banner *, #hud > .toast, #hud > .viewerpop { pointer-events: none; }
#hud .party { position: absolute; left: calc(8px + var(--safe-l)); top: calc(8px + var(--safe-t)); display: flex; flex-direction: column; gap: 6px; }
.pframe { display: flex; gap: 8px; align-items: center; padding: 5px 9px 5px 5px; min-width: 188px; border-radius: 8px; cursor: pointer; }
.pframe .port { width: 46px; height: 46px; border-radius: 6px; overflow: hidden; border: 2px solid var(--gold-d); box-shadow: 0 0 0 1px #000, inset 0 0 10px #000; flex: none; background: #1a1411 center/cover; position: relative; }
.pframe .port img { width: 100%; height: 100%; object-fit: cover; }
.pframe .lvl { position: absolute; right: -2px; bottom: -2px; background: #120d09; border: 1px solid var(--gold); color: var(--gold-2); font: 700 10px var(--serif); padding: 0 4px; border-radius: 4px; }
.pframe .pts { position: absolute; left: -3px; top: -3px; width: 14px; height: 14px; border-radius: 50%; background: #facc15; color: #000; font: 800 10px var(--sans); display: grid; place-items: center; box-shadow: 0 0 8px #facc15; animation: pulse 1.2s infinite; }
.pframe .info { flex: 1; min-width: 0; }
.pframe .nm { font: 700 12px var(--serif); color: var(--gold-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: flex; justify-content: space-between; gap: 6px; }
.pframe .nm small { color: var(--muted); font: 600 10px var(--sans); }
.bar { position: relative; height: 11px; margin-top: 3px; border-radius: 3px; background: #0a0706; border: 1px solid #000; box-shadow: inset 0 1px 3px #000, 0 0 0 1px rgba(212,169,74,.25); overflow: hidden; }
.bar > i { position: absolute; inset: 0; transform-origin: left; transition: transform .35s cubic-bezier(.2,.8,.2,1); }
.bar > i.ghost { background: rgba(255,240,200,.55); transition: transform .9s .25s ease-out; }
.bar.hp > i.fill { background: linear-gradient(180deg, var(--hp2), var(--hp) 55%, #6e1411); }
.bar.mp > i.fill { background: linear-gradient(180deg, var(--mp2), var(--mp) 55%, #12306a); }
.bar.xp { height: 5px; } .bar.xp > i.fill { background: linear-gradient(90deg, #6d28d9, var(--xp)); }
.bar span { position: absolute; inset: 0; font: 700 9px/11px var(--sans); text-align: center; color: #fff; text-shadow: 0 1px 2px #000; }
.statusrow { display: flex; gap: 2px; margin-top: 2px; font-size: 11px; min-height: 0; }

.topright { position: absolute; right: calc(8px + var(--safe-r)); top: calc(8px + var(--safe-t)); display: flex; flex-direction: column; align-items: center; gap: 4px; }
.minimap { width: 112px; height: 112px; border-radius: 50%; position: relative; cursor: pointer; padding: 0; }
.minimap canvas { width: 100%; height: 100%; border-radius: 50%; display: block; }
.minimap .ring { position: absolute; inset: -6px; border-radius: 50%; border: 3px solid var(--gold-d); box-shadow: 0 0 0 1px #000, 0 0 0 4px #1a130d, 0 0 0 5px rgba(212,169,74,.6), 0 6px 20px rgba(0,0,0,.8), inset 0 0 18px #000; pointer-events: none; }
.minimap .n { position: absolute; top: -10px; left: 50%; transform: translateX(-50%); font: 700 10px var(--serif); color: var(--gold-2); background: #120d09; border: 1px solid var(--gold-d); border-radius: 3px; padding: 0 4px; }
.chip { font: 700 11px var(--sans); padding: 3px 8px; border-radius: 999px; background: rgba(10,8,7,.85); border: 1px solid rgba(212,169,74,.45); color: var(--text); display: flex; gap: 6px; align-items: center; white-space: nowrap; box-shadow: 0 2px 8px #000; }
.chip.timer { font: 700 13px var(--serif); color: #ffd7a3; }
.chip.timer.warn { color: #ff8f7a; border-color: #ef4444; animation: pulse 1s infinite; }
.chip.views { color: #f9a8d4; }
.chip.gold { color: #fde68a; }

.regiontitle { position: absolute; left: 50%; top: 22%; transform: translateX(-50%); text-align: center; pointer-events: none; opacity: 0; transition: opacity .8s; width: 90%; }
.regiontitle.show { opacity: 1; }
.regiontitle h2 { margin: 0; font: 700 clamp(22px, 6vw, 40px) var(--serif); color: var(--gold-2); text-shadow: 0 0 20px rgba(212,169,74,.4), 0 3px 0 #000, 0 0 40px #000; letter-spacing: .08em; }
.regiontitle p { margin: 4px 0 0; font: 600 12px var(--sans); color: var(--muted); letter-spacing: .2em; text-transform: uppercase; text-shadow: 0 2px 4px #000; }
.regiontitle .rule { height: 1px; width: 60%; margin: 8px auto; background: linear-gradient(90deg, transparent, var(--gold), transparent); }
.roomname { position: absolute; left: 50%; top: calc(132px + var(--safe-t)); transform: translateX(-50%); font: 600 13px var(--serif); color: #e8d9b8; text-shadow: 0 2px 4px #000; opacity: 0; transition: opacity .6s; pointer-events: none; white-space: nowrap; }
.roomname.show { opacity: .9; }

.banner { position: absolute; left: 50%; top: calc(10px + var(--safe-t)); transform: translate(-50%, -160%); transition: transform .6s cubic-bezier(.2,1.4,.3,1); z-index: 30; display: flex; align-items: center; gap: 12px; padding: 10px 22px 10px 12px; min-width: 260px; max-width: min(92vw, 560px); pointer-events: none; }
.banner.show { transform: translate(-50%, 0); opacity: 1; visibility: visible; }
#hud .banner:not(.show) { opacity: 0; visibility: hidden; transition: transform .6s, opacity .4s, visibility 0s .6s; }
.banner .crest { width: 48px; height: 52px; flex: none; display: grid; place-items: center; font-size: 24px; background: radial-gradient(circle at 50% 35%, #3a2c1d, #0e0a07); border: 2px solid var(--gold); clip-path: polygon(50% 0, 100% 18%, 100% 70%, 50% 100%, 0 70%, 0 18%); }
.banner h3 { margin: 0; font: 700 18px var(--serif); color: var(--gold-2); text-shadow: 0 2px 0 #000; }
.banner p { margin: 2px 0 0; font: 500 12px var(--sans); color: #e7dccb; }
@media (max-width: 520px) { .banner { top: calc(130px + var(--safe-t)); } }

.syslog { position: absolute; left: calc(8px + var(--safe-l)); right: calc(8px + var(--safe-r)); bottom: calc(92px + var(--safe-b)); display: flex; flex-direction: column; gap: 4px; align-items: center; pointer-events: none; }
.sysmsg { max-width: min(560px, 96%); padding: 7px 12px 7px 34px; position: relative; font: 500 12.5px/1.35 var(--sans); color: #d9f2ff; background: linear-gradient(90deg, rgba(8,20,30,.92), rgba(8,14,22,.85)); border: 1px solid rgba(96,165,250,.45); border-radius: 6px; box-shadow: 0 0 18px rgba(56,189,248,.15), 0 4px 12px #000; animation: sysin .4s ease-out; transition: opacity .6s, transform .6s; }
.sysmsg::before { content: 'SYS'; position: absolute; left: 6px; top: 8px; font: 800 8px var(--sans); color: #38bdf8; letter-spacing: .1em; }
.sysmsg.out { opacity: 0; transform: translateY(-6px); }
@keyframes sysin { from { opacity: 0; transform: translateY(8px) scale(.98); } to { opacity: 1; transform: none; } }

.hotbar { position: absolute; left: 50%; bottom: calc(10px + var(--safe-b)); transform: translateX(-50%); display: flex; gap: 6px; padding: 8px 10px; align-items: flex-end; }
.slot { width: 54px; height: 54px; border-radius: 8px; position: relative; display: grid; place-items: center; font-size: 22px; cursor: pointer; border: 1px solid #000; background: radial-gradient(circle at 50% 30%, #3a2e24, #140f0c 75%); box-shadow: 0 0 0 1px var(--gold-d), inset 0 0 12px #000, inset 0 1px 0 rgba(255,220,170,.15); transition: transform .08s, box-shadow .2s; }
.slot:active { transform: scale(.92); }
.slot .k { position: absolute; bottom: -1px; left: 50%; transform: translateX(-50%); font: 700 8.5px var(--sans); color: var(--muted); background: #0b0807; padding: 0 3px; border-radius: 3px; border: 1px solid #2a2118; white-space: nowrap; }
.slot .q { position: absolute; right: 3px; top: 2px; font: 800 10px var(--sans); color: #fff; text-shadow: 0 1px 2px #000; }
.slot.glow { box-shadow: 0 0 0 1px var(--gold), 0 0 14px rgba(250,204,21,.6), inset 0 0 12px #000; animation: blink 1.4s infinite; }
.slot.dis { opacity: .4; }
.slot .badge { position: absolute; right: -4px; top: -4px; background: #dc2626; color: #fff; font: 800 10px var(--sans); border-radius: 999px; min-width: 16px; height: 16px; display: grid; place-items: center; padding: 0 3px; box-shadow: 0 0 8px #dc2626; }
.menubtns { position: absolute; right: calc(8px + var(--safe-r)); bottom: calc(80px + var(--safe-b)); display: flex; flex-direction: column; gap: 6px; }
.menubtns .slot { width: 46px; height: 46px; font-size: 19px; }
.questbox { position: absolute; left: calc(8px + var(--safe-l)); top: calc(118px + var(--safe-t)); display: flex; flex-direction: column; gap: 4px; max-width: 220px; pointer-events: none; }
.quest { font: 600 11px var(--sans); padding: 5px 8px; border-radius: 6px; background: rgba(10,16,28,.85); border: 1px solid rgba(96,165,250,.5); color: #cfe6ff; }
.quest b { color: #93c5fd; }
@media (orientation: landscape) and (max-height: 520px) {
  .syslog { bottom: calc(76px + var(--safe-b)); left: 30%; right: 30%; }
  .menubtns { bottom: calc(10px + var(--safe-b)); flex-direction: row; }
  .hotbar { left: 50%; }
  .minimap { width: 96px; height: 96px; }
  .questbox { top: auto; bottom: calc(80px + var(--safe-b)); }
  .regiontitle { top: 30%; }
}

.joy { position: absolute; width: 120px; height: 120px; margin: -60px 0 0 -60px; border-radius: 50%; border: 2px solid rgba(212,169,74,.45); background: radial-gradient(circle, rgba(212,169,74,.08), rgba(0,0,0,.25)); pointer-events: none; z-index: 20; }
.joy i { position: absolute; left: 50%; top: 50%; width: 50px; height: 50px; margin: -25px; border-radius: 50%; background: radial-gradient(circle at 40% 35%, #f3d389, #7a5a1e); box-shadow: 0 0 14px rgba(212,169,74,.6); }
.tapmark { position: absolute; width: 30px; height: 30px; margin: -15px; border: 2px solid var(--gold-2); border-radius: 50%; pointer-events: none; animation: tapping .5s ease-out forwards; z-index: 19; }
@keyframes tapping { from { transform: scale(.3); opacity: 1; } to { transform: scale(1.4); opacity: 0; } }
.bark { position: absolute; transform: translate(-50%, -100%); padding: 5px 9px; font: 600 12px var(--sans); color: #1a120b; background: #f6ead2; border-radius: 10px; max-width: 220px; text-align: center; pointer-events: none; box-shadow: 0 4px 12px rgba(0,0,0,.7); animation: sysin .25s; z-index: 25; }
.bark::after { content: ''; position: absolute; left: 50%; bottom: -6px; border: 6px solid transparent; border-top-color: #f6ead2; border-bottom: 0; transform: translateX(-50%); }
.toast { position: absolute; left: 50%; top: calc(50% + 60px); transform: translateX(-50%); font: 600 12px var(--sans); padding: 6px 12px; border-radius: 999px; background: rgba(0,0,0,.8); border: 1px solid rgba(212,169,74,.4); pointer-events: none; animation: sysin .3s; z-index: 40; white-space: nowrap; }
.viewerpop { position: absolute; right: calc(16px + var(--safe-r)); top: calc(170px + var(--safe-t)); font: 800 13px var(--sans); color: #f9a8d4; text-shadow: 0 0 10px rgba(244,114,182,.7), 0 2px 2px #000; pointer-events: none; animation: vpop 1.6s ease-out forwards; z-index: 22; text-align: right; }
.viewerpop small { display: block; font: 600 10px var(--sans); color: #fbcfe8; }
@keyframes vpop { 0% { transform: translateY(10px) scale(.8); opacity: 0; } 15% { transform: none; opacity: 1; } 80% { opacity: 1; } 100% { transform: translateY(-24px); opacity: 0; } }
@keyframes pulse { 0%,100% { filter: brightness(1); } 50% { filter: brightness(1.35); } }

/* ---------- Modals / panels ---------- */
.modal-wrap { position: absolute; inset: 0; z-index: 50; display: grid; place-items: center; background: radial-gradient(ellipse at center, rgba(0,0,0,.55), rgba(0,0,0,.85)); backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px); animation: fadein .25s; padding: calc(10px + var(--safe-t)) calc(8px + var(--safe-r)) calc(10px + var(--safe-b)) calc(8px + var(--safe-l)); }
@keyframes fadein { from { opacity: 0; } to { opacity: 1; } }
.panel { width: min(720px, 100%); max-height: 100%; display: flex; flex-direction: column; animation: panelin .35s cubic-bezier(.2,1.2,.3,1); }
@keyframes panelin { from { transform: translateY(20px) scale(.96); opacity: 0; } to { transform: none; opacity: 1; } }
.panel header { display: flex; align-items: center; gap: 10px; padding: 14px 16px 10px; border-bottom: 1px solid rgba(212,169,74,.25); }
.panel header h2 { margin: 0; flex: 1; font: 700 20px var(--serif); color: var(--gold-2); letter-spacing: .05em; text-shadow: 0 2px 0 #000; }
.panel .x { width: 40px; height: 40px; border-radius: 8px; border: 1px solid var(--gold-d); background: #140f0c; font-size: 18px; cursor: pointer; flex: none; }
.panel .body { padding: 12px 14px 16px; overflow: auto; -webkit-overflow-scrolling: touch; touch-action: pan-y; flex: 1; }
.tabs { display: flex; gap: 4px; padding: 8px 12px 0; overflow-x: auto; touch-action: pan-x; }
.tab { padding: 9px 12px; border-radius: 8px 8px 0 0; background: #1a1411; border: 1px solid #3a2c1f; border-bottom: 0; font: 700 12px var(--serif); color: var(--muted); cursor: pointer; white-space: nowrap; }
.tab.on { background: linear-gradient(#3a2b1c, #1d150f); color: var(--gold-2); border-color: var(--gold-d); }
.btn { min-height: 44px; padding: 10px 16px; border-radius: 8px; cursor: pointer; font: 700 14px var(--serif); letter-spacing: .03em; color: #1b1206; background: linear-gradient(180deg, #f6dc94, #c99a3d 55%, #8f6620); border: 1px solid #2a1c08; box-shadow: 0 0 0 1px rgba(255,230,170,.35) inset, 0 3px 0 #3d2a0c, 0 6px 14px rgba(0,0,0,.5); transition: transform .08s, filter .2s; }
.btn:active { transform: translateY(2px); box-shadow: 0 0 0 1px rgba(255,230,170,.35) inset, 0 1px 0 #3d2a0c; }
.btn.ghost { color: var(--gold-2); background: linear-gradient(180deg, #2a2019, #15100c); border-color: var(--gold-d); box-shadow: 0 0 0 1px rgba(212,169,74,.25) inset, 0 3px 0 #000; }
.btn.danger { background: linear-gradient(180deg, #f87171, #b91c1c 55%, #7f1d1d); color: #fff; }
.btn[disabled] { filter: grayscale(1) brightness(.6); pointer-events: none; }
.btn.small { min-height: 34px; padding: 6px 10px; font-size: 12px; }
.row { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.grid-inv { display: grid; grid-template-columns: repeat(auto-fill, minmax(64px, 1fr)); gap: 6px; }
.icell { aspect-ratio: 1; border-radius: 8px; position: relative; display: grid; place-items: center; font-size: 26px; cursor: pointer; background: radial-gradient(circle at 50% 35%, #2c231c, #110d0a 75%); border: 1px solid #000; box-shadow: 0 0 0 1px var(--rc, #3a2c1f), inset 0 0 14px #000; }
.icell .q { position: absolute; right: 4px; bottom: 2px; font: 800 11px var(--sans); text-shadow: 0 1px 2px #000; }
.icell.sel { box-shadow: 0 0 0 2px var(--gold-2), 0 0 12px rgba(250,204,21,.5), inset 0 0 14px #000; }
.icell .rg { position: absolute; inset: 0; border-radius: 8px; background: radial-gradient(circle at 50% 100%, var(--rc), transparent 60%); opacity: .25; pointer-events: none; }
.detail { margin-top: 12px; padding: 12px; border-radius: 8px; background: rgba(0,0,0,.35); border: 1px solid #3a2c1f; }
.detail h4 { margin: 0 0 4px; font: 700 16px var(--serif); }
.detail .rar { font: 700 10px var(--sans); letter-spacing: .15em; text-transform: uppercase; }
.detail p { margin: 6px 0; font-size: 13px; line-height: 1.45; color: #d8ccb8; }
.detail .fl { font-style: italic; color: var(--muted); }
.mods { display: flex; flex-wrap: wrap; gap: 4px; margin: 6px 0; }
.mods span { font: 700 11px var(--sans); padding: 2px 6px; border-radius: 4px; background: #1b1511; border: 1px solid #3a2c1f; }
.mods .up { color: #86efac; } .mods .dn { color: #fca5a5; }
.equip { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; margin-bottom: 10px; }
.eslot { aspect-ratio: 1; border-radius: 8px; border: 1px dashed #4a3a2a; display: grid; place-items: center; font-size: 22px; position: relative; cursor: pointer; background: rgba(0,0,0,.35); }
.eslot small { position: absolute; bottom: 2px; font: 700 8px var(--sans); color: var(--muted); text-transform: uppercase; letter-spacing: .08em; }
.eslot.f { border-style: solid; box-shadow: 0 0 0 1px var(--rc, #3a2c1f), inset 0 0 12px #000; }
.who { display: flex; gap: 6px; margin-bottom: 10px; overflow-x: auto; }
.who button { display: flex; gap: 6px; align-items: center; padding: 4px 10px 4px 4px; border-radius: 999px; background: #17110d; border: 1px solid #3a2c1f; cursor: pointer; }
.who button.on { border-color: var(--gold); box-shadow: 0 0 10px rgba(212,169,74,.4); }
.who img { width: 30px; height: 30px; border-radius: 50%; object-fit: cover; background: #222; }
.statgrid { display: grid; grid-template-columns: 1fr; gap: 6px; }
.stat { display: grid; grid-template-columns: 54px 1fr 44px 44px; align-items: center; gap: 8px; padding: 6px 8px; border-radius: 8px; background: rgba(0,0,0,.3); border: 1px solid #2b2118; }
.stat b { font: 800 14px var(--serif); }
.stat .v { font: 800 20px var(--serif); text-align: right; }
.stat .d { font-size: 11px; color: var(--muted); }
.plus { width: 40px; height: 40px; border-radius: 50%; font: 800 20px var(--sans); background: radial-gradient(circle at 40% 35%, #fde68a, #b7791f); color: #2a1a05; border: 1px solid #000; cursor: pointer; box-shadow: 0 0 10px rgba(250,204,21,.5); }
.plus[disabled] { opacity: .2; box-shadow: none; }
.derived { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 6px; margin-top: 10px; }
.derived div { padding: 7px 9px; border-radius: 6px; background: rgba(0,0,0,.3); border: 1px solid #2b2118; font-size: 12px; display: flex; justify-content: space-between; }
.derived b { color: var(--gold-2); }
.skillrow { display: grid; grid-template-columns: 42px 1fr; gap: 10px; padding: 9px; border-radius: 8px; background: rgba(0,0,0,.3); border: 1px solid #2b2118; margin-bottom: 6px; }
.skillrow .ic { width: 42px; height: 42px; border-radius: 8px; display: grid; place-items: center; font-size: 22px; background: radial-gradient(circle, #3a2c20, #0d0a08); border: 1px solid var(--gold-d); }
.skillrow h5 { margin: 0; font: 700 14px var(--serif); display: flex; justify-content: space-between; }
.skillrow p { margin: 3px 0 5px; font-size: 12px; color: #cfc2ad; line-height: 1.4; }
.ach { display: grid; grid-template-columns: 40px 1fr; gap: 10px; padding: 9px; border-radius: 8px; background: rgba(0,0,0,.3); border: 1px solid #2b2118; margin-bottom: 6px; }
.ach.locked { opacity: .45; filter: grayscale(.8); }
.ach .ic { font-size: 26px; display: grid; place-items: center; }
.ach h5 { margin: 0; font: 700 13px var(--serif); color: var(--gold-2); }
.ach p { margin: 3px 0 0; font-size: 12px; color: #cfc2ad; }
.boxcard { display: flex; gap: 10px; align-items: center; padding: 10px; border-radius: 10px; background: rgba(0,0,0,.35); border: 1px solid var(--bc, #3a2c1f); margin-bottom: 6px; box-shadow: inset 0 0 20px rgba(0,0,0,.6), 0 0 12px color-mix(in srgb, var(--bc) 30%, transparent); }
.boxcard .ic { width: 52px; height: 52px; border-radius: 10px; display: grid; place-items: center; font-size: 28px; background: radial-gradient(circle at 40% 30%, var(--bc), #0b0806 70%); }
.boxcard .t { flex: 1; }
.boxcard h5 { margin: 0; font: 700 14px var(--serif); }
.boxcard small { color: var(--muted); }
.dialog { display: grid; grid-template-columns: 96px 1fr; gap: 12px; align-items: start; }
.dialog .face { width: 96px; height: 96px; border-radius: 10px; overflow: hidden; border: 2px solid var(--gold-d); box-shadow: 0 0 0 1px #000, 0 0 20px rgba(0,0,0,.8); background: #111 center/cover; }
.dialog .face img { width: 100%; height: 100%; object-fit: cover; }
.dialog .speaker { font: 700 15px var(--serif); color: var(--gold-2); }
.dialog .speaker small { display: block; color: var(--muted); font: 600 11px var(--sans); }
.dialog .text { margin-top: 6px; font-size: 14.5px; line-height: 1.55; color: #eadfcb; min-height: 4.5em; }
.dialog .text .sys, i.sys { color: #9bd7ff; font-style: normal; display: block; margin-top: 6px; font-size: 13px; }
.choices { display: flex; flex-direction: column; gap: 8px; margin-top: 12px; }
.choice { text-align: left; min-height: 48px; padding: 10px 14px; border-radius: 8px; cursor: pointer; font: 600 14px var(--sans); color: #f1e6d2; background: linear-gradient(90deg, rgba(60,45,30,.8), rgba(25,19,14,.85)); border: 1px solid var(--gold-d); display: flex; gap: 10px; align-items: center; }
.choice:active { filter: brightness(1.3); }
.choice .tag { margin-left: auto; font: 800 10px var(--sans); padding: 2px 6px; border-radius: 4px; background: #0d0907; border: 1px solid #4a3a2a; color: #fde68a; white-space: nowrap; }
.choice[disabled] { opacity: .4; }
@media (max-width: 480px) { .dialog { grid-template-columns: 64px 1fr; } .dialog .face { width: 64px; height: 64px; } }

/* ---------- Dice (stat checks) ---------- */
.dice-wrap { display: flex; flex-direction: column; align-items: center; gap: 10px; padding: 10px 0; }
.d20 { width: 120px; height: 120px; position: relative; display: grid; place-items: center; font: 800 44px var(--serif); color: #fff; text-shadow: 0 2px 0 #000; filter: drop-shadow(0 0 18px rgba(212,169,74,.4)); }
.d20::before { content: ''; position: absolute; inset: 0; background: linear-gradient(135deg, #5b3e1f, #20150b); clip-path: polygon(50% 0, 95% 25%, 95% 75%, 50% 100%, 5% 75%, 5% 25%); border: 0; }
.d20::after { content: ''; position: absolute; inset: 6px; background: linear-gradient(135deg, rgba(255,220,160,.25), transparent 60%); clip-path: polygon(50% 0, 95% 25%, 95% 75%, 50% 100%, 5% 75%, 5% 25%); }
.d20 span { position: relative; z-index: 1; }
.d20.rolling { animation: roll .9s cubic-bezier(.2,.8,.3,1); }
.d20.ok { filter: drop-shadow(0 0 22px rgba(74,222,128,.9)); } .d20.no { filter: drop-shadow(0 0 22px rgba(239,68,68,.9)); }
@keyframes roll { 0% { transform: rotate(0) scale(.6); } 70% { transform: rotate(720deg) scale(1.15); } 100% { transform: rotate(720deg) scale(1); } }
.checkline { font: 700 14px var(--serif); color: var(--gold-2); } .checkline.ok { color: #86efac; } .checkline.no { color: #fca5a5; }

/* ---------- Loot box opening ---------- */
.boxstage { position: absolute; inset: 0; z-index: 70; display: grid; place-items: center; background: radial-gradient(circle at 50% 45%, rgba(40,25,10,.6), rgba(0,0,0,.95) 70%); overflow: hidden; }
.boxstage .rays { position: absolute; width: 200vmax; height: 200vmax; left: 50%; top: 45%; margin: -100vmax 0 0 -100vmax; background: repeating-conic-gradient(from 0deg, rgba(255,220,140,.12) 0 6deg, transparent 6deg 18deg); animation: spin 14s linear infinite; opacity: 0; transition: opacity .6s; }
.boxstage.opened .rays { opacity: 1; }
@keyframes spin { to { transform: rotate(360deg); } }
.lootbox { width: 150px; height: 140px; position: relative; cursor: pointer; transform-style: preserve-3d; filter: drop-shadow(0 20px 30px rgba(0,0,0,.8)); }
.lootbox .lid, .lootbox .base { position: absolute; left: 0; right: 0; border-radius: 10px; border: 2px solid #000; }
.lootbox .base { bottom: 0; height: 96px; background: linear-gradient(180deg, var(--bc), color-mix(in srgb, var(--bc) 35%, #000)); box-shadow: inset 0 0 0 4px rgba(0,0,0,.25), inset 0 -20px 30px rgba(0,0,0,.4); }
.lootbox .lid { top: 6px; height: 44px; left: -8px; right: -8px; background: linear-gradient(180deg, color-mix(in srgb, var(--bc) 80%, #fff), var(--bc)); transition: transform .5s cubic-bezier(.3,1.6,.4,1); transform-origin: 10% 100%; }
.lootbox .band { position: absolute; left: calc(50% - 12px); width: 24px; top: 6px; bottom: 0; background: linear-gradient(90deg, #00000055, #ffffff33, #00000055); border-radius: 4px; }
.lootbox .lock { position: absolute; left: calc(50% - 14px); top: 40px; width: 28px; height: 30px; border-radius: 6px; background: radial-gradient(circle at 40% 30%, #fff4c2, #b7791f); border: 2px solid #000; z-index: 2; }
.lootbox.shake { animation: bshake .35s infinite; }
@keyframes bshake { 0%,100% { transform: rotate(0); } 25% { transform: rotate(-6deg) translateY(-3px); } 75% { transform: rotate(6deg) translateY(-3px); } }
.lootbox.open .lid { transform: translateY(-60px) rotate(-35deg); }
.lootbox.open .lock { opacity: 0; transition: opacity .2s; }
.boxstage .label { position: absolute; top: calc(12% + var(--safe-t)); text-align: center; width: 100%; }
.boxstage .label h2 { margin: 0; font: 700 26px var(--serif); color: var(--gold-2); text-shadow: 0 0 20px rgba(212,169,74,.5), 0 3px 0 #000; }
.boxstage .label p { margin: 6px 0 0; color: var(--muted); font-size: 13px; }
.rewards { position: absolute; bottom: calc(14% + var(--safe-b)); left: 0; right: 0; display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; padding: 0 12px; }
.reward { width: 96px; padding: 10px 6px; border-radius: 10px; text-align: center; background: linear-gradient(180deg, rgba(30,24,18,.95), rgba(10,8,6,.95)); border: 1px solid var(--rc); box-shadow: 0 0 20px color-mix(in srgb, var(--rc) 60%, transparent), inset 0 0 20px rgba(0,0,0,.6); opacity: 0; transform: translateY(30px) scale(.7) rotateY(90deg); transition: all .55s cubic-bezier(.2,1.4,.3,1); }
.reward.in { opacity: 1; transform: none; }
.reward .ic { font-size: 30px; }
.reward .nm { font: 700 11px var(--serif); margin-top: 4px; color: var(--rc); line-height: 1.2; }
.reward .rr { font: 800 8px var(--sans); letter-spacing: .14em; text-transform: uppercase; color: var(--muted); margin-top: 3px; }
.tapnote { position: absolute; bottom: calc(5% + var(--safe-b)); width: 100%; text-align: center; font: 600 12px var(--sans); color: var(--muted); letter-spacing: .2em; text-transform: uppercase; animation: pulse 1.6s infinite; }

/* ---------- Combat ---------- */
#combat { position: absolute; inset: 0; z-index: 45; overflow: hidden; background: #050407; }
#combat .arena { position: absolute; inset: 0; background-size: cover; background-position: center; filter: brightness(.55) saturate(.9); transform: scale(1.06); }
#combat .arena-fx { position: absolute; inset: 0; background: radial-gradient(ellipse at 50% 60%, rgba(255,160,80,.14), transparent 60%), radial-gradient(ellipse at center, transparent 35%, rgba(0,0,0,.85) 100%); pointer-events: none; }
#combat .order { position: absolute; top: calc(8px + var(--safe-t)); left: 50%; transform: translateX(-50%); display: flex; gap: 4px; padding: 5px 10px; z-index: 3; max-width: 96vw; overflow: hidden; }
#combat .order .o { width: 34px; height: 34px; border-radius: 50%; overflow: hidden; border: 2px solid #3a2c1f; background: #111 center/cover; flex: none; transition: all .3s; }
#combat .order .o.now { border-color: var(--gold-2); box-shadow: 0 0 12px var(--gold); width: 42px; height: 42px; }
#combat .order .o.enemy { border-color: #7f1d1d; }
#combat .order .o img { width: 100%; height: 100%; object-fit: cover; }
#combat .field { position: absolute; left: 0; right: 0; top: calc(56px + var(--safe-t)); bottom: calc(150px + var(--safe-b)); display: flex; flex-direction: column; justify-content: space-between; }
#combat .side { display: flex; justify-content: center; align-items: flex-end; gap: clamp(4px, 2vw, 22px); padding: 0 8px; flex-wrap: nowrap; }
#combat .side.enemies { padding-top: 8px; }
.unit { position: relative; width: clamp(88px, 26vw, 170px); display: flex; flex-direction: column; align-items: center; cursor: pointer; transition: transform .25s, filter .3s; }
.unit .fig { width: 100%; aspect-ratio: 1; position: relative; display: grid; place-items: end center; }
.unit .fig img { width: 100%; height: 100%; object-fit: contain; filter: drop-shadow(0 10px 12px rgba(0,0,0,.85)); transform-origin: 50% 100%; animation: idle 3s ease-in-out infinite; }
.unit .fig canvas { width: 100%; height: 100%; }
.unit .fig img.cut { border-radius: 50%; object-fit: cover; -webkit-mask-image: radial-gradient(circle, #000 55%, transparent 72%); mask-image: radial-gradient(circle, #000 55%, transparent 72%); }
.unit .shadowd { position: absolute; bottom: 2%; left: 18%; right: 18%; height: 14%; border-radius: 50%; background: radial-gradient(ellipse, rgba(0,0,0,.75), transparent 70%); z-index: -1; }
.unit.boss { width: clamp(150px, 46vw, 300px); }
.unit.elite .fig img { filter: drop-shadow(0 0 10px rgba(250,204,21,.6)) drop-shadow(0 10px 12px rgba(0,0,0,.85)); }
@keyframes idle { 0%,100% { transform: scaleY(1); } 50% { transform: scaleY(1.025) translateY(-1px); } }
.unit .plate { width: 100%; max-width: 150px; margin-top: -4px; padding: 4px 6px; border-radius: 6px; background: rgba(10,8,7,.88); border: 1px solid #3a2c1f; }
.unit .plate .nm { font: 700 11px var(--serif); text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: #efe0c2; }
.unit .plate .nm small { color: var(--muted); font: 600 9px var(--sans); }
.unit.dead { filter: grayscale(1) brightness(.35); transform: scale(.9) translateY(10px); pointer-events: none; }
.unit.dead .fig img { animation: none; }
.unit.active .plate { border-color: var(--gold); box-shadow: 0 0 12px rgba(212,169,74,.6); }
.unit.targetable { animation: tgt 1s infinite; }
.unit.targetable .plate { border-color: #ef4444; }
@keyframes tgt { 0%,100% { filter: drop-shadow(0 0 0 transparent); } 50% { filter: drop-shadow(0 0 12px rgba(239,68,68,.8)); } }
.unit.ally-target.targetable .plate { border-color: #4ade80; }
.unit .intent { position: absolute; top: -6px; left: 50%; transform: translateX(-50%); display: flex; align-items: center; gap: 4px; padding: 3px 8px; border-radius: 999px; background: rgba(12,9,7,.92); border: 1px solid #4a3a2a; font: 700 10px var(--sans); white-space: nowrap; z-index: 3; box-shadow: 0 2px 8px #000; }
.unit .intent.danger { border-color: #ef4444; color: #fecaca; box-shadow: 0 0 14px rgba(239,68,68,.6); animation: pulse .8s infinite; }
.unit .intent b { font-size: 13px; }
.unit .sts { display: flex; gap: 2px; justify-content: center; margin-top: 2px; font-size: 12px; min-height: 14px; }
.unit .sts span { position: relative; }
.unit .sts span small { position: absolute; right: -4px; bottom: -3px; font: 800 8px var(--sans); color: #fff; text-shadow: 0 0 2px #000; }
.unit.lunge-r .fig { animation: lungeR .35s ease; } .unit.lunge-l .fig { animation: lungeL .35s ease; }
.unit.lunge-u .fig { animation: lungeU .35s ease; } .unit.lunge-d .fig { animation: lungeD .35s ease; }
@keyframes lungeU { 50% { transform: translateY(-28px) scale(1.06); } } @keyframes lungeD { 50% { transform: translateY(28px) scale(1.06); } }
@keyframes lungeR { 50% { transform: translateX(28px); } } @keyframes lungeL { 50% { transform: translateX(-28px); } }
.unit.hit .fig { animation: hitk .3s; }

.unit.healed .fig { animation: healg .6s; } @keyframes healg { 50% { filter: brightness(1.6) drop-shadow(0 0 16px #4ade80); } }
.dmgnum { position: absolute; font: 800 26px var(--serif); color: #fff; text-shadow: 0 3px 0 #000, 0 0 10px rgba(0,0,0,.8); pointer-events: none; z-index: 10; animation: dmg 1s cubic-bezier(.2,1.2,.3,1) forwards; white-space: nowrap; }
.dmgnum.crit { font-size: 38px; color: #ffd24a; text-shadow: 0 3px 0 #000, 0 0 18px rgba(255,180,40,.9); }
.dmgnum.heal { color: #86efac; } .dmgnum.miss { color: #cbd5e1; font-size: 18px; } .dmgnum.mana { color: #93c5fd; } .dmgnum.st { font-size: 14px; }
@keyframes dmg { 0% { transform: translate(-50%, 0) scale(.4); opacity: 0; } 20% { transform: translate(-50%, -18px) scale(1.2); opacity: 1; } 100% { transform: translate(-50%, -70px) scale(1); opacity: 0; } }
#combat .actions { position: absolute; left: 0; right: 0; bottom: 0; padding: 8px calc(8px + var(--safe-r)) calc(8px + var(--safe-b)) calc(8px + var(--safe-l)); z-index: 4; }
#combat .actbar { display: grid; grid-template-columns: repeat(5, 1fr); gap: 6px; max-width: 620px; margin: 0 auto; }
#combat .act { min-height: 62px; border-radius: 10px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; font: 700 11px var(--serif); cursor: pointer; color: #f3e3c3; background: radial-gradient(circle at 50% 25%, #43342a, #15100c 75%); border: 1px solid #000; box-shadow: 0 0 0 1px var(--gold-d), inset 0 0 14px #000; }
#combat .act b { font-size: 22px; }
#combat .act:active { transform: scale(.95); }
#combat .act[disabled] { opacity: .35; }
#combat .who-turn { text-align: center; font: 700 13px var(--serif); color: var(--gold-2); margin-bottom: 6px; text-shadow: 0 2px 0 #000; min-height: 18px; }
#combat .sheet { max-width: 620px; margin: 0 auto 6px; max-height: 40vh; overflow: auto; display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 6px; touch-action: pan-y; }
#combat .sk { text-align: left; padding: 8px 10px; border-radius: 8px; cursor: pointer; background: linear-gradient(180deg, rgba(40,31,24,.95), rgba(14,10,8,.95)); border: 1px solid var(--gold-d); display: grid; grid-template-columns: 28px 1fr; gap: 2px 8px; align-items: center; }
#combat .sk b { grid-row: span 2; font-size: 22px; }
#combat .sk span { font: 700 12px var(--serif); }
#combat .sk small { font: 600 10px var(--sans); color: var(--muted); }
#combat .sk[disabled] { opacity: .35; }
.combat-log { position: absolute; left: 50%; transform: translateX(-50%); bottom: calc(150px + var(--safe-b)); width: min(560px, 92%); text-align: center; font: 600 13px var(--sans); color: #f4e9d6; text-shadow: 0 2px 4px #000; z-index: 5; pointer-events: none; min-height: 18px; }
.cbanner { position: absolute; left: 0; right: 0; top: 38%; text-align: center; z-index: 12; pointer-events: none; animation: cban 1.8s ease forwards; }
.cbanner h2 { margin: 0; font: 800 clamp(26px, 8vw, 48px) var(--serif); color: var(--c, #fde68a); text-shadow: 0 0 24px var(--c, #fde68a), 0 4px 0 #000; letter-spacing: .06em; }
.cbanner p { margin: 4px 0 0; font: 600 14px var(--sans); color: #fff; text-shadow: 0 2px 4px #000; }
.cbanner::before { content: ''; position: absolute; left: 0; right: 0; top: -20px; bottom: -20px; background: linear-gradient(90deg, transparent, rgba(0,0,0,.75) 20%, rgba(0,0,0,.75) 80%, transparent); z-index: -1; }
@keyframes cban { 0% { opacity: 0; transform: scaleX(.6); } 12% { opacity: 1; transform: none; } 80% { opacity: 1; } 100% { opacity: 0; } }
.flashfx { position: absolute; inset: 0; pointer-events: none; z-index: 11; }
.boom { position: absolute; width: 220px; height: 220px; margin: -110px; border-radius: 50%; pointer-events: none; z-index: 9; background: radial-gradient(circle, #fff7c2 0%, #fb923c 30%, rgba(220,38,38,.6) 55%, transparent 70%); animation: boom .6s ease-out forwards; mix-blend-mode: screen; }
@keyframes boom { from { transform: scale(.2); opacity: 1; } to { transform: scale(1.6); opacity: 0; } }
.missile { position: absolute; width: 18px; height: 18px; margin: -9px; border-radius: 50%; background: radial-gradient(circle, #fff, #a78bfa 45%, transparent 70%); box-shadow: 0 0 20px #8b5cf6, 0 0 40px #6d28d9; pointer-events: none; z-index: 9; }
.slash { position: absolute; width: 140px; height: 140px; margin: -70px; pointer-events: none; z-index: 9; background: linear-gradient(135deg, transparent 45%, rgba(255,255,255,.95) 49%, rgba(255,220,150,.8) 51%, transparent 55%); animation: slash .3s ease-out forwards; }
@keyframes slash { from { transform: scale(.4) rotate(-20deg); opacity: 1; } to { transform: scale(1.3) rotate(10deg); opacity: 0; } }
.screen-flash { position: absolute; inset: 0; background: #fff; opacity: 0; pointer-events: none; z-index: 60; }
.shake-heavy { animation: shk .45s; } @keyframes shk { 10%,90% { transform: translate(-2px, 1px); } 20%,80% { transform: translate(4px, -2px); } 30%,50%,70% { transform: translate(-6px, 3px); } 40%,60% { transform: translate(6px, -3px); } }
.transition { position: absolute; inset: 0; z-index: 80; pointer-events: none; background: #000; opacity: 0; }
.transition.go { animation: trans 1.1s ease forwards; }
@keyframes trans { 0% { opacity: 0; clip-path: circle(150% at 50% 50%); } 40% { opacity: 1; clip-path: circle(0% at 50% 50%); background: #000; } 41% { clip-path: none; } 100% { opacity: 0; } }
.victory { position: absolute; inset: 0; z-index: 20; display: grid; place-items: center; background: rgba(0,0,0,.6); animation: fadein .4s; }
.victory .panel { width: min(460px, 94%); }

/* ---------- Title / creator / cinematic ---------- */
.screen { position: absolute; inset: 0; z-index: 90; overflow: hidden; background: #000; }
.title-bg { position: absolute; inset: 0; background-repeat: no-repeat; background-size: cover; background-position: center top; transform-origin: 50% 0; animation: titledrift 30s ease-in-out infinite alternate; }
.title-bgfill { position: absolute; inset: -40px; background-size: cover; background-position: center bottom; filter: blur(22px) brightness(.55); }
@keyframes titledrift { from { transform: scale(1); } to { transform: scale(1.04); } }
@keyframes kenburns { from { transform: scale(1.05); } to { transform: scale(1.18) translate(-2%, -1%); } }
.title-shade { position: absolute; inset: 0; background: linear-gradient(180deg, rgba(0,0,0,.3), transparent 30%, rgba(0,0,0,.2) 55%, rgba(0,0,0,.92)); }
.title-ui { position: absolute; left: 0; right: 0; bottom: calc(6% + var(--safe-b)); display: flex; flex-direction: column; align-items: center; gap: 10px; padding: 0 20px; }
.logo { text-align: center; position: absolute; top: calc(8% + var(--safe-t)); left: 0; right: 0; }
.logo h1 { margin: 0; font: 800 clamp(34px, 10vw, 76px)/0.95 var(--serif); color: var(--gold-2); letter-spacing: .06em; text-shadow: 0 0 30px rgba(212,169,74,.5), 0 4px 0 #3a2508, 0 8px 30px #000; }
.logo h1 span { display: block; font-size: .42em; letter-spacing: .4em; color: #f1e3c2; margin-top: 8px; }
.logo p { font: 600 11px var(--sans); letter-spacing: .3em; color: #cbb994; text-transform: uppercase; text-shadow: 0 2px 4px #000; }
.title-ui .btn { width: min(320px, 86vw); font-size: 16px; min-height: 52px; }
.fineprint { font-size: 10px; color: #8d8170; text-align: center; max-width: 520px; line-height: 1.4; }
.embers { position: absolute; inset: 0; pointer-events: none; }
.cine { position: absolute; inset: 0; display: grid; place-items: center; background: #000; z-index: 95; }
.cine .shot { position: absolute; inset: 0; background-size: cover; background-position: center; opacity: 0; transition: opacity 1.4s; }
.cine .shot.on { opacity: 1; animation: kenburns 12s ease-out forwards; }
.cine .bars::before, .cine .bars::after { content: ''; position: absolute; left: 0; right: 0; height: 9vh; background: #000; z-index: 3; }
.cine .bars::before { top: 0; } .cine .bars::after { bottom: 0; }
.cine .caption { position: absolute; left: 6%; right: 6%; bottom: calc(14vh + var(--safe-b)); z-index: 4; text-align: center; font: 500 clamp(15px, 4.2vw, 22px)/1.5 var(--serif); color: #f3e8d2; text-shadow: 0 2px 8px #000, 0 0 30px #000; opacity: 0; transition: opacity 1s; }
.cine .caption.on { opacity: 1; }
.cine .caption.system { font-family: var(--sans); color: #bfe6ff; font-size: clamp(14px, 3.8vw, 18px); }
.cine .skip { position: absolute; right: calc(12px + var(--safe-r)); top: calc(12px + var(--safe-t)); z-index: 5; }
.creator { position: absolute; inset: 0; z-index: 92; display: flex; flex-direction: column; background: radial-gradient(ellipse at 50% 0%, #2a1d12, #070505 70%); }
.creator .head { padding: calc(12px + var(--safe-t)) 16px 8px; text-align: center; }
.creator .head h2 { margin: 0; font: 700 22px var(--serif); color: var(--gold-2); }
.creator .head p { margin: 4px 0 0; font-size: 12px; color: #9bd7ff; }
.creator .steps { display: flex; gap: 4px; justify-content: center; margin-top: 8px; }
.creator .steps i { width: 26px; height: 4px; border-radius: 2px; background: #3a2c1f; } .creator .steps i.on { background: var(--gold); box-shadow: 0 0 8px var(--gold); }
.creator .body { flex: 1; overflow: auto; padding: 8px 14px; touch-action: pan-y; -webkit-overflow-scrolling: touch; }
.creator .foot { display: flex; gap: 8px; padding: 10px 14px calc(10px + var(--safe-b)); border-top: 1px solid rgba(212,169,74,.2); background: rgba(0,0,0,.4); }
.creator .foot .btn { flex: 1; }
.cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 8px; }
.card { position: relative; padding: 10px; border-radius: 10px; cursor: pointer; background: linear-gradient(180deg, rgba(40,30,22,.9), rgba(14,10,8,.95)); border: 1px solid #3a2c1f; transition: all .2s; text-align: left; }
.card.on { border-color: var(--gold); box-shadow: 0 0 0 1px var(--gold), 0 0 18px rgba(212,169,74,.35); }
.card h4 { margin: 0; font: 700 13.5px var(--serif); color: var(--gold-2); display: flex; gap: 6px; align-items: center; }
.card p { margin: 5px 0 0; font-size: 11.5px; line-height: 1.4; color: #cdbfa8; }
.card .mods { margin: 6px 0 0; }
.card.dis { opacity: .35; pointer-events: none; }
.preset { aspect-ratio: 3/4; padding: 0; overflow: hidden; display: flex; flex-direction: column; justify-content: flex-end; }
.preset img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.preset .cap { position: relative; padding: 24px 8px 8px; background: linear-gradient(transparent, rgba(0,0,0,.9)); font: 700 12px var(--serif); color: var(--gold-2); }
.preset .cap small { display: block; font: 500 10px var(--sans); color: #d6c8b0; }
.namefield { width: 100%; font: 700 20px var(--serif); padding: 12px 14px; border-radius: 10px; background: #0d0907; color: var(--gold-2); border: 1px solid var(--gold-d); outline: none; text-align: center; user-select: text; -webkit-user-select: text; }
.section-t { font: 700 13px var(--serif); color: var(--gold-2); margin: 14px 0 6px; letter-spacing: .08em; text-transform: uppercase; }
.pointsleft { text-align: center; font: 800 16px var(--serif); color: #fde68a; margin: 6px 0 10px; }
.minus { width: 40px; height: 40px; border-radius: 50%; font: 800 20px var(--sans); background: #241a12; color: var(--gold-2); border: 1px solid var(--gold-d); cursor: pointer; }
.summary { display: grid; grid-template-columns: 120px 1fr; gap: 12px; }
.summary img { width: 120px; border-radius: 10px; border: 2px solid var(--gold-d); }
.ending { position: absolute; inset: 0; z-index: 96; display: grid; place-items: center; background: radial-gradient(ellipse, rgba(20,10,5,.85), #000); animation: fadein 1s; padding: 16px; }
.ending .panel { width: min(560px, 100%); }
.statlist { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; margin: 10px 0; }
.statlist div { padding: 8px; border-radius: 6px; background: rgba(0,0,0,.35); border: 1px solid #2b2118; display: flex; justify-content: space-between; font-size: 12.5px; }
.statlist b { color: var(--gold-2); }
/* full map */
.mapscreen { position: absolute; inset: 0; z-index: 55; background: #050407; display: flex; flex-direction: column; animation: fadein .25s; }
.mapscreen canvas { flex: 1; width: 100%; touch-action: none; }
.mapscreen .mhead { display: flex; align-items: center; gap: 8px; padding: calc(8px + var(--safe-t)) 12px 8px; border-bottom: 1px solid rgba(212,169,74,.3); background: rgba(14,10,8,.95); }
.mapscreen .mhead h2 { flex: 1; margin: 0; font: 700 18px var(--serif); color: var(--gold-2); }
.mapscreen .legend { display: flex; flex-wrap: wrap; gap: 8px 12px; padding: 8px 12px calc(8px + var(--safe-b)); font-size: 11px; color: var(--muted); background: rgba(14,10,8,.95); border-top: 1px solid rgba(212,169,74,.3); }
.mapscreen .legend i { display: inline-block; width: 10px; height: 10px; border-radius: 2px; margin-right: 4px; vertical-align: -1px; }
.loading { position: absolute; inset: 0; display: grid; place-items: center; background: #000; z-index: 200; font: 700 14px var(--serif); color: var(--gold-2); letter-spacing: .3em; }

/* ---------- runtime containers & juice (added with main.js) ---------- */
#world { position: absolute; inset: 0; }
#world canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; touch-action: none; }
#ui { position: absolute; inset: 0; pointer-events: none; z-index: 5; }
#ui > * { pointer-events: auto; }
#ui > #hud { pointer-events: none; }
#ui > .toast, #ui > .viewerpop, #ui > .bark, #ui > .tapmark, #ui > .spark, #ui > .flashfx, #ui > .joy { pointer-events: none; }
.spark { position: absolute; width: 6px; height: 6px; margin: -3px; border-radius: 50%; pointer-events: none; z-index: 120; box-shadow: 0 0 10px currentColor; animation: spark .9s cubic-bezier(.2,.7,.3,1) forwards; }
@keyframes spark { from { transform: translate(0,0) scale(1); opacity: 1; } to { transform: translate(var(--dx), var(--dy)) scale(.2); opacity: 0; } }
.flashfx { animation: flashfx .45s ease-out forwards; mix-blend-mode: screen; }
@keyframes flashfx { from { opacity: .85; } to { opacity: 0; } }
.sleepfade { position: absolute; inset: 0; z-index: 70; background: #000; display: grid; place-items: center; animation: fadein .6s; transition: opacity .9s; }
.sleepfade p { font: 700 28px var(--serif); color: #c7d2fe; letter-spacing: .3em; animation: blink 1.4s infinite; }
.sleepfade.out { opacity: 0; }
.loading { transition: opacity .4s; display: flex; flex-direction: column; gap: 18px; align-items: center; justify-content: center; }
.loading .spin { width: 54px; height: 54px; border-radius: 50%; border: 3px solid rgba(212,169,74,.2); border-top-color: var(--gold); animation: spin 1s linear infinite; box-shadow: 0 0 30px rgba(212,169,74,.25); }
.loading p { margin: 0; font-size: 12px; }
@keyframes spin { to { transform: rotate(360deg); } }
.tip { position: fixed; z-index: 300; max-width: min(300px, 80vw); padding: 9px 11px; border-radius: 8px; font-size: 12px; line-height: 1.45; color: #efe6d6; pointer-events: none;
  background: linear-gradient(180deg, rgba(34,27,22,.98), rgba(12,9,8,.98)); border: 1px solid var(--gold-d); box-shadow: 0 0 0 1px #000, 0 8px 24px rgba(0,0,0,.8); animation: fadein .12s; }
.tip b { color: var(--gold-2); }
.lootimg { width: 132px; height: 132px; object-fit: contain; filter: drop-shadow(0 10px 18px rgba(0,0,0,.8)) drop-shadow(0 0 22px var(--glow, rgba(212,169,74,.5))); animation: bob 2.2s ease-in-out infinite; }
@keyframes bob { 50% { transform: translateY(-6px); } }
i.sys, .sys { color: #9bd7ff; font-style: normal; }
.title-ui .btn:first-of-type { box-shadow: 0 0 0 1px var(--gold), 0 0 30px rgba(212,169,74,.45); }
@keyframes blink { 50% { opacity: .55; } }

/* ===================== UI KIT (assets/art/ui) — painted dark-metal frames, buttons, icons ===================== */
:root { --kit-panel: url(../assets/art/ui/panel-frame.png); --kit-btn: url(../assets/art/ui/button-default.png); --kit-btn-h: url(../assets/art/ui/button-hover.png); --kit-btn-p: url(../assets/art/ui/button-pressed.png); --kit-btn-d: url(../assets/art/ui/button-disabled.png); }
/* 9-slice panel frame: 128px margins on the 1024 source, drawn slightly outside the box so content keeps its space */
.frame { border: 1px solid transparent; border-radius: 6px; background: radial-gradient(ellipse at 50% 0%, rgba(46,36,28,.97), rgba(14,11,9,.97) 70%) padding-box; box-shadow: 0 14px 40px rgba(0,0,0,.75), inset 0 0 40px rgba(0,0,0,.65);
  border-image-source: var(--kit-panel); border-image-slice: 128; border-image-width: 34px; border-image-outset: 16px; border-image-repeat: stretch; }
.frame::before, .frame::after { display: none; }
.frame.nocap { border-image-width: 22px; border-image-outset: 10px; }
.panel.frame { margin: 16px; }
#hud .pframe.frame, .pframe { }
/* buttons */
.btn.ghost, .panel .x, .creator .foot .btn.ghost, .btn.small.ghost { background: none; box-shadow: none; border: 0; border-image: var(--kit-btn) 70 80 fill / 14px 16px stretch; color: var(--gold-2); text-shadow: 0 2px 0 #000; }
.btn.ghost:hover, .panel .x:hover { border-image-source: var(--kit-btn-h); }
.btn.ghost:active, .panel .x:active { border-image-source: var(--kit-btn-p); transform: translateY(1px); }
.btn.ghost[disabled] { border-image-source: var(--kit-btn-d); filter: none; opacity: .6; }
.btn:not(.ghost):not(.danger) { border: 0; border-image: var(--kit-btn) 70 80 / 14px 16px stretch; background: linear-gradient(180deg, #f3d488, #c4943a 55%, #7d5618) padding-box; background-clip: padding-box; box-shadow: 0 6px 16px rgba(0,0,0,.55), inset 0 0 0 1px rgba(255,236,190,.35); text-shadow: 0 1px 0 rgba(255,240,200,.5); }
.btn:not(.ghost):not(.danger):hover { border-image-source: var(--kit-btn-h); filter: brightness(1.06); }
.panel .x { color: var(--gold-2); font-size: 16px; width: 42px; height: 42px; }
/* icons */
img.uic { width: 30px; height: 30px; object-fit: contain; display: block; pointer-events: none; filter: drop-shadow(0 2px 3px rgba(0,0,0,.8)); }
img.uic.item { width: 78%; height: 78%; }
img.uic.ghost { width: 62%; height: 62%; opacity: .22; filter: grayscale(.6); }
.slot img.uic { width: 40px; height: 40px; }
.menubtns .slot img.uic { width: 36px; height: 36px; }
.slot { background: radial-gradient(circle at 50% 35%, #2e241c, #0d0a08 72%); }
.icell img.uic.item, .eslot img.uic.item { width: 74%; height: 74%; }
.boxcard .ic img.uic, .reward .ic img.uic, .skillrow .ic img.uic { width: 86%; height: 86%; }
.reward .ic img.uic.item { width: 64px; height: 64px; margin: 0 auto; }
#combat .act b img.uic, #combat .sk b img.uic { width: 32px; height: 32px; margin: 0 auto; }
#combat .act { background: radial-gradient(circle at 50% 30%, #3a2d24, #110d0a 75%); border: 0; border-image: var(--kit-btn) 70 80 fill / 12px 14px stretch; box-shadow: none; }
#combat .act:active { border-image-source: var(--kit-btn-p); }
#combat .act[disabled] { border-image-source: var(--kit-btn-d); }
/* minimap with painted frame */
.minimap .ring { inset: -17px; border: 0; border-radius: 0; box-shadow: none; background: url(../assets/art/ui/minimap-frame.png) center/100% 100% no-repeat; filter: drop-shadow(0 6px 14px rgba(0,0,0,.85)); }
.minimap canvas { box-shadow: inset 0 0 18px #000; }
.minimap .n { top: -20px; z-index: 2; }
.topright { padding-top: 10px; }
/* combat layout: enemies upper third, party lower third */
#combat .field { top: calc(64px + var(--safe-t)); bottom: calc(170px + var(--safe-b)); justify-content: space-around; }
.unit { width: clamp(100px, 29vw, 190px); }
#combat .side.allies .unit { width: clamp(96px, 27vw, 170px); }
.unit .plate { border: 0; border-image: url(../assets/art/ui/bar-frame.png) 37 106 37 108 fill / 8px 14px 8px 14px stretch; background: none; padding: 6px 14px; max-width: 170px; }
.panel.frame { width: min(720px, calc(100% - 28px)); max-height: calc(100% - 28px); margin: 14px; }
.victory .panel.frame, .ending .panel.frame { width: min(520px, calc(100% - 28px)); }
@media (max-width: 600px) { .syslog { right: calc(66px + var(--safe-r)); align-items: flex-start; } .sysmsg { max-width: 100%; } }
@media (max-width: 520px) { .banner { top: calc(186px + var(--safe-t)); } }
/* System holo-map */
.mapscreen { background: radial-gradient(120% 80% at 50% 40%, #0a1a28, #020509 70%); }
.mapscreen .mhead { background: linear-gradient(180deg, rgba(6,18,30,.96), rgba(4,10,18,.9)); border-bottom: 1px solid rgba(125,211,252,.35); box-shadow: 0 6px 20px rgba(0,0,0,.5); }
.mapscreen .mhead h2 { color: #e6f6ff; text-shadow: 0 0 12px rgba(110,200,255,.6); font-size: 17px; }
.mapscreen .sysbadge { font: 800 9px var(--sans); letter-spacing: .18em; color: #38bdf8; border: 1px solid rgba(56,189,248,.5); padding: 3px 6px; border-radius: 4px; background: rgba(8,30,48,.7); }
.mapscreen .mwrap { position: relative; flex: 1; display: flex; margin: 22px 20px; min-height: 0; background: #030a12; }
.mapscreen .mwrap canvas { flex: 1; width: 100%; height: 100%; border-radius: 6px; }
.mapscreen .mscan { position: absolute; inset: 0; pointer-events: none; border-radius: 6px; background: repeating-linear-gradient(180deg, rgba(120,210,255,.035) 0 1px, transparent 1px 3px), radial-gradient(ellipse at center, transparent 55%, rgba(0,0,0,.65)); animation: mscan 6s linear infinite; }
@keyframes mscan { from { background-position: 0 0, 0 0; } to { background-position: 0 120px, 0 0; } }
.mapscreen .legend { background: linear-gradient(0deg, rgba(6,18,30,.96), rgba(4,10,18,.9)); border-top: 1px solid rgba(125,211,252,.35); color: #b6d8ea; }
.mapscreen .legend i { border-radius: 50%; box-shadow: 0 0 6px currentColor; }
/* ---- combat arena v2: staged 3/4 composition, props, embers, boss arena */
#combat .aprop { position: absolute; pointer-events: none; filter: brightness(.8) drop-shadow(0 8px 10px rgba(0,0,0,.8)); z-index: 0; }
#combat .embers { position: absolute; inset: 0; pointer-events: none; overflow: hidden; }
#combat .embers i { position: absolute; bottom: -10px; width: 4px; height: 4px; border-radius: 50%; background: #ffb35c; box-shadow: 0 0 8px 2px rgba(255,140,40,.7); animation: ember 6s linear infinite; opacity: 0; }
@keyframes ember { 0% { transform: translate(0, 0); opacity: 0; } 10% { opacity: .9; } 100% { transform: translate(30px, -90vh); opacity: 0; } }
#combat .side.enemies { justify-content: flex-end; padding-right: 4%; }
#combat .side.allies { justify-content: flex-start; padding-left: 4%; }
#combat .side.enemies .unit:nth-child(2) { transform: translateY(18px); } #combat .side.enemies .unit:nth-child(3) { transform: translateY(-14px); }
#combat .side.allies .unit:nth-child(2) { transform: translateY(-22px); } #combat .side.allies .unit:nth-child(3) { transform: translateY(10px); }
#combat .side.enemies .unit .fig img { animation-duration: 2.6s; }
#combat .side.allies .unit .fig img { animation-duration: 3.2s; }
@keyframes idle { 0%,100% { transform: scaleY(1) translateY(0); } 50% { transform: scaleY(1.035) scaleX(.99) translateY(-3px); } }
/* QA3: the hit flash keeps the art readable (warm overexposure + red rim) instead of a white silhouette */
@keyframes hitk { 0% { filter: brightness(1.85) saturate(1.25) sepia(.25) drop-shadow(0 0 10px rgba(255,90,60,.85)); transform: translateX(0); } 22% { filter: brightness(1.4) saturate(1.1) drop-shadow(0 0 6px rgba(255,90,60,.6)); transform: translateX(-10px) rotate(-2deg); } 60% { filter: brightness(1.1); transform: translateX(7px); } 100% { filter: none; transform: none; } }
#combat.bossarena .arena-fx { background: radial-gradient(ellipse at 60% 40%, rgba(255,60,40,.22), transparent 55%), radial-gradient(ellipse at center, transparent 30%, rgba(0,0,0,.9) 100%); }
#combat .ritual { position: absolute; left: 50%; top: 52%; width: 120vmin; height: 46vmin; margin-left: -60vmin; border-radius: 50%; border: 2px solid rgba(255,80,60,.5); box-shadow: 0 0 40px rgba(255,60,40,.45), inset 0 0 50px rgba(255,60,40,.35); animation: pulse 2.2s infinite; }
.bossintro { position: absolute; inset: 0; z-index: 30; display: grid; place-items: center; background: radial-gradient(ellipse at 50% 45%, rgba(120,10,10,.55), rgba(0,0,0,.92) 70%); animation: fadein .3s; overflow: hidden; }
.bossintro.out { animation: biout .45s forwards; } @keyframes biout { to { opacity: 0; transform: scale(1.06); } }
.bossintro .bar { position: absolute; left: 0; right: 0; height: 12vh; background: #000; animation: barin .4s ease-out; } .bossintro .bar.t { top: 0; } .bossintro .bar.b { bottom: 0; }
@keyframes barin { from { height: 0; } }
.bossintro .glare { position: absolute; inset: 0; background: linear-gradient(100deg, transparent 40%, rgba(255,200,160,.18) 50%, transparent 60%); animation: glare 1.6s ease-out .4s both; } @keyframes glare { from { transform: translateX(-100%); } to { transform: translateX(100%); } }
.bossintro .bossart { position: absolute; bottom: 12vh; right: -4vw; height: 66vh; max-width: 90vw; object-fit: contain; filter: drop-shadow(0 0 30px rgba(255,60,40,.5)); animation: bossin .7s cubic-bezier(.2,.9,.3,1.2) both; }
@keyframes bossin { from { transform: translateX(40vw) scale(1.2); opacity: 0; } to { transform: none; opacity: 1; } }
.bossintro .txt { position: absolute; left: 6vw; right: 6vw; top: 16vh; text-shadow: 0 4px 0 #000, 0 0 30px #000; }
.bossintro .kicker { font: 800 12px var(--sans); letter-spacing: .4em; color: #fca5a5; animation: fadein .4s .3s both; }
.bossintro h1 { margin: 6px 0; font: 800 clamp(40px, 12vw, 96px)/0.92 var(--serif); color: #fde68a; letter-spacing: .03em; animation: slam .5s cubic-bezier(.3,1.6,.5,1) .65s both; }
@keyframes slam { from { transform: scale(3); opacity: 0; filter: blur(6px); } 70% { transform: scale(.96); opacity: 1; filter: none; } to { transform: none; } }
.bossintro .lvl { font: 700 13px var(--sans); color: #fecaca; animation: fadein .4s 1s both; }
.bossintro p { max-width: 520px; font: 500 italic 14px/1.4 var(--sans); color: #e7dccb; animation: fadein .5s 1.2s both; }
.bossintro .skip { position: absolute; right: calc(16px + var(--safe-r)); bottom: calc(14vh + 10px); font: 700 13px var(--serif); color: #fde68a; background: rgba(0,0,0,.6); border: 1px solid #b45309; border-radius: 8px; padding: 8px 14px; }
#combat .side { width: 100%; max-width: 980px; margin: 0 auto; box-sizing: border-box; }
@media (min-width: 900px) { #combat .side.enemies { padding-right: 10%; } #combat .side.allies { padding-left: 10%; } }
#combat .cspark { position: absolute; height: auto; aspect-ratio: 1; border-radius: 50%; z-index: 8; pointer-events: none; animation: cspark .6s cubic-bezier(.2,.8,.4,1) forwards; }
@keyframes cspark { from { transform: translate(-50%, -50%) scale(1); opacity: 1; } to { transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy) + 30px)) scale(.3); opacity: 0; } }
#combat .cring { position: absolute; width: 20px; height: 20px; margin: -10px 0 0 -10px; border: 3px solid; border-radius: 50%; z-index: 8; pointer-events: none; animation: cring .45s ease-out forwards; }
@keyframes cring { to { transform: scale(7); opacity: 0; border-width: 1px; } }
#combat.hitstop .field { filter: contrast(1.25) brightness(1.15); transform: scale(1.012); }

/* ---- parallax combat backdrop (js/ui/backdrop.js; art from assets/art/backdrops when shipped) */
.backdrop { position: absolute; inset: -4%; --px: 0; --py: 0; pointer-events: auto; }
.backdrop .bdl { position: absolute; inset: 0; background-size: cover; background-position: 50% 40%;
  transform: translate3d(calc(var(--px) * var(--d) * -9px), calc(var(--py) * var(--d) * -5px), 0) scale(calc(1.02 + var(--d) * 0.02));
  transition: transform .6s cubic-bezier(.2,.7,.2,1); animation: bddrift calc(18s - var(--d) * 3s) ease-in-out infinite alternate; will-change: transform; }
.backdrop .bdl:first-child { filter: brightness(.85) saturate(.95); }
.backdrop.kick .bdl { animation: bdkick .32s cubic-bezier(.2,.8,.2,1), bddrift 18s ease-in-out infinite alternate; }
@keyframes bddrift { from { background-position: 48% 40%; } to { background-position: 52% 41%; } }
@keyframes bdkick { 0% { translate: 0 0; } 25% { translate: calc(var(--d) * 4px) calc(var(--d) * -3px); } 100% { translate: 0 0; } }
.vfxdom { image-rendering: auto; }
@media (prefers-reduced-motion: reduce) { .backdrop .bdl { animation: none; transition: none; } }

/* ---- dev overlay (js/engine/debug.js) */
.devov { position: fixed; left: 8px; right: 8px; top: calc(env(safe-area-inset-top) + 8px); z-index: 9999; background: rgba(5,8,14,.86); border: 1px solid #22d3ee55; border-radius: 8px; color: #a5f3fc; font: 11px/1.35 ui-monospace, Menlo, monospace; padding: 8px; max-height: 60vh; display: flex; flex-direction: column; gap: 6px; }
.devov[hidden] { display: none; }
.devov pre { margin: 0; white-space: pre-wrap; }
.devov .devout { overflow: auto; max-height: 30vh; color: #e2e8f0; }
.devov input { background: #0b1220; color: #e2e8f0; border: 1px solid #334155; border-radius: 6px; padding: 8px; font: inherit; font-size: 16px; }
/* manifest backdrops: light glows, fog, foreground frame */
.backdrop .bdlights { background: none; }
.backdrop .bdlights i { position: absolute; transform: translate(-50%, -50%); border-radius: 50%; mix-blend-mode: screen; animation: bdflick 2s ease-in-out infinite alternate; pointer-events: none; }
@keyframes bdflick { 0% { opacity: .55; } 40% { opacity: .9; } 55% { opacity: .7; } 100% { opacity: 1; } }
.backdrop .bdfog { position: absolute; inset: 0; z-index: 1; pointer-events: none; }
#combat .bdl.near { position: absolute; inset: -4%; z-index: 1; pointer-events: none; background-size: cover; background-position: 50% 40%; transform: translate3d(calc(var(--px, 0) * var(--d) * -9px), calc(var(--py, 0) * var(--d) * -5px), 0) scale(1.04); transition: transform .6s cubic-bezier(.2,.7,.2,1); }
#combat.staged .field { justify-content: flex-start; }
@media (prefers-reduced-motion: reduce) { .backdrop .bdlights i { animation: none; } }

/* ======================= QA pass 1 fixes (see qa/FIXES.md) ======================= */
.invcols { display: block; }
.eslot { max-width: 84px; width: 100%; justify-self: center; }
/* endings never clip: scrolling body, sticky button row (P1-9) */
.ending { padding: max(12px, var(--safe-t)) max(12px, var(--safe-r)) max(12px, var(--safe-b)) max(12px, var(--safe-l)); }
.ending .panel { max-height: calc(100dvh - var(--safe-t) - var(--safe-b) - 24px); display: flex; flex-direction: column; }
.ending .panel .body { overflow: auto; }
.ending .panel .body > .row:last-child { position: sticky; bottom: 0; padding: 10px 0 4px; background: linear-gradient(transparent, rgba(12,8,6,.96) 30%); margin-bottom: 0; }
/* creator respects the notch / home indicator (P1-11) */
.creator { padding-left: max(0px, var(--safe-l)); padding-right: max(0px, var(--safe-r)); padding-top: var(--safe-t); }
.creator .foot { padding-left: max(14px, var(--safe-l)); padding-right: max(14px, var(--safe-r)); }
/* tap targets >= 44px (P2-1) */
button, .btn, .tab, .panel .x, .who button, .choice { min-height: 44px; }
.panel .x, .btn.small, .mapscreen .btn { min-width: 44px; }
.tabs .tab, .tabs button { min-height: 44px; padding-left: 14px; padding-right: 14px; }
/* tiny text floor (P2-2) */
small, .unit .plate .nm, .act small, .act .k { font-size: max(11px, 1em); }
@media (hover: none) { #combat .act .k, #combat .act kbd, .keyhint { display: none; } }
/* combat names: two lines instead of an ellipsis; intents stay inside the viewport (P2-3) */
.unit .plate .nm { white-space: normal; overflow: visible; text-overflow: clip; line-height: 1.15; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.unit .intent { max-width: min(46vw, 240px); white-space: normal; }
/* region title sits under the HUD stack in portrait (P2-4) */
@media (orientation: portrait) { .regiontitle { top: calc(250px + var(--safe-t)); } }
/* hero tokens bigger in combat (P2-6) */
#combat .side.allies .unit { width: clamp(110px, 32vw, 200px); }

@media (orientation: landscape) and (max-height: 520px) {
  /* landscape explore: system log clears the hotbar (P1-10) */
  .syslog { bottom: calc(100px + var(--safe-b)); }
  /* landscape combat (P1-1): party left, enemies right, sized by height; compact action bar pinned bottom-right */
  #combat .field { top: calc(46px + var(--safe-t)); bottom: calc(100px + var(--safe-b)); left: var(--safe-l); right: var(--safe-r); flex-direction: row-reverse; justify-content: space-around; align-items: flex-end; }
  #combat .side { flex: 1; align-items: flex-end; padding-top: 0; }
  #combat .unit, #combat .side.allies .unit { width: min(20vw, 30vh); }
  #combat .unit.boss { width: min(32vw, 48vh); }
  #combat .actions { left: auto; right: 0; width: min(600px, 62vw); padding: 4px calc(6px + var(--safe-r)) calc(4px + var(--safe-b)) 6px; }
  #combat .act { min-height: 50px; } #combat .act b { font-size: 18px; }
  #combat .who-turn { margin-bottom: 2px; }
  #combat .combat-log { top: calc(54px + var(--safe-t)); bottom: auto; width: min(520px, 60vw); }
  /* landscape inventory: two columns (P1-8) */
  .invcols { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr); gap: 12px; align-items: start; }
  .equip { grid-template-columns: repeat(4, minmax(0, 84px)); justify-content: start; }
  .ending .statlist { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
#combat .field { z-index: 2; }
#combat .order .o.nextr { opacity: .45; filter: grayscale(.6); width: 28px; height: 28px; align-self: center; }
#combat .order .osep { width: 2px; align-self: stretch; margin: 4px 3px; background: linear-gradient(transparent, var(--gold), transparent); flex: none; }

/* WebGL world (js/render/pixi_world.js): the 2D canvas becomes a transparent overlay; Pixi draws its own vignette */
#world canvas.glworld { pointer-events: none; }
#world canvas.gl-overlay { background: transparent; }
#world:has(canvas.gl-overlay) .vignette { display: none; }

/* bark subtitles (System AI / boss / monster lines) — sits above the action bar, never blocks input */
.subtitle { position: fixed; left: 50%; bottom: calc(env(safe-area-inset-bottom, 0px) + 250px); transform: translate(-50%, 8px); max-width: min(92vw, 560px);
  padding: 8px 14px; border-radius: 10px; background: rgba(8, 10, 14, .78); border: 1px solid rgba(255,255,255,.08); color: #e8e4da; font: 600 14px/1.35 system-ui, sans-serif;
  text-align: center; pointer-events: none; opacity: 0; transition: opacity .25s, transform .25s; z-index: 940; text-shadow: 0 1px 2px #000; }
.subtitle.show { opacity: 1; transform: translate(-50%, 0); }
.subtitle b { font-size: 11px; letter-spacing: .12em; margin-right: 4px; }
.subtitle.sys b { color: #4fd1ff; } .subtitle.boss b { color: #ff6a4a; } .subtitle.mob { font-style: italic; color: #cfc6b4; }
@media (prefers-reduced-motion: reduce) { .subtitle { transition: none; } }
.replaytag { position: fixed; top: calc(env(safe-area-inset-top, 0px) + 6px); left: 50%; transform: translateX(-50%); z-index: 960; padding: 3px 10px; border-radius: 99px;
  background: rgba(180, 30, 30, .85); color: #fff; font: 700 11px/1.4 system-ui, sans-serif; letter-spacing: .14em; pointer-events: none; }
.toast, .viewerpop, .regiontitle, .roomname, .syslog { pointer-events: none; }
/* QA2 P1-7: enemies stand in the darkest part of the painted arenas (baked edge vignette), and most monster art is
   dark-on-dark. Give the enemy side its own key light: a warm pool behind each living enemy, a lift + thin rim on the
   figure, and in landscape pull the row in off the vignetted edge. Dead units keep their grey-out. */
#combat .side.enemies .unit:not(.dead) .fig::before { content: ''; position: absolute; left: -18%; right: -18%; top: 4%; bottom: -6%; z-index: -1; pointer-events: none; background: radial-gradient(ellipse at 50% 72%, rgba(255,214,160,.30), rgba(255,170,90,.12) 42%, transparent 70%); mix-blend-mode: screen; }
#combat .side.enemies .unit:not(.dead) .fig img, #combat .side.enemies .unit:not(.dead) .fig canvas { filter: brightness(1.22) contrast(1.06) drop-shadow(0 0 1.5px rgba(255,232,196,.6)) drop-shadow(0 10px 12px rgba(0,0,0,.8)); }
#combat .side.enemies .unit.elite:not(.dead) .fig img, #combat .side.enemies .unit.elite:not(.dead) .fig canvas { filter: brightness(1.22) contrast(1.06) drop-shadow(0 0 2px rgba(255,232,196,.7)) drop-shadow(0 0 12px rgba(250,204,21,.6)) drop-shadow(0 10px 12px rgba(0,0,0,.8)); }
#combat .side.enemies .unit .plate { box-shadow: 0 0 14px rgba(0,0,0,.6); }
@media (orientation: landscape) { #combat .side.enemies { padding-right: 9%; } #combat .side.allies { padding-left: 5%; } }
/* QA2 P2-3: price / Open buttons (Shop Buy+Services, Loot Boxes, crafting) are a clean gold-rimmed pill: no framed
   plate inside, light tabular digits, coin and number never overlap, never clipped. */
.panel .btn.small:not(.ghost), .modal .btn.small:not(.ghost), .btn.small:not(.ghost):not(.danger) { border: 1px solid #d4a94a; border-image: none; border-radius: 999px; background: linear-gradient(180deg, #5d4520, #2a1e0e) padding-box; box-shadow: inset 0 1px 0 rgba(255,236,190,.25), 0 3px 8px rgba(0,0,0,.5); color: #fde68a; text-shadow: 0 1px 0 #000; font: 800 13px/1 var(--sans); letter-spacing: .02em; font-variant-numeric: tabular-nums; white-space: nowrap; padding: 0 14px; min-height: 40px; min-width: 64px; width: auto; flex: 0 0 auto; overflow: visible; display: inline-flex; align-items: center; justify-content: center; gap: 4px; }
.btn.small:not(.ghost):not(.danger):hover { border-color: #f6dc94; filter: brightness(1.12); }
.btn.small:not(.ghost)[disabled] { filter: none; opacity: .55; color: #d6c7a6; border-color: #6b5a3c; background: linear-gradient(180deg, #2c241a, #18130d); }
.btn.small.ghost { white-space: nowrap; font: 800 13px/1 var(--sans); font-variant-numeric: tabular-nums; padding: 0 14px; min-width: 64px; }
/* QA2 P1-2 elite tell in combat: ember-gold plate with a skull, matching the map badge */
#combat .unit.elite .plate { border-image: none; border: 1px solid #facc15; border-radius: 8px; background: linear-gradient(180deg, rgba(60,18,8,.94), rgba(20,8,5,.94)); box-shadow: 0 0 14px rgba(249,115,22,.45), inset 0 0 0 1px rgba(252,165,165,.25); }
#combat .unit.elite .plate .nm::before { content: '☠ '; color: #fca5a5; }
#combat .unit.elite .plate .nm { color: #fde68a; }
/* P1-4 painted boss portraits (600x750 cards) on the intro: framed card instead of a cut-out */
.bossintro .bossart.portrait { height: min(62vh, 520px); aspect-ratio: 600 / 750; width: auto; object-fit: cover; right: 6vw; bottom: 14vh; border-radius: 14px; border: 2px solid #7f1d1d; box-shadow: 0 0 40px rgba(255,60,40,.45), 0 20px 60px rgba(0,0,0,.8); filter: none; -webkit-mask-image: linear-gradient(180deg, #000 80%, transparent); mask-image: linear-gradient(180deg, #000 80%, transparent); }
@media (orientation: portrait) { .bossintro .bossart.portrait { left: 0; right: 0; margin: 0 auto; bottom: 26vh; height: min(48vh, 440px); } }
/* ---- juice pass (premium feel) ---- */
/* hit-stop: every CSS animation in the arena holds for a beat on contact */
#combat.frozen *, #combat.frozen *::before, #combat.frozen *::after { animation-play-state: paused !important; transition-duration: 0s !important; }
/* damage numbers: gold-to-ember gradient fill, dark stroke, pop with overshoot, arc away, scale with hit share */
.dmgnum { font: 900 calc(26px * var(--sz, 1)) / 1 var(--serif); letter-spacing: .02em; display: flex; flex-direction: column; align-items: center; text-shadow: none; animation: dmg2 1.05s cubic-bezier(.15,.9,.25,1) forwards; will-change: transform, opacity; }
.dmgnum span { color: #fff1c9; text-shadow: 0 2px 0 #1a0a04, 1.5px 0 0 #1a0a04, -1.5px 0 0 #1a0a04, 0 -1.5px 0 #1a0a04, 1px 1px 0 #1a0a04, -1px 1px 0 #1a0a04, 0 4px 0 rgba(0,0,0,.7), 0 0 12px rgba(0,0,0,.7); }
.dmgnum.hurt span { color: #ff6b5e; }
.dmgnum.fire span { color: #ffa94d; }
.dmgnum.magic span { color: #b4bcff; }
.dmgnum.heal span { color: #7ef0a4; }
.dmgnum.mana span { color: #8ec5ff; }
.dmgnum.miss span { color: #cbd5e1; font-size: .7em; letter-spacing: .12em; }
.dmgnum.st { font-size: 15px; }
.dmgnum.crit { font-size: calc(40px * var(--sz, 1)); animation: dmgcrit 1.25s cubic-bezier(.15,.9,.25,1) forwards; }
.dmgnum.crit span { color: #ffd23f; text-shadow: 0 2px 0 #1a0a04, 1.5px 0 0 #1a0a04, -1.5px 0 0 #1a0a04, 0 -1.5px 0 #1a0a04, 1px 1px 0 #1a0a04, -1px 1px 0 #1a0a04, 0 4px 0 rgba(0,0,0,.7), 0 0 12px rgba(0,0,0,.7), 0 0 18px rgba(255,150,30,.95); }
.dmgnum em { font: 800 10px/1 var(--sans); font-style: normal; letter-spacing: .32em; color: #fde68a; text-shadow: 0 1px 0 #000, 0 0 8px rgba(255,170,40,.9); margin-bottom: 2px; }
@keyframes dmg2 { 0% { transform: translate(-50%, 6px) scale(.3); opacity: 0; } 14% { transform: translate(calc(-50% + var(--dx) * .25), -22px) scale(1.25); opacity: 1; } 28% { transform: translate(calc(-50% + var(--dx) * .4), -28px) scale(1); } 70% { opacity: 1; } 100% { transform: translate(calc(-50% + var(--dx)), -64px) scale(.92); opacity: 0; } }
@keyframes dmgcrit { 0% { transform: translate(-50%, 0) scale(.2) rotate(-8deg); opacity: 0; } 12% { transform: translate(-50%, -26px) scale(1.5) rotate(3deg); opacity: 1; } 22% { transform: translate(-50%, -30px) scale(1.05) rotate(-1deg); } 30% { transform: translate(-50%, -30px) scale(1.12); } 72% { opacity: 1; } 100% { transform: translate(calc(-50% + var(--dx) * .6), -80px) scale(1); opacity: 0; } }
/* menus: backdrop blur ramps in, panel springs in, closes with a quick drop; tabs slide in their direction */
.modal-wrap { animation: mwin .22s ease-out both; }
@keyframes mwin { from { opacity: 0; backdrop-filter: blur(0); } to { opacity: 1; } }
.modal-wrap.closing { animation: mwout .2s ease-in forwards; pointer-events: none; }
.modal-wrap.closing .panel { animation: panelout .2s cubic-bezier(.5,0,.75,0) forwards; }
@keyframes mwout { to { opacity: 0; } }
@keyframes panelout { to { transform: translateY(14px) scale(.95); opacity: 0; } }
.panel .body.swap-r > * { animation: swapr .26s cubic-bezier(.2,.8,.3,1) both; } .panel .body.swap-l > * { animation: swapl .26s cubic-bezier(.2,.8,.3,1) both; }
.panel .body[class*=swap] > *:nth-child(2) { animation-delay: .02s; } .panel .body[class*=swap] > *:nth-child(3) { animation-delay: .04s; } .panel .body[class*=swap] > *:nth-child(4) { animation-delay: .06s; } .panel .body[class*=swap] > *:nth-child(5) { animation-delay: .08s; } .panel .body[class*=swap] > *:nth-child(n+6) { animation-delay: .1s; }
@keyframes swapr { from { transform: translateX(18px); opacity: 0; } to { transform: none; opacity: 1; } } @keyframes swapl { from { transform: translateX(-18px); opacity: 0; } to { transform: none; opacity: 1; } }
/* tactile presses */
.act, .slot, .choice, .tab, .btn { transition: transform .08s ease, filter .12s ease; }
.act:active, .slot:active, .choice:active, .tab:active { transform: scale(.95); }
/* loading: wordmark + progress */
.loading .wordmark { display: flex; flex-direction: column; align-items: center; gap: 4px; animation: wmin 1s cubic-bezier(.2,.8,.3,1) both; }
.loading .wordmark span { font: 700 11px var(--sans); letter-spacing: .5em; color: #a8946c; }
.loading .wordmark b { font: 800 clamp(30px, 8vw, 54px) var(--serif); letter-spacing: .08em; color: transparent; background: linear-gradient(180deg, #fff3cf, #e0b25a 55%, #8f6620); -webkit-background-clip: text; background-clip: text; filter: drop-shadow(0 4px 14px rgba(212,169,74,.35)); }
@keyframes wmin { from { opacity: 0; transform: translateY(10px) scale(.97); letter-spacing: .2em; } }
.loading .ldbar { width: min(260px, 64vw); height: 4px; border-radius: 4px; background: rgba(212,169,74,.15); overflow: hidden; box-shadow: 0 0 0 1px rgba(212,169,74,.2); }
.loading .ldbar i { display: block; height: 100%; transform-origin: 0 50%; transform: scaleX(0); background: linear-gradient(90deg, #8f6620, #f6dc94); box-shadow: 0 0 12px rgba(246,220,148,.7); transition: transform .35s cubic-bezier(.2,.8,.3,1); }
.loading .ldtip { max-width: min(320px, 80vw); text-align: center; font: 500 12px/1.5 var(--sans); letter-spacing: 0; color: #8c7d63; transition: opacity .3s; }
.loading .ldtip.out { opacity: 0; }
.loading .spin { display: none; }
.loading.done { opacity: 0; transform: scale(1.04); transition: opacity .5s ease, transform .6s ease; pointer-events: none; }
@media (prefers-reduced-motion: reduce) { .dmgnum, .dmgnum.crit { animation-duration: .8s; } .panel .body.swap-r > *, .panel .body.swap-l > * { animation: none; } }

/* ---- QA pass 3 layout fixes ---- */
/* combat log: centred without transform (the sysin animation + hit-stop pause used to leave it shifted half a width right), wraps to 2 lines */
#combat .combat-log { left: 0; right: 0; margin: 0 auto; transform: none; max-width: calc(100% - 24px); white-space: normal; overflow-wrap: anywhere; line-height: 1.3; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
/* name plates: long names shrink to fit (JS fitText) and may break inside a long word rather than ellipsize */
.unit .plate .nm { overflow-wrap: anywhere; hyphens: auto; -webkit-hyphens: auto; -webkit-line-clamp: 3; }
#combat .unit.elite .plate { max-width: 180px; }
/* dead units: the corpse stays dimmed, its plate/intent/status fade out (no ghost "SEWER RAT" label) */
.unit.dead .plate, .unit.dead .intent, .unit.dead .sts { opacity: 0; transition: opacity .5s ease .35s; }
.unit.dead { opacity: .55; transition: opacity .6s ease .3s, filter .4s, transform .4s; }
/* landscape combat: an open Items/Skills sheet is one compact row and lifts/shrinks the enemy side instead of covering its plates */
@media (orientation: landscape) and (max-height: 520px) {
  #combat .sheet { display: flex; flex-wrap: nowrap; overflow-x: auto; overflow-y: hidden; max-height: 64px; touch-action: pan-x; }
  #combat .sheet > * { flex: 0 0 auto; min-width: 150px; }
  #combat .side { transition: transform .22s cubic-bezier(.2,.8,.3,1); }
  #combat:has(.sheet:not(.hidden)) .side.enemies { transform: translateY(-34px) scale(.84); transform-origin: 50% 0; }
  #combat:has(.sheet:not(.hidden)) .who-turn { display: none; }
  #combat .who-turn { position: relative; z-index: 1; }
}
/* System AI / bark subtitles in combat sit in the free band under the turn-order strip (portrait) or between the two sides (landscape), never over plates or the pet */
body:has(#combat) .subtitle { top: calc(env(safe-area-inset-top, 0px) + 66px); bottom: auto; max-width: min(84vw, 480px); font-size: 13px; }
@media (orientation: landscape) and (max-height: 520px) { body:has(#combat) .subtitle { top: 40%; max-width: min(30vw, 340px); font-size: 12.5px; } }
/* landscape explore: at most 2 short system lines (older ones fade), compact banner */
@media (orientation: landscape) and (max-height: 520px) {
  .syslog { left: 28%; right: 28%; gap: 3px; }
  .syslog > :nth-last-child(n+3) { display: none; }
  .sysmsg { font-size: 11.5px; padding: 4px 9px 4px 30px; } .sysmsg::before { top: 6px; }
  .banner { padding: 6px 16px 6px 8px; gap: 8px; max-width: 46vw; }
  .banner .crest { width: 34px; height: 38px; font-size: 18px; }
  .banner h3 { font-size: 14px; } .banner p { font-size: 11px; }
}
@media (hover: none) and (pointer: coarse) { .kbd, .act .k { display: none; } } /* no keyboard hints on touch */
/* a subtitle never covers an open panel: with a modal up it moves to the top edge */
body:has(.modal-wrap) .subtitle { top: calc(env(safe-area-inset-top, 0px) + 10px); bottom: auto; max-width: min(88vw, 520px); }

/* QA P3 reduced motion: html.rm is set from prefers-reduced-motion or Settings > Reduce motion (js/engine/motion.js).
   Decorative motion collapses to its end state; information that only exists as an animation (damage numbers,
   combat banners, viewer pops) fades in place instead of flying. */
html.rm *:not(.dmgnum):not(.cbanner):not(.viewerpop), html.rm *::before, html.rm *::after {
  animation-duration: 1ms !important; animation-delay: 0s !important; animation-iteration-count: 1 !important;
  transition-duration: 1ms !important; transition-delay: 0s !important; scroll-behavior: auto !important; }
html.rm .dmgnum, html.rm .dmgnum.crit { animation-name: rmdmg !important; animation-duration: 1s !important; animation-iteration-count: 1 !important; }
html.rm .cbanner, html.rm .viewerpop { animation-name: rmfade !important; animation-iteration-count: 1 !important; }
html.rm #combat .embers, html.rm .title-embers, html.rm .boxstage .rays { display: none !important; }
@keyframes rmdmg { 0% { opacity: 0; transform: translate(-50%, -24px); } 8%, 80% { opacity: 1; transform: translate(-50%, -24px); } 100% { opacity: 0; transform: translate(-50%, -24px); } }
@keyframes rmfade { 0% { opacity: 0; } 10%, 82% { opacity: 1; } 100% { opacity: 0; } }
/* QA3 showcase: the room name yields while the big region title is up (they collided in landscape) */
#hud:has(> .regiontitle.show) > .roomname { opacity: 0; }
@media (orientation: landscape) and (max-height: 500px) { .roomname { top: calc(12px + var(--safe-t)); } .regiontitle { top: 16%; } }
