:root{
  /* ================= forge palette =====================================
     Warm iron, oiled wood, worn leather and parchment lit by one ember-
     coloured light source. Rarity is read from trim + a restrained glow,
     never from a wall of neon. ======================================== */
  --iron1:#5a6270; --iron2:#3a4149; --iron3:#23282e;
  --char1:#2b2620; --char2:#1c1811; --char3:#100d09;
  --wood1:#6b4b2c; --wood2:#4a331d; --wood3:#2e2012;
  --leath1:#6b4a30; --leath2:#4a3320;
  --parch1:#efe3c4; --parch2:#ddcb9e; --parch3:#c9b483;
  --ink:#2a2016; --ink2:#5a4a36; --ink-soft:#7a6a54;

  --ember:#e0752a; --ember2:#a8480f; --ember-lt:#ffb066;
  --steel:#5c8bb0; --steel2:#33587a;
  --moss:#5c9a54; --moss2:#33641f;
  --rust:#b8503a; --rust2:#7c2c1c;
  --gold:#dcaa3e; --gold2:#a87516;

  --r0:#9a9186; --r1:#4f8fd1; --r2:#9463d6; --r3:#dba33a; --r4:#e2653f; --r5:#d1568f;
  --safe-b:env(safe-area-inset-bottom,0px);
}
*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html,body{height:100%}
body{margin:0;color:var(--parch1);font-family:'Work Sans',system-ui,sans-serif;font-size:15px;line-height:1.35;
  font-weight:500;-webkit-font-smoothing:antialiased;overscroll-behavior:none;background:var(--char3)}
h1,h2,h3{margin:0;font-weight:600;font-family:'Cinzel',Georgia,serif;letter-spacing:.02em}
button{font:inherit;font-weight:600;color:inherit;border:none;background:none;cursor:pointer;padding:0}
button:focus-visible{outline:3px solid var(--ember-lt);outline-offset:2px}
button:disabled{filter:saturate(.3) brightness(.8);cursor:not-allowed}
.num{font-variant-numeric:tabular-nums;font-weight:600}
.aicon{display:inline-block;vertical-align:middle;object-fit:contain}
.glyph{display:inline-block;vertical-align:middle;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;
  -webkit-mask-position:center;mask-position:center;-webkit-mask-size:contain;mask-size:contain}

