/* Echoes of the Fallen: portrait, touch-first. Retro pixel dungeon-crawler look: near-black navy, pixel font,
   colour-coded outlined boxes, a big tiled top-down arena. Art slots (.art) show sprites/line icons until real art lands. */
:root {
  --bg: #07070d; --panel: #0f0f1d; --panel2: #171729; --line: #2a2a48; --line2: #3e3e68;
  --text: #e6e6f0; --dim: #8a8aa8;
  --gold: #f0c93a; --cyan: #36c0e0; --red: #e0556a; --blue: #5a88f0; --green: #46c864; --purple: #7a58c8; --pink: #d8449a;
  --gold-bg: #1a1608; --accent: var(--gold); --accent2: #ffe07a; --good: var(--green); --bad: var(--red);
  --r: 3px; --r-sm: 3px;
  --font: 'DotGothic16', 'VT323', ui-monospace, 'Courier New', 'Noto Sans CJK SC', 'Noto Sans SC', 'PingFang SC', 'Hiragino Sans', 'Microsoft YaHei', 'Malgun Gothic', monospace; /* last named fonts are system CJK fallbacks */
  --sab: env(safe-area-inset-bottom); --sat: env(safe-area-inset-top);
}
* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body { height: 100%; }
body {
  margin: 0; background: #030307; color: var(--text); font: 14px/1.35 var(--font);
  font-variant-numeric: tabular-nums; overscroll-behavior: none; user-select: none; -webkit-user-select: none;
}
textarea, input { user-select: text; -webkit-user-select: text; }
/* Settings > Accessibility. Text size zooms the page content, not the battle HUD, which is laid out to fit. */
html[data-text="large"] #view, html[data-text="large"] #modal .card { zoom: 1.15; }
html[data-text="xlarge"] #view, html[data-text="xlarge"] #modal .card { zoom: 1.3; }
html[data-motion="reduced"] *, html[data-motion="reduced"] *::before, html[data-motion="reduced"] *::after { animation: none !important; transition: none !important; }
html[data-contrast="high"] { --text: #fff; --dim: #c4c4d8; --line: #5a5a88; --line2: #8a8ac0; }
#app {
  height: 100dvh; max-width: 560px; margin: 0 auto; display: flex; flex-direction: column; position: relative; overflow: hidden;
  background: var(--bg); padding-left: env(safe-area-inset-left); padding-right: env(safe-area-inset-right);
}

/* ---------- HUD: floor panel + currency boxes ---------- */
#hud { display: grid; grid-template-columns: 1fr auto; gap: 4px; padding: calc(var(--sat) + 2px) 6px 2px; }
.floor-badge { display: flex; align-items: center; gap: 6px; padding: 2px 8px; background: var(--panel); border: 2px solid var(--line2); border-radius: var(--r); position: relative; }
.floor-badge::before { content: ''; align-self: stretch; width: 4px; background: var(--gold); margin: -2px 0; }
.floor-badge .lbl { font-size: 10px; color: var(--dim); letter-spacing: .1em; text-transform: uppercase; }
.floor-badge b { font-size: 22px; line-height: 1; color: var(--text); font-weight: 400; }
.floor-badge .best { font-size: 11px; color: var(--dim); margin-left: auto; }
.floor-badge .go { font-size: 10px; color: var(--gold); letter-spacing: .06em; padding-left: 8px; border-left: 1px solid var(--line2); white-space: nowrap; }
button.floor-badge { width: 100%; min-height: 36px; text-align: left; color: var(--text); font: inherit; cursor: pointer; }
button.floor-badge:active { border-color: var(--gold); }
.chips { display: flex; flex-direction: column; gap: 2px; min-width: 112px; }
.chip { display: flex; align-items: center; gap: 6px; padding: 0 6px; background: var(--panel); border: 2px solid var(--line2); border-radius: var(--r); }
.chip b { margin-left: auto; font-weight: 400; color: var(--gold); }
.chip.shards b, .chip.diamonds b { color: var(--cyan); }
.chip .ico { width: 16px; height: 16px; color: inherit; }
.chip.gold .ico { color: var(--gold); } .chip.shards .ico, .chip.diamonds .ico { color: var(--cyan); }

