/* =====================================================================
   ECLYRIA: REINOS DO VÉU — ESTILO
   Otimizado para leitura em compartilhamento de tela (Discord).
   ===================================================================== */

:root{
  --bg:#07070c; --bg2:#0d0d16; --bg3:#141422; --panel:#12121e;
  --line:#2a2a3d; --line2:#3d3d55;
  --txt:#e8e6f0; --txt2:#a5a3b8; --txt3:#6e6c85;
  --gold:#f0b429; --blood:#dc2626; --dark:#8b5cf6; --fire:#f97316; --water:#0ea5e9; --veil:#22d3ee;
  --ok:#4ade80; --warn:#fbbf24; --bad:#ef4444;
  --serif:'Cinzel','Trajan Pro',Georgia,'Times New Roman',serif;
  --body:'Segoe UI',Inter,system-ui,-apple-system,sans-serif;
  --mono:'Consolas','JetBrains Mono',monospace;
  --accent:var(--veil);
  --r:10px;
}

*{box-sizing:border-box;margin:0;padding:0}
html,body{height:100%}
body{
  background:var(--bg); color:var(--txt); font-family:var(--body);
  font-size:16px; overflow:hidden; -webkit-font-smoothing:antialiased;
}
#app{height:100vh;display:flex;flex-direction:column}

/* fundo animado */
#bgfx{position:fixed;inset:0;z-index:0;pointer-events:none;
  background:
    radial-gradient(ellipse 90% 60% at 50% -10%, color-mix(in srgb,var(--accent) 16%,transparent), transparent 65%),
    radial-gradient(ellipse 70% 50% at 10% 100%, color-mix(in srgb,var(--accent) 10%,transparent), transparent 60%),
    linear-gradient(180deg,#07070c,#0a0a13 55%,#05050a);
  transition:background 1.4s ease;
}
#bgfx::after{content:'';position:absolute;inset:0;opacity:.05;
  background-image:repeating-linear-gradient(0deg,transparent,transparent 2px,#fff 2px,#fff 3px);
  animation:scan 12s linear infinite}
@keyframes scan{to{transform:translateY(60px)}}
#app>*{position:relative;z-index:1}