/* ================= boot splash: up first, gone last ======================= */
.bootsplash{position:fixed;inset:0;z-index:9999;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:20px;
  background:radial-gradient(120% 60% at 50% 100%,#3a2414 0%,var(--char2) 46%,var(--char3) 100%);
  transition:opacity .45s ease;opacity:1}
.bootsplash.hide{opacity:0;pointer-events:none}
.bootmark{width:78px;height:78px;display:flex;align-items:center;justify-content:center;
  box-shadow:0 10px 26px rgba(0,0,0,.55);border-radius:50%}
.bootmark img{width:100%;height:100%;filter:drop-shadow(0 0 8px rgba(255,176,102,.5))}
.boottitle{font-family:'Cinzel',Georgia,serif;font-size:30px;letter-spacing:.07em;color:var(--parch1);
  text-shadow:0 2px 10px rgba(0,0,0,.6);margin:0}
.boottitle span{color:var(--ember-lt)}
.bootbar{width:150px;height:5px;border-radius:3px;background:rgba(255,255,255,.12);overflow:hidden}
.bootbar i{display:block;width:40%;height:100%;border-radius:3px;
  background:linear-gradient(90deg,transparent,var(--ember-lt),transparent);
  animation:bootsweep 1.1s ease-in-out infinite}
@keyframes bootsweep{0%{transform:translateX(-130%)}100%{transform:translateX(370%)}}

/* a thin sweep at the very top of the viewport for any in-flight callEdge()
   call (js/00-api.js) — boot uses it too, but it's general-purpose */
.loadingbar{position:fixed;left:0;top:0;width:100%;height:3px;z-index:9500;pointer-events:none;
  overflow:hidden;opacity:0;transition:opacity .2s ease}
.loadingbar.on{opacity:1}
.loadingbar i{display:block;width:34%;height:100%;
  background:linear-gradient(90deg,transparent,var(--ember-lt),transparent);
  animation:loadsweep 1s linear infinite}
@keyframes loadsweep{0%{transform:translateX(-120%)}100%{transform:translateX(390%)}}

/* a whisper of grain baked into the same background layer as the ambient glow
   so flat CSS gradients read as forged metal/leather rather than vector fill —
   a background layer, not an overlay element, so it can't disturb stacking */
#app{max-width:520px;margin:0 auto;min-height:100%;position:relative;display:flex;flex-direction:column;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='90' height='90'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.05'/%3E%3C/svg%3E"),
    radial-gradient(120% 60% at 50% 100%,#3a2414 0%,var(--char2) 46%,var(--char3) 100%);
  background-attachment:fixed,fixed}

/* ================= panels: forged iron plate, riveted cap ================ */
.panel{position:relative;background:linear-gradient(180deg,#2f2a23,#211c17);border:2px solid var(--char3);
  border-radius:12px;box-shadow:0 5px 0 rgba(0,0,0,.4),0 10px 16px rgba(0,0,0,.35),inset 0 1px 0 rgba(255,255,255,.04);
  margin-bottom:14px;overflow:hidden}
.panel>.ph{position:relative;padding:10px 16px;display:flex;align-items:center;gap:9px;
  color:var(--parch1);text-shadow:0 1px 2px rgba(0,0,0,.6);border-bottom:2px solid var(--char3);
  background:linear-gradient(180deg,var(--iron1) 0,var(--iron2) 100%)}
.panel>.ph::before{content:"";position:absolute;left:0;right:0;top:0;height:42%;
  background:linear-gradient(180deg,rgba(255,255,255,.12),transparent)}
.panel>.ph h2{font-size:16px;margin-right:auto;position:relative;display:flex;align-items:center;gap:8px}
.panel>.ph>.btn{position:relative}
.panel.org>.ph h2::before,.panel.grn>.ph h2::before,.panel.pur>.ph h2::before,
.panel.gold>.ph h2::before,.panel.info>.ph h2::before,.panel.chat>.ph h2::before{
  content:"";flex:none;width:18px;height:18px;background:currentColor;opacity:.92;
  -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-position:center;mask-position:center;
  -webkit-mask-size:contain;mask-size:contain;filter:drop-shadow(0 1px 1px rgba(0,0,0,.4))}
.panel.org>.ph{background:linear-gradient(180deg,var(--ember),var(--ember2))}
.panel.org>.ph h2::before{-webkit-mask-image:url(../assets/resources/tabclan.svg);mask-image:url(../assets/resources/tabclan.svg)}
.panel.grn>.ph{background:linear-gradient(180deg,var(--moss),var(--moss2))}
.panel.grn>.ph h2::before{-webkit-mask-image:url(../assets/resources/tabdungeons.svg);mask-image:url(../assets/resources/tabdungeons.svg)}
.panel.pur>.ph{background:linear-gradient(180deg,#7a5cae,#4c3778)}
.panel.pur>.ph h2::before{-webkit-mask-image:url(../assets/resources/tableague.svg);mask-image:url(../assets/resources/tableague.svg)}
.panel.gold>.ph{background:linear-gradient(180deg,var(--gold),var(--gold2));color:#3a2606}
.panel.gold>.ph h2::before{-webkit-mask-image:url(../assets/resources/tabshop.svg);mask-image:url(../assets/resources/tabshop.svg)}
.panel.info>.ph{background:linear-gradient(180deg,var(--steel),var(--steel2))}
.panel.info>.ph h2::before{-webkit-mask-image:url(../assets/resources/tabranking.svg);mask-image:url(../assets/resources/tabranking.svg)}
.panel.chat>.ph{background:linear-gradient(180deg,#3fa8a0,#1f6b66)}
.panel.chat>.ph h2::before{-webkit-mask-image:url(../assets/resources/tabchat.svg);mask-image:url(../assets/resources/tabchat.svg)}
.pb{padding:14px;position:relative;background:linear-gradient(180deg,#292420 0,#221d19 100%)}
.pb::before{content:"";position:absolute;left:0;right:0;top:0;height:8px;
  background:linear-gradient(180deg,rgba(255,255,255,.06),transparent);pointer-events:none}

/* ================= buttons: tactile, forged, one light source ============ */
.btn{position:relative;display:inline-flex;align-items:center;justify-content:center;gap:7px;
  padding:11px 18px;border-radius:10px;border:2px solid var(--char3);overflow:hidden;
  background:linear-gradient(180deg,#4a423a,#332c26);color:var(--parch1);
  box-shadow:0 4px 0 #1a1611;font-size:14.5px;white-space:nowrap;
  transition:transform .06s ease,box-shadow .06s ease}
.btn::before{content:"";position:absolute;left:8%;right:8%;top:2px;height:22%;border-radius:99px;
  background:rgba(255,255,255,.12);pointer-events:none}
.btn:active:not(:disabled){transform:translateY(4px);box-shadow:0 0 0 #1a1611}
.btn.go{background:linear-gradient(180deg,#6ba85f,var(--moss2));color:#f2ead2;box-shadow:0 4px 0 #1f3c14;text-shadow:0 1px 1px rgba(0,0,0,.3)}
.btn.go:active:not(:disabled){box-shadow:0 0 0 #1f3c14}
.btn.pri{background:linear-gradient(180deg,#ef8a3e,var(--ember2));color:#fff3e2;box-shadow:0 4px 0 #6e340a;text-shadow:0 1px 1px rgba(0,0,0,.32)}
.btn.pri:active:not(:disabled){box-shadow:0 0 0 #6e340a}
.btn.info{background:linear-gradient(180deg,#6fa2c4,var(--steel2));color:#f0f6fa;box-shadow:0 4px 0 #1e3247;text-shadow:0 1px 1px rgba(0,0,0,.3)}
.btn.info:active:not(:disabled){box-shadow:0 0 0 #1e3247}
.btn.bad{background:linear-gradient(180deg,#c96952,var(--rust2));color:#fdf0ea;box-shadow:0 4px 0 #4a1810}
.btn.sm{padding:7px 13px;font-size:13px;border-width:1.5px;border-radius:8px;box-shadow:0 3px 0 #1a1611}
.btn.sm.go{box-shadow:0 3px 0 #1f3c14}.btn.sm.pri{box-shadow:0 3px 0 #6e340a}
.btn.sm.info{box-shadow:0 3px 0 #1e3247}.btn.sm.bad{box-shadow:0 3px 0 #4a1810}
.btn.wide{width:100%}

/* ================= top bar: dark oiled wood ============================== */
.top{position:sticky;top:0;z-index:40;display:flex;gap:8px;padding:10px 12px;
  background:linear-gradient(180deg,var(--wood1) 0,var(--wood2) 55%,var(--wood3) 100%);
  border-bottom:3px solid var(--char3);box-shadow:0 5px 14px rgba(0,0,0,.4)}
.res{position:relative;flex:1;min-width:0;display:flex;align-items:center;padding:5px 11px 5px 34px;
  border-radius:999px;background:linear-gradient(180deg,#241a10,#150f09);border:2px solid var(--char3)}
.res .ic{position:absolute;left:-2px;top:50%;margin-top:-16px;width:32px;height:32px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;border:2px solid var(--char3);
  background:radial-gradient(circle at 34% 26%,#4a3620,#1e150c)}
.res .ic .aicon,.res .ic svg{width:19px;height:19px}
.res .v{font-size:14px;color:var(--parch1);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  text-shadow:0 1px 2px rgba(0,0,0,.7)}
.pulse{animation:pulse .36s cubic-bezier(.2,1.6,.4,1)}
@keyframes pulse{0%{transform:scale(1)}40%{transform:scale(1.25)}100%{transform:scale(1)}}

.page{display:none;padding:14px 12px 0}
.page.on{display:block;animation:pagein .22s ease}
@keyframes pagein{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
.pad{padding-bottom:calc(86px + var(--safe-b))}

/* ================= battle scene =========================================== */
.arena{position:relative;overflow:hidden;margin-bottom:0;background:var(--char3)}
/* :not(svg svg) — only the scene's own svg: the fighters are drawn as crops
   in nested svgs, and sizing those to 100% squashed the hero and foe flat */
.arena svg:not(svg svg){display:block;width:100%;height:auto}
/* #scene has no intrinsic height of its own — without this it collapses to
   the svg's fixed aspect-ratio height and leaves the rest of a taller arena
   as empty black space. Absolutely filling the arena plus the scene's own
   xMidYMax "slice" (see buildScene() in js/05-combat.js) makes the
   background genuinely cover whatever height the arena grows to, cropping
   width instead of letterboxing. */
#scene{position:absolute;inset:0;z-index:1}
.hpstrip{position:absolute;left:8px;right:8px;top:9px;display:flex;gap:6px;pointer-events:none;z-index:2}
.hpseg{flex:1;height:13px;border-radius:6px;background:linear-gradient(180deg,#150f09,#1c1811);overflow:hidden;
  border:1.5px solid rgba(0,0,0,.75);box-shadow:0 2px 3px rgba(0,0,0,.5),0 1px 0 rgba(255,255,255,.06) inset}
.hpseg>i{display:block;height:100%;width:100%;transition:width .18s linear;border-radius:6px;position:relative}
.hpseg>i::after{content:"";position:absolute;left:0;right:0;top:0;height:45%;background:rgba(255,255,255,.22);border-radius:6px 6px 0 0}
.hpseg.me>i{background:linear-gradient(180deg,#a0f088,var(--moss2));box-shadow:0 0 8px rgba(140,220,120,.6)}
.hpseg.foe>i{background:linear-gradient(180deg,#ff9878,var(--rust2));box-shadow:0 0 8px rgba(255,110,80,.55)}

.fx{position:absolute;inset:0;pointer-events:none;overflow:hidden;z-index:3}
.pop{position:absolute;font-weight:700;font-size:19px;pointer-events:none;white-space:nowrap;
  text-shadow:-2px 0 #000,2px 0 #000,0 -2px #000,0 2px #000,
              -2px -2px #000,2px -2px #000,-2px 2px #000,2px 3px #000}
.pop.big{font-size:29px}
.pwrdelta{position:fixed;z-index:70;transform:translateX(-50%);font-weight:800;font-size:15px;
  pointer-events:none;white-space:nowrap;
  text-shadow:-1.5px 0 #000,1.5px 0 #000,0 -1.5px #000,0 1.5px #000,0 2px 4px rgba(0,0,0,.6)}
.pwrdelta.up{color:#a0f088}
.pwrdelta.dn{color:#ff8a6a}
.spark{position:absolute;width:9px;height:9px;border-radius:50%;pointer-events:none;
  border:2px solid rgba(0,0,0,.6)}
.ring{position:absolute;border-radius:50%;border:4px solid #fff;pointer-events:none}
.banner{position:absolute;left:0;right:0;top:26%;text-align:center;font-size:32px;font-weight:700;
  font-family:'Cinzel',Georgia,serif;pointer-events:none;text-shadow:-3px 0 #000,3px 0 #000,0 -3px #000,0 3px #000,
              -3px -3px #000,3px -3px #000,-3px 3px #000,3px 6px #000}
.flyer{position:fixed;z-index:55;pointer-events:none}
/* ================= skill-cast flourishes ================================= */
.slashfx{position:absolute;height:6px;border-radius:3px;pointer-events:none;
  background:linear-gradient(90deg,rgba(255,255,255,0),rgba(255,255,255,.95),rgba(255,255,255,0));
  filter:drop-shadow(0 0 5px rgba(255,255,255,.7))}
.beamfx{position:absolute;pointer-events:none;border-radius:6px}
.windfx{position:absolute;height:3px;border-radius:2px;pointer-events:none;
  background:linear-gradient(90deg,transparent,#fff,transparent)}
.pulsefx{position:absolute;border-radius:50%;border:3px solid;box-sizing:border-box;pointer-events:none}
.castSigil{position:absolute;width:46px;height:46px;border:2px solid var(--skill-fx);border-radius:50%;
  display:grid;place-items:center;pointer-events:none;background:radial-gradient(circle,#171a38cc 30%,transparent 72%);
  box-shadow:0 0 9px var(--skill-fx),inset 0 0 9px var(--skill-fx)}
.castSigil::before,.castSigil::after{content:"";position:absolute;inset:4px;border:1px solid var(--skill-fx);
  border-radius:8px;transform:rotate(45deg);opacity:.7}.castSigil::after{inset:10px;border-radius:50%;transform:none;opacity:.35}
.castSigil .castGlyph{position:relative;z-index:1;filter:drop-shadow(0 0 4px var(--skill-fx))}
.skillParticle{position:absolute;border-radius:50%;pointer-events:none}

/* ================= stage header: floats on the scene ===================== */
.stagehead{position:absolute;left:0;right:0;top:22px;z-index:2;display:flex;align-items:center;
  justify-content:center;gap:10px;pointer-events:none}
.stagemid{text-align:center;min-width:120px;padding:4px 16px 6px;border-radius:10px;
  background:linear-gradient(180deg,rgba(16,13,9,.5),rgba(16,13,9,.28));
  box-shadow:0 2px 6px rgba(0,0,0,.3)}
.stagemid b{display:block;font-size:19px;line-height:1.15;color:#fff3e2;font-family:'Cinzel',Georgia,serif;
  text-shadow:0 2px 4px rgba(0,0,0,.85)}
.stagemid span{display:block;font-size:10.5px;letter-spacing:.03em;color:var(--ember-lt);
  text-shadow:0 1.5px 3px rgba(0,0,0,.9)}
@keyframes pipnow{0%,100%{transform:scale(1)}50%{transform:scale(1.3)}}

/* ================= skills ================================================= */
.skillrow{display:flex;gap:8px;margin-bottom:8px}
.sk{flex:1;position:relative;overflow:hidden;height:50px;border-radius:10px;border:2px solid var(--char3);
  background:linear-gradient(180deg,#43392c,#2c241c);box-shadow:0 4px 0 #17130f;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px}
.sk::before{content:"";position:absolute;left:8%;right:8%;top:2px;height:20%;border-radius:99px;
  background:rgba(255,255,255,.1);pointer-events:none}
.sk:active:not(:disabled){transform:translateY(4px);box-shadow:none}
.sk .cdfill{position:absolute;left:0;right:0;bottom:0;background:rgba(0,0,0,.62);pointer-events:none}
.sk .nm{position:relative;font-size:10.5px;line-height:1.05;text-align:center;padding:0 3px;color:var(--parch2)}
.sk svg,.sk .glyph{position:relative}
.sk .skillIconGlyph{filter:drop-shadow(0 1px 0 #080b18) drop-shadow(0 0 5px currentColor);
  transition:transform .18s ease,filter .18s ease}
.sk:hover .skillIconGlyph,.sk:focus-visible .skillIconGlyph{transform:scale(1.12) rotate(-4deg)}
.sk:active:not(:disabled) .skillIconGlyph{transform:scale(.88) rotate(7deg)}
.sk.rdy{background:linear-gradient(180deg,#5a4a30,#7a5c26);animation:skrdy 1.5s ease-in-out infinite}
.sk.rdy .skillIconGlyph{animation:skillready 1.5s ease-in-out infinite}
@keyframes skrdy{0%,100%{box-shadow:0 4px 0 #17130f}50%{box-shadow:0 4px 0 #17130f,0 0 12px 2px rgba(224,117,42,.65)}}
@keyframes skillready{0%,100%{transform:scale(1)}50%{transform:scale(1.12);filter:drop-shadow(0 0 8px currentColor)}}
.sk.empty{background:linear-gradient(180deg,#3a3226,#2a241c);border-style:dashed;border-color:var(--ink-soft)}
.sk.empty .nm{color:var(--parch1);font-weight:600}
.sk.empty::after{content:"+";position:absolute;right:5px;top:2px;font-size:14px;font-weight:800;color:var(--ember-lt);
  text-shadow:0 1px 2px rgba(0,0,0,.6)}
.sk.locked{background:repeating-linear-gradient(45deg,#241f19,#241f19 8px,#1c1812 8px,#1c1812 16px);opacity:.75}
.sk.locked .nm{color:var(--ink-soft)}

/* ================= equipment: plain grid, no card chrome ================= */
.eqwrap{position:relative;padding-top:4px;margin-bottom:8px}
.gearwrap{display:grid;grid-template-columns:repeat(6,1fr);gap:6px}
.mats{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}
.mat{display:inline-flex;align-items:center;gap:5px;font-size:12px;padding:4px 10px;border-radius:999px;
  background:#332c24;border:1.5px solid var(--char3);color:var(--parch2)}
.mat b{font-weight:600;color:var(--parch1)}
.sockdot{position:absolute;left:5px;bottom:18px;width:11px;height:11px;border-radius:50%;
  border:2px solid var(--char3);z-index:2}
.sockdot.empty{background:#2a221a;box-shadow:inset 0 2px 2px rgba(0,0,0,.6)}
.slot .role{position:absolute;left:4px;top:10px;width:7px;height:7px;border-radius:50%;
  border:1.5px solid var(--char3);z-index:2}
.slot.lit{box-shadow:0 4px 0 #17130f,0 0 12px 2px var(--glow)}
.gemdot{width:26px;height:26px;flex:none;border-radius:50%;border:2px solid var(--char3);
  box-shadow:inset -3px -3px 0 rgba(0,0,0,.35),inset 3px 3px 0 rgba(255,255,255,.18)}
.itemframe{position:relative;width:70px;height:70px;flex:none;border-radius:12px;
  border:2px solid var(--char3);display:flex;align-items:center;justify-content:center;
  overflow:hidden;background:linear-gradient(180deg,#463c30,#2e2620);
  box-shadow:0 4px 0 rgba(0,0,0,.4)}
.itemframe .sockdot{left:6px;bottom:6px;width:14px;height:14px}
/* percentage width/height on an <img> inside a centered flex box doesn't
   resolve reliably here (replaced-element/flex sizing quirk) — position it
   absolutely instead so the percentage resolves against the box itself */
.itemframe .aicon{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:88%;height:88%}
.prot{display:flex;gap:8px;align-items:center;margin-top:9px;font-size:12.5px;color:var(--parch2)}
.prot input{accent-color:var(--ember);width:17px;height:17px}
.slot{position:relative;aspect-ratio:1;border-radius:10px;border:2px solid var(--char3);overflow:hidden;
  background:linear-gradient(180deg,#463c30,#2e2620);box-shadow:0 3px 0 #17130f;
  display:flex;flex-direction:column;align-items:center;justify-content:center;padding:5px 3px 0}
.slot .aicon{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:84%;height:84%}
.slot::before{content:"";position:absolute;left:10%;right:10%;top:6px;height:16%;border-radius:99px;
  background:rgba(255,255,255,.1);pointer-events:none}
.slot:active:not(:disabled){transform:translateY(3px);box-shadow:none}
.slot .band,.itemframe .band{position:absolute;left:0;right:0;top:0;height:5px;background:var(--r0);
  border-bottom:1.5px solid rgba(0,0,0,.5);z-index:1}
.slot .val{position:absolute;left:0;right:0;bottom:0;padding:2px 0 3px;font-size:10px;font-weight:600;
  background:rgba(0,0,0,.55);color:var(--parch1)}
.slot .lv{position:absolute;right:3px;top:9px;font-size:10px;color:#f2ead2;
  background:linear-gradient(180deg,#6ba85f,var(--moss2));border:1.5px solid var(--char3);border-radius:6px;
  padding:0 4px;line-height:1.3;z-index:2}
.slot .sn{font-size:9.5px;line-height:1.05;color:var(--parch2);text-align:center;padding-bottom:5px}
.slot .ghost{opacity:.32}
/* rarity trim reads through a thin top-band colour (see .band above) plus a
   restrained material shift per tier — no per-rarity neon backgrounds */
.slot.f1{background:linear-gradient(180deg,#3c4a54,#28333c)}
.slot.f2{background:linear-gradient(180deg,#463a54,#2e2638)}
.slot.f3{background:linear-gradient(180deg,#4a4230,#332c1e);box-shadow:0 3px 0 #17130f,inset 0 0 0 1px rgba(219,163,58,.35)}
.slot.f4{background:linear-gradient(180deg,#4a362c,#331f18);box-shadow:0 3px 0 #17130f,inset 0 0 0 1px rgba(226,101,63,.4)}
.slot.f5{background:linear-gradient(180deg,#463040,#2e1e2a);box-shadow:0 3px 0 #17130f,inset 0 0 0 1px rgba(209,86,143,.45)}
.slot.new{animation:slotnew .5s cubic-bezier(.2,1.7,.4,1)}
@keyframes slotnew{0%{transform:scale(1)}35%{transform:scale(1.16) rotate(-3deg)}100%{transform:scale(1)}}

/* ================= forge: one anvil, a level badge riding its corner, auto = */
.forgerow{display:flex;align-items:stretch;gap:8px}
.anvilwrap{flex:1;min-width:0;position:relative;display:flex}
.anvilbtn{flex:1;min-width:0;display:flex;flex-direction:column;align-items:center;position:relative;
  border-radius:10px;border:2px solid var(--char3);background:linear-gradient(180deg,#463c30,#2e2620);
  box-shadow:0 4px 0 #17130f;overflow:hidden;padding:0}
.anvilbtn:active:not(:disabled){transform:translateY(4px);box-shadow:none}
.anvilbtn .anvil{width:100%;height:42px;position:relative;
  background:radial-gradient(120% 140% at 50% 108%,rgba(255,122,45,.24),transparent 62%),
             linear-gradient(180deg,#3a2e22,#1c140e);
  box-shadow:inset 0 2px 5px rgba(0,0,0,.5),inset 0 -1px 0 rgba(255,255,255,.05)}
.anvilbtn .anvil svg{display:block;width:100%;height:100%}
.anvilbtn .flash{position:absolute;inset:0;opacity:0;pointer-events:none}
.anvilbtn .cdfill{position:absolute;left:0;top:0;bottom:0;width:0;background:rgba(0,0,0,.42);z-index:1}
.hamcount{display:flex;align-items:center;justify-content:center;gap:6px;margin:4px 8px;padding:3px 10px;
  font-size:12.5px;color:var(--parch2);background:rgba(0,0,0,.28);border-radius:20px;
  border:1px solid rgba(255,255,255,.06)}
.hamcount .ic{width:15px;height:15px;display:flex}
.hamcount b{color:var(--gold);font-weight:700;font-size:13px}
/* rides the anvil's top-right corner instead of sitting beside it as its own
   button — one forge control, not two */
.forgelvl{position:absolute;top:-7px;right:-7px;z-index:2;flex:none;width:50px;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:3px;padding:5px 4px;border-radius:9px;border:2px solid var(--char3);
  background:linear-gradient(180deg,#6fa2c4,var(--steel2));box-shadow:0 3px 0 #1e3247;color:#f0f6fa;
  text-shadow:0 1px 1px rgba(0,0,0,.35)}
.forgelvl:active{transform:translateY(3px);box-shadow:none}
.forgelvl b{font-size:10px;line-height:1.15;text-align:center;font-family:'Work Sans',sans-serif}
.forgelvl .bar{width:100%;height:5px}
.forgelvl .dot{position:absolute;top:-4px;right:-4px;width:12px;height:12px;border-radius:50%;
  background:var(--rust);border:2px solid var(--char3);display:none}
.forgelvl.alert .dot{display:block;animation:pipnow 1.1s ease-in-out infinite}
.autobtn{flex:none;width:60px;display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:3px;border-radius:10px;border:2px solid var(--char3);font-size:11.5px;font-weight:600;
  background:linear-gradient(180deg,#463c30,#2e2620);box-shadow:0 4px 0 #17130f;color:var(--parch2)}
.autobtn.on{background:linear-gradient(180deg,#6ba85f,var(--moss2));color:#f2ead2;box-shadow:0 4px 0 #1f3c14;
  text-shadow:0 1px 1px rgba(0,0,0,.3)}
.autobtn:active{transform:translateY(4px);box-shadow:none}

/* ================= forge stack: undecided drops, newest pushed in on the
   left — tap one to equip/sell it, at which point it's gone (see
   markStackResolved in js/06-forge.js) ===================================== */
.foundrow{display:flex;flex-wrap:wrap;align-items:center;gap:6px;min-height:34px;
  max-height:112px;overflow-y:auto;margin-bottom:6px}
.foundrow:empty::before{content:"Strike the anvil — what you forge stacks up here";
  font-size:11px;color:var(--ink-soft);line-height:34px}
.foundrow .fitem{position:relative;flex:none;width:30px;height:30px;border-radius:8px;
  border:2px solid var(--char3);display:flex;align-items:center;justify-content:center;
  box-shadow:0 2px 0 rgba(0,0,0,.4),0 0 0 2px var(--gold);cursor:pointer;
  animation:fitemin .32s cubic-bezier(.2,1.7,.4,1)}
.foundrow .fitem:active{transform:translateY(2px)}
.foundrow .fitem img{width:19px;height:19px}
.foundrow .fitem .fa{position:absolute;right:-4px;bottom:-4px;width:13px;height:13px;border-radius:50%;
  border:1.5px solid var(--char3);display:flex;align-items:center;justify-content:center;
  font-size:8px;line-height:1;color:#fff;font-weight:700;background:var(--rust2)}
@keyframes fitemin{0%{opacity:0;transform:translateX(-16px) scale(.5)}100%{opacity:1;transform:none}}

.drop{display:flex;gap:12px;align-items:flex-start;padding:12px;border-radius:12px;
  background:linear-gradient(180deg,var(--parch1),var(--parch2));border:2px solid var(--ink2);margin-top:10px;
  box-shadow:0 4px 0 rgba(0,0,0,.3);color:var(--ink)}
.drop.in{animation:dropin .42s cubic-bezier(.2,1.7,.4,1)}
@keyframes dropin{0%{opacity:0;transform:translateY(16px) scale(.8)}60%{transform:translateY(-3px) scale(1.04)}100%{opacity:1;transform:none}}
.drop .nm{font-weight:600;font-size:15.5px}
.drop .meta{font-size:12px;color:var(--ink2)}
.acts{display:flex;gap:8px;margin-top:10px}
.acts .btn{flex:1}
.subline{display:flex;flex-wrap:wrap;gap:6px;margin-top:7px}
.tag{font-size:11.5px;padding:3px 9px;border-radius:8px;background:#332c24;border:1.5px solid var(--char3);color:var(--parch2)}
.tag.up{background:#274420;color:#bdeab0;border-color:#3a6430}.tag.dn{background:#4a2420;color:#f0b8ac;border-color:#6a342c}
.toggles{display:flex;gap:16px;flex-wrap:wrap;margin-top:8px;font-size:13px;color:var(--parch2)}
.toggles label{display:flex;gap:7px;align-items:center;cursor:pointer}
.toggles input{accent-color:var(--ember);width:18px;height:18px}
.chkrow{display:flex;align-items:center;gap:10px;padding:9px 4px;
  border-bottom:1.5px dotted rgba(255,255,255,.12);font-size:13.5px;cursor:pointer}
.chkrow:last-child{border-bottom:none}
.chkrow input{accent-color:var(--ember);width:18px;height:18px;flex:none}
.erarow{display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:9px;
  border:1.5px solid var(--char3);margin-bottom:6px;font-size:13px;cursor:pointer;background:#2e2822}
.erarow input{accent-color:var(--ember);width:18px;height:18px;flex:none}
.erarow span{flex:1;font-weight:600;color:var(--parch1)}
.erarow b{font-weight:700}
.stepperRow{display:flex;align-items:center;gap:10px}
.stepper{display:flex;align-items:center;gap:9px}
.stepper button{width:30px;height:30px;border-radius:8px;border:1.5px solid var(--char3);
  background:#3a322a;color:var(--parch1);font-weight:800;font-size:16px;box-shadow:0 3px 0 #17130f;flex:none}
.stepper button:active{transform:translateY(3px);box-shadow:none}
.stepper b{min-width:26px;text-align:center;font-size:15px}

/* ================= rows ================================================ */
.row{display:flex;gap:11px;align-items:center;padding:11px 11px 11px 13px;border-radius:11px;position:relative;
  background:linear-gradient(180deg,#372f26,#28221c);border:2px solid var(--char3);margin-bottom:11px;
  box-shadow:0 4px 0 rgba(0,0,0,.32),inset 0 1px 0 rgba(255,255,255,.04)}
.row::before{content:"";position:absolute;left:0;top:8%;bottom:8%;width:3px;border-radius:3px;
  background:linear-gradient(180deg,var(--ember-lt),var(--ember2));opacity:.55}
.row:last-child{margin-bottom:0}
.row .grow{flex:1;min-width:0}
.row .t1{font-weight:600;font-size:14.5px;color:var(--parch1)}
.row .t2{font-size:12px;color:var(--parch2);font-weight:400}
.lock{font-size:13px;color:var(--parch2);padding:13px;text-align:center;border-radius:11px;margin-bottom:11px;
  background:repeating-linear-gradient(45deg,#2e2822,#2e2822 10px,#262019 10px,#262019 20px);
  border:2px dashed var(--char3)}
.chip{display:inline-flex;align-items:center;gap:5px;font-size:12px;padding:4px 10px;border-radius:999px;
  background:#332c24;border:1.5px solid var(--char3);color:var(--parch2)}
.dicon{width:44px;height:44px;flex:none;border-radius:10px;border:2px solid var(--char3);
  display:flex;align-items:center;justify-content:center;box-shadow:0 3px 0 rgba(0,0,0,.5)}
.keys{display:flex;align-items:center;gap:4px;margin-top:5px}
.keypip{display:inline-flex;opacity:.24;filter:grayscale(1)}
.keypip.has{opacity:1;filter:none}
.keys .mini{margin-left:6px}

.statgrid{display:grid;grid-template-columns:1fr 1fr;gap:7px 14px;font-size:13px}
.statgrid div{display:flex;justify-content:space-between;gap:8px;padding:4px 0;
  border-bottom:1.5px dotted rgba(255,255,255,.12)}
.statgrid span{color:var(--parch2);font-weight:400}
.statgrid b{font-weight:600;color:var(--parch1)}
.sheet .statgrid span{color:var(--ink2)}
.sheet .statgrid b{color:var(--ink)}
.rar0{color:#8a8072}.rar1{color:#2f6fac}.rar2{color:#6f43ac}.rar3{color:#a1710e}
.rar4{color:#a8402f}.rar5{color:#a13c6c}
.meter{height:6px;border-radius:3px;background:rgba(0,0,0,.4);overflow:hidden;border:1px solid rgba(0,0,0,.4)}
.meter>i{display:block;height:100%;background:linear-gradient(180deg,#ef8a3e,var(--ember2))}
.sheet .meter{background:rgba(42,32,22,.18);border-color:rgba(42,32,22,.3)}
.mini{font-size:12.5px;color:var(--parch2);font-weight:400}
.mini,.lock{color:var(--parch2)}
.sheet .mini{color:var(--ink2)}
.tt{font-size:13.5px;margin:15px 0 8px;font-weight:600;color:var(--parch1);font-family:'Cinzel',Georgia,serif}

/* ================= drop odds: era > quality accordion ==================== */
.eraOdds{border-radius:11px;background:linear-gradient(180deg,#332c24,#28221c);
  border:2px solid var(--char3);margin-bottom:8px;overflow:hidden}
.eraOdds summary{list-style:none;cursor:pointer;padding:11px;display:flex;
  justify-content:space-between;gap:8px;font-weight:600;font-size:14px;color:var(--parch1)}
.eraOdds summary::-webkit-details-marker{display:none}
.eraOdds summary::after{content:'+';color:var(--parch2);font-weight:700}
.eraOdds[open] summary::after{content:'\2212'}
.eraOdds .pb2{padding:0 11px 11px}
.qualOdds summary{list-style:none;cursor:pointer;font-size:12px;font-weight:600;
  color:var(--parch2);padding:2px 0}
.qualOdds summary::-webkit-details-marker{display:none}
.sheet .eraOdds{background:linear-gradient(180deg,#efe2c0,#e6d6ac);border-color:var(--ink2)}
.sheet .eraOdds summary{color:var(--ink)}
.sheet .qualOdds summary{color:var(--ink2)}
.sheet .tt{color:var(--ink)}
.seg{display:flex;gap:8px;margin-bottom:14px}
.seg button{flex:1;padding:10px;border-radius:9px;border:2px solid var(--char3);font-size:13.5px;
  background:linear-gradient(180deg,#3a322a,#2a241e);box-shadow:0 4px 0 #17130f;color:var(--parch2)}
.seg button.on{background:linear-gradient(180deg,#ef8a3e,var(--ember2));color:#fff3e2;box-shadow:0 4px 0 #6e340a}
.seg button:active{transform:translateY(4px);box-shadow:none}
.logbox{max-height:150px;overflow:auto;font-size:12.5px;color:var(--parch2);font-weight:400}
.logbox div{padding:5px 0;border-bottom:1.5px dotted rgba(255,255,255,.12)}
.sheet .logbox,.sheet .logbox div{color:var(--ink2);border-bottom-color:rgba(0,0,0,.14)}

/* ================= world chat ============================================= */
.chatbox{max-height:min(52vh,440px);overflow-y:auto;display:flex;flex-direction:column;gap:2px}
.chatbox .row{padding:8px 9px}
.chatbox .row.me{background:rgba(224,117,42,.14)}
.chatrow{display:flex;gap:6px;align-items:baseline}
.chatname{font-weight:600;font-size:12.5px;color:var(--ember-lt)}
.chattime{font-size:10.5px;color:var(--parch2)}
.chatbody{font-size:14px;color:var(--parch1);word-break:break-word;margin-top:2px}

/* ================= tabs ================================================ */
.tabs{position:fixed;left:0;right:0;bottom:0;z-index:50;display:flex;max-width:520px;margin:0 auto;
  background:linear-gradient(180deg,var(--wood1),var(--wood3));border-top:3px solid var(--char3);
  padding:6px 6px calc(6px + var(--safe-b));gap:6px;box-shadow:0 -6px 16px rgba(0,0,0,.4)}
.tabs button{flex:1;padding:7px 2px 6px;display:flex;flex-direction:column;align-items:center;gap:3px;
  font-size:11px;color:#e8d3ae;position:relative;border-radius:9px;border:1.5px solid transparent}
.tabs button.on{color:#fff3e2;border-color:var(--char3);
  background:linear-gradient(180deg,#ef8a3e,var(--ember2));box-shadow:0 3px 0 rgba(0,0,0,.4)}
.tabs .clanflag{display:inline-flex;align-items:center;justify-content:center;width:21px;height:21px;border-radius:6px;
  border:2px solid rgba(17,10,6,.45);background:linear-gradient(135deg,var(--flag-a),var(--flag-b));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.35),inset 0 -2px 0 rgba(0,0,0,.2);font-size:9px;font-weight:700;
  letter-spacing:.04em;color:var(--flag-c);text-shadow:0 1px 1px rgba(0,0,0,.4);position:relative}
.tabs .clanflag::before{content:"";position:absolute;inset:0;border-radius:inherit;background:linear-gradient(180deg,rgba(255,255,255,.18),transparent 55%)}
.badgegrid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
.clanbadgepick{display:flex;align-items:center;gap:10px;padding:10px 12px;border-radius:10px;border:2px solid var(--ink2);background:#f5ecd4;color:var(--ink);text-align:left;box-shadow:0 3px 0 rgba(0,0,0,.12)}
.clanbadgepick.sel{outline:3px solid var(--ember);outline-offset:-2px;background:#efe0b8}
.clanrank{display:inline-block;margin-left:4px;padding:1px 6px;border-radius:6px;font-size:10.5px;font-weight:800;vertical-align:1px;background:#e3e7ec;color:#3b4552}
.clanrank.r-leader{background:#f2b73d;color:#3a2606}.clanrank.r-captain{background:#78c7ff;color:#0c2c4a}.clanrank.r-elder{background:#a7dca0;color:#173d12}
.tabs .dot{position:absolute;top:2px;left:calc(50% + 5px);width:13px;height:13px;border-radius:50%;
  background:var(--rust);border:2px solid var(--char3);display:none}
.tabs button.alert .dot{display:block;animation:pipnow 1.1s ease-in-out infinite}

/* ================= sheet: parchment, the one light material in the UI ==== */
.veil{position:fixed;inset:0;z-index:60;background:rgba(10,8,5,.68);display:none;
  align-items:flex-end;justify-content:center;backdrop-filter:blur(3px)}
.veil.on{display:flex}
.sheet{width:100%;max-width:520px;background:linear-gradient(180deg,var(--parch1),var(--parch2));
  border:3px solid var(--ink2);border-bottom:none;border-radius:16px 16px 0 0;color:var(--ink);
  padding:18px 15px calc(24px + var(--safe-b));max-height:84vh;overflow:auto;
  animation:up .28s cubic-bezier(.2,1.4,.4,1)}
@keyframes up{from{transform:translateY(40px)}to{transform:none}}
.sheet h3{font-size:20px;margin-bottom:3px;color:var(--ink)}
.sheet .close{float:right;width:34px;height:34px;border-radius:9px;border:2px solid var(--ink2);
  background:linear-gradient(180deg,#c96952,var(--rust2));color:#fdf0ea;font-size:18px;line-height:1;
  box-shadow:0 3px 0 #4a1810}
.sheet .row{background:linear-gradient(180deg,#f5ecd4,#e6d8b4);border-color:var(--ink2);box-shadow:0 3px 0 rgba(0,0,0,.14)}
.sheet .row .t1{color:var(--ink)}
.sheet .row .t2{color:var(--ink2)}
.sheet .tag{background:#e6d8b4;border-color:var(--ink2);color:var(--ink2)}
.sheet .tag.up{background:#cfe8bd;color:#2c5a1e;border-color:#8fbf74}
.sheet .tag.dn{background:#f0c7bc;color:#7a2c1c;border-color:#d1836c}
.sheet .mat{background:#e6d8b4;border-color:var(--ink2);color:var(--ink2)}
.sheet .mat b{color:var(--ink)}
.sheet .chip{background:#e6d8b4;border-color:var(--ink2);color:var(--ink2)}
.sheet .lock{background:repeating-linear-gradient(45deg,#e6d8b4,#e6d8b4 10px,#dccb9c 10px,#dccb9c 20px);border-color:var(--ink2);color:var(--ink2)}
.sheet .erarow{background:#f0e4c4;border-color:var(--ink2)}
.sheet .erarow span{color:var(--ink)}
.sheet .chkrow{border-bottom-color:rgba(42,32,22,.2)}
.sheet .statgrid div{border-bottom-color:rgba(42,32,22,.22)}
/* ================= Home: fixed to the screen, no scroll ================= */
:root{ --topH:58px; --tabH:70px; }
#pHome.on{
  /* vh first as a fallback for browsers without dvh support (would
     otherwise drop the whole declaration and leave #pHome with no
     height at all, collapsing the arena to its 70px floor below) */
  height:calc(100vh - var(--topH) - var(--tabH) - var(--safe-b));
  height:calc(100dvh - var(--topH) - var(--tabH) - var(--safe-b));
  display:flex; flex-direction:column; overflow-y:auto;
  padding:0 10px 8px; gap:0; background:var(--char3);
}
/* buildScene()'s viewBox is 440x190 (≈2.32:1) with preserveAspectRatio
   "slice" — the background deliberately covers whatever box it's given,
   cropping width instead of letterboxing (see js/05-combat.js). But "slice"
   zooms in enough to always cover the FULL height, so on a tall/narrow
   phone where the arena ends up much taller than ~0.7x its own width, that
   zoom crops so much width that the hero/foe's resting X positions
   (HERO_RANGED_X..FOE_RANGED_X, roughly the middle 55% of the 440-wide
   canvas) fall outside the visible slice — they render oversized and
   partly off-screen. Capping the arena's height relative to its own width
   (≈viewport width on mobile, where #app's max-width:520 doesn't bind)
   keeps the zoom bounded so that middle band always stays on-screen; any
   leftover vertical space just shows as background above/below the arena. */
#pHome.on .arena{ flex:1 1 auto; min-height:100px; max-height:70vw; margin:0 -10px 8px; }
#pHome.on .arena svg:not(svg svg){ width:100%; height:100%; display:block; }
#pHome.on .skillrow{ flex:0 0 auto }
#pHome.on .eqwrap{ flex:0 0 auto }
#pHome.on .foundrow{ flex:0 0 auto }
#pHome.on .forgerow{ flex:0 0 auto }
@media (prefers-reduced-motion:reduce){*{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important}}

/* ================= text inputs (clan name/tag, auth) ================= */
.ipt{font:inherit;font-size:14px;color:var(--parch1);background:#171410;
  border:1.5px solid var(--char3);border-radius:9px;padding:9px 11px;min-width:0}
.ipt::placeholder{color:var(--ink-soft)}
.ipt:focus{outline:none;border-color:var(--ember2)}
.ipt.wide{width:100%}
.sheet .ipt{color:var(--ink);background:#f5ecd4;border-color:var(--ink2)}

/* ================= auth gate ================= */
.authgate{position:fixed;inset:0;z-index:55;display:none;align-items:center;justify-content:center;
  padding:20px;background:radial-gradient(120% 60% at 50% 100%,#3a2414 0%,var(--char2) 46%,var(--char3) 100%)}
.authcard{width:100%;max-width:360px;background:linear-gradient(180deg,#2f2a23,#211c17);
  border:2px solid var(--char3);border-radius:14px;
  box-shadow:0 8px 0 rgba(0,0,0,.4),0 16px 24px rgba(0,0,0,.4);padding:24px}
.authlogo{display:block;margin:0 auto 10px;filter:drop-shadow(0 0 6px rgba(255,176,102,.4))}
.authcard h1{font-size:22px;text-align:center;margin-bottom:6px;color:var(--parch1)}
.authcard .mini{text-align:center;margin-bottom:16px}
.authcard .ipt{margin-bottom:10px}
.autherr{background:#4a2420;color:#f0b8ac;border:1.5px solid #6a342c;border-radius:9px;
  padding:8px 11px;font-size:12.5px;margin-bottom:10px}
.authdiv{display:flex;align-items:center;gap:10px;margin:14px 0;color:var(--ink-soft);font-size:12px}
.authdiv::before,.authdiv::after{content:"";flex:1;height:1px;background:var(--char3)}
.authgate .btn.wide{display:inline-flex;gap:8px}
.authswitch{text-align:center;margin-top:16px;font-size:13px;color:var(--parch2)}

/* ================= profile bar (top-left of the top bar) ================= */
.profileBar{position:relative;flex:0 0 auto;max-width:112px;display:flex;align-items:center;gap:7px;
  padding:4px 12px 4px 4px;border-radius:999px;background:linear-gradient(180deg,#241a10,#150f09);
  border:2px solid var(--char3)}
.profileBar .avatar{width:30px;height:30px;flex:none;border-radius:50%;overflow:hidden;
  border:2px solid var(--char3);background:var(--iron2)}
.profileBar .avatar img{width:100%;height:100%;display:block}
.profileBar .pname{font-size:12.5px;font-weight:600;color:var(--parch1);overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap;text-shadow:0 1px 2px rgba(0,0,0,.7)}

.avatarGrid{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin:6px 0 4px}
.avatarPick{position:relative;aspect-ratio:1;border-radius:50%;overflow:hidden;cursor:pointer;
  border:3px solid transparent;background:var(--iron2)}
.avatarPick img{width:100%;height:100%;display:block}
.avatarPick.sel{border-color:var(--ember)}
.sheet .avatarPick{background:#e6d8b4}

/* ================= ranking ================= */
.rankNo{width:24px;flex:none;text-align:center;font-weight:700;color:var(--parch2)}
.row.me{outline:2px solid var(--ember);outline-offset:-2px}
.rankAvatar{width:28px;height:28px;flex:none;border-radius:50%;overflow:hidden;background:var(--iron2)}
.rankAvatar img{width:100%;height:100%;display:block}
.authswitch a{color:var(--ember-lt);font-weight:600;text-decoration:underline}