/* ---------- Scroll area + tab bar ---------- */
main { flex: 1; overflow-y: auto; overflow-x: hidden; padding: 4px 10px 20px; display: flex; flex-direction: column; gap: 8px; -webkit-overflow-scrolling: touch; }
main > * { flex-shrink: 0; }
nav#tabs { display: flex; background: #05050a; border-top: 2px solid var(--line2); padding-bottom: var(--sab); }
nav#tabs button {
  flex: 1; min-height: 50px; border: 0; border-radius: 0; background: none; color: var(--dim); display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 2px; font-size: 11px; position: relative; padding: 4px 0;
}
nav#tabs button .ico { width: 22px; height: 22px; }
nav#tabs button.on { color: var(--gold); background: linear-gradient(#f0c93a1c, transparent); box-shadow: inset 0 2px 0 var(--gold); }
.tabbar { display: flex; align-items: center; justify-content: space-between; position: sticky; top: -4px; z-index: 5; margin: -4px -10px 0; padding: 4px 10px; background: #05050a; border-bottom: 2px solid var(--line2); }
.tabbar .tabright { display: flex; align-items: center; gap: 8px; }
.tabbar .chip { min-width: 96px; }
#hud[hidden] { display: none; }
.tabbar button { min-width: 48px; min-height: 40px; font-size: 20px; line-height: 1; }
.badge { position: absolute; top: 4px; left: calc(50% + 8px); min-width: 16px; height: 16px; padding: 0 4px; background: var(--red); color: #fff; font: 11px/16px var(--font); text-align: center; font-style: normal; border-radius: 2px; }
.badge[hidden] { display: none; }

/* ---------- Buttons ---------- */
button {
  min-height: 38px; padding: 4px 12px; border: 2px solid var(--line2); border-radius: var(--r-sm);
  background: var(--panel2); color: var(--text); font: 13px var(--font); touch-action: manipulation;
}
button:active:not(:disabled) { filter: brightness(1.3); }
button:disabled { opacity: .35; }
button.primary { background: var(--gold-bg); border-color: var(--gold); color: var(--gold); }
button.danger { background: #2a0e14; border-color: var(--red); color: #ff9aa8; }
button.sm { min-height: 32px; padding: 2px 9px; font-size: 12px; }
button.block { width: 100%; }
button .sub { display: block; font-size: 11px; opacity: .7; }

/* ---------- Cards, rows, text ---------- */
.card { background: var(--panel); border: 2px solid var(--line2); border-radius: var(--r); padding: 10px; }
.card.goal { border-color: var(--line2); }
.h { font-size: 14px; } .title { font-size: 17px; }
.row { display: flex; justify-content: space-between; gap: 8px; align-items: center; margin: 6px 0; }
.row > :first-child { flex: 1; min-width: 0; }
.row.tight { margin: 2px 0; }
.row.wrap { flex-wrap: wrap; justify-content: flex-start; gap: 4px; }
.row.wrap > :first-child { flex: 0 1 auto; }
.row.wrap .tag { padding: 2px 6px; }
.dim { color: var(--dim); font-size: 12.5px; }
.small { font-size: 12px; }
.sect { margin: 6px 2px 0; font-size: 11px; letter-spacing: .12em; text-transform: uppercase; color: var(--dim); display: flex; align-items: center; gap: 8px; }
.sect::after { content: ''; flex: 1; height: 2px; background: var(--line); }
.tag { display: inline-block; padding: 0 6px; border-radius: 2px; font-size: 11px; background: #ffffff10; color: var(--dim); }
.tag.c { color: var(--c); background: color-mix(in srgb, var(--c) 16%, transparent); }
.toggle { display: flex; justify-content: space-between; align-items: center; min-height: 40px; margin: 0; }
.toggle input { width: 20px; height: 20px; accent-color: var(--gold); }
.toggle { gap: 12px; }
.toggle span { min-width: 0; }
.checks { display: flex; flex-wrap: wrap; gap: 4px 14px; }
.checks .toggle { display: inline-flex; justify-content: flex-start; gap: 6px; margin-top: 0; }
.toggle input[type=range] { flex: 1; max-width: 160px; width: auto; }
.toggle input[type=number] { flex: none; width: 72px; height: auto; min-height: 40px; background: var(--panel2); color: var(--text); border: 2px solid var(--line2); border-radius: var(--r-sm); padding: 0 8px; font: inherit; text-align: right; accent-color: auto; }
select { min-height: 40px; background: var(--panel2); color: var(--text); border: 2px solid var(--line2); border-radius: var(--r-sm); padding: 0 8px; font: inherit; max-width: 55%; }
textarea { width: 100%; background: var(--bg); color: inherit; border: 2px solid var(--line); border-radius: var(--r-sm); padding: 8px; font: inherit; }
.stack > * + * { margin-top: 8px; }

/* ---------- Bars ---------- */
.bar { position: relative; height: 10px; background: #05050b; border: 2px solid var(--line2); border-radius: 2px; overflow: hidden; }
.bar > i { display: block; height: 100%; width: 0; background: var(--green); transition: width .2s linear; }
.bar.foe > i { background: var(--red); }
/* Champion hp: the pale trail behind the fill shrinks late, so a hit shows as a chunk; the fill turns red when low. */
.bar.hp > i { position: relative; z-index: 1; } .bar.hp > i.low { background: var(--red); }
.bar.hp > b { position: absolute; left: 0; top: 0; height: 100%; width: 0; background: #f4e9c8; transition: width .6s ease-out .35s; }
.bar.xp > i { background: var(--blue); }
.bar.gauge > i { background: var(--pink); }
.bar.thin { height: 8px; }
.bar.tall { height: 24px; } .bar.tall span { position: absolute; inset: 0; display: flex; align-items: center; justify-content: flex-end; padding-right: 8px; font-size: 14px; text-shadow: 1px 1px 0 #000; }
.bar.mid { height: 16px; } .bar.mid span { position: absolute; inset: 0; display: flex; align-items: center; justify-content: flex-end; padding-right: 6px; font-size: 10px; text-shadow: 1px 1px 0 #000; }
.bar .lbl { position: absolute; left: 6px; top: 0; bottom: 0; display: flex; align-items: center; font-style: normal; font-size: 12px; letter-spacing: 1px; color: #fff; text-shadow: 1px 1px 0 #000; z-index: 1; }
.bar.mid .lbl { font-size: 10px; }
.bar.full > i { animation: pulse 1.2s steps(2) infinite; }
@keyframes pulse { 50% { filter: brightness(1.5); } }

/* ---------- Art slots ---------- */
.art {
  --c: #3a4a8a; position: relative; display: inline-grid; place-items: center; flex: none; overflow: hidden; color: #9aa3d8;
  width: 44px; height: 44px; border-radius: var(--r-sm); border: 2px solid var(--c); background: #090913;
}
.art svg { width: 58%; height: 58%; }
.art img { width: 100%; height: 100%; object-fit: contain; image-rendering: pixelated; pointer-events: none; }
.art.svgicon { border: 0; background: none; overflow: visible; }
.art.svgicon img { image-rendering: pixelated; }
.art.pngicon img { image-rendering: auto; }
.art.pngicon.upgrade img, .art.pngicon.soul img { image-rendering: pixelated; border-radius: 4px; }
.item .art.upgrade, .item .art.ui { width: 44px; height: 44px; flex: none; }
.art.locked { opacity: .45; }
.art.ico { width: 20px; height: 20px; border: 0; background: none; border-radius: 0; color: inherit; }
.art.ico svg { width: 100%; height: 100%; }
.art.hero { width: 100%; height: auto; aspect-ratio: 3 / 4; }
.art.hero svg { width: 34%; height: 34%; }
.art.ore, .art.gem { width: 36px; height: 36px; color: var(--c); }
.art.ore + span, .art.gem + span { margin-left: 8px; }
.art.modeled svg { width: 100%; height: 100%; stroke-width: 0; }
.art.modeled.gear svg { width: 80%; height: 80%; }
.art.modeled.pet svg { width: 84%; height: 84%; }
.mt .wn { display: block; margin-top: 2px; font-size: 10px; line-height: 1.2; text-align: center; overflow-wrap: anywhere; }
.art.pet { width: 100%; height: auto; aspect-ratio: 1; }
.art.pet svg { width: 42%; height: 42%; }
.art.champion, .art.foe { width: 92px; height: 92px; border: 0; background: none; overflow: visible; }
.art.champion svg, .art.foe svg { width: 100%; height: 100%; stroke-width: 0; }
.px { width: 100%; height: 100%; image-rendering: pixelated; filter: drop-shadow(0 3px 0 #0009); }
.art.foe svg.px { transform: scaleX(-1); }
.art.foe.boss { width: 140px; height: 140px; }
.art.foe.boss svg.px { filter: drop-shadow(0 0 8px #e0556a99) drop-shadow(0 3px 0 #0009); }
.item .art.champion { width: 44px; height: 44px; border: 2px solid var(--c, var(--blue)); background: #090913; padding: 2px; overflow: hidden; }
.item .art.champion svg.px { filter: none; }

/* ---------- Battle: sticky top block (stats, skill slots, arena) ---------- */
.battleTop { position: sticky; top: -4px; z-index: 6; background: var(--bg); margin: -4px -10px 0; padding: 4px 10px 6px; display: flex; flex-direction: column; gap: 6px; }
.statbar { display: flex; gap: 6px; align-items: stretch; }
.lvbox { width: 52px; display: flex; flex-direction: column; align-items: center; justify-content: center; background: var(--panel); border: 2px solid var(--line2); border-radius: var(--r); }
.lvbox small { font-size: 10px; color: var(--gold); line-height: 1; } .lvbox b { font-size: 20px; line-height: 1.1; font-weight: 400; color: var(--text); }
.hpcol { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; justify-content: center; }
.hpcol .xptxt { font-size: 10px; color: var(--dim); text-align: right; line-height: 1; }
.statrow { display: flex; gap: 6px; justify-content: flex-end; }
.sbox { flex: 1; display: flex; align-items: center; gap: 6px; padding: 4px 8px; background: var(--panel); border: 2px solid var(--c); border-radius: var(--r); font-size: 12px; min-height: 32px; }
.sbox i { width: 10px; height: 10px; background: var(--c); flex: none; } .sbox span { color: var(--c); } .sbox b { margin-left: auto; font-weight: 400; color: var(--c); }
.sbox.atk { --c: var(--red); } .sbox.def { --c: var(--blue); }
.speeds { display: flex; gap: 6px; }
button.spd.on { border-color: var(--gold); color: var(--gold); }
button.spd { min-height: 28px; min-width: 48px; padding: 1px 8px; font-size: 12px; border-color: var(--line2); background: var(--panel2); color: var(--text); }
.gaugerow { display: flex; align-items: center; gap: 6px; }
.gaugerow > span { font-size: 11px; color: var(--pink); } .gaugerow .bar { flex: 1; }
.slots { display: flex; gap: 6px; justify-content: center; }
.slot { position: relative; width: 40px; height: 40px; border: 2px solid var(--line2); border-radius: var(--r-sm); background: #090913; display: grid; place-items: center; }
.slot.on { border-color: var(--line2); color: var(--text); } .slot em { position: absolute; right: 2px; bottom: -1px; font-style: normal; font-size: 11px; color: var(--gold); text-shadow: 1px 1px 0 #000; }
.slot .art { color: inherit; }
.slot { overflow: hidden; } .slot.cooling .art { opacity: .8; }
.slot .cd { position: absolute; left: 0; right: 0; bottom: 0; background: rgba(5, 5, 12, .68); border-top: 2px solid var(--gold); pointer-events: none; }

/* ---------- Arena: big tiled top-down floor ---------- */
.stage {
  --tile: #1a1626; --edge: #090710; --lit: #3b2a66; --glow: #7a58c8;
  position: relative; border: 2px solid var(--line2); border-radius: var(--r); overflow: hidden; height: clamp(260px, 42dvh, 440px);
  background:
    linear-gradient(90deg, transparent calc(100% - 2px), var(--edge) 0) 0 0 / 32px 32px,
    linear-gradient(transparent calc(100% - 2px), var(--edge) 0) 0 0 / 32px 32px,
    radial-gradient(ellipse 80% 70% at 50% 55%, color-mix(in srgb, var(--glow) 45%, transparent), transparent 75%),
    var(--tile);
  image-rendering: pixelated;
}
.stage[data-env="stone"] { --tile: #24262c; --edge: #0d0e11; --glow: #7a8090; }
.stage[data-env="cave"]  { --tile: #2a2018; --edge: #100b07; --glow: #b07a3a; }
.stage[data-env="lava"]  { --tile: #2e1612; --edge: #120706; --glow: #ff5a1f; }
.stage[data-env="ice"]   { --tile: #1c2a38; --edge: #0a1018; --glow: #5ab8ff; }
.stage[data-env="abyss"] { --tile: #1a1626; --edge: #090710; --glow: #7a58c8; }
.stage.hasbg { background: var(--bg-art) center / cover no-repeat, var(--tile); } /* a themed floor replaces the grid */
.stage::before { content: ''; position: absolute; inset: 0; z-index: 2; pointer-events: none; background: radial-gradient(ellipse at 50% 55%, transparent 55%, #000a 100%); }
.stage-top { position: absolute; z-index: 3; top: 6px; left: 6px; right: 6px; display: flex; justify-content: space-between; align-items: flex-start; gap: 8px; }
.zone, .pill { font-size: 12px; padding: 1px 8px; background: #000a; border: 2px solid var(--line2); border-radius: 2px; color: var(--text); }
.pill.boss { color: #ff9aa8; border-color: var(--red); } .pill.dungeon { color: var(--gold); border-color: var(--gold); }
.field { position: absolute; z-index: 1; inset: 28px 8px 8px; }
.unit { display: flex; flex-direction: column; align-items: center; gap: 2px; width: 96px; position: relative; }
.unit::before { content: ''; position: absolute; left: 14%; right: 14%; bottom: 20px; height: 10px; background: #0007; border-radius: 50%; }
.unit .art { position: relative; }
.unit .bar { width: 100%; height: 6px; border-width: 1px; } .unit .nm { font-size: 12px; text-shadow: 1px 1px 0 #000; text-align: center; line-height: 1.1; }
.unit.champion .art { animation: bob 2.4s steps(2) infinite; } .unit.foe .art { animation: bob 2s steps(2) infinite reverse; }
.allies { position: absolute; inset: 0; pointer-events: none; }
.unit.champion { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); z-index: 3; }
.unit.ally { position: absolute; left: 50%; top: 50%; width: 60px; will-change: transform; transition: transform .11s linear; }
.unit.ally::before { display: none; }
.unit.ally .art.pet { width: 44px; height: 44px; aspect-ratio: auto; }
.unit.ally .nm { display: none; font-size: 10px; }
.foes { position: absolute; inset: 0; pointer-events: none; z-index: 2; }
.foes .unit { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); width: 64px; will-change: transform; transition: transform .11s linear; } .foes .unit.boss { width: 104px; }
.foes .unit.foe.west .art.foe svg.px { transform: none; }
.foes .unit .nm, .foes .unit .bar { display: none; } .foes .unit.near .bar, .foes .unit.boss .bar, .foes .unit.boss .nm { display: block; }
.foes .unit:not(.boss) .art.foe { width: 44px; height: 44px; }
.foes .none { position: absolute; left: 50%; top: 20%; transform: translate(-50%, -50%); color: var(--dim); font-size: 12px; }

@keyframes bob { 50% { transform: translateY(-3px); } }
@media (prefers-reduced-motion: reduce) { .unit .art, .art.has-img .spr, .art.atk, .art.atk .part, .mob, .mob svg, .fx, .art.has-img::before, .art.has-img::after, .showcase img, .showcase::before, .showcase::after, .bar.full > i { animation: none; } .bar > i { transition: none; } }
@media (max-height: 640px) { .stage { height: 240px; } }
.actions { display: grid; grid-template-columns: 1fr; gap: 8px; }

/* ---------- Segmented sub tabs ---------- */
.sbanners { display: grid; gap: 10px; }
.sbanner { position: relative; display: flex; flex-direction: column; justify-content: flex-end; gap: 6px; min-height: 168px; padding: 14px; text-align: left; overflow: hidden; border: 2px solid var(--line2); border-radius: var(--r); background: linear-gradient(135deg, var(--panel), var(--c2, var(--panel))) center / cover no-repeat; box-shadow: inset 0 0 28px color-mix(in srgb, var(--c, var(--line2)) 30%, transparent); }
.sbanner.s-heroes { --c: var(--gold); --c2: #2a2208; }
.sbanner.s-pets { --c: var(--accent2); --c2: #0c2418; }
.sb-art { width: 80px; flex: none; display: flex; justify-content: center; align-items: center; }
.sb-art .art { width: 100%; max-width: 80px; }
.sb-info { flex: 1; display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.sb-shade { position: absolute; inset: 0; background: linear-gradient(to top, #050509f2 8%, #05050980 45%, transparent 80%); pointer-events: none; }
.sbanner > *:not(.sb-shade), .summon-bg > * { position: relative; }
.summon-bg > .sb-shade { position: absolute; }
.sb-title { font-size: 24px; color: var(--c); text-shadow: 2px 2px 0 #000; }
.sb-foot { display: flex; justify-content: space-between; align-items: center; }
.sb-go { font-size: 26px; color: var(--c); line-height: 1; }
.sbanner:active { transform: scale(.985); }
.sb-sub { font-size: 12px; color: var(--text); text-shadow: 1px 1px 0 #000; }
.backbtn { min-height: 40px; align-self: flex-start; }
.seg { display: flex; gap: 4px; }
.seg button { flex: 1; min-height: 34px; background: var(--panel); border-color: var(--line); color: var(--dim); font-size: 12.5px; }
.seg button.on { border-color: var(--gold); color: var(--gold); background: var(--gold-bg); }

.skins { display: flex; gap: 6px; overflow-x: auto; padding-bottom: 2px; }
.skins button { flex: 0 0 76px; display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 4px; min-height: 48px; background: var(--panel); border-color: var(--line); color: var(--dim); font-size: 11px; line-height: 1.15; }
.skins button img { width: 56px; height: 56px; object-fit: contain; image-rendering: pixelated; }
.skins button.on { border-color: var(--gold); color: var(--gold); background: var(--gold-bg); }

/* ---------- List items (upgrades, skills, gear, soul) ---------- */
.item { display: flex; gap: 10px; align-items: center; padding: 8px; background: var(--panel); border: 2px solid var(--line); border-left: 4px solid var(--c, var(--line2)); border-radius: var(--r); }
.item .body { flex: 1; min-width: 0; }
.item .nm { font-size: 14px; } .item .nm .lv { color: var(--gold); font-size: 12px; margin-left: 6px; }
.item .btns { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.item.empty { border-style: dashed; background: none; opacity: .6; }
.item.locked { opacity: .5; }
.item .buy { min-width: 0; min-height: 28px; padding: 1px 4px; font-size: 10px; line-height: 1.15; }
.item .buys { display: flex; gap: 3px; flex-shrink: 0; }
.item .buys .buy { min-width: 38px; }
.item.top { align-items: flex-start; }
.stats { margin-top: 2px; }
.stat { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.power, .setbox { margin-top: 6px; padding: 6px 8px; border-radius: 8px; border: 1px solid var(--line); font-size: 12px; }
.power { border-left: 4px solid var(--lc, var(--line)); }
.power .pn { font-weight: 700; color: var(--lc, inherit); }
.setbox { border-left: 4px solid var(--sc, var(--line)); }
.setbox .sn { font-weight: 700; color: var(--sc, inherit); }
.setbox .sb { color: var(--dim); }
.setbox .sb.on { color: var(--sc, inherit); }
.affix { display: flex; align-items: center; justify-content: space-between; gap: 6px; font-size: 12px; color: var(--dim); margin-top: 4px; padding-top: 4px; border-top: 2px solid var(--line); }
.affix .stat { flex: 1; }
.affix .btns { margin-top: 0; flex-wrap: nowrap; flex-shrink: 0; }
.affix .btns button { min-height: 30px; padding: 0 8px; font-size: 11px; }
.affix.socks, .detail .affix.socks { display: block; }
.affix.socks .btns, .detail .affix.socks .btns { display: flex; flex-wrap: wrap; flex-shrink: 1; min-width: 0; width: 100%; }
.affix.socks select { flex: 1 1 96px; min-width: 0; max-width: 100%; text-overflow: ellipsis; }
.affix.socks .btns button { flex: 1 1 100%; }

/* ---------- Tile grid (Heroes, Pets) ---------- */
.tiles { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; }
.tile { display: flex; flex-direction: column; gap: 6px; padding: 8px; border-radius: var(--r); border: 2px solid var(--c, var(--line2)); background: var(--panel); }
.tile.locked { opacity: .6; }
.tile .art { align-self: center; max-width: 100%; }
.tile .art.pet { width: 66%; }
.tile .nm { font-size: 14px; line-height: 1.2; }
.tile .blurb { font-size: 12px; color: var(--dim); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.tile .btns { display: grid; gap: 6px; margin-top: auto; }
.tile .btns button { min-height: 34px; font-size: 12px; }
/* Pets: one row per pet (portrait left, details right, actions below) */
.tiles.list { grid-template-columns: 1fr; }
.tiles.list .tile { display: grid; grid-template-columns: 76px 1fr; column-gap: 12px; row-gap: 8px; align-items: start; }
.tiles.list .tile .art.pet { width: 76px; align-self: start; }
.tiles.list .info { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.tiles.list .btns { grid-column: 1 / -1; grid-auto-flow: column; grid-auto-columns: 1fr; }
.tiles.list .btns button { padding: 0 6px; }
/* Compact sprite grid (Heroes, Pets, Gear): tap a tile for the detail window */
.tiles.mini { grid-template-columns: repeat(4, 1fr); gap: 6px; }
.bagwrap { container-type: inline-size; }
.bagwrap .tiles.bag { max-height: calc(5 * (100cqw - 20px) / 6 + 16px); overflow-y: auto; align-content: start; }
.tiles.bag { grid-template-columns: repeat(6, 1fr); gap: 4px; }
.tiles.bag .mt { padding: 2px; border-width: 1px; }
.tiles.bag .mt .bd { font-size: 8px; padding: 1px 2px; }
.tiles.bag .mt .bd.lv { left: 1px; bottom: 1px; }
.tiles.bag .mt .bd.st { right: 1px; top: 1px; }
.mt { position: relative; display: block; padding: 4px; min-height: 0; border: 2px solid var(--c, var(--line2)); border-radius: var(--r); background: var(--panel); }
.mt .art { width: 100%; }
.mt .art.hero { aspect-ratio: 3 / 4; }
.mt.gt .art { aspect-ratio: 1; height: auto; }
.mt.locked { opacity: .55; }
.mt.empty { border-style: dashed; background: none; opacity: .6; }
.mt.in-loadout { box-shadow: 0 0 0 2px var(--gold); }
.mt .bd { position: absolute; font-size: 10px; line-height: 1; padding: 2px 3px; border-radius: 3px; background: #000b; color: var(--text, #fff); pointer-events: none; }
.mt .bd.lv { left: 3px; bottom: 3px; }
.mt .bd.new { left: 3px; top: 3px; min-width: 14px; text-align: center; background: var(--red); color: #fff; font-weight: 700; }
.tiles.bag .mt .bd.new { left: 1px; top: 1px; }
.mt .bd.st { right: 3px; top: 3px; color: var(--gold); }
.mt .bd.fit { right: 3px; bottom: 3px; color: var(--gold); } /* top-left belongs to the lock */
.mt .bd.lock { left: 3px; top: 3px; color: var(--gold); display: flex; }
.tiles.bag .mt .bd.lock { left: 1px; top: 1px; }
.tiles.bag .mt .bd.fit { right: 1px; bottom: 1px; }
.mt.empty .bd.lv { max-width: calc(100% - 6px); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--dim); }
#modal .card.detail { animation: none; }
.dhead { display: flex; gap: 12px; align-items: center; }
.dhead .art { width: 84px; flex: none; }
.dhead .art.hero { aspect-ratio: 3 / 4; }
.dhead .info { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.detail .btns { display: grid; gap: 6px; }
.detail .item .btns { display: flex; }
.stars { color: var(--gold); letter-spacing: 1px; }
.tile.in-loadout { box-shadow: 0 0 0 2px var(--gold); }


/* ---------- Skills and Soul Tree (tiles, sticky header, detail sheet) ---------- */
.skgrid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }
.skgrid.slots { margin-top: 8px; }
.sk { position: relative; display: flex; flex-direction: column; align-items: center; gap: 2px; min-height: 48px; padding: 4px 2px; background: var(--panel2); border: 2px solid var(--line); border-radius: var(--r-sm); font-size: 11px; line-height: 1.15; text-align: center; }
.sk .art { width: 40px; height: 40px; }
.art.skill { background: color-mix(in srgb, var(--c) 14%, #090913); border: 2px solid var(--c); }
.art.skill svg { width: 62%; height: 62%; }
.art.skill.has-icon { display: grid; place-items: center; }
.art.skill.has-icon img { width: 100%; height: 100%; object-fit: cover; image-rendering: auto; }
.dhead .art.skill { height: 84px; }
.sk .nm { font-size: 11px; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sk .br { font-size: 10px; color: var(--dim); max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sk .lv { color: var(--gold); font-size: 10px; }
.sk.eq { border-color: var(--gold); }
.sk.new, .sk.locked { opacity: .6; }
.sk.empty { border-style: dashed; justify-content: center; background: none; color: var(--dim); min-height: 76px; }
.sk .dot { position: absolute; top: 3px; right: 3px; width: 10px; height: 10px; border-radius: 50%; background: var(--pink, #ff5fa8); box-shadow: 0 0 0 2px #000; }
.evo { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.evo button { min-height: 64px; white-space: normal; }
.seg.mult { margin: 2px 0; }
.item.pick { width: 100%; text-align: left; }
.soulhead { position: sticky; top: 44px; z-index: 4; display: flex; flex-direction: column; gap: 6px; padding: 6px 0; background: var(--bg); }
.seg button b { color: var(--green); font-weight: 400; margin-left: 4px; }
.sngrid { display: flex; flex-direction: column; gap: 8px; }
.snode { display: flex; align-items: center; gap: 10px; padding: 8px 8px 8px 10px; background: var(--panel); border: 2px solid var(--line); border-radius: var(--r); }
.snode.can { border-color: var(--accent); }
.snode.maxed { border-color: var(--gold); }
.snode.locked > .art, .snode.locked .sn-body { opacity: .5; }
.snode > .art { width: 44px; height: 44px; flex: none; }
.sn-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.sn-top { display: flex; justify-content: space-between; gap: 8px; align-items: baseline; }
.sn-top .nm { font-size: 14px; line-height: 1.2; }
.sn-top .lv { color: var(--gold); font-size: 12px; flex: none; }
.sn-fx { font-size: 12px; line-height: 1.25; color: var(--dim); }
.sn-buy { flex: none; width: 76px; min-height: 48px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; font-size: 13px; color: var(--dim); }
.sn-buy.primary { color: var(--accent); }
.sn-buy.max { color: var(--gold); border: 2px solid var(--gold); border-radius: var(--r); }
.sn-buy b { font-weight: 400; }
.sn-buy .ico { width: 14px; height: 14px; }

#modal .card.detail { position: relative; }
.detail .x { position: absolute; top: 6px; right: 6px; width: 44px; min-height: 44px; padding: 0; font-size: 18px; z-index: 1; }
.detail .dhead .info, .detail > .title { padding-right: 50px; }
.detail button.big { min-height: 56px; font-size: 16px; }
.detail button.danger.block { margin-top: 18px; min-height: 40px; }

/* ---------- Modal ---------- */
#modal { position: fixed; inset: 0; z-index: 10; background: #000c; display: grid; align-items: end; justify-items: center; padding: 12px; padding-bottom: calc(12px + var(--sab)); }
#modal[hidden] { display: none; }
#modal .card { max-width: 520px; width: 100%; max-height: 85dvh; overflow-y: auto; border-color: var(--line2); animation: rise .15s steps(3); background: var(--panel); }
#modal .card > * + * { margin-top: 10px; }
@keyframes rise { from { transform: translateY(24px); opacity: 0; } }

/* ---------- Pull result ---------- */
.pulled { display: flex; gap: 12px; align-items: center; border-color: var(--c, var(--line2)); background: linear-gradient(120deg, color-mix(in srgb, var(--c, var(--line2)) 22%, var(--panel)), var(--panel)); box-shadow: 0 0 14px color-mix(in srgb, var(--c, transparent) 45%, transparent); }
.pulled .art { width: 56px; height: 56px; }
.pulled .art.hero, .pulled .art.pet { height: 56px; aspect-ratio: auto; }

/* ---------- Desktop: keep the phone column centred ---------- */
@media (min-width: 600px) { #app { border-left: 2px solid var(--line); border-right: 2px solid var(--line); } }

/* Battle tab is just stats + arena: the arena fills the screen. */
.battleTop { flex: 1 1 auto; min-height: 0; position: static; margin: 0; padding: 0; }
main > .battleTop { flex-shrink: 1; }
.battleTop .stage { flex: 1 1 auto; height: auto; min-height: 240px; }
/* Full-bleed arena: edge to edge, no frame, flush with the nav. */
main:has(> .battleTop) { padding-bottom: 0; }
main > .battleTop .stage { margin: 0 -10px; border-width: 0; border-radius: 0; }
nav#tabs button { font-size: 10px; } nav#tabs button .ico { width: 20px; height: 20px; }

/* Dev options modal: sticky header + tabs, scrolling body */
#modal .card.dev { padding: 0; display: flex; flex-direction: column; overflow: hidden; height: min(85dvh, 680px); }
#modal .card.dev > * + * { margin-top: 0; }
.dev-head { flex: none; padding: 10px 10px 0; background: var(--panel); border-bottom: 2px solid var(--line2); }
.dev-head .row { margin: 0 0 6px; }
.dev-head .row button { min-height: 36px; flex: none; }
.devmsg { min-height: 34px; padding: 6px 8px; margin-bottom: 8px; background: var(--panel2); border-left: 4px solid var(--green); border-radius: var(--r-sm); font-size: 12.5px; color: var(--text); }
.devtabs { display: flex; gap: 4px; overflow-x: auto; margin: 0 -10px; padding: 0 10px; scrollbar-width: none; }
.devtabs button { flex: 1 0 auto; min-height: 40px; border-bottom: 0; border-radius: var(--r-sm) var(--r-sm) 0 0; background: var(--panel); border-color: var(--line); color: var(--dim); }
.devtabs button.on { background: var(--panel2); border-color: var(--gold); color: var(--gold); }
.dev-body { flex: 1; overflow-y: auto; padding: 10px; overscroll-behavior: contain; }
.dev .pane { display: flex; flex-direction: column; gap: 8px; }
.dev .pane[hidden] { display: none; }
.dev .pane > .title:not(:first-child) { margin-top: 8px; padding-top: 10px; border-top: 1px solid var(--line); }
.dev .grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 8px; }
.dev .grid.one { grid-template-columns: 1fr; }
.dev .grid.g4 { grid-template-columns: repeat(4, 1fr); }
.dev .grid > * { margin: 0; min-width: 0; }
.dev button { min-height: 44px; }
.dev button.big { min-height: 56px; font-size: 15px; }
.dev button.on { border-color: var(--gold); color: var(--gold); background: var(--gold-bg); }
.dev button.tog.on { border-color: var(--green); color: var(--green); background: #0c2418; }
.dev .fld { display: flex; align-items: center; gap: 8px; }
.dev .fld > span { flex: none; min-width: 78px; color: var(--dim); font-size: 12.5px; }
.dev input[type=number] { min-height: 44px; flex: 1; width: 0; min-width: 0; background: var(--panel2); color: var(--text); border: 2px solid var(--line2); border-radius: var(--r-sm); padding: 0 8px; font: inherit; }
.dev select { width: 100%; max-width: none; min-height: 44px; min-width: 0; }


/* ---------- Real art: no box, alive idle ----------
   PNG art is drawn facing left (--flip:-1 turns party members toward the foes). Float + sway + breathe, a pulsing glow in the
   rarity colour, and drifting sparkles. */
.art.has-img { border: 0; background: none; overflow: visible; }
.art.champion.has-img { --c: #ffcf70; }
.unit.champion, .unit.ally { --flip: -1; }
.unit.champion .art.has-img { animation: none; }
.art.has-img .spr { display: block; position: relative; width: 100%; height: 100%; }
.art.has-img .spr img { display: block; width: 100%; height: 100%; object-fit: contain; }
/* Idle overlay of a top-tier skin (web/tools/fx_idle): N frames side by side, one square per frame with a pad of 1/8 round the sprite so particles can leave its edge */
.idlefx { display: none; position: absolute; left: -12.5%; top: -12.5%; width: 125%; height: 125%; pointer-events: none; z-index: 2; image-rendering: pixelated; background-repeat: no-repeat; background-size: calc(var(--n) * 100%) 100%; animation: idleplay calc(var(--n) * var(--ms)) steps(var(--n), jump-none) infinite; }
.unit.champion .art.hero .spr .idlefx, .dhead .art.hero .spr .idlefx { display: block; }
.idlefx.smooth { image-rendering: auto; }
@keyframes idleplay { from { background-position-x: 0%; } to { background-position-x: 100%; } }
@media (prefers-reduced-motion: reduce) { .idlefx { animation: none; } }
.art.has-img .spr.parted { width: auto; max-width: 100%; }
.art.has-img .spr.parted img.part { position: absolute; inset: 0; }
.art.has-img .spr {
  transform-origin: 50% 100%;
  animation: alive 3.2s ease-in-out infinite, glow 2.4s ease-in-out infinite;
  filter: drop-shadow(0 0 3px var(--c));
}
.tile:nth-child(2n) .art.has-img .spr, .unit.ally:nth-child(2) .art.has-img .spr { animation-delay: -1.1s, -.7s; }
.tile:nth-child(3n) .art.has-img .spr, .unit.ally:nth-child(3) .art.has-img .spr { animation-delay: -2.2s, -1.5s; }
@keyframes alive {
  0%, 100% { transform: scaleX(var(--flip, 1)); }
  50% { transform: scaleX(var(--flip, 1)); }
}
@keyframes glow { 50% { filter: drop-shadow(0 0 9px var(--c)) brightness(1.12); } }
.art.has-img::before, .art.has-img::after, .showcase::before, .showcase::after {
  content: ''; position: absolute; width: 3px; height: 3px; background: #fff; box-shadow: 0 0 5px var(--c, #ffcf70);
  left: 24%; bottom: 25%; opacity: 0; pointer-events: none; z-index: 2; animation: rise 3.4s linear infinite;
}
.art.has-img::after, .showcase::after { left: 72%; bottom: 15%; animation-duration: 4.2s; animation-delay: -1.7s; }
@keyframes rise { 0% { transform: translateY(0); opacity: 0; } 15% { opacity: 1; } 100% { transform: translateY(-38px); opacity: 0; } }
.showcase { position: relative; display: flex; justify-content: center; padding: 8px 0; --c: #ffcf70; }
.showcase img { width: min(100%, 300px); height: auto; image-rendering: pixelated; pointer-events: none; transform-origin: 50% 100%;
  animation: alive 3.6s ease-in-out infinite, glow 2.6s ease-in-out infinite; filter: drop-shadow(0 0 4px var(--c)); }
.showcase::before { left: 30%; bottom: 20%; } .showcase::after { left: 66%; bottom: 14%; }

/* ---------- Attacks ----------
   .art.atk is set by attackFx() (main.js): lunge toward --tx/--ty with a wind-up tilt; biters also snap the lower jaw. Uses the
   individual translate/rotate properties so it layers over the idle animation. */
.art.atk { animation: lunge .34s ease-out; }
@keyframes lunge {
  0% { translate: 0 0; rotate: 0deg; }
  28% { translate: calc(var(--tx) * -.35) calc(var(--ty) * -.35); rotate: calc(var(--dir) * -7deg); }
  55% { translate: var(--tx) var(--ty); rotate: calc(var(--dir) * 11deg); }
  100% { translate: 0 0; rotate: 0deg; }
}
.unit[data-atk="smash"] .art.atk { animation-name: smash; }
@keyframes smash {
  0% { translate: 0 0; scale: 1; }
  35% { translate: 0 -8px; scale: 1.06 .96; }
  60% { translate: var(--tx) var(--ty); scale: .94 1.08; }
  100% { translate: 0 0; scale: 1; }
}
.art.atk .spr.parted img.jaw { animation: chomp .34s ease-out; }
.art.atk .spr.parted img.weapon { animation: wswing .34s ease-in-out; }
@keyframes wswing { 0%, 100% { rotate: 0deg; } 28% { rotate: calc(var(--w) * 1deg); } 58% { rotate: calc(var(--s) * 1deg); } }
/* the dark inside of the mouth shows only while the jaw is open */
.art.has-img .spr.hasjaw::before { content: ''; position: absolute; inset: 0; background: #2b0f1c; clip-path: var(--jclip); opacity: 0; }
.art.atk .spr.hasjaw::before { animation: mouth .34s ease-out; }
@keyframes mouth { 0%, 100% { opacity: 0; } 20%, 45% { opacity: 1; } }
@keyframes chomp { 0%, 100% { rotate: 0deg; } 30% { rotate: -34deg; } 55% { rotate: 2deg; } }
.unit[data-atk="bite"] .art.atk { animation-name: lunge; }
.fx { position: absolute; left: 50%; top: 45%; width: 44px; height: 44px; margin: -22px 0 0 -22px; pointer-events: none; z-index: 5; }
.fx.swing { border-radius: 50%; border: 5px solid transparent; border-right-color: #fff4c0; border-top-color: #ffd36a99; rotate: var(--rot); animation: slash .26s steps(5) forwards; }
.fx.swing::after { content: ''; position: absolute; inset: -9px; border-radius: 50%; border: 3px solid transparent; border-right-color: #fff; }
@keyframes slash { 0% { scale: .5; opacity: 1; transform: rotate(-70deg); } 100% { scale: 1.25; opacity: 0; transform: rotate(40deg); } }
.fx.smash, .fx.lunge { border-radius: 50%; background: radial-gradient(circle, #fff 0 18%, #ffb347aa 19% 45%, transparent 46%); animation: burst .28s steps(4) forwards; }
.fx.lunge { background: radial-gradient(circle, #ffd0d0 0 15%, #ff4a4aaa 16% 42%, transparent 43%); }
@keyframes burst { 0% { scale: .3; opacity: 1; } 100% { scale: 1.5; opacity: 0; } }
.fx.bite::before, .fx.bite::after { content: ''; position: absolute; left: 0; right: 0; height: 50%; background: #fff; }
.fx.bite::before { top: 0; clip-path: polygon(0 0, 100% 0, 100% 35%, 83% 100%, 67% 35%, 50% 100%, 33% 35%, 17% 100%, 0 35%); animation: fangT .3s steps(4) forwards; }
.fx.bite::after { bottom: 0; clip-path: polygon(0 100%, 100% 100%, 100% 65%, 83% 0, 67% 65%, 50% 0, 33% 65%, 17% 0, 0 65%); animation: fangB .3s steps(4) forwards; }
@keyframes fangT { 0% { translate: 0 -16px; opacity: 1; } 55% { translate: 0 1px; } 100% { translate: 0 1px; opacity: 0; } }
@keyframes fangB { 0% { translate: 0 16px; opacity: 1; } 55% { translate: 0 -1px; } 100% { translate: 0 -1px; opacity: 0; } }

/* ---------- Smaller monsters, crowd, roaming allies ---------- */
.art.foe { width: 54px; height: 54px; } .art.foe.boss { width: 96px; height: 96px; }
.crowd { position: absolute; inset: 0; z-index: 1; overflow: hidden; pointer-events: none; }
.mob { position: absolute; width: 30px; height: 30px; margin: -15px 0 0 -15px; animation: advance var(--t, 3s) ease-in-out var(--d, 0s) infinite alternate; }
.mob svg { width: 100%; height: 100%; image-rendering: pixelated; filter: drop-shadow(0 2px 0 #0009); animation: hop .5s steps(2) infinite; animation-delay: var(--d, 0s); }
.mob.east svg { transform: scaleX(-1); }
@keyframes advance { to { translate: var(--dx) var(--dy); } }
@keyframes hop { 50% { translate: 0 -2px; } }
.mob.pop { animation: advance var(--t, 3s) ease-in-out var(--d, 0s) infinite alternate, pop 1.4s linear; }
@keyframes pop { 0% { scale: 1; opacity: 1; } 8% { scale: 1.5 .6; filter: brightness(3); } 22% { scale: .2 1.6; opacity: 0; } 85% { opacity: 0; } 100% { scale: 1; opacity: 1; } }

/* ---------- Field units are sized in world units (--u px per unit, set from the engine's field size) ---------- */
.field .unit.champion { width: calc(var(--u, 2px) * 30); }
.field .unit.champion .art.champion { width: calc(var(--u, 2px) * 28); height: calc(var(--u, 2px) * 28); }
.field .unit.champion .art.hero { width: calc(var(--u, 2px) * 42); height: calc(var(--u, 2px) * 42); aspect-ratio: auto; }
.field .foes .unit { width: calc(var(--u, 2px) * 20); }
.field .foes .unit:not(.boss) .art.foe { width: calc(var(--u, 2px) * 19); height: calc(var(--u, 2px) * 19); }
.field .foes .unit.boss { width: calc(var(--u, 2px) * 46); }
.field .foes .unit.boss .art.foe { width: calc(var(--u, 2px) * 44); height: calc(var(--u, 2px) * 44); }
.field .unit.ally { width: calc(var(--u, 2px) * 20); }
.field .unit.ally .art.pet { width: calc(var(--u, 2px) * 16); height: calc(var(--u, 2px) * 16); }
.field .unit .nm { font-size: 11px; }


.stage.paused::after { content: 'PAUSED'; position: absolute; z-index: 4; bottom: 8px; left: 50%; transform: translateX(-50%); padding: 2px 10px; font-size: 12px; letter-spacing: 2px; color: #ffd36a; background: #000a; border: 1px solid #ffd36a; border-radius: 4px; pointer-events: none; }
.stage.showcase #championUnit, .stage.showcase .allies, .stage.showcase .pets { visibility: hidden; }
.field .foes .unit.still { width: calc(var(--u, 2px) * 63); transition: none; }
.field .foes .unit.still .art.foe, .field .foes .unit.still .art.champion { width: calc(var(--u, 2px) * 60); height: calc(var(--u, 2px) * 60); animation: none; }
.foes .unit.still .nm { display: block; font-size: 10px; }
.foes .unit.still .bar { display: none; }
.foes .unit.foe.west .art.foe.has-img:not(.pair) { scale: -1 1; } /* single-model PNG foes face left; west-side foes are mirrored (not --flip: the idle animation applies it twice) */
.unit.champion { will-change: transform; transition: transform .26s linear; } /* the view re-renders at 4 Hz; the glide fills the gaps */
.unit.champion .art.champion.pair { --flip: 1; } /* two-model champion: pick the model by facing instead of mirroring */
.unit.champion .art.champion.pair .spr + .spr, .unit.champion.faceR .art.champion.pair .spr:first-child { display: none; }
.unit.champion.faceR .art.champion.pair .spr + .spr { display: block; }
.art.foe.pair .spr + .spr, .foes .unit.foe.west .art.foe.pair .spr:first-child { display: none; }
.foes .unit.foe.west .art.foe.pair .spr + .spr { display: block; }
/* Champion models shown on the field via the show command (same facing rules as foe pairs) */
.foes .unit.foe .art.champion.pair .spr + .spr, .foes .unit.foe.west .art.champion.pair .spr:first-child { display: none; }
.foes .unit.foe.west .art.champion.pair .spr + .spr { display: block; }

/* Gear tab: champion beside a top-down column of equipment slots */
.doll { display: grid; grid-template-columns: 1fr 88px; gap: 12px; align-items: center; }
.doll .champion-pane { display: flex; flex-direction: column; align-items: center; gap: 6px; }
.doll .champion-pane .art { width: 100%; max-width: 160px; height: auto; aspect-ratio: 1; }
.doll .slot-col { display: flex; flex-direction: column; gap: 6px; }
.doll .art.champion.pair .spr + .spr { display: none; }
.doll { grid-template-columns: 1fr 72px; }
.doll .champion-pane .art { max-width: 200px; }

/* paper doll: helm over the champion, weapon left, armor right, amulet/boots/ring below */
.doll { grid-template-columns: 72px 1fr 72px; grid-template-areas: ". helm ." "weapon champion armor" "amulet boots ring"; justify-items: center; align-items: center; }
.doll .ds { width: 72px; }
.doll .ds-helm { grid-area: helm; } .doll .ds-weapon { grid-area: weapon; } .doll .ds-armor { grid-area: armor; }
.doll .ds-amulet { grid-area: amulet; } .doll .ds-boots { grid-area: boots; } .doll .ds-ring { grid-area: ring; }
.doll .ds-champion { grid-area: champion; }
.doll .champion-pane .art { max-width: 140px; }
.turntable { position: relative; display: block; width: 104px; height: 104px; margin: 0 -7px; } /* 1:1 with the 104px frames so the pixels stay crisp; spills into the grid gap */
.turntable img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; image-rendering: pixelated; opacity: 0; animation: turn 3.2s step-end infinite; }
.lshow { display: flex; justify-content: center; padding: 8px 0 4px; }
.lshow .turntable, .lshow .turntable.big { width: 264px; height: 264px; margin: 0; }
.turntable.big { width: 132px; height: 132px; margin: -14px -23px; } /* Hero models have more padding in their frames, so they get a larger slot */
@keyframes turn { 0% { opacity: 1; } 12.5% { opacity: 0; } 100% { opacity: 0; } } /* one facing shown at a time, stepping around the circle */
/* Flat-card spin for heroes without real rotations: 8 stepped widths round the turn, the back half dimmed; plus a slow breath from the feet. Same 3.2s period as the real turntable. */
.turntable.fake img { opacity: 1; transform-origin: 50% 92%; animation: fakespin 3.2s step-end infinite, breathe 2.6s ease-in-out infinite; }
@keyframes fakespin {
  0% { transform: scaleX(1); filter: none; } 12.5% { transform: scaleX(.71); filter: none; } 25% { transform: scaleX(.12); filter: none; }
  37.5% { transform: scaleX(-.71); filter: brightness(.72); } 50% { transform: scaleX(-1); filter: brightness(.72); } 62.5% { transform: scaleX(-.71); filter: brightness(.72); }
  75% { transform: scaleX(-.12); filter: none; } 87.5% { transform: scaleX(.71); filter: none; }
}
@keyframes breathe { 0%, 100% { scale: 1 1; } 50% { scale: 1 1.025; } }

/* Gems tab: hero + type x rank grid */
.gleg { display: grid; grid-template-columns: 1fr 1fr; gap: 6px 10px; }
.gl { display: flex; align-items: center; gap: 6px; font-size: 12px; }
.gl .art.gem { width: 24px; height: 24px; flex: none; }
.gl em { display: block; font-style: normal; color: var(--dim); font-size: 11px; }
.ggrid { display: grid; grid-template-columns: 62px repeat(5, 1fr); gap: 5px; align-items: center; }
.ggrid .gh { text-align: center; font-size: 9px; color: var(--gold); }
.ggrid .gt { font-size: 11px; color: var(--c); }
.gcell { position: relative; min-height: 0; aspect-ratio: 1; padding: 0; display: flex; align-items: center; justify-content: center; background: var(--panel); border: 2px solid var(--line); opacity: .4; }
.gcell .art.gem { width: calc(40% + var(--r, 0) * 8%); height: auto; aspect-ratio: 1; }
.gcell.r1 { --r: 0; } .gcell.r2 { --r: 1; } .gcell.r3 { --r: 2; } .gcell.r4 { --r: 3; } .gcell.r5 { --r: 4; }
.gcell.has { opacity: 1; border-color: var(--c); box-shadow: inset 0 0 calc(var(--r) * 4px) var(--c); }
.gcell.r5.has { box-shadow: inset 0 0 12px var(--c), 0 0 8px var(--c); border-color: var(--gold); }
.gcell b { position: absolute; right: 2px; bottom: 1px; font-size: 10px; font-weight: 400; background: #000b; padding: 0 3px; border-radius: 3px; }
.gcell.can { animation: gpulse 1.2s ease-in-out infinite; }
.gcell.can:disabled { opacity: 1; }
@keyframes gpulse { 50% { box-shadow: 0 0 10px var(--c), inset 0 0 10px var(--c); } }
.gleg { margin: 6px 0; }
.gemrow { display: flex; align-items: center; justify-content: space-between; gap: 8px; border-left: 3px solid var(--c); padding: 3px 0 3px 8px; margin: 4px 0; }
.gemchips { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 4px; }
.gchip { font-size: 11px; color: var(--dim); background: var(--panel); border: 1px solid var(--c); border-radius: 10px; padding: 1px 7px; white-space: nowrap; }
.gchip b { font-weight: 400; color: var(--text); }

/* Settings sheet */
#modal .card.settings { max-width: 360px; }
.slist { display: flex; flex-direction: column; gap: 6px; }
.slist button { min-height: 44px; text-align: left; padding: 0 12px; }

/* Settings list: small popover right-aligned directly above the Settings button */
#modal.pop { background: none; align-items: end; justify-items: end; padding: 0 6px calc(var(--navh, 56px) + 4px); padding-bottom: calc(var(--navh, 56px) + 4px); }
#modal.pop .card.settings { width: auto; min-width: 150px; max-width: 200px; padding: 6px; }
#modal.pop .slist button { white-space: nowrap; min-height: 40px; font-size: 13px; }
#modal.pop { padding: 0 var(--popr, 6px) calc(var(--navh, 56px) + 4px) 6px; }
#modal.pop { padding: 0; }
#modal.pop .card.settings { position: absolute; }
.badge.inl { position: static; display: inline-block; margin-left: 6px; vertical-align: middle; }

/* Forge preview and Workshop */
.odd { display: flex; align-items: center; gap: 8px; font-size: 12px; margin: 2px 0; }
.odd > :first-child { width: 96px; color: var(--c); }
.odd > :last-child { width: 40px; text-align: right; color: var(--dim); }
.odd .ob { flex: 1; height: 6px; background: var(--line); border-radius: 2px; overflow: hidden; }
.odd .ob i { display: block; height: 100%; background: var(--c); }
.pv { margin: 6px 0; }
.mt.sel { outline: 2px solid var(--gold); outline-offset: 1px; }
.card select.sm { max-width: 100%; }

/* Forge layout */
.fgopts { display: flex; flex-direction: column; gap: 8px; }
.fgopts > .sect { margin-top: 8px; }
.fggrid { display: grid; gap: 6px; }
.fggrid.c3 { grid-template-columns: repeat(3, 1fr); }
.fggrid.c2 { grid-template-columns: repeat(2, 1fr); }
.fggrid button { min-height: 44px; padding: 4px 6px; }
.fggrid button.ore { display: flex; flex-direction: column; align-items: center; gap: 2px; min-height: 76px; border-color: var(--line2); }
.fggrid button.ore.primary { border-color: var(--c, var(--gold)); background: color-mix(in srgb, var(--c, var(--gold)) 16%, var(--panel2)); color: var(--text); }
.fggrid button.ore.none { opacity: .45; }
.fggrid button.ore b { font-weight: normal; color: var(--gold); }
.fggrid select { max-width: none; width: 100%; }
.mixrow { display: flex; justify-content: space-between; align-items: center; }
.stepper { display: flex; align-items: center; gap: 8px; }
.stepper b { min-width: 64px; text-align: center; font-weight: normal; font-size: 12px; }
.stepper button { min-width: 40px; }
.fgmods { display: flex; flex-direction: column; gap: 6px; }
.mod > button { display: flex; align-items: center; gap: 10px; width: 100%; min-height: 52px; padding: 6px 10px; text-align: left; }
.mod.on > button { border-color: var(--gold); background: var(--gold-bg); }
.mod .mk { flex: none; width: 22px; height: 22px; border: 2px solid var(--line2); border-radius: 3px; display: grid; place-items: center; color: var(--gold); font-size: 14px; }
.mod.on .mk { border-color: var(--gold); }
.mod .mtx { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.mod .mc { flex: none; color: var(--gold); font-size: 12px; }
.mod select { margin-top: 6px; width: 100%; max-width: none; }
.fgbar { position: sticky; bottom: -20px; margin: 0 -2px -20px; padding: 8px 2px 24px; background: var(--bg); border-top: 2px solid var(--line); display: flex; flex-direction: column; gap: 4px; z-index: 2; }
.fgbar button { min-height: 48px; font-size: 16px; }

/* Workshop */
.bagwrap.ws .tiles.bag { max-height: calc(100cqw + 20px); margin-top: 6px; padding-bottom: 0; }
.wsfilt > summary { cursor: pointer; padding: 4px 0; }
.wsfilt[open] > summary { margin-bottom: 4px; }
.mt .bd.eq { right: 1px; bottom: 1px; color: var(--gold); }
.wsact { display: flex; align-items: center; gap: 12px; padding: 12px 2px; border-top: 2px solid var(--line); }
.wsact:first-of-type { border-top: 0; }
.wsact .wst { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; line-height: 1.3; }
.wsact .wst b { font-size: 15px; }
.wsact button { min-width: 104px; min-height: 44px; flex: none; padding: 4px 8px; line-height: 1.25; }
.need { color: var(--bad); font-size: 11px; }
.wsaff { display: flex; flex-direction: column; gap: 8px; padding: 12px 12px; margin-top: 8px; background: var(--panel2, var(--panel)); border: 2px solid var(--line); border-radius: var(--r); }
.wsahead { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
.wsahead b { font-weight: 400; }
.wsaval { color: var(--gold); font-size: 16px; }
.wslegend { display: flex; flex-wrap: wrap; gap: 4px 12px; margin-top: 4px; }
.wslegend b { font-weight: 400; color: var(--text); }
.wsmeta { display: flex; align-items: center; gap: 8px; }
.wsmeta .qbar { flex: 1; margin: 0; }
.wsmeta .qbar.good i { background: var(--accent2, var(--gold)); }
.wsmeta .qbar.top i { background: var(--gold); }
.wsmeta .qbar i { background: var(--dim); }
.wspips { display: flex; gap: 3px; }
.wspips i { width: 7px; height: 7px; border-radius: 50%; background: var(--line); }
.wspips i.on { background: var(--gold); }
.wsbtns { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
.wsb { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px; width: 100%; min-height: 48px; padding: 4px 6px; line-height: 1.2; }
.wsb small { color: var(--gold); font-size: 11px; }
.wsb:disabled small { color: var(--dim); }
.qbar { height: 6px; background: var(--line); border-radius: 2px; overflow: hidden; margin: 2px 0 6px; }
.qbar i { display: block; height: 100%; background: var(--accent2, var(--gold)); }
.qbar.q i { background: var(--gold); }
.wsmsg { border-color: var(--gold); color: var(--gold); }

/* ---------- Floors page ---------- */
.floorgrid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 6px; }
.floorgrid .fl { min-height: 48px; padding: 2px; position: relative; }
.floorgrid .fl i { position: absolute; top: 1px; right: 4px; font-style: normal; font-size: 11px; }
.floorgrid .fl.b-mini i { color: var(--dim); }
.floorgrid .fl.b-demi { border-color: var(--cyan); } .floorgrid .fl.b-demi i { color: var(--cyan); }
.floorgrid .fl.b-floor { border-color: var(--gold); } .floorgrid .fl.b-floor i { color: var(--gold); }
.floorgrid .fl.b-realm { border-color: var(--pink); } .floorgrid .fl.b-realm i { color: var(--pink); }
.floorgrid .fl.farm { background: var(--gold-bg); }
.floorgrid .fl.cur { box-shadow: inset 0 0 0 2px var(--green); }
.floorgrid .fl.sel { border-color: var(--text); background: var(--panel); }
button.on { border-color: var(--gold); color: var(--gold); }
.sb-art:empty { display: none; }

/* A worn Hero stands on the ground: no bob or rising sparkles, a dark contact shadow instead of a glow, and the empty
   frame under its feet is pulled down (--drop) so the feet sit on the unit's ground line. */
.unit.champion .art.hero.has-img .spr { animation: stand 3.2s ease-in-out infinite; filter: drop-shadow(0 2px 0 #0009); translate: 0 calc(var(--drop, 0%) + 6%); }
@keyframes stand { 0%, 100%, 50% { transform: scaleX(var(--flip, 1)); } }
.unit.champion .art.hero.has-img::before { left: 50%; bottom: 0; width: 70%; height: 8%; margin-left: -35%; background: #0007; border-radius: 50%; box-shadow: none; opacity: 1; animation: none; transform: none; z-index: -1; }
.unit.champion .art.hero.has-img::after { display: none; }
/* The champion drifts across the field all the time, so the worn Hero walks: a quick two-step bounce with a squash on the
   ground-side frame, over a shadow that stays put. The generic unit shadow is replaced by a wider one under the feet. */
.unit.champion:has(.art.hero.has-img)::before { display: none; }
.unit.champion .art.hero.has-img .spr img { transform-origin: 50% 92%; animation: walk .44s steps(2, jump-none) infinite; }
@keyframes walk { 0% { transform: translateY(0); } 100% { transform: translateY(-1px); } }
.unit.champion .art.hero.has-img::before { bottom: -12%; width: 80%; height: 11%; margin-left: -40%; background: #000a; }
/* Fenrir is posed three-quarter, so his rear paws sit higher in the frame than his front ones: a deeper shadow spans both rows. */
.unit.champion .art.hero.has-img[data-art="hero/fenrir"]::before { bottom: -6%; height: 23%; }
.unit.champion .art.hero.has-img[data-art="hero/fenrir"] .spr img { rotate: -9deg; } /* tips him nose-up so the rear paws come down towards the front ones */
.unit.champion:has(.art.hero.has-img) .nm, .unit.champion .bar { display: none; }
.field .unit:not(.still) .nm, .field .unit:not(.still) .bar { display: none; } /* no names or health bars over any sprite on the field (showcase poses keep their names) */

.lgauge { position: absolute; z-index: 4; right: 8px; bottom: 8px; width: 58px; height: 58px; pointer-events: none; }
.lgauge[hidden] { display: none; }
.lg-ring { position: absolute; inset: 0; border-radius: 50%; background: conic-gradient(#ffd36a calc(var(--p, 0) * 1%), #000a 0); -webkit-mask: radial-gradient(circle, transparent 22px, #000 23px); mask: radial-gradient(circle, transparent 22px, #000 23px); }
.lg-face { position: absolute; inset: 6px; border-radius: 50%; overflow: hidden; background: #090913; border: 1px solid #fff3; display: grid; place-items: center; }
.lg-face > * { width: 140%; height: 140%; max-width: none; object-fit: cover; object-position: 50% 20%; }
.lgauge b { position: absolute; left: 50%; bottom: -3px; transform: translateX(-50%); padding: 0 5px; border-radius: 6px; background: #000c; font-size: 9px; line-height: 13px; font-weight: 400; color: #ffd36a; }
.lgauge.full { filter: drop-shadow(0 0 6px #ffd36a); animation: lgpulse .7s ease-in-out infinite alternate; }
@keyframes lgpulse { to { transform: scale(1.08); } }

/* Hero special: a burst from Thor's hammer, Heimdall's eyes or Valkyrie's spear. --t is the tier (0 Basic .. 5 Deity): bigger, brighter, more rays, rings, and from tier 3 a stage flash. */
.lfx { position: absolute; width: 0; height: 0; pointer-events: none; z-index: 5; --c1: #fff; --c2: #6ad0ff; --s: calc(1 + var(--t) * .45 + var(--st, 0) * .1); }
.lfx.thor { --c1: #fff; --c2: #5ac8ff; }
.lfx.heimdall { --c1: #fff6c8; --c2: #ffc933; }
.lfx.valkyrie { --c1: #fff; --c2: #b8e4ff; }
.lfx.odin { --c1: #fff; --c2: #ffd35a; }
.lfx.freyja { --c1: #fff0f4; --c2: #ff7aa8; }
.lfx.loki { --c1: #f1dcff; --c2: #a64dff; }
.lfx.draugr { --c1: #eaffd9; --c2: #6fcf4a; }
.lfx.fenrir { --c1: #ffe0e0; --c2: #e03a3a; }
.lfx i { position: absolute; left: 0; top: 0; display: block; }
.lfx .glow { width: calc(var(--u, 2px) * 6 * var(--s)); height: calc(var(--u, 2px) * 6 * var(--s)); margin: calc(var(--u, 2px) * -3 * var(--s)); border-radius: 50%; background: radial-gradient(circle, var(--c1) 0 25%, var(--c2) 45%, transparent 70%); animation: lglow .7s ease-out forwards; }
.lfx .ring { width: calc(var(--u, 2px) * 14 * var(--s)); height: calc(var(--u, 2px) * 14 * var(--s)); margin: calc(var(--u, 2px) * -7 * var(--s)); border-radius: 50%; border: calc(1px + var(--t) * .5px) solid var(--c2); box-shadow: 0 0 6px var(--c2), inset 0 0 6px var(--c2); animation: lring .8s ease-out forwards; }
.lfx .ring.r2 { animation-delay: .15s; opacity: 0; border-color: var(--c1); }
.lfx .ray { width: calc(var(--u, 2px) * (8 + var(--t) * 3)); height: calc(1px + var(--t) * .6px); margin-top: calc(-.5px - var(--t) * .3px); transform-origin: 0 50%; rotate: var(--a); background: linear-gradient(90deg, var(--c1), var(--c2) 60%, transparent); box-shadow: 0 0 5px var(--c2); animation: lray .6s var(--d) ease-out both; }
.lfx.thor .ray { clip-path: polygon(0 40%, 25% 0, 45% 100%, 70% 20%, 100% 55%, 70% 80%, 45% 30%, 25% 100%); height: calc(3px + var(--t) * 1px); }
.lfx.t4, .lfx.t5 { filter: drop-shadow(0 0 8px var(--c2)); }
.lfx.t5 { animation: lhue 1s linear; }
.lfx.heimdall.t3 .ring, .lfx.heimdall.t4 .ring, .lfx.heimdall.t5 .ring { border-image: none; border-color: #ff6a6a; box-shadow: 0 0 8px #ffd35a, 0 0 8px #5ad8ff, inset 0 0 8px #b46aff; }
@keyframes lglow { 0% { scale: .2; opacity: 1; } 35% { scale: 1.1; opacity: 1; } 100% { scale: 1.6; opacity: 0; } }
@keyframes lring { 0% { scale: .2; opacity: 1; } 100% { scale: 1.8; opacity: 0; } }
@keyframes lray { 0% { scale: 0 1; opacity: 1; } 40% { scale: 1 1; opacity: 1; } 100% { scale: 1.2 .4; opacity: 0; } }
@keyframes lhue { to { filter: drop-shadow(0 0 8px var(--c2)) hue-rotate(360deg); } }
.skflash { position: absolute; inset: 0; z-index: 7; pointer-events: none; mix-blend-mode: screen; }
.stage.lflash::after { content: ''; position: absolute; inset: 0; z-index: 4; pointer-events: none; background: radial-gradient(circle at 50% 55%, #fff 0, #bfe6ff 40%, transparent 75%); opacity: 0; animation: lflash .5s ease-out; }
@keyframes lflash { 0% { opacity: calc(.2 + var(--lt, 3) * .1); } 100% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .lfx *, .stage.lflash::after { animation-duration: .01s; } }

/* ---------- Hero rarity ladder: glow, sparkles, orbiting motes, card sweep, prismatic top tier ----------
   Counts and glow radius come from hero_heroes.rarityFx (--glow, tier class rt0..rt5); sparkles are CSS-only spans. */
.art.has-img.rt .spr { animation: alive 3.2s ease-in-out infinite, rglow 2.4s ease-in-out infinite; filter: drop-shadow(0 0 calc(var(--glow) * .35) var(--c)); }
.art.has-img.rt5 .spr { animation: alive 3.2s ease-in-out infinite, prism 5s linear infinite; }
@keyframes rglow { 0%, 100% { filter: drop-shadow(0 0 calc(var(--glow) * .35) var(--c)); } 50% { filter: drop-shadow(0 0 var(--glow) var(--c)) drop-shadow(0 0 2px #fff6) brightness(1.1); } }
@keyframes prism {
  0%, 100% { filter: drop-shadow(0 0 var(--glow) #ff7ad9) brightness(1.1); } 25% { filter: drop-shadow(0 0 var(--glow) #ffd35a) brightness(1.15); }
  50% { filter: drop-shadow(0 0 var(--glow) #7affc8) brightness(1.1); } 75% { filter: drop-shadow(0 0 var(--glow) #7ab8ff) brightness(1.15); }
}
.sparks { position: absolute; inset: 0; pointer-events: none; z-index: 3; }
.sp { position: absolute; left: var(--x); top: var(--y); width: 12px; height: 12px; margin: -6px 0 0 -6px; opacity: 0; animation: twinkle var(--t) ease-in-out var(--d) infinite;
  background: linear-gradient(#fff, #fff) center / 100% 1px no-repeat, linear-gradient(#fff, #fff) center / 1px 100% no-repeat, radial-gradient(circle, #fff 0 18%, var(--c, #ffcf70) 38%, transparent 70%); }
@keyframes twinkle { 0%, 100% { opacity: 0; scale: .2; rotate: 0deg; } 50% { opacity: 1; scale: 1; rotate: 45deg; } }
.sp.em { width: 4px; height: 4px; margin: 0; background: radial-gradient(circle, #fff 0 25%, var(--c, #ffcf70) 55%, transparent 75%); animation: ember var(--t) linear var(--d) infinite; }
@keyframes ember { 0% { opacity: 0; translate: 0 6px; } 20% { opacity: 1; } 100% { opacity: 0; translate: 3px -34px; } }
.orbit { position: absolute; left: 50%; top: 58%; width: 0; height: 0; --orb: 34px; animation: orbit 5s linear infinite; }
.orbit .sp { left: 0; top: 0; margin: -4px; --t: 1.6s; animation: twinkle var(--t) ease-in-out infinite; transform: rotate(var(--a)) translateX(var(--orb)); }
@keyframes orbit { from { transform: rotateX(68deg) rotateZ(0deg); } to { transform: rotateX(68deg) rotateZ(360deg); } }
.mt .orbit, .dhead .orbit { --orb: 22px; }
.turntable .orbit { --orb: 62px; } .lshow .turntable .orbit { --orb: 120px; }
.mt .sparks > :nth-child(n+11), .dhead .sparks > :nth-child(n+11) { display: none; }
.unit .sparks > :nth-child(n+9) { display: none; }
/* card sweep (Mythic and up) and foil frame (Deity) */
.mt:has(.art.rt4)::after, .mt:has(.art.rt5)::after, .dhead:has(.art.rt4)::after, .dhead:has(.art.rt5)::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; z-index: 4;
  background: linear-gradient(110deg, transparent 35%, #ffffff55 50%, transparent 65%) 200% 0 / 250% 100%; animation: sweep 3.6s linear infinite; }
.dhead { position: relative; }
@keyframes sweep { to { background-position: -100% 0; } }
.mt:has(.art.rt5) { animation: foil 4s linear infinite; }
@keyframes foil { 0%, 100% { border-color: #ff7ad9; box-shadow: 0 0 9px #ff7ad9; } 25% { border-color: #ffd35a; box-shadow: 0 0 9px #ffd35a; } 50% { border-color: #7affc8; box-shadow: 0 0 9px #7affc8; } 75% { border-color: #7ab8ff; box-shadow: 0 0 9px #7ab8ff; } }
/* spin showcase: pulsing glow, ground ring, and a ring that bursts out when it opens */
.turntable.rt { animation: rglow 2.6s ease-in-out infinite; }
.turntable.rt5 { animation: prism 5s linear infinite; }
.turntable.rt::before { content: ''; position: absolute; left: 12%; right: 12%; bottom: 3%; height: 14%; border-radius: 50%; background: radial-gradient(ellipse, var(--c) 0, transparent 70%); opacity: .55; }
.lshow .turntable.rt::after { content: ''; position: absolute; left: 50%; bottom: 8%; width: 70%; height: 16%; margin-left: -35%; border-radius: 50%; border: 2px solid var(--c); box-shadow: 0 0 10px var(--c); animation: revealring 1s ease-out both; pointer-events: none; }
@keyframes revealring { from { scale: .2; opacity: .9; } to { scale: 1.7; opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .turntable.fake img { animation: none; } .sp, .orbit, .art.has-img.rt .spr, .turntable.rt, .mt:has(.art.rt5), .mt::after, .dhead::after { animation: none; } .sp { opacity: .8; scale: .8; } }

.aura-dot { display: inline-block; width: 10px; height: 10px; border-radius: 50%; background: var(--c); box-shadow: 0 0 6px var(--c); vertical-align: middle; }

/* ---------- Shop: dark and restrained. Matte gold = buy, violet = Crystals. ---------- */
.shop { display: flex; flex-direction: column; gap: 10px; }
.art.ico.svgicon { width: 16px; height: 16px; } .art.gem.svgicon { width: 32px; height: 32px; }
.art.ico.big { width: 48px; height: 48px; } .art.ico.lg { width: 48px; height: 48px; } .art.ico.xl { width: 96px; height: 96px; }
.art.ico.big, .art.ico.lg, .art.ico.xl { flex: none; }
.sh-champion { position: relative; overflow: hidden; padding: 14px; border: 1px solid #6a4aa8; border-radius: var(--r); background: linear-gradient(160deg, #1d1533, #0d0a18 60%, #130d26); text-align: center; }
.sh-glow { position: absolute; inset: -40% -10% auto; height: 120%; background: radial-gradient(closest-side, rgba(176, 92, 255, .2), transparent); pointer-events: none; }
.sh-bal { position: relative; display: flex; align-items: center; justify-content: center; gap: 10px; }
.sh-bal .art.ico { filter: drop-shadow(0 2px 6px #000a); }
.sh-bal .lbl { font-size: 10px; letter-spacing: .12em; text-transform: uppercase; color: #cdb2ff; text-align: left; }
.sh-bal b { font-size: 30px; line-height: 1; font-weight: 400; color: #fff;  }
.sh-sub { position: relative; margin-top: 8px; font-size: 12px; color: #cdb2ff; }
.sh-free { position: relative; overflow: hidden; margin-top: 10px; width: 100%; min-height: 44px; border-color: #b8902a; background: #241b07; color: #f0d98a; }
.sh-free i { content: ''; position: absolute; top: 0; left: -60%; width: 40%; height: 100%; background: linear-gradient(100deg, transparent, rgba(255, 255, 255, .45), transparent); transform: skewX(-20deg); animation: sweep 4.5s ease-in-out infinite; pointer-events: none; }
.sh-toast { position: sticky; top: 4px; z-index: 5; display: flex; align-items: center; justify-content: center; gap: 8px; padding: 10px; border: 1px solid #b8902a; border-radius: var(--r); background: #1d1608; color: #f0d98a; animation: spop .3s ease-out; box-shadow: 0 4px 14px #000a; }
.sh-toast .burst { position: absolute; inset: 0; pointer-events: none; background: radial-gradient(circle at 50% 50%, rgba(255, 255, 255, .25), transparent 60%); animation: sburst .6s ease-out forwards; }
.sh-toast .art.ico { width: 32px; height: 32px; position: relative; }
.sh-toast span { position: relative; }
.sh-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; margin-top: 6px; padding-bottom: 4px; border-bottom: 1px solid var(--line2); }
.sh-head span { font-size: 15px; letter-spacing: .08em; text-transform: uppercase; color: var(--gold); }
.sh-head em { font-style: normal; font-size: 11px; color: var(--dim); }
.sh-buy { position: relative; overflow: hidden; display: inline-flex; flex-direction: column; align-items: center; justify-content: center; min-height: 40px; padding: 4px 12px; }
.sh-buy small { font-size: 10px; opacity: .8; }
.sh-buy.hot { border-color: #b8902a; background: linear-gradient(180deg, #33290f, #1d1607); color: #f0d98a; }
.sh-buy.hot:disabled { box-shadow: none; }
.sh-buy .cr { display: inline-flex; align-items: center; gap: 4px; } .sh-buy .cr .art.ico { width: 16px; height: 16px; } .sh-buy .cr b { font-weight: 400; }
.ribbon { position: absolute; top: 8px; right: -30px; width: 110px; padding: 2px 0; transform: rotate(40deg); text-align: center; font-size: 10px; letter-spacing: .06em; text-transform: uppercase; background: #7a2434; color: #f2d6da; z-index: 2; }
.sh-feature { position: relative; overflow: hidden; display: grid; grid-template-columns: auto 1fr; gap: 8px 12px; padding: 12px; border: 1px solid #b8902a; border-radius: var(--r); background: linear-gradient(150deg, #2a2008, #110e08 70%); }
.sh-feature .sh-fart { align-self: center; } .sh-feature .sh-fart .art { filter: drop-shadow(0 3px 6px #000a); }
.sh-feature .sh-fbody { padding-right: 18px; } .sh-feature .sh-buy { grid-column: 1 / -1; }
.gis { display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0 2px; }
.gi { display: inline-flex; align-items: center; gap: 3px; padding: 1px 6px 1px 2px; background: #0008; border: 1px solid var(--line2); border-radius: 10px; } .gi .art.ico { width: 16px; height: 16px; } .gi b { font-weight: 400; font-size: 12px; }
.sh-was { font-size: 12px; color: #9fe8a8; } .sh-was s { color: var(--dim); }
.packs { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
.pack { position: relative; overflow: hidden; display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 10px 4px 8px; border: 1px solid #4a3578; border-radius: var(--r); background: linear-gradient(180deg, #1c1230, #0d0a18); text-align: center; }
.pack.tag { border-color: #8a62d0; }
.pack:last-child.tag { border-color: #b8902a; }
.pack .art.ico { margin-top: 16px; filter: drop-shadow(0 3px 5px #000a); }
.pack .ribbon { top: 0; left: 0; right: 0; width: auto; transform: none; font-size: 10px; padding: 1px 0; background: #4a3578; color: #e6dcff; } .pack:last-child .ribbon { background: #7a5c14; color: #fff1c4; }
.pack .amt { font-size: 20px; color: #fff; } .pack .nm { font-size: 10px; color: var(--dim); min-height: 26px; line-height: 1.2; }
.bonus { font-size: 11px; color: #9fcba8; } .bonus.none { visibility: hidden; }
.pack .sh-buy { width: 100%; margin-top: 4px; }
.bundles { display: grid; grid-template-columns: repeat(2, 1fr); gap: 6px; }
.bundle { display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 10px 6px 8px; text-align: center; border: 1px solid var(--line2); border-radius: var(--r); background: var(--panel); }
.bundle .nm { color: var(--text); } .bundle .amt { font-size: 12px; color: var(--cyan); min-height: 32px; }
.bundle .lim { display: flex; align-items: center; gap: 6px; min-height: 18px; } .bundle .sh-buy { width: 100%; margin-top: 4px; }
.pips { display: inline-flex; gap: 3px; } .pips i { width: 9px; height: 9px; border-radius: 2px; background: #1c1c33; border: 1px solid var(--line2); } .pips i.on { background: #b8902a; border-color: #d8b24a; }
.perk { display: flex; align-items: center; gap: 10px; padding: 10px; border: 1px solid var(--line2); border-radius: var(--r); background: var(--panel); }
.perk > div { flex: 1; min-width: 0; } .perk p { margin: 2px 0 4px; } .perk .sh-buy { min-width: 84px; }
.auras { display: grid; grid-template-columns: repeat(2, 1fr); gap: 6px; }
.aura { display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 10px 6px 8px; text-align: center; border: 1px solid var(--line2); border-radius: var(--r); background: var(--panel); }
.aura.worn { border-color: var(--c); }
.aura p { margin: 0; min-height: 30px; } .aura .sh-buy { width: 100%; margin-top: 4px; } .aura .nm { color: var(--c); }
.aura .orb { position: relative; width: 64px; height: 64px; display: grid; place-items: center; }
.aura .orb::before { content: ''; position: absolute; inset: 0; border-radius: 50%; background: radial-gradient(closest-side, var(--c), transparent); opacity: .45; }
.aura .orb i { position: relative; width: 22px; height: 22px; border-radius: 50%; background: #fff; box-shadow: 0 0 10px 2px var(--c); }
.sh-rates summary { cursor: pointer; min-height: 32px; display: flex; align-items: center; } .sh-rates > * + * { margin-top: 6px; }
@keyframes sfloat { 50% { transform: translateY(-4px) rotate(2deg); } }
@keyframes shpulse { 50% { opacity: .55; transform: scale(1.06); } }
@keyframes sglow { 50% { box-shadow: 0 0 16px rgba(240, 201, 58, .6); } }
@keyframes sweep { 0%, 55% { left: -60%; } 100% { left: 130%; } }
@keyframes spop { 0% { transform: scale(.6); opacity: 0; } 100% { transform: scale(1); opacity: 1; } }
@keyframes sburst { 0% { opacity: 1; transform: scale(.3); } 100% { opacity: 0; transform: scale(2.2); } }
@media (prefers-reduced-motion: reduce) { .sh-glow, .sh-bal .art, .sh-free, .sh-free i, .sh-buy.hot::after, .sh-feature, .sh-feature .art, .pack .art, .aura .orb::before, .sh-toast, .sh-toast .burst { animation: none; } }

/* ---------- FAQ ---------- */
.faq-cur { background: var(--panel); border: 1px solid var(--line2); border-radius: var(--r); margin-top: 6px; }
.faq-cur > summary { display: flex; align-items: center; gap: 10px; padding: 8px 10px; cursor: pointer; list-style: none; min-height: 56px; }
.faq-cur > summary::-webkit-details-marker { display: none; }
.faq-cur > summary::after { content: '+'; margin-left: auto; color: var(--dim); font-size: 18px; }
.faq-cur[open] > summary::after { content: '-'; }
.faq-cur[open] { border-color: var(--gold); }
.faq-cur .ft { display: flex; flex-direction: column; min-width: 0; } .faq-cur .ft b { font-weight: 400; color: var(--text); }
.faq-cur .ft em { font-style: normal; font-size: 10px; margin-left: 6px; padding: 0 5px; border: 1px solid var(--line2); border-radius: 8px; color: var(--dim); }
.faq-cur.soon .art { opacity: .7; }
.faq-body { padding: 0 12px 10px; } .faq-body .lbl { margin-top: 8px; font-size: 10px; letter-spacing: .1em; text-transform: uppercase; color: var(--gold); }
.faq-body ul { margin: 2px 0 0; padding-left: 18px; } .faq-body li { margin: 2px 0; } .faq-body p { margin: 2px 0 0; }

/* Skins grouped by rank */
.rankhd { display: flex; align-items: center; gap: 8px; margin: 10px 0 4px; padding: 0 10px; min-height: 40px; border-left: 4px solid var(--c); border-radius: var(--r); background: linear-gradient(90deg, color-mix(in srgb, var(--c) 22%, transparent), transparent 80%); cursor: pointer; user-select: none; }
.rankhd b { color: var(--c); font-size: 14px; letter-spacing: .08em; text-transform: uppercase; }
.rankhd .caret { font-style: normal; color: var(--dim); width: 12px; }
.tierlbl { margin: 6px 4px 2px; }
.routehd { margin: 12px 4px 2px; padding-left: 8px; border-left: 3px solid var(--c); font-size: 13px; font-weight: 700; color: var(--c); }
.rankhd .cnt { margin-left: auto; font-size: 12px; color: var(--dim); }

.stage .dps span { display: block; font-size: 9px; color: #c9b27a; }
.stage .dps { position: absolute; z-index: 3; left: 8px; bottom: 8px; padding: 2px 8px; font-size: 12px; color: #ffd36a; background: #000a; border: 1px solid #ffd36a66; border-radius: 4px; pointer-events: none; }
.fx.hit { width: 22px; height: 22px; margin: -11px 0 0 -11px; translate: var(--ox, 0) var(--oy, 0); border-radius: 50%; background: radial-gradient(circle, #fff 0 25%, #ffe27a 26% 55%, transparent 56%); animation: burst .24s steps(3) forwards; }
.fx.hit.pet { width: 16px; height: 16px; margin: -8px 0 0 -8px; background: radial-gradient(circle, #fff 0 25%, #6fe0ff 26% 55%, transparent 56%); }
.fx.hit.skill { width: 34px; height: 34px; margin: -17px 0 0 -17px; background: radial-gradient(circle, #fff 0 22%, var(--c, #c8a0ff) 23% 58%, transparent 59%); animation-duration: .32s; }
.fx.hit.crit { width: 36px; height: 36px; margin: -18px 0 0 -18px; background: radial-gradient(circle, #fff 0 22%, #ff9a3a 23% 60%, transparent 61%); }
.sfx { position: absolute; pointer-events: none; z-index: 6; image-rendering: pixelated; }
.sfx.smooth { image-rendering: auto; }
.field.fxstage { position: relative; inset: auto; height: 200px; margin: 8px 0; overflow: hidden; border: 1px solid #fff2; border-radius: 6px; background: #14161f repeating-linear-gradient(0deg, #0000 0 23px, #fff1 23px 24px), repeating-linear-gradient(90deg, #0000 0 23px, #fff1 23px 24px); }
.fx.cast { left: 50%; top: 50%; width: 60px; height: 60px; margin: -30px 0 0 -30px; border-radius: 50%; border: 3px solid var(--c, #c8a0ff); box-shadow: 0 0 10px var(--c, #c8a0ff), inset 0 0 8px var(--c, #c8a0ff); animation: castring .5s ease-out forwards; }
@keyframes castring { 0% { scale: .4; opacity: 1; } 100% { scale: 1.9; opacity: 0; } }
.dmg { position: absolute; left: 50%; top: 10%; z-index: 6; translate: var(--ox, 0) 0; font: 11px var(--font); color: #fff; text-shadow: 1px 1px 0 #000, -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000; pointer-events: none; white-space: nowrap; animation: dmgfloat .6s ease-out forwards; }
.dmg.pet { color: #8fe8ff; font-size: 9px; } .dmg.skill { color: #d9b8ff; } .dmg.crit { color: #ffb04a; font-size: 14px; }
@keyframes dmgfloat { 0% { transform: translate(-50%, 0); opacity: 1; } 100% { transform: translate(-50%, -26px); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .dmg { animation-duration: .01s; } }
.unit.ally .art.pet.mature { width: calc(var(--u, 2px) * 16 * var(--grow, 1.5)); height: calc(var(--u, 2px) * 16 * var(--grow, 1.5)); }
.foes .unit.dying { pointer-events: none; opacity: .0; transition: opacity .3s ease-in; }
.pullrow { display: grid; grid-template-columns: 96px 1fr 1fr; gap: 6px; align-items: stretch; }
.pullrow .chip { align-self: center; min-width: 0; }
.pullrow button { min-height: 58px; }
.pullrow button .sub { display: flex; justify-content: center; align-items: center; gap: 4px; font-size: 11px; opacity: .9; }
.pullrow button .sub.bonus { font-size: 10px; color: var(--accent2); }
.pullrow button:disabled .sub { opacity: .5; }

/* Sparkles and glows are switched off for Skins and pets: no rising white motes, orbiting sparks, glow pulse or card sweep. */
.art.has-img::before, .art.has-img::after, .showcase::before, .showcase::after { animation: none; }
.art.has-img .spr, .art.has-img.rt .spr, .art.has-img.rt5 .spr { animation: none; filter: drop-shadow(0 2px 0 #0009); }
.showcase img { animation: none; filter: drop-shadow(0 2px 0 #0009); }
.sparks, .orbit { display: none; }
.turntable.rt, .turntable.rt5, .mt:has(.art.rt5) { animation: none; }
.turntable.rt::before, .lshow .turntable.rt::after { display: none; }
.mt:has(.art.rt4)::after, .mt:has(.art.rt5)::after, .dhead:has(.art.rt4)::after, .dhead:has(.art.rt5)::after { display: none; }

/* Summon pages */
.summon-bg { position: relative; overflow: hidden; aspect-ratio: 2 / 1; min-height: 150px; display: flex; align-items: flex-start; justify-content: space-between; padding: 10px 12px; border: 2px solid var(--line2); border-radius: var(--r); background: linear-gradient(160deg, #1b1630, #0b0b18) center / cover no-repeat; background-blend-mode: normal; }
.summon-bg .title { font-size: 20px; text-shadow: 2px 2px 0 #000; }
.sb-wallet { display: flex; gap: 6px; }
.summon-bg .chip { background: #050509cc; }
.pitybox { display: flex; flex-direction: column; gap: 6px; padding: 8px 10px; border: 2px solid var(--line); border-radius: var(--r); background: var(--panel2, var(--panel)); }
.pitybar .bar.gauge > i { background: var(--c, var(--gold)); }
.pitybar > span { color: var(--c, var(--text)); }
.pitybar.near .bar { box-shadow: 0 0 8px var(--c, var(--gold)); }
.pitybar { display: grid; grid-template-columns: 82px 1fr 74px; gap: 8px; align-items: center; font-size: 12px; }
.pitybar b { text-align: right; font-weight: 400; color: var(--gold); }
.pitybar .bar { height: 10px; }
.wish { display: grid; grid-template-columns: 40px auto 1fr; gap: 8px; align-items: center; padding: 4px; border: 2px solid var(--c, var(--line2)); border-radius: var(--r); }
.wish .wpic { width: 40px; height: 40px; display: block; }
.wish .wpic .art { width: 40px; height: 40px; aspect-ratio: auto; }
.wish select { min-width: 0; }
.lshow .art.pet { width: min(100%, 240px); height: auto; aspect-ratio: 1; }

/* Boss health bar: the field hides per-unit bars, so a bosses gets one across the top of the stage */
.bossbar { position: absolute; left: 60px; right: 66px; top: 34px; z-index: 5; pointer-events: none; }
.bossbar[hidden] { display: none; }
.bossbar .bb-nm { display: block; text-align: center; font-size: 12px; color: #ff9aa8; text-shadow: 1px 1px 0 #000; margin-bottom: 2px; }
.bar.tall.boss { height: 16px; border-color: var(--red); } .bar.tall.boss > i { background: var(--red); } .bar.tall.boss span { justify-content: center; padding: 0; font-size: 11px; }

/* active consumables and the message when one is used */
.buffs { position: absolute; z-index: 3; top: 34px; left: 6px; right: 6px; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 4px; pointer-events: none; } /* one slot per tonic so all three sit in a row */
.buff { position: relative; overflow: hidden; font-size: 12px; padding: 1px 8px; background: #000a; border: 2px solid var(--line2); border-radius: 2px; color: var(--text); }
.buff > i { position: absolute; left: 0; bottom: 0; height: 2px; background: var(--green); }
.buff.msg { border-color: var(--green); grid-column: 1 / -1; }
.buff { padding: 1px 4px; text-align: center; line-height: 1.25; }
.buff b { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 11px; }
.buff .bt { display: block; font-size: 11px; }

/* Bulk sell modal */
.bslist { display: flex; flex-direction: column; gap: 6px; margin: 10px 0; }
.bsrow { display: flex; align-items: center; gap: 10px; min-height: 48px; padding: 0 12px; border: 2px solid var(--c, var(--line2)); text-align: left; }
.bsrow .bsn { flex: 1; color: var(--c); }
.bsck { width: 22px; height: 22px; border: 2px solid var(--c, var(--line2)); border-radius: 4px; display: grid; place-items: center; color: var(--text); }
.bsrow.on { background: color-mix(in srgb, var(--c, var(--gold)) 16%, var(--panel2, var(--panel))); }
.bsrow:disabled { opacity: .4; }

/* Stage progress strip: one node per floor of the current ten, the last is the Mini Boss */
.stagebar { display: flex; align-items: center; gap: 10px; padding: 6px 4px; }
.stagebar b { font-weight: 400; font-size: 15px; letter-spacing: 1px; white-space: nowrap; }
.stagebar .nodes { flex: 1; padding: 0 8px; display: flex; align-items: center; gap: 0; min-width: 0; }
.stagebar .nodes i { flex: 1 1 0; height: 4px; background: #2a3248; position: relative; }
.stagebar .nodes i::after { content: ''; position: absolute; left: -6px; top: 50%; width: 12px; height: 12px; margin-top: -6px; background: #4a5268; z-index: 1; }
.stagebar .nodes i.done, .stagebar .nodes i.done::after { background: #8a6a20; }
.stagebar .nodes i.cur::after { background: var(--gold); width: 16px; height: 16px; margin-top: -8px; left: -8px; }
.stagebar .nodes i.boss { flex: 0 0 0; height: 0; }
.stagebar .nodes i.boss::after { left: -8px; width: 16px; height: 16px; margin-top: -8px; background: var(--red); border: 2px solid #ffb0a8; box-sizing: border-box; }
.stagebar .nodes i.boss.cur::after { background: var(--gold); border-color: #fff; }

.faq-jump { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; margin: 0 0 6px; }
.faq-jump button.on { border-color: var(--gold); color: var(--gold); }
.faq-jump button { min-height: 44px; padding: 0 6px; font-size: 13px; white-space: nowrap; }
.soonTag { font-style: normal; font-size: 10px; margin-left: 6px; padding: 0 5px; border: 1px solid var(--line2); border-radius: 8px; color: var(--dim); }
.sh-free { display: flex; align-items: center; justify-content: center; gap: 8px; }
.sh-free .art.ico { position: relative; width: 24px; height: 24px; flex: none; }
#modal.pop .slist { max-height: calc(100vh - 90px); overflow-y: auto; } /* 16 entries: scroll on short phones */
/* Battle screen: circle buttons under the zone name, and the dungeon list they open */
.stagetools { position: absolute; z-index: 4; top: 34px; left: 6px; right: 6px; pointer-events: none; }
.stagetools > * { pointer-events: auto; }
.circles { display: flex; flex-direction: column; gap: 8px; width: 40px; }
.circle { width: 40px; height: 40px; min-height: 40px; padding: 0; border-radius: 50%; display: flex; align-items: center; justify-content: center; background: #000b; border: 2px solid var(--line2); color: var(--text); font-size: 16px; }
.circle .art { width: 34px; height: 34px; }
.circle .art.ico.svgicon { width: 28px; height: 28px; }
.circle.on { border-color: var(--gold); }
.circle.live { border-color: #ffd36a; box-shadow: 0 0 8px #ffd36a88; }
.circle.away { filter: grayscale(1); opacity: .55; }
.circle.dunicon { background: #000d; }
.circle.dunicon.locked { opacity: .5; }
.circle.leave { border-color: var(--red); color: var(--red); }
/* a Past Self card wears champion art but sits in Skin tiles: size it like a Skin picture */
.art.champion.past { width: 100%; height: auto; aspect-ratio: 3 / 4; overflow: hidden; }
.art.champion.past.pair .spr + .spr { display: none; } /* two-model art: Skin tiles show one side (the battle picks by facing, rule above) */
.doll .ds-champion { margin-top: 16px; position: relative; z-index: 1; } /* the spinning model spills past its cell: keep it clear of the helm slot above, and on top if it still touches */
/* the boss HP bar sits between the left tool circles and the right skill column, so nothing shifts when it appears */
.buffs { left: 54px; } /* leave room for the circle buttons on the left */
.sechead { display: flex; align-items: center; justify-content: space-between; width: 100%; min-height: 44px; padding: 0 10px; text-align: left; } /* collapsible card header */
/* Skin bursts are drawn on rectangular frames whose art fills the whole frame, so the straight edges showed. Fade them out in an ellipse inscribed in the frame. */
.sfx.smooth { -webkit-mask-image: radial-gradient(ellipse closest-side at 50% 50%, #000 68%, transparent 100%); mask-image: radial-gradient(ellipse closest-side at 50% 50%, #000 68%, transparent 100%); }

/* ---------- Season Pass ---------- */
.ttl { color: var(--gold); font-size: .8em; }
.pass-row { display: grid; grid-template-columns: 1fr 34px 1fr; gap: 8px; align-items: center; }
.pass-row.mile { border-color: var(--gold); } .pass-row.final { border-color: var(--gold); background: linear-gradient(#2a2108, #14110a); box-shadow: 0 0 14px rgba(255,190,80,.35); }
.rwds { display: flex; flex-wrap: wrap; gap: 4px; }
.rwd { display: inline-flex; align-items: center; gap: 4px; font-size: 14px; background: rgba(255,255,255,.05); border-radius: 4px; padding: 2px 5px; }
.rwd .ico, .rwd .art { width: 28px; height: 28px; } .rwd.cos { flex-basis: 100%; padding: 3px 5px; font-size: 11px; color: var(--gold); }
.pico { display: inline-flex; width: 34px; height: 34px; align-items: center; justify-content: center; flex: none; overflow: hidden; }
.pico .art { width: 34px; height: 34px; } .pico .art .spr, .pico .art img { max-width: 100%; max-height: 100%; }
.pico.glyph { font-weight: bold; font-size: 15px; color: var(--gold); border: 1px solid var(--line2); border-radius: 6px; }
.pass-hero { display: grid; grid-template-columns: 150px 1fr; gap: 12px; align-items: center; border-color: var(--gold); background: radial-gradient(circle at 20% 50%, #3a2a0a, #12100a 70%); }
.pass-hero .pass-art .turntable { width: 150px; height: 150px; margin: 0; } .pass-hero .pass-art .art.champion { width: 150px; height: 150px; } .pass-hero.owned { box-shadow: 0 0 14px rgba(255,190,80,.4); }
.pass-hero .art.pair .spr + .spr, .pico .art.pair .spr + .spr { display: none; }
.rwd .art.ico, .rwd .art.ico img { width: 28px; height: 28px; }
.pass-row.final .rwd.cos { font-size: 13px; } .pass-row.final .rwd.cos .pico, .pass-row.final .rwd.cos .pico .art { width: 64px; height: 64px; }

.lane { display: inline-block; padding: 1px 6px; border-radius: 10px; border: 1px solid var(--lc); color: var(--lc); font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; }
.lanehint { margin-top: 4px; }
.mt .bd.lane { left: 50%; top: 3px; transform: translateX(-50%); min-width: 14px; text-align: center; border-radius: 8px; background: var(--lc); color: #111; font-weight: 700; }
.tiles.bag .mt .bd.lane { top: 1px; }
.mt .bd.lane { font-size: 9px; padding: 0 3px; }

/* ---------- Frames (Settings > Display > UI frames): hand-drawn pixel 9-slice borders on <html data-frame="stone|iron"> ----------
   Big panels get stone (iron when the set is "iron"); every smaller box, row, button and field gets the iron band.
   Gold and red iron variants mark primary/selected and danger, so state still reads. */
html[data-frame] {
  --f-big: url(art/ui/frame_stone.png); --f-small: url(art/ui/frame_iron.png);
}
html[data-frame="iron"] { --f-big: url(art/ui/frame_iron.png); }
html[data-frame] :is(.card, #modal .card, button, .chip, .floor-badge, .lvbox, .slot, .item, .wsaff, .tile, .pack, .bundle, .perk, .aura, .sh-champion, .sh-feature, details.faq-cur, .zone, .pill, .dps, select, .snode, .setbox, .wish, .pitybox, .summon-bg) {
  /* layout keeps the old 2px border; the frame is drawn 4px wide, 2px of it outside the box, so padding and text are untouched */
  background-clip: padding-box; image-rendering: pixelated; border-style: solid; border-width: 2px;
  border-image-source: var(--f-small); border-image-slice: 4; border-image-width: 4px; border-image-outset: 2px; border-image-repeat: round;
}
html[data-frame] :is(.card, #modal .card) { border-image-source: var(--f-big); border-image-slice: 6; border-image-width: 6px; border-image-outset: 4px; }
html[data-frame="iron"] :is(.card, #modal .card) { border-image-slice: 4; border-image-width: 4px; border-image-outset: 2px; }
html[data-frame] :is(button.primary, button.on, .dps, .pill.dungeon) { border-image-source: url(art/ui/frame_iron_gold.png); }
html[data-frame] :is(button.danger, .pill.boss) { border-image-source: url(art/ui/frame_iron_red.png); }

/* ---------- Popup polish: a divider under every popup title, and padded value rows (Welcome back, reward summaries) ---------- */
#modal .card > .title:first-child { font-size: 18px; padding-bottom: 8px; border-bottom: 2px solid var(--line2); }
#modal .card > .row:has(> b:last-child) { margin: 0; padding: 8px 2px; border-bottom: 2px solid var(--line); }
#modal .card > p.dim { margin: 8px 0 4px; }
#modal .card > button.primary.block { margin-top: 14px; min-height: 46px; }

/* Item detail popup: roomier bonus-stat rows (the text wraps instead of cutting off), clearer button groups */
.detail .affix { padding-top: 10px; margin-top: 10px; gap: 10px; font-size: 13px; color: var(--text); }
.detail .affix .stat { white-space: normal; overflow: visible; line-height: 1.3; }
.detail .affix .btns { gap: 6px; }
.detail .affix .btns button { min-height: 36px; padding: 0 10px; font-size: 12px; }
.detail .item .btns { gap: 8px; margin-top: 12px; flex-wrap: wrap; }
.detail .item .btns button { min-height: 40px; }
.detail .affix.socks { padding-top: 12px; }

/* ---------- Bottom nav: hand-drawn pixel icons (art/ui/nav_*.png) instead of the thin line icons ---------- */
nav#tabs button .ico { display: none; }
nav#tabs button::before { content: ""; width: 29px; height: 29px; background: var(--nav-ico) center / contain no-repeat; image-rendering: pixelated; }
nav#tabs button[data-tab="champion"] { --nav-ico: url(art/ui/nav_champion.svg); } nav#tabs button[data-tab="champion"].on { --nav-ico: url(art/ui/nav_champion_on.svg); }
nav#tabs button[data-tab="summon"] { --nav-ico: url(art/ui/nav_summon.svg); } nav#tabs button[data-tab="summon"].on { --nav-ico: url(art/ui/nav_summon_on.svg); }
nav#tabs button[data-tab="gear"] { --nav-ico: url(art/ui/nav_gear.svg); } nav#tabs button[data-tab="gear"].on { --nav-ico: url(art/ui/nav_gear_on.svg); }
nav#tabs button[data-tab="forge"] { --nav-ico: url(art/ui/nav_forge.svg); } nav#tabs button[data-tab="forge"].on { --nav-ico: url(art/ui/nav_forge_on.svg); }
nav#tabs button#openSettings { --nav-ico: url(art/ui/nav_more.svg); }
nav#tabs button .badge { top: 2px; left: calc(50% + 10px); }

/* ---------- Battle HUD, less crowded: skill slots sit in a column over the arena's right edge, tighter bars and speed row ---------- */
.stage > .slots { position: absolute; z-index: 3; right: 8px; top: 44px; flex-direction: column; gap: 6px; align-items: flex-end; }
.stage > .slots .slot { width: 38px; height: 38px; background-color: #05050bcc; }
.battleTop { gap: 4px; }
.stagebar { padding: 2px 4px; }
.statrow { display: flex; gap: 6px; align-items: center; justify-content: center; }
button.spd { min-height: 26px; min-width: 44px; padding: 0 6px; }
.battleTop .stage { min-height: 300px; }

/* ---------- Readability: brighter secondary text, bigger helper text (Bag gem loadouts, notes) ---------- */
:root { --dim: #a2a2c0; }
.dim { font-size: 13px; line-height: 1.4; }
.dim.small { font-size: 12.5px; }
.row.tight { margin: 6px 0; }
.seg button:not(.on) { color: #b4b4cf; }

/* ---------- Skill slots: the icon is always fully visible; the cooldown is a recharge bar along the bottom, ready slots get a gold frame ---------- */
.slot .cd { top: auto; right: auto; left: 0; bottom: 0; height: 5px; width: 0; background: var(--gold); border: 0; z-index: 2; transition: width .2s linear; }
.slot.cooling::after { content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 5px; background: #000b; z-index: 1; }
.slot.cooling .art { opacity: .6; filter: saturate(.6); }
.slot.on:not(.cooling) .art { filter: drop-shadow(0 0 2px #000); }
.stage > .slots .slot, .slots .slot { background-color: #1b1b30; }
.stage > .slots .slot { width: 46px; height: 46px; }
html[data-frame] .slot.on:not(.cooling) { border-image-source: url(art/ui/frame_iron_gold.png); }
.slot.on:not(.cooling) { border-color: var(--gold); }
.stage > .slots .slot .art { filter: brightness(1.45) contrast(1.1); }
.stage > .slots .slot.cooling .art { filter: brightness(1.15) saturate(.6); opacity: .75; }
.stage > .slots .slot em { top: 1px; right: 3px; bottom: auto; font-size: 10px; }

/* ---------- Champion upgrades: icon + text on top, a full-width row of four equal buy buttons underneath ---------- */
.item:has(> .buys) { flex-wrap: wrap; row-gap: 10px; padding: 10px; }
.item:has(> .buys) .body { flex: 1 1 0; }
.item > .buys { flex: 1 1 100%; display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }
.item .buys .buy { min-width: 0; min-height: 42px; padding: 2px 4px; font-size: 13px; line-height: 1.25; }
.item .buys .buy:not(:disabled):not(.primary) { color: var(--text); }
.item .nm { font-size: 15px; }

/* Merchant tab: risk rows reuse the Workshop action layout */
.wsact + .wsact { margin-top: 6px; }

/* Special skins (Season Pass and event looks): a proper-sized portrait instead of the 34px reward icon */
.pico.big, .pico.big .art { width: 96px; height: 128px; }
.pico.big { overflow: visible; }
.row.tight:has(> .pico.big) { gap: 12px; align-items: center; padding: 6px 0; }
.spinbox { flex: none; width: 156px; height: 156px; display: flex; align-items: center; justify-content: center; }
.spinbox .turntable, .spinbox .turntable.big { width: 156px; height: 156px; margin: 0; }
.spinbox.locked { filter: brightness(.55) grayscale(.4); }
.row.tight:has(> .spinbox) { gap: 10px; align-items: center; padding: 6px 0; }

/* Corrupted gear: a rank above Primordial, drawn dark and wrong. The rank colour is #5c0f2a (hero_gear.json corrupted.color), matched below. */
.mt[style*="#5c0f2a"], .item[style*="#5c0f2a"] { background: radial-gradient(circle at 50% 40%, #1c0512, #030103 72%); border-color: #5c0f2a; animation: corruptPulse 2.6s ease-in-out infinite; }
.mt[style*="#5c0f2a"] .art, .item[style*="#5c0f2a"] .art { filter: brightness(.85) contrast(1.3) saturate(.35) drop-shadow(0 0 5px #b0123a); }
.item[style*="#5c0f2a"] .nm { color: #c3335f; text-shadow: 0 0 6px #7a0a2a; animation: corruptFlicker 3.3s steps(1) infinite; }
.stat.unk { color: #8a3050; letter-spacing: 4px; animation: corruptFlicker 2.1s steps(1) infinite; }
.stat.bad { color: #d0345f; text-shadow: 0 0 5px #5c0f2a; }
.corruptnote { color: #b04466; }
@keyframes corruptPulse { 0%, 100% { box-shadow: 0 0 4px #5c0f2a, inset 0 0 8px #000; } 50% { box-shadow: 0 0 15px #a01442, inset 0 0 14px #2a0010; } }
@keyframes corruptFlicker { 0%, 91%, 100% { opacity: 1; } 92% { opacity: .3; } 94% { opacity: .9; } 96% { opacity: .45; } }

.cmp { padding: 6px 8px; }
.cmp-r { display: grid; grid-template-columns: 1.1fr 1fr 1fr; gap: 6px; align-items: center; padding: 3px 0; font-size: 12px; border-top: 1px solid var(--line); }
.cmp-hd { border-top: 0; align-items: start; }
.cmp-h { display: flex; flex-direction: column; align-items: center; gap: 2px; text-align: center; min-width: 0; border-bottom: 2px solid var(--c, var(--line2)); padding-bottom: 4px; }
.cmp-h .art { width: 40px; height: 40px; }
.cmp-h > .small:nth-child(3) { overflow-wrap: anywhere; }
.cmp-s { color: var(--dim); }
.cmp-w, .cmp-n { text-align: center; font-weight: 700; }
.cmp-w { color: var(--dim); }
.cmp-n.up { color: var(--good); } .cmp-n.down { color: var(--bad); }
.agchips { display: flex; flex-wrap: wrap; gap: 6px; margin: 4px 0 8px; }
.agchip { min-height: 40px; padding: 0 12px; background: var(--panel); border-color: var(--line); color: var(--dim); font-size: 12.5px; }
.agchip { display: flex; flex-direction: column; align-items: flex-start; text-align: left; line-height: 1.25; padding-top: 4px; padding-bottom: 4px; }
.agchip small { font-size: 10.5px; opacity: .75; }
.agchip.fit { border-color: var(--gold); }
.agchip.on { border-color: var(--gold); color: var(--gold); background: var(--gold-bg); }

/* Quests / Achievements / Collection rows (claimlist.js) */
.qgrid { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.qtile { display: flex; flex-direction: column; gap: 4px; padding: 8px; background: var(--panel); border: 2px solid var(--line2); border-radius: var(--r); min-width: 0; }
.qtile.wide { grid-column: 1 / -1; }
.qtile.ready { border-color: var(--gold); }
.qtile.got { opacity: .65; }
.qnav { justify-content: center; gap: 12px; }
.qname { overflow-wrap: anywhere; }
.qside { margin-top: auto; text-align: center; }
.qside button { min-height: 44px; width: 100%; }
.qprog { font-size: 13px; color: var(--dim); }
.qok { color: var(--green); font-size: 18px; }
.qwide { display: flex; flex-direction: column; gap: 6px; }
/* Gear tiles (bag and worn): rank colour must read at a glance */
.mt.gt:not(.empty) { border-width: 3px; background: color-mix(in srgb, var(--c) 22%, var(--panel)); box-shadow: inset 0 0 8px color-mix(in srgb, var(--c) 45%, transparent); }
.mt.gt:not(.empty) .bd.lv { background: var(--c); color: #000; font-weight: 700; }

/* Event calendar: a grid of day tiles; the whole tile is the claim button */
.ecal { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }
.eday { display: flex; flex-direction: column; align-items: center; justify-content: space-between; gap: 6px; min-height: 96px; padding: 6px 4px; background: var(--panel2); border: 2px solid var(--line2); border-radius: var(--r); color: var(--text); }
.eday .en { font-size: 11px; color: var(--dim); letter-spacing: .06em; text-transform: uppercase; }
.eday .ert-list { display: flex; flex-direction: column; align-items: center; gap: 2px; flex: 1; justify-content: center; }
.eday .ert { display: flex; align-items: center; gap: 4px; font-size: 13px; }
.eday .ert b { font-weight: 400; color: var(--gold); }
.eday .ert .art, .eday .ert img { width: 22px; height: 22px; }
.eday .est { font-size: 11px; color: var(--dim); }
.eday.open { border-color: var(--gold); background: var(--gold-bg); box-shadow: 0 0 8px #f0c93a55; }
.eday.open .est { color: var(--gold); font-weight: 700; }
.eday.today .en { color: var(--gold); }
.eday.done { opacity: .5; } .eday.done .est { color: var(--green); font-size: 16px; }
.eday.later { opacity: .75; }
.eday.last { grid-column: span 2; border-width: 3px; }
.eday.last .ert .art, .eday.last .ert img { width: 28px; height: 28px; }
/* Tonic buffs sit under the boss HP bar (which takes the same top strip) and clear the skill slots on the right */
.buffs.lower { top: 72px; right: 62px; }