/* ============================ TOPO ============================ */
header{
  display:flex;align-items:center;gap:16px;padding:10px 18px;
  background:linear-gradient(180deg,#0f0f1b,#0a0a12);
  border-bottom:2px solid var(--line);box-shadow:0 4px 24px #000a;flex:0 0 auto;
}
.brand{font-family:var(--serif);font-weight:700;letter-spacing:.14em;font-size:19px;
  background:linear-gradient(90deg,#fff,var(--accent));-webkit-background-clip:text;background-clip:text;color:transparent;white-space:nowrap}
.brand small{display:block;font-size:9px;letter-spacing:.32em;color:var(--txt3);-webkit-text-fill-color:var(--txt3)}
.hdr-chip{display:flex;align-items:center;gap:7px;background:var(--bg3);border:1px solid var(--line);
  border-radius:99px;padding:5px 13px;font-size:12.5px;color:var(--txt2);white-space:nowrap}
.hdr-chip b{color:var(--txt);font-weight:600}
.hdr-spacer{flex:1}
header button{font-size:12.5px}

/* ============================ LAYOUT ========================== */
main{flex:1;display:grid;grid-template-columns:290px minmax(0,1fr) 330px;grid-template-areas:"party stage side";gap:12px;padding:12px;overflow:hidden}
.col{display:flex;flex-direction:column;gap:12px;min-height:0;overflow-y:auto;overflow-x:hidden}
.col::-webkit-scrollbar{width:8px}
.col::-webkit-scrollbar-thumb{background:var(--line);border-radius:4px}
.col::-webkit-scrollbar-track{background:transparent}

.panel{background:linear-gradient(180deg,var(--panel),#0c0c15);border:1px solid var(--line);
  border-radius:var(--r);overflow:hidden;flex:0 0 auto}
.panel.grow{flex:1 1 auto;display:flex;flex-direction:column;min-height:0}
.panel-h{display:flex;align-items:center;gap:8px;padding:9px 13px;background:#0a0a12;
  border-bottom:1px solid var(--line);font-family:var(--serif);font-size:12px;
  letter-spacing:.2em;text-transform:uppercase;color:var(--txt2)}
.panel-h .sp{flex:1}
.panel-b{padding:12px;overflow-y:auto;flex:1;min-height:0}
.panel-b::-webkit-scrollbar{width:7px}
.panel-b::-webkit-scrollbar-thumb{background:var(--line);border-radius:4px}

/* ============================ BOTÕES ========================== */
button{font-family:var(--body);background:var(--bg3);color:var(--txt);border:1px solid var(--line2);
  border-radius:7px;padding:8px 13px;cursor:pointer;font-size:13.5px;transition:.14s;font-weight:500}
button:hover:not(:disabled){background:#1e1e30;border-color:var(--accent);transform:translateY(-1px)}
button:active:not(:disabled){transform:translateY(0)}
button:disabled{opacity:.34;cursor:not-allowed}
button.primary{background:linear-gradient(180deg,#1d4ed8,#1e3a8a);border-color:#3b82f6}
button.gold{background:linear-gradient(180deg,#b45309,#78350f);border-color:var(--gold);color:#fde68a}
button.danger{background:linear-gradient(180deg,#991b1b,#7f1d1d);border-color:#dc2626}
button.ghost{background:transparent;border-color:var(--line)}
button.sm{padding:5px 9px;font-size:12px}
button.wide{width:100%}
button.on{background:linear-gradient(180deg,#0e7490,#155e75);border-color:var(--veil)}

/* ========================= CARDS DE HERÓI ===================== */
.hero{position:relative;background:linear-gradient(135deg,#12121e,#0b0b13);
  border:1px solid var(--line);border-left:4px solid var(--c);border-radius:var(--r);
  padding:11px;cursor:pointer;transition:.16s}
.hero:hover{border-color:var(--c);box-shadow:0 0 22px -6px var(--c)}
.hero.active{border-color:var(--c);box-shadow:0 0 0 2px var(--c),0 0 26px -4px var(--c);
  background:linear-gradient(135deg,color-mix(in srgb,var(--c) 15%,#12121e),#0b0b13)}
.hero.dead{filter:grayscale(1) brightness(.5)}
.hero.targetable{outline:2px dashed var(--warn);outline-offset:2px;animation:pulse 1s infinite}
@keyframes pulse{50%{outline-color:#fff}}
.hero-top{display:flex;align-items:center;gap:9px;margin-bottom:8px}
.hero-ico{font-size:24px;filter:drop-shadow(0 0 8px var(--c))}
.hero-nm{font-family:var(--serif);font-size:14.5px;font-weight:700;color:var(--c);line-height:1.15}
.hero-pl{font-size:10.5px;color:var(--txt3);letter-spacing:.07em}
.hero-lv{margin-left:auto;background:var(--bg);border:1px solid var(--line2);border-radius:6px;
  padding:2px 7px;font-size:11px;color:var(--gold);font-weight:700;white-space:nowrap}

.bar{height:13px;background:#05050a;border:1px solid var(--line);border-radius:4px;
  overflow:hidden;position:relative;margin-bottom:4px}
.bar>i{display:block;height:100%;border-radius:2px;transition:width .45s cubic-bezier(.2,.9,.3,1)}
.bar>span{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  font-size:9.5px;font-weight:700;color:#fff;text-shadow:0 1px 3px #000,0 0 6px #000;letter-spacing:.04em}
.bar.hp>i{background:linear-gradient(90deg,#7f1d1d,#ef4444,#f87171)}
.bar.mp>i{background:linear-gradient(90deg,#1e3a8a,#3b82f6,#60a5fa)}
.bar.res>i{background:linear-gradient(90deg,var(--c),color-mix(in srgb,var(--c) 40%,#fff))}
.bar.xp{height:5px}.bar.xp>i{background:linear-gradient(90deg,#a16207,var(--gold))}
.bar.sm{height:9px}

.tide-strip{display:flex;gap:3px;margin-bottom:4px}
.tide-strip>i{flex:1;height:7px;background:#05050a;border:1px solid var(--line);border-radius:3px}
.tide-strip>i.on{background:linear-gradient(90deg,#0369a1,#38bdf8);box-shadow:0 0 8px #38bdf8}

.stats-row{display:flex;flex-wrap:wrap;gap:4px;margin-top:7px}
.stat{background:#08080f;border:1px solid var(--line);border-radius:5px;padding:2px 6px;font-size:10.5px;color:var(--txt2)}
.stat b{color:var(--txt);font-weight:600}

.stx{display:flex;flex-wrap:wrap;gap:3px;margin-top:6px;min-height:19px}
.st{font-size:10px;padding:2px 6px;border-radius:99px;border:1px solid;background:#0008;white-space:nowrap}

/* ============================ PALCO =========================== */
#stage{flex:1;display:flex;flex-direction:column;min-height:0;gap:12px}

/* ---------- narrativa ---------- */
#narrative{background:linear-gradient(180deg,#0e0e18,#08080f);border:1px solid var(--line);
  border-radius:var(--r);padding:26px 34px;overflow-y:auto;overflow-x:hidden;flex:1;min-height:0}
#narrative h2{font-family:var(--serif);font-size:26px;letter-spacing:.06em;margin-bottom:6px;
  background:linear-gradient(90deg,#fff,var(--accent));-webkit-background-clip:text;background-clip:text;color:transparent}
#narrative .sub{color:var(--txt3);font-size:12px;letter-spacing:.24em;text-transform:uppercase;margin-bottom:20px}
#narrative .body{font-size:19px;line-height:1.75;white-space:pre-wrap;color:#ddd9e8;max-width:78ch}
#narrative .body em{color:var(--accent);font-style:italic}
#narrative .body strong{color:var(--gold)}
.cursor{display:inline-block;width:9px;height:20px;background:var(--accent);
  vertical-align:-3px;animation:blink .8s steps(2) infinite}
@keyframes blink{50%{opacity:0}}

/* ---------- mapa ---------- */
#map-wrap{flex:1;min-height:0;position:relative;background:
  radial-gradient(ellipse at 50% 40%,#101024,#06060c);border:1px solid var(--line);
  border-radius:var(--r);overflow:hidden}
#map{width:100%;height:100%;display:block}
.node{cursor:pointer;transition:.2s}
.node:hover .node-ring{stroke-width:3.5;r:30}
.node.alterado .node-ring{stroke-width:3px}
.node-eco{stroke-dasharray:3 5;transform-origin:center;animation:ecoMapa 5s linear infinite}
@keyframes ecoMapa{to{stroke-dashoffset:-54}}
.node-lbl{font-family:var(--serif);font-size:13px;fill:#fff;text-anchor:middle;
  letter-spacing:.09em;paint-order:stroke;stroke:#000;stroke-width:4px}
.node-sub{font-size:8.5px;fill:#9a98ad;text-anchor:middle;letter-spacing:.16em;
  text-transform:uppercase;paint-order:stroke;stroke:#000;stroke-width:3px}
.map-path{stroke:#2a2a3d;stroke-width:2;stroke-dasharray:6 7;fill:none;opacity:.7}
.map-path.lit{stroke:var(--accent);opacity:.55;animation:dash 22s linear infinite}
@keyframes dash{to{stroke-dashoffset:-260}}
#party-token{filter:drop-shadow(0 0 12px var(--gold))}
/* cada herói balança um pouco fora de fase — dá sensação de caminhada */
.walker{animation:bob 1.6s ease-in-out infinite}
@keyframes bob{0%,100%{transform:translateY(0)}50%{transform:translateY(-4px)}}
#party-token.walking .walker{animation:march .42s ease-in-out infinite}
@keyframes march{0%,100%{transform:translateY(0)}50%{transform:translateY(-7px)}}

/* ---------- combate ---------- */
#combat{flex:1;display:flex;flex-direction:column;min-height:0;gap:10px}
#enemy-field{flex:0 0 auto;display:flex;flex-wrap:wrap;gap:11px;justify-content:center;
  padding:16px 12px;background:radial-gradient(ellipse at 50% 0%,#1a0d14,#08080f);
  border:1px solid var(--line);border-radius:var(--r);min-height:150px;align-items:flex-start}
.enemy{width:158px;background:linear-gradient(180deg,#170f16,#0c0810);border:1px solid #3a2030;
  border-radius:9px;padding:9px;cursor:pointer;transition:.16s;position:relative}
.enemy:hover{border-color:var(--bad);transform:translateY(-3px)}
.enemy.boss{width:230px;border-color:var(--gold);box-shadow:0 0 30px -8px var(--gold);
  background:linear-gradient(180deg,#1d1210,#0c0810)}
.enemy.dead{filter:grayscale(1) brightness(.34);pointer-events:none}
.enemy.targetable{outline:2px dashed var(--warn);outline-offset:3px;animation:pulse 1s infinite}
.enemy.acting{border-color:#fff;box-shadow:0 0 0 2px #fff8,0 0 26px -4px #fff}
.enemy-ico{font-size:33px;text-align:center;filter:drop-shadow(0 0 10px #000)}
.enemy.boss .enemy-ico{font-size:50px}
.enemy-nm{font-family:var(--serif);font-size:12.5px;text-align:center;margin:5px 0;color:#f5d3d3;line-height:1.2}
.enemy.boss .enemy-nm{font-size:15px;color:var(--gold)}
.enemy-lv{position:absolute;top:5px;right:7px;font-size:9.5px;color:var(--txt3)}

/* ordem de turnos */
#turn-order{display:flex;gap:6px;align-items:center;overflow-x:auto;padding:7px 10px;
  background:#0a0a12;border:1px solid var(--line);border-radius:var(--r);flex:0 0 auto}
/* `flex:0 0 auto` e o que impede o chip de ENCOLHER. Num flex row o padrao
   e `0 1 auto`, ou seja, encolhivel -- e como o texto e `nowrap`, encolher
   nao quebra linha: transborda por cima do vizinho. Ficou latente enquanto
   a barra tinha folga, e apareceu no dia em que entrou mais um chip: o
   titulo do objetivo passou a ser pintado por cima do chip seguinte. A
   barra ja tem `overflow-x:auto`; quem deve ceder e a rolagem, nao o chip. */
.turn-chip{display:flex;align-items:center;gap:5px;padding:4px 9px;border-radius:99px;
  border:1px solid var(--line);background:#12121e;font-size:11.5px;white-space:nowrap;
  opacity:.6;flex:0 0 auto}
.turn-chip.now{opacity:1;border-color:var(--gold);background:linear-gradient(90deg,#2a1f08,#12121e);
  box-shadow:0 0 14px -3px var(--gold);font-weight:700}
.turn-chip.dead{opacity:.22;text-decoration:line-through}
/* O chip de efeito de campo nao e um turno na fila -- ele so mora na mesma
   barra. Fundo proprio e um brilho fraco separam "isto esta acontecendo no
   campo" de "esta unidade age nesta ordem", que e a leitura de todos os
   chips vizinhos. */
.turn-chip.campo{opacity:1;font-weight:600;
  background:linear-gradient(180deg,#ffffff12,#00000038);
  box-shadow:0 0 10px -2px currentColor}
#round-badge{font-family:var(--serif);font-size:12px;letter-spacing:.16em;color:var(--gold);
  padding-right:10px;border-right:1px solid var(--line);margin-right:4px;white-space:nowrap}

/* menu de ações */
#actions{flex:0 0 auto;background:linear-gradient(180deg,#101019,#0a0a12);
  border:1px solid var(--line);border-radius:var(--r);padding:11px}
.act-who{font-family:var(--serif);font-size:14px;margin-bottom:9px;display:flex;align-items:center;gap:8px}
.act-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(178px,1fr));gap:7px}
.skill-btn{display:flex;align-items:center;gap:8px;text-align:left;padding:9px 11px;position:relative;overflow:hidden}
.skill-btn .ico{font-size:19px;flex:0 0 auto}
.skill-btn .nm{font-size:12.8px;font-weight:600;line-height:1.2}
.skill-btn .cost{font-size:10px;color:var(--txt3);margin-top:1px}
.skill-btn.ult{background:linear-gradient(100deg,#3b0764,#1e1b4b);border-color:var(--gold);color:#fde68a}
.skill-btn.ult.ready{animation:ultglow 1.5s ease-in-out infinite;box-shadow:0 0 22px -4px var(--gold)}
@keyframes ultglow{50%{box-shadow:0 0 34px -2px var(--gold)}}
.skill-btn.combo{background:linear-gradient(100deg,#7f1d1d,#4c1d95);border-color:#f472b6;color:#fbcfe8;
  animation:ultglow 1.2s infinite}

/* log */
#log{font-family:var(--mono);font-size:12.3px;line-height:1.65}
#log .l{padding:2px 5px;border-left:2px solid transparent;margin-bottom:1px;border-radius:0 3px 3px 0}
.l.round{color:var(--gold);border-color:var(--gold);background:#f0b4290e;font-weight:700;
  letter-spacing:.12em;margin:6px 0;text-align:center;border-left:none;border-top:1px solid #f0b42933}
.l.action{color:#cbd5e1;border-color:#475569;background:#ffffff06}
.l.dmg{color:#fca5a5}
.l.crit{color:#fde047;border-color:var(--gold);background:#f0b42912;font-weight:700}
.l.heal{color:#86efac}
.l.status{color:#c4b5fd}
.l.death{color:#ef4444;font-weight:700;border-color:var(--bad)}
.l.win{color:var(--ok);font-weight:700;background:#4ade8012;border-color:var(--ok);text-align:center}
.l.lose{color:var(--bad);font-weight:700;background:#ef444412;border-color:var(--bad);text-align:center}
.l.combo{color:#f9a8d4;font-weight:700;background:#f472b615;border-color:#f472b6;text-align:center}
.l.ult{color:#fde68a;font-weight:700;background:#a855f715;border-color:var(--gold)}
.l.phase{color:#fdba74;font-weight:700;background:#f9731615;border-color:var(--fire)}
.l.tide{color:#7dd3fc;border-color:var(--water);background:#0ea5e912}
.l.info,.l.field,.l.shield,.l.counter,.l.summon,.l.revive{color:var(--txt2)}
.l.gm{color:var(--veil);background:#22d3ee10;border-color:var(--veil)}

/* ============================ DADOS =========================== */
#dice-face{width:100%;aspect-ratio:1.35;display:flex;align-items:center;justify-content:center;
  font-family:var(--serif);font-size:62px;font-weight:700;
  background:radial-gradient(circle at 50% 35%,#1c1c2e,#0a0a12);
  border:2px solid var(--line2);border-radius:14px;position:relative;color:var(--txt);
  text-shadow:0 0 26px currentColor;transition:.2s}
#dice-face.rolling{animation:shake .09s infinite}
@keyframes shake{0%{transform:translate(-3px,2px) rotate(-2deg)}50%{transform:translate(3px,-2px) rotate(2deg)}100%{transform:translate(-2px,-1px) rotate(-1deg)}}
#dice-face.nat20{color:var(--gold);border-color:var(--gold);box-shadow:0 0 44px -6px var(--gold)}
#dice-face.nat1{color:var(--bad);border-color:var(--bad);box-shadow:0 0 44px -6px var(--bad)}
#dice-face small{position:absolute;bottom:9px;font-size:11px;letter-spacing:.2em;color:var(--txt3);
  text-shadow:none;font-family:var(--body)}
.dice-row{display:grid;grid-template-columns:repeat(4,1fr);gap:5px;margin-top:9px}
#dice-result{margin-top:9px;font-size:12.5px;color:var(--txt2);text-align:center;min-height:34px;line-height:1.4}

/* ========================== QUEST LOG ========================= */
.quest{border:1px solid var(--line);border-radius:8px;padding:9px 11px;margin-bottom:8px;
  background:#0c0c15;border-left:3px solid var(--qc,var(--line2))}
.quest.done{opacity:.5}
.quest.locked{opacity:.32;filter:grayscale(1)}
.quest-t{font-family:var(--serif);font-size:13px;display:flex;align-items:center;gap:6px;line-height:1.25}
.quest-tag{font-size:9px;letter-spacing:.14em;text-transform:uppercase;padding:1px 5px;
  border-radius:3px;border:1px solid;margin-left:auto;white-space:nowrap}
.quest-s{font-size:11.5px;color:var(--txt3);margin:5px 0 7px;line-height:1.45}
.step{display:flex;gap:7px;align-items:flex-start;font-size:11.8px;color:var(--txt2);
  padding:3px 0;cursor:pointer;line-height:1.4}
.step:hover{color:var(--txt)}
.step .box{flex:0 0 auto;width:14px;height:14px;border:1px solid var(--line2);border-radius:3px;
  margin-top:1px;display:flex;align-items:center;justify-content:center;font-size:10px}
.step.on .box{background:var(--ok);border-color:var(--ok);color:#000}
.step.on{color:var(--txt3);text-decoration:line-through}

/* ========================== INVENTÁRIO ======================== */
.item{display:flex;align-items:center;gap:8px;padding:6px 8px;border-radius:6px;
  border:1px solid var(--line);background:#0c0c15;margin-bottom:5px;cursor:pointer;transition:.13s}
.item:hover{border-color:var(--rc);background:#15151f}
.item .ic{font-size:17px}
.item .nm{font-size:12.3px;color:var(--rc);font-weight:600;line-height:1.2}
.item .ds{font-size:10px;color:var(--txt3);line-height:1.3}
.item .qt{margin-left:auto;font-size:11px;color:var(--txt2);background:#000;padding:1px 6px;border-radius:4px}

/* =========================== MODAL ============================ */
.modal{position:fixed;inset:0;background:#000d;backdrop-filter:blur(7px);z-index:100;
  display:flex;align-items:center;justify-content:center;padding:24px;animation:fade .2s}
@keyframes fade{from{opacity:0}}
.modal-box{background:linear-gradient(180deg,#12121e,#0a0a12);border:1px solid var(--line2);
  border-radius:14px;max-width:min(1020px,96vw);max-height:92vh;overflow-y:auto;
  box-shadow:0 30px 90px #000;width:100%}
.modal-h{display:flex;align-items:center;gap:12px;padding:15px 22px;border-bottom:1px solid var(--line);
  font-family:var(--serif);font-size:18px;letter-spacing:.09em;position:sticky;top:0;
  background:#0d0d17;z-index:2}
.modal-b{padding:22px}
.modal-f{padding:14px 22px;border-top:1px solid var(--line);display:flex;gap:9px;justify-content:flex-end;
  position:sticky;bottom:0;background:#0d0d17}

/* ===================== ENTRADA — O VÉU SE ABRE ==================== */
.modal-home{background:radial-gradient(ellipse at 50% 20%,#10223c88 0%,#05060bdd 48%,#020205f2 100%);backdrop-filter:blur(11px)}
.modal-home .modal-box{width:min(940px,96vw);overflow:hidden;border:1px solid #46506b;border-radius:6px;
  background:#090b12;box-shadow:0 38px 120px #000,0 0 80px #0b274055}
.modal-home .modal-h{min-height:42px;padding:10px 18px;background:linear-gradient(90deg,#131827,#0b0d14 45%,#131827);
  border-bottom-color:#3c455b;color:#bfcbe3;font-size:10px;letter-spacing:.24em;text-transform:uppercase}
.modal-home .modal-h::before{content:'CRÔNICAS DE ECLYRIA';color:#d7b56f}.modal-home .modal-h{font-size:0}
.modal-home .modal-h button{font-size:15px}.modal-home .modal-b{background:radial-gradient(ellipse at 26% 50%,#192c46aa 0%,transparent 55%),#090b12}
.eclyria-home{display:grid;grid-template-columns:minmax(0,1.08fr) minmax(340px,.92fr);min-height:440px;position:relative;overflow:hidden}
.eclyria-home::before{content:'';position:absolute;inset:0;pointer-events:none;opacity:.45;background-image:linear-gradient(90deg,transparent 49.8%,#6b78951c 50%,transparent 50.2%),linear-gradient(#6b78910d 1px,transparent 1px);background-size:100% 100%,100% 5px}
.home-chronicle{position:relative;display:flex;flex-direction:column;justify-content:center;padding:50px 50px 42px;isolation:isolate;border-right:1px solid #374154}
.home-chronicle::after{content:'';position:absolute;inset:17px 0 17px 17px;z-index:-1;border:1px solid #9a78402e;box-shadow:inset 0 0 70px #0008;pointer-events:none}
.home-rift{position:absolute;right:22px;top:28px;width:155px;height:150px;opacity:.7;filter:drop-shadow(0 0 25px #5ac8f055);pointer-events:none}
.home-rift::before,.home-rift::after,.home-rift i,.home-rift b,.home-rift span{content:'';position:absolute;display:block;border-radius:50%;border:1px solid #7fe7ff77;transform:rotate(-28deg)}
.home-rift::before{width:123px;height:17px;left:14px;top:66px;box-shadow:0 0 22px #3ac6f4}.home-rift::after{width:72px;height:8px;left:38px;top:70px;background:#c9f6ff88;box-shadow:0 0 20px #b9f3ff}
.home-rift i{width:112px;height:45px;left:18px;top:47px;border-color:#7e65d2aa}.home-rift b{width:98px;height:72px;left:24px;top:32px;border-color:#d2a86b55}.home-rift span{width:133px;height:30px;left:8px;top:58px;border-color:#47c7e466}
.home-overline,.home-path-label{font:700 10px var(--mono);letter-spacing:.22em;color:#caa35e;margin-bottom:13px}.home-chronicle h1{font-family:var(--serif);font-size:44px;letter-spacing:.12em;line-height:.88;color:#e9edf9;text-shadow:0 3px 0 #080a10,0 0 28px #7abbe044;margin:0}
.home-chronicle h1 small{display:block;font:600 10px var(--body);letter-spacing:.52em;color:#9eabc4;margin:13px 0 0 4px}.home-copy{max-width:390px;margin:27px 0 25px;color:#c2c7d2;font:15px/1.65 var(--body)}
.home-forces{display:flex;gap:7px;flex-wrap:wrap}.home-forces span{display:inline-flex;align-items:center;gap:7px;padding:6px 8px;border:1px solid #53607988;background:#080b1288;color:#bbc5d8;font:700 9px var(--mono);letter-spacing:.08em;text-transform:uppercase}.home-forces i{width:7px;height:7px;display:block;border-radius:50%;box-shadow:0 0 9px currentColor}.home-forces .blood{color:#e27070}.home-forces .shadow{color:#b58bea}.home-forces .dragon{color:#eeae67}.home-forces .tide{color:#6fc7ee}
.home-paths{position:relative;padding:47px 35px 35px;background:linear-gradient(135deg,#111827bb,#080a10cc);display:flex;flex-direction:column;justify-content:center;gap:9px}.home-path-label{color:#8ea7c8;margin-bottom:7px}
.home-action{width:100%;min-height:67px;display:flex;align-items:center;gap:14px;padding:12px 15px;text-align:left;color:#e6eaf3;border:1px solid #44516b;background:linear-gradient(110deg,#131a29,#0b0d15);cursor:pointer;transition:transform .18s ease,border-color .18s ease,box-shadow .18s ease}.home-action:hover:not(:disabled),.home-action:focus-visible{transform:translateX(-3px);border-color:#95c9ec;box-shadow:0 0 0 1px #6fbde855,0 10px 28px #0008;outline:none}.home-action:disabled{opacity:.45;cursor:not-allowed}.home-action svg{width:27px;height:27px;flex:none;fill:none;stroke:currentColor;stroke-width:1.55;stroke-linecap:round;stroke-linejoin:round;color:#cdb171}.home-action.host svg{color:#67c7ef}.home-action.join svg{color:#b99bea}.home-action span{display:grid;gap:3px}.home-action b{font:700 14px var(--serif);letter-spacing:.05em}.home-action small,.home-utility small{color:#8d99af;font:11px/1.35 var(--body)}
.home-action.local{border-color:#806b3f;background:linear-gradient(110deg,#1b1b1c,#0d0c0d)}.home-action.host{border-color:#39789d;background:linear-gradient(110deg,#102239,#0b111d);box-shadow:inset 3px 0 #55c4ed}.home-action.host:hover:not(:disabled),.home-action.host:focus-visible{border-color:#7cd9fb;box-shadow:inset 3px 0 #8be3ff,0 0 0 1px #6fbde855,0 10px 28px #0008}
.home-utility{display:grid;gap:5px;margin-top:7px;padding-top:14px;border-top:1px solid #394153}.home-utility button{display:flex;justify-content:space-between;align-items:baseline;gap:8px;padding:6px 0;border:0;background:transparent;color:#b6c5d9;text-align:left;cursor:pointer}.home-utility button:hover,.home-utility button:focus-visible{color:#f0cf82;outline:none}.home-utility button span{font:700 11px var(--body)}.home-utility button small{font-size:10px;text-align:right}
@media(max-width:700px){.modal-home{padding:12px}.modal-home .modal-box{max-height:96vh}.eclyria-home{grid-template-columns:1fr;overflow:auto}.home-chronicle{padding:38px 30px 28px;border-right:0;border-bottom:1px solid #374154}.home-rift{right:-18px;top:-8px;opacity:.34}.home-chronicle h1{font-size:36px}.home-copy{margin:20px 0}.home-paths{padding:30px}.home-forces{max-width:320px}}
@media(prefers-reduced-motion:reduce){.home-action{transition:none}.home-action:hover:not(:disabled){transform:none}}

/* seleção de classe */
.cls-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(232px,1fr));gap:13px}
.cls-card{border:2px solid var(--line);border-radius:12px;padding:16px;cursor:pointer;transition:.18s;
  background:linear-gradient(160deg,#12121e,#0a0a12);position:relative;overflow:hidden}
.cls-card::before{content:'';position:absolute;inset:0;background:radial-gradient(circle at 50% 0%,var(--c),transparent 70%);opacity:.11}
.cls-card:hover{border-color:var(--c);transform:translateY(-3px)}
.cls-card.sel{border-color:var(--c);box-shadow:0 0 0 2px var(--c),0 0 34px -6px var(--c)}
.cls-card.taken{opacity:.35;pointer-events:none;filter:grayscale(1)}
.cls-ico{font-size:44px;text-align:center;filter:drop-shadow(0 0 14px var(--c))}
.cls-nm{font-family:var(--serif);font-size:18px;text-align:center;color:var(--c);margin:7px 0 2px}
.cls-role{font-size:10.5px;text-align:center;color:var(--txt3);letter-spacing:.13em;text-transform:uppercase}
.cls-tag{font-size:12px;text-align:center;color:var(--txt2);margin:9px 0;font-style:italic;line-height:1.45}
.cls-in{width:100%;background:#05050a;border:1px solid var(--line2);color:var(--txt);
  border-radius:7px;padding:8px 11px;font-size:13.5px;margin-top:9px;font-family:var(--body)}
.cls-in:focus{outline:none;border-color:var(--c)}

/* árvore de talentos */
.tree-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:15px}
.tree{border:1px solid var(--line);border-radius:10px;padding:13px;background:#0b0b13}
.tree-h{font-family:var(--serif);font-size:14px;color:var(--tc);text-align:center;margin-bottom:3px}
.tree-d{font-size:10px;color:var(--txt3);text-align:center;letter-spacing:.14em;text-transform:uppercase;margin-bottom:11px}
.tnode{border:1px solid var(--line);border-radius:7px;padding:8px 10px;margin-bottom:7px;
  cursor:pointer;transition:.14s;background:#0e0e18}
.tnode:hover:not(.locked){border-color:var(--tc)}
.tnode.on{border-color:var(--tc);background:color-mix(in srgb,var(--tc) 16%,#0e0e18);
  box-shadow:0 0 16px -5px var(--tc)}
.tnode.locked{opacity:.34;cursor:not-allowed}
.tnode .n{font-size:12.5px;font-weight:600;color:var(--txt)}
.tnode .d{font-size:10.5px;color:var(--txt3);margin-top:2px;line-height:1.4}
.subclass-pick{display:grid;grid-template-columns:repeat(3,1fr);gap:9px;margin-bottom:15px}
.subclass-card{display:flex;flex-direction:column;gap:4px;text-align:left;padding:11px;border:1px solid var(--line2);
  border-left:3px solid var(--sc);border-radius:8px;background:#0b0b13;color:var(--txt);cursor:pointer;transition:.16s}
.subclass-card:hover{border-color:var(--sc);transform:translateY(-2px);box-shadow:0 8px 24px -15px var(--sc)}
.subclass-card b{font-family:var(--serif);color:var(--sc)} .subclass-card span{font-size:11px;color:var(--txt3)}
.subclass-current{margin:0 auto 14px;width:max-content;max-width:100%;border:1px solid var(--sc);color:var(--txt2);padding:5px 11px;border-radius:99px;font-size:11px}

/* painel do narrador */
#gm{position:fixed;top:0;right:0;bottom:0;width:480px;max-width:96vw;z-index:90;
  background:linear-gradient(180deg,#0d0d17,#08080f);border-left:2px solid var(--veil);
  box-shadow:-24px 0 70px #000c;transform:translateX(100%);transition:.32s cubic-bezier(.4,0,.2,1);
  display:flex;flex-direction:column}
#gm.open{transform:translateX(0)}
#gm-h{padding:13px 17px;border-bottom:1px solid var(--line);display:flex;align-items:center;gap:9px;
  font-family:var(--serif);letter-spacing:.16em;font-size:14px;color:var(--veil);background:#0a0a12}
#gm-b{flex:1;overflow-y:auto;padding:15px}
.gm-sec{margin-bottom:19px}
.gm-sec>h4{font-size:10.5px;letter-spacing:.22em;text-transform:uppercase;color:var(--txt3);
  margin-bottom:8px;padding-bottom:5px;border-bottom:1px solid var(--line)}
.gm-row{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:7px}
.gm-row>*{flex:1;min-width:0}
textarea,select,input[type=text],input[type=number]{
  width:100%;background:#05050a;border:1px solid var(--line2);color:var(--txt);
  border-radius:7px;padding:8px 11px;font-size:13px;font-family:var(--body);resize:vertical}
textarea:focus,select:focus,input:focus{outline:none;border-color:var(--veil)}
textarea{min-height:110px;line-height:1.6}
label.lbl{display:block;font-size:10.5px;color:var(--txt3);margin:8px 0 3px;letter-spacing:.1em;text-transform:uppercase}
input[type=range]{width:100%;accent-color:var(--veil)}

/* toast / anúncio grande */
#toast-wrap{position:fixed;top:70px;left:50%;transform:translateX(-50%);z-index:200;
  display:flex;flex-direction:column;gap:8px;align-items:center;pointer-events:none}
.toast{background:#12121ef2;border:1px solid var(--line2);border-left:4px solid var(--tc,var(--accent));
  border-radius:9px;padding:11px 20px;font-size:14px;box-shadow:0 12px 40px #000b;
  animation:slidein .3s;max-width:70vw}
@keyframes slidein{from{opacity:0;transform:translateY(-16px)}}

#banner{position:fixed;inset:0;z-index:150;display:none;align-items:center;justify-content:center;
  background:#000c;backdrop-filter:blur(5px);pointer-events:none}
#banner.show{display:flex;animation:fade .3s}
#banner .t{font-family:var(--serif);font-size:clamp(38px,8vw,104px);letter-spacing:.14em;text-align:center;
  background:linear-gradient(90deg,#fff,var(--bc,var(--gold)),#fff);-webkit-background-clip:text;
  background-clip:text;color:transparent;text-shadow:0 0 70px var(--bc,var(--gold));
  animation:bpop .7s cubic-bezier(.2,1.4,.4,1);line-height:1.1;padding:0 20px}
#banner .s{text-align:center;color:var(--txt2);letter-spacing:.34em;text-transform:uppercase;
  font-size:clamp(11px,1.6vw,16px);margin-top:12px}
@keyframes bpop{from{opacity:0;transform:scale(.72)}}

/* dano flutuante */
.float{position:fixed;pointer-events:none;z-index:210;font-family:var(--serif);font-weight:700;
  text-shadow:0 2px 10px #000,0 0 20px currentColor;animation:floatup 1.15s cubic-bezier(.2,.8,.4,1) forwards}
@keyframes floatup{0%{opacity:0;transform:translateY(0) scale(.6)}
  18%{opacity:1;transform:translateY(-16px) scale(1.22)}
  100%{opacity:0;transform:translateY(-70px) scale(1)}}

.shake{animation:hitshake .34s}
@keyframes hitshake{0%,100%{transform:translateX(0)}20%{transform:translateX(-9px)}40%{transform:translateX(8px)}60%{transform:translateX(-5px)}80%{transform:translateX(3px)}}

/* =====================================================================
   CAMADA VISUAL — arte da campanha
   ===================================================================== */

/* ---------- cenário de fundo atrás da narrativa ---------- */
/* A arte da cena e DECORACAO e nunca deve receber clique. Ela e
   position:absolute cobrindo o painel inteiro, e elemento posicionado
   pinta acima de nao-posicionado: o botao de confirmar leitura ficava
   por baixo dela e o clique morria na imagem de fundo. O botao existia,
   estava habilitado e tinha handler -- so nao chegava nele. */
#scene-art{pointer-events:none;position:absolute;inset:0;z-index:0;background-size:cover;background-position:center;
  opacity:0;transition:opacity 1.6s ease, transform 18s linear;transform:scale(1.04)}
#scene-art.on{opacity:.62;transform:scale(1.10)}
/* Escurece só o suficiente para o texto continuar legível por cima. */
#scene-art::after{pointer-events:none;content:'';position:absolute;inset:0;
  background:linear-gradient(180deg,#07070ce6 0%,#07070c66 38%,#07070cd9 100%)}
#narrative{position:relative}
/* Só o CONTEÚDO sobe de camada. Um seletor curinga aqui sobrescreveria o
   position:absolute do cenário e o fundo sumiria. */
#narrative>h2,
#narrative>.sub,
#narrative>.body,
#narrative>#choices{position:relative;z-index:1}

/* ---------- retrato do herói ----------
   O emoji fica atrás como espaço reservado; a pintura entra por cima
   quando termina de carregar. Assim nada nunca aparece vazio.        */
.hero-face{position:relative;width:46px;height:46px;flex:0 0 auto;border-radius:9px;
  display:flex;align-items:center;justify-content:center;font-size:24px;
  background:#05050a;border:1px solid var(--c);box-shadow:0 0 14px -4px var(--c);
  overflow:hidden;transition:.2s}
.hero:hover .hero-face{transform:scale(1.06)}
.hero.dead .hero-face{filter:grayscale(1) brightness(.5)}
.hero-portrait{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  object-position:center 18%}

.enemy-face{position:relative;width:100%;aspect-ratio:3/4;border-radius:8px;overflow:hidden;
  background:#0a0a12;border:1px solid #3a2030;display:flex;align-items:center;
  justify-content:center;font-size:36px}
.enemy.boss .enemy-face{border-color:var(--gold);box-shadow:0 0 26px -8px var(--gold);font-size:54px}
.enemy.dead .enemy-face{filter:grayscale(1) brightness(.35)}
.hero-banner{width:100%;height:96px;object-fit:cover;object-position:center 22%;
  border-radius:8px;margin-bottom:9px;border:1px solid var(--line);
  mask-image:linear-gradient(180deg,#000 55%,transparent);-webkit-mask-image:linear-gradient(180deg,#000 55%,transparent)}

/* ---------- arte do inimigo no combate ---------- */
.enemy-art{width:100%;aspect-ratio:3/4;object-fit:cover;border-radius:8px;
  border:1px solid #3a2030;background:#0a0a12;display:block}
.enemy.boss .enemy-art{aspect-ratio:3/4;border-color:var(--gold);
  box-shadow:0 0 26px -8px var(--gold)}
.enemy.dead .enemy-art{filter:grayscale(1) brightness(.35)}

/* ---------- entrada de chefe em tela cheia ---------- */
#boss-splash{position:fixed;inset:0;z-index:160;display:none;align-items:center;justify-content:center;
  background:#000d;backdrop-filter:blur(4px);overflow:hidden}
#boss-splash.show{display:flex;animation:fade .4s}
#boss-splash img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  opacity:.55;animation:bossZoom 4.2s ease-out forwards}
@keyframes bossZoom{from{transform:scale(1.22)}to{transform:scale(1.02)}}
#boss-splash .veil{position:absolute;inset:0;
  background:radial-gradient(ellipse at 50% 50%,transparent 20%,#07070ce6 78%)}
#boss-splash .txt{position:relative;text-align:center;padding:0 24px}
#boss-splash .nm{font-family:var(--serif);font-size:clamp(34px,7vw,86px);letter-spacing:.1em;
  color:#fff;text-shadow:0 0 42px var(--gold),0 4px 22px #000;animation:bpop .8s cubic-bezier(.2,1.4,.4,1)}
#boss-splash .sb{letter-spacing:.42em;text-transform:uppercase;color:var(--gold);
  font-size:clamp(11px,1.7vw,15px);margin-top:12px}
#boss-splash .ds{color:var(--txt2);font-style:italic;margin-top:16px;max-width:60ch;
  margin-inline:auto;line-height:1.65;font-size:clamp(12px,1.6vw,15px)}

/* ---------- animações de combate ---------- */
.lunge{animation:lunge .42s cubic-bezier(.3,1.4,.4,1)}
@keyframes lunge{0%{transform:translateY(0)}35%{transform:translateY(-14px) scale(1.05)}100%{transform:translateY(0)}}
.hitflash{animation:hitflash .32s}
@keyframes hitflash{0%,100%{filter:none}30%{filter:brightness(2.4) saturate(.3)}}
.healpulse{animation:healpulse .8s}
@keyframes healpulse{0%,100%{box-shadow:none}40%{box-shadow:0 0 0 3px #4ade8066,0 0 30px -4px #4ade80}}

/* clarão elemental por cima do campo */
#fx-flash{position:fixed;inset:0;z-index:140;pointer-events:none;opacity:0}
#fx-flash.go{animation:fxflash .55s ease-out}
@keyframes fxflash{0%{opacity:0}18%{opacity:.55}100%{opacity:0}}

/* rasgo de tela para ultimates */
#fx-slash{position:fixed;inset:0;z-index:141;pointer-events:none;display:none}
#fx-slash.go{display:block}
#fx-slash i{position:absolute;left:-20%;width:140%;height:3px;background:linear-gradient(90deg,transparent,#fff,transparent);
  box-shadow:0 0 24px 6px currentColor;opacity:0;animation:slash .5s ease-out forwards}
@keyframes slash{0%{opacity:0;transform:translateX(-30%) scaleX(.2)}
  25%{opacity:1}100%{opacity:0;transform:translateX(30%) scaleX(1.1)}}

/* =====================================================================
   PALCO DE BATALHA — inimigos em cima, grupo embaixo, cenário ao fundo
   ===================================================================== */
#battle-stage{position:relative;flex:1;min-height:340px;border:1px solid var(--line);
  border-radius:var(--r);overflow:hidden;display:flex;flex-direction:column;
  justify-content:space-between;padding:18px 16px;background:#06060b}
#bs-bg{position:absolute;inset:0;background-size:cover;background-position:center 38%;
  opacity:0;transition:opacity 1.2s;transform:scale(1.06)}
#bs-bg.on{opacity:.42}
#bs-bg::after{content:'';position:absolute;inset:0;
  background:linear-gradient(180deg,#06060bd9 0%,#06060b73 42%,#06060bf2 100%)}
#bs-fx{position:absolute;inset:0;pointer-events:none;z-index:5}
.bs-row{position:relative;z-index:2;display:flex;justify-content:center;align-items:flex-end;
  gap:clamp(10px,2vw,30px);flex-wrap:wrap}
#bs-enemies{align-items:flex-start}

/* ------------------------------ sprite ------------------------------ */
.sprite{position:relative;cursor:pointer;transition:transform .3s cubic-bezier(.3,1.3,.4,1),filter .3s;
  display:flex;flex-direction:column;align-items:center;width:var(--w)}
.sprite .body{position:relative;width:var(--w);height:var(--h);border-radius:10px;overflow:hidden;
  background:#0a0a12;border:1px solid var(--c);display:flex;align-items:center;
  justify-content:center;font-size:calc(var(--w)*.45);
  box-shadow:0 6px 26px -8px #000, 0 0 0 0 var(--c);transition:.25s}
.sprite .body img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.sprite .nm{margin-top:6px;font-size:11px;color:var(--txt2);text-align:center;max-width:var(--w);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sprite .hpbar{width:var(--w);height:6px;background:#05050a;border:1px solid var(--line);
  border-radius:3px;overflow:hidden;margin-top:3px}
.sprite .hpbar i{display:block;height:100%;background:linear-gradient(90deg,#7f1d1d,#ef4444);
  transition:width .5s cubic-bezier(.2,.9,.3,1)}
.sprite .stx{display:flex;gap:2px;margin-top:3px;min-height:14px;flex-wrap:wrap;justify-content:center}

.sprite.hero  { --w:clamp(66px,8vw,96px);  --h:calc(var(--w)*1.32) }
.sprite.foe   { --w:clamp(74px,9vw,110px); --h:calc(var(--w)*1.32) }
.sprite.boss  { --w:clamp(130px,17vw,210px); --h:calc(var(--w)*1.18) }

/* quem está agindo dá um passo à frente e brilha */
.sprite.acting{transform:translateY(-14px) scale(1.07);z-index:4}
.sprite.acting .body{box-shadow:0 10px 34px -8px #000, 0 0 0 2px var(--c), 0 0 34px -4px var(--c)}
.sprite.acting .nm{color:var(--c);font-weight:700}

/* alvo selecionável */
.sprite.targetable .body{outline:2px dashed var(--warn);outline-offset:3px;animation:pulse 1s infinite}
.sprite.targetable:hover{transform:translateY(-6px) scale(1.04)}

/* golpear: avança na direção do inimigo e volta */
.sprite.strike-up  {animation:strikeUp .5s cubic-bezier(.3,1.5,.4,1)}
.sprite.strike-down{animation:strikeDown .5s cubic-bezier(.3,1.5,.4,1)}
@keyframes strikeUp{0%{transform:translateY(0)}40%{transform:translateY(-42px) scale(1.1)}100%{transform:translateY(0)}}
@keyframes strikeDown{0%{transform:translateY(0)}40%{transform:translateY(42px) scale(1.1)}100%{transform:translateY(0)}}

/* apanhar: recua, treme e pisca */
.sprite.hurt{animation:spriteHurt .45s}
@keyframes spriteHurt{
  0%{transform:translateX(0)}
  15%{transform:translateX(-10px);filter:brightness(2.6) saturate(.2)}
  35%{transform:translateX(8px)}55%{transform:translateX(-5px);filter:none}
  75%{transform:translateX(3px)}100%{transform:translateX(0)}}

/* curar */
.sprite.blessed .body{animation:blessed .9s}
@keyframes blessed{0%,100%{box-shadow:0 6px 26px -8px #000}
  45%{box-shadow:0 0 0 3px #4ade8088, 0 0 42px -2px #4ade80}}

/* cair */
.sprite.down{filter:grayscale(1) brightness(.42);transform:translateY(8px) rotate(-6deg);opacity:.65}
.sprite.dying{animation:dying .7s forwards}
@keyframes dying{0%{filter:brightness(3)}100%{filter:grayscale(1) brightness(.42);transform:translateY(8px) rotate(-6deg);opacity:.65}}

.sprite .lv{position:absolute;top:3px;right:5px;font-size:9px;color:#fff9;
  text-shadow:0 1px 3px #000;z-index:2}

/* ------------------------- projétil de skill ------------------------ */
.bolt{position:absolute;width:26px;height:26px;border-radius:50%;pointer-events:none;
  background:radial-gradient(circle,#fff 8%,currentColor 45%,transparent 72%);
  filter:blur(1px) drop-shadow(0 0 12px currentColor);z-index:6}
.bolt.trail{width:60px;height:8px;border-radius:99px;
  background:linear-gradient(90deg,transparent,currentColor,#fff)}
.impact{position:absolute;width:110px;height:110px;margin:-55px 0 0 -55px;border-radius:50%;
  pointer-events:none;z-index:6;background:radial-gradient(circle,#fff 0%,currentColor 32%,transparent 68%);
  animation:impact .5s ease-out forwards}
@keyframes impact{0%{transform:scale(.2);opacity:1}100%{transform:scale(1.5);opacity:0}}

/* =====================================================================
   ESCOLHAS DA CENA — o que o grupo pode fazer agora
   ===================================================================== */
#choices{margin-top:26px;display:grid;gap:9px;max-width:78ch}
#choices:empty{display:none}
.choice{display:flex;align-items:flex-start;gap:12px;text-align:left;padding:14px 16px;
  background:linear-gradient(100deg,#12121ecc,#0c0c15cc);border:1px solid var(--line2);
  border-left:3px solid var(--rk);border-radius:10px;cursor:pointer;transition:.16s;
  font-size:15px;line-height:1.5;backdrop-filter:blur(3px)}
.choice:hover:not(:disabled){border-color:var(--rk);transform:translateX(4px);
  box-shadow:0 0 28px -10px var(--rk)}
.choice:disabled{opacity:.4;cursor:wait;transform:none}
.choice .n{flex:0 0 auto;width:24px;height:24px;border-radius:6px;background:#05050a;
  border:1px solid var(--rk);color:var(--rk);display:flex;align-items:center;
  justify-content:center;font-size:12px;font-weight:700;margin-top:1px}
.choice .t{flex:1}
.choice .t b{display:block;color:var(--txt);font-weight:600}
.choice .t i{display:block;color:var(--txt3);font-style:italic;font-size:12.5px;margin-top:3px}
.choice .choice-meta{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-top:8px}
.choice .choice-check,.choice .choice-scope{display:inline-flex;color:var(--txt2);font-style:normal;
  font-size:9.5px;letter-spacing:.11em;text-transform:uppercase;opacity:.88;border:1px solid #303044;
  border-radius:99px;padding:2px 7px;background:#080810aa}
.choice .choice-scope{color:#c7bce8;border-color:#594b7655}
.choice .r{flex:0 0 auto;font-size:9.5px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--rk);border:1px solid var(--rk);border-radius:99px;padding:2px 8px;margin-top:2px}

#choices .thinking{display:flex;align-items:center;gap:10px;color:var(--veil);
  font-size:14px;padding:14px 4px;font-style:italic}
#choices .thinking::before{content:'';width:14px;height:14px;border-radius:50%;
  border:2px solid var(--veil);border-top-color:transparent;animation:spin .8s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}

/* =====================================================================
   ROLAGEM DE DADO — só aparece quando a cena pede
   ===================================================================== */
#dice-overlay{position:fixed;inset:0;z-index:170;display:none;align-items:center;
  justify-content:center;background:#000d;backdrop-filter:blur(6px)}
#dice-overlay.show{display:flex;animation:fade .25s}
.dice-box{text-align:center;padding:24px}
.dice-who{font-family:var(--serif);font-size:clamp(15px,2.4vw,22px);color:var(--txt2);
  letter-spacing:.14em;margin-bottom:20px}
.dice-cube{width:clamp(130px,20vw,190px);height:clamp(130px,20vw,190px);margin:0 auto;
  display:flex;align-items:center;justify-content:center;font-family:var(--serif);
  font-size:clamp(56px,9vw,86px);font-weight:700;
  background:radial-gradient(circle at 50% 32%,#1e1e33,#0a0a12);
  border:3px solid var(--line2);border-radius:22px;color:var(--txt);
  text-shadow:0 0 34px currentColor;transition:.25s}
.dice-cube.rolling{animation:diceroll .1s infinite}
@keyframes diceroll{0%{transform:translate(-4px,3px) rotate(-4deg)}
  50%{transform:translate(4px,-3px) rotate(4deg)}100%{transform:translate(-2px,-1px) rotate(-2deg)}}
.dice-cube.win{color:var(--ok);border-color:var(--ok);box-shadow:0 0 70px -8px var(--ok)}
.dice-cube.lose{color:var(--bad);border-color:var(--bad);box-shadow:0 0 70px -8px var(--bad)}
.dice-cube.crit{color:var(--gold);border-color:var(--gold);box-shadow:0 0 90px -6px var(--gold)}
.dice-meta{margin-top:18px;color:var(--txt2);font-size:14px;letter-spacing:.05em}
.dice-verdict{margin-top:14px;font-family:var(--serif);font-size:clamp(20px,3.4vw,32px);
  letter-spacing:.2em;text-transform:uppercase;min-height:40px}

/* ---------- arte grande no códex / item ---------- */
.art-hero{width:100%;max-height:340px;object-fit:cover;border-radius:12px;
  border:1px solid var(--line2);margin-bottom:16px;background:#05050a}
.art-square{width:100%;aspect-ratio:1;object-fit:cover;border-radius:12px;
  border:1px solid var(--rc,var(--line2));background:#05050a;
  box-shadow:0 0 34px -12px var(--rc,var(--line2))}

/* carregamento suave: a imagem entra em fade quando chega */
img[data-fade]{opacity:0;transition:opacity .5s}
img[data-fade].ready{opacity:1}

/* nó do mapa com arte */
.node-art{opacity:.9}

.hidden{display:none!important}
.muted{color:var(--txt3)}
.tiny{font-size:11px}
.center{text-align:center}
kbd{background:#05050a;border:1px solid var(--line2);border-bottom-width:2px;border-radius:4px;
  padding:1px 6px;font-family:var(--mono);font-size:11px;color:var(--txt2)}

/* modo apresentação: esconde controles, texto gigante */
body.present main{grid-template-columns:250px minmax(0,1fr) 0}
body.present #col-right{display:none}
body.present #col-right{display:none}
body.present .col:last-child{display:none}
body.present #narrative .body{font-size:24px}

@media (max-width:1500px){ main{grid-template-columns:262px minmax(0,1fr) 300px} }
/* Estreitando: em vez de ESCONDER missões e registro, eles descem para uma
   faixa embaixo. Perde-se espaço, não informação. */
@media (max-width:1250px){
  main{ grid-template-columns:240px minmax(0,1fr);
        grid-template-rows:minmax(0,1fr) auto;
        grid-template-areas:"party stage" "party side"; }
  #col-right{ flex-direction:row; max-height:186px; }
  #col-right .panel{ flex:1 1 0; min-width:0; }
}

/* =====================================================================
   EFEITOS DE HABILIDADE (js/vfx.js)
   Cada elemento tem a sua linguagem visual. Tudo aqui vive dentro de
   #bs-fx, em coordenadas do palco, e some sozinho quando a animacao acaba.
   ===================================================================== */
#bs-fx > div, #bs-fx > svg { pointer-events: none; }
.vfx-svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }

/* --- fogo: chuva de brasas --- */
.vfx-brasa {
  position: absolute; border-radius: 50%; background: currentColor;
  box-shadow: 0 0 10px currentColor, 0 0 22px currentColor;
  animation: brasaCai 1.05s cubic-bezier(.35,0,.7,1) forwards; opacity: 0;
}
@keyframes brasaCai {
  0%   { transform: translate(0,0) scale(.5); opacity: 0; }
  14%  { opacity: 1; }
  78%  { opacity: 1; }
  100% { transform: translate(var(--dx), var(--dy)) scale(.25); opacity: 0; }
}
.vfx-chama {
  position: absolute; width: var(--lg); height: 26px;
  margin-left: calc(var(--lg) / -2); margin-top: -14px;
  border-radius: 50%; background: radial-gradient(ellipse at center, currentColor, transparent 70%);
  filter: blur(2px); animation: chamaPulsa .8s ease-out forwards;
}
@keyframes chamaPulsa {
  0%   { transform: scaleX(.3) scaleY(.4); opacity: 0; }
  30%  { transform: scaleX(1) scaleY(1); opacity: .95; }
  100% { transform: scaleX(1.3) scaleY(.6); opacity: 0; }
}
.vfx-faisca {
  position: absolute; width: 3px; height: 3px; border-radius: 50%;
  background: currentColor; box-shadow: 0 0 8px currentColor;
  animation: faiscaSobe .85s ease-out forwards; opacity: 0;
}
@keyframes faiscaSobe {
  0%   { transform: translate(0,0); opacity: 0; }
  20%  { opacity: 1; }
  100% { transform: translate(var(--dx), var(--dy)); opacity: 0; }
}

/* --- agua: onda que sobe --- */
.vfx-onda {
  position: absolute; width: var(--lg); height: var(--alt);
  margin-left: calc(var(--lg) / -2); margin-top: calc(var(--alt) * -1);
  border-radius: 46% 54% 38% 62% / 74% 68% 32% 26%;
  background: linear-gradient(to top, currentColor 0%, currentColor 32%, transparent 88%);
  opacity: 0; filter: blur(.5px);
  animation: ondaSobe .95s cubic-bezier(.18,.72,.28,1) forwards;
}
.vfx-onda-2 { opacity: 0; mix-blend-mode: screen; }
@keyframes ondaSobe {
  0%   { transform: translateY(28%) scaleY(.12) scaleX(.7); opacity: 0; }
  22%  { opacity: .9; }
  62%  { transform: translateY(-14%) scaleY(1.06) scaleX(1.05); opacity: .8; }
  100% { transform: translateY(-40%) scaleY(.85) scaleX(1.15); opacity: 0; }
}
.vfx-gota {
  position: absolute; width: 5px; height: 7px; border-radius: 50% 50% 55% 55%;
  background: currentColor; box-shadow: 0 0 9px currentColor;
  animation: gotaVoa .9s cubic-bezier(.25,.7,.4,1) forwards; opacity: 0;
}
@keyframes gotaVoa {
  0%   { transform: translate(0,0) scale(.6); opacity: 0; }
  18%  { opacity: 1; }
  100% { transform: translate(var(--dx), var(--dy)) scale(.3); opacity: 0; }
}
.vfx-vortice {
  position: absolute; width: var(--lg); height: calc(var(--lg) * .34);
  margin-left: calc(var(--lg) / -2); margin-top: calc(var(--lg) * -.17);
  border: 2.5px solid currentColor; border-radius: 50%;
  border-top-color: transparent; opacity: 0;
  animation: vorticeGira 1s cubic-bezier(.3,.7,.4,1) forwards;
}
@keyframes vorticeGira {
  0%   { transform: rotate(0deg) scale(1.3); opacity: 0; }
  25%  { opacity: .9; }
  100% { transform: rotate(560deg) scale(.2); opacity: 0; }
}

/* --- correntes (Blood Chain) --- */
.vfx-elo {
  position: absolute; width: 17px; height: 10px;
  border: 2.5px solid currentColor; border-radius: 50%;
  box-shadow: 0 0 8px currentColor, inset 0 0 4px currentColor;
  opacity: 0; animation: eloEntra 1s cubic-bezier(.2,1.5,.4,1) forwards;
}
@keyframes eloEntra {
  0%   { opacity: 0; transform: translate(-50%,-50%) rotate(var(--r,0deg)) scale(.2); }
  22%  { opacity: 1; }
  72%  { opacity: 1; }
  100% { opacity: 0; }
}
.vfx-argola {
  position: absolute; width: calc(var(--r) * 2); height: calc(var(--r) * 2);
  margin-left: calc(var(--r) * -1); margin-top: calc(var(--r) * -1);
  border: 4px solid currentColor; border-radius: 50%;
  border-left-color: transparent; border-right-color: transparent;
  box-shadow: 0 0 16px currentColor; opacity: 0;
  animation: argolaAperta .75s cubic-bezier(.3,.1,.2,1) forwards;
}
@keyframes argolaAperta {
  0%   { transform: scale(2.1) rotate(0deg); opacity: 0; }
  30%  { opacity: 1; }
  100% { transform: scale(.85) rotate(180deg); opacity: 0; }
}

/* --- sangue --- */
.vfx-respingo {
  position: absolute; border-radius: 50% 50% 60% 40%;
  background: currentColor; box-shadow: 0 0 8px currentColor;
  animation: respingoVoa 1s cubic-bezier(.2,.6,.35,1) forwards; opacity: 0;
}
@keyframes respingoVoa {
  0%   { transform: translate(-50%,-50%) scale(.3); opacity: 0; }
  12%  { opacity: 1; }
  100% { transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) scale(.4); opacity: 0; }
}
.vfx-corte {
  position: absolute; width: var(--lg); height: 4px; margin-left: 0;
  background: linear-gradient(90deg, transparent, currentColor 22%, #fff 50%, currentColor 78%, transparent);
  box-shadow: 0 0 18px currentColor; border-radius: 3px; opacity: 0;
  animation: corteRasga .45s ease-out forwards;
}
@keyframes corteRasga {
  0%   { opacity: 0; clip-path: inset(0 100% 0 0); }
  25%  { opacity: 1; }
  55%  { clip-path: inset(0 0 0 0); opacity: 1; }
  100% { clip-path: inset(0 0 0 0); opacity: 0; }
}

/* --- trevas: garras subindo --- */
.vfx-garra {
  position: absolute; width: 10px; height: var(--h); margin-left: -5px;
  border-radius: 50% 50% 18% 18% / 62% 62% 8% 8%;
  background: linear-gradient(to top, currentColor 8%, transparent 96%);
  transform-origin: bottom center; opacity: 0; filter: blur(.4px);
  animation: garraSobe 1s cubic-bezier(.2,.85,.3,1) forwards;
}
@keyframes garraSobe {
  0%   { transform: translate(-50%,0) scaleY(0) rotate(0deg); opacity: 0; }
  20%  { opacity: .95; }
  55%  { transform: translate(-50%,0) scaleY(1.06) rotate(var(--tw)); opacity: .95; }
  100% { transform: translate(-50%,0) scaleY(.85) rotate(calc(var(--tw) * -.6)); opacity: 0; }
}
.vfx-mancha {
  position: absolute; width: var(--lg); height: calc(var(--lg) * .3);
  margin-left: calc(var(--lg) / -2); margin-top: calc(var(--lg) * -.15);
  border-radius: 50%; background: radial-gradient(ellipse at center, currentColor, transparent 72%);
  opacity: 0; filter: blur(3px); animation: manchaAbre 1s ease-out forwards;
}
@keyframes manchaAbre {
  0% { transform: scale(.2); opacity: 0; } 35% { opacity: .8; }
  100% { transform: scale(1.15); opacity: 0; }
}

/* --- veu: fenda --- */
.vfx-fenda {
  position: absolute; width: 16px; height: var(--h);
  margin-left: -8px; margin-top: calc(var(--h) / -2);
  border-radius: 50%; background: linear-gradient(to bottom, transparent, currentColor 22%, #fff 50%, currentColor 78%, transparent);
  box-shadow: 0 0 26px currentColor; opacity: 0;
  animation: fendaAbre .85s cubic-bezier(.3,.2,.2,1) forwards;
}
@keyframes fendaAbre {
  0%   { transform: scaleY(.05) scaleX(.4); opacity: 0; }
  25%  { transform: scaleY(1) scaleX(1); opacity: 1; }
  70%  { transform: scaleY(1) scaleX(2.4); opacity: .9; }
  100% { transform: scaleY(.06) scaleX(.2); opacity: 0; }
}
.vfx-cinza {
  position: absolute; width: 4px; height: 4px; border-radius: 50%;
  background: currentColor; box-shadow: 0 0 9px currentColor; opacity: 0;
  animation: cinzaSuga .8s cubic-bezier(.4,0,.6,1) forwards;
}
@keyframes cinzaSuga {
  0% { transform: translate(-50%,-50%) scale(1); opacity: 0; }
  20% { opacity: 1; }
  100% { transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) scale(.1); opacity: 0; }
}
.vfx-anel {
  position: absolute; width: calc(var(--r,40px) * 2); height: calc(var(--r,40px) * 2);
  margin-left: calc(var(--r,40px) * -1); margin-top: calc(var(--r,40px) * -1);
  border: 3px solid currentColor; border-radius: 50%;
  box-shadow: 0 0 20px currentColor; opacity: 0;
  animation: anelExplode .65s cubic-bezier(.15,.8,.3,1) forwards;
}
@keyframes anelExplode {
  0% { transform: scale(.15); opacity: 1; }
  100% { transform: scale(1.9); opacity: 0; }
}

/* --- raio --- */
.vfx-raio-nucleo { fill: none; stroke: #fff; stroke-width: 3.5; stroke-linecap: round;
  stroke-linejoin: round; animation: raioPisca .6s steps(1) forwards; }
.vfx-raio-halo   { fill: none; stroke: currentColor; stroke-width: 13; stroke-linecap: round;
  stroke-linejoin: round; opacity: .5; filter: blur(4px); animation: raioPisca .6s steps(1) forwards; }
@keyframes raioPisca {
  0%,14%  { opacity: 1; } 18%,26% { opacity: .15; }
  30%,52% { opacity: 1; } 56%,64% { opacity: .3; }
  68%,84% { opacity: .8; } 100%   { opacity: 0; }
}

/* --- lanca / meteoro --- */
.vfx-lanca {
  position: absolute; width: var(--lg); height: 7px; border-radius: 4px;
  background: linear-gradient(90deg, transparent, currentColor 35%, #fff 92%, #fff);
  box-shadow: 0 0 18px currentColor; opacity: 0;
  animation: lancaAvanca .42s cubic-bezier(.6,0,.9,.6) forwards;
}
@keyframes lancaAvanca {
  0%   { opacity: 0; }
  15%  { opacity: 1; }
  100% { transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) rotate(var(--ang)); opacity: .6; }
}
.vfx-meteoro {
  position: absolute; width: 24px; height: 24px; margin: -12px 0 0 -12px;
  border-radius: 50%; background: radial-gradient(circle at 35% 35%, #fff, currentColor 60%, transparent);
  box-shadow: 0 0 30px currentColor, -26px -26px 40px -6px currentColor;
  animation: meteoroCai .5s cubic-bezier(.7,0,.9,.5) forwards;
}
@keyframes meteoroCai {
  0%   { transform: translate(0,0) scale(.7); opacity: .3; }
  20%  { opacity: 1; }
  100% { transform: translate(var(--dx), var(--dy)) scale(1.25); opacity: 1; }
}

/* --- escudo / cura / dreno / selo --- */
.vfx-escudo {
  position: absolute; width: calc(var(--r) * 2); height: calc(var(--r) * 2);
  margin-left: calc(var(--r) * -1); margin-top: calc(var(--r) * -1);
  border: 2.5px solid currentColor;
  clip-path: polygon(50% 0%, 93% 25%, 93% 75%, 50% 100%, 7% 75%, 7% 25%);
  background: radial-gradient(circle, transparent 55%, currentColor 100%);
  opacity: 0; animation: escudoErgue 1.2s cubic-bezier(.2,.9,.3,1) forwards;
}
@keyframes escudoErgue {
  0%   { transform: scale(.4) rotate(-20deg); opacity: 0; }
  25%  { transform: scale(1.08) rotate(0deg); opacity: .95; }
  70%  { transform: scale(1) rotate(0deg); opacity: .7; }
  100% { transform: scale(1.05) rotate(12deg); opacity: 0; }
}
.vfx-luz {
  position: absolute; border-radius: 50%; background: currentColor;
  box-shadow: 0 0 12px currentColor; opacity: 0;
  animation: luzSobe 1.2s ease-out forwards;
}
@keyframes luzSobe {
  0%   { transform: translate(0,0) scale(.4); opacity: 0; }
  22%  { opacity: 1; }
  100% { transform: translate(var(--dx), var(--dy)) scale(.9); opacity: 0; }
}
.vfx-halo {
  position: absolute; width: calc(var(--r) * 2); height: calc(var(--r) * 2);
  margin-left: calc(var(--r) * -1); margin-top: calc(var(--r) * -1);
  border-radius: 50%; background: radial-gradient(circle, currentColor 0%, transparent 68%);
  opacity: 0; animation: haloPulsa 1s ease-out forwards;
}
@keyframes haloPulsa {
  0% { transform: scale(.3); opacity: 0; } 35% { opacity: .55; }
  100% { transform: scale(1.25); opacity: 0; }
}
.vfx-fio {
  position: absolute; width: 5px; height: 5px; border-radius: 50%;
  background: currentColor; box-shadow: 0 0 12px currentColor; opacity: 0;
  animation: fioPuxa .95s cubic-bezier(.35,.05,.4,1) forwards;
}
@keyframes fioPuxa {
  0% { transform: translate(0,0) scale(.5); opacity: 0; }
  18% { opacity: 1; }
  100% { transform: translate(var(--dx), var(--dy)) scale(1.1); opacity: 0; }
}
.vfx-selo {
  position: absolute; width: calc(var(--r) * 2); height: calc(var(--r) * 2);
  margin-left: calc(var(--r) * -1); margin-top: calc(var(--r) * -1);
  border: 3px double currentColor; border-radius: 50%;
  box-shadow: 0 0 18px currentColor, inset 0 0 14px currentColor;
  opacity: 0; animation: seloGira 1.3s cubic-bezier(.2,.8,.3,1) forwards;
}
.vfx-selo::before {
  content: ''; position: absolute; inset: 18%;
  border: 2px solid currentColor; border-radius: 50%;
  border-style: dashed;
}
.vfx-selo-2 { animation-direction: reverse; }
@keyframes seloGira {
  0%   { transform: scale(.3) rotate(0deg); opacity: 0; }
  25%  { transform: scale(1) rotate(90deg); opacity: 1; }
  75%  { opacity: .85; }
  100% { transform: scale(1.15) rotate(320deg); opacity: 0; }
}

/* --- de quem e a vez --- */
.vfx-vez {
  position: absolute; left: 50%; top: 8px; transform: translateX(-50%);
  font-family: var(--ff-title, inherit); font-size: 15px; letter-spacing: .16em;
  text-transform: uppercase; text-shadow: 0 0 14px currentColor, 0 2px 6px #000;
  white-space: nowrap; opacity: 0; animation: vezEntra 1.05s ease-out forwards;
}
@keyframes vezEntra {
  0%   { opacity: 0; transform: translateX(-50%) translateY(-10px); }
  18%  { opacity: 1; transform: translateX(-50%) translateY(0); }
  72%  { opacity: 1; }
  100% { opacity: 0; transform: translateX(-50%) translateY(-6px); }
}

/* --- carga antes do golpe, e trava de acoes --- */
.sprite.carregando .body {
  animation: cargaBrilha .62s ease-in;
  filter: drop-shadow(0 0 12px var(--carga, #fff));
}
@keyframes cargaBrilha {
  0%   { filter: drop-shadow(0 0 0 var(--carga, #fff)); }
  70%  { filter: drop-shadow(0 0 22px var(--carga, #fff)) brightness(1.3); }
  100% { filter: drop-shadow(0 0 6px var(--carga, #fff)); }
}
#actions.travado { opacity: .45; pointer-events: none; filter: saturate(.5); }
#actions { transition: opacity .18s ease, filter .18s ease; }

/* =====================================================================
   LAYOUT QUE CABE NA JANELA
   A coluna do meio agora pode encolher (minmax(0,1fr)); estas regras
   garantem que os filhos dela tambem encolham, em vez de empurrar a
   grade para fora da tela.
   ===================================================================== */
#stage, #combat, #narrative, #map-wrap, #battle-stage, #actions, #log-panel { min-width: 0; }
#actions .act-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
#battle-stage { max-width: 100%; }
.bs-row { flex-wrap: wrap; }

/* Barras extras do sprite: MP e o recurso da classe, para nao ter que
   procurar o card na lateral no meio da luta. */
.sprite .hpbar.mp   { margin-top: 2px; }
.sprite .hpbar.mp i { background: linear-gradient(90deg, #1d4ed8, #38bdf8); }
.sprite .hpbar.res  { margin-top: 2px; }
.sprite .hpbar.res i{ background: linear-gradient(90deg, color-mix(in srgb, var(--rc) 55%, #000), var(--rc)); }
.sprite .res-txt {
  font-size: 9.5px; letter-spacing: .04em; color: var(--txt3);
  text-align: center; margin-top: 2px; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
}

/* Telas estreitas: o grupo vira uma faixa horizontal em cima do palco,
   para os cards nunca ficarem escondidos embaixo do registro. */
@media (max-width: 1000px) {
  main { grid-template-columns: minmax(0, 1fr);
         grid-template-rows: auto minmax(0, 1fr) auto;
         grid-template-areas: "party" "stage" "side"; }
  /* o grupo vira uma faixa: os dois paineis dividem a largura e cada um
     rola por dentro, para nada empurrar a pagina para fora da janela */
  #col-party { flex-direction: row; overflow: hidden; max-height: 196px; gap: 10px; }
  #col-party .panel { flex: 1 1 0; min-width: 0; }
  #col-party .panel-b { max-height: 152px; overflow-x: auto; overflow-y: hidden; }
  #party-list { display: flex; gap: 8px; }
  #party-list .hero { flex: 0 0 206px; }
  #inv-list { max-height: 152px !important; overflow-y: auto; }
  #log-panel { max-height: 148px !important; }
  #log { max-height: 106px !important; }
}
/* ultima linha de defesa: nada justifica a pagina inteira rolar de lado */
html, body { overflow-x: hidden; }

/* ===================== DIFICULDADE (tela de criacao) ================= */
.dif-box { margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--line); }
.dif-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(168px, 1fr)); gap: 9px; }
.dif {
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 12px 10px; text-align: center; border: 2px solid var(--line);
  border-radius: 10px; background: #0c0c15; cursor: pointer; transition: .16s;
}
.dif:hover { border-color: var(--line2); transform: translateY(-2px); }
.dif .ic { font-size: 26px; line-height: 1; }
.dif b { font-family: var(--serif); font-size: 14px; letter-spacing: .06em; }
.dif i { font-size: 10.5px; color: var(--txt3); font-style: normal; line-height: 1.4; }
.dif[data-sel] { border-color: var(--gold); background: #171204;
  box-shadow: 0 0 0 1px var(--gold), 0 0 26px -8px var(--gold); }
.dif[data-sel] b { color: var(--gold); }

/* inimigo de elite: o titulo dourado avisa que aquele ali e outro problema */
.sprite .nm { transition: color .2s; }
.enemy.elite, .sprite.elite .nm { color: #fbbf24; }

/* ===================== VOTACAO DAS ESCOLHAS ========================= */
.voto-barra {
  font-size: 11.5px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--txt3); padding: 6px 2px 10px; border-bottom: 1px dashed var(--line);
  margin-bottom: 9px;
}
.voto-barra b { color: var(--gold); }
.voto-barra.fechada b { color: var(--ok); }
.choice .votos {
  font-size: 12px; color: var(--gold); white-space: nowrap;
  margin-left: auto; padding-left: 10px; font-variant-numeric: tabular-nums;
}
.choice.meu { border-color: var(--veil); box-shadow: inset 3px 0 0 var(--veil); }
.choice.venceu { border-color: var(--ok); background: #06170e; }
.choice.perdeu { opacity: .4; }
.choice.pronto { border-color: var(--gold); background: linear-gradient(90deg, #17120433, transparent); }
.choice.pronto:hover { background: linear-gradient(90deg, #1f180644, transparent); }


/* =====================================================================
   O CENTRO E SO A BATALHA
   Registro e missoes vivem na coluna da direita. O palco e as habilidades
   ficam sozinhos no meio, sem nada por cima de nada.
   ===================================================================== */
#col-party { grid-area: party; }
#stage     { grid-area: stage; }
#col-right { grid-area: side; }

#stage  { overflow: hidden; }
#combat { display: flex; flex-direction: column; min-height: 0; gap: 10px; flex: 1; }
#battle-stage { flex: 1 1 auto; min-height: 220px; }
#actions { flex: 0 0 auto; max-height: 40%; overflow-y: auto; }

/* missoes e registro dividem a altura da coluna, cada um rolando por dentro */
#col-right { gap: 12px; overflow: hidden; }
#col-right .panel.grow { flex: 1 1 0; min-height: 120px; }
#col-right .panel-b { overflow-y: auto; min-height: 0; }
#log { font-size: 12px; }

/* =====================================================================
   SPRITES ANIMADOS (js/sprites.js)
   ===================================================================== */
.spr {
  image-rendering: pixelated; image-rendering: crisp-edges;
  background-repeat: no-repeat; pointer-events: none;
  filter: drop-shadow(0 3px 5px rgba(0,0,0,.55));
}
.spr.espelhado { transform: scaleX(-1); }
/* Quando o boneco entra, a caixa do retrato deixa de ser uma moldura de
   tamanho fixo: ela vira apenas um encaixe. Sem isto o sprite era
   ESMAGADO (flex encolhe) e CORTADO (overflow hidden) -- ficava um risco
   de 25px de largura no lugar do heroi. */
.body.com-sprite > img { display: none; }        /* o boneco substitui a pintura */
.body.com-sprite {
  width: auto; height: auto; min-width: var(--w);
  overflow: visible; background: none; border-color: transparent;
  box-shadow: none; border-radius: 0;
  display: flex; align-items: flex-end; justify-content: center;
}
.body.com-sprite > .spr { flex: 0 0 auto; }      /* nunca encolher o boneco */
/* o realce de quem age e de quem pode ser alvo passa para o proprio boneco */
.sprite.acting .body.com-sprite { box-shadow: none; }
.sprite.acting .body.com-sprite > .spr {
  filter: drop-shadow(0 4px 6px rgba(0,0,0,.6)) drop-shadow(0 0 10px var(--c));
}
.sprite.targetable .body.com-sprite { outline: none; }
.sprite.targetable .body.com-sprite > .spr {
  filter: drop-shadow(0 3px 5px rgba(0,0,0,.55)) drop-shadow(0 0 8px var(--warn));
}
/* ---- o grupo caminhando no mapa ---- */
.map-andarilho { overflow: hidden; image-rendering: pixelated; }
.map-andarilho image { image-rendering: pixelated; }
#party-token .walker { filter: drop-shadow(0 3px 4px rgba(0,0,0,.7)); }

/* ---------------------------------------------------------------------
   SPRITE COM BONECO
   O contentor tinha largura fixa (var(--w), ~71px) enquanto o boneco tem
   116px: ele vazava para fora e a fila saia torta. Com boneco, quem manda
   na largura e o boneco; a barra e o nome continuam no tamanho antigo.
   --------------------------------------------------------------------- */
.sprite.tem-boneco { width: auto; }
.sprite.tem-boneco .body {
  width: auto; height: auto; min-width: 0;
  background: none; border-color: transparent; box-shadow: none;
  border-radius: 0; overflow: visible; font-size: 0;
  display: flex; align-items: flex-end; justify-content: center;
}
.sprite.tem-boneco .body > .spr { flex: 0 0 auto; }
.sprite.tem-boneco .nm,
.sprite.tem-boneco .hpbar { width: var(--w); max-width: var(--w); }
.sprite.tem-boneco .lv {
  font-size: 9px; background: #0a0a12cc; border-radius: 4px;
  padding: 0 3px; z-index: 2;
}
/* o realce mora no proprio boneco, ja que nao ha mais moldura */
.sprite.tem-boneco.acting .body { box-shadow: none; }
.sprite.tem-boneco.acting .spr {
  filter: drop-shadow(0 4px 6px rgba(0,0,0,.6)) drop-shadow(0 0 10px var(--c));
}
.sprite.tem-boneco.targetable .body { outline: none; }
.sprite.tem-boneco.targetable .spr {
  filter: drop-shadow(0 3px 5px rgba(0,0,0,.55)) drop-shadow(0 0 9px var(--warn));
}

/* Todos os pes na mesma linha. Sem isto, quem tem menos barras embaixo
   (o dragao nao tem recurso de classe) flutua alguns pixels acima ou
   abaixo dos outros, e a fila parece desalinhada. */
#bs-party   .sprite.tem-boneco .body { min-height: 130px; }
#bs-enemies .sprite.tem-boneco .body { min-height: 156px; }
.bs-row { align-items: flex-start; }

/* =====================================================================
   PALCO NO ESTILO DA REFERENCIA
   Sem molduras: criaturas sobre o cenario. O inimigo leva nome e vida
   acima da cabeca; o heroi, abaixo dos pes. Foi assim que o jogo que a
   mesa citou resolveu, e resolve bem -- a leitura fica na criatura, nao
   numa ficha flutuando.
   ===================================================================== */
#bs-enemies .sprite { flex-direction: column; justify-content: flex-end; }
#bs-enemies .sprite .nm {
  margin: 0 0 3px; font-size: 12px; font-weight: 600; color: #e6e2f0;
  text-shadow: 0 1px 3px #000, 0 0 8px #000; letter-spacing: .02em;
}
#bs-enemies .sprite .hpbar { margin: 0 0 5px; height: 7px; }
#bs-enemies .sprite .stx { margin: 0 0 4px; }

#bs-party .sprite .nm { margin-top: 5px; font-weight: 600; color: #e6e2f0;
  text-shadow: 0 1px 3px #000; }

/* o nivel vira uma pastilha discreta, nao um selo na moldura */
.sprite.tem-boneco .lv {
  position: absolute; top: auto; bottom: 2px; right: 2px;
  background: #05050acc; border: 1px solid var(--line2); color: var(--txt2);
}

/* profundidade: o palco escurece nas bordas e o chao ganha peso */
#battle-stage::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(ellipse at 50% 45%, transparent 40%, #05050acc 100%);
  z-index: 1;
}
#bs-enemies, #bs-party { position: relative; z-index: 2; }
#bs-fx { z-index: 3; }

/* sombra sob os pes, para o boneco nao parecer colado no fundo */
.sprite.tem-boneco .body::after {
  content: ''; position: absolute; left: 50%; bottom: 2px;
  width: 54%; height: 9px; transform: translateX(-50%);
  background: radial-gradient(ellipse, rgba(0,0,0,.55), transparent 70%);
  pointer-events: none;
}

/* Leitura tática: a intenção é texto + ícone, não uma cor ambígua. */
.enemy-intent{display:flex;align-items:center;justify-content:center;gap:3px;max-width:var(--w);margin-top:4px;padding:3px 5px;border:1px solid rgba(244,194,73,.52);border-radius:4px;background:#0a0911e8;color:#f7d982;font-size:9px;line-height:1.1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.enemy-intent b{font-weight:700}.enemy-intent i{font-style:normal;color:#d2c3a6;overflow:hidden;text-overflow:ellipsis}
/* `min-width` com PISO, nao zero. Com zero o objetivo era a unica coisa
   encolhivel da barra e absorvia toda a pressao dos chips: espremia ate
   ~20px e sumia na pratica. A barra rola na horizontal -- e ela que deve
   ceder quando falta espaco, nao o texto que diz o que a mesa tem de fazer. */
.combat-objective{display:flex;align-items:baseline;gap:7px;min-width:150px;margin:0 8px;padding:5px 9px;border-left:2px solid var(--gold);background:#12110ce8;color:#e8dcc4;font-size:10px;letter-spacing:.04em}
/* o titulo tambem corta: `nowrap` sozinho transborda em vez de truncar */
.combat-objective b{font-family:Georgia,serif;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.combat-objective i{font-style:normal;color:var(--txt3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
@media(max-width:760px){.combat-objective i{display:none}.combat-objective{margin-left:4px}.enemy-intent{font-size:8px}}

/* o boneco tambem entra nos cards quando o modo e "pixel" */
.face-boneco { display: flex; align-items: flex-end; justify-content: center;
  background: none !important; overflow: visible !important; }
.face-boneco > .spr { flex: 0 0 auto; }

/* ---- fundo ilustrado do mapa ---- */
#map-wrap { position: relative; background-size: 100% 100%; background-position: center;
  border-radius: var(--r); overflow: hidden; transition: background-image .4s; }
#map-wrap.com-arte::before {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(ellipse at 50% 50%, rgba(5,5,10,.03) 30%, rgba(5,5,10,.52) 100%);
}
#map-wrap.com-arte #map { position: relative; z-index: 1; }
/* com ilustracao atras, os nos precisam de contorno para nao sumirem */
#map-wrap.com-arte .node-lbl, #map-wrap.com-arte .node-sub {
  paint-order: stroke; stroke: #05050a; stroke-width: 3px; stroke-linejoin: round;
}
#map-wrap.com-arte .map-path { stroke: #e7c984; stroke-width: 3.4px; stroke-opacity: .7;
  stroke-dasharray: 2 8; filter: drop-shadow(0 1px 1px #160d08); }
#map-wrap.com-arte .node-ring { filter: drop-shadow(0 2px 2px #000); }
#map-wrap.com-arte .node:hover .node-ring { stroke-width: 4px; filter: drop-shadow(0 0 10px currentColor); }

/* =====================================================================
   O PALCO, COMO NA REFERENCIA
   O palco vinha espremido em 220px enquanto as duas fileiras somavam 454
   -- por isso o grupo transbordava por cima dos inimigos. Agora ele tem
   altura de verdade, os inimigos ficam na faixa de cima, o grupo na de
   baixo, e sobra ceu no meio.
   ===================================================================== */
#battle-stage {
  min-height: 440px;
  display: flex; flex-direction: column; justify-content: space-between;
  padding: 18px 16px 22px; gap: 0;
}
#bs-enemies, #bs-party { flex: 0 0 auto; display: flex; justify-content: center; }
#bs-enemies { gap: clamp(14px, 3vw, 44px); align-items: flex-end; }
#bs-party   { gap: clamp(10px, 2.2vw, 30px); align-items: flex-end; }

/* o palco manda; as habilidades ficam com o que sobrar */
#actions { max-height: 34%; }

/* o nivel nao precisa aparecer no palco: ele ja esta no card lateral,
   e no palco so polui a criatura */
#battle-stage .sprite .lv { display: none; }

/* bonecos maiores, como no jogo que a mesa citou de referencia */
.sprite.hero  { --w: clamp(74px, 9vw, 104px); }
.sprite.foe   { --w: clamp(78px, 9.5vw, 116px); }
.sprite.boss  { --w: clamp(140px, 18vw, 224px); }

/* barra de vida mais legivel sobre o cenario */
#bs-enemies .sprite .hpbar,
#bs-party   .sprite .hpbar { height: 8px; border-color: #000a; }
#battle-stage .sprite .hpbar { box-shadow: 0 1px 4px #000c; }

/* A fileira NAO pode quebrar linha: com wrap, o quinto heroi descia para
   uma segunda fila e empurrava tudo para fora do palco. Fila unica, e o
   que nao couber rola de lado. */
#bs-enemies, #bs-party { flex-wrap: nowrap; overflow-x: auto; overflow-y: visible; }
#bs-enemies::-webkit-scrollbar, #bs-party::-webkit-scrollbar { height: 5px; }
#bs-enemies::-webkit-scrollbar-thumb, #bs-party::-webkit-scrollbar-thumb {
  background: var(--line); border-radius: 3px;
}
#bs-enemies .sprite, #bs-party .sprite { flex: 0 0 auto; }
#bs-enemies { gap: clamp(10px, 2vw, 30px); }
#bs-party   { gap: clamp(8px, 1.6vw, 22px); }

/* As alturas minimas que eu tinha posto para alinhar os pes agora sobram:
   os bonecos mudaram de tamanho e elas so inflavam a fileira. O alinhamento
   passa a vir do proprio flex-end. */
#bs-party   .sprite.tem-boneco .body,
#bs-enemies .sprite.tem-boneco .body { min-height: 0; }
#battle-stage { min-height: 430px; }
#bs-enemies .sprite .stx { min-height: 0; }

.sprite .hpbar.res.vazia { visibility: hidden; }
#battle-stage { min-height: 470px; }

/* Tabuleiro do mundo: titulo e legenda pertencem ao mapa, nao ao HUD. */
.map-cartouche rect, .map-legend rect { fill: #100f11e8; stroke: #8c7650; stroke-width: 2; }
.map-cartouche rect { filter: drop-shadow(0 2px 2px #000); }
.map-title { fill: #e8cf9f; font-family: Georgia, serif; font-size: 20px; font-weight: 700; letter-spacing: 1.4px; }
.map-kicker { fill: #cec4b1; font-family: Georgia, serif; font-size: 9px; letter-spacing: 1.4px; }
.map-legend-label { fill: #e6dfd1; font-size: 8.5px; font-family: Georgia, serif; }
.map-ecos rect { fill:#100f11e8; stroke:#645779; stroke-width:1.5px; }
.map-eco-title { fill:#cdb8ed; font-family:Georgia,serif; font-size:9px; font-weight:700; letter-spacing:1.3px; }
.map-eco-text { fill:#e6dfd1; font-family:Georgia,serif; font-size:8px; }
.world-ledger { margin-top:16px; border:1px solid #6d5c9355; border-left:3px solid var(--veil); border-radius:9px; padding:14px; background:#0a0a12; }
.world-ledger-title { font-family:var(--serif); color:#cdb8ed; letter-spacing:.12em; font-size:13px; text-transform:uppercase; margin-bottom:8px; }
.world-ledger-row { display:grid; grid-template-columns:minmax(95px, .34fr) 1fr; gap:9px; padding:8px 0; border-top:1px solid var(--line); font-size:12px; line-height:1.45; }
.world-ledger-row b { color:var(--gold); } .world-ledger-row span { color:var(--txt2); }
@media (prefers-reduced-motion: reduce){.node-eco{animation:none}}
/* Efeitos adicionais: vento, vapor e noite. Todos usam apenas transform/opacity. */
.vfx-vento { position:absolute; width:var(--lg); height:3px; border-radius:999px;
  background:linear-gradient(90deg,transparent,currentColor 22%,#fff 50%,currentColor 78%,transparent);
  box-shadow:0 0 12px currentColor; opacity:0; animation:ventoCorta .62s ease-out forwards; }
@keyframes ventoCorta { 0%{transform:translate(-50%,-50%) scaleX(.15);opacity:0} 18%{opacity:.9} 100%{transform:translate(calc(-50% + var(--dx)),calc(-50% + var(--dy))) scaleX(1.4);opacity:0} }
.vfx-vapor { position:absolute; width:calc(var(--r) * 2); height:calc(var(--r) * 1.3); margin-left:calc(var(--r) * -1); margin-top:calc(var(--r) * -.65);
  border-radius:50%; background:radial-gradient(ellipse,rgba(240,252,255,.86),color-mix(in srgb,currentColor 55%,transparent) 42%,transparent 72%); filter:blur(4px); opacity:0; animation:vaporSobe 1.2s ease-out forwards; }
@keyframes vaporSobe { 0%{transform:translate(0,0) scale(.3);opacity:0} 22%{opacity:.82} 100%{transform:translate(var(--dx),var(--dy)) scale(1.65);opacity:0} }
.vfx-noite { position:absolute; width:calc(var(--r) * 2); height:calc(var(--r) * 2); margin-left:calc(var(--r) * -1); margin-top:calc(var(--r) * -1); border-radius:50%;
  background:radial-gradient(circle,currentColor 0%,rgba(6,3,16,.82) 48%,transparent 75%); mix-blend-mode:multiply; opacity:0; animation:noiteFecha 1.45s ease-in-out forwards; }
@keyframes noiteFecha { 0%{transform:scale(.15);opacity:0} 30%{opacity:.9} 72%{transform:scale(1.25);opacity:.78} 100%{transform:scale(1.38);opacity:0} }
@media (prefers-reduced-motion: reduce){ .vfx-vento,.vfx-vapor,.vfx-noite{animation-duration:.01ms!important} }
/* =====================================================================
   PALCO CINEMATOGRAFICO V2
   A composicao e a mesma dos RPGs de console: ceu/ruina no fundo,
   inimigos no plano alto, herois no primeiro plano e HUD fora da cena.
   ===================================================================== */
#battle-stage {
  min-height: min(54vh, 590px); border-radius: 4px;
  border: 1px solid #25243a; background: radial-gradient(ellipse at 50% 30%, #1a2235 0%, #080a12 68%);
  box-shadow: inset 0 0 80px #000d, 0 12px 42px #0008; isolation: isolate;
}
/* Com horizonte BAIXO na pintura, ancorar pelo topo mostra o ceu e a
   silhueta distante -- que e o que o cenario tem de bom -- em vez de
   centralizar num miolo que o chao vai cobrir de qualquer jeito. */
#bs-bg { background-position: center 12%; transform: scale(1.05); }
#bs-bg.on { opacity: .95; }
#bs-bg::after { background: linear-gradient(180deg, #070912cc 0%, #080b1366 37%, #05060be6 100%); }
#battle-stage::before {
  content: ''; position: absolute; z-index: 1; pointer-events: none; left: 7%; right: 7%; bottom: 5%; height: 48%;
  background: radial-gradient(ellipse at 50% 80%, rgba(5,6,10,.1) 0 22%, rgba(2,3,7,.72) 72%, transparent 74%);
  border-bottom: 1px solid rgba(180,208,255,.12);
}
#bs-enemies, #bs-party { width: 100%; overflow: hidden; scrollbar-width: none; }
#bs-enemies::-webkit-scrollbar, #bs-party::-webkit-scrollbar { display: none; }
#bs-enemies { min-height: 183px; padding-top: 10px; align-items: flex-end; }
#bs-party { min-height: 176px; padding-bottom: 2px; align-items: flex-end; }
#bs-enemies .sprite .nm { font-size: 12px; text-transform: uppercase; letter-spacing: .06em; }
#bs-party .sprite .nm { font-size: 11px; letter-spacing: .03em; }
#bs-enemies .sprite .hpbar, #bs-party .sprite .hpbar { background: #04050bdf; }
#bs-enemies .sprite.tem-boneco .body::after, #bs-party .sprite.tem-boneco .body::after { bottom: -1px; opacity: .95; }
.sprite.hero { --w: clamp(62px, 7.6vw, 106px); }
.sprite.foe { --w: clamp(66px, 8vw, 118px); }
.sprite.boss { --w: clamp(150px, 18vw, 230px); }
#battle-stage .sprite { transition: transform .22s cubic-bezier(.22,1,.36,1), filter .22s; }
#battle-stage .sprite:hover { transform: translateY(-5px) scale(1.035); }
@media (max-width: 760px) {
  #battle-stage { min-height: 460px; }
  #bs-enemies, #bs-party { overflow-x: auto; justify-content: flex-start; padding-left: 8px; padding-right: 8px; }
  #bs-enemies { min-height: 175px; } #bs-party { min-height: 160px; }
}
/* =====================================================================
   COREOGRAFIA CINEMATICA
   Cada acao tem foco, antecipacao, impacto e recuperacao. Transformacoes
   ficam no palco; o HUD nao treme nem desloca a leitura dos jogadores.
   ===================================================================== */
#battle-stage { --cam-x: 0px; --cam-y: 0px; --cine-cor: #fff; }
#battle-stage #bs-bg { transition: transform .48s cubic-bezier(.16,.9,.24,1), opacity .35s ease; }
#battle-stage .bs-row { transition: transform .38s cubic-bezier(.16,.9,.24,1), filter .28s ease; }
#battle-stage.cinema #bs-bg { transform: scale(1.13) translate(var(--cam-x), var(--cam-y)); opacity: .78; }
#battle-stage.cinema .bs-row { transform: translate(var(--cam-x), var(--cam-y)) scale(1.018); }
#battle-stage.cinema::after { background: radial-gradient(ellipse at 50% 48%, transparent 24%, rgba(2,3,9,.78) 88%); }
#battle-stage.cinema-ult #bs-bg { transform: scale(1.19) translate(var(--cam-x), var(--cam-y)); filter: saturate(1.38) contrast(1.12); }
#battle-stage.cinema-ult::before { box-shadow: inset 0 0 90px 18px color-mix(in srgb, var(--cine-cor) 28%, transparent); }
.sprite.cinema-caster { z-index: 8; filter: drop-shadow(0 0 15px var(--cine-cor)) brightness(1.12); }
.sprite.cinema-target { z-index: 7; filter: drop-shadow(0 0 11px var(--cine-cor)); }
#battle-stage.hit-stop .spr, #battle-stage.hit-stop .vfx-vento, #battle-stage.hit-stop .vfx-onda,
#battle-stage.hit-stop .vfx-brasa, #battle-stage.hit-stop .vfx-corte, #battle-stage.hit-stop .vfx-impact-ring { animation-play-state: paused !important; }
.vfx-impact-ring { position:absolute; width:34px; height:34px; margin:-17px 0 0 -17px; border:3px solid currentColor; border-radius:50%;
  box-shadow:0 0 20px currentColor, inset 0 0 14px currentColor; pointer-events:none; opacity:0; animation:impactRing .52s cubic-bezier(.12,.76,.28,1) forwards; }
.vfx-impact-ring.forte { width:64px; height:64px; margin:-32px 0 0 -32px; border-width:5px; animation-duration:.78s; }
@keyframes impactRing { 0%{transform:scale(.16);opacity:1} 32%{opacity:.92} 100%{transform:scale(2.35);opacity:0} }
@media (prefers-reduced-motion: reduce) {
  #battle-stage.cinema #bs-bg, #battle-stage.cinema .bs-row { transform:none; }
  .vfx-impact-ring { animation-duration:.01ms !important; }
}
.vfx-skill-callout { position:absolute; z-index:12; transform:translate(-50%,-100%); min-width:124px; padding:6px 10px 7px;
  border-left:2px solid var(--skill-cor); border-right:2px solid var(--skill-cor); color:#f7f5ff;
  background:linear-gradient(90deg,transparent,rgba(4,5,12,.92) 18%,rgba(4,5,12,.92) 82%,transparent);
  text-align:center; text-shadow:0 2px 4px #000,0 0 12px var(--skill-cor); pointer-events:none; opacity:0;
  animation:skillCall .9s cubic-bezier(.16,.9,.24,1) forwards; }
.vfx-skill-callout span { color:var(--skill-cor); margin-right:5px; }.vfx-skill-callout b { font:700 11px/1.1 Georgia,serif; letter-spacing:.11em; text-transform:uppercase; }
.vfx-skill-callout.ultimate { min-width:220px; padding:11px 16px; border-top:1px solid var(--skill-cor); border-bottom:1px solid var(--skill-cor); animation-duration:1.65s; }
.vfx-skill-callout.ultimate b { font-size:16px; letter-spacing:.16em; }

/* --- A FAIXA DO GOLPE GRANDE ------------------------------------------
   O relato: "o texto fica na cena e nao da pra ver direito a acao de
   fundo". Estava certo -- e a causa era o ancoramento. O aviso nasce
   ACIMA DO SPRITE, o que serve para um golpe comum, mas num combo os dois
   herois estao no meio do palco: a caixa caia exatamente sobre a acao.

   Golpe grande ganha FAIXA no topo do palco, atravessada de ponta a
   ponta, fora da zona onde o efeito acontece. E sai de cena antes do
   impacto, para o momento que importa ficar limpo.
   --------------------------------------------------------------------- */
.vfx-skill-faixa{ position:absolute; left:0; right:0; top:0; z-index:13;
  display:flex; align-items:center; justify-content:center; gap:9px;
  padding:9px 16px 10px; pointer-events:none; opacity:0;
  color:#f7f5ff; text-align:center;
  background:linear-gradient(90deg, transparent, rgba(4,5,12,.9) 14%,
             rgba(4,5,12,.94) 50%, rgba(4,5,12,.9) 86%, transparent);
  border-bottom:1px solid color-mix(in srgb, var(--skill-cor) 70%, transparent);
  box-shadow:0 10px 34px -14px var(--skill-cor);
  text-shadow:0 2px 5px #000, 0 0 16px var(--skill-cor);
  animation:skillFaixa 1.5s cubic-bezier(.16,.9,.24,1) forwards; }
.vfx-skill-faixa span{ color:var(--skill-cor); font-size:17px }
.vfx-skill-faixa b{ font:700 15px/1.1 Georgia,serif; letter-spacing:.2em; text-transform:uppercase }
.vfx-skill-faixa i{ font:600 10px/1 var(--sans); letter-spacing:.14em;
  font-style:normal; color:color-mix(in srgb, var(--skill-cor) 60%, #cfc9dd) }
/* Fecha em 62% da vida: o impacto sai por volta de 1000ms e a faixa tem
   que ter sumido ate la. Um aviso que ainda esta na tela quando o golpe
   cai e justamente o que o jogador reclamou. */
@keyframes skillFaixa{
  0%  { opacity:0; transform:translateY(-100%) }
  14% { opacity:1; transform:translateY(0) }
  58% { opacity:1; transform:translateY(0) }
  100%{ opacity:0; transform:translateY(-100%) } }
@keyframes skillCall { 0%{transform:translate(-50%,-75%) scale(.82);opacity:0} 20%{opacity:1} 72%{transform:translate(-50%,-112%) scale(1)} 100%{transform:translate(-50%,-125%) scale(.98);opacity:0} }

/* Assinaturas de habilidade: a arena responde ao que foi usado, em vez de
   trocar apenas a cor de uma orb. Todas as transicoes usam transform/opacity. */
.vfx-rugido{position:absolute;width:calc(var(--r) * 2);height:calc(var(--r) * 1.15);margin-left:calc(var(--r) * -1);margin-top:calc(var(--r) * -.58);border:3px solid currentColor;border-left-color:transparent;border-bottom-color:transparent;border-radius:50%;box-shadow:0 0 16px currentColor;opacity:0;animation:rugidoVoa .8s cubic-bezier(.12,.78,.25,1) forwards}
@keyframes rugidoVoa{0%{transform:translate(0,0) scale(.15) rotate(-12deg);opacity:0}15%{opacity:.95}100%{transform:translate(var(--dx),var(--dy)) scale(2.7) rotate(8deg);opacity:0}}
.vfx-muralha{position:absolute;width:var(--lg);height:var(--alt);margin-left:calc(var(--lg) / -2);margin-top:calc(var(--alt) * -1);border:3px solid color-mix(in srgb,currentColor 76%,#e9fdff);border-bottom:0;border-radius:48% 52% 12% 12%/18% 22% 5% 5%;background:linear-gradient(to top,color-mix(in srgb,currentColor 76%,transparent),color-mix(in srgb,#e7fdff 52%,transparent) 45%,transparent);box-shadow:0 0 28px currentColor,inset 0 0 22px #dffcff66;opacity:0;animation:muralhaErgue 1.35s cubic-bezier(.14,.86,.26,1) forwards}
@keyframes muralhaErgue{0%{transform:translateY(42%) scaleY(.12) scaleX(.72);opacity:0}18%{opacity:.85}48%{transform:translateY(-2%) scaleY(1.05);opacity:.92}100%{transform:translateY(-12%) scaleY(1);opacity:0}}
#battle-stage.cinema-ult .sprite.cinema-target{animation:cinemaAlvo .52s ease-in-out 2}
@keyframes cinemaAlvo{50%{transform:translateY(4px) scale(.955);filter:brightness(1.65) saturate(1.35)}}
@media (prefers-reduced-motion:reduce){.vfx-rugido,.vfx-muralha,.sprite.cinema-target{animation-duration:.01ms!important}}

/* Progressão: características ficam separadas da especialização para que o
   primeiro nível ganho sempre dê uma decisão concreta ao jogador. */
.progress-panel{margin:0 0 16px;padding:12px;border:1px solid #37334d;border-radius:9px;background:linear-gradient(135deg,#0d0d18,#090a11)}
.progress-h{display:flex;align-items:baseline;justify-content:space-between;margin-bottom:9px;font:700 11px/1 Georgia,serif;letter-spacing:.13em;color:#d7d0bd}
.progress-h b{color:var(--gold);font:600 11px/1 var(--sans);letter-spacing:0}
.attribute-grid{display:grid;grid-template-columns:repeat(5,1fr);gap:7px}

/* --- PERICIAS: a escada que o dado usa ------------------------------
   Sete cartoes numa fileira ficariam com 90px cada num modal de 700 --
   estreito demais para caber "Resistência" sem quebrar no meio. Em duas
   fileiras de quatro sobra largura para o nome, os postos e o numero. */
.pericia-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:7px}
.pericia-card{display:flex;flex-direction:column;gap:4px;align-items:flex-start;
  padding:9px 10px;border:1px solid #37334d;border-radius:8px;
  background:linear-gradient(160deg,#12111e,#0b0b13);color:var(--txt2);
  text-align:left;cursor:default;transition:border-color .15s,transform .1s}
.pericia-card b{font:600 12px/1.2 var(--sans);color:#e6e0f5}
.pericia-card em{font-style:normal;font:700 12px/1 var(--sans);color:var(--gold)}
.pericia-card small{font-size:10px;line-height:1.35;color:var(--txt3)}
.pericia-card .pips{display:flex;gap:3px}
.pericia-card .pips i{width:9px;height:9px;border-radius:50%;
  border:1px solid #4a4463;background:#0a0a11}
.pericia-card .pips i.on{background:var(--gold);border-color:var(--gold);
  box-shadow:0 0 5px color-mix(in srgb,var(--gold) 60%,transparent)}
.pericia-card.ready{cursor:pointer;border-color:color-mix(in srgb,var(--gold) 55%,#37334d)}
.pericia-card.ready:hover{transform:translateY(-1px);border-color:var(--gold)}
.pericia-card[disabled]{opacity:.62}

/* --- O QUE O TALENTO FAZ COM O SEU KIT ------------------------------
   A habilidade concedida vivia no fim da descricao, na mesma tipografia
   de "+12% de ATK". Virou selo porque e a informacao que muda como o
   heroi JOGA, e nao so quanto ele soma. */
.tsels{display:flex;flex-wrap:wrap;gap:4px;margin-top:6px}
.tsel{font:600 10px/1 var(--sans);padding:4px 6px;border-radius:5px;
  border:1px solid transparent;white-space:nowrap}
.tsel.ganha{color:#7ee2a8;background:#0e2419;border-color:#1f5638}
.tsel.perde{color:#e59a9a;background:#2a1416;border-color:#5c2a2c}
.tsel.per{color:#e8d08a;background:#241f10;border-color:#57492a}
.attribute-card{min-height:79px;display:flex;flex-direction:column;align-items:flex-start;gap:4px;padding:8px;border:1px solid #2a293a;border-radius:6px;background:#0a0b13;color:var(--txt);text-align:left}
.attribute-card.ready{cursor:pointer;border-color:#71613e;background:linear-gradient(145deg,#15130e,#0a0b13)}
.attribute-card.ready:hover{border-color:var(--gold);transform:translateY(-2px);box-shadow:0 7px 18px #0008}
.attribute-card b{font:700 12px/1.1 Georgia,serif;color:#e1d8c6}.attribute-card b em{font:700 11px var(--sans);font-style:normal;color:var(--gold);margin-left:3px}
.attribute-card span{font-size:9.5px;line-height:1.25;color:var(--txt3)}.attribute-card small{margin-top:auto;color:#8baeca;font-size:9px}
@media(max-width:700px){.attribute-grid,.pericia-grid{grid-template-columns:repeat(2,1fr)}.tree-grid,.subclass-pick{grid-template-columns:1fr}}

/* =====================================================================
   PALCO EM VISTA LATERAL  (camada final — vence os ajustes anteriores)

   O grupo ocupa a esquerda, os inimigos a direita, e as duas formacoes se
   encaram, como no Knights of Pen and Paper. Antes o confronto era no eixo
   vertical (inimigos em cima, grupo embaixo) e nao havia onde mostrar
   vanguarda e retaguarda.

   Cada lado e duas colunas. A VANGUARDA fica na borda interna, de frente
   para o inimigo; a RETAGUARDA na borda externa. Assim a regra do motor --
   aco nao alcanca o fundo enquanto a frente viver -- vira distancia visivel
   na tela, e nao um selo escrito no card.

   #bs-enemies vem ANTES de #bs-party no HTML, entao `row-reverse` poe os
   inimigos a direita sem precisar mexer no index.html nem usar `order`.
   ===================================================================== */
#battle-stage{
  flex-direction:row-reverse;
  align-items:stretch;
  justify-content:space-between;
  gap:clamp(10px,3vw,58px);
  padding:20px clamp(10px,2.4vw,30px) 14px;
  min-height:452px;
}
#battle-stage>.bs-row{
  flex:1 1 0;
  display:flex;
  align-items:stretch;
  justify-content:center;
  gap:clamp(6px,1.4vw,26px);
  min-width:0;
  flex-wrap:nowrap;
  overflow:visible;
}
/* A retaguarda do grupo e a do inimigo sao as bordas EXTERNAS do palco. */
#bs-party  {justify-content:flex-start}
#bs-enemies{justify-content:flex-end}

/* Uma fileira e uma coluna de corpos. Ela existe mesmo vazia: sem largura
   reservada, matar o ultimo da vanguarda fazia a formacao saltar de lado. */
.bs-fileira{
  position:relative;
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:flex-end;
  min-width:clamp(66px,8.5vw,116px);
  padding-bottom:2px;
}
/* Sobreposicao proposital: corpos empilhados sem folga leem como uma
   multidao em profundidade, e cabem quatro numa fileira sem estourar a
   altura do palco. O escalonamento lateral desfaz o efeito de fila indiana. */
.bs-fileira .sprite{transform:translateX(var(--escalonar,0px))}
/* A sobreposicao apertada empurrava o rotulo de quem esta embaixo para
   cima do corpo de quem esta em cima. Com o chao mais alto sobra altura
   para afrouxar, e so as fileiras lotadas continuam se encavalando. */
.bs-fileira .sprite+.sprite{margin-top:-12px}
.bs-fileira[data-n="4"] .sprite+.sprite{margin-top:-22px}
.bs-fileira[data-n="5"] .sprite+.sprite{margin-top:-30px}

/* A retaguarda esta mais longe: um pouco menor e mais apagada. E a unica
   pista visual de profundidade que nao depende de perspectiva desenhada. */
.bs-fileira.f-fundo{align-self:flex-end;padding-bottom:26px}
.bs-fileira.f-fundo .sprite{filter:brightness(.86) saturate(.9)}
.bs-fileira.f-fundo .sprite.acting{filter:none}

/* No palco lateral o heroi mostra so nome e vida. MP e recurso de classe ja
   estao no painel do grupo, a esquerda; repetir aqui roubava a altura que
   os corpos precisam. */
#bs-party .sprite .hpbar.mp,
#bs-party .sprite .hpbar.res,
#bs-party .sprite .res-txt{display:none}

/* O rotulo do inimigo continua acima da cabeca e o do heroi abaixo dos pes,
   como estava; so o eixo do confronto mudou. */
#bs-enemies .sprite{flex-direction:column;justify-content:flex-end}
#bs-party   .sprite{flex-direction:column;justify-content:flex-end}
#bs-enemies,#bs-party{align-items:flex-end}

/* Chao unico: as duas formacoes pisam na mesma linha, senao uma parece
   flutuar em relacao a outra. */
#battle-stage::after{background:radial-gradient(ellipse at 50% 78%,transparent 42%,rgba(2,3,9,.6) 96%)}

@media(max-width:900px){
  #battle-stage{gap:8px;padding:10px 8px;min-height:400px}
  .bs-fileira{min-width:58px}
  .bs-fileira.f-fundo{padding-bottom:16px}
}
/* ---------------------------------------------------------------------
   O CARD FANTASMA NO PALCO

   `.sprite.hero` casa tambem com a regra generica `.hero`, que existe
   para o painel do grupo e pinta fundo, borda e sombra. No palco lateral
   isso virava uma caixa por heroi, e as caixas se sobrepunham quando a
   fileira empilha. O palco mostra CRIATURAS, nao fichas -- entao aqui a
   pintura e desligada, e so no palco.
   --------------------------------------------------------------------- */
#battle-stage .sprite.hero,
#battle-stage .sprite.foe{
  background:none!important;border:0!important;box-shadow:none!important;
  padding:0;border-radius:0;
}

/* Nome do inimigo cabia em uma linha de 106px e "Colossal Sereia do
   Abismo" virava "Colossal Sereia do...". No palco o rotulo pode ser mais
   largo que o boneco e quebrar em duas linhas: ler o nome importa mais
   que manter a coluna estreita. */
#battle-stage .sprite .nm{
  white-space:normal;overflow:visible;text-overflow:clip;
  width:auto;max-width:clamp(84px,11vw,150px);
  line-height:1.15;
}
#battle-stage .sprite.tem-boneco .nm{width:auto;max-width:clamp(84px,11vw,150px)}

/* =====================================================================
   O CHAO

   As duas formacoes pisavam no nada: a arte da regiao ocupava o quadro
   inteiro com `cover` e os bonecos flutuavam sobre ela. Faltava um plano
   de solo -- que e o que a Infinity Engine e o Diablo desenham, e o que
   faz o personagem PARECER estar em algum lugar.

   Nada de arte nova. O chao e construido com gradiente, e herda a cor do
   reino pela variavel --chao, escrita em renderStage(). Assim o solo de
   Aqualis nao tem o tom do solo de Drakoria.
   ===================================================================== */
#battle-stage{ --chao:#8b7aa8; }

#bs-chao{
  position:absolute;left:0;right:0;bottom:0;height:47%;
  pointer-events:none;z-index:1;
  background:
    /* a nevoa onde o solo encontra o cenario: sem ela a emenda e uma
       linha reta que denuncia os dois planos */
    linear-gradient(to bottom,
      color-mix(in srgb, var(--chao) 9%, #06060b) 0%,
      color-mix(in srgb, var(--chao) 5%, #06060b00) 26%,
      transparent 42%),
    /* o solo: mais claro no meio, onde as formacoes pisam, escurecendo
       para as bordas -- e a leitura barata de profundidade */
    radial-gradient(ellipse 128% 155% at 50% 122%,
      color-mix(in srgb, var(--chao) 26%, #100e18) 0%,
      color-mix(in srgb, var(--chao) 12%, #0b0a12) 38%,
      #07060c 100%);
}

/* A arena: a mancha de luz onde os dois lados se encontram. Da ao palco
   um centro, em vez de um degrade uniforme de canto a canto. */
#bs-chao::before{
  content:'';position:absolute;left:50%;bottom:2%;
  width:138%;height:82%;transform:translateX(-50%);
  border-radius:50%;
  background:radial-gradient(ellipse at 50% 44%,
    color-mix(in srgb, var(--chao) 22%, transparent) 0%,
    color-mix(in srgb, var(--chao) 9%, transparent) 46%,
    transparent 74%);
  box-shadow:inset 0 14px 46px rgba(0,0,0,.5);
}

/* A linha do horizonte, fina e sem contorno duro: e onde o olho decide
   que existe um chao e nao so um degrade. */
#bs-chao::after{
  content:'';position:absolute;left:6%;right:6%;top:0;height:1px;
  background:linear-gradient(to right,transparent,
    color-mix(in srgb, var(--chao) 40%, transparent) 22%,
    color-mix(in srgb, var(--chao) 40%, transparent) 78%,transparent);
  opacity:.5;
}

/* A arte da regiao vira CENARIO DE FUNDO: ela para no horizonte em vez de
   escorrer ate o rodape por baixo dos pes de todo mundo. */
#bs-bg::after{
  background:linear-gradient(180deg,
    #06060b66 0%, #06060b1a 30%, #06060b59 50%,
    #06060bb3 66%, #06060bf2 80%)!important;
}

/* Sombra de contato. A anterior era um borrao fixo de 9px que nao crescia
   com o boneco: Vyrakos, com 235px, pairava sobre a mesma manchinha do
   Filhote de Brasa. Agora ela acompanha a largura do corpo. */
#battle-stage .sprite.tem-boneco .body::after{
  width:72%;height:11%;min-height:7px;max-height:20px;
  bottom:1px;
  background:radial-gradient(ellipse at 50% 50%,
    rgba(0,0,0,.62) 0%, rgba(0,0,0,.34) 46%, transparent 74%);
  filter:blur(.5px);
}
/* Quem esta na retaguarda esta mais longe: sombra menor e mais fraca. */
#battle-stage .bs-fileira.f-fundo .sprite.tem-boneco .body::after{
  width:58%;opacity:.62;
}

/* As duas formacoes ficam ACIMA do chao, nunca por baixo dele. */
#bs-enemies,#bs-party{position:relative;z-index:3}

@media(max-width:900px){ #bs-chao{height:42%} }

/* ---------------------------------------------------------------------
   PERSPECTIVA DENTRO DA FILEIRA

   O chao sozinho nao resolvia: numa coluna vertical so o boneco de baixo
   pisa na linha do solo, e os de cima ficavam no ar. Medido: pes em 152,
   215 e 277 px contra um horizonte em 271 -- tres corpos no ceu.

   A saida e perspectiva, nao alinhamento. Quem esta mais acima esta mais
   LONGE: encolhe, perde contraste e ganha a bruma do ar entre ele e a
   camera. O chao sobe atras de todos, com emenda longa em vez de linha.
   --------------------------------------------------------------------- */
/* 76% ainda deixava o boneco mais ao fundo de cada fileira ACIMA do
   horizonte -- visivel na foto de Drakoria, com o Couracado boiando. O
   topo do chao e um esmaecimento longo, entao subir nao rouba o cenario:
   ele continua aparecendo por transparencia. */
#bs-chao{
  height:84%;
  /* O chao precisa de ALTURA para que o boneco mais ao fundo da fileira
     pise em alguma coisa, mas nao precisa de OPACIDADE em toda ela.
     Agora que o cenario e pintura de verdade gravada no disco -- e nao um
     degrade generico -- cobrir 84% da tela com solido era jogar fora o que
     acabou de ser feito. O terco de cima do chao vira transparente e a
     pintura aparece por tras, com o solido so onde os pes encostam. */
  -webkit-mask-image:linear-gradient(to bottom, transparent 0%, rgba(0,0,0,.55) 22%, #000 46%);
  mask-image:linear-gradient(to bottom, transparent 0%, rgba(0,0,0,.55) 22%, #000 46%);
}
/* Tao alto, o horizonte deixa de ser uma linha e vira transicao. */
#bs-chao::after{display:none}
#bs-chao::before{height:64%;bottom:1%}

.bs-fileira .sprite{
  transform:translateX(var(--escalonar,0px)) scale(calc(1 - var(--dist,0) * .14));
  transform-origin:50% 100%;
  filter:saturate(calc(1 - var(--dist,0) * .34))
         brightness(calc(1 - var(--dist,0) * .2))
         contrast(calc(1 - var(--dist,0) * .12))
         blur(calc(var(--dist,0) * .35px));
}
/* A bruma aerea era uma CAIXA por cima do boneco -- e no print apareceu
   exatamente como isso: retangulos claros atras de cada personagem. Um
   overlay retangular nunca vai casar com a silhueta de um sprite. A bruma
   volta como FILTRO, que segue o recorte do proprio desenho. */
.bs-fileira .sprite.acting{filter:none}

/* =====================================================================
   TERRENO POR REINO

   Um degrade escuro nao e chao: e um vazio com cor. O que faz o
   personagem parecer estar EM ALGUM LUGAR e o lugar ter regra propria --
   em Aqualis se pisa em pedra seca e o resto e agua; em Drakoria a rocha
   racha e o magma aparece por baixo.

   Duas plataformas, uma sob cada formacao, porque e ali que os pes
   encostam. O que estiver fora delas e o reino.
   ===================================================================== */
/* A plataforma tem que cobrir a PROFUNDIDADE inteira da formacao, nao so
   os pes de quem esta na frente. Com 34% de altura so a vanguarda pisava
   nela e a retaguarda boiava -- exatamente o que a foto mostrou. A elipse
   larga e baixa e o que le como disco em perspectiva. */
#bs-chao .plat{
  position:absolute;bottom:2%;height:62%;width:43%;
  /* Raios diferentes nos quatro cantos: um circulo perfeito lia como
     holofote desenhado no chao, nao como ilha de pedra. */
  border-radius:48% 52% 46% 54% / 44% 46% 54% 56%;
  pointer-events:none;z-index:2;
  background:
    /* a rocha e ESCURA. O que a destaca da agua e a borda que pega luz,
       nao um miolo claro -- miolo claro e projetor, nao pedra. */
    radial-gradient(ellipse at 50% 40%,
      color-mix(in srgb, var(--chao) 13%, #14131c) 0%,
      color-mix(in srgb, var(--chao) 8%,  #100f17) 58%,
      color-mix(in srgb, var(--chao) 3%,  #08070d) 100%);
  box-shadow:
    0 -1px 0 color-mix(in srgb, var(--chao) 26%, transparent),
    inset 0 14px 30px rgba(0,0,0,.5),
    0 20px 54px rgba(0,0,0,.66);
}
/* As duas ilhas se encostavam no meio e viravam uma lente. Separadas, o
   vao entre elas e o que mostra o terreno do reino. */
#bs-chao .plat.esq{left:0%}
#bs-chao .plat.dir{right:0%}
/* A agua fica ATRAS da pedra. Com o detalhe por cima, as faixas de onda
   cruzavam a ilha e ela deixava de parecer solida. */
#bs-chao .detalhe{position:absolute;inset:0;pointer-events:none;z-index:1}

/* =====================================================================
   A PLACA PINTADA DO SOLO

   O relato: "o piso/chao do background da luta ainda nao tem a qualidade
   da imagem de fundo e dos sprites". Estava certo, e nenhum ajuste de
   degrade ia resolver -- porque degrade nao tem DETALHE. O cenario e
   matte painting de 1920x1080 gravado no disco, os bonecos sao pixel
   art, e entre os dois havia color-mix. A unica das tres linguagens sem
   textura era justamente a que ocupa o terco de baixo da tela.

   Agora existe pintura tambem no chao: tools/gerar_chao.py grava uma
   placa por reino em assets/art/chao-<reino>.jpg. O CSS usa a placa como
   TEXTURA e mantem os degrades como LUZ -- sombra de contato, vinheta,
   brilho da beirada. Textura embaixo, iluminacao em cima.

   A placa entra por pseudo-elemento, e nao no `background` de .plat,
   porque cada terreno reescreve esse `background` inteiro: entrar la
   obrigaria a repetir a mesma url em seis regras, e a setima ficaria
   para tras na proxima mudanca.
   ===================================================================== */
/* As placas em si moram em css/chao.css, gerado por tools/gerar_chao.py e
   embutido como data: URI. Nao e capricho: como url() de arquivo, a placa
   chegava DEPOIS do quadro em 1 de cada 3 capturas -- medido em 2400, 6000
   e 15000 ms de orcamento, sempre 2 de 3, ou seja o problema nunca foi
   tempo. `background-image` de pseudo-elemento so e buscado depois do
   elemento existir e ser disposto. Folha de estilo bloqueia a pintura,
   entao dentro dela a textura ja esta pronta no primeiro pixel -- e o
   jogador tambem para de ver o chao liso por um instante ao trocar de
   regiao.

   As declaracoes de --placa vivem SO la. Se estivessem aqui tambem,
   existiria a versao em que as duas discordam e a que vence depende da
   ordem dos <link>. */
#bs-chao{ --placa:none; }

/* A laje onde a formacao pisa. A mascara elipsoidal e o que impede o
   recorte de tesoura: a pedra desbota no vazio em vez de terminar numa
   borda de JPEG. */
#bs-chao .plat::before{
  content:'';position:absolute;inset:0;border-radius:inherit;
  pointer-events:none;
  background:
    /* A luz e VERTICAL, nao radial. A primeira versao usava vinheta
       redonda e o resultado, na foto de Eldoria, foi uma CUPULA de pedra
       no lugar de um piso: sombra concentrica em volta de um miolo claro
       e exatamente como se desenha uma esfera. Chao em perspectiva
       escurece para o FUNDO (topo) e clareia para a camera. */
    linear-gradient(to bottom,
      rgba(6,5,12,.88) 0%, rgba(6,5,12,.46) 24%,
      rgba(6,5,12,.08) 60%, rgba(6,5,12,.50) 100%),
    /* Tinta do reino. As placas saem do gerador NIVELADAS na mesma
       faixa de brilho, de proposito -- para o CSS nao precisar de um
       ajuste por regiao. A identidade volta aqui, pela mesma variavel
       --chao que ja pinta o resto do solo. */
    /* A base do multiply e CLARA de proposito. Com #6b6478 (42% de
       luminancia) o multiply cortava quase 60% do brilho e a pedra de
       Eldoria, que e clara, virava piso preto. A camada esta aqui para
       TINGIR, nao para escurecer -- quem escurece e o degrade de luz. */
    linear-gradient(color-mix(in srgb, var(--chao) 24%, #d2ccdf),
                    color-mix(in srgb, var(--chao) 24%, #d2ccdf)),
    var(--placa) 22% 68% / 168% auto no-repeat;
  background-blend-mode:normal, multiply, normal;
  -webkit-mask-image:radial-gradient(ellipse at 50% 50%,
    #000 50%, rgba(0,0,0,.5) 76%, transparent 97%);
  mask-image:radial-gradient(ellipse at 50% 50%,
    #000 50%, rgba(0,0,0,.5) 76%, transparent 97%);
  /* a placa vem de foto: sem esta correcao ela grita mais que o cenario,
     que e pintura escura, e o chao passa a ser a coisa mais viva da tela */
  filter:saturate(.86) contrast(1.05);
  opacity:1;
}
/* Cada laje mostra um PEDACO diferente da mesma placa. Com o mesmo
   recorte nas duas, o palco ficava espelhado e o olho notava a copia. */
#bs-chao .plat.dir::before{ background-position:76% 30% }

/* Em Aqualis a laje esta molhada: a agua parada devolve o brilho do ceu,
   entao a placa la reflete em vez de afundar. */
#bs-chao[data-terreno="aqualis"] .plat::before{ filter:saturate(1) contrast(1.05) brightness(1.08) }
/* ...e o grao AMBIENTE recua em Aqualis. Com a placa virando pedra
   molhada, o grao passou a espalhar rocha pelo palco inteiro -- e a regra
   do reino e o contrario: solido onde se pisa, mar no resto. Aqui quem
   manda fora das lajes e a agua do `.detalhe`. */
#bs-chao[data-terreno="aqualis"] .grao{ opacity:.12 }

/* O grao do solo AMBIENTE -- o que esta fora das lajes. Sem ele a laje
   virava uma ilha nitida sobre um degrade liso, e a emenda entre as duas
   qualidades ficava mais visivel que antes de existir textura. */
#bs-chao .grao{
  position:absolute;inset:0;pointer-events:none;z-index:0;
  background:var(--placa) 50% 84% / 46% auto repeat;
  /* `overlay` em vez de opacidade: assim o grao MODULA o que estiver
     embaixo em vez de pintar por cima. Com opacidade normal a textura
     sumia em Aqualis, cujo solo e claro, e chapava em Drakoria, cujo
     solo e quase preto -- o mesmo valor dava dois resultados opostos. */
  mix-blend-mode:overlay;
  opacity:.42;
  filter:saturate(.5) contrast(1.12);
  -webkit-mask-image:linear-gradient(to bottom, transparent 34%, #000 68%, #000 100%);
  mask-image:linear-gradient(to bottom, transparent 34%, #000 68%, #000 100%);
}

/* ------------------------------ AQUALIS ------------------------------
   O pedido literal: solido onde se pisa, agua no resto. As plataformas
   viram lajes molhadas; entre elas e ao redor, mar. */
#bs-chao[data-terreno="aqualis"]{
  background:
    linear-gradient(to bottom, #06080ecc 0%, #06080e33 20%, transparent 38%),
    radial-gradient(ellipse 130% 150% at 50% 118%, #123246 0%, #0a1d2c 44%, #050b12 100%);
}
/* O mar: faixas horizontais claras que deslizam devagar. Horizontais
   porque reflexo em agua parada e horizontal -- diagonal vira tecido. */
#bs-chao[data-terreno="aqualis"] .detalhe{
  background:
    /* brilho largo no meio, onde a luz do ceu bate na agua */
    radial-gradient(ellipse 52% 22% at 50% 84%, rgba(150,220,255,.13), transparent 72%),
    repeating-linear-gradient(to bottom,
      transparent 0 9px,
      rgba(170,232,255,.2) 9px 12px,
      transparent 12px 21px);
  mask-image:linear-gradient(to bottom, transparent 30%, #000 56%, #000 100%);
  animation:mare 9s linear infinite;
}
@keyframes mare{ from{background-position:0 0,0 0} to{background-position:0 0,0 21px} }
/* A laje encharcada: mais escura e com o brilho de agua parada em cima. */
#bs-chao[data-terreno="aqualis"] .plat{
  background:
    linear-gradient(to bottom, rgba(174,231,255,.13) 0 3%, transparent 16%),
    radial-gradient(ellipse at 50% 40%, #1b3141 0%, #122630 56%, #08131a 100%);
  box-shadow:0 -2px 0 rgba(186,240,255,.42), inset 0 14px 30px rgba(0,0,0,.52),
             0 20px 54px rgba(0,0,0,.68);
}
/* Espuma na beirada: onde a pedra encontra o mar. */
#bs-chao[data-terreno="aqualis"] .plat::after{
  content:'';position:absolute;inset:-3px;border-radius:50%;
  border:2px solid rgba(190,240,255,.2);
  filter:blur(1.5px);animation:espuma 3.6s ease-in-out infinite;
}
@keyframes espuma{ 50%{ border-color:rgba(190,240,255,.44); inset:-5px } }

/* ------------------------------ DRAKORIA ----------------------------- */
#bs-chao[data-terreno="drakoria"]{
  background:
    linear-gradient(to bottom, #0d0704cc 0%, #0d070433 20%, transparent 38%),
    radial-gradient(ellipse 130% 150% at 50% 120%, #3a1a0c 0%, #1d0d07 46%, #0a0503 100%);
}
/* Fissuras de magma: veios finos que pulsam, nao um chao laranja inteiro. */
#bs-chao[data-terreno="drakoria"] .detalhe{
  background:
    radial-gradient(ellipse 40% 3% at 30% 74%, rgba(255,110,30,.5), transparent 70%),
    radial-gradient(ellipse 30% 2% at 62% 86%, rgba(255,80,20,.42), transparent 70%),
    radial-gradient(ellipse 22% 2% at 47% 66%, rgba(255,150,40,.3), transparent 70%);
  animation:brasa 4.5s ease-in-out infinite;
}
@keyframes brasa{ 50%{opacity:.5} }
#bs-chao[data-terreno="drakoria"] .plat{
  background:
    linear-gradient(to bottom, rgba(255,160,90,.1) 0 4%, transparent 20%),
    radial-gradient(ellipse at 50% 36%, #4a2d20 0%, #2a170f 54%, #120a06 100%);
  box-shadow:0 -2px 0 rgba(255,140,60,.28), inset 0 10px 26px rgba(0,0,0,.46),
             0 18px 50px rgba(0,0,0,.66);
}

/* ------------------------------ VHALDRAK ----------------------------- */
#bs-chao[data-terreno="vhaldrak"]{
  background:
    linear-gradient(to bottom, #0d0406cc 0%, #0d040633 20%, transparent 38%),
    radial-gradient(ellipse 130% 150% at 50% 120%, #3d1119 0%, #1e080d 46%, #0a0305 100%);
}
/* Poças que nao secam. */
#bs-chao[data-terreno="vhaldrak"] .detalhe{
  background:
    radial-gradient(ellipse 9% 3% at 24% 80%, rgba(150,20,32,.44), transparent 72%),
    radial-gradient(ellipse 12% 3% at 55% 90%, rgba(120,14,26,.4), transparent 74%),
    radial-gradient(ellipse 7% 2% at 74% 72%, rgba(160,26,38,.34), transparent 72%);
}

/* ------------------------------ NOCTHERA ----------------------------- */
#bs-chao[data-terreno="nocthera"]{
  background:
    linear-gradient(to bottom, #08060ecc 0%, #08060e33 20%, transparent 38%),
    radial-gradient(ellipse 130% 150% at 50% 122%, #241a3d 0%, #130d21 46%, #06040b 100%);
}
/* A sombra nao tem chao firme: o proprio solo respira. */
#bs-chao[data-terreno="nocthera"] .detalhe{
  background:radial-gradient(ellipse 60% 26% at 50% 92%, rgba(139,92,246,.14), transparent 72%);
  animation:respiro 7s ease-in-out infinite;
}
@keyframes respiro{ 50%{opacity:.45; transform:scale(1.06)} }

/* ------------------------------ ELDORIA ------------------------------ */
#bs-chao[data-terreno="eldoria"]{
  background:
    linear-gradient(to bottom, #07070ccc 0%, #07070c33 20%, transparent 38%),
    radial-gradient(ellipse 130% 150% at 50% 120%, #2b2c38 0%, #16171f 46%, #07070c 100%);
}
/* Calcada partida: a cidade rachou quando o ceu rachou. */
#bs-chao[data-terreno="eldoria"] .detalhe{
  background:
    linear-gradient(105deg, transparent 49.6%, rgba(190,200,225,.1) 49.9%, transparent 50.3%),
    linear-gradient(72deg,  transparent 31.7%, rgba(190,200,225,.07) 32%, transparent 32.4%),
    linear-gradient(96deg,  transparent 70.7%, rgba(190,200,225,.06) 71%, transparent 71.4%);
  mask-image:linear-gradient(to bottom, transparent 40%, #000 70%);
}

@media(prefers-reduced-motion:reduce){
  #bs-chao .detalhe,#bs-chao .plat::after{animation:none!important}
}

/* ---------------------------------------------------------------------
   MODO FOTO (tools/foto.ps1)
   Banner, splash de chefe e avisos sao apresentacao: numa foto de
   verificacao eles so cobrem o que precisa ser olhado.
   --------------------------------------------------------------------- */
html[data-foto] #banner, html[data-foto] .banner,
html[data-foto] #boss-splash, html[data-foto] .boss-splash, html[data-foto] .toast,
html[data-foto] #toasts, html[data-foto] .overlay,
html[data-foto] .modal, html[data-foto] #setup,
html[data-foto] .cinema-flash{ display:none!important; opacity:0!important }
/* ...menos quando a JANELA E O ASSUNTO. A cena `talentos` existe para
   fotografar o painel de pericias e o selo de habilidade no no do
   talento -- as duas coisas que so se conferem olhando. A regra acima e
   ampla de proposito (cala splash, banner e aviso), e engolia tambem a
   unica coisa que essa cena tinha para mostrar. */
html[data-foto="talentos"] .modal{ display:flex!important; opacity:1!important }

/* --- NA FOTO, A PLATAFORMA TEM TAMANHO FIXO -------------------------
   `ajustarPlataformas` mede a caixa real dos bonecos e escreve o tamanho
   em estilo inline. E o certo para o jogo -- foi assim que os personagens
   pararam de flutuar. Mas para a regressao visual e uma corrida: o Edge
   fotografa quando o orcamento de tempo virtual acaba, e isso cai em
   pontos diferentes da montagem. Resultado medido: a MESMA cena
   alternando entre dois estados, 18% a 21% de diferenca, em cerca de
   metade das rodadas.

   Foi tentado, e medido, sem resolver: orcamento de 2400/6000/15000 ms
   (2 de 3 em todos os tres), placa embutida como data: URI, esperar
   Sprites.precarregar, tirar o redesenho em setTimeout, por uma remedida
   em prazo fixo (piorou), trocar `animation-play-state:paused` por
   `animation:none` (piorou bastante).

   Com tamanho fixo, a foto para de sortear e volta a cobrir o quadro
   INTEIRO -- bonecos, fileiras, cenario, cards, HUD. O que ela deixa de
   cobrir e o DIMENSIONAMENTO da plataforma, e isso esta escrito aqui para
   ninguem achar que esta coberto: confere-se a mao, com
   `toolsoto.ps1 -Cena palco`. */
html[data-foto] #bs-chao .plat{
  top:auto!important; bottom:6%!important;
  height:17%!important; width:43%!important;
}
html[data-foto] #bs-chao .plat.esq{ left:0%!important;  right:auto!important }
html[data-foto] #bs-chao .plat.dir{ right:0%!important; left:auto!important }
html[data-foto] #battle-stage{ animation:none!important }

/* ---------------------------------------------------------------------
   O ROTULO TEM QUE SER LEGIVEL SOBRE O DESENHO

   Nome e barra de vida ficam acima da cabeca do inimigo, e numa fileira
   em coluna eles caem inevitavelmente sobre o corpo de quem esta atras.
   Sombra de texto sozinha nao resolve quando o fundo e um dragao
   vermelho aceso. Uma placa escura, com recorte suave e sem contorno
   duro, devolve a leitura sem virar caixa.
   --------------------------------------------------------------------- */
#battle-stage .sprite .nm{
  position:relative;padding:1px 7px 2px;
  isolation:isolate;
}
#battle-stage .sprite .nm::before{
  content:'';position:absolute;inset:-1px -2px;z-index:-1;
  background:radial-gradient(ellipse at 50% 50%,
    rgba(5,5,10,.9) 0%, rgba(5,5,10,.72) 58%, transparent 88%);
}
/* A intencao ja tem fundo proprio; so precisava sair da frente do corpo. */
#battle-stage .enemy-intent{background:#05050ff2;border-color:rgba(244,194,73,.6)}

/* Nome comprido de chefe ("Vyrakos, The Ancient Flame") empurrava a
   intencao para cima do sprite. Duas linhas no maximo, e o resto corta. */
#battle-stage .sprite .nm{
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
  overflow:hidden;
}

/* =====================================================================
   EXPLORAÇÃO DE CIDADE E CÉDULA DA MESA
   A pauta usa o mesmo botão .choice das escolhas de cena — o que muda é o
   cabeçalho que a apresenta e a cédula que mostra de quem é a vez.
   ===================================================================== */
.pauta-cab{border:1px solid var(--line2);border-left:3px solid var(--gold);border-radius:8px;
  padding:10px 13px;margin-bottom:10px;background:linear-gradient(90deg,#14100333,transparent)}
.pauta-cab>b{display:block;color:var(--gold);font-size:13.5px;letter-spacing:.05em;margin-bottom:3px}
.pauta-cab>span{display:block;color:var(--txt2);font-size:12.5px;line-height:1.6}
.pauta-cab>span b{display:inline;color:var(--gold);font-size:inherit;letter-spacing:0}
.pauta-cab.livre{border-left-color:var(--veil);background:linear-gradient(90deg,#04141733,transparent)}
.pauta-cab.livre>b{color:var(--veil)}

.cedula-local{display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  border:1px dashed var(--line2);border-radius:8px;padding:8px 11px;margin-bottom:10px;
  background:#07070d}
.cedula-local .cedula-t{font-size:9.5px;letter-spacing:.18em;color:var(--txt3);
  text-transform:uppercase;margin-right:4px}
.cedula-local .ficha{font-size:11.5px;color:var(--txt3);border:1px solid var(--line2);
  border-radius:999px;padding:3px 9px;white-space:nowrap}
.cedula-local .ficha.votou{color:var(--ok);border-color:#1c4a2e}
.cedula-local .ficha.vez{color:var(--gold);border-color:var(--gold);
  box-shadow:0 0 0 2px #b9891522;animation:cedula-pulsa 1.4s ease-in-out infinite}
.cedula-local .cedula-x{flex:1;text-align:right;font-size:11px;color:var(--txt3);font-style:italic}
@keyframes cedula-pulsa{0%,100%{opacity:1}50%{opacity:.55}}

.choice.pauta .n{background:#0b0b14;color:var(--txt2)}
.choice.livre{border-style:dashed}
.choice.livre .n{background:#05050a}

#chip-jornada .jornada-pips{letter-spacing:.12em;color:var(--gold)}

/* ---------------------------------------------------------------------
   COMBO: OS DOIS HEROIS APARECEM

   Um combo e a unica jogada que exige DUAS pessoas, e ate agora ele era
   visualmente igual a um golpe comum. O palco escurece, os dois
   envolvidos ficam acesos, e cada um entra na sua vez.
   --------------------------------------------------------------------- */
#battle-stage.combo-foco .sprite{
  filter:brightness(.2) saturate(.28) blur(1.1px);
  transition:filter .28s ease;
}
#battle-stage.combo-foco .sprite.em-combo{
  filter:none;
  z-index:60!important;
}
/* O halo mora no boneco, nao numa caixa atras dele -- caixa retangular
   sobre sprite recortado ja nos custou uma rodada de retrabalho. */
/* O halo precisa vencer sprites escuros -- o Tide Knight e azul-noite e
   sumia num brilho suave. Duas sombras coloridas mais uma branca fina
   destacam a silhueta contra qualquer fundo. */
#battle-stage.combo-foco .sprite.em-combo .spr{
  filter:drop-shadow(0 0 3px #fff)
         drop-shadow(0 0 16px var(--c, #fff))
         drop-shadow(0 0 34px color-mix(in srgb, var(--c,#fff) 75%, transparent))
         brightness(1.28) saturate(1.15);
  animation:comboPulsa .42s ease-in-out 5;
}
@keyframes comboPulsa{ 50%{ transform:translateY(-5px) scale(1.06) } }

/* O chao sob os dois acende junto: e o que amarra a dupla como uma coisa
   so, em vez de dois bonecos iluminados por acaso. */
#battle-stage.combo-foco .sprite.em-combo .body::after{
  background:radial-gradient(ellipse at 50% 50%,
    color-mix(in srgb, var(--c,#fff) 55%, transparent) 0%,
    color-mix(in srgb, var(--c,#fff) 22%, transparent) 48%, transparent 76%);
  height:16%;width:88%;
}
#battle-stage.combo-foco::after{
  background:radial-gradient(ellipse at 50% 62%, transparent 18%, rgba(2,3,9,.86) 88%);
}
@media(prefers-reduced-motion:reduce){
  #battle-stage.combo-foco .sprite.em-combo .spr{animation:none}
}

/* ---------------------------------------------------------------------
   CONFIRMAR A LEITURA

   O jogo avancava sozinho quando a datilografia terminava, e com o
   narrador desligado isso era instantaneo -- ninguem terminava de ler.
   Agora ha um botao, e ele precisa PARECER o proximo passo obvio, senao
   a mesa fica esperando algo que ja esta na tela.
   --------------------------------------------------------------------- */
#continuar-leitura{
  /* Contexto de empilhamento proprio: sem isto o botao fica na camada de
     elementos nao-posicionados e QUALQUER absolute do painel passa na
     frente dele. Cinto e suspensorio junto com o pointer-events da arte. */
  position:relative;z-index:3;
  display:flex;flex-direction:column;align-items:center;gap:2px;
  margin:18px auto 6px;padding:11px 26px;
  border:1px solid var(--gold);border-radius:8px;
  background:linear-gradient(145deg,#1a1509,#0d0b06);
  color:var(--gold);cursor:pointer;
  font:600 14px/1.2 Georgia,serif;letter-spacing:.04em;
  box-shadow:0 6px 22px -8px #000, inset 0 1px 0 #ffffff14;
  animation:leituraChama 2.1s ease-in-out infinite;
}
#continuar-leitura i{
  font:400 10px/1.2 var(--sans);font-style:normal;
  color:var(--txt3);letter-spacing:.02em;
}
#continuar-leitura:hover{
  background:linear-gradient(145deg,#241c0c,#12100a);
  transform:translateY(-1px);animation:none;
}
/* Pulsa devagar: chama o olho sem competir com o texto que esta sendo lido. */
@keyframes leituraChama{
  50%{ box-shadow:0 6px 22px -8px #000, 0 0 0 3px color-mix(in srgb,var(--gold) 18%,transparent),
       inset 0 1px 0 #ffffff14 }
}
@media(prefers-reduced-motion:reduce){ #continuar-leitura{animation:none} }

/* O objetivo de missao e informacao, nao botao: sem cursor de clique e
   sem realce de hover, para ninguem tentar resolver a missao por ali. */
.quest .step{cursor:default}
.quest .step:hover{background:none}

/* Escolha de conversa ja tentada: continua visivel, para a mesa lembrar do
   que fez, mas sem convidar ao clique. */
.choice.esgotada{opacity:.42;cursor:not-allowed;filter:saturate(.4)}
.choice.esgotada:hover{transform:none;border-color:var(--line)}

/* ---------------------------------------------------------------------
   INVESTIDA

   O corpo sai do lugar, chega, bate e volta. A ida e rapida e a volta e
   mais lenta -- quem ataca avanca com intencao e recua com o peso do
   golpe. A curva de saida estica um pouco no fim para dar a impressao de
   que o corpo passou do ponto no impacto.
   --------------------------------------------------------------------- */
.sprite.investindo{
  animation:investida .56s cubic-bezier(.22,.9,.28,1) both;
  will-change:transform;
}
@keyframes investida{
  0%   { transform:translate(0,0) }
  34%  { transform:translate(var(--inv-x,0), var(--inv-y,0)) scale(1.04) }
  44%  { transform:translate(calc(var(--inv-x,0px) * 1.06), var(--inv-y,0)) scale(1.02) }
  100% { transform:translate(0,0) }
}
/* Rastro curto atras de quem avanca: sem ele o corpo teleporta em vez de
   percorrer. */
.sprite.investindo .spr{
  filter:drop-shadow(calc(var(--inv-x,0px) * -0.06) 0 5px rgba(0,0,0,.45));
}
@media(prefers-reduced-motion:reduce){
  .sprite.investindo{animation:lunge .3s ease both}
}

/* Icone de item recortado da camada do equipamento: pixel art, entao
   nunca suavizar, e alinhado ao texto como um emoji estaria. */
.ico-item{
  image-rendering:pixelated;
  vertical-align:-0.28em;
  filter:drop-shadow(0 1px 2px #000a);
}

/* No modo foto congelado, NADA pulsa. A agua de Aqualis, as fissuras de
   Drakoria e o respiro de Nocthera sao animacao de CSS: sem parar elas, a
   mesma cena fotografada duas vezes difere e a regressao visual vira
   ruido. So vale com data-congelado, que so o modo foto liga. */
/* `animation-play-state:paused` e nao `animation:none`. Tentei `none`
   achando que zerar seria mais deterministico que pausar -- e MEDI: ficou
   pior, as duas cenas passaram a oscilar em quase toda rodada. `none`
   remove tambem os estilos que a animacao aplicava, e varios elementos
   dependem deles para ficarem no lugar. Pausar preserva o layout. */
html[data-congelado] *,
html[data-congelado] *::before,
html[data-congelado] *::after{
  animation-play-state:paused!important;
  transition:none!important;
}
