/*
 * narvoda.css - a medieval phone screen.
 *
 * Materials, not colours: panels are parchment, the HUD is an oak beam, the
 * bottom bar is wrought iron with rivets, trim is tarnished gold leaf and
 * badges are wax seals. Every one of those is a token on :root so a later
 * change is one block, not a hunt through the file. No images: texture is
 * CSS gradients, pictures are inline SVG from assets/icons.php.
 *
 * Phone first at 360px. The frame is a flex column of exactly the viewport
 * height, the HUD and bar never scroll, and the middle either scrolls (cards)
 * or fills (the battle). Everything a thumb presses is at least 44px tall.
 *
 * Fonts are a local serif stack on purpose: no CDN, no @font-face, so the
 * live CSP has nothing to block and a slow connection has nothing to wait
 * for. Small caps and letter-spacing do the chiselled look.
 */
:root {
  color-scheme: dark;
  /* parchment */
  --parch:       #e9dcc0;
  --parch-dark:  #c9b387;
  --parch-edge:  #a08a5c;
  --ink:         #2b2118;
  --ink-muted:   #6d5a44;
  /* oak and iron */
  --oak:         #4a2f1b;
  --oak-light:   #6b4423;
  --oak-dark:    #2e1c10;
  --iron:        #1c1a18;
  --iron-light:  #3a3733;
  --rivet:       #6e6861;
  /* gold leaf, tarnished */
  --gold:        #c9a24a;
  --gold-light:  #e8cf7a;
  --gold-dark:   #7d5f1f;
  /* heraldry and wax */
  --red:         #8a1c1c;
  --blue:        #1f3a68;
  --wax:         #a5231f;
  --wax-dark:    #6e1210;
  --green:       #3f8a4a;
  --warn:        #c8862a;
  --xp:          #4a78b8;
  /* text on the dark surround */
  --text:        #efe4c8;
  --muted:       #a89c82;
  --bg:          #0f0c0a;
  --serif: "Palatino Linotype", Palatino, "Book Antiqua", Georgia, "Times New Roman", serif;
  --radius: 4px;
  /* aliases kept for the feature pages that used the old names */
  --card: var(--parch);
  --line: rgba(46, 28, 16, .35);
  --bg-top: var(--bg);
  --bg-bot: var(--bg);
}

* { box-sizing: border-box; }

html, body { margin: 0; padding: 0; height: 100%; }

body {
  background:
    radial-gradient(ellipse at 50% 0%, rgba(201, 162, 74, .08), transparent 60%),
    var(--bg);
  color: var(--text);
  font-family: var(--serif);
  font-size: 16px;
  line-height: 1.4;
  overflow-x: hidden;
  -webkit-text-size-adjust: 100%;
}

h1, h2, h3 {
  margin: 0;
  font-weight: 700;
  line-height: 1.2;
  font-variant: small-caps;
  letter-spacing: .06em;
}
h1 { font-size: 30px; }
h2 { font-size: 18px; }
p  { margin: 8px 0; }

.muted   { color: var(--muted); }
.small   { font-size: 13px; }
.gold    { color: var(--gold); }
.xp      { color: var(--xp); }
.ok-text { color: var(--green); }
.warn    { color: var(--warn); }
.hint    { margin: 10px 0 0; font-size: 14px; }
.inline  { display: inline; }
.center  { text-align: center; }
.stack   { display: grid; gap: 10px; }
.stack label { display: grid; gap: 4px; font-size: 14px; }
[hidden] { display: none !important; }
.sr-only {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}

/* ================================================================ frame */

body.app { overflow: hidden; }

.frame {
  position: relative;
  width: 100%;
  max-width: 480px;
  margin: 0 auto;
  height: 100vh;
  height: 100dvh;
  height: var(--vvh, 100dvh); /* the measured height from narvoda.js, see the note there (18 Sep 2026) */
  display: flex;
  flex-direction: column;
  background: #171310;
}
/* A dark surround with iron edges on anything wider than a phone. */
@media (min-width: 481px) {
  .frame { border-left: 2px solid var(--iron-light); border-right: 2px solid var(--iron-light); }
}

/* The middle. Feature pages scroll here; the Fight page fills it. */
.content {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 12px 12px 16px;
  background:
    radial-gradient(ellipse at 50% 100%, rgba(201, 162, 74, .06), transparent 60%),
    linear-gradient(180deg, #1b1612, #120f0c);
}
.page-game .content { padding: 0; overflow: hidden; display: flex; }

/* ================================================================== HUD */
/* An oak beam. The grain is two repeating gradients laid over the wood. */
.hud {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: calc(6px + env(safe-area-inset-top)) 10px 6px;
  background:
    linear-gradient(180deg, var(--oak-light), var(--oak) 60%, var(--oak-dark));
  border-bottom: 3px solid var(--iron);
  box-shadow: 0 3px 0 var(--iron-light), 0 6px 12px rgba(0, 0, 0, .6);
  z-index: 5;
}

/* The avatar: an iron-bound roundel with the class emblem inside. */
.hud-avatar {
  position: relative;
  flex: 0 0 auto;
  width: 50px; height: 50px;
  text-decoration: none;
}
.avatar-ring {
  display: flex; align-items: center; justify-content: center;
  width: 50px; height: 50px;
  border-radius: 50%;
  background: radial-gradient(circle at 40% 35%, #2a2420, #0e0c0a);
  border: 3px solid var(--iron-light);
  box-shadow: 0 0 0 1px var(--gold-dark), inset 0 0 0 2px var(--iron), 0 2px 6px rgba(0, 0, 0, .7);
}
.avatar-ring .emblem, .avatar-ring .ico { width: 26px; height: 26px; }
.avatar-small { width: 30px; height: 30px; border-width: 2px; vertical-align: middle; display: inline-flex; }
.avatar-small .emblem { width: 16px; height: 16px; }
/* the level: a little wax seal on the rim */
.lvl-badge {
  position: absolute; right: -4px; bottom: -3px;
  min-width: 20px; height: 20px; padding: 0 4px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #d9463d, var(--wax) 55%, var(--wax-dark));
  border: 1px solid var(--wax-dark);
  color: var(--gold-light);
  font-size: 11px; font-weight: 700; line-height: 18px; text-align: center;
  box-shadow: 0 1px 3px rgba(0, 0, 0, .8);
}

.hud-who { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.hud-name {
  font-variant: small-caps; letter-spacing: .05em; font-size: 16px;
  color: var(--parch);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  text-shadow: 0 1px 0 #000;
}
.hud-class { font-size: 11px; color: var(--parch-dark); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bar-mini { height: 7px; margin: 3px 0 0; max-width: 120px; }

.hud-right { flex: 0 0 auto; display: flex; flex-direction: column; align-items: flex-end; gap: 4px; }
.counters { display: flex; gap: 4px; }
/* coin pouches: a small parchment tag with the icon and the number */
.counter {
  display: inline-flex; align-items: center; gap: 3px;
  padding: 2px 6px 2px 4px;
  border-radius: 10px;
  background: linear-gradient(180deg, var(--parch), var(--parch-dark));
  border: 1px solid var(--oak-dark);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .5), 0 1px 2px rgba(0, 0, 0, .6);
  color: var(--ink);
  font-size: 12px; font-weight: 700;
  min-height: 22px;
}
.counter .ico { width: 15px; height: 15px; }
.counter-key { color: var(--ink); }
/* the stage: a banner hanging from the beam, swallow-tailed */
.chip-zone {
  padding: 3px 10px 8px;
  background: linear-gradient(180deg, #a32626, var(--red));
  border: 1px solid var(--gold-dark);
  border-top: 2px solid var(--gold);
  border-radius: 0;
  clip-path: polygon(0 0, 100% 0, 100% 100%, 50% 78%, 0 100%);
  color: var(--gold-light);
  font-size: 11px; font-variant: small-caps; letter-spacing: .04em;
  max-width: 170px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ================================================================ flash */
/* A parchment note pinned under the beam. narvoda.js takes it down after
 * a few seconds; without JS it stays, which is fine. */
.flash {
  position: absolute;
  left: 12px; right: 12px;
  top: calc(72px + env(safe-area-inset-top));
  z-index: 30;
  padding: 10px 14px;
  border-radius: var(--radius);
  background: linear-gradient(180deg, var(--parch), var(--parch-dark));
  border: 1px solid var(--oak-dark);
  border-left-width: 6px;
  color: var(--ink);
  font-size: 14px;
  box-shadow: 0 6px 16px rgba(0, 0, 0, .6);
  animation: flash-in .25s ease-out;
}
.flash-ok  { border-left-color: var(--green); }
.flash-bad { border-left-color: var(--wax); }
@keyframes flash-in { from { opacity: 0; transform: translateY(-8px); } }

/* ================================================================ cards */
/* Parchment. The fibre is a pair of faint repeating gradients. */
.card {
  position: relative;
  background:
    linear-gradient(180deg, var(--parch) 0%, #dccaa6 100%);
  border: 1px solid var(--oak-dark);
  border-radius: var(--radius);
  box-shadow: inset 0 0 0 1px rgba(255, 250, 235, .45), inset 0 0 40px rgba(120, 90, 50, .12), 0 3px 8px rgba(0, 0, 0, .5);
  padding: 12px 14px 14px;
  margin: 0 0 12px;
  color: var(--ink);
}
.card h1, .card h2, .card h3 { color: var(--oak-dark); }
.card .muted, .sheet .muted { color: var(--ink-muted); }
.card .gold, .sheet .gold { color: var(--gold-dark); }
.card .xp, .sheet .xp { color: var(--blue); }
.card .ok-text, .sheet .ok-text { color: #2f6b3a; }
.card .warn, .sheet .warn { color: #8a4a12; }
.card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 10px;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--gold-dark);
}
.card-head h2 { display: flex; align-items: center; gap: 6px; }
.card-head h2 .ico { width: 20px; height: 20px; }

.pill, .chip {
  display: inline-block;
  font-size: 12px;
  padding: 2px 9px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: rgba(46, 28, 16, .08);
  color: var(--ink-muted);
  white-space: nowrap;
  font-variant: small-caps; letter-spacing: .03em;
}
.chip { padding: 1px 8px; }
.pill-red { color: var(--parch); background: var(--wax); border-color: var(--wax-dark); }
.chip-gold {
  color: var(--ink);
  background: linear-gradient(180deg, var(--gold-light), var(--gold));
  border-color: var(--gold-dark);
}
.chip-on { color: var(--parch); background: var(--green); border-color: #265a2e; }
/* a dark iron chip, for text laid over the battle */
.chip-dark {
  display: inline-flex; align-items: center; gap: 4px;
  color: var(--parch);
  background: rgba(20, 16, 12, .75);
  border-color: var(--iron-light);
  font-variant: normal;
  padding: 3px 9px 3px 6px;
  min-height: 26px;
}
.chip-dark .ico { width: 14px; height: 14px; }
.locked { opacity: .5; }

/* ================================================================= bars */
.bar {
  height: 14px;
  border-radius: 3px;
  background: rgba(0, 0, 0, .35);
  border: 1px solid rgba(0, 0, 0, .5);
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, .6);
  overflow: hidden;
  margin: 4px 0 10px;
}
.bar-fill {
  height: 100%;
  transition: width .3s linear;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .3);
}
.bar-hp   { background: linear-gradient(180deg, #62b06c, var(--green)); }
.bar-mon  { background: linear-gradient(180deg, #d0463c, var(--wax)); }
.bar-xp   { background: linear-gradient(180deg, #6d9ad6, var(--xp)); }
.bar-gate { background: linear-gradient(180deg, var(--gold-light), var(--gold)); }
.bar-tiny { height: 6px; margin: 2px 0; border-radius: 2px; }

.fighter-row { display: flex; justify-content: space-between; gap: 8px; font-size: 14px; }
.fighter-row.small { font-size: 13px; }

/* ============================================================ stat grid */
.stat-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
  margin: 0 0 10px;
}
.stat-grid.three { grid-template-columns: repeat(3, 1fr); }
.stat-grid div {
  background: rgba(46, 28, 16, .07);
  border: 1px solid rgba(46, 28, 16, .25);
  border-radius: var(--radius);
  padding: 6px 4px;
  text-align: center;
}
.stat-grid dt { font-size: 11px; color: var(--ink-muted); font-variant: small-caps; letter-spacing: .04em; }
.stat-grid dd { margin: 2px 0 0; font-size: 18px; font-weight: 700; }

/* ============================================================== buttons */
/* Oak with an iron edge. Gold leaf for the one that matters. */
.btn {
  display: flex; align-items: center; justify-content: center; gap: 6px;
  width: 100%;
  min-height: 44px;
  padding: 8px 16px;
  border-radius: var(--radius);
  border: 1px solid var(--iron);
  background:
    linear-gradient(180deg, var(--oak-light), var(--oak) 60%, var(--oak-dark));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 2px 4px rgba(0, 0, 0, .5);
  color: var(--parch);
  font: inherit;
  font-weight: 700;
  font-variant: small-caps; letter-spacing: .05em;
  text-decoration: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.btn .ico { width: 18px; height: 18px; }
.btn:active { transform: translateY(1px) scale(.97); box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1); }
.btn-gold {
  background: linear-gradient(180deg, var(--gold-light), var(--gold) 55%, #9d7a2a);
  border-color: var(--gold-dark);
  color: var(--ink);
  text-shadow: 0 1px 0 rgba(255, 255, 255, .35);
}
.btn-red {
  background: linear-gradient(180deg, #b23a30, var(--red) 60%, #5a1210);
  border-color: var(--wax-dark);
  color: var(--parch);
}
.btn-big   { min-height: 52px; font-size: 19px; }
.btn-small { min-height: 36px; width: auto; padding: 6px 12px; font-size: 13px; }
.btn-ghost {
  background: transparent;
  box-shadow: none;
  border-color: currentColor;
  color: inherit;
  opacity: .85;
}
.btn:disabled, .btn[disabled] {
  opacity: .4;
  cursor: not-allowed;
  filter: grayscale(.7);
}
.btn:disabled:active { transform: none; }

input[type="text"], input[type="password"] {
  width: 100%;
  min-height: 44px;
  padding: 8px 12px;
  border-radius: var(--radius);
  border: 1px solid var(--oak-dark);
  background: #f4ead4;
  color: var(--ink);
  font: inherit;
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, .25);
}
input:focus { outline: 2px solid var(--gold); outline-offset: 1px; }

/* ============================================================= upgrades */
.upgrade-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 0;
  border-top: 1px solid rgba(46, 28, 16, .25);
}
.upgrade-row:first-of-type { border-top: 0; }
.upgrade-info { flex: 1; min-width: 0; }
.btn-buy { width: auto; flex: 0 0 auto; min-width: 104px; font-size: 14px; }

/* =================================================== rows (feature pages) */
.row-list { display: grid; gap: 8px; }
.row {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 8px 10px;
  border: 1px solid rgba(46, 28, 16, .3);
  border-radius: var(--radius);
  background: rgba(255, 250, 235, .35);
}
.row-info { flex: 1; min-width: 0; }
.row-info strong { display: block; }
.row .btn { width: auto; flex: 0 0 auto; min-width: 88px; font-size: 14px; }

/* =============================================================== ticker */
/* A strip of parchment scroll. The track holds the line twice and slides
 * by half its width, so the loop has no visible join. */
.ticker {
  flex: 0 0 auto;
  height: 24px;
  overflow: hidden;
  background:
    linear-gradient(180deg, rgba(0, 0, 0, .25), transparent 30%, transparent 70%, rgba(0, 0, 0, .25)),
    linear-gradient(180deg, var(--parch-dark), var(--parch) 50%, var(--parch-dark));
  border-top: 2px solid var(--oak-dark);
  border-bottom: 1px solid var(--oak-dark);
  color: var(--ink);
  font-size: 12px; font-style: italic;
  line-height: 22px;
  position: relative;
}
.ticker::before, .ticker::after {
  content: ""; position: absolute; top: 0; bottom: 0; width: 8px; z-index: 1;
  background: linear-gradient(90deg, var(--parch-edge), var(--parch-dark));
  border-right: 1px solid var(--oak-dark);
}
.ticker::before { left: 0; }
.ticker::after { right: 0; transform: scaleX(-1); }
.ticker-track {
  display: inline-flex;
  white-space: nowrap;
  animation: ticker 40s linear infinite;
  will-change: transform;
}
.ticker-track span { padding: 0 60px 0 12px; }
@keyframes ticker { to { transform: translateX(-50%); } }

/* ============================================================== the bar */
/* Wrought iron with rivets in the corners, seven wooden shields on it. */
.bar-btn { -webkit-tap-highlight-color: transparent; }
.navbar {
  flex: 0 0 auto;
  display: flex;
  justify-content: space-between;
  gap: 2px;
  height: auto;
  margin: 0;
  padding: 6px 4px calc(6px + env(safe-area-inset-bottom));
  border: 0;
  border-top: 3px solid var(--iron-light);
  border-radius: 0;
  overflow: visible;
  background:
    radial-gradient(circle at 6px 8px, var(--rivet) 2px, transparent 3px),
    radial-gradient(circle at calc(100% - 6px) 8px, var(--rivet) 2px, transparent 3px),
    radial-gradient(circle at 6px calc(100% - 8px), var(--rivet) 2px, transparent 3px),
    radial-gradient(circle at calc(100% - 6px) calc(100% - 8px), var(--rivet) 2px, transparent 3px),
    linear-gradient(180deg, #2a2724, var(--iron) 70%, #0c0b0a);
  box-shadow: 0 -4px 12px rgba(0, 0, 0, .6);
}
.bar-btn {
  flex: 1 1 0;
  min-width: 0;
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 2px 0 0;
  min-height: 58px;
  border: 0;
  background: none;
  color: var(--parch-dark);
  text-decoration: none;
  font: inherit;
  cursor: pointer;
}
/* the shield: oak, iron rim, gold frame, rounded to a point at the bottom */
.bar-ico {
  display: flex; align-items: center; justify-content: center;
  width: 40px; height: 40px;
  border-radius: 5px 5px 18px 18px;
  background:
    linear-gradient(180deg, var(--oak-light), var(--oak) 60%, var(--oak-dark));
  border: 2px solid var(--gold-dark);
  box-shadow: 0 0 0 1px var(--iron), inset 0 1px 0 rgba(255, 255, 255, .15), 0 2px 4px rgba(0, 0, 0, .6);
  color: var(--parch);
  transition: box-shadow .2s, transform .1s;
}
.bar-ico .ico { width: 22px; height: 22px; }
.bar-label { font-size: 11px; font-variant: small-caps; letter-spacing: .04em; line-height: 1; }
.bar-btn:active .bar-ico { transform: translateY(1px); }
.bar-on { color: var(--gold-light); }
.bar-on .bar-ico {
  border-color: var(--gold-light);
  color: var(--gold-light);
  box-shadow: 0 0 0 1px var(--gold-dark), 0 0 12px rgba(232, 207, 122, .55), inset 0 0 8px rgba(232, 207, 122, .25);
}

/* ============================================================ the scene */
/* Layers, back to front: sky, hills, ground, mist, then the fighters and
 * the numbers. The colours come from the zone block below. */
.scene {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
  --sky-a: #2a3a3a; --sky-b: #5a6b52;
  --hill-far: #263a2c; --hill-near: #1b2a20;
  --ground-a: #3b4a2a; --ground-b: #25301a;
  --mon-a: #5c6b3a; --mon-b: #3a4526;
}
.sky {
  position: absolute; left: 0; right: 0; top: 0; height: 62%;
  background: linear-gradient(180deg, var(--sky-a), var(--sky-b));
}
.hills {
  position: absolute; left: 0; right: 0; top: 34%; height: 30%; width: 100%;
}
.hill-far  { fill: var(--hill-far); }
.hill-near { fill: var(--hill-near); }
.keep      { fill: var(--hill-far); opacity: .85; }
/* cobbles: three offset dot grids read as laid stone from a phone away */
.ground {
  position: absolute; left: 0; right: 0; bottom: 0; height: 40%;
  background:
    radial-gradient(ellipse 12px 7px at 10px 8px, rgba(0, 0, 0, .18) 60%, transparent 62%) 0 0 / 26px 18px,
    radial-gradient(ellipse 12px 7px at 23px 17px, rgba(0, 0, 0, .14) 60%, transparent 62%) 0 0 / 26px 18px,
    radial-gradient(ellipse 12px 7px at 10px 8px, rgba(255, 255, 255, .05) 60%, transparent 62%) 13px 9px / 26px 18px,
    linear-gradient(180deg, var(--ground-a), var(--ground-b));
  border-top: 2px solid rgba(0, 0, 0, .35);
}
.mist {
  position: absolute; inset: 0;
  background:
    linear-gradient(180deg, rgba(0, 0, 0, .35), transparent 25%, transparent 75%, rgba(0, 0, 0, .45)),
    radial-gradient(ellipse at 50% 60%, rgba(255, 240, 200, .06), transparent 60%);
  pointer-events: none;
}

.scene-top {
  position: absolute; left: 8px; right: 8px; top: 8px;
  display: flex; align-items: center; justify-content: space-between;
  z-index: 3;
}
.scene-note {
  position: absolute; right: 8px; top: 62px; z-index: 3;
  margin: 0; padding: 4px 10px;
  max-width: 55%;
  font-size: 12px;
  background: rgba(20, 16, 12, .75);
  border: 1px solid var(--iron-light);
  border-radius: var(--radius);
  color: var(--gold-light);
}
/* the boss gate: a ring that fills as the kills come in */
.gate-ring {
  position: relative; width: 44px; height: 44px;
  display: flex; align-items: center; justify-content: center;
}
.gate-ring svg { position: absolute; inset: 0; width: 100%; height: 100%; transform: rotate(-90deg); }
.ring-bg { fill: rgba(20, 16, 12, .75); stroke: var(--iron-light); stroke-width: 3; }
.ring-fg {
  fill: none; stroke: var(--gold); stroke-width: 3; stroke-linecap: round;
  stroke-dasharray: var(--gate, 0) 100;
  transition: stroke-dasharray .4s ease-out;
}
.gate-ring b { position: relative; font-size: 10px; color: var(--parch); }

/* the round buttons down the left edge */
.edge {
  position: absolute; left: 8px; top: 62px; z-index: 4;
  display: flex; flex-direction: column; gap: 10px;
}
.edge-btn {
  position: relative;
  width: 50px; height: 50px;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0;
  border-radius: 50%;
  border: 2px solid var(--gold-dark);
  background: radial-gradient(circle at 40% 30%, var(--oak-light), var(--oak) 60%, var(--oak-dark));
  box-shadow: 0 0 0 2px var(--iron), 0 3px 6px rgba(0, 0, 0, .7);
  color: var(--parch);
  cursor: pointer;
  padding: 0;
  font: inherit;
  -webkit-tap-highlight-color: transparent;
}
.edge-btn .ico { width: 22px; height: 22px; }
.edge-label { font-size: 9px; font-variant: small-caps; letter-spacing: .05em; line-height: 1; }
.edge-btn:active { transform: translateY(1px); }
.edge-lit {
  border-color: #ff8a7a;
  animation: lit 1.4s ease-in-out infinite;
}
@keyframes lit {
  0%, 100% { box-shadow: 0 0 0 2px var(--iron), 0 0 6px rgba(255, 90, 70, .5); }
  50%      { box-shadow: 0 0 0 2px var(--iron), 0 0 18px rgba(255, 90, 70, .95); }
}
/* wax-seal badges */
.badge {
  position: absolute; top: -6px; right: -8px;
  min-width: 20px; height: 20px; padding: 0 5px;
  border-radius: 10px;
  font-size: 10px; font-weight: 700; line-height: 18px; text-align: center;
  border: 1px solid var(--wax-dark);
  background: radial-gradient(circle at 35% 30%, #d9463d, var(--wax) 55%, var(--wax-dark));
  color: var(--gold-light);
  box-shadow: 0 1px 3px rgba(0, 0, 0, .8);
  animation: badge-pulse 2s ease-in-out infinite;
}
.badge-gold { color: var(--gold-light); }
.badge-red { animation-duration: 1s; }
@keyframes badge-pulse { 50% { transform: scale(1.12); } }

/* the fighters stand on the ground line */
.fighters {
  position: absolute; left: 0; right: 0; bottom: 21%;
  display: flex; justify-content: space-between; align-items: flex-end;
  padding: 0 6px 0 62px;
  z-index: 2;
}
.spot { position: relative; width: 108px; }
.spot-hero { margin-left: 4%; }
.tag {
  position: absolute; left: 50%; top: -40px; width: 104px;
  transform: translateX(-50%);
  text-align: center;
  font-size: 11px; line-height: 1.1;
  color: var(--parch);
  text-shadow: 0 1px 0 #000, 0 0 4px #000;
}
.tag-name { display: block; font-variant: small-caps; letter-spacing: .04em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tag-hp { display: block; font-size: 10px; color: var(--parch-dark); }
.tag .bar { margin: 2px 6px; }

.sprite { display: block; width: 100%; height: auto; overflow: visible; }
.sprite-hero { width: 96px; animation: bob 2.2s ease-in-out infinite; transform-origin: 50% 100%; }
.sprite-hero .arm { transform-origin: 46px 36px; }
.sprite-mon { width: 108px; animation: mon-bob 2.6s ease-in-out infinite; transform-origin: 50% 100%; }
.mon-flyer { animation: hover 1.8s ease-in-out infinite; }
.mon-flyer .wing { transform-origin: 40px 30px; animation: flap .5s ease-in-out infinite alternate; }
.mon-flyer .wing-r { animation-name: flap-r; }
.mon-dragon .wing { transform-origin: 36px 30px; animation: flap .9s ease-in-out infinite alternate; }
.mon-shadow .body { animation: shimmer 2s ease-in-out infinite; }
/* BREATHING, FEET PLANTED (21 Sep 2026, "keep the feet planted firmly on the ground plane while the upper body gently
   sways or bobs"): the bob used to lift the whole figure 3px, feet and all, so he hovered. Now the chest rises by a
   scale from the feet (transform-origin is 50% 100% on every sprite) and nothing leaves the ground. */
@keyframes bob     { 50% { transform: scaleY(1.022) scaleX(.993); } }
@keyframes mon-bob { 50% { transform: scaleY(1.018) scaleX(1.012); } }
@keyframes hover   { 50% { transform: translateY(-8px); } }
@keyframes flap    { from { transform: rotate(-8deg); } to { transform: rotate(10deg); } }
@keyframes flap-r  { from { transform: rotate(8deg); }  to { transform: rotate(-10deg); } }
@keyframes shimmer { 50% { opacity: .75; } }

/* scene.js toggles these: the hero lunges, the monster flinches, dies, and
 * the next one steps in */
.spot-hero.lunge .sprite-hero { animation: lunge .3s ease-out; }
.spot-hero.lunge .arm { animation: swing .3s ease-out; }
@keyframes lunge { 30% { transform: translateX(22px); } 100% { transform: translateX(0); } }
@keyframes swing { 30% { transform: rotate(-35deg); } 100% { transform: rotate(0); } }
.spot-mon.hit .sprite-mon { animation: shake .22s linear; }
@keyframes shake {
  25% { transform: translateX(4px) rotate(2deg); }
  75% { transform: translateX(-4px) rotate(-2deg); }
}
.spot-mon.dead .sprite-mon { animation: die .45s ease-in forwards; }
@keyframes die { to { opacity: 0; transform: translateY(10px) scale(.8) rotate(12deg); } }
.spot-mon.spawn .sprite-mon { animation: spawn .4s ease-out; }
@keyframes spawn { from { opacity: 0; transform: translateX(40px); } }
.spot-hero.hurt .sprite-hero { animation: hurt .25s linear; }
@keyframes hurt { 50% { filter: brightness(1.8) sepia(1) hue-rotate(-40deg); } }

/* the numbers */
.floaters { position: absolute; inset: 0; pointer-events: none; z-index: 6; overflow: hidden; }
.float {
  position: absolute;
  transform: translate(-50%, 0);
  font-weight: 700;
  font-size: 24px;
  color: #fff3d0;
  text-shadow: 0 2px 0 #1a0f08, 0 0 6px rgba(0, 0, 0, .9);
  letter-spacing: .02em;
  animation: float-up 1.1s ease-out forwards;
  white-space: nowrap;
}
.float-hurt { font-size: 16px; color: #ff9a8a; }
.float-gold { font-size: 17px; color: var(--gold-light); animation-duration: 1.5s; }
.float-crit { font-size: 36px; color: #ffd36b; animation: crit-up 1.4s ease-out forwards; }
/* the CRIT stamp: a red wax seal pressed at a slant */
.float-crit .stamp {
  display: inline-block;
  margin-right: 6px;
  padding: 7px 5px;
  border-radius: 50%;
  font-size: 11px; letter-spacing: .15em; line-height: 1;
  color: var(--parch);
  text-shadow: none;
  background: radial-gradient(circle at 35% 30%, #d9463d, var(--wax) 55%, var(--wax-dark));
  border: 2px solid #ffb3a7;
  box-shadow: 0 2px 4px rgba(0, 0, 0, .7), inset 0 0 0 2px var(--wax-dark);
  transform: rotate(-14deg);
  vertical-align: middle;
}
@keyframes float-up {
  0%   { opacity: 0; transform: translate(-50%, 6px) scale(.6); }
  15%  { opacity: 1; transform: translate(-50%, -8px) scale(1.15); }
  100% { opacity: 0; transform: translate(-50%, -76px) scale(1); }
}
@keyframes crit-up {
  0%   { opacity: 0; transform: translate(-50%, 10px) scale(.4); }
  12%  { opacity: 1; transform: translate(-50%, -10px) scale(1.3); }
  25%  { transform: translate(-50%, -14px) scale(1.05); }
  100% { opacity: 0; transform: translate(-50%, -90px) scale(1); }
}

.rates {
  position: absolute; left: 8px; right: 8px; bottom: 8px; z-index: 3;
  display: flex; justify-content: center; flex-wrap: wrap; gap: 4px 12px;
  font-size: 11px;
  color: var(--parch);
  text-shadow: 0 1px 0 #000, 0 0 4px #000;
}
.rates .gold { color: var(--gold-light); }
.rates .xp { color: #9ec0f0; }

/* ------------------------------------------------- zone palettes */
/* One block per zone, keyed on data-zone from nv_zone_name(). Each sets
 * the sky, the hills, the ground and the two monster fills. */
[data-zone="marshes"] .scene        { --sky-a: #2a3a3a; --sky-b: #5a6b52; --hill-far: #263a2c; --hill-near: #1b2a20; --ground-a: #3b4a2a; --ground-b: #25301a; --mon-a: #5c6b3a; --mon-b: #3a4526; }
[data-zone="thornwood"] .scene      { --sky-a: #2c2438; --sky-b: #55404c; --hill-far: #2e2c1e; --hill-near: #1c1c14; --ground-a: #3d3124; --ground-b: #241c14; --mon-a: #6a4a3a; --mon-b: #40291f; }
[data-zone="ashlands"] .scene       { --sky-a: #3a2420; --sky-b: #86402c; --hill-far: #3e2b26; --hill-near: #241816; --ground-a: #3d3232; --ground-b: #1f1a1a; --mon-a: #8a4030; --mon-b: #4a2018; }
[data-zone="frostreach"] .scene     { --sky-a: #1e2a44; --sky-b: #8aa8c4; --hill-far: #5e738e; --hill-near: #3c4e66; --ground-a: #c4d2de; --ground-b: #8ea3b8; --mon-a: #7aa0c0; --mon-b: #4a6a8a; }
[data-zone="ridge"] .scene          { --sky-a: #2a2a3c; --sky-b: #757585; --hill-far: #4c4c54; --hill-near: #2e2e36; --ground-a: #5a5248; --ground-b: #3a342c; --mon-a: #7a7062; --mon-b: #4a4238; }
[data-zone="salt-wastes"] .scene    { --sky-a: #4a3a2a; --sky-b: #cfae7e; --hill-far: #a89880; --hill-near: #7a6c58; --ground-a: #d8c8a8; --ground-b: #a89878; --mon-a: #b8a888; --mon-b: #7a6a50; }
[data-zone="nightfall-vale"] .scene { --sky-a: #0c0c1c; --sky-b: #2e1e4c; --hill-far: #1e1634; --hill-near: #100c1e; --ground-a: #221b36; --ground-b: #0f0c18; --mon-a: #52407a; --mon-b: #2a1c44; }
[data-zone="dragon-ruins"] .scene   { --sky-a: #2a1010; --sky-b: #7a2e1c; --hill-far: #3e2222; --hill-near: #221212; --ground-a: #4a2a1a; --ground-b: #2a1810; --mon-a: #962c2c; --mon-b: #4a1414; }
/* light zones need dark text on the ground */
[data-zone="frostreach"] .rates, [data-zone="salt-wastes"] .rates { color: #fff; }

/* =============================================================== sheets */
/* Unrolled scrolls that slide up over the scene. narvoda.js flips the
 * hidden attribute; nothing here needs JS to be drawn. */
.sheet-back {
  position: fixed; inset: 0; z-index: 40;
  background: rgba(8, 6, 4, .6);
  animation: fade-in .2s ease-out;
}
@keyframes fade-in { from { opacity: 0; } }
.sheet {
  position: fixed;
  left: 50%; bottom: 0;
  transform: translateX(-50%);
  width: 100%; max-width: 480px;
  max-height: 86vh; max-height: 86dvh;
  z-index: 41;
  display: flex; flex-direction: column;
  padding: 6px 14px calc(14px + env(safe-area-inset-bottom));
  background:
    linear-gradient(180deg, var(--parch) 0%, #dccaa6 100%);
  border: 2px solid var(--oak-dark);
  border-bottom: 0;
  border-radius: 10px 10px 0 0;
  box-shadow: 0 -8px 30px rgba(0, 0, 0, .7), inset 0 0 40px rgba(120, 90, 50, .15);
  color: var(--ink);
  overflow-y: auto;
  animation: sheet-up .28s ease-out;
}
@keyframes sheet-up { from { transform: translate(-50%, 100%); } }
/* the rolled top of the scroll */
.sheet-grip {
  flex: 0 0 auto;
  height: 14px;
  margin: 0 -8px 8px;
  border-radius: 7px;
  background: linear-gradient(180deg, var(--parch-edge), #e2d2a8 40%, #8f7a4c);
  border: 1px solid var(--oak-dark);
  box-shadow: 0 2px 3px rgba(0, 0, 0, .35);
}
.sheet .card-head { flex: 0 0 auto; }
.sheet h2 { color: var(--oak-dark); flex: 1; min-width: 0; }
.sheet-scroll { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
/* the close button: a wax seal */
.btn-close {
  width: 40px; min-height: 40px; height: 40px; padding: 0;
  border-radius: 50%;
  border: 2px solid var(--wax-dark);
  background: radial-gradient(circle at 35% 30%, #d9463d, var(--wax) 55%, var(--wax-dark));
  box-shadow: 0 2px 4px rgba(0, 0, 0, .6), inset 0 0 0 2px rgba(255, 200, 190, .25);
  color: var(--parch);
  opacity: 1;
  flex: 0 0 auto;
}
.btn-close .ico { width: 18px; height: 18px; }
.boss-row { display: flex; gap: 12px; align-items: center; margin-bottom: 10px; }
.boss-pic { flex: 0 0 90px; width: 90px; --mon-a: #7a2e22; --mon-b: #3a1410; }
.boss-pic .sprite { animation: mon-bob 2.6s ease-in-out infinite; }
.boss-info { flex: 1; min-width: 0; }
.boss-info .bar { margin-bottom: 0; }
.logout-row { margin: 16px 0 4px; display: flex; justify-content: center; }
.logout-row .btn { color: var(--ink-muted); }

/* ================================================= title and choose */
.title-frame {
  max-width: 480px;
  margin: 0 auto;
  min-height: 100vh; min-height: 100dvh;
  padding: 16px 16px calc(32px + env(safe-area-inset-bottom));
  background:
    radial-gradient(ellipse at 50% 100%, rgba(201, 162, 74, .07), transparent 60%),
    linear-gradient(180deg, #1b1612, #120f0c);
}
@media (min-width: 481px) {
  .title-frame { border-left: 2px solid var(--iron-light); border-right: 2px solid var(--iron-light); }
}
.hero-title { text-align: center; padding: 10px 0 18px; }
.title-art { width: 230px; max-width: 80%; height: auto; display: block; margin: 0 auto 6px; filter: drop-shadow(0 6px 10px rgba(0, 0, 0, .7)); }
.hero-title h1 {
  color: var(--gold-light);
  background: linear-gradient(180deg, #fbe6a0, var(--gold) 60%, #9d7a2a);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
  filter: drop-shadow(0 2px 0 #3a2a10);
}
.tagline { color: var(--parch-dark); font-style: italic; margin: 6px 0 0; font-size: 15px; }
/* The gate used to pin the note in the flow, but the toast is centred by a translate(-50%) in its own keyframes, so a static one
   was shoved half off the left edge ("the wrong password is off the screen", 20 Sep 2026). It floats like everywhere else now. */
.title-frame .flash { position: fixed; }

.auth-grid { display: grid; gap: 12px; }
@media (min-width: 560px) { .auth-grid { grid-template-columns: 1fr 1fr; } }
.class-card { display: block; }
.class-card .card-head { border-bottom: 0; padding-bottom: 0; margin-bottom: 4px; }
.class-card .blurb { color: var(--ink-muted); margin: 0 0 10px; font-style: italic; }
.class-figure { flex: 0 0 auto; width: 64px; height: 64px; }
.class-figure .sprite { width: 64px; height: 64px; animation: bob 2.2s ease-in-out infinite; }

/* ---- the Treasury's two marks on the HUD: rank under the name, Crowns ---- */
.hud-rank {
  display: block; font-size: 10px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--gold-light); line-height: 1.1; margin-top: 1px;
}
a.counter-crown { text-decoration: none; color: var(--ink); }
.counter-crown .plus {
  margin-left: 2px; width: 14px; height: 14px; border-radius: 50%;
  background: var(--wax); color: #fff; font-size: 11px; line-height: 14px; text-align: center;
  box-shadow: 0 1px 1px rgba(0,0,0,.5);
}

/* ---- the login, centred, in an iron-bound oak box (16 Sep 2026: "this is ugly") ---- */
.title-frame {
  display: flex; flex-direction: column; justify-content: center; align-items: stretch;
  background-image:
    radial-gradient(ellipse at 50% 30%, rgba(201, 162, 74, .10), transparent 55%),
    linear-gradient(180deg, #1b1612, #0f0c0a);
}
.title-frame.has-gate-art {
  background-image:
    linear-gradient(180deg, rgba(15, 12, 10, .55), rgba(15, 12, 10, .85)),
    url(../images/gate.png);
  background-size: cover; background-position: center top;
}
.gate-box {
  position: relative;
  margin: 8px auto 0; width: 100%; max-width: 440px;
  padding: 18px 16px 16px;
  border-radius: 10px;
  background: linear-gradient(180deg, var(--oak-light), var(--oak) 40%, var(--oak-dark));
  border: 3px solid var(--gold-dark);
  outline: 2px solid var(--iron);
  box-shadow:
    inset 0 1px 0 rgba(255, 230, 160, .25),
    inset 0 0 0 1px rgba(0, 0, 0, .5),
    0 14px 30px rgba(0, 0, 0, .7);
}
/* four iron rivets in the corners */
.gate-box::before, .gate-box::after {
  content: ""; position: absolute; width: 10px; height: 10px; border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, var(--rivet), var(--iron) 70%);
  box-shadow: 0 1px 1px rgba(0,0,0,.8);
}
.gate-box::before { top: 6px; left: 6px; box-shadow: 0 1px 1px rgba(0,0,0,.8), calc(100% + 396px) 0 0 transparent; }
.gate-box::after  { bottom: 6px; right: 6px; }
.gate-box .card { margin: 0; box-shadow: inset 0 0 0 1px rgba(0,0,0,.15), 0 2px 6px rgba(0,0,0,.5); }
.gate-box .auth-grid { gap: 12px; }
@media (max-width: 559px) { .gate-box { max-width: 360px; } }

/* ---- generated pictures (tools/picture.php), each behind an is_file() check ---- */
.backdrop {
  position: absolute; inset: 0;
  background-size: cover; background-position: 50% 35%;
}
/* with a painted backdrop the drawn sky, hills and cobbles stand down; the mist
   stays, it is what ties the sprites to the ground */
.has-backdrop .sky, .has-backdrop .hills { display: none; }
.has-backdrop .ground {
  background: linear-gradient(180deg, transparent, rgba(0, 0, 0, .35));
  border-top: 0; height: 30%;
}
.sprite-img { object-fit: contain; }
.sprite-img.sprite-mon { width: 120px; height: 120px; filter: drop-shadow(0 6px 4px rgba(0, 0, 0, .55)); }
.sprite-img.sprite-boss { width: 100%; height: auto; }
.portrait { width: 100%; height: 100%; border-radius: 50%; object-fit: cover; display: block; }
.pic-row { width: 56px; height: 56px; object-fit: contain; flex: 0 0 auto; }

/* ================================================= the title screen, again
   16 Sep 2026: "the login page is boring and plain". A painted backdrop over
   the whole window, a real title, two torches and drifting embers. All CSS;
   the only picture is the backdrop, and the page stands without it. */
body.title-screen { background: #0b0908; min-height: 100vh; position: relative; overflow-x: hidden; }
.gate-bg {
  position: fixed; inset: 0; z-index: 0;
  background-size: cover; background-position: 50% 40%;
  filter: saturate(1.05);
}
.gate-bg::after {
  content: ""; position: absolute; inset: 0;
  background:
    radial-gradient(ellipse at 50% 55%, rgba(0, 0, 0, 0) 20%, rgba(11, 9, 8, .78) 75%),
    linear-gradient(180deg, rgba(11, 9, 8, .55), rgba(11, 9, 8, .25) 30%, rgba(11, 9, 8, .85));
}
.title-screen .title-frame {
  position: relative; z-index: 2;
  max-width: 560px; border: 0 !important;
  background: none;
  padding-top: 6vh;
}
.title-sigil { width: 84px; height: 84px; margin: 0 auto -6px; color: var(--gold); filter: drop-shadow(0 0 14px rgba(232, 207, 122, .45)); animation: sigil-glow 3.5s ease-in-out infinite; }
.title-sigil svg { width: 100%; height: 100%; }
@keyframes sigil-glow { 50% { filter: drop-shadow(0 0 26px rgba(232, 207, 122, .8)); } }
.title-word { margin: 0; line-height: .95; text-align: center; }
.title-word span {
  display: block; font-size: 22px; letter-spacing: .45em; text-transform: uppercase;
  color: var(--parch); text-shadow: 0 2px 6px #000; font-weight: 400;
}
.title-word b {
  display: block; font-size: 64px; letter-spacing: .06em; font-weight: 700;
  background: linear-gradient(180deg, #fff3c4 0%, #e8cf7a 35%, #c9a24a 60%, #8a6a22 100%);
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
  filter: drop-shadow(0 3px 0 #3a2a10) drop-shadow(0 8px 18px rgba(0, 0, 0, .8));
}
@media (max-width: 430px) { .title-word b { font-size: 48px; } .title-word span { font-size: 17px; } }
.title-screen .tagline { color: var(--parch); text-shadow: 0 2px 6px #000; font-size: 16px; }

/* torches, one either side of the box - a flame of three blurred blobs */
.gate-box { overflow: visible; }
.torch {
  position: absolute; top: -34px; width: 22px; height: 60px; pointer-events: none;
}
.torch-l { left: -8px; } .torch-r { right: -8px; }
.torch::before {            /* the flame */
  content: ""; position: absolute; left: 50%; top: 0; width: 26px; height: 34px;
  transform: translateX(-50%);
  border-radius: 50% 50% 45% 45% / 60% 60% 40% 40%;
  background: radial-gradient(ellipse at 50% 80%, #fff2b0 0%, #ffb340 30%, #e0561a 60%, transparent 72%);
  filter: blur(1.5px);
  animation: flame .5s ease-in-out infinite alternate;
}
.torch::after {             /* the handle, iron with a gold band */
  content: ""; position: absolute; left: 50%; top: 26px; width: 10px; height: 36px;
  transform: translateX(-50%);
  background: linear-gradient(180deg, var(--gold-dark) 0 20%, var(--iron) 20%);
  border-radius: 3px 3px 5px 5px;
  box-shadow: 0 0 22px 6px rgba(255, 160, 60, .28);
}
.torch-r::before { animation-delay: .27s; }
@keyframes flame {
  from { transform: translateX(-50%) scale(1, 1) rotate(-3deg); }
  to   { transform: translateX(-52%) scale(1.08, 1.18) rotate(4deg); }
}

/* embers rising past the box */
.embers { position: fixed; inset: 0; z-index: 1; pointer-events: none; overflow: hidden; }
.embers i {
  position: absolute; bottom: -10px; width: 4px; height: 4px; border-radius: 50%;
  background: #ffb75a; box-shadow: 0 0 8px 2px rgba(255, 150, 60, .55);
  opacity: 0; animation: ember 9s linear infinite;
}
.embers i:nth-child(1)  { left: 8%;  animation-delay: 0s;   animation-duration: 11s; }
.embers i:nth-child(2)  { left: 16%; animation-delay: 2s;   width: 3px; height: 3px; }
.embers i:nth-child(3)  { left: 24%; animation-delay: 5s;   animation-duration: 13s; }
.embers i:nth-child(4)  { left: 33%; animation-delay: 1s;   width: 5px; height: 5px; }
.embers i:nth-child(5)  { left: 41%; animation-delay: 7s; }
.embers i:nth-child(6)  { left: 50%; animation-delay: 3.5s; animation-duration: 12s; }
.embers i:nth-child(7)  { left: 58%; animation-delay: 6s;   width: 3px; height: 3px; }
.embers i:nth-child(8)  { left: 66%; animation-delay: .5s;  animation-duration: 10s; }
.embers i:nth-child(9)  { left: 74%; animation-delay: 4s; }
.embers i:nth-child(10) { left: 82%; animation-delay: 8s;   width: 5px; height: 5px; }
.embers i:nth-child(11) { left: 90%; animation-delay: 2.5s; animation-duration: 14s; }
.embers i:nth-child(12) { left: 96%; animation-delay: 6.5s; width: 3px; height: 3px; }
@keyframes ember {
  0%   { transform: translate(0, 0); opacity: 0; }
  10%  { opacity: .9; }
  50%  { transform: translate(18px, -50vh); opacity: .7; }
  100% { transform: translate(-12px, -104vh); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) { .embers, .torch::before, .title-sigil { animation: none; } }

/* ---- round three pictures ---- */
.sprite-img.sprite-hero { width: 110px; height: 110px; filter: drop-shadow(0 6px 4px rgba(0, 0, 0, .55)); }
.hero-attack { display: none; }
.spot-hero.lunge .hero-idle { display: none; }
.spot-hero.lunge .hero-attack { display: block; }
.class-splash { width: 100%; height: 150px; object-fit: cover; object-position: 50% 20%; border-radius: 8px; margin: 4px 0 10px; border: 1px solid var(--parch-edge); }
.card-art { width: calc(100% + 28px); margin: -12px -14px 10px; height: 120px; object-fit: cover; object-position: 50% 45%; border-radius: 10px 10px 0 0; display: block; }
.pic-small { width: 40px; height: 40px; }
.class-figure .sprite-img { width: 64px; height: 64px; filter: none; }
.class-figure .hero-attack { display: none; }

/* ================================================= motion, 16 Sep 2026
   "more of an animation and not like 2 pictures swapping". The two poses now
   cross-fade, the lunge has weight (a crouch, a drive forward, a settle), the
   idle breathes, and every hit drops two short effects: a flash at the hero
   and a burst at the monster. */
.spot-hero { perspective: 400px; }
.sprite-img.sprite-hero {
  position: absolute; left: 50%; bottom: 0; transform: translateX(-50%);
  transition: opacity .12s ease;
  transform-origin: 50% 100%;
}
.spot-hero { position: relative; height: 118px; }
.hero-idle   { opacity: 1; animation: breathe 2.4s ease-in-out infinite; }
.hero-attack { opacity: 0; display: block; }
.spot-hero.lunge .hero-idle   { opacity: 0; animation: none; }
.spot-hero.lunge .hero-attack { opacity: 1; animation: strike .42s cubic-bezier(.2, .9, .3, 1); }
.spot-hero.lunge .sprite-hero.hero-idle { animation: none; }
@keyframes breathe {
  50% { transform: translateX(-50%) translateY(-2px) scale(1.015, .985); }
}
@keyframes strike {
  0%   { transform: translateX(-50%) scale(.94, 1.06); }
  18%  { transform: translateX(-50%) translateX(-6px) scale(1.06, .94); }
  45%  { transform: translateX(-50%) translateX(26px) scale(1.04, .98); }
  100% { transform: translateX(-50%) scale(1, 1); }
}
/* the drawn (SVG) hero keeps its old lunge */
.spot-hero.lunge svg.sprite-hero { animation: lunge .3s ease-out; }

/* monster: a white flash on the hit, on top of the shake it already had */
.spot-mon.hit .sprite-img.sprite-mon { animation: shake .22s linear, hitflash .22s linear; }
@keyframes hitflash { 30% { filter: brightness(2.2) saturate(.4) drop-shadow(0 0 6px #fff); } }

/* the effects: an <i class="fx ..."> dropped on a spot for 600ms */
.fx { position: absolute; pointer-events: none; z-index: 5; left: 50%; top: 45%; width: 70px; height: 70px; margin: -35px 0 0 -35px; border-radius: 50%; }
.burst {
  background: radial-gradient(circle, rgba(255, 255, 255, .95) 0 12%, rgba(255, 210, 120, .8) 22%, rgba(255, 120, 40, .0) 60%);
  animation: burst .38s ease-out forwards;
}
.burst-crit {
  background: radial-gradient(circle, #fff 0 10%, rgba(255, 90, 60, .9) 20%, rgba(200, 30, 30, 0) 62%);
  animation: burst .5s ease-out forwards; width: 110px; height: 110px; margin: -55px 0 0 -55px;
}
.burst::after {          /* spokes, so it reads as an impact not a glow */
  content: ""; position: absolute; inset: 0; border-radius: 50%;
  background:
    conic-gradient(from 0deg, transparent 0 8%, rgba(255,255,255,.7) 9% 11%, transparent 12% 33%, rgba(255,255,255,.7) 34% 36%, transparent 37% 58%, rgba(255,255,255,.7) 59% 61%, transparent 62% 83%, rgba(255,255,255,.7) 84% 86%, transparent 87%);
  mask: radial-gradient(circle, transparent 30%, #000 35%, #000 55%, transparent 60%);
  -webkit-mask: radial-gradient(circle, transparent 30%, #000 35%, #000 55%, transparent 60%);
}
@keyframes burst { from { transform: scale(.3); opacity: 1; } to { transform: scale(1.6); opacity: 0; } }
/* the hero's flash: a muzzle blast, a frost bloom, an ember arc */
.flash-gunner { left: 92%; top: 42%; width: 46px; height: 46px; margin: -23px; background: radial-gradient(circle, #fff 0 15%, #ffd070 30%, rgba(255, 140, 40, 0) 65%); animation: muzzle .25s ease-out forwards; }
.flash-mage   { left: 88%; top: 30%; width: 56px; height: 56px; margin: -28px; background: radial-gradient(circle, #fff 0 10%, #a8e6ff 28%, rgba(120, 200, 255, 0) 65%); animation: burst .4s ease-out forwards; }
.flash-blade  { left: 80%; top: 45%; width: 80px; height: 80px; margin: -40px; border-radius: 50%; background: conic-gradient(from 200deg, transparent 0 55%, rgba(255, 160, 60, .0) 56%, rgba(255, 200, 90, .9) 70%, rgba(255, 120, 30, .0) 88%); animation: arc .32s ease-out forwards; }
@keyframes muzzle { from { transform: scale(.4); opacity: 1; } to { transform: scale(1.5); opacity: 0; } }
@keyframes arc { from { transform: rotate(-40deg) scale(.7); opacity: 1; } to { transform: rotate(30deg) scale(1.15); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .fx, .hero-idle, .hero-attack { animation: none !important; } }

/* ================================================= the dense frame, 17 Sep 2026
   Two HUD rows, a shortcut strip with badges, a chat line, and a bar that
   scrolls sideways when nine shields will not fit. */
.hud { flex-direction: column; gap: 4px; padding-bottom: 5px; }
.hud-row { display: flex; align-items: center; gap: 8px; width: 100%; }
.hud-row-b { gap: 6px; flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
.hud-row-b::-webkit-scrollbar { display: none; }
.hud-row-a .hud-avatar { width: 46px; height: 46px; }
.hud-row-a .avatar-ring { width: 46px; height: 46px; }
.hud-right { display: flex; flex-direction: column; align-items: flex-end; gap: 3px; }
.counters { display: flex; gap: 4px; flex-wrap: nowrap; }
.counter { padding: 1px 5px 1px 3px; font-size: 11px; min-height: 20px; }
.hud-class { display: flex; align-items: center; gap: 6px; }
.vip-badge {
  display: inline-block; padding: 0 6px; border-radius: 6px; font-size: 10px; font-weight: 800; letter-spacing: .05em;
  color: #2a1a05; background: linear-gradient(180deg, #ffe9a0, var(--gold) 55%, #9c7620);
  border: 1px solid #5a4210; text-decoration: none; box-shadow: 0 1px 2px rgba(0,0,0,.6);
}
.cp {
  display: inline-flex; align-items: center; gap: 4px; text-decoration: none;
  color: #ffd98a; font-size: 12px; font-weight: 800; letter-spacing: .02em;
  padding: 1px 8px; border-radius: 10px; border: 1px solid var(--gold-dark);
  background: linear-gradient(180deg, rgba(0,0,0,.35), rgba(0,0,0,.6));
  text-shadow: 0 1px 2px #000;
}
.cp .ico { width: 14px; height: 14px; }
.hud-pill {
  display: inline-flex; align-items: center; gap: 4px; flex: 0 0 auto;
  padding: 3px 9px; border-radius: 999px; font-size: 11px; font-weight: 700; text-decoration: none;
  border: 1px solid var(--gold-dark); color: var(--parch);
  background: linear-gradient(180deg, var(--oak-light), var(--oak-dark));
  box-shadow: inset 0 1px 0 rgba(255,230,160,.2), 0 1px 2px rgba(0,0,0,.6);
  white-space: nowrap;
}
.hud-pill .ico { width: 14px; height: 14px; }
.hud-pill-gift { border-color: var(--wax); color: #ffd5c8; }
.hud-pill-gold { color: #ffe3a0; }
.hud-row-b .chip-zone { margin-left: auto; padding: 2px 9px 6px; font-size: 11px; max-width: 46%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hud-pill { padding: 3px 7px; }
.hud-stat { display: inline-flex; align-items: center; gap: 3px; color: var(--parch); font-size: 11px; white-space: nowrap; }
.hud-stat .ico { width: 13px; height: 13px; opacity: .8; }
.hud-stat b { color: var(--gold-light); }

.shortcuts {
  flex: 0 0 auto; display: flex; gap: 2px; padding: 5px 6px 4px;
  background: linear-gradient(180deg, rgba(0,0,0,.55), rgba(0,0,0,.25));
  border-bottom: 1px solid rgba(255,255,255,.06);
  overflow-x: auto; scrollbar-width: none; z-index: 4;
}
.shortcuts::-webkit-scrollbar { display: none; }
.sc { flex: 1 0 52px; display: flex; flex-direction: column; align-items: center; gap: 2px; text-decoration: none; color: var(--parch); min-height: 44px; }
.sc-ico {
  position: relative; width: 34px; height: 34px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: radial-gradient(circle at 40% 35%, var(--oak-light), var(--oak-dark));
  border: 2px solid var(--gold-dark); box-shadow: 0 2px 4px rgba(0,0,0,.7), inset 0 1px 0 rgba(255,230,160,.25);
  color: var(--gold-light);
}
.sc-ico .ico { width: 18px; height: 18px; }
.sc-label { font-size: 10px; font-variant: small-caps; letter-spacing: .04em; line-height: 1; }
.sc-on .sc-ico { border-color: var(--gold-light); box-shadow: 0 0 8px rgba(232,207,122,.6); }
.sc .badge-red { position: absolute; top: -5px; right: -6px; }

.chatline {
  flex: 0 0 auto; display: flex; align-items: center; gap: 8px; min-height: 30px;
  padding: 3px 10px; text-decoration: none; color: var(--ink);
  background: linear-gradient(180deg, var(--parch), var(--parch-dark)); border-top: 1px solid var(--parch-edge); border-bottom: 1px solid var(--parch-edge);
  font-size: 12px; font-style: italic;
}
.chatline-ico { width: 16px; height: 16px; color: var(--ink-muted); flex: 0 0 auto; }
.chatline-ico .ico { width: 16px; height: 16px; }
.chatline-text { flex: 1 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.chatline-go { font-style: normal; font-size: 10px; font-variant: small-caps; letter-spacing: .06em; color: var(--gold-dark); font-weight: 700; }

.navbar { justify-content: flex-start; overflow-x: auto; scrollbar-width: none; scroll-snap-type: x proximity; }
.navbar::-webkit-scrollbar { display: none; }
.navbar .bar-btn { flex: 0 0 auto; min-width: 58px; scroll-snap-align: start; }
@media (min-width: 480px) { .navbar { justify-content: space-between; } .navbar .bar-btn { flex: 1 1 0; } }
.tracker {
  position: absolute; left: 8px; top: 46%; z-index: 4; max-width: 62%;
  display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px 4px 6px;
  border-radius: 999px; text-decoration: none; font-size: 11px; color: var(--parch);
  background: linear-gradient(180deg, rgba(0,0,0,.6), rgba(0,0,0,.75)); border: 1px solid var(--gold-dark);
}
.tracker .ico { width: 14px; height: 14px; color: var(--gold-light); flex: 0 0 auto; }
.tracker span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.frame-iron   { border-color: #9aa0a6; box-shadow: 0 0 0 1px #4a4f55, inset 0 0 0 2px #6b7076, 0 2px 6px rgba(0, 0, 0, .7); }
.frame-gold   { border-color: var(--gold); box-shadow: 0 0 0 1px var(--gold-dark), inset 0 0 0 2px var(--gold-dark), 0 0 8px rgba(201, 162, 74, .6); }
.frame-dragon { border-color: #b3262e; box-shadow: 0 0 0 2px var(--gold), inset 0 0 0 2px #5a1116, 0 0 10px rgba(179, 38, 46, .7); }
.hud-pill .badge-red { position: static; margin-left: 4px; font-size: 9px; min-width: 15px; height: 15px; line-height: 15px; }
.hud-pill-carnival { border-color: var(--blue); color: #cfe0ff; }

/* ================================================= the layout, 17 Sep 2026
   "bottom bar is still missing pictures, tabs in the wrong place". Pictured
   buttons everywhere a picture exists; on the Fight screen the shortcuts sit
   as a grid over the top-left of the scene and a column of round buttons
   runs down the right, the way the reference lays its screen out. */
.ui-pic { width: 100%; height: 100%; object-fit: contain; display: block; filter: drop-shadow(0 2px 2px rgba(0,0,0,.6)); }
.bar-ico .ui-pic { width: 40px; height: 40px; }
.bar-ico:has(.ui-pic) { background: radial-gradient(circle at 50% 35%, rgba(255,235,180,.18), transparent 60%), linear-gradient(180deg, var(--oak-light), var(--oak-dark)); }
.sc-ico .ui-pic { width: 30px; height: 30px; }
.edge-btn .ui-pic { width: 34px; height: 34px; }

/* the grid over the scene */
.scene-grid {
  position: absolute; left: 6px; top: 44px; z-index: 5;
  display: grid; grid-template-columns: repeat(4, 54px); gap: 4px 2px;
}
.scene-grid .sc { flex: none; min-height: 0; }
.scene-grid .sc-ico { width: 40px; height: 40px; background: radial-gradient(circle at 40% 35%, rgba(60,45,30,.85), rgba(15,12,10,.9)); }
.scene-grid .sc-label { color: #fff; text-shadow: 0 1px 2px #000, 0 0 4px #000; font-size: 9px; }
/* the left column moves down beneath the grid */
.page-game .edge:not(.edge-right) { top: 156px; }
/* the right column */
.edge-right { position: absolute; right: 6px; top: 44px; z-index: 5; display: flex; flex-direction: column; gap: 6px; align-items: flex-end; }
.edge-right .edge-btn { width: 50px; height: 50px; padding: 2px; text-decoration: none; display: flex; flex-direction: column; align-items: center; justify-content: center; }
.edge-right .edge-label { font-size: 9px; color: #fff; text-shadow: 0 1px 2px #000; line-height: 1; margin-top: -2px; }
.edge-right .badge-red { position: absolute; top: -4px; right: -4px; }
.tracker { top: auto; bottom: 12%; left: 8px; }

/* the chat row */
.chatrow {
  flex: 0 0 auto; display: flex; align-items: stretch; gap: 4px; min-height: 40px;
  padding: 3px 6px; background: linear-gradient(180deg, var(--parch), var(--parch-dark));
  border-top: 1px solid var(--parch-edge); border-bottom: 1px solid var(--parch-edge);
}
.chatrow .chatline { flex: 1 1 auto; min-width: 0; padding: 0 6px; border: 0; background: none; }
.chatrow-btn {
  flex: 0 0 auto; width: 46px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0;
  text-decoration: none; color: var(--ink); font-size: 9px; font-variant: small-caps; letter-spacing: .04em;
}
.chatrow-btn .ico, .chatrow-btn .ui-pic { width: 24px; height: 24px; }
.chatrow-btn.on { color: var(--gold-dark); font-weight: 700; }
@media (max-width: 430px) {
  .scene-grid { grid-template-columns: repeat(4, 50px); }
  .scene-grid .sc-ico { width: 36px; height: 36px; }
}
.edge .edge-btn .ui-pic { width: 34px; height: 34px; }
/* the right column must not sit on the monster: four buttons, and the monster steps in */
.edge-right .edge-btn { width: 46px; height: 46px; }
.page-game .spot-mon { margin-right: 44px; }
.page-game .spot-hero { margin-left: 6px; }
/* the second HUD row wraps rather than squashing the stage banner */
.hud-row-b { flex-wrap: wrap; overflow: visible; row-gap: 4px; }
.hud-row-b .chip-zone { max-width: none; }
.hud-row-b .hud-pill-carnival { order: 5; }
.hud-row-b .hud-clock { order: 6; margin-left: auto; }
.hud-row-b .hud-stat:not(.hud-clock) { order: 4; }
/* circles, not shields (17 Sep 2026: "make the shields a circle instead") */
.bar-ico { border-radius: 50%; width: 46px; height: 46px; overflow: hidden; }
.bar-ico .ui-pic { width: 42px; height: 42px; }
.bar-ico:has(.ui-pic) { background: radial-gradient(circle at 50% 30%, #3a2a18, #120d08 75%); }

/* ================================================= the fantasy skin, 17 Sep 2026
   "do a more fantasy redesign on the menu tabs, they're plain". Panels, sheets,
   rows, buttons and inputs move from parchment to deep indigo with ornate
   gold frames, jewelled corners and glossy buttons. The HUD and bars keep
   their oak and iron. Appended last on purpose: every rule here must win. */
:root {
  --panel: #1a1f3d; --panel-2: #10132a; --panel-3: #232a55;
  --frame: #d4a94e; --frame-dark: #7a5a1c; --frame-light: #ffe9a8;
  --ivory: #f1e8d2; --ivory-muted: #b3ab97;
  --gem-red: #d0343c; --gem-blue: #3d7de0; --gem-green: #3fbf6a;
}
.content { background: radial-gradient(ellipse at 50% 0%, #1b2140 0%, #0b0d1c 70%); }
.page-game .content { background: none; }

.card, .sheet {
  color: var(--ivory);
  background:
    radial-gradient(ellipse at 50% 0%, rgba(90, 110, 200, .18), transparent 55%),
    linear-gradient(180deg, var(--panel) 0%, var(--panel-2) 100%);
  border: 2px solid var(--frame);
  border-radius: 12px;
  box-shadow:
    0 0 0 1px var(--frame-dark), 0 0 0 4px var(--panel-2), 0 0 0 5px var(--frame-dark),
    inset 0 1px 0 rgba(255,255,255,.12), inset 0 0 40px rgba(0,0,0,.45), 0 10px 24px rgba(0,0,0,.7);
  position: relative;
}
.card { margin: 8px 2px 16px; }
/* jewelled corners */
.card::before, .card::after, .sheet::before, .sheet::after {
  content: ""; position: absolute; width: 14px; height: 14px; border-radius: 50%; z-index: 2;
  background: radial-gradient(circle at 35% 35%, #fff 0, var(--gem-blue) 25%, #1b3a8a 70%, #0a1a40 100%);
  box-shadow: 0 0 0 2px var(--frame), 0 0 6px rgba(120,170,255,.8);
}
.card::before, .sheet::before { top: -7px; left: -7px; }
.card::after,  .sheet::after  { top: -7px; right: -7px; }
.card .muted, .sheet .muted { color: var(--ivory-muted); }
.card .small, .sheet .small { color: var(--ivory-muted); }
.card p, .sheet p, .card label, .sheet label { color: var(--ivory); }
.card .gold, .sheet .gold { color: var(--frame-light); }
.card .xp, .sheet .xp { color: #9cc4ff; }

/* ribbon headers */
.card-head { border-bottom: 0; padding: 0 0 8px; margin-bottom: 10px; position: relative; }
.card-head::after {
  content: ""; position: absolute; left: 10%; right: 10%; bottom: 0; height: 2px;
  background: linear-gradient(90deg, transparent, var(--frame), transparent);
}
.card-head h2, .sheet h2 {
  color: var(--frame-light); text-shadow: 0 1px 0 #3a2a10, 0 0 8px rgba(255,210,120,.35);
  letter-spacing: .06em;
}
.card-head h2 .ico { color: var(--frame); }

/* rows and tiles */
.row, .upgrade-row {
  background: linear-gradient(180deg, rgba(255,255,255,.05), rgba(0,0,0,.25));
  border: 1px solid rgba(212,169,78,.45); border-radius: 10px;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.06);
  color: var(--ivory);
}
.upgrade-row { border-top: 1px solid rgba(212,169,78,.45); margin-bottom: 6px; padding: 8px 10px; }
.row strong, .upgrade-row strong, .row-info strong { color: #fff; }
.row.locked, .locked { opacity: .55; }
.stat-grid div {
  background: linear-gradient(180deg, rgba(0,0,0,.35), rgba(0,0,0,.55));
  border: 1px solid rgba(212,169,78,.5); border-radius: 8px;
}
.stat-grid dt { color: var(--ivory-muted); }
.stat-grid dd { color: var(--frame-light); text-shadow: 0 0 6px rgba(255,210,120,.35); }
.bar { background: linear-gradient(180deg, #06081a, #141936); border: 1px solid rgba(212,169,78,.5); }
.pill, .chip { background: rgba(0,0,0,.35); border-color: rgba(212,169,78,.55); color: var(--ivory); }
.chip-gold { color: var(--frame-light); }
.chip-on { color: #b9f0c8; border-color: rgba(63,191,106,.6); background: rgba(63,191,106,.15); }
.pill-red { color: #ffb0a8; border-color: rgba(208,52,60,.6); background: rgba(208,52,60,.15); }

/* glossy buttons */
.btn {
  color: var(--ivory); border: 1px solid var(--frame-dark); border-radius: 10px;
  background: linear-gradient(180deg, #3b4479 0%, #232a55 48%, #171c3d 52%, #2a3164 100%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.25), inset 0 -2px 0 rgba(0,0,0,.4), 0 3px 6px rgba(0,0,0,.6), 0 0 0 1px rgba(0,0,0,.6);
  text-shadow: 0 1px 1px #000;
}
.btn-gold {
  color: #2b1a04; border-color: #6a4a10;
  background: linear-gradient(180deg, #fff2b8 0%, #f0c452 45%, #d39a25 55%, #f2c65a 100%);
  text-shadow: 0 1px 0 rgba(255,255,255,.5);
}
.btn-red {
  color: #fff; border-color: #6a1a1a;
  background: linear-gradient(180deg, #ff8a80 0%, #d0343c 48%, #9a1e24 52%, #c8323a 100%);
}
.btn:disabled, .btn[disabled] { filter: grayscale(.7) brightness(.7); }
.btn-ghost { background: transparent; border-color: rgba(212,169,78,.5); box-shadow: none; color: var(--ivory-muted); }
.btn-close {
  width: 40px; height: 40px; border-radius: 50%; color: #fff;
  background: radial-gradient(circle at 35% 30%, #ff9a90, var(--gem-red) 45%, #6e1418 100%);
  border: 2px solid var(--frame); box-shadow: 0 0 0 1px var(--frame-dark), 0 2px 6px rgba(0,0,0,.7);
}
input[type="text"], input[type="password"], select, textarea {
  color: var(--ivory); background: linear-gradient(180deg, #090b1c, #141936);
  border: 1px solid rgba(212,169,78,.6); border-radius: 8px;
}
input::placeholder { color: #6d6f88; }
.flash { border: 1px solid var(--frame); background: linear-gradient(180deg, #2a3164, #171c3d); color: var(--ivory); box-shadow: 0 4px 12px rgba(0,0,0,.6); }
.flash-bad { border-color: var(--gem-red); }

/* the sheets: same skin, grip becomes a gold bar */
.sheet-grip { background: linear-gradient(90deg, var(--frame-dark), var(--frame), var(--frame-dark)); border: 0; height: 5px; border-radius: 3px; }
.sheet-back { background: rgba(4, 6, 18, .7); }

/* the title screen forms keep parchment inside the oak box */
.gate-box .card { color: var(--ink); background: linear-gradient(180deg, var(--parch) 0%, #dccaa6 100%); border: 1px solid var(--oak-dark); box-shadow: none; }
.gate-box .card::before, .gate-box .card::after { display: none; }
.gate-box .card p, .gate-box .card label { color: var(--ink); }
.gate-box input[type="text"], .gate-box input[type="password"] { color: var(--ink); background: #fff8e6; border-color: var(--parch-edge); }
.gate-box .card-head h2 { color: var(--ink); text-shadow: none; }
.edge-right { left: auto; width: auto; }   /* it inherited .edge's left:8px and covered the grid (17 Sep 2026: "nothing is clickable") */
/* the sheet scrolls, so its corner gems sit inside the frame and nothing pokes out sideways */
.sheet { overflow: hidden; }
.sheet::before, .sheet::after { top: 6px; }
.sheet::before { left: 6px; } .sheet::after { right: 6px; }
.sheet-scroll { overflow-x: hidden; }
.sheet .card-head { padding-left: 14px; padding-right: 14px; }

/* ================================================= the HUD in the fantasy skin, 17 Sep 2026
   "redesign this more to a fantasy look to match the bottom panel". */
.hud {
  background:
    radial-gradient(ellipse at 50% -20%, rgba(120, 150, 255, .25), transparent 60%),
    linear-gradient(180deg, #232a55 0%, #151a3a 60%, #0e1128 100%);
  border-bottom: 2px solid var(--frame);
  box-shadow: 0 2px 0 var(--frame-dark), 0 6px 14px rgba(0, 0, 0, .7), inset 0 1px 0 rgba(255,255,255,.12);
}
.hud-name { color: var(--frame-light); text-shadow: 0 1px 0 #3a2a10, 0 0 8px rgba(255,210,120,.3); }
.hud-class { color: var(--ivory-muted); }
.avatar-ring {
  border: 3px solid var(--frame);
  box-shadow: 0 0 0 1px var(--frame-dark), 0 0 0 3px #0e1128, 0 0 0 4px var(--frame-dark), 0 0 12px rgba(120,170,255,.45);
  background: radial-gradient(circle at 40% 35%, #2a3468, #0b0e22);
}
.lvl-badge {
  background: radial-gradient(circle at 35% 30%, #ff9a90, var(--gem-red) 45%, #6e1418 100%);
  border: 2px solid var(--frame); color: #fff; text-shadow: 0 1px 1px #000;
}
.counter {
  background: linear-gradient(180deg, #0a0d20, #1a2046);
  border: 1px solid var(--frame); color: var(--ivory);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.08), 0 1px 2px rgba(0,0,0,.7);
}
.counter-key, a.counter-crown { color: var(--ivory); }
.counter-crown .plus { background: radial-gradient(circle at 35% 30%, #ff9a90, var(--gem-red) 50%, #6e1418); }
.cp { background: linear-gradient(180deg, #0a0d20, #1a2046); border-color: var(--frame); color: var(--frame-light); }
.hud-pill {
  color: var(--ivory); border-color: var(--frame);
  background: linear-gradient(180deg, #3b4479 0%, #232a55 48%, #171c3d 52%, #2a3164 100%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 2px 4px rgba(0,0,0,.6);
}
.hud-pill-gift { color: #ffd5c8; border-color: var(--gem-red); }
.hud-pill-gold { color: var(--frame-light); }
.hud-pill-carnival { color: #cfe0ff; border-color: var(--gem-blue); }
.hud-stat { color: var(--ivory-muted); }
.hud-stat b { color: var(--frame-light); }
.chip-zone {
  color: var(--frame-light); background: linear-gradient(180deg, #8a1c1c, #5a1010);
  border: 1px solid var(--frame); text-shadow: 0 1px 1px #000;
}
.bar-mini { border-color: var(--frame-dark); }
.vip-badge { box-shadow: 0 0 6px rgba(255,210,120,.5), 0 1px 2px rgba(0,0,0,.6); }

/* the strips and the bar, to match */
.shortcuts { background: linear-gradient(180deg, #0e1128, #151a3a); border-bottom: 1px solid var(--frame-dark); }
.sc-ico { background: radial-gradient(circle at 40% 35%, #2a3468, #0b0e22); border-color: var(--frame); }
.scene-grid .sc-ico, .edge-right .edge-btn, .edge .edge-btn { background: radial-gradient(circle at 40% 35%, rgba(42,52,104,.92), rgba(11,14,34,.95)); border-color: var(--frame); box-shadow: 0 0 0 1px var(--frame-dark), 0 2px 6px rgba(0,0,0,.7); }
.chatrow { background: linear-gradient(180deg, #151a3a, #0e1128); border-top: 1px solid var(--frame); border-bottom: 1px solid var(--frame-dark); }
.chatrow .chatline, .chatrow-btn { color: var(--ivory); }
.chatline-text { color: var(--ivory-muted); }
.chatrow-btn.on { color: var(--frame-light); }
.navbar {
  background:
    radial-gradient(circle at 6px 8px, var(--frame) 2px, transparent 3px),
    radial-gradient(circle at calc(100% - 6px) 8px, var(--frame) 2px, transparent 3px),
    linear-gradient(180deg, #1a2046 0%, #0e1128 100%);
  border-top: 2px solid var(--frame);
  box-shadow: 0 -2px 0 var(--frame-dark), 0 -6px 14px rgba(0,0,0,.6);
}
.bar-ico { border-color: var(--frame); box-shadow: 0 0 0 1px var(--frame-dark), 0 2px 6px rgba(0,0,0,.7); }
.bar-ico:has(.ui-pic) { background: radial-gradient(circle at 50% 30%, #2a3468, #0b0e22 75%); }
.bar-label { color: var(--ivory); }
.bar-on .bar-label { color: var(--frame-light); }
.bar-on .bar-ico { box-shadow: 0 0 0 1px var(--frame-dark), 0 0 12px rgba(255,220,130,.75); }
.ticker { background: linear-gradient(180deg, #151a3a, #0e1128); color: var(--ivory-muted); border-color: var(--frame-dark); }
/* sheets size to their content: a fixed child of the flex column was being
   stretched to the column's height (17 Sep 2026: "a lot of empty space") */
.sheet { align-self: flex-start; height: auto; }
/* no diagonal lines anywhere (17 Sep 2026) */
.card, .sheet {
  background:
    radial-gradient(ellipse at 50% 0%, rgba(90, 110, 200, .18), transparent 55%),
    linear-gradient(180deg, var(--panel) 0%, var(--panel-2) 100%);
}
.hud {
  background:
    radial-gradient(ellipse at 50% -20%, rgba(120, 150, 255, .25), transparent 60%),
    linear-gradient(180deg, #232a55 0%, #151a3a 60%, #0e1128 100%);
}
.gate-box .card { background: linear-gradient(180deg, var(--parch) 0%, #dccaa6 100%); }
/* no scrollbar on the page scroller (17 Sep 2026) */
.content, .sheet-scroll, .sheet { scrollbar-width: none; }
.content::-webkit-scrollbar, .sheet-scroll::-webkit-scrollbar, .sheet::-webkit-scrollbar { display: none; }

/* ================================================= the top bar, picture two (17 Sep 2026) */
.hud2 { padding: calc(2px + env(safe-area-inset-top)) 0 4px; gap: 0; }
.strip {
  display: flex; align-items: center; gap: 6px; width: 100%;
  padding: 2px 8px; min-height: 22px;
  background: linear-gradient(180deg, #05070f, #0b0e22); border-bottom: 1px solid var(--frame-dark);
  font-size: 11px; color: var(--ivory-muted);
}
.strip-lv { flex: 0 0 auto; white-space: nowrap; }
.strip-lv b { color: var(--frame-light); font-weight: 700; }
.cur { display: flex; gap: 4px; margin-left: auto; }
.cur-item {
  display: inline-flex; align-items: center; gap: 3px; text-decoration: none; color: var(--ivory);
  padding: 0 2px 0 0; font-size: 11px; font-weight: 700;
}
.cur-pic { width: 18px; height: 18px; object-fit: contain; filter: drop-shadow(0 1px 1px #000); }
.cur-item .ico { width: 16px; height: 16px; }
.cur-plus {
  width: 14px; height: 14px; border-radius: 50%; margin-left: 1px;
  background: radial-gradient(circle at 35% 30%, #9fe08a, #3fbf6a 50%, #1c6b38); color: #04200e;
  font-size: 11px; line-height: 14px; text-align: center; font-weight: 900;
  box-shadow: 0 1px 1px rgba(0,0,0,.6);
}
.cur-crown .cur-plus { background: radial-gradient(circle at 35% 30%, #ffd08a, #f0a030 50%, #8a4a08); }

.hud-main { display: flex; align-items: flex-start; gap: 8px; padding: 4px 8px 0; width: 100%; }
.hud2 .hud-avatar { width: 56px; height: 56px; }
.hud2 .avatar-ring { width: 56px; height: 56px; }
.hud-mid { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.hud-cpline { display: flex; align-items: center; gap: 8px; }
.cp-big {
  text-decoration: none; font-style: italic; font-weight: 900; font-size: 18px; letter-spacing: .02em;
  color: #ffd26a; text-shadow: 0 1px 0 #7a4a00, 0 2px 4px rgba(0,0,0,.8), 0 0 10px rgba(255,190,80,.45);
  white-space: nowrap;
}
.cp-big b { font-size: 20px; }
.hud-vip {
  position: relative; text-decoration: none; display: inline-flex; flex-direction: column; align-items: center;
  width: 44px; height: 34px; justify-content: center;
  background: radial-gradient(circle at 50% 30%, #fff1b0, #e8b64a 45%, #9c6b12 100%);
  clip-path: polygon(50% 0, 100% 22%, 88% 100%, 12% 100%, 0 22%);
  color: #3a2200; line-height: 1; filter: drop-shadow(0 2px 3px rgba(0,0,0,.7));
}
.vip-n { font-size: 15px; font-weight: 900; }
.vip-t { font-size: 8px; font-weight: 800; letter-spacing: .1em; }
.hud-relic { width: 34px; height: 34px; display: block; }
.hud-relic .ui-pic, .hud-relic .ico { width: 34px; height: 34px; }
.hud-pills { display: flex; gap: 6px; }
.pill2 {
  display: inline-flex; align-items: center; gap: 4px; padding: 2px 10px; border-radius: 999px;
  font-size: 11px; font-weight: 800; text-decoration: none; color: #fff; text-shadow: 0 1px 1px rgba(0,0,0,.6);
  border: 1px solid rgba(0,0,0,.5); box-shadow: inset 0 1px 0 rgba(255,255,255,.35), 0 2px 3px rgba(0,0,0,.6);
  position: relative;
}
.pill2 i { font-style: normal; font-size: 10px; opacity: .9; }
.pill2-green  { background: linear-gradient(180deg, #7ee29a, #2e9c55 55%, #1f6b3b); }
.pill2-orange { background: linear-gradient(180deg, #ffc46a, #f08a1c 55%, #a85508); }
.pill2-red    { background: linear-gradient(180deg, #ff8f86, #d0343c 55%, #8a1c22); }
.pill2 .badge-red { position: static; margin-left: 2px; min-width: 14px; height: 14px; line-height: 14px; font-size: 9px; }
.hud-mid .bar-mini { width: 60%; max-width: 160px; }
.hud-side { flex: 0 0 auto; display: flex; flex-direction: column; align-items: flex-end; gap: 2px; font-size: 10px; color: var(--ivory-muted); text-align: right; }
.side-line { display: inline-flex; align-items: center; gap: 3px; white-space: nowrap; text-decoration: none; color: var(--ivory-muted); }
.side-tag { color: var(--frame-light); font-weight: 700; }
.side-ping { color: #8fd48f; }
.side-rate b { color: var(--frame-light); }
.side-rate .cur-pic, .side-rate .ico { width: 14px; height: 14px; }
.side-xp .ico { color: #7fb0ff; }
.side-carnival { color: #cfe0ff; }
.hud-name-tag { display: block; width: 100%; padding: 2px 10px 0; font-size: 10px; color: var(--ivory-muted); text-align: left; }
@media (max-width: 430px) { .cp-big { font-size: 15px; } .cp-big b { font-size: 17px; } .hud-side { font-size: 9px; } }
.hud-pills { align-items: center; }
.pill2 { white-space: nowrap; line-height: 1.1; min-height: 0; height: 22px; padding: 0 9px; }
.hud-side .side-carnival { display: none; }
.hud-name-tag .carn { color: #cfe0ff; text-decoration: none; margin-left: 8px; }
/* the winged VIP badge (a picture, the number sits in its medallion) */
.hud-vip.vip-pic { padding-top: 11px;
  width: 74px; height: 46px; clip-path: none; background: none;
  background-size: contain; background-repeat: no-repeat; background-position: center;
  filter: drop-shadow(0 2px 3px rgba(0,0,0,.7)); justify-content: flex-start; padding-top: 12px;
}
.hud-vip.vip-pic .vip-n { font-size: 15px; font-weight: 900; color: #3a2200; line-height: 1; text-shadow: 0 1px 0 rgba(255,255,255,.5); }
.hud-vip.vip-pic .vip-t { display: block; font-size: 6px; font-weight: 900; letter-spacing: .1em; color: #5a3a00; line-height: 1; }
/* the chat feed: two tagged lines above the bar */
.chatfeed { display: flex; flex-direction: column; justify-content: center; gap: 1px; font-style: normal; font-size: 11px; line-height: 1.25; }
.feed-line { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: var(--ivory); }
.feed-tag { font-weight: 800; margin-right: 2px; }
.feed-world { color: #7fc8ff; } .feed-herald { color: #ffd26a; } .feed-guild { color: #9ee89a; } .feed-narvoda { color: var(--ivory-muted); }
.feed-name { font-style: normal; color: #cfe0ff; }
.chatrow { min-height: 44px; }
/* the chat sheet on the Fight screen */
.chat-scroll { max-height: 46vh; padding: 4px 2px; }
.chat-line { margin: 0 0 4px; font-size: 13px; color: var(--ivory); }
.chat-line b { color: #cfe0ff; }
.chat-herald { color: #ffd26a; font-style: italic; }
.chat-herald b { color: #ffd26a; }
.chat-form { display: flex; gap: 6px; margin-top: 8px; }
.chat-form input { flex: 1 1 auto; min-width: 0; min-height: 40px; padding: 0 10px; }
.chat-form .btn { flex: 0 0 auto; width: auto; min-width: 70px; }
.feed-line { display: block; max-width: 100%; } .chatfeed { min-width: 0; overflow: hidden; }
/* the VIP number sits dead centre of the medallion, big and readable */
.hud-vip.vip-pic { position: relative; padding: 0; display: block; }
.hud-vip.vip-pic .vip-n {
  position: absolute; left: 50%; top: 54%; transform: translate(-50%, -50%);
  font-size: 17px; font-weight: 900; color: #fff; line-height: 1;
  text-shadow: 0 0 2px #7a4a00, 0 1px 2px #5a3200, 0 0 6px rgba(0,0,0,.6);
}
.hud-vip.vip-pic .vip-t { position: absolute; left: 50%; top: 82%; transform: translate(-50%, -50%); font-size: 6px; color: #7a4a00; }
.edge-right .edge-label { font-size: 8px; }
.pill2 .ui-pic { width: 16px; height: 16px; margin-right: 2px; }
.upmode { display: inline-flex; gap: 2px; margin-left: auto; margin-right: 8px; }
.upmode-btn { min-height: 26px; padding: 0 10px; border-radius: 999px; border: 1px solid var(--frame-dark); background: rgba(0,0,0,.35); color: var(--ivory-muted); font-weight: 800; font-size: 12px; }
.upmode-btn.on { background: linear-gradient(180deg, #fff2b8, #d39a25); color: #2b1a04; }
.upgrade-row button { touch-action: none; user-select: none; -webkit-user-select: none; }

/* ---- Auto-Stage Clearing toggle, 17 Sep 2026 (include/auto.php) --------
 * A small round "Auto" under the gate ring. Hung off the ring with absolute
 * position so the top strip keeps its height and the chips stay centred on
 * the ring. Lit green when on. */
.gate-stack { position: relative; display: inline-flex; }
.auto-form { position: absolute; left: 50%; top: 100%; transform: translateX(-50%); margin-top: 4px; }
.auto-btn {
  width: 34px; height: 34px;
  border-radius: 50%;
  border: 2px solid var(--iron-light);
  background: rgba(20, 16, 12, .75);
  color: var(--ink-muted);
  font: inherit; font-size: 9px; font-variant: small-caps; letter-spacing: .05em;
  cursor: pointer; padding: 0;
  -webkit-tap-highlight-color: transparent;
}
.auto-btn:active { transform: translateY(1px); }
.auto-btn.auto-on {
  color: #b9f0c8;
  border-color: rgba(63, 191, 106, .9);
  background: rgba(63, 191, 106, .25);
  box-shadow: 0 0 10px rgba(63, 191, 106, .6);
}

/* ---- the Settings switches and the chosen title, 17 Sep 2026 -----------
 * <body> carries pref-nomotion / pref-nodamage / pref-nochat from
 * nv_settings_body_class(), and narvoda.js flips them on a tap. Sound has
 * no rule: nothing plays one yet. The frame class sits on .avatar-ring
 * itself (it was on the <a> round it, which has no border, so nothing
 * ever showed). */
body.pref-nomotion .sprite, body.pref-nomotion .sprite-hero, body.pref-nomotion .sprite-mon,
body.pref-nomotion .sprite-img, body.pref-nomotion .hero-idle, body.pref-nomotion .hero-attack,
body.pref-nomotion .fx, body.pref-nomotion .embers, body.pref-nomotion .embers i,
body.pref-nomotion .torch::before, body.pref-nomotion .title-sigil, body.pref-nomotion .boss-pic .sprite,
body.pref-nomotion .class-figure .sprite { animation: none !important; }
body.pref-nomotion .sheet, body.pref-nomotion .sheet-back, body.pref-nomotion .btn, body.pref-nomotion .bar-btn,
body.pref-nomotion .flash, body.pref-nomotion .sc { transition: none !important; animation: none !important; }
body.pref-nodamage .floaters { display: none; }
body.pref-nochat .chatrow .chatline { visibility: hidden; }
.hud-title { margin-left: 6px; font-style: italic; color: var(--gold-light, #e8cf7a); }
.hud-title[hidden] { display: none; }

/* ==== the Fight screen's icon grid: three rows of six (include/grid.php), 17 Sep 2026 ====
 * The left column (Loot, Boss, then the grid's six) keeps the left 54px for
 * the whole height; the grid sits to its right, 46px icons, 8px labels,
 * rows two and three folded until More is tapped. The fold is .grid-open on
 * #scene, flipped in narvoda.js; the right column moves down under the open
 * grid so no link ever sits on another. Measured at 390x844 (scene 569px
 * tall): the hero stands at x 68-176 from y 330, the monster at x 232-340,
 * the tracker at bottom 12% - the left column ends at 420 and the right at
 * 536 when open, clear of all three. Eight left buttons only fit at 44px. */
.page-game .scene-grid { left: 60px; right: 6px; top: 40px; z-index: 6; grid-template-columns: repeat(6, 1fr); gap: 3px 2px; justify-items: center; }
.page-game .scene-grid .sc { gap: 1px; width: 100%; }
.page-game .scene-grid .sc-ico { width: 46px; height: 46px; }
.page-game .scene-grid .sc-ico .ui-pic { width: 36px; height: 36px; }
.page-game .scene-grid .sc-label { font-size: 8px; letter-spacing: .02em; white-space: nowrap; }
.page-game .scene-grid .sc .badge-red { top: -4px; right: -4px; min-width: 16px; height: 16px; line-height: 14px; font-size: 9px; padding: 0 3px; }
.page-game .scene:not(.grid-open) .scene-grid .sc-fold { display: none; }
.grid-more {
  position: absolute; left: calc(60px + (100% - 66px) / 2); top: 98px; transform: translateX(-50%); z-index: 6;
  height: 18px; padding: 0 12px; border-radius: 9px; font: inherit; font-size: 9px; font-variant: small-caps; letter-spacing: .06em;
  color: var(--ivory, #fff); background: rgba(11, 14, 34, .9); border: 1px solid var(--frame, #6b5a2a); cursor: pointer; line-height: 16px;
}
.grid-more .badge-red { top: -6px; right: -8px; min-width: 14px; height: 14px; line-height: 12px; font-size: 8px; padding: 0 3px; }
.page-game .scene.grid-open .grid-more { top: 214px; }
.page-game .scene.grid-open .grid-more::after { content: ' \25B4'; }
.page-game .scene:not(.grid-open) .grid-more::after { content: ' \25BE'; }
.page-game .edge:not(.edge-right) { top: 40px; gap: 4px; }
.page-game .edge-right { top: 122px; gap: 4px; }
.page-game .scene.grid-open .edge-right { top: 240px; }
.page-game .edge:not(.edge-right) .edge-btn { width: 44px; height: 44px; }
.page-game .edge-right .edge-btn { width: 46px; height: 46px; }
.page-game .edge a.edge-btn { text-decoration: none; padding: 2px; display: flex; flex-direction: column; align-items: center; justify-content: center; }
.page-game .edge .edge-btn .ui-pic { width: 30px; height: 30px; }
.page-game .edge .edge-label { font-size: 8px; color: #fff; text-shadow: 0 1px 2px #000; line-height: 1; margin-top: -2px; }
.page-game .edge .badge-red { top: -4px; right: -4px; min-width: 16px; height: 16px; line-height: 14px; font-size: 9px; padding: 0 3px; }
.page-game .edge .badge-gold { top: -4px; right: -6px; }

/* no corner gems on the panels, anywhere (17 Sep 2026: "i want the dots gone from everything") */
.card::before, .card::after, .sheet::before, .sheet::after { display: none !important; }
/* the "why" tip and the wrap that catches taps on disabled buttons */
.why-wrap { display: inline-block; position: relative; cursor: help; }
.why-wrap > button, .why-wrap > .btn { pointer-events: none; }
.row .why-wrap, .upgrade-row .why-wrap { flex: 0 0 auto; }
.why-wrap > .btn-big, .why-wrap > .btn:not(.btn-small):not(.btn-buy) { width: 100%; }
.card > .why-wrap, form > .why-wrap:only-child { display: block; }
.whytip {
  position: fixed; z-index: 90; display: none; max-width: 260px;
  padding: 6px 10px; border-radius: 8px; font-size: 12px; line-height: 1.3;
  color: var(--ivory); background: linear-gradient(180deg, #2a3164, #10132a);
  border: 1px solid var(--frame); box-shadow: 0 4px 12px rgba(0,0,0,.7);
  pointer-events: none; animation: tip-in .15s ease-out;
}
@keyframes tip-in { from { opacity: 0; transform: translateY(4px); } }
.locked { cursor: help; }

/* ================================================= polish, 17 Sep 2026
   "we need to add more style to the game", "it needs to feel alive". Cosmetic
   only; the JS half is assets/polish.js plus class flips in scene.js. At rest it
   is transforms and opacity. One off-list at the end (body.pref-nomotion; polish.js
   adds that class for the system preference too). */
/* 1. scene life: particles (polish.js builds them, a recipe a zone),
   a light-ray wash on .scene::before, a 3px sway on the painted backdrop */
.parts { position: absolute; inset: 0; z-index: 1; pointer-events: none; overflow: hidden; contain: strict; }
.parts i { position: absolute; display: block; width: 4px; height: 4px; border-radius: 50%; background: #fff; opacity: 0;
  animation: p-move var(--t, 8s) linear var(--d, 0s) infinite, p-fade var(--t, 8s) ease-in-out var(--d, 0s) infinite; }
@keyframes p-move { to { transform: translate(var(--dx, 0px), var(--dy, -200px)); } }
@keyframes p-fade { 0% { opacity: 0; } 15% { opacity: var(--o, .8); } 80% { opacity: var(--o, .8); } 100% { opacity: 0; } }
.parts .p-fly { background: #d8ff9a; box-shadow: 0 0 6px 2px rgba(200,255,140,.6); animation: p-drift var(--t, 6s) ease-in-out var(--d, 0s) infinite alternate, p-blink 2.3s ease-in-out var(--d, 0s) infinite; }
.parts .p-star { width: 2px; height: 2px; box-shadow: 0 0 3px 1px rgba(255,255,255,.5); animation: p-blink var(--t, 3s) ease-in-out var(--d, 0s) infinite; }
@keyframes p-drift { to { transform: translate(var(--dx, 20px), var(--dy, -20px)); } }
@keyframes p-blink { 0%, 100% { opacity: .1; } 50% { opacity: var(--o, .9); } }
.parts .p-ember { background: #ffb75a; box-shadow: 0 0 6px 2px rgba(255,140,50,.55); }
.parts .p-spark { width: 2px; height: 2px; background: #fff0c0; box-shadow: 0 0 4px 1px rgba(255,200,120,.7); }
.parts .p-snow { background: rgba(255,255,255,.9); filter: blur(.4px); }
.parts .p-dust { width: 3px; height: 3px; background: rgba(230,210,170,.55); }
.parts .p-heat { width: 2px; height: 2px; background: rgba(255,255,255,.7); }
.parts .p-leaf { width: 7px; height: 4px; border-radius: 60% 40%; background: #b8862e; animation: p-leaf var(--t, 9s) linear var(--d, 0s) infinite, p-fade var(--t, 9s) ease-in-out var(--d, 0s) infinite; }
@keyframes p-leaf {   /* tumbles as it falls */
  50% { transform: translate(calc(var(--dx) * .1), calc(var(--dy) * .5)) rotate(300deg); }
  100% { transform: translate(var(--dx), var(--dy)) rotate(600deg); } }
.parts .p-bird { width: 12px; height: 5px; border-radius: 50% 50% 0 0; background: none; border-top: 2px solid rgba(20,20,30,.7); animation: p-move var(--t, 20s) linear var(--d, 0s) infinite, p-fade var(--t, 20s) ease-in-out var(--d, 0s) infinite; }
.parts .p-wisp { width: 120px; height: 26px; background: rgba(220,240,220,.35); filter: blur(8px); }
.parts.paused i { animation-play-state: paused; }   /* polish.js, while the tab is hidden */
.scene { --ray: .06; }
.scene::before { content: ""; position: absolute; left: -40px; right: -40px; top: -10px; height: 70%; z-index: 1; pointer-events: none;
  background: repeating-linear-gradient(104deg, transparent 0 34px, rgba(255,240,200,var(--ray)) 34px 52px, transparent 52px 90px);
  -webkit-mask: radial-gradient(ellipse at 30% 0%, #000 10%, transparent 75%); mask: radial-gradient(ellipse at 30% 0%, #000 10%, transparent 75%);
  animation: rays 9s ease-in-out infinite alternate; }
@keyframes rays { from { transform: translateX(-12px); opacity: .7; } to { transform: translateX(12px); opacity: 1; } }
[data-zone="thornwood"] .scene { --ray: .12; }
[data-zone="frostreach"] .scene, [data-zone="salt-wastes"] .scene { --ray: .09; }
[data-zone="nightfall-vale"] .scene { --ray: .025; }
.has-backdrop .backdrop { inset: -6px; animation: sway 16s ease-in-out infinite alternate; }   /* the slack hides the edge */
@keyframes sway { from { transform: translate(-3px, 0); } to { transform: translate(3px, -2px); } }
/* 2. hit feel: a crit rocks the scene, the bar blinks, chunkier numbers that pop
   1.3 to 1, six coins on a kill, the gold flying to the counter (path: polish.js) */
.scene.quake { animation: quake .12s linear; }
@keyframes quake { 25% { transform: translate(3px, -2px); } 50% { transform: translate(-3px, 2px); } 75% { transform: translate(2px, 1px); } }
.bar-fill.hp-flash { animation: hp-flash .2s linear; }
@keyframes hp-flash { 0%, 55% { filter: brightness(3) saturate(0); } }
.float { font-weight: 900; -webkit-text-stroke: .8px #1a0f08; paint-order: stroke fill; animation: pop-up 1.1s ease-out forwards; }
@keyframes pop-up { 0% { opacity: 0; transform: translate(-50%, 8px) scale(.5); } 14% { opacity: 1; transform: translate(-50%, -6px) scale(1.3); }
  32% { transform: translate(-50%, -16px) scale(1); } 100% { opacity: 0; transform: translate(-50%, -76px) scale(1); } }
.coin-fly { position: absolute; z-index: 20; pointer-events: none; white-space: nowrap; font-weight: 900; font-size: 16px; color: var(--gold-light);
  text-shadow: 0 1px 0 #3a2a10, 0 0 6px rgba(0,0,0,.9); }
.coin-fly::before, .coin { border-radius: 50%; background: radial-gradient(circle at 35% 30%, #fff6c0, #e8b640 55%, #8a5a10); box-shadow: 0 0 4px rgba(255,210,100,.8); }
.coin-fly::before { content: ""; display: inline-block; width: 10px; height: 10px; margin: 0 3px -1px 0; }
.coin { position: absolute; left: 50%; top: 55%; width: 7px; height: 7px; margin: -3px; z-index: 5; pointer-events: none; animation: coin-pop .7s cubic-bezier(.2, .6, .4, 1) forwards; }
@keyframes coin-pop { 40% { opacity: 1; transform: translate(var(--cx), calc(var(--cy) - 26px)) scale(1.1); } 100% { opacity: 0; transform: translate(calc(var(--cx) * 1.3), calc(var(--cy) + 22px)) scale(.5); } }
#hud-gold { display: inline-block; }
#hud-gold.gold-pulse { animation: gold-pulse .6s ease-out; }
@keyframes gold-pulse { 20% { transform: scale(1.3); color: #fff8d0; } 60% { transform: scale(1.1); } }
/* 3. banners: LEVEL UP and STAGE CLEARED sweep across the scene for 1.5s */
.banner { position: absolute; left: 0; right: 0; top: 40%; z-index: 30; pointer-events: none; padding: 10px 0; text-align: center;
  font-size: 30px; font-weight: 900; font-variant: small-caps; letter-spacing: .14em;
  color: #fff6c8; text-shadow: 0 2px 0 #7a4a00, 0 0 18px rgba(255,200,80,.9), 0 4px 10px rgba(0,0,0,.8);
  background: linear-gradient(90deg, transparent, rgba(60,30,0,.75) 25%, rgba(60,30,0,.75) 75%, transparent);
  border-top: 2px solid var(--gold-light); border-bottom: 2px solid var(--gold-light);
  animation: banner-sweep 1.5s cubic-bezier(.2, .8, .3, 1) forwards; }
.banner-stage { color: #ffd0c0; text-shadow: 0 2px 0 #6e1210, 0 0 18px rgba(255,120,90,.9); }
@keyframes banner-sweep { 0% { opacity: 0; transform: translateX(-100%) skewX(-8deg); } 22% { opacity: 1; transform: translateX(0) skewX(0); }
  78% { opacity: 1; transform: translateX(0); } 100% { opacity: 0; transform: translateX(100%) skewX(8deg); } }
/* 4. panel dressing: a flourish (inline SVG) under every head, a light sweep on the
   gold button, a glint over the currencies and the bar in turn, the lit tab breathing,
   sheets landing with an overshoot, the page fading in */
.card-head::after { height: 10px; left: 6%; right: 6%; bottom: -2px; background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 60 10'%3E%3Cpath d='M30 1l4 4-4 4-4-4z' fill='%23ffe9a8'/%3E%3Ccircle cx='19' cy='5' r='1.5' fill='%23d4a94e'/%3E%3Ccircle cx='41' cy='5' r='1.5' fill='%23d4a94e'/%3E%3Cpath d='M0 5h15M45 5h15' stroke='%23d4a94e'/%3E%3C/svg%3E") 50% 50% / 60px 10px no-repeat,
    linear-gradient(90deg, transparent, var(--frame) 30%, transparent 46%, transparent 54%, var(--frame) 70%, transparent) 50% 50% / 100% 1px no-repeat; }
.btn-gold, .cur-item, .bar-ico, .cp-big { position: relative; }
.btn-gold, .cur-item { overflow: hidden; }
.btn-gold::after, .cur-item::after, .bar-ico::after { content: ""; position: absolute; top: -10%; bottom: -10%; left: 0; width: 40%; pointer-events: none;
  background: linear-gradient(105deg, transparent, rgba(255,245,200,.5) 50%, transparent); transform: translateX(-150%) skewX(-15deg); }
.btn-gold::after { width: 45%; opacity: 0; }
.btn-gold:hover::after, .btn-gold:active::after { animation: sweep .55s ease-out; }
@keyframes sweep { 0% { transform: translateX(-150%) skewX(-15deg); opacity: 1; } 100% { transform: translateX(320%) skewX(-15deg); opacity: 0; } }
.cur-item::after, .bar-ico::after { animation: glint-x 6s linear infinite; }
@keyframes glint-x { 0% { transform: translateX(-150%) skewX(-15deg); } 12% { transform: translateX(300%) skewX(-15deg); } 100% { transform: translateX(300%) skewX(-15deg); } }
.cur-item:nth-child(2)::after { animation-delay: 1.5s; } .cur-item:nth-child(3)::after { animation-delay: 3s; } .cur-item:nth-child(4)::after { animation-delay: 4.5s; }
.bar-btn:nth-child(2n) .bar-ico::after { animation-delay: 3s; } .bar-btn:nth-child(3n) .bar-ico::after { animation-delay: 1.5s; }
.bar-on .bar-ico::before { content: ""; position: absolute; inset: 0; border-radius: 50%; pointer-events: none; box-shadow: inset 0 0 10px 2px rgba(255,225,140,.85); animation: glow-op 2s ease-in-out infinite; }
@keyframes glow-op { 0%, 100% { opacity: .35; } 50% { opacity: 1; } }
@keyframes sheet-up { 0% { transform: translate(-50%, 100%); } 70% { transform: translate(-50%, -8px); } 100% { transform: translate(-50%, 0); } }
.sheet { animation: sheet-up .36s cubic-bezier(.2, .8, .3, 1); }
.content { animation: content-in .25s ease-out; }
@keyframes content-in { from { opacity: 0; } }
/* 5. the title screen: a 30s push in, three embers a span, a glint masked by the logo */
/* the logo's size rule went missing from the file at 01:40 (concurrent edits above); it lives here now */
.title-logo { display: block; width: min(92vw, 520px); height: auto; margin: 0 auto 4px; filter: drop-shadow(0 8px 18px rgba(0,0,0,.8)); animation: logo-in .8s ease-out; }
.title-logo-small { width: min(80vw, 360px); margin-bottom: 10px; }
@keyframes logo-in { from { opacity: 0; transform: translateY(-10px) scale(.96); } }
.gate-bg { animation: gate-zoom 30s ease-in-out infinite alternate; transform-origin: 50% 40%; }
@keyframes gate-zoom { to { transform: scale(1.06); } }
.embers i { box-shadow: 0 0 8px 2px rgba(255,150,60,.55), 28px -70px 0 -1px #ffb75a, -34px -150px 0 -1px #ffa040; }
.hero-title { position: relative; }
.hero-title::after { content: ""; position: absolute; left: 50%; top: 10px; width: min(92vw, 520px); aspect-ratio: 1000 / 719; pointer-events: none; transform: translateX(-50%);
  -webkit-mask: url(../images/logo/logo.png) 50% 50% / contain no-repeat; mask: url(../images/logo/logo.png) 50% 50% / contain no-repeat;
  background: linear-gradient(110deg, transparent 42%, rgba(255,255,255,.55) 50%, transparent 58%) 0 0 / 300% 100% no-repeat;
  animation: logo-glint 8s linear 2s infinite; }
@keyframes logo-glint { 0% { background-position: 120% 0; } 10% { background-position: -20% 0; } 100% { background-position: -20% 0; } }
/* 6. alive at rest: buttons breathe on their own beats, the lit boss button throbs,
   badges beat, the loot badge hops on a change (.bump, polish.js), a sparkle on CP,
   a new chat line slides in, the monster fidgets (.twitch, scene.js) */
.page-game .scene-grid .sc-ico, .page-game .edge-btn { animation: breathe-btn 3s ease-in-out infinite; }
.page-game .scene-grid .sc:nth-child(3n+2) .sc-ico, .page-game .edge .edge-btn:nth-child(3n+2) { animation-delay: -1s; }
.page-game .scene-grid .sc:nth-child(3n) .sc-ico, .page-game .edge .edge-btn:nth-child(3n) { animation-delay: -2s; }
.page-game .scene-grid .sc:nth-child(2n) .sc-ico, .page-game .edge-right .edge-btn:nth-child(2n) { animation-duration: 3.4s; }
@keyframes breathe-btn { 50% { transform: scale(1.04); } }
.page-game .edge-btn:active { animation: none; transform: translateY(1px); }
.edge-btn.edge-lit { animation: lit 1.4s ease-in-out infinite, throb 1.4s ease-in-out infinite; }
@keyframes throb { 50% { transform: scale(1.08); } }
.badge-red { animation: badge-beat 1s ease-in-out infinite; }
@keyframes badge-beat { 50% { transform: scale(1.2); } }
.badge.bump { animation: bump .3s ease-out; }
@keyframes bump { 40% { transform: translateY(-4px) scale(1.2); } }
.cp-big::after { content: ""; position: absolute; left: 18px; top: -4px; width: 10px; height: 10px; pointer-events: none; opacity: 0; transform: scale(0);
  background: radial-gradient(circle, #fff 0 20%, rgba(255,255,255,0) 60%), linear-gradient(#fff, #fff) 50% 50% / 1.5px 100% no-repeat;
  animation: cp-glint 7s ease-in-out infinite; }
@keyframes cp-glint { 0%, 100% { opacity: 0; transform: scale(0) rotate(0); } 4% { opacity: 1; transform: scale(1.1) rotate(45deg); } 8% { opacity: 0; transform: scale(0) rotate(90deg); } }
.feed-line.feed-new { animation: feed-in .4s ease-out; }
@keyframes feed-in { from { opacity: 0; transform: translateX(14px); } }
.spot-mon.twitch:not(.hit) .sprite-mon { animation: twitch .5s ease-out; }
@keyframes twitch { 30% { transform: translateY(-7px) scaleX(1.05) rotate(-2deg); } 60% { transform: translateY(0) scaleX(.98); } }
/* the off switch: the Settings toggle; polish.js maps the system preference onto it.
   The title screen has no JS, so it keeps a media rule. */
body.pref-nomotion :is(.parts, .coin, .coin-fly, .banner) { display: none !important; }
body.pref-nomotion :is(.backdrop, .scene, .bar-fill, .content, .sc-ico, .edge-btn, .badge, .cp-big, .feed-line, #hud-gold),
body.pref-nomotion .scene::before, body.pref-nomotion .cur-item::after, body.pref-nomotion .bar-ico::after, body.pref-nomotion .bar-ico::before,
body.pref-nomotion .btn-gold::after, body.pref-nomotion .cp-big::after { animation: none !important; }
@media (prefers-reduced-motion: reduce) { .gate-bg, .hero-title::after { animation: none; } }
.feed-system { color: #ffd26a; }

/* ================================================= the premium set, 17 Sep 2026
 * "the stuff u buy with real cash needs more style so it stands out and
 * people want to pay for it". One shared look for every real-money row on
 * treasury, vip, events, pass, journey, relics, shop, land and guild:
 *   .premium       the row: violet-to-indigo panel, gold double frame, a
 *                  shimmer sweep every 6s, the picture large with a glow
 *   .prem-name     the item's name, in gold
 *   .prem-chips    what you get, as icon + number chips (.prem-chip)
 *   .prem-value    the honest value line under the button
 *   .prem-ribbon   the corner banner: First buy x2, Best value, Popular,
 *                  Limited (with a countdown), Season
 *   .prem-buy      wraps the buy form; .btn-buy-premium is its button with
 *                  the .prem-price tag inside
 *   .prem-dot      the "daily" pulse on the VIP pack and the Charter
 *   .prem-ladder   the Fund's payout ladder as small gold coins
 *   .prem-banner   the wide art on top of the Dragon Pass card
 * Every class is prem- prefixed because the page already has .banner,
 * .coin and .burst for other things. Appended last so it wins on order.
 * The "Real money" line on each card is deliberately NOT styled here. */
.premium {
  /* clip, not hidden: hidden makes the row a scroll container, and a focus()
   * or scrollIntoView() on the button then scrolls the row itself so the
   * picture vanishes upward (found in the 390px test, 17 Sep 2026) */
  position: relative; overflow: hidden; overflow: clip; isolation: isolate;
  padding: 12px 12px 12px; gap: 12px; align-items: flex-start;
  color: var(--ivory);
  background:
    radial-gradient(ellipse at 20% 0%, rgba(150, 90, 255, .28), transparent 55%),
    radial-gradient(ellipse at 100% 100%, rgba(60, 110, 255, .22), transparent 50%),
    linear-gradient(160deg, #2b1a5e 0%, #1c1f52 50%, #131a44 100%);
  border: 2px solid var(--frame); border-radius: 12px;
  box-shadow:
    inset 0 0 0 2px #10132a, inset 0 0 0 3px var(--frame-dark),
    inset 0 1px 0 rgba(255,255,255,.15), 0 0 16px rgba(212,169,78,.22), 0 6px 14px rgba(0,0,0,.6);
}
.premium.locked { opacity: .7; }
/* the shimmer: a slanted band of light that crosses once every six seconds */
.premium::before {
  content: ""; position: absolute; top: -60%; bottom: -60%; left: -45%; width: 35%; z-index: 0; pointer-events: none;
  background: linear-gradient(105deg, transparent 0%, rgba(255, 236, 170, .0) 35%, rgba(255, 236, 170, .28) 50%, transparent 65%);
  transform: skewX(-18deg);
  animation: prem-sweep 6s ease-in-out infinite;
}
@keyframes prem-sweep { 0% { left: -45%; } 22%, 100% { left: 145%; } }
.premium > * { position: relative; z-index: 1; }

/* the picture, 72px, on a soft gold glow that breathes */
.prem-pic {
  flex: 0 0 auto; width: 84px; height: 84px; display: grid; place-items: center; margin: -2px 0 0;
  background: radial-gradient(circle, rgba(255, 220, 130, .48) 0%, rgba(255, 200, 90, .18) 42%, transparent 68%);
  animation: prem-glow 3.2s ease-in-out infinite;
}
.prem-pic img, .premium .pic-row, .premium .pic-small {
  width: 72px; height: 72px; object-fit: contain;
  filter: drop-shadow(0 0 6px rgba(255, 225, 150, .75)) drop-shadow(0 3px 3px rgba(0,0,0,.6));
}
.prem-pic img { animation: prem-float 4s ease-in-out infinite; }
@keyframes prem-glow  { 50% { transform: scale(1.08); opacity: .85; } }
@keyframes prem-float { 50% { transform: translateY(-3px); } }

.premium .row-info { flex: 1 1 140px; min-width: 0; }
.premium .prem-name, .premium .row-info > strong {
  display: block; color: var(--frame-light); font-size: 17px; line-height: 1.2; letter-spacing: .02em;
  text-shadow: 0 1px 0 #3a2a10, 0 0 8px rgba(255, 210, 120, .45);
}
.premium .row-info .small { display: block; margin-top: 3px; }
.premium .small, .premium .muted { color: #cfc7b2; }

/* what you get: one chip per thing, the picture then the number */
.prem-chips { display: flex; flex-wrap: wrap; gap: 5px; margin: 6px 0 2px; }
.prem-chip {
  display: inline-flex; align-items: center; gap: 4px; min-height: 26px;
  padding: 2px 9px 2px 4px; border-radius: 999px;
  color: #fff; font-size: 13px; font-weight: 700; white-space: nowrap;
  background: linear-gradient(180deg, rgba(0,0,0,.45), rgba(0,0,0,.25));
  border: 1px solid rgba(212, 169, 78, .6);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.08);
}
.prem-chip img { width: 20px; height: 20px; object-fit: contain; filter: drop-shadow(0 1px 1px #000); }
.prem-chip b { color: var(--frame-light); }
.prem-chip.prem-chip-x2 { border-color: #ffb0a8; color: #ffd5d0; background: linear-gradient(180deg, rgba(208,52,60,.4), rgba(120,20,30,.4)); }
.prem-chip.prem-chip-x2 s { color: #a99; font-weight: 400; margin-right: 2px; }

/* the value line: small, honest, gold */
.prem-value { display: block; margin: 6px 0 0; font-size: 12px; color: #e6cf8a; font-style: italic; }
.prem-value::before { content: "\2726  "; color: var(--frame); font-style: normal; }

/* the buy block sits under the words, full width, so the button is a big
 * target at 360px and nothing gets squeezed beside the picture */
.premium .prem-buy { flex: 1 1 100%; position: relative; margin: 2px 0 0; }
.premium .prem-buy form { margin: 0; }
.premium .prem-buy .btn { width: 100%; min-width: 0; }
.premium .prem-buy + .prem-value { flex: 1 1 100%; margin-top: 0; }

/* the button: 48px, gold gloss, a highlight that keeps moving, the price
 * tag on the right and a small crown on the left */
.btn-buy-premium {
  position: relative; overflow: hidden;
  min-height: 48px; padding: 6px 6px 6px 12px; gap: 8px;
  border-radius: 12px; font-size: 15px; letter-spacing: .05em;
  color: #2b1a04; border: 1px solid #6a4a10;
  background: linear-gradient(180deg, #fff4c4 0%, #f3c85a 44%, #d59d26 56%, #f4c95c 100%);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.7), inset 0 -2px 0 rgba(0,0,0,.25),
    0 0 0 1px rgba(0,0,0,.5), 0 3px 8px rgba(0,0,0,.6), 0 0 14px rgba(255, 205, 100, .35);
  text-shadow: 0 1px 0 rgba(255,255,255,.55);
  transition: transform .08s ease-out, box-shadow .08s ease-out;
}
.btn-buy-premium::after {
  content: ""; position: absolute; top: -30%; bottom: -30%; left: 0; width: 38%; pointer-events: none;
  background: linear-gradient(105deg, transparent 0%, rgba(255,255,255,.6) 50%, transparent 100%);
  transform: translateX(-160%) skewX(-16deg);
  animation: prem-gloss 3.4s ease-in-out infinite;
}
@keyframes prem-gloss { 0% { transform: translateX(-160%) skewX(-16deg); } 45%, 100% { transform: translateX(340%) skewX(-16deg); } }
.btn-buy-premium:active { transform: scale(.96); box-shadow: inset 0 2px 4px rgba(0,0,0,.3), 0 1px 3px rgba(0,0,0,.5); }
.btn-buy-premium:disabled:active { transform: none; }
.btn-buy-premium .prem-crown { display: inline-flex; width: 20px; height: 20px; flex: 0 0 auto; }
.btn-buy-premium .prem-crown img { width: 20px; height: 20px; object-fit: contain; filter: drop-shadow(0 1px 1px rgba(0,0,0,.5)); }
.btn-buy-premium .prem-txt { flex: 1 1 auto; text-align: left; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.prem-price {
  flex: 0 0 auto; margin-left: auto;
  padding: 5px 12px; border-radius: 999px;
  font-size: 16px; font-weight: 700; font-variant: normal; letter-spacing: 0;
  color: var(--frame-light); text-shadow: 0 1px 1px #000;
  background: linear-gradient(180deg, #4a2f0a, #1e1204);
  border: 1px solid #8a6a2a;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.6);
}
/* the "busy" state while the in-place buy is on its way */
.btn-buy-premium.busy { filter: brightness(.85); pointer-events: none; }

/* the corner ribbon: a band across the top-right corner */
.prem-ribbon {
  position: absolute; top: 14px; right: -34px; z-index: 3; width: 140px; padding: 3px 0;
  transform: rotate(45deg); text-align: center;
  font-size: 11px; font-weight: 700; font-variant: small-caps; letter-spacing: .08em; line-height: 1.2;
  color: #2b1a04; background: linear-gradient(180deg, #ffe9a8, #d4a94e 60%, #b8892e);
  box-shadow: 0 1px 4px rgba(0,0,0,.6), inset 0 1px 0 rgba(255,255,255,.5);
  border-top: 1px solid rgba(255,255,255,.4); border-bottom: 1px solid rgba(0,0,0,.35);
  pointer-events: none;
}
.prem-ribbon-first   { color: #fff; background: linear-gradient(180deg, #ff8a80, #d0343c 60%, #8e1c22); text-shadow: 0 1px 1px #000; }
.prem-ribbon-best    { color: #062a10; background: linear-gradient(180deg, #b9f0c8, #3fbf6a 60%, #227a40); }
.prem-ribbon-popular { color: #fff; background: linear-gradient(180deg, #9cc4ff, #3d7de0 60%, #1d4aa0); text-shadow: 0 1px 1px #000; }
.prem-ribbon-limited { color: #fff; background: linear-gradient(180deg, #ffb070, #e0662a 60%, #9a3a10); text-shadow: 0 1px 1px #000; }
.prem-ribbon-season  { color: #2b1a04; background: linear-gradient(180deg, #fff4c4, #f0c452 60%, #b8892e); }
/* a ribbon needs the row's top-right corner clear: the name wraps short of it */
.premium.has-ribbon .row-info { padding-right: 30px; }
/* the countdown chip that goes with Limited */
.prem-timer {
  display: inline-flex; align-items: center; gap: 4px; margin-top: 4px;
  padding: 1px 8px; border-radius: 999px; font-size: 12px; font-weight: 700;
  color: #ffd9b8; background: rgba(224, 102, 42, .25); border: 1px solid rgba(224, 102, 42, .7);
}
.prem-timer::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: #ff9a60; box-shadow: 0 0 6px #ff9a60; animation: prem-pulse 1.2s ease-in-out infinite; }

/* the daily dot: a green pulse beside the name on things that pay every day */
.prem-dot {
  display: inline-block; width: 9px; height: 9px; margin: 0 4px 1px 0; border-radius: 50%; vertical-align: middle;
  background: radial-gradient(circle at 35% 30%, #d6ffe0, #3fbf6a 50%, #1c6b38);
  box-shadow: 0 0 0 0 rgba(63, 191, 106, .7);
  animation: prem-ping 1.8s ease-out infinite;
}
@keyframes prem-ping  { 0% { box-shadow: 0 0 0 0 rgba(63,191,106,.7); } 70% { box-shadow: 0 0 0 8px rgba(63,191,106,0); } 100% { box-shadow: 0 0 0 0 rgba(63,191,106,0); } }
@keyframes prem-pulse { 50% { opacity: .35; } }
.prem-daily { font-size: 11px; color: #b9f0c8; font-variant: small-caps; letter-spacing: .06em; margin-left: 4px; }

/* the Fund's ladder: one gold coin a milestone, lit when reached, ticked when paid */
.prem-ladder { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0 2px; }
.prem-coin-step {
  display: grid; justify-items: center; gap: 2px; min-width: 52px; padding: 5px 4px 4px;
  border-radius: 10px; border: 1px solid rgba(212,169,78,.35); background: rgba(0,0,0,.3);
  font-size: 11px; color: #cfc7b2; opacity: .55;
}
.prem-coin-step i {
  display: block; width: 26px; height: 26px; border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #fff6c8, #f0c452 40%, #b8892e 75%, #6a4a10);
  box-shadow: inset 0 0 0 3px rgba(0,0,0,.12), inset 0 0 0 5px rgba(255,255,255,.25), 0 2px 3px rgba(0,0,0,.6);
}
.prem-coin-step b { color: var(--frame-light); font-size: 12px; }
.prem-coin-step.here { opacity: 1; border-color: var(--frame); }
.prem-coin-step.here i { box-shadow: inset 0 0 0 3px rgba(0,0,0,.12), inset 0 0 0 5px rgba(255,255,255,.25), 0 0 10px rgba(255,220,130,.8); }
.prem-coin-step.paid { opacity: 1; border-color: rgba(63,191,106,.7); }
.prem-coin-step.paid i { background: radial-gradient(circle at 35% 30%, #d6ffe0, #3fbf6a 45%, #1c6b38); }
.prem-coin-step.paid i::after { content: "\2713"; display: block; text-align: center; line-height: 26px; color: #fff; font-size: 15px; font-weight: 700; }

/* the Dragon Pass: the wide banner across the top of the card, the season
 * name in its empty centre, and a gold column for the paid track */
.prem-banner {
  position: relative; display: block;
  width: calc(100% + 28px); margin: -12px -14px 10px; height: 118px;
  border-radius: 10px 10px 0 0; overflow: hidden;
  background: #1a1040;
}
.prem-banner img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 45%; display: block; }
.prem-banner-text {
  position: absolute; left: 50%; top: 61%; transform: translate(-50%, -50%);
  width: 46%; text-align: center; color: #3a2a10; line-height: 1.1;
}
.prem-banner-text b { display: block; font-size: 16px; letter-spacing: .04em; }
.prem-banner-text span { display: block; font-size: 10px; text-transform: uppercase; letter-spacing: .12em; color: #6a4a10; }
.prem-track-paid, .pass-row .pass-paid.prem-track-paid {
  border-left: 1px solid rgba(212,169,78,.5); padding-left: 8px; margin: -6px 0; padding-top: 6px; padding-bottom: 6px;
  background: linear-gradient(90deg, rgba(212,169,78,.14), rgba(212,169,78,.05));
  border-radius: 0 8px 8px 0;
}
.prem-track-paid .small { color: var(--frame-light); }
.prem-track-free .small { color: #a8a69c; }
.pass-heads .prem-head-paid { color: var(--frame-light); text-shadow: 0 0 6px rgba(255,210,120,.4); }

/* after a test buy lands: coins burst off the button and the row flashes */
.premium.prem-flash { animation: prem-flash .9s ease-out; }
@keyframes prem-flash { 0% { box-shadow: 0 0 0 0 rgba(255,225,140,.9), 0 0 30px rgba(255,220,130,.9); } 100% { box-shadow: inset 0 0 0 2px #10132a, inset 0 0 0 3px var(--frame-dark), 0 0 16px rgba(212,169,78,.22); } }
.prem-buy .fx.burst { left: 50%; top: 50%; z-index: 6; }
.prem-coin {
  position: absolute; left: 50%; top: 50%; z-index: 7; width: 14px; height: 14px; margin: -7px 0 0 -7px; border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle at 35% 30%, #fff6c8, #f0c452 45%, #9d7a2a);
  box-shadow: inset 0 0 0 2px rgba(0,0,0,.1), 0 0 6px rgba(255,220,130,.8);
  animation: prem-coin .8s cubic-bezier(.2,.7,.3,1) forwards;
}
@keyframes prem-coin {
  0%   { transform: translate(0, 0) scale(.6); opacity: 1; }
  60%  { opacity: 1; }
  100% { transform: translate(var(--dx, 0px), var(--dy, -60px)) scale(1); opacity: 0; }
}

/* narrow phones: the chips wrap, the price tag stays whole */
@media (max-width: 380px) {
  .premium { padding: 10px; gap: 10px; }
  .prem-pic { width: 76px; height: 76px; }
  .prem-pic img, .premium .pic-row, .premium .pic-small { width: 66px; height: 66px; }
  .btn-buy-premium { font-size: 14px; padding-left: 10px; }
  .prem-price { font-size: 15px; padding: 5px 10px; }
}
/* the off switches, same as the rest of the page */
body.pref-nomotion .premium::before, body.pref-nomotion .btn-buy-premium::after, body.pref-nomotion .prem-pic, body.pref-nomotion .prem-pic img,
body.pref-nomotion .prem-dot, body.pref-nomotion .prem-timer::before, body.pref-nomotion .premium.prem-flash { animation: none !important; }
body.pref-nomotion .prem-coin, body.pref-nomotion .prem-buy .fx { display: none !important; }
@media (prefers-reduced-motion: reduce) {
  .premium::before, .btn-buy-premium::after, .prem-pic, .prem-pic img, .prem-dot, .prem-timer::before, .premium.prem-flash { animation: none !important; }
  .prem-coin, .prem-buy .fx { display: none !important; }
}
/* the claim button inside a premium row (Charter, Fund, Supplies, Seven-Day) is full width and as tall as the buy button */
.premium .prem-claim .btn { width: 100%; min-height: 48px; font-size: 15px; }
/* Best value / Popular as a small tag when First buy x2 has the corner */
.prem-chip.prem-tag { font-size: 11px; font-variant: small-caps; letter-spacing: .06em; padding: 2px 9px; font-weight: 700; }
.prem-tag-best { color: #b9f0c8; border-color: rgba(63, 191, 106, .7); }
.prem-tag-popular { color: #9cc4ff; border-color: rgba(61, 125, 224, .7); }
/* riding into the fight: the mount under the hero, the pet at their side */
.spot-hero { overflow: visible; }
.ride-mount { position: absolute; left: 50%; bottom: -6px; width: 150px; height: auto; transform: translateX(-46%); z-index: 0; filter: drop-shadow(0 6px 4px rgba(0,0,0,.55)); animation: mount-bob 2.6s ease-in-out infinite; }
.spot-hero:has(.ride-mount) .sprite-hero { bottom: 38px; z-index: 1; }
.spot-hero:has(.ride-mount) .tag { top: -78px; }
.ride-pet { position: absolute; left: -44px; bottom: 0; width: 54px; height: auto; z-index: 1; filter: drop-shadow(0 4px 3px rgba(0,0,0,.5)); animation: pet-bob 1.8s ease-in-out infinite; }
@keyframes mount-bob { 50% { transform: translateX(-46%) scaleY(1.015); } }
@keyframes pet-bob { 50% { transform: scaleY(1.04) scaleX(.985); } }   /* planted too (21 Sep 2026) */
body.pref-nomotion .ride-mount, body.pref-nomotion .ride-pet { animation: none; }

/* ---- the quality of life packs, 17 Sep 2026 (include/qol.php) -----------
 * A locked convenience keeps its place on the page so the player can see
 * what the pack buys: .qol-locked is the link-shaped button with a padlock
 * (.qol-lock) drawn in CSS, and .auto-btn.auto-locked is the round Auto
 * toggle with the same padlock in its corner. The padlock is two shapes,
 * no image, so the live CSP has nothing to block. The Treasury rows reuse
 * .premium above; .qol-held only dims a row already bought. */
.qol-locked { display: inline-flex; align-items: center; gap: 6px; opacity: .8; text-decoration: none; }
.qol-locked .small { text-transform: none; letter-spacing: 0; }
.qol-lock, .auto-btn.auto-locked::after {
  content: ""; display: inline-block; width: 9px; height: 8px; border-radius: 2px;
  background: var(--frame, #d4a94e); position: relative; flex: none;
  box-shadow: inset 0 3px 0 rgba(0, 0, 0, .35);
}
.qol-lock::before, .auto-btn.auto-locked::before {
  content: ""; position: absolute; left: 1.5px; top: -5px; width: 4px; height: 5px;
  border: 1.5px solid var(--frame, #d4a94e); border-bottom: 0; border-radius: 4px 4px 0 0;
}
.auto-btn.auto-locked { position: relative; opacity: .75; }
.auto-btn.auto-locked::after { position: absolute; right: -3px; bottom: -2px; }
.auto-btn.auto-locked::before { left: auto; right: -0.5px; bottom: 6px; top: auto; }
.qol-row.qol-held { opacity: .75; }
.qol-row .prem-chip { font-size: 11px; }
.sweep-form { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 6px; }
.sweep-form .btn { width: auto; }

/* ================================================= the bottom cluster, 17 Sep 2026
   "i want the stage and boss down here with the auto". The Stage orb wears
   the boss gate ring; Auto-Stage sits under it; Boss beside; the quest to the
   right. Sits along the bottom of the scene above the rates line. */
.scene-bottom {
  position: absolute; left: 8px; right: 8px; bottom: 40px; z-index: 6;
  display: flex; align-items: flex-end; gap: 10px;
}
.orb-wrap { position: relative; display: flex; flex-direction: column; align-items: center; gap: 2px; flex: 0 0 auto; }
.gate-ring.orb {
  position: relative; width: 74px; height: 74px; display: flex; align-items: center; justify-content: center;
  background: none; border: 0; box-shadow: none;
}
.gate-ring.orb svg { position: absolute; inset: 0; width: 100%; height: 100%; transform: rotate(-90deg); }
.gate-ring.orb .ring-bg { fill: none; stroke: rgba(0,0,0,.55); stroke-width: 3; }
.gate-ring.orb .ring-fg { fill: none; stroke: var(--frame-light); stroke-width: 3; stroke-linecap: round; stroke-dasharray: var(--gate, 0) 100; filter: drop-shadow(0 0 4px rgba(255,220,130,.8)); }
.orb-pic { position: absolute; left: 50%; top: 50%; width: 62px; height: 62px; transform: translate(-50%, -50%); object-fit: contain; filter: drop-shadow(0 4px 6px rgba(0,0,0,.7)); }
.orb-stage { position: relative; z-index: 2; font-size: 9px; letter-spacing: .06em; text-transform: uppercase; color: #fff; text-shadow: 0 1px 2px #000, 0 0 6px #000; text-align: center; line-height: 1; margin-top: -2px; }
.orb-stage b { display: block; font-size: 22px; font-weight: 900; color: var(--frame-light); text-shadow: 0 1px 0 #7a4a00, 0 2px 6px #000; }
.orb-gate { position: absolute; bottom: -2px; left: 50%; transform: translateX(-50%); z-index: 2; font-size: 9px; padding: 0 6px; border-radius: 999px; background: rgba(0,0,0,.7); color: var(--frame-light); border: 1px solid var(--frame-dark); }
.orb-auto { position: static; margin-top: 4px; }
.orb-auto .auto-btn {
  width: auto; height: 22px; min-height: 0; padding: 0 10px; border-radius: 999px; font-size: 10px; font-weight: 800;
  background: linear-gradient(180deg, #3b4479, #171c3d); color: var(--ivory-muted); border: 1px solid var(--frame-dark);
}
.orb-auto .auto-btn.auto-on { background: linear-gradient(180deg, #7ee29a, #2e9c55 55%, #1f6b3b); color: #fff; box-shadow: 0 0 10px rgba(126,226,154,.6); }
.orb-auto .auto-btn.auto-locked::before { content: "\1F512  "; font-size: 9px; }
.scene-bottom .edge-btn { position: relative; width: 56px; height: 56px; flex: 0 0 auto; margin-bottom: 26px; }
.scene-bottom .tracker { position: static; flex: 1 1 auto; margin-bottom: 30px; max-width: none; }
/* the top strip keeps the kill chip and the timer only */
.scene-top { justify-content: space-between; }
@media (max-width: 430px) { .scene-bottom { gap: 6px; } .scene-bottom .edge-btn { width: 50px; height: 50px; } }
.orb-wrap .auto-form, .orb-wrap .orb-auto { position: static !important; left: auto !important; top: auto !important; transform: none !important; margin: 4px 0 0 !important; }
.orb-wrap .auto-btn { position: static !important; transform: none !important; }

/* the black and gold VIP badge for VIP 11 and up (17 Sep 2026): the number is
 * pale gold on the black medallion, where the white of the gold badge would
 * be lost in the gems */
.hud-vip.vip-pic.vip-high .vip-n { color: #ffe08a; text-shadow: 0 0 2px #000, 0 1px 2px #000, 0 0 6px rgba(255,200,90,.6); }
.hud-vip.vip-pic.vip-high .vip-t { color: #ffd26a; }
/* the bottom cluster must not swallow taps meant for the right column beside it */
.scene-bottom { pointer-events: none; }
.scene-bottom > * , .scene-bottom .orb-wrap > * { pointer-events: auto; }
/* riding, properly: the hero sits on the mount's back, not beside it (17 Sep 2026) */
.ride-mount { width: 164px; bottom: -8px; transform: translateX(-44%); }
.spot-hero:has(.ride-mount) .sprite-hero { width: 82px; height: 82px; bottom: 58px; transform: translateX(-66%); }
.spot-hero:has(.ride-mount) .hero-idle { animation: none; }
.spot-hero:has(.ride-mount).lunge .hero-attack { transform: translateX(-66%); animation: strike-ride .42s cubic-bezier(.2, .9, .3, 1); }
@keyframes strike-ride { 18% { transform: translateX(-70%) scale(1.04, .96); } 45% { transform: translateX(-52%) scale(1.03, .98); } 100% { transform: translateX(-66%); } }
.spot-hero:has(.ride-mount) .tag { top: -96px; }
.spot-hero:has(.ride-mount) .ride-pet { left: -58px; width: 50px; }
@keyframes mount-bob { 50% { transform: translateX(-44%) scaleY(1.015); } }
/* 17 Sep 2026: "put the guy back as it was and make the mount fit" - the hero
   stands as he always did; the mount is a smaller companion behind him */
.spot-hero:has(.ride-mount) .sprite-hero { width: 110px; height: 110px; bottom: 0; transform: translateX(-50%); z-index: 2; }
.spot-hero:has(.ride-mount) .hero-idle { animation: breathe 2.4s ease-in-out infinite; }
.spot-hero:has(.ride-mount).lunge .hero-attack { transform: translateX(-50%); animation: strike .42s cubic-bezier(.2, .9, .3, 1); }
.spot-hero:has(.ride-mount) .tag { top: -40px; }
.ride-mount { width: 118px; height: auto; max-height: 130px; object-fit: contain; object-position: bottom; bottom: 2px; left: 50%; transform: translateX(-18%); z-index: 1; opacity: .95; }
@keyframes mount-bob { 50% { transform: translateX(-18%) scaleY(1.015); } }
.spot-hero:has(.ride-mount) .ride-pet { left: -46px; width: 52px; }
.spot-hero:has(.ride-mount) .ride-pet, .ride-pet { left: -14px; bottom: -2px; width: 46px; z-index: 3; }

/* ================================================= the Stage orb, again (17 Sep 2026)
   "fix the stage on the button and the square around it, make it look alive" */
.gate-ring.orb, .gate-ring.orb * { background: none !important; box-shadow: none !important; border: 0 !important; }
.gate-ring.orb { width: 92px; height: 92px; }
.gate-ring.orb svg { position: absolute; inset: -4px; width: calc(100% + 8px); height: calc(100% + 8px); transform: rotate(-90deg); overflow: visible; }
.gate-ring.orb .ring-bg { stroke: rgba(0,0,0,.6); stroke-width: 2.6; }
.gate-ring.orb .ring-fg { stroke: #ffe08a; stroke-width: 2.6; filter: drop-shadow(0 0 5px rgba(255,220,130,.9)); transition: stroke-dasharray .6s ease; }
.orb-pic { width: 84px; height: 84px; animation: orb-float 3.2s ease-in-out infinite; }
.gate-ring.orb::after {              /* the glint that slides round the ring */
  content: ""; position: absolute; inset: 4px; border-radius: 50%; pointer-events: none;
  background: conic-gradient(from 0deg, transparent 0 78%, rgba(255,255,255,.55) 86%, transparent 94%);
  animation: orb-glint 4s linear infinite; mix-blend-mode: screen;
}
.orb-stage {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -54%);
  margin: 0; display: flex; flex-direction: column; align-items: center; line-height: 1; z-index: 3;
  font-size: 8px; letter-spacing: .14em; color: #dff3ff; text-shadow: 0 0 6px #1a6bff, 0 1px 2px #000;
}
.orb-stage b { font-size: 30px; margin-top: 1px; color: #fff; text-shadow: 0 0 10px #4fa3ff, 0 0 20px #1a6bff, 0 2px 2px #000; animation: orb-pulse 2.2s ease-in-out infinite; }
.orb-gate { bottom: -4px; right: -6px; left: auto; transform: none; background: rgba(0,0,0,.75) !important; border: 1px solid var(--frame-dark) !important; font-size: 10px; padding: 1px 7px; }
@keyframes orb-float { 50% { transform: translate(-50%, -52%) scale(1.03); } }
@keyframes orb-pulse { 50% { text-shadow: 0 0 16px #7fc0ff, 0 0 32px #2a7bff, 0 2px 2px #000; } }
@keyframes orb-glint { to { transform: rotate(360deg); } }
.orb-wrap { gap: 0; }
.orb-wrap .orb-auto { margin-top: 8px !important; }
body.pref-nomotion .orb-pic, body.pref-nomotion .orb-stage b, body.pref-nomotion .gate-ring.orb::after { animation: none; }
.scene-bottom { bottom: 32px; }
.orb-gate { display: inline-block; z-index: 4; }

/* ================================================= the side cards (17 Sep 2026)
   top right of the scene: who leads this week, and the nightly Rift window */
.side-cards { position: absolute; right: 6px; top: 44px; z-index: 5; display: flex; flex-direction: column; gap: 6px; width: 96px; }
.side-card {
  display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 5px 4px 6px;
  border-radius: 10px; text-decoration: none; color: var(--ivory); text-align: center;
  background: linear-gradient(180deg, rgba(42,52,104,.92), rgba(11,14,34,.95));
  border: 1px solid var(--frame); box-shadow: 0 0 0 1px var(--frame-dark), 0 3px 8px rgba(0,0,0,.7);
}
.side-title { font-size: 9px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--frame-light); }
.side-pic { width: 44px; height: 44px; border-radius: 50%; overflow: hidden; border: 2px solid var(--frame); background: #0b0e22; display: flex; align-items: center; justify-content: center; }
.side-pic img, .side-pic .ui-pic { width: 100%; height: 100%; object-fit: cover; }
.side-name { font-size: 11px; font-weight: 700; max-width: 88px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.side-sub { font-size: 9px; color: var(--ivory-muted); }
.side-timer { font-size: 10px; font-weight: 800; color: #8fd48f; font-variant-numeric: tabular-nums; }
.side-rift .side-sub { color: #cfe0ff; }
.side-open { border-color: #ffb340; box-shadow: 0 0 0 1px var(--frame-dark), 0 0 14px rgba(255,180,60,.6); }
.side-open .side-timer { color: #ffd070; }
/* the right column starts under the two cards */
.edge-right { top: 226px; }
@media (max-height: 760px) { .side-cards { width: 88px; } .edge-right { top: 210px; } }
.side-pic-champ { background-size: 118%; background-position: center 30%; background-repeat: no-repeat; border-color: #ffd070; }
.side-pic-champ img { width: 60%; height: 60%; border-radius: 50%; margin-top: 4px; box-shadow: 0 0 0 1px #0b0e22; }
.side-pic-rift { border: 0; background: transparent; width: 48px; height: 48px; overflow: visible; }
.side-pic-rift img { object-fit: contain; filter: drop-shadow(0 0 6px rgba(160,90,255,.8)); animation: nv-side-breathe 3.2s ease-in-out infinite; }
.side-open .side-pic-rift img { animation-duration: 1.4s; filter: drop-shadow(0 0 10px rgba(255,180,60,.9)); }
@keyframes nv-side-breathe { 0%,100% { transform: scale(1) rotate(-2deg); } 50% { transform: scale(1.08) rotate(2deg); } }

/* ================================================= lifetime rewards, 17 Sep 2026
   (include/lifetime.php). These show on every page, so they are here and not
   in lifetime.css: the chat bubbles a rung hands out (bubble-<key> on a
   Tavern line and on the feed line above the bar), the four ladder frames
   (frame-<key> on the portrait ring, same as settings.css's VIP ones), the
   cloak or wings behind the hero in the fight, and the Crown Circle laurel
   for the HUD (nv_lifetime_badge). */
.tavern-line[class*="bubble-"] { padding: 3px 8px; border-radius: 8px; margin: 2px 0; border: 1px solid transparent; }
.bubble-parchment { background: linear-gradient(180deg, #f3e6c4, #e2ceA0); border-color: #b89a62 !important; color: #3a2a12; }
.bubble-parchment .tavern-who, .bubble-parchment .tavern-body { color: #3a2a12; }
.bubble-ember { background: linear-gradient(180deg, rgba(120,30,10,.75), rgba(60,10,5,.85)); border-color: #ff7a2a !important; box-shadow: inset 0 0 12px rgba(255,120,40,.35); }
.bubble-ember .tavern-who { color: #ffb070; }
.bubble-frost { background: linear-gradient(180deg, rgba(40,80,120,.7), rgba(15,35,70,.85)); border-color: #9fdcff !important; box-shadow: inset 0 0 12px rgba(160,220,255,.35); }
.bubble-frost .tavern-who { color: #cfefff; }
.bubble-gold { background: linear-gradient(180deg, rgba(90,65,10,.75), rgba(45,30,5,.9)); border-color: var(--frame) !important; box-shadow: 0 0 6px rgba(224,176,64,.35); }
.bubble-gold .tavern-who { color: var(--frame-light); }
.bubble-dragon { background: linear-gradient(90deg, rgba(120,15,20,.85), rgba(60,5,10,.9)); border-color: #d4a94e !important; box-shadow: inset 0 0 0 1px #8a1a22; }
.bubble-dragon .tavern-who { color: #ffd26a; }
.bubble-void { background: radial-gradient(circle at 20% 30%, #241a3f, #05040c 70%); border-color: #6a4bb8 !important; box-shadow: inset 0 0 14px rgba(140,100,255,.35); }
.bubble-void .tavern-who { color: #c9b6ff; }
.feed-line[class*="bubble-"] { padding: 0 6px; border-radius: 6px; }
.feed-line.bubble-parchment { color: #3a2a12; }
.feed-line.bubble-parchment .feed-name, .feed-line.bubble-parchment .feed-tag { color: #5a3a12; }

.frame-embers    { border-color: #ff7a2a; box-shadow: 0 0 0 1px #7a2a05, inset 0 0 0 2px #b8421a, 0 0 10px rgba(255,120,40,.7); }
.frame-rimecrown { border-color: #cfefff; box-shadow: 0 0 0 1px #4a90c0, inset 0 0 0 2px #7fc4ee, 0 0 10px rgba(160,220,255,.7); }
.frame-laurel    { border-color: #ffe08a; box-shadow: 0 0 0 2px #b8860b, inset 0 0 0 2px #e6b84a, 0 0 12px rgba(255,220,120,.8); }
.frame-wyrmcoil  { border-color: #d4a94e; box-shadow: 0 0 0 2px #8a1a22, inset 0 0 0 3px #b3262e, 0 0 12px rgba(212,169,78,.8); }

.ride-cloak { position: absolute; left: 50%; bottom: 6px; width: 150px; height: auto; max-height: 130px; object-fit: contain; object-position: bottom; transform: translateX(-50%); z-index: 0; opacity: .95; filter: drop-shadow(0 4px 6px rgba(0,0,0,.5)); animation: cloak-sway 3.2s ease-in-out infinite; transform-origin: 50% 20%; }
.spot-hero:has(.ride-cloak) .sprite-hero { z-index: 2; }
.spot-hero:has(.ride-mount) .ride-cloak { z-index: 1; }
@keyframes cloak-sway { 50% { transform: translateX(-50%) scale(1.03, 1) translateY(-2px); } }
body.pref-nomotion .ride-cloak { animation: none; }

.hud-circle { display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 30px; margin-left: 4px; vertical-align: middle; text-decoration: none; filter: drop-shadow(0 0 4px rgba(255,220,120,.6)); }
.hud-circle img { width: 28px; height: 28px; object-fit: contain; }
.hud-circle-txt { font-size: 10px; font-weight: 900; color: var(--frame-light); letter-spacing: .06em; }
/* the two cards sit in a row under the grid, and the right column starts under them
   (a stacked pair pushed the column off the bottom of the scene, 17 Sep 2026) */
.page-game .side-cards { top: 114px; right: 6px; width: auto; flex-direction: row; gap: 5px; }
.page-game .side-card { width: 82px; padding: 4px 3px 5px; gap: 1px; }
.page-game .side-title { font-size: 8px; letter-spacing: .04em; }
.page-game .side-pic { width: 36px; height: 36px; }
.page-game .side-pic-rift { width: 40px; height: 40px; }
.page-game .side-name { font-size: 10px; max-width: 76px; }
.page-game .side-sub { font-size: 8px; max-width: 76px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.page-game .side-timer { font-size: 9px; }
.page-game .edge-right { top: 206px; gap: 3px; }
.page-game .edge-right .edge-btn { width: 42px; height: 42px; }
.page-game .edge-right .edge-btn .ui-pic { width: 27px; height: 27px; }
.page-game .scene.grid-open .side-cards { top: 232px; }
.page-game .scene.grid-open .edge-right { top: 324px; }
/* the champion's crown sits on the portrait rather than hiding behind it */
.side-pic-champ { position: relative; overflow: visible; background-size: 0 0; margin-top: 8px; }
.side-pic-champ img { width: 100%; height: 100%; margin: 0; border-radius: 50%; }
.side-pic-champ::before { content: ""; position: absolute; left: 50%; top: -16px; width: 40px; height: 28px; margin-left: -20px; background: inherit; background-size: contain; background-position: center bottom; background-repeat: no-repeat; z-index: 2; filter: drop-shadow(0 1px 2px rgba(0,0,0,.8)); animation: nv-side-crown 2.6s ease-in-out infinite; }
@keyframes nv-side-crown { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-2px); } }
.page-game .side-title { font-size: 7.5px; letter-spacing: 0; white-space: nowrap; }
.side-pic-champ { margin-top: 11px; }
.side-pic-champ::before { top: -13px; height: 22px; width: 34px; margin-left: -17px; }
.page-game .edge .edge-btn { width: 42px; height: 42px; }
.page-game .edge .edge-btn .ui-pic { width: 27px; height: 27px; }
.page-game .edge { gap: 3px; }
/* particles drift off the edge and a tap on More then scrolled the scene sideways to
   them (17 Sep 2026); clip cannot be scrolled, hidden can */
.page-game .scene { overflow: clip; }
.page-game .scene.grid-open .side-cards { display: none; }
.page-game .scene.grid-open .edge-right { top: 234px; }

/* the faded way back, every screen but the Fight one (17 Sep 2026) */
.back-arrow {
  position: fixed; left: 8px; bottom: calc(var(--navbar-h, 84px) + 46px); z-index: 40;
  width: 38px; height: 38px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
  color: var(--ivory); text-decoration: none; opacity: .5;
  background: radial-gradient(circle at 40% 35%, rgba(42,52,104,.95), rgba(11,14,34,.95));
  border: 1px solid var(--frame); box-shadow: 0 0 0 1px var(--frame-dark), 0 2px 6px rgba(0,0,0,.6);
  transition: opacity .2s, transform .15s;
}
.back-arrow:hover, .back-arrow:focus-visible { opacity: .95; }
.back-arrow:active { transform: scale(.92); opacity: 1; }

/* ================================================= THE CAMPAIGN CARD (17 Sep 2026: "i like 13 build it")
   Layout 13 of the mockups: the zone as the whole backdrop, a rail down each
   edge, the card in the middle, the live fight in a strip along the bottom.
   Scoped to .scene.campaign so the old rules for the grid, orb and bottom
   cluster (still in this file) stay out of the way. */
.page-game .scene.campaign { display: block; }
.scene.campaign .camp-shade { position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(180deg, rgba(6,8,22,.55) 0, rgba(6,8,22,.25) 30%, rgba(6,8,22,.35) 60%, rgba(6,8,22,.8) 100%); }
.scene.campaign .has-backdrop .backdrop, .scene.campaign .backdrop { filter: saturate(.85) brightness(.85); }
.scene.campaign .mist { opacity: .5; }
.scene.campaign .ground { display: none; }
.scene.campaign .scene-top { top: 6px; z-index: 5; }

/* the rails: five and six round buttons, 44px, one under the other */
.page-game .scene.campaign .edge:not(.edge-right) { left: 6px; top: 42px; gap: 5px; }
.page-game .scene.campaign .edge-right { left: auto; right: 6px; top: 42px; gap: 5px; }
.page-game .scene.campaign .edge .edge-btn, .page-game .scene.campaign .edge-right .edge-btn { width: 44px; height: 44px; }
.page-game .scene.campaign .edge .edge-btn .ui-pic { width: 29px; height: 29px; }
.scene.campaign .edge-more .ui-pic, .scene.campaign .edge-more .ico { color: var(--frame-light); }

/* the card */
.scene.campaign .camp {
  position: absolute; left: 60px; right: 60px; top: 44px; z-index: 5;
  padding: 10px 10px 8px; text-align: center; border-radius: 14px; color: var(--ivory);
  background: linear-gradient(180deg, rgba(35,42,85,.94), rgba(16,19,42,.97));
  border: 1px solid var(--frame); box-shadow: 0 0 0 1px var(--frame-dark), 0 10px 30px rgba(0,0,0,.75);
}
.scene.campaign .camp::before { content: ""; position: absolute; left: 10px; right: 10px; top: 0; height: 2px; background: linear-gradient(90deg, transparent, var(--frame-light), transparent); }
.camp-eyebrow { font-family: Cinzel, Georgia, serif; font-size: 9px; letter-spacing: .14em; text-transform: uppercase; color: var(--ivory-muted); }
.camp-zone { font-family: Cinzel, Georgia, serif; font-size: 20px; margin: 2px 0 0; color: var(--frame-light); text-shadow: 0 1px 3px #000; }
.camp-pic { height: 118px; margin: 4px auto 0; display: flex; align-items: flex-end; justify-content: center; }
.camp-pic .sprite-boss, .camp-pic .sprite-mon { width: auto; height: 118px; max-width: 160px; filter: drop-shadow(0 8px 8px rgba(0,0,0,.7)); animation: camp-breathe 3s ease-in-out infinite; transform-origin: 50% 100%; }
.camp-pic.camp-ready .sprite-boss, .camp-pic.camp-ready .sprite-mon { filter: drop-shadow(0 0 14px rgba(255,80,60,.8)) drop-shadow(0 8px 8px rgba(0,0,0,.7)); animation-duration: 1.4s; }
@keyframes camp-breathe { 0%,100% { transform: scale(1); } 50% { transform: scale(1.04) translateY(-2px); } }
.camp-stage { font-size: 13px; margin-top: 6px; }
.camp-stage b { color: var(--frame-light); }
.camp-bar { height: 8px; margin: 5px 14px 0; }
.camp-boss { font-size: 12px; margin-top: 6px; }
.camp-boss b { color: #ff9a9a; }
.camp-hint { font-size: 11px; margin: 3px 0 0; min-height: 14px; }
.camp-form { margin-top: 7px; }
.camp-form .btn-big { width: 100%; min-height: 44px; font-size: 15px; }
.camp-form #boss-fight:disabled { opacity: .55; filter: grayscale(.5); }
.btn-lit { animation: lit-pulse 1.2s ease-in-out infinite; }
@keyframes lit-pulse { 0%,100% { box-shadow: 0 0 0 0 rgba(255,80,60,.0); } 50% { box-shadow: 0 0 18px 2px rgba(255,80,60,.7); } }
#camp-claim b { font-variant-numeric: tabular-nums; }
.camp-row { display: flex; align-items: center; justify-content: space-between; gap: 6px; margin-top: 8px; }
.camp-auto { margin: 0; }
.scene.campaign .auto-btn { position: static !important; transform: none; font-size: 10px; padding: 5px 10px; }
.camp-up { font-size: 11px; padding: 4px 10px; }
.camp-foot { display: flex; gap: 6px; margin-top: 8px; border-top: 1px solid rgba(255,230,160,.15); padding-top: 7px; }
.camp-chip { flex: 1; display: flex; align-items: center; gap: 5px; min-width: 0; padding: 3px 6px; border-radius: 10px; text-decoration: none; color: var(--ivory);
  background: rgba(0,0,0,.35); border: 1px solid var(--frame-dark); font-size: 10px; }
.camp-chip img { width: 22px; height: 22px; object-fit: contain; flex: none; }
.camp-chip span { font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.camp-chip small { margin-left: auto; color: #8fd48f; font-weight: 700; white-space: nowrap; }
.camp-chip.chip-open { border-color: #ffb340; box-shadow: 0 0 10px rgba(255,180,60,.5); }
.camp-chip.chip-open small { color: #ffd070; }

/* the tracker sits on the strip's top edge */
.page-game .scene.campaign .camp-tracker { position: absolute; left: 8px; right: auto; top: auto; bottom: 142px; max-width: 70%; z-index: 6; margin: 0; }

/* the live fight, a strip along the bottom */
.fight-strip { position: absolute; left: 0; right: 0; bottom: 0; height: 150px; z-index: 4; overflow: hidden; border-top: 1px solid var(--frame-dark); box-shadow: 0 -6px 18px rgba(0,0,0,.6); }
.fight-strip .strip-back { position: absolute; inset: -4px; background-size: cover; background-position: center 80%; filter: brightness(.9); }
.fight-strip::after { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, rgba(6,8,22,.5), transparent 40%, rgba(6,8,22,.35)); pointer-events: none; }
.scene.campaign .fighters { position: absolute; left: 0; right: 0; bottom: 4px; top: auto; padding: 0 8px; justify-content: space-between; align-items: flex-end; z-index: 2; }
.scene.campaign .spot { width: 96px; zoom: .78; }
.scene.campaign .spot-hero { margin-left: 6%; }
.scene.campaign .spot-mon { margin-right: 6%; }
.scene.campaign .strip-rates { bottom: 4px; left: 0; right: 0; font-size: 10px; z-index: 3; gap: 2px 8px; }
.scene.campaign .floaters { z-index: 7; }
.scene.campaign .scene-note { display: none; }

/* the Everything sheet: the whole grid, four across */
.grid-sheet { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px 4px; padding: 6px 0 12px; }
.grid-sheet .sc { flex: none; min-height: 0; }
.grid-sheet .sc-ico { width: 52px; height: 52px; }
.grid-sheet .sc-ico .ui-pic { width: 36px; height: 36px; }
.grid-sheet .sc-label { color: var(--ivory); font-size: 10px; }

@media (max-height: 740px) {
  .scene.campaign .camp { top: 40px; padding-top: 6px; }
  .camp-pic { height: 92px; } .camp-pic .sprite-boss, .camp-pic .sprite-mon { height: 92px; }
  .fight-strip { height: 130px; }
  .page-game .scene.campaign .camp-tracker { bottom: 122px; }
}
/* the card has to fit between the rails' top and the strip: 539px of scene,
   less 124px of strip, less the top strip. Measured 17 Sep 2026. */
.camp-auto.auto-form { position: static !important; left: auto !important; top: auto !important; transform: none !important; margin: 0 !important; }
.scene.campaign .camp { top: 40px; padding: 7px 10px 7px; }
.camp-zone { font-size: 18px; }
.camp-pic { height: 84px; margin-top: 2px; }
.camp-pic .sprite-boss, .camp-pic .sprite-mon { height: 84px; max-width: 130px; }
.camp-stage { margin-top: 4px; font-size: 12px; }
.camp-bar { margin-top: 4px; height: 7px; }
.camp-boss { margin-top: 4px; font-size: 11px; }
.camp-hint { font-size: 10px; margin-top: 2px; min-height: 12px; }
.camp-form { margin-top: 5px; }
.camp-form .btn-big { min-height: 40px; font-size: 14px; padding-top: 6px; padding-bottom: 6px; }
.camp-row { margin-top: 6px; }
.camp-foot { margin-top: 6px; padding-top: 5px; }
.camp-chip { padding: 2px 6px; } .camp-chip img { width: 20px; height: 20px; }
.fight-strip { height: 124px; }
.page-game .scene.campaign .camp-tracker { bottom: 116px; }
.scene.campaign .spot { zoom: .7; }
@media (max-height: 740px) { .fight-strip { height: 124px; } .page-game .scene.campaign .camp-tracker { bottom: 116px; } }
.scene.campaign .camp { padding-bottom: 5px; }
.camp-eyebrow { font-size: 8px; }
.camp-row { margin-top: 4px; }
.camp-foot { margin-top: 4px; padding-top: 4px; }
.camp-form .btn-big { min-height: 38px; }
.scene.campaign .auto-btn { white-space: nowrap; }
.page-game .scene.campaign .camp-tracker { bottom: 98px; left: 6px; max-width: 64%; font-size: 10px; padding: 3px 8px 3px 5px; }
.fight-strip { height: 120px; }
/* a sheet taller than the scene scrolls inside itself instead of running
   under the chat row (the Everything sheet has 31 tiles) */
.page-game .sheet { max-height: 100%; }
.page-game .sheet .sheet-scroll { overflow-y: auto; }
/* the Auto-Stage switch on the card: a pill with a knob, filled green when it is on */
.camp-auto .auto-btn {
  width: auto; height: 26px; min-height: 0; padding: 0 10px 0 28px; border-radius: 999px; position: relative;
  font-size: 10px; font-weight: 800; letter-spacing: .04em; white-space: nowrap;
  background: linear-gradient(180deg, #3b4479, #171c3d); color: var(--ivory); border: 1px solid var(--frame-dark); opacity: 1;
}
.camp-auto .auto-btn::after { content: ""; position: absolute; left: 4px; top: 4px; width: 16px; height: 16px; border-radius: 50%;
  background: linear-gradient(180deg, #e8e2d2, #9a9282); box-shadow: 0 1px 3px rgba(0,0,0,.7); transition: left .2s, background .2s; }
.camp-auto .auto-btn.auto-on { background: linear-gradient(180deg, #7ee29a, #2e9c55 55%, #1f6b3b); color: #fff; border-color: #8fe08f; box-shadow: 0 0 10px rgba(126,226,154,.6); }
.camp-auto .auto-btn.auto-on::after { background: #fff; }
.camp-auto .auto-btn.auto-locked { opacity: .8; }
.camp-auto .auto-btn.auto-locked::before { content: "\1F512"; position: absolute; left: auto; right: -4px; top: -6px; bottom: auto; font-size: 10px; }
/* the switch's knob needs the button positioned; the static rule above was for the old orb */
.scene.campaign .camp-auto .auto-btn { position: relative !important; }
.camp-auto .auto-btn.auto-locked::before { transform: none; }

/* THE QUEST BANNER above the fight (17 Sep 2026): ribbon title, the step, the way on */
.quest-banner {
  position: absolute; left: 50%; bottom: 124px; transform: translateX(-50%); z-index: 6;
  width: 250px; padding: 14px 8px 6px; text-align: center; text-decoration: none; color: var(--ivory);
  background: linear-gradient(180deg, rgba(16,19,42,.85), rgba(6,8,22,.92)); border: 1px solid var(--frame-dark); border-radius: 10px;
  box-shadow: 0 4px 12px rgba(0,0,0,.6);
}
.qb-title {
  position: absolute; left: 50%; top: -14px; transform: translateX(-50%); width: 132px; height: 34px; line-height: 30px;
  background: url(../images/ui/cut/ribbon.png) center/contain no-repeat;
  font-family: Cinzel, Georgia, serif; font-weight: 800; font-size: 12px; letter-spacing: .08em; color: #fff4d6; text-shadow: 0 1px 2px #000, 0 0 6px rgba(0,0,0,.8);
}
.qb-line { display: block; font-size: 12px; margin-top: 6px; }
.qb-line b { color: #ff9a9a; }
.qb-sub { display: block; font-size: 10px; color: var(--ivory-muted); margin-top: 1px; }
.quest-banner.quest-done { border-color: var(--frame); box-shadow: 0 0 14px rgba(255,220,120,.5); }
.quest-banner.quest-done .qb-line b { color: #8fd48f; }
.quest-banner.quest-done .qb-sub { color: var(--frame-light); }
/* the card ends where the banner begins */
.scene.campaign .camp { top: 36px; }
.scene.campaign .camp-foot { display: none; }
.fight-strip { height: 112px; }
.scene.campaign .spot { zoom: .64; }
@media (max-height: 740px) { .fight-strip { height: 112px; } }
/* the champion and Rift chips ride in the top strip, between the two counters */
.scene.campaign .camp-foot { display: flex; margin: 0; padding: 0; border: 0; gap: 4px; flex: 1 1 auto; min-width: 0; justify-content: center; }
.scene.campaign .scene-top { display: flex; align-items: center; gap: 4px; left: 6px; right: 6px; }
.scene.campaign .camp-chip { flex: 0 1 auto; max-width: 118px; padding: 1px 6px 1px 3px; font-size: 9px; background: rgba(0,0,0,.6); }
.scene.campaign .camp-chip img { width: 18px; height: 18px; }
.scene.campaign .camp-chip small { margin-left: 4px; }
.scene.campaign .camp { top: 38px; }
.camp-pic { height: 74px; } .camp-pic .sprite-boss, .camp-pic .sprite-mon { height: 74px; max-width: 120px; }
.camp-hint { min-height: 0; }
.quest-banner { bottom: 114px; padding-bottom: 5px; }
.camp-form { margin-top: 4px; }
.camp-pic { height: 70px; } .camp-pic .sprite-boss, .camp-pic .sprite-mon { height: 70px; }
.camp-row { margin-top: 3px; }
form.quest-banner { padding: 0; border: 0; background: none; box-shadow: none; }
.qb-btn { display: block; width: 100%; padding: 14px 8px 5px; border-radius: 10px; cursor: pointer; font: inherit; color: var(--ivory); text-align: center; position: relative;
  background: linear-gradient(180deg, rgba(16,19,42,.85), rgba(6,8,22,.92)); border: 1px solid var(--frame); box-shadow: 0 0 14px rgba(255,220,120,.5); animation: lit-pulse-gold 1.6s ease-in-out infinite; }
.qb-btn:active { transform: translateY(1px); }
.qb-btn .qb-sub { color: var(--frame-light); font-weight: 700; }
@keyframes lit-pulse-gold { 0%,100% { box-shadow: 0 0 8px rgba(255,220,120,.35); } 50% { box-shadow: 0 0 18px 3px rgba(255,220,120,.75); } }
/* no knob (17 Sep 2026: "i dont want the dot, just green on and off") */
.camp-auto .auto-btn { padding: 0 12px; }
.camp-auto .auto-btn::after { display: none; }
.camp-auto .auto-btn.auto-locked::before { right: -6px; top: -7px; }

/* ================================================= THE TOAST (17 Sep 2026: "we need better pop ups")
   Centred over the scene, a gold frame, a medallion for what happened, a
   title line and the words. Tap to dismiss; it goes on its own after 3.6s. */
.flash, .flash.flash-live {
  position: fixed; left: 50%; top: 34%; right: auto; transform: translate(-50%, -50%);
  width: min(88%, 400px); z-index: 60; display: flex; align-items: center; gap: 12px;
  padding: 12px 14px 12px 10px; border-radius: 14px; cursor: pointer;
  color: var(--ivory); font-size: 14px; line-height: 1.3;
  background: radial-gradient(ellipse at 50% 0%, rgba(90,110,200,.25), transparent 60%), linear-gradient(180deg, #232a55, #0f1230);
  border: 2px solid var(--frame); border-left-width: 2px;
  box-shadow: 0 0 0 1px var(--frame-dark), 0 0 0 4px #0b0e22, 0 0 0 5px var(--frame-dark), 0 16px 40px rgba(0,0,0,.8), inset 0 1px 0 rgba(255,255,255,.12);
  animation: toast-in .32s cubic-bezier(.2,.9,.3,1.2);
}
.flash::before { content: ""; position: absolute; left: 14px; right: 14px; top: -1px; height: 2px; background: linear-gradient(90deg, transparent, var(--frame-light), transparent); }
.flash::after { content: ""; position: absolute; left: 14px; right: 14px; bottom: -1px; height: 2px; background: linear-gradient(90deg, transparent, var(--frame-dark), transparent); }
.flash-pic { flex: none; width: 54px; height: 54px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
  background: radial-gradient(circle at 40% 35%, #2a3468, #0b0e22); border: 2px solid var(--frame); box-shadow: 0 0 0 1px var(--frame-dark), 0 3px 8px rgba(0,0,0,.7); }
.flash-pic img { width: 40px; height: 40px; object-fit: contain; }
.flash-body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.flash-title { font-family: Cinzel, Georgia, serif; font-size: 13px; letter-spacing: .08em; text-transform: uppercase; color: var(--frame-light); }
.flash-text { font-size: 13px; color: var(--ivory); }
.flash-ok { border-color: var(--frame); }
.flash-ok .flash-pic { border-color: #8fe08f; box-shadow: 0 0 0 1px #2e6b3a, 0 0 12px rgba(126,226,154,.6); }
.flash-ok .flash-title { color: #b9f0c8; }
.flash-bad { border-color: #d0343c; }
.flash-bad .flash-pic { border-color: #ff7d7d; box-shadow: 0 0 0 1px #6b1418, 0 0 12px rgba(255,80,60,.6); animation: toast-shake .5s ease-out; }
.flash-bad .flash-title { color: #ff9a9a; }
.flash-bad::before { background: linear-gradient(90deg, transparent, #ff9a9a, transparent); }
@keyframes toast-in { from { opacity: 0; transform: translate(-50%, -60%) scale(.92); } to { opacity: 1; transform: translate(-50%, -50%) scale(1); } }
@keyframes toast-shake { 0%,100% { transform: translateX(0); } 20% { transform: translateX(-4px); } 40% { transform: translateX(4px); } 60% { transform: translateX(-3px); } 80% { transform: translateX(3px); } }
.flash[hidden] { display: none; }
/* the toast never blocks a tap: it sits under the HUD (top set by narvoda.js) and lets clicks through */
.flash, .flash.flash-live { top: 160px; transform: translateX(-50%); pointer-events: none; cursor: default; padding: 9px 12px 9px 8px; gap: 10px; }
.flash-pic { width: 46px; height: 46px; } .flash-pic img { width: 34px; height: 34px; }
.flash-title { font-size: 12px; } .flash-text { font-size: 12.5px; }
@keyframes toast-in { from { opacity: 0; transform: translate(-50%, -14px) scale(.96); } to { opacity: 1; transform: translate(-50%, 0) scale(1); } }

/* wings behind the hero on the fight strip (include/wings.php, 17 Sep 2026) */
.ride-wings { position: absolute; left: 50%; bottom: 34px; width: 150px; height: auto; max-height: 120px; object-fit: contain; object-position: bottom; transform: translateX(-50%); transform-origin: 50% 40%; z-index: 0; opacity: .96; filter: drop-shadow(0 4px 6px rgba(0,0,0,.5)); animation: wing-flap-ride 2.8s ease-in-out infinite; pointer-events: none; }
@keyframes wing-flap-ride { 0%, 100% { transform: translateX(-50%) scaleX(1); } 50% { transform: translateX(-50%) scaleX(.92); } }
.spot-hero:has(.ride-wings) .sprite-hero { position: relative; z-index: 2; }
body.pref-nomotion .ride-wings { animation: none; }
/* the bound warden floating at the hero's shoulder (include/wardens.php, 17 Sep 2026) */
.ride-warden { position: absolute; left: 50%; bottom: 74px; width: 70px; height: auto; transform: translateX(-118%); z-index: 0; opacity: .88; filter: drop-shadow(0 0 8px rgba(190,150,255,.75)) drop-shadow(0 4px 3px rgba(0,0,0,.4)); animation: warden-bob 3.4s ease-in-out infinite; pointer-events: none; }
@keyframes warden-bob { 0%, 100% { transform: translateX(-118%) translateY(0); } 50% { transform: translateX(-118%) translateY(-8px); } }
body.pref-nomotion .ride-warden { animation: none; }

/* ================================================= THE BLADE SHAPE (17 Sep 2026: "make my game run like Blade Idle does")
   The fight fills the screen from above. Scoped to .scene.blade; the older
   campaign and dense rules stay in the file and out of the way. */
.page-game .hud2 .hud-main, .page-game .hud-name-tag { display: none; }   /* the thin strip is the whole HUD here */
.page-game .hud2 { min-height: 0; padding-bottom: 0; }
.page-game .scene.blade { display: block; }
.scene.blade .backdrop { filter: none; background-position: center 40%; }
.scene.blade .ground, .scene.blade .hills, .scene.blade .sky { display: none; }
.scene.blade .mist { opacity: .35; }
.scene.blade .scene-note { display: none; }

/* the top row */
.bi-top { position: absolute; left: 6px; right: 6px; top: 6px; z-index: 6; display: flex; align-items: center; gap: 6px; }
.bi-round { width: 42px; height: 42px; border-radius: 50%; flex: none; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0; text-decoration: none; position: relative;
  background: radial-gradient(circle at 40% 35%, rgba(42,52,104,.95), rgba(11,14,34,.97)); border: 2px solid var(--frame); box-shadow: 0 0 0 1px var(--frame-dark), 0 2px 6px rgba(0,0,0,.7); color: #fff; cursor: pointer; padding: 0; font: inherit; }
.bi-round .ui-pic { width: 22px; height: 22px; } .bi-round .ico { width: 20px; height: 20px; }
.bi-round span { font-family: Cinzel, serif; font-size: 7px; letter-spacing: .04em; text-shadow: 0 1px 2px #000; line-height: 1; margin-top: 1px; }
.bi-round .badge { top: -4px; right: -4px; }
.bi-stage { flex: 1 1 auto; min-width: 0; }
.bi-stage-line { display: flex; align-items: baseline; gap: 5px; font-size: 11px; color: var(--ivory); text-shadow: 0 1px 2px #000; }
.bi-stage-lbl { font-family: Cinzel, serif; font-size: 9px; color: var(--ivory-muted); }
.bi-stage-n { font-family: Cinzel, serif; font-size: 14px; color: #fff; }
.bi-stage-k b { color: #8fd48f; font-variant-numeric: tabular-nums; }
.bi-stage-zone { margin-left: auto; font-size: 10px; color: var(--ivory-muted); white-space: nowrap; }
.bi-bar { height: 10px; border-radius: 5px; background: rgba(0,0,0,.6); border: 1px solid #000; overflow: hidden; box-shadow: inset 0 1px 2px rgba(0,0,0,.8); }
.bi-fill { height: 100%; background: linear-gradient(90deg, #2f7de0, #7fc0ff); box-shadow: 0 0 8px rgba(120,190,255,.7); transition: width .4s; }
.bi-timer { display: inline-flex; align-items: center; gap: 3px; padding: 3px 7px; border-radius: 12px; background: rgba(0,0,0,.6); border: 1px solid var(--frame-dark); font-size: 10px; color: var(--ivory); flex: none; }
.bi-timer .ico { width: 12px; height: 12px; }
.bi-quest { position: absolute; left: 10px; top: 56px; z-index: 6; display: inline-flex; align-items: center; gap: 6px; max-width: 70%; padding: 4px 10px 4px 6px; border-radius: 14px; text-decoration: none; color: var(--ivory); font-size: 11px;
  background: linear-gradient(180deg, rgba(0,0,0,.55), rgba(0,0,0,.7)); border: 1px solid var(--frame-dark); }
.bi-quest .ico { width: 14px; height: 14px; color: var(--frame-light); flex: none; }
.bi-quest span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bi-quest b { color: #ff9a9a; }
form.bi-quest { padding: 0; background: none; border: 0; }
.bi-quest-btn { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px 4px 6px; border-radius: 14px; font: inherit; font-size: 11px; color: var(--ivory); cursor: pointer;
  background: linear-gradient(180deg, rgba(60,50,0,.75), rgba(0,0,0,.8)); border: 1px solid var(--frame); box-shadow: 0 0 10px rgba(255,220,120,.5); animation: lit-pulse-gold 1.6s ease-in-out infinite; }
.bi-quest-btn b { color: var(--frame-light); }

/* the rails */
.page-game .scene.blade .edge:not(.edge-right) { left: 4px; top: 90px; gap: 4px; }
.page-game .scene.blade .edge-right { left: auto; right: 4px; top: 90px; gap: 4px; }
.page-game .scene.blade .edge .edge-btn, .page-game .scene.blade .edge-right .edge-btn { width: 40px; height: 40px; }
.page-game .scene.blade .edge .edge-btn .ui-pic { width: 26px; height: 26px; }
.page-game .scene.blade .edge .edge-label { font-size: 7px; }
.bi-loot { display: flex; flex-direction: column; align-items: center; gap: 1px; margin: 0; }
.bi-loot .edge-loot { border-color: var(--frame-light); box-shadow: 0 0 0 1px var(--frame-dark), 0 0 10px rgba(255,220,120,.5); }
.bi-loot-n { font-size: 9px; font-weight: 800; color: var(--frame-light); text-shadow: 0 1px 2px #000; font-variant-numeric: tabular-nums; }

/* THE ARENA */
.arena { position: absolute; left: 0; right: 0; top: 80px; bottom: 150px; z-index: 3; }
.scene.blade .spot { position: absolute; width: 96px; }
.scene.blade .spot-hero { left: 50%; top: 50%; transform: translate(-50%, -40%); margin: 0; z-index: 4; }
.scene.blade .spot-hero.face-left .sprite-hero, .scene.blade .spot-hero.face-left .ride-pet { transform: scaleX(-1); }
.scene.blade .spot-hero.face-left .ride-mount { transform: translateX(-82%) scaleX(-1); }
.scene.blade .spot-mon { z-index: 3; transition: left .35s ease, top .35s ease; margin: 0; }
.scene.blade .mob-p0 { left: 64%; top: 46%; }
.scene.blade .mob-p1 { left: 8%;  top: 40%; }
.scene.blade .mob-p2 { left: 58%; top: 6%; }
.scene.blade .mob-p3 { left: 12%; top: 66%; }
.scene.blade .mob-p4 { left: 66%; top: 72%; }
.scene.blade .mob-extra { opacity: .92; }
.scene.blade .mob-extra .sprite-mon { animation-delay: -1.3s; width: 100px; height: 100px; }
.scene.blade .mob-extra.mob-p2 .sprite-mon, .scene.blade .mob-extra.mob-p3 .sprite-mon { width: 84px; height: 84px; opacity: .85; }
.scene.blade .mob-gone { opacity: 0; transition: opacity .3s; }
.scene.blade .mob-in .sprite-mon { animation: spawn .45s ease-out; }
.scene.blade .mob-flinch .sprite-mon { animation: shake .22s linear; }
.scene.blade .mob-target .tag { display: block; }
.scene.blade .mob-extra .tag { display: none; }
.arena-fx { position: absolute; inset: 0; pointer-events: none; z-index: 5; overflow: visible; }
.afx { position: absolute; left: 50%; top: 50%; width: 220px; height: 220px; margin: -110px 0 0 -110px; border-radius: 50%; animation: afx-ring .8s ease-out forwards; }
.afx-atk { border: 6px solid rgba(255,120,40,.9); box-shadow: 0 0 40px rgba(255,120,40,.7), inset 0 0 40px rgba(255,200,80,.6); }
.afx-hp { border: 6px solid rgba(120,220,150,.9); box-shadow: 0 0 40px rgba(120,220,150,.7), inset 0 0 40px rgba(180,255,200,.5); }
.afx-gold { border: 6px solid rgba(255,220,100,.95); box-shadow: 0 0 40px rgba(255,220,100,.8), inset 0 0 40px rgba(255,240,180,.6); }
.afx-speed { border: 6px solid rgba(120,200,255,.95); box-shadow: 0 0 40px rgba(120,200,255,.8), inset 0 0 40px rgba(200,230,255,.6); animation-duration: .5s; }
.afx-ult { width: 320px; height: 320px; margin: -160px 0 0 -160px; border: 10px solid rgba(255,60,60,.95); box-shadow: 0 0 80px rgba(255,80,40,.9), inset 0 0 80px rgba(255,160,60,.7); animation-duration: 1s; }
@keyframes afx-ring { from { transform: scale(.2) rotate(0deg); opacity: 1; } to { transform: scale(1.4) rotate(90deg); opacity: 0; } }
.afx-name { position: absolute; left: 50%; top: 22%; transform: translateX(-50%); font-family: Cinzel, serif; font-weight: 800; font-size: 22px; color: #ffd070; -webkit-text-stroke: 1px #000; text-shadow: 0 2px 6px #000, 0 0 14px rgba(255,200,80,.8); white-space: nowrap; animation: afx-name 1.1s ease-out forwards; }
.afx-name.afx-big { font-size: 34px; color: #ff9a3a; }
@keyframes afx-name { 0% { transform: translateX(-50%) scale(.6); opacity: 0; } 15% { transform: translateX(-50%) scale(1.15); opacity: 1; } 70% { transform: translateX(-50%) scale(1); opacity: 1; } 100% { transform: translateX(-50%) translateY(-30px) scale(1); opacity: 0; } }
.arena-skill .spot-hero .sprite-hero { filter: drop-shadow(0 0 16px rgba(255,200,80,.9)) drop-shadow(0 6px 4px rgba(0,0,0,.55)); }
.arena-crit { animation: quake .14s linear; }
.scene.blade .ride-wings { bottom: 30px; width: 130px; }
.scene.blade .ride-mount { width: 110px; transform: translateX(-18%); }
.scene.blade .ride-warden { bottom: 60px; }
.bi-note { position: absolute; left: 50%; top: 84px; transform: translateX(-50%); z-index: 6; margin: 0; font-size: 11px; padding: 3px 10px; border-radius: 12px; background: rgba(0,0,0,.6); border: 1px solid var(--gem-red); white-space: nowrap; }

/* the bottom cluster */
.bi-bottom { position: absolute; left: 6px; right: 6px; bottom: 22px; z-index: 6; }
.bi-presets { display: flex; align-items: center; gap: 6px; margin-bottom: 6px; }
.bi-preset { width: 26px; height: 26px; border-radius: 6px; border: 1px solid var(--frame-dark); background: rgba(11,14,34,.9); color: var(--ivory-muted); font: inherit; font-weight: 800; font-size: 12px; cursor: pointer; padding: 0; }
.bi-preset.on { background: linear-gradient(180deg, #ff7d7d, #d0343c); color: #fff; border-color: #ff9a9a; box-shadow: 0 0 8px rgba(255,80,60,.6); }
.bi-preset-cfg { margin-left: auto; display: inline-flex; align-items: center; gap: 4px; font-size: 10px; color: var(--ivory-muted); text-decoration: none; }
.bi-preset-cfg .ico { width: 16px; height: 16px; }
.bi-row { display: flex; align-items: flex-end; gap: 8px; }
.bi-skills { flex: 1 1 auto; display: flex; justify-content: space-between; gap: 4px; }
.bi-skill { display: flex; flex-direction: column; align-items: center; gap: 2px; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.bi-hex { position: relative; width: 50px; height: 50px; display: flex; align-items: center; justify-content: center; clip-path: polygon(25% 3%, 75% 3%, 100% 50%, 75% 97%, 25% 97%, 0 50%);
  background: linear-gradient(180deg, #2a3468, #0b0e22); box-shadow: inset 0 0 0 2px var(--frame); }
.bi-hex img, .bi-hex .ui-pic { width: 34px; height: 34px; }
.bi-cd { position: absolute; inset: 0; background: conic-gradient(rgba(0,0,0,.75) var(--p, 100%), transparent 0); display: none; }
.bi-skill.cooling .bi-cd { display: block; animation: bi-cd var(--cd, 10s) linear forwards; }
@keyframes bi-cd { from { --p: 100%; } to { --p: 0%; } }
@property --p { syntax: "<percentage>"; inherits: false; initial-value: 100%; }
.bi-skill.cooling .bi-hex { filter: saturate(.5); }
.bi-skill.locked { opacity: .45; cursor: default; }
.bi-mult { font-size: 10px; font-weight: 800; color: #fff; text-shadow: 0 1px 2px #000; font-variant-numeric: tabular-nums; }
.bi-ult .bi-hex { box-shadow: inset 0 0 0 2px #ff7d7d; }
.bi-stack { display: flex; flex-direction: column; gap: 4px; flex: none; }
.bi-stack-form { margin: 0; }
.bi-stack-btn { width: 54px; height: 40px; border-radius: 8px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0; padding: 0; font: inherit; cursor: pointer;
  background: linear-gradient(180deg, #2a3468, #0b0e22); border: 1px solid var(--frame-dark); color: var(--ivory); position: relative !important; transform: none !important; opacity: 1; }
.bi-stack-btn .ui-pic { width: 20px; height: 20px; } .bi-stack-btn .ico { width: 16px; height: 16px; }
.bi-stack-btn span { font-family: Cinzel, serif; font-size: 8px; letter-spacing: .04em; }
.bi-stage-btn:disabled { opacity: .5; filter: grayscale(.6); }
.bi-stage-btn.lit { border-color: #ff9a9a; box-shadow: 0 0 12px rgba(255,80,60,.7); animation: lit-pulse 1.2s ease-in-out infinite; }
.bi-stack-btn.auto-on { background: linear-gradient(180deg, #7ee29a, #2e9c55 55%, #1f6b3b); color: #fff; border-color: #8fe08f; }
.bi-stack-btn.auto-locked::after { content: "\1F512"; position: absolute; font-size: 9px; right: 2px; top: 1px; }
.bi-stack-btn.auto-locked::before { display: none; }
.bi-auto { font-family: Cinzel, serif; font-weight: 800; font-size: 10px; letter-spacing: .06em; color: var(--ivory-muted); }
.bi-auto.on { background: linear-gradient(180deg, #3fbf6a, #1d6a34); color: #fff; border-color: #8fe08f; box-shadow: 0 0 8px rgba(63,191,106,.6); }
.bi-rates { bottom: 4px; font-size: 9px; z-index: 6; }
.page-game .sheet { max-height: 100%; }
@media (max-height: 740px) { .arena { bottom: 140px; } .bi-hex { width: 44px; height: 44px; } .bi-hex img, .bi-hex .ui-pic { width: 30px; height: 30px; } }
.bi-stack .auto-form { position: static !important; left: auto !important; top: auto !important; transform: none !important; margin: 0 !important; }
.scene.blade .edge .edge-btn .ui-pic { width: 26px; height: 26px; }

/* one button family on the fight screen (17 Sep 2026: "none of the buttons
   look the same"): every tappable thing is the gold-ringed dark disc the
   rails and the bar use. Stage / Repeat / AUTO, the presets and the Buff and
   Menu rounds all take it; the skill hexes keep the same ring and fill. */
.bi-stack { flex-direction: column; gap: 6px; align-items: center; }
.bi-stack-btn, .bi-stack-btn.auto-btn, .bi-stack-btn.bi-auto {
  width: 46px; height: 46px; border-radius: 50%; padding: 0;
  background: radial-gradient(circle at 40% 35%, rgba(42,52,104,.95), rgba(11,14,34,.97));
  border: 2px solid var(--frame); box-shadow: 0 0 0 1px var(--frame-dark), 0 2px 6px rgba(0,0,0,.7); color: #fff;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0;
}
.bi-stack-btn .ui-pic { width: 24px; height: 24px; } .bi-stack-btn .ico { width: 18px; height: 18px; color: var(--frame-light); }
.bi-stack-btn span { font-family: Cinzel, serif; font-size: 7px; letter-spacing: .04em; text-shadow: 0 1px 2px #000; line-height: 1; margin-top: 1px; }
.bi-stage-btn:disabled { opacity: .55; filter: grayscale(.5); }
.bi-stage-btn.lit { border-color: #ff9a9a; box-shadow: 0 0 0 1px var(--frame-dark), 0 0 14px rgba(255,80,60,.8); }
.bi-stack-btn.auto-on { border-color: #8fe08f; box-shadow: 0 0 0 1px var(--frame-dark), 0 0 12px rgba(126,226,154,.7); background: radial-gradient(circle at 40% 35%, rgba(46,120,80,.95), rgba(11,30,20,.97)); }
.bi-stack-btn.auto-locked::after { right: 0; top: -2px; }
.bi-auto { font-size: 9px; letter-spacing: .04em; color: var(--ivory-muted); }
.bi-auto.on { border-color: #8fe08f; box-shadow: 0 0 0 1px var(--frame-dark), 0 0 12px rgba(63,191,106,.7); background: radial-gradient(circle at 40% 35%, rgba(46,120,80,.95), rgba(11,30,20,.97)); color: #fff; }
.bi-preset { width: 30px; height: 30px; border-radius: 50%; border: 2px solid var(--frame); box-shadow: 0 0 0 1px var(--frame-dark), 0 2px 6px rgba(0,0,0,.7);
  background: radial-gradient(circle at 40% 35%, rgba(42,52,104,.95), rgba(11,14,34,.97)); color: var(--ivory-muted); font-family: Cinzel, serif; font-size: 11px; }
.bi-preset.on { color: #fff; border-color: var(--frame-light); box-shadow: 0 0 0 1px var(--frame-dark), 0 0 10px rgba(255,220,120,.7); background: radial-gradient(circle at 40% 35%, #6b4a10, #2a1a00); }
.bi-preset-cfg { width: 30px; height: 30px; border-radius: 50%; margin-left: auto; justify-content: center; border: 2px solid var(--frame); box-shadow: 0 0 0 1px var(--frame-dark), 0 2px 6px rgba(0,0,0,.7); background: radial-gradient(circle at 40% 35%, rgba(42,52,104,.95), rgba(11,14,34,.97)); }
.bi-preset-cfg span { display: none; } .bi-preset-cfg .ico { color: var(--frame-light); }
.bi-hex { box-shadow: none; background: var(--frame); clip-path: polygon(25% 3%, 75% 3%, 100% 50%, 75% 97%, 25% 97%, 0 50%); }
.bi-hex::after { content: ""; position: absolute; inset: 2px; clip-path: polygon(25% 3%, 75% 3%, 100% 50%, 75% 97%, 25% 97%, 0 50%); background: radial-gradient(circle at 40% 35%, rgba(42,52,104,.95), rgba(11,14,34,.97)); z-index: 0; }
.bi-hex img, .bi-hex .ui-pic, .bi-cd { position: relative; z-index: 1; }
.bi-cd { position: absolute; }
.bi-ult .bi-hex { background: #ff9a9a; box-shadow: none; }
.bi-timer { height: 26px; border: 2px solid var(--frame); box-shadow: 0 0 0 1px var(--frame-dark); background: radial-gradient(circle at 40% 35%, rgba(42,52,104,.95), rgba(11,14,34,.97)); }
.bi-quest, .bi-quest-btn { border: 2px solid var(--frame); box-shadow: 0 0 0 1px var(--frame-dark); background: radial-gradient(circle at 40% 35%, rgba(42,52,104,.95), rgba(11,14,34,.97)); }
.bi-quest-btn { box-shadow: 0 0 0 1px var(--frame-dark), 0 0 10px rgba(255,220,120,.6); }

/* "make it look real" (17 Sep 2026): the pack stands on shadows facing the
   hero, walks in from the edge, drops where it dies, lunges; the skill
   effects are a slash, bolts and a burst, nothing spins. */
.scene.blade .spot-mon { transition: none; }
.scene.blade .spot-mon.mob-jump { transition: none !important; }
.scene.blade .spot::after { content: ""; position: absolute; left: 50%; bottom: -4px; width: 70%; height: 16px; margin-left: -35%; border-radius: 50%; background: radial-gradient(ellipse, rgba(0,0,0,.45), rgba(0,0,0,0) 70%); z-index: -1; pointer-events: none; }
.scene.blade .spot-hero::after { width: 80%; margin-left: -40%; bottom: -2px; }
/* the monster pictures face left (toward a hero on their left); the ones on his left turn round */
.scene.blade .spot-mon.mob-left .sprite-mon { transform: scaleX(-1); animation: mon-bob-flip 2.6s ease-in-out infinite; }
.scene.blade .spot-mon.mob-left .tag { direction: ltr; }
@keyframes mon-bob-flip { 50% { transform: scaleX(-1.02) translateY(-2px); } }
.scene.blade .mob-hide { visibility: hidden; }
.scene.blade .mob-walk { animation: mob-walk .85s cubic-bezier(.3, .8, .4, 1) both; }
@keyframes mob-walk { from { transform: translate(var(--from, 160px, 0)); opacity: 0; } 20% { opacity: 1; } to { transform: translate(0, 0); opacity: 1; } }
.scene.blade .mob-walk .sprite-mon { animation: mob-step .22s ease-in-out 4; }
@keyframes mob-step { 50% { transform: translateY(-5px); } }
.scene.blade .mob-left.mob-walk .sprite-mon { animation: mob-step-flip .22s ease-in-out 4; }
@keyframes mob-step-flip { 0%, 100% { transform: scaleX(-1); } 50% { transform: scaleX(-1) translateY(-5px); } }
.scene.blade .mob-lunge .sprite-mon { animation: mob-lunge .5s ease-out; }
@keyframes mob-lunge { 30% { transform: translateX(-16px) scale(1.04); } 60% { transform: translateX(-10px); } 100% { transform: translateX(0); } }
.scene.blade .mob-left.mob-lunge .sprite-mon { animation: mob-lunge-flip .5s ease-out; }
@keyframes mob-lunge-flip { 0%, 100% { transform: scaleX(-1); } 30% { transform: scaleX(-1) translateX(-16px) scale(1.04); } 60% { transform: scaleX(-1) translateX(-10px); } }
.scene.blade .spot-mon.dead .sprite-mon { animation: mob-fall .48s ease-in forwards; }
@keyframes mob-fall { 40% { transform: translateY(-6px) rotate(0deg); filter: brightness(1.6); } to { opacity: 0; transform: translateY(14px) rotate(-70deg) scale(.9); filter: brightness(.4); } }
.scene.blade .mob-left.dead .sprite-mon { animation: mob-fall-flip .48s ease-in forwards; }
@keyframes mob-fall-flip { 40% { transform: scaleX(-1) translateY(-6px); filter: brightness(1.6); } to { opacity: 0; transform: scaleX(-1) translateY(14px) rotate(-70deg) scale(.9); filter: brightness(.4); } }
.scene.blade .spot-mon.spawn .sprite-mon { animation: mob-wake .3s ease-out; }
@keyframes mob-wake { from { filter: brightness(2); transform: scale(1.08); } }
.scene.blade .mob-left.spawn .sprite-mon { animation: mob-wake-flip .3s ease-out; }
@keyframes mob-wake-flip { from { filter: brightness(2); transform: scaleX(-1.08); } to { transform: scaleX(-1); } }
.scene.blade .mob-struck .sprite-mon { filter: brightness(2.2) saturate(0); }
.scene.blade .hero-cast .sprite-hero { filter: drop-shadow(0 0 18px rgba(255,220,120,.95)) drop-shadow(0 6px 4px rgba(0,0,0,.55)); }

/* the effects: no rotation loops, each a single motion toward the target */
.afx { animation: none; border: 0; box-shadow: none; }
.afx-slash { width: 180px; height: 180px; margin: -90px 0 0 -30px; border-radius: 50%; border: 14px solid transparent; border-top-color: rgba(255,230,160,.95); border-right-color: rgba(255,160,60,.9); box-shadow: 0 0 24px rgba(255,180,80,.7); animation: afx-slash .42s cubic-bezier(.2, .9, .3, 1) forwards; }
@keyframes afx-slash { from { transform: rotate(-70deg) scale(.5); opacity: 0; } 30% { opacity: 1; } to { transform: rotate(40deg) scale(1.15); opacity: 0; } }
.afx-slash.afx-left { margin-left: -150px; transform-origin: 50% 50%; animation-name: afx-slash-left; }
@keyframes afx-slash-left { from { transform: scaleX(-1) rotate(-70deg) scale(.5); opacity: 0; } 30% { opacity: 1; } to { transform: scaleX(-1) rotate(40deg) scale(1.15); opacity: 0; } }
.afx-bolt { width: 120px; height: 6px; margin: -3px 0 0 0; border-radius: 3px; background: linear-gradient(90deg, rgba(255,240,180,0), #fff 40%, #ffd070); box-shadow: 0 0 10px rgba(255,220,120,.9); transform-origin: 0 50%; animation: afx-bolt .32s ease-out forwards; }
.afx-b1 { animation-delay: 0s; --ang: -14deg; } .afx-b2 { animation-delay: .08s; --ang: 0deg; } .afx-b3 { animation-delay: .16s; --ang: 14deg; }
@keyframes afx-bolt { from { transform: rotate(var(--ang, 0deg)) scaleX(.2); opacity: 0; } 30% { opacity: 1; } to { transform: rotate(var(--ang, 0deg)) translateX(var(--len, 140px)) scaleX(1); opacity: 0; } }
.afx-bolt.afx-left { transform-origin: 0 50%; animation-name: afx-bolt-left; }
@keyframes afx-bolt-left { from { transform: scaleX(-1) rotate(var(--ang, 0deg)) scaleX(.2); opacity: 0; } 30% { opacity: 1; } to { transform: scaleX(-1) rotate(var(--ang, 0deg)) translateX(140px) scaleX(1); opacity: 0; } }
.afx-nova { width: 60px; height: 60px; margin: -30px 0 0 -30px; border-radius: 50%; background: radial-gradient(circle, rgba(255,255,255,.95), rgba(160,220,255,.7) 40%, rgba(120,200,255,0) 70%); animation: afx-nova .6s ease-out forwards; }
@keyframes afx-nova { from { transform: scale(.3); opacity: 1; } to { transform: scale(4.5); opacity: 0; } }
.afx-flash { position: absolute; inset: -40px; margin: 0; width: auto; height: auto; border-radius: 0; background: rgba(255,240,200,.55); animation: afx-flash .35s ease-out forwards; }
@keyframes afx-flash { from { opacity: 1; } to { opacity: 0; } }
.afx-name { top: 26%; }

/* the flip lives on the container, never on the animated picture (17 Sep
   2026: "the pictures are still spinning when fighting monsters on the side").
   A hit or a lunge animates the picture's transform and would undo a flip
   set there, frame by frame, which read as spinning. */
.scene.blade .spot-mon.mob-left .sprite-mon { transform: none; animation: mon-bob 2.6s ease-in-out infinite; }
.scene.blade .spot-mon.mob-left { transform: scaleX(-1); }
.scene.blade .spot-mon.mob-left .tag { transform: scaleX(-1); }
.scene.blade .mob-left.mob-walk { animation-name: mob-walk-left; }
@keyframes mob-walk-left { from { transform: scaleX(-1) translate(var(--from, 160px, 0)); opacity: 0; } 20% { opacity: 1; } to { transform: scaleX(-1) translate(0, 0); opacity: 1; } }
.scene.blade .mob-left.mob-walk .sprite-mon { animation: mob-step .22s ease-in-out 4; }
.scene.blade .mob-left.mob-lunge .sprite-mon { animation: mob-lunge .5s ease-out; }
.scene.blade .mob-left.dead .sprite-mon { animation: mob-fall .48s ease-in forwards; }
.scene.blade .mob-left.spawn .sprite-mon { animation: mob-wake .3s ease-out; }
.scene.blade .mob-left.hit .sprite-mon { animation: shake .22s linear; }
.scene.blade .spot-hero.face-left { transform: translate(-50%, -40%) scaleX(-1); }
.scene.blade .spot-hero.face-left .sprite-hero, .scene.blade .spot-hero.face-left .ride-pet { transform: none; }
.scene.blade .spot-hero.face-left .ride-mount { transform: translateX(-18%); }
.scene.blade .spot-hero.face-left .tag { transform: scaleX(-1); }
.scene.blade .spot-hero.face-left .ride-wings { transform: translateX(-50%); }
.scene.blade .mob-p1 { left: 15%; top: 40%; }
.scene.blade .mob-p3 { left: 17%; top: 66%; }
.scene.blade .mob-p0 { left: 60%; }
.scene.blade .mob-p4 { left: 62%; }
/* the Menu in sections (17 Sep 2026) */
.menu-h { font-family: Cinzel, Georgia, serif; font-size: 11px; letter-spacing: .12em; text-transform: uppercase; color: var(--frame-light); margin: 12px 0 2px; padding-bottom: 3px; border-bottom: 1px solid rgba(255,230,160,.18); }
.menu-h-wait { color: #ff9a9a; margin-top: 4px; }
.menu-wait { background: rgba(255,120,80,.08); border-radius: 10px; }
.grid-sheet { padding: 6px 0 4px; }
button.sc { background: none; border: 0; padding: 0; font: inherit; color: var(--ivory); cursor: pointer; -webkit-appearance: none; appearance: none; }
.grid-sheet .sc-label { font-size: 11px; font-variant: normal; letter-spacing: 0; text-transform: none; }
/* VIP name colours in chat (include/vip.php chat row, 17 Sep 2026) */
.vipname-gold .feed-name, .vipname-gold .tavern-name, .vipname-gold b:first-child { color: #ffd070; }
.vipname-ruby .feed-name, .vipname-ruby .tavern-name, .vipname-ruby b:first-child { color: #ff8a8a; text-shadow: 0 0 6px rgba(255,80,80,.5); }
.vipname-dragon .feed-name, .vipname-dragon .tavern-name, .vipname-dragon b:first-child { color: #ff9a3a; text-shadow: 0 0 8px rgba(255,140,40,.7); }
.vipname-crown .feed-name, .vipname-crown .tavern-name, .vipname-crown b:first-child { color: #fff; text-shadow: 0 0 10px #ffd070, 0 0 3px #ffd070; }
/* the full HUD stays on the fight page (17 Sep 2026: "put the info we had here back about VIP relic etc") */
.page-game .hud2 .hud-main, .page-game .hud-name-tag { display: flex; }
.page-game .hud-name-tag { display: block; }
.page-game .scene.blade .bi-top .bi-round.bi-buff { display: none; }   /* Buffs is a pill in the HUD again */
.arena { top: 74px; }
/* with the full HUD back the scene is 540px: rails at 34px, the stack at 40px, so nothing overlaps */
.page-game .scene.blade .edge:not(.edge-right), .page-game .scene.blade .edge-right { top: 86px; gap: 3px; }
.page-game .scene.blade .edge .edge-btn, .page-game .scene.blade .edge-right .edge-btn { width: 36px; height: 36px; }
.page-game .scene.blade .edge .edge-btn .ui-pic { width: 23px; height: 23px; }
.page-game .scene.blade .edge .edge-label { font-size: 6.5px; }
.page-game .scene.blade .edge .badge-red { min-width: 14px; height: 14px; line-height: 12px; font-size: 8px; top: -3px; right: -3px; }
.bi-loot-n { font-size: 8px; }
.bi-stack-btn, .bi-stack-btn.auto-btn, .bi-stack-btn.bi-auto { width: 40px; height: 40px; }
.bi-stack-btn .ui-pic { width: 20px; height: 20px; } .bi-stack-btn span { font-size: 6px; }
.bi-auto { font-size: 8px; }
.bi-stack { gap: 4px; }
.bi-bottom { bottom: 18px; }
.bi-presets { margin-bottom: 4px; }
.bi-preset, .bi-preset-cfg { width: 26px; height: 26px; font-size: 10px; }
.bi-hex { width: 46px; height: 46px; } .bi-hex img, .bi-hex .ui-pic { width: 31px; height: 31px; }
.bi-top { top: 4px; }
.bi-quest { top: 50px; }
.arena { top: 70px; bottom: 132px; }
.scene.blade .mob-p2 { top: 2%; }
.scene.blade .mob-p3 { top: 62%; } .scene.blade .mob-p4 { top: 66%; }
.bi-rates { bottom: 2px; font-size: 8px; }
/* the Stage / Repeat / AUTO stack stands on its own at the bottom right, so the
   presets sit just above the skills instead of being pushed up into the rails */
.bi-row { padding-right: 46px; }
.bi-stack { position: absolute; right: 0; bottom: 0; }
.bi-row .bi-skills { justify-content: space-around; }
/* the race / champion widget top right under Menu; the right rail starts under it (17 Sep 2026) */
.bi-widgets { position: absolute; right: 4px; top: 50px; z-index: 6; width: 88px; display: flex; flex-direction: column; gap: 4px; }
.bi-widget { display: flex; flex-direction: column; align-items: center; gap: 1px; padding: 4px 3px 5px; border-radius: 10px; text-decoration: none; color: var(--ivory); text-align: center;
  background: linear-gradient(180deg, rgba(42,52,104,.94), rgba(11,14,34,.96)); border: 2px solid var(--frame); box-shadow: 0 0 0 1px var(--frame-dark), 0 3px 8px rgba(0,0,0,.7); }
.bi-w-title { font-family: Cinzel, serif; font-size: 7.5px; letter-spacing: .04em; text-transform: uppercase; color: var(--frame-light); white-space: nowrap; }
.bi-w-pic { width: 34px; height: 34px; border-radius: 50%; overflow: hidden; border: 2px solid var(--frame); background: #0b0e22; display: flex; align-items: center; justify-content: center; margin: 1px 0; }
.bi-w-pic img, .bi-w-pic .ui-pic { width: 100%; height: 100%; object-fit: cover; }
.bi-w-pic.bi-w-rift { border: 0; background: none; width: 30px; height: 30px; } .bi-w-pic.bi-w-rift img { object-fit: contain; }
.bi-w-name { font-size: 10px; font-weight: 700; max-width: 80px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bi-w-sub { font-size: 8px; color: var(--ivory-muted); max-width: 80px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bi-w-timer { font-size: 9px; font-weight: 800; color: #8fd48f; font-variant-numeric: tabular-nums; }
.bi-race { border-color: #ffb340; }
.bi-race .bi-w-title { color: #ffd070; }
.bi-open { border-color: #ffb340; box-shadow: 0 0 0 1px var(--frame-dark), 0 0 12px rgba(255,180,60,.6); } .bi-open .bi-w-timer { color: #ffd070; }
.bi-rift { padding-top: 3px; }
.page-game .scene.blade .edge-right { top: 150px; }
.scene.blade:has(.bi-rift) .edge-right { top: 226px; }
.page-game .scene.blade .edge:not(.edge-right) { top: 86px; }
/* with a widget above it the right rail is 34px and the stack 34px, so they never meet */
.bi-widget { padding: 3px 3px 4px; gap: 0; }
.bi-w-pic { width: 28px; height: 28px; }
.bi-w-name { font-size: 9.5px; } .bi-w-sub { font-size: 7.5px; } .bi-w-timer { font-size: 8.5px; } .bi-w-title { font-size: 7px; }
.page-game .scene.blade .edge-right { top: 128px; gap: 2px; }
.scene.blade:has(.bi-rift) .edge-right { top: 196px; }
.page-game .scene.blade .edge-right .edge-btn { width: 34px; height: 34px; }
.page-game .scene.blade .edge-right .edge-btn .ui-pic { width: 22px; height: 22px; }
.bi-stack-btn, .bi-stack-btn.auto-btn, .bi-stack-btn.bi-auto { width: 36px; height: 36px; }
.bi-stack-btn .ui-pic { width: 18px; height: 18px; } .bi-stack-btn .ico { width: 15px; height: 15px; }
.bi-stack { gap: 3px; }
.bi-bottom { bottom: 14px; }
.page-game .scene.blade .edge-right { top: 141px; }
.scene.blade:has(.bi-rift) .edge-right { top: 206px; }
.bi-stack-btn, .bi-stack-btn.auto-btn, .bi-stack-btn.bi-auto { width: 33px; height: 33px; }
.bi-bottom { bottom: 10px; }
.bi-rates { bottom: 0; }
.card-head h2 .ui-pic { width: 28px; height: 28px; vertical-align: middle; margin-right: 4px; }
/* no skill row or presets on the fight screen (17 Sep 2026: "get rid of the skills off screen");
   the skills still fire from blade.js, the row is just not drawn */
.bi-presets, .bi-skills { display: none; }
.bi-row { padding-right: 0; min-height: 0; }
.bi-bottom { left: auto; right: 6px; bottom: 10px; }
.bi-stack { position: static; }
.arena { bottom: 40px; }
.scene.blade .mob-p3 { top: 70%; } .scene.blade .mob-p4 { top: 74%; }
.bi-rates { bottom: 2px; left: 8px; right: 60px; justify-content: flex-start; }
.page-game .scene.blade .edge:not(.edge-right) { top: 86px; }
/* the fight stays near the middle of tall screens rather than sinking (17 Sep 2026: "harder to read") */
.arena { top: 70px; bottom: auto; height: min(calc(100% - 110px), 430px); }
.scene.blade .spot-hero { top: 46%; }
.scene.blade .mob-p0 { left: 62%; top: 36%; }
.scene.blade .mob-p4 { left: 60%; top: 74%; }
.scene.blade .mob-p1 { top: 34%; }
/* origin and star sign on the class page (include/origins.php, 17 Sep 2026) */
.origin-pick { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; margin-top: 6px; }
.origin-signs { grid-template-columns: repeat(3, 1fr); margin-top: 10px; }
.origin-chip { position: relative; cursor: pointer; }
.origin-chip input { position: absolute; opacity: 0; width: 0; height: 0; }
.origin-chip span { display: flex; flex-direction: column; gap: 2px; padding: 8px 10px; border-radius: 10px; background: rgba(0,0,0,.35); border: 1px solid var(--frame-dark); font-size: 12px; min-height: 100%; }
.origin-chip b { font-family: Cinzel, Georgia, serif; font-size: 12px; color: var(--ivory); }
.origin-chip small { color: var(--ivory-muted); font-size: 11px; line-height: 1.3; }
.origin-chip i { font-style: normal; color: #8fd48f; font-size: 11px; }
.origin-chip input:checked + span { border-color: var(--frame-light); box-shadow: 0 0 10px rgba(255,220,120,.5); background: rgba(60,50,0,.35); }
.origin-sign span { padding: 6px 6px; text-align: center; align-items: center; }
.origin-sign b { font-size: 11px; }
/* the party walks a step behind the hero (include/allies.php, 17 Sep 2026) */
.ride-ally { position: absolute; bottom: 0; width: 62px; height: auto; z-index: 0; opacity: .95; filter: drop-shadow(0 4px 3px rgba(0,0,0,.5)); animation: ally-bob 2.4s ease-in-out infinite; pointer-events: none; }
.ride-ally-1 { left: -58px; bottom: 6px; animation-delay: -.4s; }
.ride-ally-2 { left: -34px; bottom: 34px; width: 54px; opacity: .85; animation-delay: -1.1s; }
.ride-ally-3 { left: -10px; bottom: 56px; width: 48px; opacity: .75; animation-delay: -1.8s; }
@keyframes ally-bob { 50% { transform: scaleY(1.025) scaleX(.99); } }   /* planted (21 Sep 2026); the warden and kin are spirits and keep their hover */
.scene.blade .spot-hero.face-left .ride-ally { transform: none; }
body.pref-nomotion .ride-ally { animation: none; }
.frame-sunburst { border-color: #ffd070; box-shadow: 0 0 0 2px #ff9a3a, inset 0 0 0 2px #7a4a10, 0 0 14px rgba(255,180,60,.9), 0 0 28px rgba(255,120,40,.5); }
.race-place { width: 26px; height: 26px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; font-weight: 800; background: rgba(0,0,0,.4); border: 1px solid var(--frame-dark); flex: none; }
.race-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.race-score { color: var(--frame-light); white-space: nowrap; } .race-score small { color: var(--ivory-muted); font-weight: 400; }
.race-mine { background: rgba(255,230,160,.08); border-radius: 8px; }
/* the fight sits in the lower middle of the scene, clear of the widget and the
   rails' tops, in a tighter ring (18 Sep 2026: "the fight positioning is really bad") */
.arena { top: auto; bottom: 36px; height: min(calc(100% - 150px), 430px); }
.scene.blade .spot-hero { top: 50%; }
.scene.blade .mob-p0 { left: 63%; top: 44%; }
.scene.blade .mob-p1 { left: 13%; top: 40%; }
.scene.blade .mob-p2 { left: 36%; top: 12%; }
.scene.blade .mob-p3 { left: 18%; top: 72%; }
.scene.blade .mob-p4 { left: 58%; top: 74%; }
/* skins: tints on the hero, pet and mount (include/skins.php, 18 Sep 2026) */
.hero-skin { display: contents; }
.skin-ashen { filter: sepia(.8) saturate(.4) brightness(.7) contrast(1.15) drop-shadow(0 0 6px rgba(40,30,20,.9)); }
.skin-frost { filter: hue-rotate(190deg) saturate(1.2) brightness(1.1) drop-shadow(0 0 8px rgba(120,200,255,.85)) drop-shadow(0 0 16px rgba(80,160,255,.45)); }
.skin-gilt  { filter: sepia(1) saturate(2.4) hue-rotate(-12deg) brightness(1.12) contrast(1.1) drop-shadow(0 0 8px rgba(255,214,90,.9)); animation: skin-sparkle 1.6s ease-in-out infinite; }
.skin-void  { filter: hue-rotate(250deg) saturate(1.3) brightness(.75) drop-shadow(0 0 10px rgba(120,40,200,.9)) drop-shadow(0 4px 14px rgba(10,0,30,.95)); }
.skin-ember { filter: sepia(.7) saturate(3) hue-rotate(-25deg) brightness(1.05) drop-shadow(0 0 8px rgba(255,120,30,.9)) drop-shadow(0 0 18px rgba(255,60,0,.5)); animation: skin-ember 1.2s ease-in-out infinite alternate; }
.skin-storm { filter: hue-rotate(160deg) saturate(1.6) brightness(1.15) drop-shadow(0 0 8px rgba(80,240,255,.9)); animation: skin-storm 2.4s steps(1, end) infinite; }
@keyframes skin-sparkle { 0%, 100% { filter: sepia(1) saturate(2.4) hue-rotate(-12deg) brightness(1.12) contrast(1.1) drop-shadow(0 0 8px rgba(255,214,90,.9)); } 50% { filter: sepia(1) saturate(2.4) hue-rotate(-12deg) brightness(1.3) contrast(1.1) drop-shadow(0 0 14px rgba(255,240,160,1)); } }
@keyframes skin-ember { from { filter: sepia(.7) saturate(3) hue-rotate(-25deg) brightness(1.05) drop-shadow(0 0 8px rgba(255,120,30,.9)) drop-shadow(0 0 18px rgba(255,60,0,.5)); } to { filter: sepia(.7) saturate(3) hue-rotate(-25deg) brightness(1.15) drop-shadow(0 0 12px rgba(255,160,40,1)) drop-shadow(0 0 26px rgba(255,80,0,.7)); } }
@keyframes skin-storm { 0%, 88%, 100% { filter: hue-rotate(160deg) saturate(1.6) brightness(1.15) drop-shadow(0 0 8px rgba(80,240,255,.9)); } 90%, 94% { filter: hue-rotate(160deg) saturate(1.6) brightness(1.8) drop-shadow(0 0 16px rgba(220,255,255,1)); } 92% { filter: hue-rotate(160deg) saturate(1.6) brightness(1.15) drop-shadow(0 0 8px rgba(80,240,255,.9)); } }
.skin-magma { filter: sepia(.8) saturate(2.6) hue-rotate(-30deg) brightness(.9) contrast(1.25) drop-shadow(0 0 8px rgba(255,90,20,.95)) drop-shadow(0 0 18px rgba(200,40,0,.55)); animation: skin-magma 2.2s ease-in-out infinite alternate; }
@keyframes skin-magma { from { filter: sepia(.8) saturate(2.6) hue-rotate(-30deg) brightness(.9) contrast(1.25) drop-shadow(0 0 8px rgba(255,90,20,.95)) drop-shadow(0 0 18px rgba(200,40,0,.55)); } to { filter: sepia(.8) saturate(2.6) hue-rotate(-30deg) brightness(1.02) contrast(1.25) drop-shadow(0 0 12px rgba(255,140,30,1)) drop-shadow(0 0 28px rgba(255,60,0,.75)); } }   /* Magma (21 Sep 2026): the same rule as skins.css, game.php does not load that file */
.hero-skin[class*="skin-"] .sprite-hero { filter: inherit; }
/* Double it (include/doubler.php) */
.bi-double { position: absolute; left: 10px; top: 84px; z-index: 6; margin: 0; }
.bi-double-btn { display: flex; flex-direction: column; align-items: flex-start; gap: 1px; padding: 5px 12px 5px 10px; border-radius: 14px; font: inherit; color: var(--ivory); cursor: pointer; text-align: left;
  background: linear-gradient(180deg, rgba(60,50,0,.8), rgba(0,0,0,.85)); border: 2px solid var(--frame-light); box-shadow: 0 0 0 1px var(--frame-dark), 0 0 12px rgba(255,220,120,.6); animation: lit-pulse-gold 1.6s ease-in-out infinite; }
.bi-double-btn b { font-family: Cinzel, serif; font-size: 11px; color: var(--frame-light); }
.bi-double-btn span { font-size: 10px; } .bi-double-btn small { font-size: 9px; color: #8fd48f; font-weight: 700; }
/* fight placement, third go (18 Sep 2026): the arena is the whole tall screen under the HUD, the hero
   stands low in the middle like Blade Idle and every monster is above him, none under his feet */
.arena { top: 130px; bottom: 44px; height: auto; }
.scene.blade .spot-hero { top: 72%; }
.scene.blade .mob-p0 { left: 60%; top: 52%; }
.scene.blade .mob-p1 { left: 18%; top: 52%; }
.scene.blade .mob-p2 { left: 58%; top: 28%; }
.scene.blade .mob-p3 { left: 20%; top: 30%; }
.scene.blade .mob-p4 { left: 40%; top: 10%; }
@media (max-height: 740px) { .arena { top: 120px; bottom: 40px; height: auto; } .scene.blade .spot-hero { top: 70%; } }
/* fight placement, fourth go: full height arena, the hero in the middle of it and the pack in a ring round him, two in front, two behind, one above */
.scene.blade .spot-hero { top: 56%; }
.scene.blade .mob-p0 { left: 62%; top: 48%; }
.scene.blade .mob-p1 { left: 14%; top: 48%; }
.scene.blade .mob-p2 { left: 38%; top: 12%; }
.scene.blade .mob-p3 { left: 20%; top: 72%; }
.scene.blade .mob-p4 { left: 58%; top: 72%; }
@media (max-height: 740px) { .scene.blade .spot-hero { top: 56%; } }
/* 18 Sep 2026, "the main guy is moving": the attack frames were drawn on their own canvases, so the
   swap to one of them put a second, shifted hero on screen for a moment. The hero now keeps his one
   picture and attacks in place: a recoil, no drift, the class flash does the rest. */
.scene.blade .spot-hero .hero-attack { display: none !important; }
.scene.blade .spot-hero.lunge .hero-idle, .scene.blade .spot-hero:has(.ride-mount).lunge .hero-idle { opacity: 1; animation: strike-still .34s cubic-bezier(.2, .9, .3, 1); }
@keyframes strike-still {
  0%   { transform: translateX(-50%) scale(.96, 1.04); }
  30%  { transform: translateX(-50%) scale(1.06, .95); }
  60%  { transform: translateX(-50%) translateX(6px) scale(1.02, 1); }
  100% { transform: translateX(-50%) scale(1, 1); }
}
/* ONE ENEMY (18 Sep 2026, "lets just have 1 enemy to make this easier and make more style in
   attacking, moving and enemys dieing, live motion"). The pack is gone; the one monster walks in from
   the top, is knocked back on every hit, flies and tumbles when it dies, and the next walks in. */
.scene.blade .mob-extra { display: none !important; }
.scene.blade .spot-hero { left: 42%; top: 58%; }
.scene.blade .mob-p0 { left: 62%; top: 50%; }
.arena-fx { top: 58%; left: 42%; right: auto; bottom: auto; width: 0; height: 0; overflow: visible; }
.afx { top: 0; left: 0; }
/* the hero: a dash at the target and back, in place, no drift and no second picture */
.scene.blade .spot-hero.lunge .hero-idle, .scene.blade .spot-hero:has(.ride-mount).lunge .hero-idle { animation: hero-dash .36s cubic-bezier(.2, .9, .3, 1); }
@keyframes hero-dash {
  0%   { transform: translateX(-50%) scale(.94, 1.06); }
  22%  { transform: translateX(-50%) translateX(-8px) scale(1.04, .96); }
  55%  { transform: translateX(-50%) translateX(34px) scale(1.06, .98); filter: brightness(1.25); }
  100% { transform: translateX(-50%) scale(1, 1); }
}
/* the enemy walks in from the top edge (blade.js adds mob-enter), steps as it comes */
.scene.blade .spot-mon.mob-enter { animation: mob-enter .8s cubic-bezier(.3, .8, .4, 1) both; }
@keyframes mob-enter { from { transform: translate(70px, -260px); opacity: 0; } 15% { opacity: 1; } to { transform: translate(0, 0); opacity: 1; } }
.scene.blade .spot-mon.mob-enter .sprite-mon { animation: mob-step .2s ease-in-out 4; }
.scene.blade .spot-mon.mob-enter.dead { animation: none; }
/* the enemy lunges at the hero when it bites (nv:bite) */
.scene.blade .spot-mon.mob-bite .sprite-mon { animation: mob-bite .46s cubic-bezier(.2, .9, .3, 1); }
@keyframes mob-bite { 25% { transform: translateX(-4px) scale(1.05, .95); } 55% { transform: translateX(-40px) scale(1.06, 1); filter: brightness(1.2); } 100% { transform: translateX(0); } }
/* every hit: a white flash and a knock back, a crit knocks harder */
.scene.blade .spot-mon.hit .sprite-mon { animation: mob-knock .26s ease-out; }
@keyframes mob-knock { 20% { transform: translateX(14px) rotate(4deg); filter: brightness(2.4) saturate(0); } 60% { transform: translateX(8px); filter: brightness(1.3); } 100% { transform: translateX(0); } }
.scene.blade .spot-mon.hit.hit-crit .sprite-mon { animation: mob-knock-crit .34s ease-out; }
@keyframes mob-knock-crit { 20% { transform: translateX(28px) translateY(-8px) rotate(10deg); filter: brightness(2.6) saturate(0); } 60% { transform: translateX(14px); filter: brightness(1.2); } 100% { transform: translateX(0); } }
/* dying: launched back, tumbles, drops and fades, with a soul puff */
.scene.blade .spot-mon.dead .sprite-mon { animation: mob-launch .62s cubic-bezier(.2, .6, .4, 1) forwards; }
@keyframes mob-launch {
  0%   { transform: translate(0, 0) rotate(0); filter: brightness(2.2) saturate(0); }
  35%  { transform: translate(46px, -54px) rotate(-40deg); filter: brightness(1.4); opacity: 1; }
  70%  { transform: translate(78px, 6px) rotate(-110deg) scale(.95); opacity: .9; }
  100% { transform: translate(92px, 18px) rotate(-150deg) scale(.8); opacity: 0; filter: brightness(.3); }
}
.scene.blade .spot-mon.dead::after { opacity: 0; transition: opacity .3s; }
.afx-soul { width: 90px; height: 90px; margin: -45px 0 0 -45px; border-radius: 50%; background: radial-gradient(circle, rgba(255,255,255,.95), rgba(255,220,140,.75) 35%, rgba(255,180,60,0) 70%); animation: afx-soul .7s ease-out forwards; }
@keyframes afx-soul { from { transform: scale(.3); opacity: 1; } to { transform: scale(1.6) translateY(-40px); opacity: 0; } }
.afx-shard { width: 8px; height: 8px; margin: -4px 0 0 -4px; border-radius: 2px; background: #ffd070; box-shadow: 0 0 8px rgba(255,200,90,.9); animation: afx-shard .7s cubic-bezier(.2, .8, .4, 1) forwards; }
@keyframes afx-shard { from { transform: translate(0, 0) rotate(0); opacity: 1; } to { transform: translate(var(--dx, 40px), var(--dy, -60px)) rotate(240deg); opacity: 0; } }
/* every plain swing throws the class's own strike, a light one; the skills throw the big one */
.afx-light { opacity: .8; transform-origin: 0 50%; }
.afx-light.afx-slash { width: 120px; height: 120px; margin: -60px 0 0 0; border-width: 9px; }
.afx-light.afx-bolt { width: 90px; }
.afx-light.afx-nova { width: 44px; height: 44px; margin: -22px 0 0 -22px; }
/* the monster's tag sits above it; the hero's tag above him; both a touch higher so the knock back does not cross them */
.scene.blade .mob-p0 .tag { top: -34px; }
/* 18 Sep 2026: the hero vanished on every swing (the old two-picture swap hid the idle picture with display:none) */
.scene.blade .spot-hero.lunge .hero-idle { display: block !important; }
/* "move the fight up to the centre and lets not have everything crowded around the hero": the pair sits
   in the middle of the ground, the mount stands off behind, the pet a step ahead, the warden and the allies further back */
.scene.blade .spot-hero { left: 36%; top: 44%; }
.scene.blade .mob-p0 { left: 64%; top: 40%; }
.arena-fx { left: 36%; top: 44%; }
.scene.blade .ride-mount { width: 104px; left: 0; transform: translateX(-88%); bottom: 4px; opacity: .92; }
@keyframes mount-bob { 50% { transform: translateX(-88%) translateY(-2px); } }
.scene.blade .spot-hero:has(.ride-mount) .ride-pet, .scene.blade .ride-pet { left: auto; right: -30px; bottom: -4px; width: 44px; z-index: 3; }
.scene.blade .ride-warden { left: 0; bottom: 70px; transform: translateX(-130%); }
.scene.blade .ride-ally-1 { left: -124px; bottom: 2px; }
.scene.blade .ride-ally-2 { left: -110px; bottom: 30px; }
.scene.blade .ride-ally-3 { left: -96px; bottom: 56px; }
.scene.blade .ride-cloak { z-index: 0; }
.scene.blade .spot-hero .sprite-hero { z-index: 2; }
/* "warden is hidden": it floats on the hero's open side, above the pet, in front of the wings */
.scene.blade .ride-warden { left: 100%; bottom: 84px; width: 64px; transform: translateX(-30%); z-index: 3; opacity: .92; }
@keyframes warden-bob { 50% { transform: translateX(-30%) translateY(-6px); } }
/* a phone is 375 wide: the pair tucks in between the rails */
@media (max-width: 430px) {
  .scene.blade .spot-hero { left: 38%; }
  .scene.blade .mob-p0 { left: 58%; }
  .arena-fx { left: 38%; }
  .scene.blade .ride-mount { width: 88px; transform: translateX(-72%); }
  @keyframes mount-bob { 50% { transform: translateX(-72%) translateY(-2px); } }
}
.scene.blade .ride-warden { bottom: 104px; transform: translateX(-60%); }
@keyframes warden-bob { 50% { transform: translateX(-60%) translateY(-6px); } }
/* "its covering my health": the warden sits right of the hero above the pet, off the tag; the skill name calls out above the tag */
.scene.blade .ride-warden { left: 100%; bottom: 52px; transform: translateX(-12%); }
@keyframes warden-bob { 50% { transform: translateX(-12%) translateY(-6px); } }
.arena-fx .afx-name { top: -120px; left: 48px; }

/* PICTURED FRAMES (18 Sep 2026, "use labs to make new frames, these are plain"): each frame but Plain is a
   painted ring from Labs (images/frames/cut), laid over the portrait ring on Settings, the HUD and the
   player card. The ring keeps its own border underneath as the fallback; the picture sits a little
   larger than the ring so the ornament shows round the outside. */
.set-ring, .avatar-ring { position: relative; }
.set-ring[class*="frame-"]:not(.frame-plain)::after, .avatar-ring[class*="frame-"]:not(.frame-plain)::after {
  content: ""; position: absolute; inset: -22%; pointer-events: none; z-index: 2;
  background-size: contain; background-position: center; background-repeat: no-repeat; filter: drop-shadow(0 2px 3px rgba(0,0,0,.6));
}
.set-ring[class*="frame-"]:not(.frame-plain), .avatar-ring[class*="frame-"]:not(.frame-plain) { border-color: transparent; box-shadow: none; }
.frame-iron::after      { background-image: url(../images/frames/cut/iron.png); }
.frame-gold::after      { background-image: url(../images/frames/cut/gold.png); }
.frame-dragon::after    { background-image: url(../images/frames/cut/dragon.png); inset: -30%; }
.frame-embers::after    { background-image: url(../images/frames/cut/embers.png); }
.frame-rimecrown::after { background-image: url(../images/frames/cut/rimecrown.png); inset: -26%; }
.frame-laurel::after    { background-image: url(../images/frames/cut/laurel.png); inset: -20%; }
.frame-wyrmcoil::after  { background-image: url(../images/frames/cut/wyrmcoil.png); inset: -24%; }
.frame-sunburst::after  { background-image: url(../images/frames/cut/sunburst.png); inset: -30%; }
.frame-sunburst::after  { animation: frame-turn 14s linear infinite; }
@keyframes frame-turn { to { transform: rotate(360deg); } }
.set-choice .set-ring-small { margin: 8px auto 4px; }
/* THE QUEST BAND (18 Sep 2026, "where did my story go at the bottom like this?"): the story step, or the
   day's quest, sits at the foot of the fight the Blade Idle way: a small ornament heading, the task with
   its count in gold, and a second line saying what happens. Tap it to open the page, or to claim. */
.bi-quest, form.bi-quest { top: auto; bottom: 34px; left: 50%; right: auto; transform: translateX(-50%); max-width: 64%; width: max-content; min-width: 210px;
  display: flex; flex-direction: column; align-items: center; gap: 0; padding: 4px 14px 5px; border-radius: 10px; text-align: center; }
form.bi-quest { padding: 0; border: 0; box-shadow: none; background: none; }
.bi-quest-btn { display: flex; flex-direction: column; align-items: center; gap: 0; padding: 4px 14px 5px; border-radius: 10px; width: 100%; }
.bq-head { display: block; font-style: normal; font-family: Cinzel, serif; font-weight: 800; font-size: 11px; color: #ffd070; letter-spacing: .5px; text-shadow: 0 1px 2px #000; line-height: 1.2; }
.bq-head::before, .bq-head::after { content: "\2740"; color: var(--frame); font-size: 9px; margin: 0 5px; opacity: .85; }
.bq-line { display: block; white-space: normal; font-size: 11px; color: var(--ivory); line-height: 1.25; text-shadow: 0 1px 2px #000; }
.bq-line b { color: #ff9a9a; font-weight: 700; }
.bi-quest-btn .bq-line b { color: var(--frame-light); }
.bq-sub { display: block; font-size: 9.5px; color: #cfc6b8; line-height: 1.2; }
.bi-quest .ico { display: none; }
.bi-quest-btn .bq-sub { color: var(--frame-light); font-weight: 700; }
@media (max-width: 430px) { .bi-quest, form.bi-quest { max-width: 66%; bottom: 30px; } }
/* THE MENU AS ARIELIA SHOWS IT (18 Sep 2026, "why dosent my game look like this"): a dark glass over the
   fight with the halls as round pictures in rows of six, labels under, badges on. The fight shows through. */
.page-game #sheet-grid { background: linear-gradient(180deg, rgba(11,14,34,.9), rgba(11,14,34,.84)); backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px); border-color: var(--frame-dark); color: var(--ivory); }
.page-game #sheet-grid .sheet-grip { background: linear-gradient(90deg, var(--frame-dark), var(--frame), var(--frame-dark)); }
.page-game #sheet-grid .grid-sheet { grid-template-columns: repeat(6, 1fr); gap: 8px 2px; padding: 4px 0 8px; }
.page-game #sheet-grid .grid-sheet .sc-ico { width: 44px; height: 44px; border-width: 2px; }
.page-game #sheet-grid .grid-sheet .sc-ico .ui-pic { width: 30px; height: 30px; }
.page-game #sheet-grid .grid-sheet .sc-label { font-size: 8.5px; letter-spacing: .02em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.page-game #sheet-grid .menu-h { font-size: 10px; letter-spacing: 1px; color: #ffd070; text-transform: uppercase; margin: 6px 0 0; display: flex; align-items: center; gap: 8px; }
.page-game #sheet-grid .menu-h::before, .page-game #sheet-grid .menu-h::after { content: ""; flex: 1; height: 1px; background: linear-gradient(90deg, rgba(201,162,74,0), rgba(201,162,74,.7), rgba(201,162,74,0)); }
.page-game #sheet-grid .menu-h-wait { color: #ff9a9a; }
.page-game #sheet-grid .badge-red { transform: scale(.85); transform-origin: top right; }
@media (max-width: 430px) { .page-game #sheet-grid .grid-sheet { grid-template-columns: repeat(5, 1fr); } }
/* THE ENEMY BAR and the STAGE CALL (18 Sep 2026, from his Arielia clip) */
.bi-enemy { position: absolute; left: 50%; top: 52px; transform: translateX(-50%); z-index: 6; width: min(78%, 330px); display: flex; align-items: center; gap: 8px; padding: 3px 10px 3px 4px; border-radius: 22px;
  background: linear-gradient(90deg, rgba(11,14,34,.92), rgba(11,14,34,.78)); border: 1px solid var(--frame-dark); box-shadow: 0 2px 8px rgba(0,0,0,.5); pointer-events: none; }
.bi-enemy-pic { flex: none; width: 34px; height: 34px; border-radius: 50%; overflow: hidden; background: radial-gradient(circle at 40% 35%, #2a3468, #0b0e22); border: 2px solid var(--frame); display: flex; align-items: center; justify-content: center; }
.bi-enemy-pic img { width: 30px; height: 30px; object-fit: contain; }
.bi-enemy-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.bi-enemy-line { display: flex; align-items: baseline; gap: 6px; white-space: nowrap; overflow: hidden; }
.bi-enemy-name { font-family: Cinzel, serif; font-size: 11px; color: var(--ivory); text-shadow: 0 1px 2px #000; overflow: hidden; text-overflow: ellipsis; }
.bi-enemy-lv { font-size: 9px; color: #ffd070; }
.bi-enemy-bar { display: block; height: 7px; border-radius: 4px; background: rgba(0,0,0,.6); border: 1px solid rgba(255,214,90,.35); overflow: hidden; }
.bi-enemy-bar i { display: block; height: 100%; background: linear-gradient(180deg, #ffe97a, #f2b632 60%, #c98a12); box-shadow: 0 0 6px rgba(255,220,120,.6); transition: width .12s linear; }
.bi-enemy-left { flex: none; font-family: Cinzel, serif; font-weight: 800; font-size: 14px; color: #ffe14a; text-shadow: 0 1px 2px #000, 0 0 6px rgba(255,200,60,.5); }
.bi-enemy-left.bi-enemy-boss { color: #ff7a3a; animation: lit-pulse-gold 1s ease-in-out infinite; }
.bi-enemy-hit { animation: enemy-bar-hit .3s ease-out; }
@keyframes enemy-bar-hit { 30% { transform: translateX(-50%) scale(1.04); filter: brightness(1.4); } }
.scene.blade .mob-p0 .tag .bar { display: none; }   /* the life is on the top bar now; the name and the number stay by the monster */
@media (max-width: 430px) { .bi-enemy { top: 50px; width: 72%; } }
.bi-stagecall { position: absolute; left: 50%; top: 34%; transform: translateX(-50%) scale(.6); z-index: 7; display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 8px 26px; border-radius: 12px; opacity: 0; pointer-events: none;
  background: radial-gradient(ellipse at center, rgba(180,20,30,.75), rgba(120,0,10,0) 75%); }
.bi-stagecall b { font-family: Cinzel, serif; font-weight: 800; font-size: 26px; color: #ffd070; letter-spacing: 1px; -webkit-text-stroke: 1px #3a0000; text-shadow: 0 0 12px rgba(255,80,40,.9), 0 2px 4px #000; }
.bi-stagecall small { font-family: Cinzel, serif; font-size: 11px; color: #ffe9a8; text-shadow: 0 1px 2px #000; }
.bi-stagecall.on { animation: stagecall-in .5s cubic-bezier(.2, .9, .3, 1) forwards; }
.bi-stagecall.off { animation: stagecall-out .5s ease-in forwards; }
@keyframes stagecall-in { from { opacity: 0; transform: translateX(-50%) scale(.6); } 60% { transform: translateX(-50%) scale(1.08); } to { opacity: 1; transform: translateX(-50%) scale(1); } }
@keyframes stagecall-out { to { opacity: 0; transform: translateX(-50%) translateY(-30px) scale(.9); } }
/* ZOOM (18 Sep 2026, "pic 1 looks more zoomed and easier to read, why dosent mine look like that yet?"):
   Arielia draws everything about half as big again. The fight, the rails, the bar, the band and the
   rates all scale with the width of the screen, so a wide window is not a small game in a big field. */
:root { --zoom-hero: clamp(120px, 32vw, 176px); --zoom-mon: clamp(120px, 32vw, 176px); --zoom-btn: clamp(40px, 11vw, 56px); }
.scene.blade .spot { width: calc(var(--zoom-hero) * .9); }
.scene.blade .sprite-img.sprite-hero, .scene.blade .spot-hero:has(.ride-mount) .sprite-hero { width: var(--zoom-hero); height: var(--zoom-hero); }
.scene.blade .spot-hero { height: calc(var(--zoom-hero) + 8px); }
.scene.blade .sprite-img.sprite-mon { width: var(--zoom-mon); height: var(--zoom-mon); }
.scene.blade .ride-mount { width: calc(var(--zoom-hero) * .95); max-height: calc(var(--zoom-hero) * 1.15); }
.scene.blade .ride-wings { width: calc(var(--zoom-hero) * 1.3); max-height: calc(var(--zoom-hero) * 1.05); bottom: calc(var(--zoom-hero) * .28); }
.scene.blade .spot-hero:has(.ride-mount) .ride-pet, .scene.blade .ride-pet { width: calc(var(--zoom-hero) * .42); right: calc(var(--zoom-hero) * -.32); }
.scene.blade .ride-warden { width: calc(var(--zoom-hero) * .6); bottom: calc(var(--zoom-hero) * .5); }
.scene.blade .ride-cloak { width: calc(var(--zoom-hero) * 1.3); max-height: calc(var(--zoom-hero) * 1.2); }
.scene.blade .ride-ally { width: calc(var(--zoom-hero) * .55); }
.scene.blade .spot-hero .tag, .scene.blade .mob-p0 .tag { transform: scale(1.25); transform-origin: 50% 100%; }
.scene.blade .spot-hero:has(.ride-mount) .tag { top: -52px; }
.scene.blade .mob-p0 .tag { top: -44px; }
.scene.blade .spot-hero { left: 34%; }
.scene.blade .mob-p0 { left: 62%; }
.arena-fx { left: 34%; }
/* the rails and the stack */
.page-game .scene.blade .edge .edge-btn, .page-game .scene.blade .edge-right .edge-btn { width: var(--zoom-btn); height: var(--zoom-btn); }
.page-game .scene.blade .edge .edge-btn .ui-pic { width: calc(var(--zoom-btn) * .66); height: calc(var(--zoom-btn) * .66); }
.page-game .scene.blade .edge .edge-label { font-size: clamp(7px, 2.2vw, 10px); }
.bi-stack-btn { width: var(--zoom-btn); height: var(--zoom-btn); }
.bi-stack-btn span { font-size: clamp(7px, 2vw, 9px); }
.bi-stack-btn .ui-pic, .bi-stack-btn img { width: calc(var(--zoom-btn) * .5); height: calc(var(--zoom-btn) * .5); }
.bi-round { width: calc(var(--zoom-btn) * 1.05); height: calc(var(--zoom-btn) * 1.05); }
/* the enemy bar, the quest band, the rates and the widget */
.bi-enemy { top: 56px; width: min(80%, 380px); padding: 4px 12px 4px 5px; }
.bi-enemy-pic { width: calc(var(--zoom-btn) * .8); height: calc(var(--zoom-btn) * .8); }
.bi-enemy-pic img { width: 80%; height: 80%; }
.bi-enemy-name { font-size: clamp(11px, 3.2vw, 15px); } .bi-enemy-lv { font-size: clamp(9px, 2.6vw, 12px); }
.bi-enemy-bar { height: clamp(7px, 2.2vw, 11px); } .bi-enemy-left { font-size: clamp(14px, 4vw, 20px); }
.bi-quest, form.bi-quest { max-width: 74%; min-width: 240px; padding: 6px 18px 7px; } .bi-quest-btn { padding: 6px 18px 7px; }
.bq-head { font-size: clamp(11px, 3.2vw, 15px); } .bq-line { font-size: clamp(11px, 3.4vw, 16px); } .bq-sub { font-size: clamp(9.5px, 2.8vw, 13px); }
.bi-rates span, .rates.bi-rates span { font-size: clamp(9px, 2.6vw, 12px); }
.bi-stage-line { font-size: clamp(10px, 3vw, 14px); } .bi-stage-n { font-size: clamp(14px, 4vw, 20px); }
.bi-widgets { transform: scale(clamp(1, 1.5vw, 1.25)); transform-origin: top right; }
.bi-stagecall b { font-size: clamp(26px, 8vw, 40px); }
.afx-band-1 { font-size: clamp(22px, 6vw, 32px) !important; } .afx-band-2 { font-size: clamp(14px, 4vw, 20px) !important; }
@media (max-width: 430px) { .scene.blade .spot-hero { left: 30%; } .scene.blade .mob-p0 { left: 60%; } .arena-fx { left: 30%; } }
/* seen at real size (headless shots, 18 Sep 2026): the enemy bar ran under the race widget and the
   monster's tag under the right rail. The bar stops short of the widget; the pair sits a step left. */
.bi-enemy { left: 8px; right: auto; transform: none; width: calc(100% - 118px); max-width: 360px; }
.bi-enemy-hit { animation: enemy-bar-hit2 .3s ease-out; }
@keyframes enemy-bar-hit2 { 30% { transform: scale(1.04); filter: brightness(1.4); } }
.scene.blade .spot-hero { left: 26%; }
.scene.blade .mob-p0 { left: 56%; }
.arena-fx { left: 26%; }
@media (max-width: 430px) { .scene.blade .spot-hero { left: 22%; } .scene.blade .mob-p0 { left: 54%; } .arena-fx { left: 22%; } .bi-enemy { width: calc(100% - 108px); } }
/* THE HERO IN THE MIDDLE, STILL (18 Sep 2026): he stands centre, the enemy comes to him and stands to his
   right; his attack is his own pictures (frames.js), so no dash, no ghosts. The 340x320 canvas of those
   pictures is wider than tall, so the box is sized to it. */
.scene.blade .arena .spot-hero { left: 50%; transform: translate(-50%, -40%); }
.scene.blade .arena .mob-p0 { left: calc(50% + var(--zoom-hero) * .55); }
.arena-fx { left: 50%; }
.scene.blade .arena .spot-hero .sprite-img.sprite-hero { width: calc(var(--zoom-hero) * 1.06); height: var(--zoom-hero); object-fit: contain; object-position: center bottom; }
.scene.blade .spot-hero.rush .hero-idle, .scene.blade .spot-hero:has(.ride-mount).rush .hero-idle, .scene.blade .spot-hero:has(.ride-wings).rush .hero-idle { animation-name: fx-fly; }
.afx.afx-ghost { display: none; }
@media (max-width: 430px) { .scene.blade .arena .spot-hero { left: 46%; } .scene.blade .arena .mob-p0 { left: calc(46% + var(--zoom-hero) * .5); } .arena-fx { left: 46%; } }
.scene.blade .arena .spot-hero { left: 44%; }
.scene.blade .arena .mob-p0 { left: calc(44% + var(--zoom-hero) * .36); }
.arena-fx { left: 44%; }
.scene.blade .sprite-img.sprite-mon { width: calc(var(--zoom-mon) * .88); height: calc(var(--zoom-mon) * .88); }
@media (max-width: 430px) { .scene.blade .arena .spot-hero { left: 42%; } .scene.blade .arena .mob-p0 { left: calc(42% + var(--zoom-hero) * .34); } .arena-fx { left: 42%; } }
.page-game .scene.blade .edge:not(.edge-right) { top: 116px; }
.bi-enemy { top: 54px; }
/* TRAVEL (travel.js, 18 Sep 2026): the pack stands on the field again, smaller; the hero glides between
   them in .6s and his afterimages trail; the dash on each swing is back on */
.scene.blade.travel .mob-extra.mob-stand { display: block !important; opacity: .95; }
.scene.blade.travel .mob-extra .sprite-mon { width: calc(var(--zoom-mon) * .7); height: calc(var(--zoom-mon) * .7); }
.scene.blade.travel .spot-hero { transition: left .6s cubic-bezier(.3, .7, .3, 1), top .6s cubic-bezier(.3, .7, .3, 1); }
.scene.blade.travel .spot-hero.no-glide { transition: none; }
.scene.blade.travel .spot-hero.flying .ride-wings { animation-duration: .5s; }
.scene.blade.travel .spot-hero.flying .hero-idle { animation: fly-lean .6s ease-in-out; }
@keyframes fly-lean { 30% { transform: translateX(-50%) rotate(-8deg) translateY(-14px); } 70% { transform: translateX(-50%) rotate(-6deg) translateY(-16px); } 100% { transform: translateX(-50%); } }
.afx.afx-trail { display: block; width: auto; height: auto; margin: 0; border-radius: 0; opacity: .38; filter: brightness(1.4) saturate(.6); animation: trail-fade .38s ease-out forwards; pointer-events: none; }
@keyframes trail-fade { to { opacity: 0; transform: scale(.94); } }
.scene.blade .mob-p1 { left: 8%; top: 46%; } .scene.blade .mob-p2 { left: 40%; top: 10%; } .scene.blade .mob-p4 { left: 58%; top: 70%; }
.scene.blade.travel .spot-mon.mob-left { transform: scaleX(-1); }
.scene.blade.travel .spot-mon.mob-left .tag { transform: scaleX(-1); }
.scene.blade.travel .spot-mon.mob-left.mob-enter { animation: none; }
.scene.blade .spot-hero.face-left .tag { transform: scale(1.25) scaleX(-1); }
.scene.blade .mob-p1 { left: 15%; top: 44%; }
.scene.blade.travel .spot-mon.mob-left .tag { transform: scale(1.25) scaleX(-1); }
.scene.blade .spot-hero .tag, .scene.blade .spot-hero:has(.ride-mount) .tag { top: -26px; }
.scene.blade .mob-p4 { left: 50%; top: 64%; }
/* 18 Sep 2026, "the buttons are the right size, but i feel the hero and enemys are too big": a step down.
   The hero about 140px on his window (110 on a phone), the target smaller than him, the pack smaller still. */
:root { --zoom-hero: clamp(104px, 26vw, 140px); --zoom-mon: clamp(96px, 24vw, 128px); }
.scene.blade.travel .mob-extra .sprite-mon { width: calc(var(--zoom-mon) * .78); height: calc(var(--zoom-mon) * .78); }
/* the centring rule above out-ranked the facing flip, so the tag mirrored while the hero did not turn */
.scene.blade .arena .spot-hero.face-left { transform: translate(-50%, -40%) scaleX(-1); }
/* a pet with frames is drawn on a wider canvas than its still (18 Sep 2026); keep its box */
.scene.blade .ride-pet.pet-frames { object-fit: contain; object-position: center bottom; }
/* the wings sit on the hero's back: his picture is a wide canvas with the body at the left, so the wings anchor there */
.scene.blade .spot-hero .ride-wings { left: 40%; }
.scene.blade .spot-hero.face-left .ride-wings { transform: translateX(-50%); }
/* TEXT WITH SOME STYLE (18 Sep 2026, "the text is dull and boring everywhere, it needs some style").
   Cinzel was never loaded from anywhere, so every heading fell back to Georgia; now it is fetched, and
   Crimson Pro carries the body. Headings gold and engraved, names bright, numbers tabular, small print
   readable rather than grey. */
:root { --serif: "Crimson Pro", "Palatino Linotype", Palatino, Georgia, serif; }
body { font-family: var(--serif); font-size: 17px; }
.card-head h2, .sheet .card-head h2, h1, h2, h3, .menu-h, .qh-title { font-family: Cinzel, Georgia, serif; font-weight: 800; letter-spacing: .04em;
  background: linear-gradient(180deg, #fff1c2 0%, #ffd070 45%, #c9a24a 100%); -webkit-background-clip: text; background-clip: text; color: transparent;
  filter: drop-shadow(0 1px 0 rgba(0,0,0,.9)) drop-shadow(0 0 6px rgba(255,200,90,.25)); }
.card-head h2 .ico, .card-head h2 .ui-pic, .card-head h2 img, .card-head h2 .avatar-ring { filter: none; }
.card-head h2 { font-size: 19px; }
.row-info strong, .card strong.race-rung, .qrow strong, .gw-name { font-family: Cinzel, Georgia, serif; font-weight: 700; font-size: 14.5px; color: #fff4d6; letter-spacing: .02em; text-shadow: 0 1px 2px #000; }
.card .small, .sheet .small { color: #d9d0bb; font-size: 13px; line-height: 1.35; font-variant-numeric: tabular-nums; }
.card .muted, .sheet .muted { color: #a9a08c; }
.card p, .sheet p { font-size: 14.5px; line-height: 1.45; }
.card .small b, .sheet .small b { color: #ffd070; font-weight: 700; }
.chip, .pill { font-family: Cinzel, Georgia, serif; font-size: 10px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; }
.btn { font-family: Cinzel, Georgia, serif; font-weight: 700; letter-spacing: .05em; }
.warn { color: #ff9a9a; }
.hud-name, .who-line, .ticker { font-family: Cinzel, Georgia, serif; }
/* the rank letters read as stamps */
.badge-rank, .arms-badge, .race-rank { font-family: Cinzel, Georgia, serif; font-weight: 900; letter-spacing: .04em; }
/* the chat row shows three lines, small, until it is tapped (18 Sep 2026) */
.chatfeed { font-size: 9.5px; line-height: 1.2; gap: 0; }
.chatrow { min-height: 40px; }
.feed-line { font-size: 9.5px; }
.feed-tag { font-size: 8.5px; }
/* THE HUB TABS (18 Sep 2026): the group a page belongs to, as a tab strip under the HUD; the one you are on
   is raised and gold, the rest dark; scrolls sideways when the group is long */
.hubtabs { display: flex; align-items: stretch; gap: 0; background: linear-gradient(180deg, #141a3c, #0c1028); border-bottom: 2px solid var(--frame-dark); box-shadow: inset 0 -6px 12px rgba(0,0,0,.35); }
.hub-name { flex: none; writing-mode: vertical-rl; transform: rotate(180deg); font-family: Cinzel, Georgia, serif; font-size: 9px; font-weight: 800; letter-spacing: .18em; text-transform: uppercase; color: var(--frame); padding: 6px 2px; border-left: 1px solid var(--frame-dark); background: rgba(0,0,0,.25); }
.hub-row { flex: 1; display: flex; gap: 2px; overflow-x: auto; scrollbar-width: none; padding: 6px 6px 0; }
.hub-row::-webkit-scrollbar { display: none; }
.hubtab { flex: 1 0 auto; min-width: 62px; display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 4px 8px 6px; border-radius: 10px 10px 0 0; text-decoration: none; color: var(--ivory-muted); background: linear-gradient(180deg, rgba(42,52,104,.5), rgba(11,14,34,.6)); border: 1px solid rgba(201,162,74,.25); border-bottom: 0; position: relative; }
.hubtab .hub-ico { position: relative; width: 30px; height: 30px; display: flex; align-items: center; justify-content: center; }
.hubtab .hub-ico .ui-pic, .hubtab .hub-ico img { width: 26px; height: 26px; object-fit: contain; filter: saturate(.6) brightness(.85); }
.hubtab .hub-ico .ico { width: 22px; height: 22px; }
.hubtab .hub-label { font-family: Cinzel, Georgia, serif; font-size: 9px; font-weight: 700; letter-spacing: .04em; white-space: nowrap; }
.hubtab.on { color: #1a1200; background: linear-gradient(180deg, #ffe08a, #c9a24a 70%, #a9822e); border-color: #fff1c2; transform: translateY(-2px); box-shadow: 0 -2px 10px rgba(255,220,120,.45); }
.hubtab.on .hub-ico .ui-pic, .hubtab.on .hub-ico img { filter: none; }
.hubtab.on .hub-label { color: #1a1200; text-shadow: none; }
.hubtab .badge-red { position: absolute; top: -4px; right: -6px; transform: scale(.85); }
.chatrow { min-height: 46px; } .chatfeed { line-height: 1.25; padding: 3px 6px; }
/* POP-UPS WITH NO BOX (18 Sep 2026, "i want all click actions to pop up more faded, no back box the text is in,
   more stylish to wow a player and in a better position so its not obscuring things"): a floating callout, a
   soft dark haze behind for reading, the word DONE or NOT YET engraved in gold, the message in outlined ivory,
   a thin ornament line, the picture glowing beside it. It rises in, hangs, and fades; it never takes a tap. */
.flash, .flash.flash-live {
  top: 27%; width: min(92%, 440px); padding: 6px 12px 10px; gap: 10px; cursor: default; pointer-events: none;
  background: radial-gradient(ellipse at 50% 50%, rgba(8,10,28,.62) 0%, rgba(8,10,28,.42) 55%, rgba(8,10,28,0) 100%);
  border: 0; box-shadow: none; border-radius: 40px; backdrop-filter: blur(1.5px); -webkit-backdrop-filter: blur(1.5px);
  animation: pop-rise .42s cubic-bezier(.2,.9,.3,1.1), pop-fade .6s ease-in 2.8s forwards;
}
.flash::before, .flash::after { display: none; }
.flash-pic { width: 58px; height: 58px; background: none; border: 0; box-shadow: none; filter: drop-shadow(0 0 10px rgba(255,220,120,.85)) drop-shadow(0 4px 6px rgba(0,0,0,.8)); animation: pop-pic .5s cubic-bezier(.2,.9,.3,1.3); }
.flash-pic img { width: 52px; height: 52px; }
.flash-body { gap: 1px; }
.flash-title { font-family: Cinzel, Georgia, serif; font-size: 20px; font-weight: 900; letter-spacing: .12em; line-height: 1.1;
  background: linear-gradient(180deg, #fff6d0 0%, #ffd070 45%, #c9a24a 100%); -webkit-background-clip: text; background-clip: text; color: transparent;
  filter: drop-shadow(0 1px 0 rgba(0,0,0,1)) drop-shadow(0 0 8px rgba(255,200,90,.55)); }
.flash-title::after { content: ""; display: block; height: 1px; margin-top: 2px; background: linear-gradient(90deg, rgba(255,214,90,.9), rgba(255,214,90,0) 90%); }
.flash-text { font-size: 14px; font-weight: 600; color: #fff7e6; text-shadow: 0 0 2px #000, 0 1px 2px #000, 0 0 6px rgba(0,0,0,.9), 0 0 12px rgba(0,0,0,.6); line-height: 1.3; }
.flash-ok .flash-title, .flash-bad .flash-title { color: transparent; }
.flash-bad .flash-title { background: linear-gradient(180deg, #ffd0c8 0%, #ff8a7a 45%, #c0392b 100%); -webkit-background-clip: text; background-clip: text; }
.flash-bad .flash-pic { animation: toast-shake .5s ease-out; filter: drop-shadow(0 0 10px rgba(255,90,70,.85)) drop-shadow(0 4px 6px rgba(0,0,0,.8)); }
.flash-ok .flash-pic, .flash-bad .flash-pic { border: 0; box-shadow: none; }
@keyframes pop-rise { from { opacity: 0; transform: translate(-50%, -30%) scale(.86); } to { opacity: 1; transform: translate(-50%, -50%) scale(1); } }
@keyframes pop-fade { to { opacity: 0; transform: translate(-50%, -70%) scale(.96); } }
@keyframes pop-pic { from { transform: scale(.4) rotate(-12deg); } 60% { transform: scale(1.12) rotate(3deg); } to { transform: scale(1) rotate(0); } }
.page-game .flash, .page-game .flash.flash-live { top: 30%; }
body.pref-nomotion .flash { animation: none; }
/* THE BOTTOM OF THE FIGHT LIKE ARIELIA (18 Sep 2026): the Stage button big at the bottom left with Auto boss
   under it, the story band in the middle, the rails end above; seven tabs on the bar */
.scene.blade .bi-stack { position: absolute; left: 8px; right: auto; bottom: 30px; z-index: 7; gap: 3px; align-items: center; }
.scene.blade .bi-stack .bi-stage-btn { width: calc(var(--zoom-btn) * 1.3); height: calc(var(--zoom-btn) * 1.3); border-radius: 50%; }
.scene.blade .bi-stack .bi-stage-btn .ui-pic, .scene.blade .bi-stack .bi-stage-btn img { width: 60%; height: 60%; }
.scene.blade .bi-stack .bi-stage-btn span { font-size: clamp(8px, 2.4vw, 11px); }
.scene.blade .bi-stack .auto-btn { width: auto; height: 22px; padding: 0 10px; border-radius: 11px; flex-direction: row; gap: 4px; }
.scene.blade .bi-stack .auto-btn .ico { width: 12px; height: 12px; }
.scene.blade .bi-stack .auto-btn span { font-size: 8.5px; white-space: nowrap; }
.scene.blade .bi-stack .bi-auto { width: auto; height: 20px; padding: 0 10px; border-radius: 10px; font-size: 9px; }
.bi-quest, form.bi-quest { max-width: 58%; min-width: 200px; bottom: 36px; }
@media (max-width: 430px) { .bi-quest, form.bi-quest { max-width: 56%; min-width: 180px; left: 54%; } }
.navbar .bar-btn { min-width: 48px; }
.bar-label { font-size: clamp(8px, 2.3vw, 11px); font-family: Cinzel, Georgia, serif; font-variant: normal; letter-spacing: .02em; }
@media (max-width: 430px) { .bar-ico { transform: scale(.9); } }
/* the bottom cluster's box sits at the left now (the stack is its only child drawn) */
.scene.blade .bi-bottom { left: 6px; right: auto; bottom: 30px; }
.scene.blade .bi-stack { position: static; }
/* "this looks abit clustered at the top now" (18 Sep 2026): the race widget back to its own size, the enemy
   bar slimmer and lower in tone, the stage line quieter, so the top reads as two thin rows */
.bi-widgets { transform: none; }
.bi-enemy { top: 52px; padding: 2px 10px 3px 4px; gap: 6px; width: calc(100% - 112px); max-width: 340px; border-radius: 18px; background: linear-gradient(90deg, rgba(11,14,34,.86), rgba(11,14,34,.6)); }
.bi-enemy-pic { width: 30px; height: 30px; }
.bi-enemy-name { font-size: clamp(11px, 3vw, 13px); } .bi-enemy-lv { font-size: 9.5px; }
.bi-enemy-bar { height: 6px; } .bi-enemy-left { font-size: clamp(12px, 3.4vw, 16px); }
.bi-stage-line { font-size: clamp(10px, 2.8vw, 12px); } .bi-stage-n { font-size: clamp(13px, 3.6vw, 17px); }
.bi-stage .bi-bar { height: 5px; }
.page-game .scene.blade .edge:not(.edge-right) { top: 104px; }
/* THE STORY BAND LIKE THEIR QUEST BAND (18 Sep 2026, "mine pic 1 dosent look like pic 2"): no box, a soft dark
   band that fades at both ends, the heading in gold between swirls, the task in white with the count in red,
   the second line under it */
.bi-quest, form.bi-quest, .bi-quest-btn { border: 0 !important; box-shadow: none !important; border-radius: 0 !important;
  background: linear-gradient(90deg, rgba(20,10,30,0) 0%, rgba(20,10,30,.72) 18%, rgba(20,10,30,.78) 82%, rgba(20,10,30,0) 100%) !important;
  animation: none; padding: 5px 26px 7px !important; max-width: 66%; min-width: 230px; }
.bq-head { font-size: clamp(14px, 4vw, 18px); letter-spacing: .06em; background: linear-gradient(180deg, #fff1c2, #ffd070 50%, #c9a24a); -webkit-background-clip: text; background-clip: text; color: transparent; filter: drop-shadow(0 1px 1px #000); }
.bq-head::before, .bq-head::after { content: "\2767"; color: #ffd070; font-size: 13px; margin: 0 8px; opacity: 1; -webkit-text-fill-color: #ffd070; }
.bq-line { font-size: clamp(12px, 3.6vw, 16px); color: #fff; font-weight: 600; text-shadow: 0 1px 2px #000, 0 0 6px rgba(0,0,0,.8); }
.bq-line b { color: #ff6b5a; font-weight: 800; }
.bq-sub { font-size: clamp(11px, 3.2vw, 14px); color: #f3e9d2; text-shadow: 0 1px 2px #000; }
.bi-quest-btn .bq-sub, .bi-quest-btn .bq-line b { color: #ffe08a; }
/* the Menu button lives on the left rail now, above Claim ("move menu to the left panel") */
.page-game .scene.blade .bi-top .bi-round[data-sheet="grid"] { position: absolute; left: 4px; top: 50px; z-index: 8; }
.page-game .scene.blade .edge:not(.edge-right) { top: 112px; }
.bi-enemy { left: 62px; width: calc(100% - 172px); }
@media (max-width: 430px) { .bi-enemy { left: 58px; width: calc(100% - 160px); } }
/* the boss beats him: the bar says so (18 Sep 2026) */
.bi-enemy { flex-wrap: wrap; }
.bi-enemy-hard { display: none; flex-basis: 100%; font-size: 10px; color: #ff9a9a; line-height: 1.2; padding: 1px 2px 0 40px; }
.bi-enemy-hardmode .bi-enemy-hard { display: block; }
.bi-enemy-left.bi-enemy-toohard { color: #ff6b5a; font-size: clamp(9px, 2.6vw, 12px); letter-spacing: .04em; animation: none; }
.bi-enemy-hardmode { border-color: rgba(255,107,90,.5); }
.scene.blade .ride-mount.mount-frames { object-fit: contain; object-position: center bottom; }
.bar-label { font-size: clamp(7.5px, 2.05vw, 11px); letter-spacing: 0; }
/* THE GATE, the login page (18 Sep 2026): one card, two tabs on radio inputs, no script */
.gate-login { max-width: 420px; margin: 0 auto; }
.auth-one { position: relative; }
.gate-radio { position: absolute; opacity: 0; pointer-events: none; }
.gate-tabs { display: flex; gap: 4px; margin: 0 6px -2px; position: relative; z-index: 2; }
.gate-tab { flex: 1; display: flex; align-items: center; justify-content: center; gap: 8px; padding: 10px 8px 12px; border-radius: 12px 12px 0 0; cursor: pointer; user-select: none;
  font-family: Cinzel, Georgia, serif; font-weight: 800; font-size: 14px; letter-spacing: .06em; text-transform: uppercase; color: var(--ivory-muted);
  background: linear-gradient(180deg, rgba(42,52,104,.6), rgba(11,14,34,.7)); border: 1px solid var(--frame-dark); border-bottom: 0; }
.gate-tab .ico { width: 18px; height: 18px; }
#tab-in:checked ~ .gate-tabs .gate-tab-in, #tab-new:checked ~ .gate-tabs .gate-tab-new { color: #1a1200; background: linear-gradient(180deg, #ffe08a, #c9a24a 70%, #a9822e); border-color: #fff1c2; box-shadow: 0 -2px 12px rgba(255,220,120,.45); transform: translateY(-3px); }
.gate-pane { display: none; }
#tab-in:checked ~ .gate-pane-in, #tab-new:checked ~ .gate-pane-new { display: block; animation: pane-in .3s ease-out; }
@keyframes pane-in { from { opacity: 0; transform: translateY(6px); } }
.gate-pane .stack label { font-family: Cinzel, Georgia, serif; font-size: 12px; letter-spacing: .04em; color: #ffd070; }
.gate-pane .stack input { font-family: var(--serif); font-size: 16px; padding: 10px 12px; border-radius: 10px; border: 1px solid var(--frame-dark); background: rgba(0,0,0,.35); color: var(--ivory); box-shadow: inset 0 2px 6px rgba(0,0,0,.5); }
.gate-pane .stack input:focus { outline: none; border-color: var(--frame-light); box-shadow: inset 0 2px 6px rgba(0,0,0,.5), 0 0 0 3px rgba(255,214,90,.25); }
.btn-gate { font-size: 15px; padding: 12px; margin-top: 4px; letter-spacing: .08em; box-shadow: 0 0 18px rgba(255,214,90,.35); }
.gate-foot { text-align: center; margin: 10px 0 0; color: var(--ivory-muted); }
/* the sign up side when the Creator has closed the door (22 Sep 2026) */
.gate-shut { text-align: center; margin: 18px 0 6px; font: 700 15px/1.5 Cinzel, serif; color: var(--frame-light); }
.gate-link { color: #ffd070; text-decoration: underline; cursor: pointer; }
.gate-lore { text-align: center; font-style: italic; color: var(--ivory-muted); font-size: 13px; margin: 14px 12px 0; text-shadow: 0 1px 2px #000; }
.title-screen .card { background: linear-gradient(180deg, rgba(20,26,60,.94), rgba(11,14,34,.96)); color: var(--ivory); border-color: var(--frame); }
.title-screen .card-head h2 { color: transparent; }
.title-screen .tagline { color: #e9dcc0; text-shadow: 0 1px 3px #000; font-size: 16px; }
.name-box { max-width: 420px; margin: 0 auto; }
/* THE TOP PANEL ON A PHONE (18 Sep 2026, "the top panel needs to be smaller and transparent it covers all of
   the screen on the mobile screen"): on the fight page under 600px wide the HUD floats over the top of the
   scene as a see-through band a third of its old height, and everything the scene keeps at its top
   (stage bar, enemy bar, widget, Menu, rails, the arena itself) moves down by the same amount. */
@media (max-width: 600px) {
  .page-game .hud2 { position: absolute; left: 0; right: 0; top: 0; z-index: 9; padding: calc(1px + env(safe-area-inset-top)) 0 6px; border: 0;
    background: linear-gradient(180deg, rgba(8,10,30,.88) 0%, rgba(8,10,30,.7) 60%, rgba(8,10,30,.35) 90%, rgba(8,10,30,0) 100%); box-shadow: none; }
  .page-game .hud2 .strip { min-height: 18px; padding: 1px 6px; font-size: 10px; background: rgba(0,0,0,.35); border-bottom: 1px solid rgba(201,162,74,.25); }
  .page-game .hud2 .hud-main { gap: 6px; padding: 2px 6px 0; align-items: center; }
  .page-game .hud2 .hud-avatar, .page-game .hud2 .avatar-ring { width: 40px; height: 40px; }
  .page-game .hud2 .avatar-ring .emblem, .page-game .hud2 .avatar-ring .ico, .page-game .hud2 .avatar-ring img { width: 34px; height: 34px; }
  .page-game .hud2 .lvl-badge { transform: scale(.8); transform-origin: bottom right; }
  .page-game .hud2 .hud-cpline { gap: 6px; }
  .page-game .hud2 .cp-big { font-size: 12px; } .page-game .hud2 .cp-big b { font-size: 15px; }
  .page-game .hud2 .hud-vip { transform: scale(.72); transform-origin: left center; margin-right: -12px; }
  .page-game .hud2 .hud-relic .ui-pic, .page-game .hud2 .hud-relic img, .page-game .hud2 .hud-wings .ui-pic, .page-game .hud2 .hud-wings img { width: 22px; height: 22px; }
  .page-game .hud2 .hud-pills { gap: 4px; margin-top: 1px; }
  .page-game .hud2 .pill2 { font-size: 9.5px; padding: 1px 8px; min-height: 18px; line-height: 16px; }
  .page-game .hud2 .pill2 .ui-pic, .page-game .hud2 .pill2 img { width: 12px; height: 12px; }
  .page-game .hud2 .bar-mini { height: 4px; margin-top: 2px; max-width: 110px; }
  .page-game .hud2 .hud-side { font-size: 9px; gap: 0; }
  .page-game .hud2 .hud-name-tag { display: none; }
  /* the scene keeps its top under the band */
  .page-game .scene.blade { --hud: 96px; }
  .page-game .scene.blade .bi-top { top: calc(4px + var(--hud)); }
  .page-game .scene.blade .bi-top .bi-round[data-sheet="grid"] { top: calc(50px + var(--hud)); }
  .page-game .scene.blade .bi-enemy { top: calc(52px + var(--hud)); }
  .page-game .scene.blade .bi-widgets { top: calc(50px + var(--hud)); }
  .page-game .scene.blade .edge:not(.edge-right) { top: calc(112px + var(--hud)); }
  .page-game .scene.blade .edge-right { top: calc(141px + var(--hud)); }
  .page-game .scene.blade .arena { top: calc(130px + var(--hud)); }
  .page-game .scene.blade .bi-double { top: calc(84px + var(--hud)); }
  .page-game .scene.blade .bi-stagecall { top: calc(34% + var(--hud) / 2); }
}
@media (max-width: 600px) {
  /* the Menu button sits inside the stage bar's box, which has moved already; measure from it, not the scene */
  .page-game .scene.blade .bi-top .bi-round[data-sheet="grid"] { top: 44px; }
  .page-game .scene.blade .edge:not(.edge-right) { top: calc(104px + var(--hud)); }
}
/* "i changed my mind, i dont want it transparent" (18 Sep 2026): the compact phone HUD stays, but solid and
   in the flow above the fight again, so nothing has to move down under it; the Menu sits clear of Claim */
@media (max-width: 600px) {
  .page-game .hud2 { position: relative; background: radial-gradient(ellipse at 50% -20%, rgba(120,150,255,.25), transparent 60%), linear-gradient(180deg, #232a55 0%, #151a3a 60%, #0e1128 100%); border-bottom: 1px solid var(--frame-dark); padding-bottom: 4px; }
  .page-game .scene.blade { --hud: 0px; }
  .page-game .scene.blade .edge:not(.edge-right) { top: 118px; }
  .page-game .scene.blade .bi-top .bi-round[data-sheet="grid"] { top: 46px; }
}
/* the rails a size down and the Menu in line with them (18 Sep 2026) */
@media (max-width: 600px) {
  :root { --zoom-btn: clamp(38px, 10vw, 46px); }
  .page-game .scene.blade .bi-top .bi-round[data-sheet="grid"] { left: 4px; top: 42px; width: var(--zoom-btn); height: var(--zoom-btn); }
  .page-game .scene.blade .edge:not(.edge-right) { left: 4px; top: 100px; gap: 6px; }
  .page-game .scene.blade .edge-right { right: 4px; }
  .bi-round span { font-size: 6.5px; }
}
/* "this text on the game black and gold dosent look well" (18 Sep 2026): the engraved gradient headings read
   muddy on a phone. Headings are plain bright gold with one clean shadow now. */
.card-head h2, .sheet .card-head h2, h1, h2, h3, .menu-h, .qh-title { background: none; -webkit-background-clip: initial; background-clip: initial; color: #ffd66a; filter: none; text-shadow: 0 1px 0 #3a2a05, 0 2px 4px rgba(0,0,0,.8); }
.flash-title { background: none; -webkit-background-clip: initial; background-clip: initial; color: #ffd66a; filter: none; text-shadow: 0 1px 0 #3a2a05, 0 2px 6px rgba(0,0,0,.9); }
.flash-bad .flash-title { color: #ff8a7a; background: none; }
.flash-ok .flash-title, .flash-bad .flash-title { -webkit-text-fill-color: initial; }
.bq-head { background: none; -webkit-background-clip: initial; background-clip: initial; color: #ffd66a; filter: none; text-shadow: 0 1px 0 #3a2a05, 0 2px 4px rgba(0,0,0,.8); }
.bq-head::before, .bq-head::after { -webkit-text-fill-color: #ffd66a; }
/* TOP PANEL, LOOK 4: GLASS OVER THE FIGHT (18 Sep 2026, "i like 4 build it"). On the fight page at every width
   the HUD is the compact band floating over the top of the scene, dark glass with a blur and a gold hairline
   at its foot; the scene's own top items sit under it. Other pages keep the solid HUD. */
.page-game .hud2 { position: absolute; left: 0; right: 0; top: 0; z-index: 9; padding: calc(1px + env(safe-area-inset-top)) 0 5px; border: 0; border-bottom: 1px solid rgba(255,214,90,.55);
  background: linear-gradient(180deg, rgba(8,10,30,.86) 0%, rgba(8,10,30,.62) 100%); backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px); box-shadow: 0 2px 10px rgba(0,0,0,.45); }
.page-game .hud2 .strip { min-height: 18px; padding: 1px 6px; font-size: 10px; background: rgba(0,0,0,.35); border-bottom: 1px solid rgba(201,162,74,.25); }
.page-game .hud2 .hud-main { gap: 6px; padding: 2px 6px 0; align-items: center; }
.page-game .hud2 .hud-avatar, .page-game .hud2 .avatar-ring { width: 44px; height: 44px; }
.page-game .hud2 .avatar-ring .emblem, .page-game .hud2 .avatar-ring .ico, .page-game .hud2 .avatar-ring img { width: 38px; height: 38px; }
.page-game .hud2 .lvl-badge { transform: scale(.8); transform-origin: bottom right; }
.page-game .hud2 .hud-cpline { gap: 6px; }
.page-game .hud2 .cp-big { font-size: 12px; } .page-game .hud2 .cp-big b { font-size: 16px; }
.page-game .hud2 .hud-vip { transform: scale(.72); transform-origin: left center; margin-right: -12px; }
.page-game .hud2 .hud-relic .ui-pic, .page-game .hud2 .hud-relic img, .page-game .hud2 .hud-wings .ui-pic, .page-game .hud2 .hud-wings img { width: 22px; height: 22px; }
.page-game .hud2 .hud-pills { gap: 4px; margin-top: 1px; }
.page-game .hud2 .pill2 { font-size: 9.5px; padding: 1px 8px; min-height: 18px; line-height: 16px; }
.page-game .hud2 .pill2 .ui-pic, .page-game .hud2 .pill2 img { width: 12px; height: 12px; }
.page-game .hud2 .bar-mini { height: 4px; margin-top: 2px; max-width: 110px; }
.page-game .hud2 .hud-side { font-size: 9px; gap: 0; }
.page-game .hud2 .hud-name-tag { display: none; }
.page-game .scene.blade { --hud: 98px; }
.page-game .scene.blade .bi-top { top: calc(4px + var(--hud)); }
.page-game .scene.blade .bi-top .bi-round[data-sheet="grid"] { top: 42px; }
.page-game .scene.blade .bi-enemy { top: calc(52px + var(--hud)); }
.page-game .scene.blade .bi-widgets { top: calc(50px + var(--hud)); }
.page-game .scene.blade .edge:not(.edge-right) { top: calc(100px + var(--hud)); }
.page-game .scene.blade .edge-right { top: calc(141px + var(--hud)); }
.page-game .scene.blade .arena { top: calc(130px + var(--hud)); }
.page-game .scene.blade .bi-double { top: calc(84px + var(--hud)); }
.page-game .scene.blade .bi-stagecall { top: calc(34% + var(--hud) / 2); }
@media (max-width: 600px) { .page-game .hud2 { position: absolute; background: linear-gradient(180deg, rgba(8,10,30,.86) 0%, rgba(8,10,30,.62) 100%); border-bottom: 1px solid rgba(255,214,90,.55); } .page-game .scene.blade { --hud: 96px; } .page-game .scene.blade .edge:not(.edge-right) { top: calc(100px + var(--hud)); } }
.page-game .scene.blade { --hud: 118px; }
@media (max-width: 600px) { .page-game .scene.blade { --hud: 116px; } }
/* the glass band tidied (18 Sep 2026, "make the hero picture bigger, stop the red dot hiding under it, move the
   icons over and inline with each other"): a 60px portrait with the level badge on its rim, CP and the badges on
   one centred line with even gaps, the pills under them on the same left edge, the rates centred on the right */
.page-game .hud2 .hud-main { gap: 10px; padding: 3px 8px 0; align-items: center; }
.page-game .hud2 .hud-avatar, .page-game .hud2 .avatar-ring { width: 60px; height: 60px; overflow: visible; }
.page-game .hud2 .avatar-ring { overflow: hidden; }
.page-game .hud2 .avatar-ring .emblem, .page-game .hud2 .avatar-ring .ico, .page-game .hud2 .avatar-ring img { width: 54px; height: 54px; }
.page-game .hud2 .lvl-badge { transform: none; right: -2px; bottom: -2px; min-width: 22px; height: 22px; line-height: 20px; font-size: 11px; z-index: 3; box-shadow: 0 0 0 2px #0b0e22; }
.page-game .hud2 .hud-mid { display: flex; flex-direction: column; gap: 4px; }
.page-game .hud2 .hud-cpline { display: flex; align-items: center; gap: 10px; height: 30px; }
.page-game .hud2 .cp-big { font-size: 13px; line-height: 1; } .page-game .hud2 .cp-big b { font-size: 18px; }
.page-game .hud2 .hud-vip { transform: none; margin: 0; width: 34px; height: 28px; }
.page-game .hud2 .hud-vip.vip-pic { width: 34px; height: 30px; }
.page-game .hud2 .hud-vip.vip-pic img { width: 34px; height: 30px; object-fit: contain; }
.page-game .hud2 .hud-vip.vip-pic .vip-n { font-size: 12px; } .page-game .hud2 .hud-vip.vip-pic .vip-t { font-size: 5px; }
.page-game .hud2 .hud-relic, .page-game .hud2 .hud-wings { display: inline-flex; align-items: center; height: 28px; }
.page-game .hud2 .hud-relic .ui-pic, .page-game .hud2 .hud-relic img, .page-game .hud2 .hud-wings .ui-pic, .page-game .hud2 .hud-wings img { width: 26px; height: 26px; }
.page-game .hud2 .hud-pills { gap: 5px; margin: 0; }
.page-game .hud2 .pill2 { font-size: 10px; padding: 1px 9px; min-height: 19px; line-height: 17px; }
.page-game .hud2 .bar-mini { height: 4px; margin: 1px 0 0; max-width: 120px; }
.page-game .hud2 .hud-side { font-size: 9.5px; gap: 1px; align-self: center; line-height: 1.3; }
.page-game .scene.blade { --hud: 124px; }
@media (max-width: 600px) { .page-game .scene.blade { --hud: 122px; } }
/* the gap under the band closed (18 Sep 2026, "still a bit of space at the top") */
.page-game .scene.blade { --hud: 106px; }
@media (max-width: 600px) { .page-game .scene.blade { --hud: 104px; } }
/* BOSS on the enemy bar is plain text, no box (18 Sep 2026) */
.bi-enemy-left, .bi-enemy-left.bi-enemy-boss, .bi-enemy-left.bi-enemy-toohard { background: none !important; border: 0 !important; padding: 0 !important; box-shadow: none !important; border-radius: 0; }
.bi-enemy-left.bi-enemy-boss { animation: boss-word 1s ease-in-out infinite; }
@keyframes boss-word { 0%, 100% { text-shadow: 0 1px 2px #000, 0 0 6px rgba(255,120,40,.5); } 50% { text-shadow: 0 1px 2px #000, 0 0 14px rgba(255,140,50,1); } }
/* SKINS THAT STAY ON (18 Sep 2026, "i just bought a look skin and its not fully working"): the tint sat on a
   display:contents wrapper and was handed to the picture by filter:inherit, which every fight animation
   (the dash, the hurt flash, the cast glow) overwrote, so the skin blinked off whenever he moved. The wrapper
   is a real box over the hero now and carries the tint itself; the pictures inside animate as they like. */
.scene.blade .spot-hero .hero-skin { display: block; position: absolute; left: 0; right: 0; top: 0; bottom: 0; z-index: 2; pointer-events: none; }
.scene.blade .spot-hero .hero-skin[class*="skin-"] .sprite-hero { filter: drop-shadow(0 6px 4px rgba(0, 0, 0, .55)); }
.scene.blade .spot-hero .hero-skin .sprite-hero { z-index: auto; }
.scene.blade .spot-hero.face-left .hero-skin { transform: none; }
/* THE COMPACT TOP BAR ON EVERY PAGE (18 Sep 2026, "the old top bar is taking over pages u open"): the hall
   pages had the old tall HUD; they get the same one-row band as the fight, solid and in the flow. */
.hud2 { padding: calc(1px + env(safe-area-inset-top)) 0 5px; }
.hud2 .strip { min-height: 18px; padding: 1px 6px; font-size: 10px; background: rgba(0,0,0,.35); border-bottom: 1px solid rgba(201,162,74,.25); }
.hud2 .hud-main { gap: 10px; padding: 3px 8px 0; align-items: center; }
.hud2 .hud-avatar, .hud2 .avatar-ring { width: 60px; height: 60px; }
.hud2 .hud-avatar { overflow: visible; } .hud2 .avatar-ring { overflow: hidden; }
.hud2 .avatar-ring .emblem, .hud2 .avatar-ring .ico, .hud2 .avatar-ring img { width: 54px; height: 54px; }
.hud2 .lvl-badge { transform: none; right: -2px; bottom: -2px; min-width: 22px; height: 22px; line-height: 20px; font-size: 11px; z-index: 3; box-shadow: 0 0 0 2px #0b0e22; }
.hud2 .hud-mid { display: flex; flex-direction: column; gap: 4px; }
.hud2 .hud-cpline { display: flex; align-items: center; gap: 10px; height: 30px; }
.hud2 .cp-big { font-size: 13px; line-height: 1; } .hud2 .cp-big b { font-size: 18px; }
.hud2 .hud-vip { transform: none; margin: 0; width: 34px; height: 28px; }
.hud2 .hud-vip.vip-pic { width: 34px; height: 30px; } .hud2 .hud-vip.vip-pic img { width: 34px; height: 30px; object-fit: contain; }
.hud2 .hud-vip.vip-pic .vip-n { font-size: 12px; } .hud2 .hud-vip.vip-pic .vip-t { font-size: 5px; }
.hud2 .hud-relic, .hud2 .hud-wings { display: inline-flex; align-items: center; height: 28px; }
.hud2 .hud-relic .ui-pic, .hud2 .hud-relic img, .hud2 .hud-wings .ui-pic, .hud2 .hud-wings img { width: 26px; height: 26px; }
.hud2 .hud-pills { gap: 5px; margin: 0; }
.hud2 .pill2 { font-size: 10px; padding: 1px 9px; min-height: 19px; line-height: 17px; }
.hud2 .pill2 .ui-pic, .hud2 .pill2 img { width: 12px; height: 12px; }
.hud2 .bar-mini { height: 4px; margin: 1px 0 0; max-width: 120px; }
.hud2 .hud-side { font-size: 9.5px; gap: 1px; align-self: center; line-height: 1.3; }
.hud2 .hud-name-tag { display: none; }
/* ============================================================================================
   THE ARIELIA PANEL ON EVERY HALL (18 Sep 2026, "carry the pale panel through the rest and the other halls,
   but have tabs all in 1"). Off the fight screen every card is a pale rounded pane with navy text; panes.js
   binds a page's cards into one book with folder tabs at its foot, one pane showing at a time, and the book
   fills the space between the hub strip and the chat row so the page itself never scrolls.
   ============================================================================================ */
.frame:not(.page-game) .card { background: linear-gradient(180deg, #eef2f9 0%, #d9e1ef 100%); border: 2px solid #a9b6cf; border-radius: 16px; box-shadow: inset 0 1px 0 #fff, 0 6px 18px rgba(0,0,0,.45); color: #1b2140; padding: 10px 10px 8px; margin: 8px 6px 12px; }
.frame:not(.page-game) .card::before, .frame:not(.page-game) .card::after { display: none; }
.frame:not(.page-game) .card .card-head { padding: 0 0 6px; margin-bottom: 8px; }
.frame:not(.page-game) .card .card-head::after { background: linear-gradient(90deg, transparent, #a9b6cf, transparent); }
.frame:not(.page-game) .card .card-head h2, .frame:not(.page-game) .card h3 { color: #1b2140; text-shadow: none; font-size: 17px; }
.frame:not(.page-game) .card p, .frame:not(.page-game) .card label, .frame:not(.page-game) .card .small, .frame:not(.page-game) .card .muted, .frame:not(.page-game) .card .hint { color: #4a5578; }
.frame:not(.page-game) .card .small b, .frame:not(.page-game) .card .gold { color: #b8860b; }
.frame:not(.page-game) .card .warn { color: #c0392b; }
.frame:not(.page-game) .card strong, .frame:not(.page-game) .card .row-info strong { color: #1b2140; text-shadow: none; }
.frame:not(.page-game) .card .row, .frame:not(.page-game) .card .qrow, .frame:not(.page-game) .card .set-choice { background: linear-gradient(180deg, #fff, #e9eef7); border: 1px solid #b8c3da; border-radius: 12px; box-shadow: 0 2px 4px rgba(0,0,0,.18); color: #1b2140; }
.frame:not(.page-game) .card .row:hover { background: #fff; }
.frame:not(.page-game) .card .chip { background: #dfe6f2; border: 1px solid #a9b6cf; color: #2b3560; }
.frame:not(.page-game) .card .chip-on, .frame:not(.page-game) .card .chip-gold { background: linear-gradient(180deg, #ffe08a, #f2b632); border-color: #b8860b; color: #3a2200; }
.frame:not(.page-game) .card .pill { background: #dfe6f2; border: 1px solid #a9b6cf; color: #2b3560; }
.frame:not(.page-game) .card .pill-red { background: #e8483a; border-color: #a3221b; color: #fff; }
.frame:not(.page-game) .card .btn { font: 800 12px Cinzel, serif; letter-spacing: .04em; color: #3a2200; border-radius: 12px; border: 1px solid #b8860b; background: linear-gradient(180deg, #ffe08a, #f2b632 60%, #d19a1f); box-shadow: 0 2px 4px rgba(0,0,0,.3), inset 0 1px 0 #fff4c2; text-shadow: none; }
.frame:not(.page-game) .card .btn-ghost, .frame:not(.page-game) .card .btn.btn-ghost { background: linear-gradient(180deg, #fff, #dfe6f2); border-color: #a9b6cf; color: #4a5578; }
.frame:not(.page-game) .card .btn:disabled { opacity: .45; }
.frame:not(.page-game) .card .bar { background: #cfd7e6; border-color: #a9b6cf; }
.frame:not(.page-game) .card a { color: #2f52a8; }
.frame:not(.page-game) .card .stat-grid div, .frame:not(.page-game) .card .qtile { background: #fff; border-color: #b8c3da; color: #1b2140; }
.frame:not(.page-game) .card dt { color: #6a7392; } .frame:not(.page-game) .card dd { color: #1b2140; }
.frame:not(.page-game) .card .race-mine { background: #fff4c2; }
.frame:not(.page-game) .card table, .frame:not(.page-game) .card td, .frame:not(.page-game) .card th { color: #1b2140; }
/* the book: fills the space, tabs at its foot, the pane scrolls inside when it must */
.has-book .content { display: flex; flex-direction: column; overflow: hidden; }
.ar-book { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; margin: 6px 6px 4px; }
.ar-book .ar-pane { flex: 1 1 auto; min-height: 0; overflow-y: auto; overflow-x: hidden; margin: 0; border-radius: 16px 16px 0 0; border-bottom: 0; scrollbar-width: none; }
/* overflow-x hidden as well: overflow-y auto alone makes the other axis auto too, and a card that had said
   overflow hidden for its own decoration (the Wardens summon burst at right -10px, the trial banner at margin
   -12px) became a pane that scrolled sideways by 4 to 10px on the phone (20 Sep 2026 layout pass) */
.ar-book .ar-pane::-webkit-scrollbar { display: none; }
.ar-book-tabs { flex: none; display: flex; gap: 3px; padding: 0 4px; margin: 0; background: linear-gradient(180deg, #a9b6cf, #8d9bb8); border-radius: 0 0 16px 16px; border: 2px solid #a9b6cf; border-top: 0; overflow-x: auto; scrollbar-width: none; }
.ar-book-tabs::-webkit-scrollbar { display: none; }
.ar-book-tabs .ar-tab { flex: 1 0 auto; min-width: 64px; text-align: center; font: 700 11px Cinzel, serif; color: #2b3560; padding: 8px 8px 9px; border: 0; border-radius: 0 0 10px 10px; background: transparent; cursor: pointer; display: flex; flex-direction: column; align-items: center; gap: 1px; }
.ar-book-tabs .ar-tab small { font-size: 9px; color: #4a5578; }
.ar-book-tabs .ar-tab.on { background: linear-gradient(180deg, #fff, #eef2f9); color: #1b2140; box-shadow: 0 -2px 0 #fff inset; }
.ar-book-tabs .ar-tab.on small { color: #b8860b; }
/* the gear page's own foot tabs go, the book has them now */
#worn .ar-tabs { display: none; }
/* the group banner over the book (18 Sep 2026): painted, the page name in gold script, the group under it */
.ar-banner { flex: none; height: 92px; border-radius: 16px 16px 0 0; border: 2px solid #a9b6cf; border-bottom: 0; background: #223 center / cover no-repeat; position: relative; display: flex; flex-direction: column; justify-content: flex-end; padding: 8px 14px; overflow: hidden; }
.ar-banner::before { content: ""; position: absolute; inset: 0; background: linear-gradient(90deg, rgba(10,12,30,.72) 0%, rgba(10,12,30,.25) 55%, rgba(10,12,30,0) 100%); }
.ar-banner b { position: relative; font: 800 22px Cinzel, serif; color: #ffd66a; letter-spacing: .04em; text-shadow: 0 1px 0 #3a2a05, 0 2px 6px rgba(0,0,0,.9); line-height: 1.1; }
.ar-banner small { position: relative; font: 700 10px Cinzel, serif; color: #f1e8d2; letter-spacing: .14em; text-transform: uppercase; text-shadow: 0 1px 2px #000; }
.ar-book .ar-banner + .ar-pane { border-radius: 0; border-top: 0; }
.ar-book .ar-pane { border-radius: 0; }
.ar-book:not(:has(.ar-banner)) .ar-pane:first-child { border-radius: 16px 16px 0 0; }
.qh-head { display: none; }   /* the quests page's own header is the banner now */
.ar-book .ar-pane.ar-only { border-radius: 0 0 16px 16px; border-bottom: 2px solid #a9b6cf; }
/* the way-back arrow sits on the banner's right on a book page, off the tabs */
.has-book .back-arrow { top: 118px; bottom: auto; left: auto; right: 12px; opacity: .85; }
/* many panes: the tabs wrap into two rows instead of running off the side (18 Sep 2026) */
.ar-book-tabs { flex-wrap: wrap; overflow: visible; }
.ar-book-tabs .ar-tab { flex: 1 1 auto; min-width: 22%; padding: 7px 6px 8px; font-size: 10.5px; }
.ar-book-tabs .ar-tab small { font-size: 8.5px; }
/* "i want all the books in 1 line": the tabs share one row whatever their number; the words shrink to fit */
.ar-book-tabs { flex-wrap: nowrap; overflow: hidden; }
.ar-book-tabs .ar-tab { flex: 1 1 0; min-width: 0; padding: 7px 2px 8px; font-size: clamp(7.5px, 2.3vw, 10.5px); letter-spacing: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: block; }
.ar-book-tabs .ar-tab small { display: block; font-size: 8px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* the pane joins the banner (18 Sep 2026): the hall card rule out-ranked the book's zero margin */
.frame:not(.page-game) .ar-book .card.ar-pane { margin: 0; border-top: 0; border-radius: 0; }
.frame:not(.page-game) .ar-book .card.ar-pane.ar-only { border-radius: 0 0 16px 16px; }
.frame:not(.page-game) .ar-book:not(:has(.ar-banner)) .card.ar-pane { border-top: 2px solid #a9b6cf; border-radius: 16px 16px 0 0; }
.back-arrow { display: none !important; }

/* the race poster sat above the book as a second banner (18 Sep 2026): the hub banner is the one picture up top */
.has-book .race-banner { display: none; }

/* stacked cards inside one pane read as one sheet with a rule between them */
.frame:not(.page-game) .ar-book .ar-group { display: flex; flex-direction: column; background: #e9edf5; }
.frame:not(.page-game) .ar-book .ar-group > .card.ar-stacked { margin: 0; border: 0; border-radius: 0; flex: 0 0 auto; }
.frame:not(.page-game) .ar-book .ar-group > .card.ar-stacked + .card.ar-stacked { border-top: 2px solid #a9b6cf; }

/* SEVEN BUTTONS FILL THE BAR (18 Sep 2026, "make all the bottom panel buttons fit the screen, there's a space
   on the right"): the phone-width scroller at 1163 was for the twelve-button bar; with seven groups they
   share the width instead and nothing scrolls */
.navbar { justify-content: space-between; overflow-x: hidden; scroll-snap-type: none; }
.navbar .bar-btn { flex: 1 1 0; min-width: 0; }

/* pale panel, dark words: pages that colour their text with the ivory variables (chat lines, mail) went
   cream on cream inside the pale book (18 Sep 2026), so the variables turn navy inside every hall card */
.frame:not(.page-game) .card { --ivory: #1b2140; --ivory-muted: #4a5578; --parch: #1b2140; --parch-dark: #4a5578; }

/* MORE OF THE PANE ON A PHONE (18 Sep 2026, his Gear screenshot: the banner, a title pill saying Gear again and
   a 240px ring left the gauges and buttons under the fold). The banner is a band, not a poster; a pane whose
   own heading only repeats the banner drops that heading and keeps its pill; the gear ring, tiles and gauges
   come down a size. His phone is 360 CSS px wide and about 720 tall, which is what these were checked at. */
.ar-banner { height: 58px; padding: 0 12px; justify-content: center; }
.ar-banner b { font-size: 18px; }
.ar-banner small { font-size: 9px; }
.ar-pane.ar-dup-head .card-head h2 { display: none; }
.ar-pane.ar-dup-head .card-head { justify-content: flex-end; padding-bottom: 2px; margin-bottom: 4px; min-height: 0; }
.ar-pane.ar-dup-head .card-head:empty { display: none; }
.has-book .ar-head .ar-title { display: none; }
.has-book .ar-head { justify-content: flex-end; margin-bottom: 0; }
.has-book .ar-head .ar-cp { margin-left: 0; }
.has-book .ar-doll { grid-template-columns: 64px 1fr 64px; gap: 4px; }
.has-book .ar-tile { width: 64px; height: 76px; }
.has-book .ar-tile img { width: 38px; height: 38px; }
.has-book .ar-panel .arms-ring { width: 176px; height: 176px; margin: 0 auto 2px; }
.has-book .ar-panel .arms-rays { inset: 16px; }
.has-book .ar-panel .arms-ring-1 { inset: 22px; }
.has-book .ar-panel .arms-ring-2 { inset: 38px; }
.has-book .ar-panel .arms-ring-3 { inset: 48px; }
.has-book .ar-panel .arms-ring-pic { left: 52px; top: 52px; width: 72px; height: 72px; }
.has-book .ar-panel .arms-ring-plus { top: 108px; }
.has-book .ar-gauges { gap: 6px; margin: 0 0 4px; }
.has-book .ar-gauge { width: 54px; height: 54px; }
.has-book .ar-piece-name { margin: 0; }
.has-book .ar-level { margin: 0; }
.has-book .ar-btn { padding: 7px 12px; }

/* the hub strip on one line too (18 Sep 2026): at 360px Partner and Bond scrolled off the right of the
   Companions strip and the scroller made the strip taller; the tabs now share the width like the book tabs */
.hub-row { overflow: hidden; padding: 5px 4px 0; gap: 1px; }
.hubtab { flex: 1 1 0; min-width: 0; padding: 3px 1px 5px; }
.hubtab .hub-label { font-size: 8px; letter-spacing: 0; max-width: 100%; overflow: hidden; text-overflow: ellipsis; }
/* the 9px word only on a strip of seven tabs or fewer: with eight (Hero, Companions, Shop) a tab is 48px on a
   412px phone and Wardrobe needed 51, Training 47 and Treasury 51 at 9px, so they ended in three dots
   (20 Sep 2026 layout pass); at 8px with no spacing Wardrobe is 43 */
@media (min-width: 400px) { .hub-row:not(:has(.hubtab:nth-child(8))) .hubtab .hub-label { font-size: 9px; letter-spacing: .03em; } }
@media (max-width: 480px) { .hub-name { display: none; } } /* the banner names the group; on a phone the side word ("COMPANIONS" stood 110px tall) stretched the whole strip, 18 Sep 2026 */

/* THE FIGHT FITS A PHONE (18 Sep 2026, his stage 210 screenshot on a 360px screen: hero, wings, mount, ally and
   two ravens filled the width, Crit 3,402 was 36px tall and the two health tags sat on top of each other).
   Under 400px everything in the scene comes down a size together, the tags stop scaling up and the numbers
   drop to a size that still reads. Nothing here changes what the numbers are. */
@media (max-width: 430px) {
  :root { --zoom-hero: clamp(86px, 24vw, 100px); --zoom-mon: clamp(78px, 22vw, 92px); }
  .scene.blade .ride-wings { width: calc(var(--zoom-hero) * 1.1); max-height: calc(var(--zoom-hero) * .9); }
  .scene.blade .ride-mount { width: calc(var(--zoom-hero) * .85); max-height: calc(var(--zoom-hero) * 1); }
  .scene.blade .ride-ally { width: calc(var(--zoom-hero) * .5); }
  .scene.blade .spot-hero .tag, .scene.blade .mob-p0 .tag { transform: scale(1); }
  .tag { width: 92px; font-size: 10px; }
  .tag-hp { font-size: 9px; }
  .float { font-size: 17px; }
  .float-hurt { font-size: 12px; }
  .float-gold { font-size: 12px; }
  .float-crit { font-size: 22px; }
  .float-crit .stamp { margin-right: 4px; padding: 4px 3px; font-size: 9px; }
  .afx-name { font-size: 15px; }
  .afx-name.afx-big { font-size: 22px; }
}

/* THE PHONE PASS (18 Sep 2026, "reduce the scrolling without removing information"). Measured at 360x800 the
   pane a player reads was 389px of the 800: the top panel, the hub strip, the banner, the folder tabs, the chat
   row and the bar took the rest. Under 400px the strip, banner and bar each give back a little, and inside
   every pale card the rows, buttons, headings and paragraphs sit closer. Nothing is hidden; it is packed. */
@media (max-width: 430px) {
  .hubtab { padding: 2px 1px 4px; gap: 1px; }
  .hubtab .hub-ico { width: 26px; height: 26px; }
  .hubtab .hub-ico .ui-pic, .hubtab .hub-ico img { width: 23px; height: 23px; }
  .hub-row { padding-top: 4px; }
  .ar-banner { height: 44px; }
  .ar-banner b { font-size: 16px; }
  .ar-banner small { font-size: 8px; }
  .ar-book { margin: 4px 4px 2px; }
  .navbar { padding: 4px 3px calc(4px + env(safe-area-inset-bottom)); }
  .navbar .bar-btn { min-height: 50px; gap: 1px; }
  .bar-ico { width: 36px; height: 36px; }
  .bar-label { font-size: 10px; }
  .chatrow { min-height: 42px; }
  .frame:not(.page-game) .card { padding: 8px 8px 6px; }
  .frame:not(.page-game) .card .card-head { padding: 0 0 4px; margin-bottom: 6px; }
  .frame:not(.page-game) .card .card-head h2 { font-size: 16px; }
  .frame:not(.page-game) .card h3 { font-size: 15px; margin: 6px 0 4px; }
  .frame:not(.page-game) .card p { margin: 4px 0; line-height: 1.3; font-size: 14px; }
  .frame:not(.page-game) .card .row, .frame:not(.page-game) .card .qrow { padding: 6px 8px; gap: 8px; margin-bottom: 6px; }
  .frame:not(.page-game) .card .row-info strong { font-size: 14px; line-height: 1.2; }
  .frame:not(.page-game) .card .row .small, .frame:not(.page-game) .card .row .muted { font-size: 12px; line-height: 1.25; }
  .frame:not(.page-game) .card .btn { min-height: 38px; padding: 6px 12px; font-size: 14px; }
  .frame:not(.page-game) .card .row .btn { min-width: 72px; font-size: 13px; min-height: 34px; }
  .frame:not(.page-game) .card .bar { margin-top: 3px; }
}
/* the card art bled 4px past the pale card: its negative margins matched the old 14px padding (18 Sep 2026 audit) */
.frame:not(.page-game) .card .card-art { width: calc(100% + 20px); margin: -10px -10px 8px; }
.frame:not(.page-game) .card .card-head .chip { max-width: 56%; white-space: normal; text-align: center; line-height: 1.2; }
@media (max-width: 430px) {
  .frame:not(.page-game) .card .card-art { width: calc(100% + 16px); margin: -8px -8px 6px; height: 88px; }
}
@media (max-width: 430px) {
  .bar-label { font-size: 9px; letter-spacing: 0; max-width: 100%; overflow: hidden; }
  .prem-banner { margin-left: -8px; margin-right: -8px; width: calc(100% + 16px); }
}
.frame:not(.page-game) .card .prem-banner { width: calc(100% + 20px); margin: -10px -10px 8px; }
@media (max-width: 430px) { .frame:not(.page-game) .card .prem-banner { width: calc(100% + 16px); margin: -8px -8px 6px; height: 96px; } }
@media (max-width: 430px) {
  /* shop rows: a smaller picture, the reward chips two to a line, the buy button under rather than beside */
  .prem-pic { width: 56px; height: 56px; }
  .prem-pic img, .premium .pic-row, .premium .pic-small { width: 50px; height: 50px; }
  .prem-chips { gap: 4px; margin: 4px 0 2px; }
  .prem-chip { min-height: 22px; font-size: 12px; padding: 1px 7px 1px 3px; }
  .prem-chip img { width: 16px; height: 16px; }
  .row.premium .prem-buy, .row.premium > form { flex-basis: 100%; }
  /* quest rows: the picture and the reward tiles a size down, the count on the bar's line */
  .qpic { width: 38px; height: 38px; } .qpic img { width: 30px; height: 30px; }
  .qtiles { margin: 2px 0 1px; gap: 4px; } .qtile { width: 30px; height: 30px; } .qtile img, .qtile-blank { width: 18px; height: 18px; }
  .errand .bar, .deed-row .bar { margin: 4px 0 1px; }
  .errand, .deed-row { padding: 6px 8px; }
  .frame:not(.page-game) .card .row .btn.btn-small { min-width: 60px; padding: 5px 10px; }
  /* the Looks tiles, the ladder rungs and the pass table: closer lines */
  .frame:not(.page-game) .card .set-choice { padding: 6px 8px; }
  .frame:not(.page-game) .card table td, .frame:not(.page-game) .card table th { padding: 4px 4px; }
}
.bl-short { display: none; }
@media (max-width: 430px) { .bl-long { display: none; } .bl-short { display: inline; } }

/* the thin gold line along the top while a hall is fetched (nav.js, 18 Sep 2026) */
#nav-bar { position: fixed; left: 0; top: 0; height: 3px; width: 0; background: linear-gradient(90deg, #ffd66a, #c9a24a); z-index: 99; opacity: 0; transition: width .25s ease-out, opacity .2s; pointer-events: none; }
#nav-bar.on { width: 70%; opacity: 1; transition: width 1.2s cubic-bezier(.1,.7,.3,1), opacity .1s; }
/* the red dot on a folder tab with something waiting in its pane (panes.js, 18 Sep 2026) */
.ar-book-tabs .ar-tab { position: relative; }
.ar-tab-dot { position: absolute; top: 4px; right: 6px; width: 10px; height: 10px; border-radius: 50%; background: radial-gradient(circle at 35% 35%, #ff7a6a, #c8221a 70%); box-shadow: 0 0 0 2px #f4f6fb, 0 1px 3px rgba(0,0,0,.4); }
/* a tab with a dot keeps the corner clear for it: on a six tab strip a tab is 59px with 2px of padding, so the
   dot sat on the last letter of Summon (20 Sep 2026 layout pass, dot 188 to 198 over text ending at 196). The
   dot goes smaller and into the corner and the words shift left of it; more padding than this and Summon
   would be cut to an ellipsis at that width. */
.ar-book-tabs .ar-tab:has(.ar-tab-dot) { padding-right: 8px; }
.ar-book-tabs .ar-tab .ar-tab-dot { top: 2px; right: 3px; width: 8px; height: 8px; }

/* fields on the pale panel (18 Sep 2026, "the text in the smelt is too dark"): the game's inputs are navy on
   navy for the dark frame; inside a pale card they turn white with navy words so a picked rank can be read */
.frame:not(.page-game) .card input[type="text"], .frame:not(.page-game) .card input[type="password"], .frame:not(.page-game) .card input[type="email"], .frame:not(.page-game) .card input[type="number"], .frame:not(.page-game) .card select, .frame:not(.page-game) .card textarea {
  background: #fff; color: #1b2140; border: 1px solid #a9b6cf; box-shadow: inset 0 1px 2px rgba(27, 33, 64, .12); }
.frame:not(.page-game) .card select option { background: #fff; color: #1b2140; }
.frame:not(.page-game) .card input::placeholder, .frame:not(.page-game) .card textarea::placeholder { color: #7d869e; }
/* the small gold and pink lines under a shop row were mixed for the dark frame (18 Sep 2026): darker on pale */
.frame:not(.page-game) .card .prem-value { color: #7d5f1f; opacity: 1; }
.frame:not(.page-game) .card .prem-timer { color: #8a1a14; background: #f7d9d6; border-color: #d9736b; }
/* the Menu button sits inside .bi-top, which starts 6px in, so its left:4px landed 6px right of the rail
   under it (19 Sep 2026, "the menu on the left isent inline with the rest"): pulled back to the rail's line */
.page-game .scene.blade .bi-top .bi-round[data-sheet="grid"] { left: -2px; }

/* THE HERO RIDES (19 Sep 2026, "the mount dosent look right in that position"): the mount stood off at the
   hero's heels, small and behind the pet. Now it is under him the way Arielia draws it: centred, wider than
   the hero, the hero lifted onto its back, the name tag lifted with him, the pet still on the ground. A
   left-facing hero flips the mount too. */
.scene.blade .ride-mount, .scene.blade .ride-mount.mount-frames { left: 50%; right: auto; transform: translateX(-50%); bottom: -6px; width: calc(var(--zoom-hero) * 1.3); max-height: calc(var(--zoom-hero) * 1.05); opacity: 1; z-index: 0; object-fit: contain; object-position: center bottom; }
@keyframes mount-bob { 50% { transform: translateX(-50%) translateY(-2px); } }
.scene.blade .spot-hero.face-left .ride-mount { transform: translateX(-50%); }   /* the whole spot flips when he faces left, so the mount must not flip again (19 Sep 2026) */
.scene.blade .spot-hero:has(.ride-mount) .sprite-img.sprite-hero { bottom: calc(var(--zoom-hero) * .26); }   /* .36 floated him above the back (19 Sep 2026) */
.scene.blade .spot-hero:has(.ride-mount) .tag { top: calc(-26px - var(--zoom-hero) * .26); }
.scene.blade .spot-hero:has(.ride-mount) .ride-pet { bottom: -4px; z-index: 3; }
@media (max-width: 430px) { .scene.blade .ride-mount { width: calc(var(--zoom-hero) * 1.3); max-height: calc(var(--zoom-hero) * 1.05); transform: translateX(-50%); } }

/* THE ROAD (19 Sep 2026): the fight backdrop as a wide painting the camera pans along. The picture is 21:9,
   sized to the scene's height so it overhangs sideways; --pan (road.js) slides it, eased, a step a kill. */
.scene.blade .backdrop.road { background-size: auto 108%; background-position: var(--pan, 0px) 55%; transition: background-position 1.1s cubic-bezier(.3,.7,.3,1); filter: none; animation: none; inset: 0; }
.scene.blade .backdrop.road.road-snap { transition: none; }
.scene.blade .backdrop.road::after { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, rgba(0,0,0,.18), transparent 30%, transparent 70%, rgba(0,0,0,.32)); pointer-events: none; }

/* THE STORM (19 Sep 2026, his clip): the ultimate raises a fire tornado over the pack, a tall twisting cone of
   flame that spins up, throws embers and collapses. Drawn with three conic layers turning at different speeds. */
.afx-storm { width: 140px; height: 260px; margin: -230px 0 0 -70px; pointer-events: none;
  background:
    conic-gradient(from 0deg, transparent 0 20%, rgba(255,200,80,.9) 30%, transparent 40%, transparent 60%, rgba(255,120,30,.9) 72%, transparent 82%),
    conic-gradient(from 120deg, transparent 0 25%, rgba(255,240,180,.7) 35%, transparent 45%),
    radial-gradient(ellipse at 50% 100%, rgba(255,140,40,.9), rgba(255,60,10,.5) 40%, transparent 70%);
  clip-path: polygon(50% 0, 62% 0, 100% 100%, 0 100%, 38% 0);
  filter: blur(.6px) drop-shadow(0 0 14px rgba(255,120,30,.9));
  animation: storm-spin .28s linear infinite, storm-life 1.4s ease-out forwards; transform-origin: 50% 100%; border-radius: 0; z-index: 7; }
@keyframes storm-spin { to { background-position: 140px 0, -140px 0, 0 0; } }
@keyframes storm-life { 0% { transform: scaleY(.1) scaleX(.6); opacity: 0; } 18% { transform: scaleY(1.05) scaleX(1); opacity: 1; } 75% { transform: scaleY(1) scaleX(1.05) rotate(3deg); opacity: 1; } 100% { transform: scaleY(1.2) scaleX(.3); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .afx-storm { animation: none; display: none; } }

/* THE MARCH (march.js, 19 Sep 2026): on a road the hero stands left facing right with his party, the pack up the
   path on the right; a kill sends the beaten pack sliding away behind and the next running in from the edge */
.scene.blade.march .spot-hero { left: 24% !important; top: 50% !important; }
.scene.blade.march .arena-fx { left: 24%; top: 50%; }
.scene.blade.march .spot-mon { transition: left 1s cubic-bezier(.3,.7,.3,1), top 1s cubic-bezier(.3,.7,.3,1), opacity .5s; }
.scene.blade.march .spot-mon.mob-jump { transition: none !important; }
.scene.blade.march .spot-mon.mob-behind { opacity: 0; left: -20% !important; }
.scene.blade.march .mob-run .sprite-mon { animation: mob-step .22s ease-in-out 4; }
.scene.blade.march .spot-hero.marching .sprite-hero { transform: translateX(-50%) rotate(4deg); }
.scene.blade.march.marching .ride-pet, .scene.blade.march.marching .ride-warden, .scene.blade.march.marching .ride-ally { animation: march-bob .24s ease-in-out infinite alternate; }
.scene.blade.march.marching .ride-mount { animation: march-bob .3s ease-in-out infinite alternate; }
@keyframes march-bob { to { transform: translateY(-5px); } }
.scene.blade.march .backdrop.road { transition-duration: .9s; }
/* on the march the pack faces the hero (left), so the flip the field used is undone here */
.scene.blade.march .spot-mon.mob-left { transform: none; }
.scene.blade.march .spot-mon .sprite-mon { transform: scaleX(-1); animation: mon-bob-flip 2.6s ease-in-out infinite; }
.scene.blade.march .mob-run .sprite-mon { animation: mob-step-flip .22s ease-in-out 4; }
.scene.blade.march .spot-hero.lunge .hero-idle { animation: strike-still .34s cubic-bezier(.2, .9, .3, 1); }
.scene.blade.march .spot-mon .tag { transform: translateX(-50%); }   /* the tag never flips with the body */

/* THE RING (19 Sep 2026, "the hero is always centre and fights the 4 enemys around him, like it was before"):
   the hero fixed in the middle, the target and three more stood round him, the road and the march put away */
.scene.blade.ring .spot-hero { left: 50% !important; top: 50% !important; }
.scene.blade.ring .arena-fx { left: 50%; top: 50%; }
.scene.blade.ring .spot-mon.mob-p0 { left: 74%; top: 44%; }
.scene.blade.ring .spot-mon.mob-p1 { left: 20%; top: 40%; }
.scene.blade.ring .spot-mon.mob-p2 { left: 42%; top: 14%; }
.scene.blade.ring .spot-mon.mob-p3 { left: 26%; top: 70%; }
.scene.blade.ring .spot-mon.mob-p4 { left: 66%; top: 72%; }
.scene.blade.ring .mob-extra.mob-stand { display: block !important; opacity: .95; }
@media (max-width: 430px) {
  .scene.blade.ring .spot-mon.mob-p0 { left: 78%; } .scene.blade.ring .spot-mon.mob-p1 { left: 16%; }
  .scene.blade.ring .spot-mon.mob-p3 { left: 22%; top: 72%; } .scene.blade.ring .spot-mon.mob-p4 { left: 70%; top: 74%; }
}
/* the fight sits inside the stone ring painted on the arena ground (19 Sep 2026, "can we have the fight in the
   centre ring"): the hero at the circle's middle, the four pulled in round him rather than spread to the rails */
.scene.blade.ring .spot-hero { top: 47% !important; }
.scene.blade.ring .arena-fx { top: 47%; }
.scene.blade.ring .spot-mon.mob-p0 { left: 71%; top: 46%; }
.scene.blade.ring .spot-mon.mob-p1 { left: 29%; top: 46%; }
.scene.blade.ring .spot-mon.mob-p2 { left: 50%; top: 22%; }
.scene.blade.ring .spot-mon.mob-p3 { left: 36%; top: 64%; }
.scene.blade.ring .spot-mon.mob-p4 { left: 64%; top: 64%; }
@media (max-width: 430px) {
  .scene.blade.ring .spot-mon.mob-p0 { left: 74%; } .scene.blade.ring .spot-mon.mob-p1 { left: 26%; }
  .scene.blade.ring .spot-mon.mob-p3 { left: 34%; top: 65%; } .scene.blade.ring .spot-mon.mob-p4 { left: 66%; top: 65%; }
}
.scene.blade.ring .backdrop { background-position: center 46%; }
/* the mob spots are placed by their left edge, not their middle (measured 19 Sep 2026: 11% out), so the ring
   positions are set here by where the body's centre lands */
.scene.blade.ring .spot-mon.mob-p0 { left: 62%; top: 44%; }
.scene.blade.ring .spot-mon.mob-p1 { left: 16%; top: 44%; }
.scene.blade.ring .spot-mon.mob-p2 { left: 39%; top: 20%; }
.scene.blade.ring .spot-mon.mob-p3 { left: 24%; top: 63%; }
.scene.blade.ring .spot-mon.mob-p4 { left: 54%; top: 63%; }
@media (max-width: 430px) {
  .scene.blade.ring .spot-mon.mob-p0 { left: 64%; } .scene.blade.ring .spot-mon.mob-p1 { left: 14%; }
  .scene.blade.ring .spot-mon.mob-p3 { left: 22%; top: 64%; } .scene.blade.ring .spot-mon.mob-p4 { left: 56%; top: 64%; }
}
/* the ring: the backdrop fitted to the arena (travel.js sets top and bottom), the circle centred, the fight on it */
.scene.blade.ring .backdrop { left: 0; right: 0; background-size: cover; background-position: center center; animation: none; }
.scene.blade.ring .spot-hero { top: 50% !important; }
.scene.blade.ring .arena-fx { top: 50%; }
.scene.blade.ring .spot-mon.mob-p0 { left: 62%; top: 47%; }
.scene.blade.ring .spot-mon.mob-p1 { left: 16%; top: 47%; }
.scene.blade.ring .spot-mon.mob-p2 { left: 39%; top: 24%; }
.scene.blade.ring .spot-mon.mob-p3 { left: 24%; top: 66%; }
.scene.blade.ring .spot-mon.mob-p4 { left: 54%; top: 66%; }
/* the ring's row is --ring-y (travel.js, level with the Wings button); the hero and the four hang off it */
.scene.blade.ring .spot-hero { top: var(--ring-y, 50%) !important; }
.scene.blade.ring .arena-fx { top: var(--ring-y, 50%); }
.scene.blade.ring .spot-mon.mob-p0, .scene.blade.ring .spot-mon.mob-p1 { top: calc(var(--ring-y, 50%) - 3%); }
.scene.blade.ring .spot-mon.mob-p2 { top: calc(var(--ring-y, 50%) - 24%); }
.scene.blade.ring .spot-mon.mob-p3, .scene.blade.ring .spot-mon.mob-p4 { top: calc(var(--ring-y, 50%) + 17%); }
.scene.blade.ring .spot-hero { top: calc(var(--ring-y, 50%) - 9%) !important; }   /* the spot hangs from its top; this lands his middle on the row */
.scene.blade.ring .arena-fx { top: calc(var(--ring-y, 50%) - 9%); }
/* from the clip, kept for the ring (19 Sep 2026): the knock back on a hit and the party's step on a strike */
.scene.blade.ring .spot-mon.mob-knock .sprite-mon { animation: mob-knock .26s ease-out; }
@keyframes mob-knock { 30% { transform: translateX(14px) rotate(6deg); } 100% { transform: none; } }
.scene.blade.ring .spot-mon.mob-left.mob-knock .sprite-mon { animation: mob-knock-left .26s ease-out; }
@keyframes mob-knock-left { 30% { transform: scaleX(-1) translateX(14px) rotate(6deg); } 100% { transform: scaleX(-1); } }
.scene.blade.ring .spot-hero.party-step .ride-pet, .scene.blade.ring .spot-hero.party-step .ride-warden, .scene.blade.ring .spot-hero.party-step .ride-ally { animation: party-step .3s ease-out; }
@keyframes party-step { 40% { transform: translate(6px, -6px); } 100% { transform: none; } }

/* RIDER AND MOUNT STRIKE AS ONE (19 Sep 2026, "have them both move in unison attacking"): the mount takes the
   same dash as the hero on a strike, so the pair lunge at the target and settle back together */
.scene.blade .spot-hero:has(.ride-mount).lunge .ride-mount { animation: hero-dash .36s cubic-bezier(.2, .9, .3, 1); }
.scene.blade .spot-hero:has(.ride-mount).lunge .ride-pet { animation: hero-dash .36s cubic-bezier(.2, .9, .3, 1) .04s; }
/* a skin drawn from its own frames needs no tint (frames.js adds skin-frames when the set loads, 19 Sep 2026) */
.spot-hero.skin-frames .hero-skin { filter: none !important; animation: none !important; }   /* !important and the animation too: the Storm flicker is a keyframe filter and beat the plain none, so Storm frames ran through a 160deg hue turn and came out pink (20 Sep 2026) */

/* SMALLER TRIGGERS (19 Sep 2026, "the trigger effects, can we get them smaller so they dont take up the screen"):
   the skill band is a ribbon over the hero's head, not a banner across the fight; the crit numbers half the
   size; the ultimate's flash and storm smaller too */
.afx.afx-band { height: 38px; top: -96px; }
.afx-band-1 { font-size: clamp(14px, 3.6vw, 18px) !important; letter-spacing: .03em; }
.afx-band-2 { font-size: clamp(9px, 2.4vw, 11px) !important; letter-spacing: .1em; }
.float { font-size: 15px; }
.float-hurt { font-size: 11px; } .float-gold { font-size: 11px; }
.float-crit { font-size: 19px; }
.float-crit .stamp { font-size: 8px; padding: 3px 3px; margin-right: 3px; }
.afx-name { font-size: 13px; } .afx-name.afx-big { font-size: 18px; }
.afx-storm { width: 100px; height: 190px; margin: -170px 0 0 -50px; }
.afx-ult { width: 220px; height: 220px; margin: -110px 0 0 -110px; }
.afx-flash { opacity: .55; }

/* THE STAGE CALL (19 Sep 2026, "the stage pop up in a better position and smaller"): a small plate that drops in
   under the enemy bar, top right of the ground, rather than a 40px banner in the middle of the fight */
.bi-stagecall { left: auto; right: 10px; top: 112px; transform: none; align-items: flex-end; gap: 0; padding: 4px 10px; border-radius: 10px;
  background: linear-gradient(180deg, rgba(20,24,58,.92), rgba(11,14,34,.92)); border: 1px solid #c9a24a; box-shadow: 0 2px 8px rgba(0,0,0,.5); }
.bi-stagecall b { font-size: 16px; letter-spacing: .5px; -webkit-text-stroke: 0; text-shadow: 0 1px 2px #000; }
.bi-stagecall small { font-size: 9px; letter-spacing: .08em; text-transform: uppercase; }
.bi-stagecall.on { animation: stagecall-in2 .45s cubic-bezier(.2, .9, .3, 1) forwards; }
.bi-stagecall.off { animation: stagecall-out2 .45s ease-in forwards; }
@keyframes stagecall-in2 { from { opacity: 0; transform: translateX(40px); } to { opacity: 1; transform: none; } }
@keyframes stagecall-out2 { to { opacity: 0; transform: translateX(40px); } }
@media (max-width: 430px) { .bi-stagecall { top: 108px; right: 8px; } }
.bi-stagecall { top: 118px; right: auto; left: 56px; align-items: flex-start; }   /* under the enemy bar's left end, clear of the rings and both rails */
.bi-stagecall small { max-width: 190px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
@media (max-width: 430px) { .bi-stagecall { top: 116px; left: 52px; } }
.page-game .scene.blade .bi-stagecall { top: 236px; z-index: 9; }   /* just under the enemy bar, over the ground (the 34% rules above outranked the plate) */
@media (max-width: 430px) { .page-game .scene.blade .bi-stagecall { top: 232px; } }

/* THE FRAME PICTURE over a portrait ring (20 Sep 2026, "frames arent working"): frames/cut/<key> laid over the
   ring at 1.5x, the coloured border underneath goes quiet so the two do not fight.
   20 Sep 2026 evening, "some frames arent working", the audit: three rules were beating this one.
   1. .hud2 .avatar-ring img (54px) and .wr-ring img (100%) outrank .avatar-frame, so the wreath was drawn the
      size of the portrait or smaller, inside the ring instead of round it. The size is !important now.
   2. .hud2 .avatar-ring and .wr-ring are overflow: hidden (they clip the portrait to the circle), which cut
      the picture off at the rim. A ring that holds a frame is overflow: visible; the portrait keeps its own
      border-radius (.portrait) so nothing square shows.
   3. The 18 Sep ::after rule above (line ~3013) paints the same picture at 144% under this img, so Settings
      drew every frame twice. The ::after stays for the small chooser rings on Settings (they have no img)
      and goes quiet wherever the img is. */
.avatar-ring, .set-ring, .wr-ring { position: relative; }
.avatar-frame, .hud2 .avatar-ring img.avatar-frame, .page-game .hud2 .avatar-ring img.avatar-frame, .wr-ring img.avatar-frame, .set-ring img.avatar-frame {
  position: absolute; left: 50%; top: 50%; max-width: none;
  transform: translate(-50%, -50%); object-fit: contain; border-radius: 0; pointer-events: none; z-index: 3; filter: drop-shadow(0 1px 2px rgba(0,0,0,.6)); }
/* the size sits on the plain class alone: !important already beats the ring rules whatever their length, and
   the per-frame sizes under it (0,2,0) have to outrank this one (0,1,0), which they could not if it were long.
   The pictures carry different amounts of air round the ring; the same sizes the ::after rule was tuned to. */
.avatar-frame { width: 152% !important; height: 152% !important; }
.frame-dragon .avatar-frame, .frame-sunburst .avatar-frame { width: 160% !important; height: 160% !important; }
.frame-laurel .avatar-frame { width: 140% !important; height: 140% !important; }
.frame-wyrmcoil .avatar-frame { width: 148% !important; height: 148% !important; }
.frame-iron .avatar-frame, .frame-gold .avatar-frame, .frame-embers .avatar-frame { width: 144% !important; height: 144% !important; }
.avatar-ring:has(.avatar-frame), .set-ring:has(.avatar-frame), .wr-ring:has(.avatar-frame) { box-shadow: none !important; border-color: transparent !important; overflow: visible !important; }
.avatar-ring:has(.avatar-frame)::after, .set-ring:has(.avatar-frame)::after,
.avatar-ring[class*="frame-"]:not(.frame-plain):has(.avatar-frame)::after, .set-ring[class*="frame-"]:not(.frame-plain):has(.avatar-frame)::after { content: none !important; }   /* the old painted frame (::after, line 3016) outranked this by one class, so a worn frame drew TWICE, the painted one 30% out and the picture 60% out ("2 frames up on the avatar", 21 Sep 2026) */

/* THE NEW PLAYER PAGES READ (20 Sep 2026, "the text is really dark when choosing at the new player page"): the
   title screen is dark navy but the cards still used the parchment inks (#6d5a44 on navy). Ivory on this
   screen: the class names, the blurbs, the stat labels and the origin words. */
body.title-screen .class-card h2, body.title-screen .card-head h2 { color: var(--ivory); text-shadow: 0 1px 2px #000; }
body.title-screen .blurb, body.title-screen .class-card .blurb { color: #d8cdb4; }
body.title-screen .stat-grid dt { color: #c9bfa6; }
body.title-screen .stat-grid dd { color: var(--ivory); }
body.title-screen .origin-chip, body.title-screen .origin-pick label, body.title-screen .small, body.title-screen .muted { color: #d8cdb4; }
body.title-screen label, body.title-screen p { color: #e6dcc4; }
/* the class figure on the choose page sat on top of the class name: its sprite is absolute against the card head
   (the fight's rules), so it drew at the head's centre. Kept in its own box on the right. (20 Sep 2026) */
.class-figure { position: relative; }
.class-figure .sprite-img, .class-figure .sprite { position: static !important; left: auto !important; bottom: auto !important; transform: none !important; }

/* THE HUB STRIP UNDER THE BOOK (20 Sep 2026, "have it above the return look and chat panel, easier for phone"): the
   strip sits between the book and the chat row now (include/layout.php), so its tabs hang from its top edge and the lit
   one lifts toward the book instead of away from the HUD. */
.hubtabs { border-bottom: 0; border-top: 2px solid var(--frame-dark); box-shadow: inset 0 6px 12px rgba(0,0,0,.35); }
.hubtab { border-radius: 0 0 10px 10px; }
.hubtab.on { transform: translateY(2px); box-shadow: 0 2px 10px rgba(255,220,120,.45); }
/* the Back button on the chat row (20 Sep 2026) */
.chatrow-back { border: 0; background: transparent; padding: 0; margin: 0; cursor: pointer; font-family: inherit; -webkit-appearance: none; appearance: none; }

/* THE VERDICT ON ANYTHING WORN (21 Sep 2026, "add a better or worse to things in the game that gets equipped just
   like gear has"): the gear page has its own (arms.css .arms-verdict); the Altar bag and the Starsteel and Warplate
   bags share this one. A word, the change, and what it is against. Dark ink on the pale panels. */
.vd { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; margin: 4px 0 6px; padding: 4px 8px; border-radius: 8px; border: 1px solid; font-size: 12px; min-width: 0; }
.vd .vd-word { font-family: Cinzel, Georgia, serif; font-weight: 800; font-size: 13px; letter-spacing: .5px; text-transform: uppercase; }
.vd .vd-vs { flex: 1 1 100%; font-size: 10px; opacity: .85; line-height: 1.25; }   /* its own line: on a phone the cards are half the width and it wrapped off the card */
.vd-better { color: #14602a; border-color: #4caf6a; background: linear-gradient(90deg, #cfeed8, #e6f6ea); }
.vd-worse  { color: #8a1a14; border-color: #d9736b; background: linear-gradient(90deg, #f7d3cf, #fbe7e5); }
.vd-same   { color: #4a4a5a; border-color: #b9bccd; background: linear-gradient(90deg, #e6e8f0, #f2f3f8); }
.vd-stat { font-size: 11px; font-weight: 700; padding: 1px 7px; border-radius: 10px; border: 1px solid; white-space: nowrap; }
.vd-stat.up { color: #14602a; border-color: #4caf6a; background: #dff3e5; }
.vd-stat.down { color: #8a1a14; border-color: #d9736b; background: #fbe3e0; }


/* ================================================= THE CREST (21 Sep 2026, "build 6") */
/* The top panel his way: the portrait in the middle, gold and eggs on its left, keys and Crowns on its right, CP under
   it with the VIP badge and the relic, one small line of name, stage, time and rates, then the three pills. The
   markup is in layout.php; these rules come last on purpose so the older hud2 and page-game rules lose to them.
   The fight's scene sits under the header by --hud, measured from the header by narvoda.js (the header is taller
   than the fixed numbers above allowed for). */
.hud.hud6 { padding: calc(3px + env(safe-area-inset-top)) 8px 7px !important; gap: 0 !important; display: flex !important; flex-direction: column !important; align-items: center !important; }
.hud6 .hud-main, .page-game .hud6 .hud-main { display: flex !important; align-items: center !important; justify-content: space-between !important; gap: 8px !important; padding: 0 !important; width: 100%; }
.hud6 .cur { display: grid !important; gap: 4px !important; margin: 0 !important; flex: 1 1 0; min-width: 0; }
.hud6 .crest-left { justify-items: start; } .hud6 .crest-right { justify-items: end; }
.hud6 .cur-item { display: inline-flex; align-items: center; gap: 4px; padding: 2px 4px 2px 5px !important; border-radius: 14px; background: linear-gradient(180deg, #0a0d20, #05070f); border: 1px solid var(--frame-dark); box-shadow: inset 0 1px 0 rgba(255,255,255,.08), 0 1px 2px rgba(0,0,0,.6); font-size: 12px !important; max-width: 100%; }
.hud6 .cur-item b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.hud6 .cur-pic, .hud6 .cur-item .ico { width: 18px !important; height: 18px !important; flex: 0 0 auto; }
.hud6 .cur-plus { width: 16px !important; height: 16px !important; line-height: 16px !important; flex: 0 0 auto; }
.hud6 .hud-avatar, .hud6 .avatar-ring, .page-game .hud6 .hud-avatar, .page-game .hud6 .avatar-ring { width: 64px !important; height: 64px !important; margin: 0 6px !important; flex: 0 0 auto; }
.hud6 .avatar-ring img, .page-game .hud6 .avatar-ring img, .hud6 .avatar-ring .emblem, .hud6 .avatar-ring .ico { width: 62px !important; height: 62px !important; }
.hud6 .avatar-ring img.avatar-frame, .page-game .hud6 .avatar-ring img.avatar-frame { width: 152% !important; height: 152% !important; }
.hud6 .crest-cp, .page-game .hud6 .crest-cp { display: flex !important; align-items: center !important; justify-content: center !important; gap: 10px !important; margin-top: 6px; }
.hud6 .cp-big, .page-game .hud6 .cp-big { font-size: 18px !important; } .hud6 .cp-big b, .page-game .hud6 .cp-big b { font-size: 21px !important; }
.hud6 .hud-vip, .page-game .hud6 .hud-vip { all: unset; display: inline-flex !important; align-items: center; gap: 3px; cursor: pointer; white-space: nowrap; flex-direction: row; font-family: Cinzel, Georgia, serif; font-weight: 800; font-size: 10px; letter-spacing: .04em; color: var(--frame-light); }
.hud6 .hud-vip img { width: 20px !important; height: 20px !important; object-fit: contain; }
.hud6 .hud-relic, .page-game .hud6 .hud-relic { width: 24px !important; height: 24px !important; }
.hud6 .hud-relic .ui-pic, .hud6 .hud-relic .ico { width: 24px !important; height: 24px !important; }
.hud6 .crest-hp, .page-game .hud6 .crest-hp { width: 140px !important; max-width: 60% !important; height: 4px; margin: 4px auto 0; }
.hud6 .crest-line { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 2px 5px; margin-top: 4px; font-size: 10px; color: var(--ivory-muted); max-width: 100%; }
.hud6 .crest-line b { color: var(--frame-light); }
.hud6 .crest-dot { opacity: .6; }
.hud6 .plate-name { font-family: Cinzel, Georgia, serif; font-weight: 800; font-size: 11px; color: #fff; text-decoration: none; }
.hud6 .plate-name .hud-title { font-family: 'Crimson Pro', Georgia, serif; font-weight: 500; font-size: 10px; color: var(--frame-light); margin-left: 4px; }
.hud6 .side-rate { font-size: 10px; } .hud6 .side-rate .cur-pic, .hud6 .side-rate .ico { width: 13px !important; height: 13px !important; }
.hud6 .side-carnival { display: none; }
.hud6 .hud-pills, .page-game .hud6 .hud-pills { display: flex !important; justify-content: center; gap: 8px !important; padding: 6px 0 0 !important; width: 100%; }
.hud6 .pill2, .page-game .hud6 .pill2 { flex: 0 1 120px; justify-content: center; height: 26px !important; padding: 0 10px !important; font-size: 12px !important; }
.hud6 .hud-side, .hud6 .hud-name-tag, .hud6 .strip { display: none !important; }
@media (max-width: 380px) { .hud6 .plate-time { display: none; } .hud6 .crest-line .side-xp { display: none; } }
.hud6 .hud-vip, .page-game .hud6 .hud-vip, .hud6 .hud-vip.vip-pic { width: auto !important; height: auto !important; clip-path: none !important; background: none !important; filter: none !important; }
.hud6 .hud-vip span, .hud6 .hud-vip.vip-pic span { display: inline !important; position: static !important; font-size: 10px !important; color: var(--frame-light) !important; }
/* SMALLER (21 Sep 2026, his phone: "Shrink it and text bubbles so it dosent take up screen space, want the same size it
   was before"): the Crest at the old panel's height, about 106px. Portrait 48, money pills 11px, CP 14px, the small
   line 9px, pills 20px, the health line 3px. */
.hud.hud6 { padding: calc(2px + env(safe-area-inset-top)) 6px 4px !important; }
.hud6 .hud-main, .page-game .hud6 .hud-main { gap: 6px !important; }
.hud6 .cur { gap: 3px !important; }
.hud6 .cur-item { padding: 1px 3px 1px 4px !important; font-size: 11px !important; border-radius: 12px; }
.hud6 .cur-pic, .hud6 .cur-item .ico { width: 15px !important; height: 15px !important; }
.hud6 .cur-plus { width: 14px !important; height: 14px !important; line-height: 14px !important; font-size: 10px; }
.hud6 .hud-avatar, .hud6 .avatar-ring, .page-game .hud6 .hud-avatar, .page-game .hud6 .avatar-ring { width: 48px !important; height: 48px !important; margin: 0 4px !important; }
.hud6 .avatar-ring img, .page-game .hud6 .avatar-ring img, .hud6 .avatar-ring .emblem, .hud6 .avatar-ring .ico { width: 46px !important; height: 46px !important; }
.hud6 .lvl-badge { width: 18px; height: 18px; line-height: 18px; font-size: 9px; right: -3px; bottom: -3px; }
.hud6 .crest-cp, .page-game .hud6 .crest-cp { gap: 8px !important; margin-top: 1px; line-height: 1; }
.hud6 .cp-big, .page-game .hud6 .cp-big { font-size: 14px !important; } .hud6 .cp-big b, .page-game .hud6 .cp-big b { font-size: 16px !important; }
.hud6 .hud-vip img { width: 16px !important; height: 16px !important; }
.hud6 .hud-vip span, .hud6 .hud-vip.vip-pic span { font-size: 9px !important; }
.hud6 .hud-relic, .page-game .hud6 .hud-relic { width: 18px !important; height: 18px !important; }
.hud6 .hud-relic .ui-pic, .hud6 .hud-relic .ico { width: 18px !important; height: 18px !important; }
.hud6 .crest-hp, .page-game .hud6 .crest-hp { height: 3px; margin: 2px auto 0; width: 120px !important; }
.hud6 .crest-line { margin-top: 2px; font-size: 9px; gap: 1px 4px; line-height: 1.2; }
.hud6 .plate-name { font-size: 10px; } .hud6 .plate-name .hud-title { font-size: 9px; }
.hud6 .side-rate { font-size: 9px; } .hud6 .side-rate .cur-pic, .hud6 .side-rate .ico { width: 11px !important; height: 11px !important; }
.hud6 .hud-pills, .page-game .hud6 .hud-pills { gap: 6px !important; padding: 4px 0 0 !important; }
.hud6 .pill2, .page-game .hud6 .pill2 { flex: 0 1 108px; height: 20px !important; padding: 0 8px !important; font-size: 11px !important; }
.hud6 .pill2 .ui-pic, .hud6 .pill2 .ico { width: 14px; height: 14px; }
.hud6 .pill2 .badge-red { min-width: 13px; height: 13px; line-height: 13px; font-size: 9px; }
.hud6 .crest-cp, .page-game .hud6 .crest-cp { height: 18px !important; margin: 1px 0 0 !important; overflow: visible; }
.hud6 .crest-cp > * { line-height: 18px !important; height: 18px; }
.hud6 .hud-avatar, .hud6 .avatar-ring, .page-game .hud6 .hud-avatar, .page-game .hud6 .avatar-ring { width: 44px !important; height: 44px !important; }
.hud6 .avatar-ring img, .page-game .hud6 .avatar-ring img, .hud6 .avatar-ring .emblem, .hud6 .avatar-ring .ico { width: 42px !important; height: 42px !important; }
.hud6 .hud-pills, .page-game .hud6 .hud-pills { padding: 3px 0 0 !important; }
/* the frame was cut at the top (21 Sep 2026): a worn frame is half again the portrait's size, and the portrait sat 2px
   from the panel's top edge, so the frame's top 10px were off the panel. The portrait row starts 10px down now and the
   pills row gives the 3px back; the panel stays open at the edges so the frame can hang past them. */
.hud.hud6 { overflow: visible !important; }
.hud6 .hud-main, .page-game .hud6 .hud-main { padding-top: 10px !important; }
.hud6 .hud-pills, .page-game .hud6 .hud-pills { padding-top: 1px !important; }
.hud6 .crest-line { margin-top: 1px; }
/* THE SUNBURST TURNS AGAIN (21 Sep 2026, "this isent working on my frame up top its static"): the turn lived on the
   painted ::after, which the double frame fix above switches off, so the picture stood still. The picture is centred by
   translate, so its turn keeps the translate in the keyframes. */
.frame-sunburst .avatar-frame { animation: frame-turn-pic 14s linear infinite; }
@keyframes frame-turn-pic { from { transform: translate(-50%, -50%) rotate(0deg); } to { transform: translate(-50%, -50%) rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .frame-sunburst .avatar-frame { animation: none; } }
/* FIVE MORE FRAMES (21 Sep 2026, "i want 5 new frames"): the ring colours for the fallback border, the painted ring
   (kept for the ::after path) and the picture size on the HUD, the same three rules the first frames have above. */
.frame-frostbloom  { border-color: #bfefff; box-shadow: 0 0 0 2px #7fd4ff, inset 0 0 0 2px #2f7fbf, 0 0 14px rgba(127,212,255,.9); }
.frame-thornwreath { border-color: #3a5a2a; box-shadow: 0 0 0 2px #c8202a, inset 0 0 0 2px #1e2e14, 0 0 12px rgba(200,32,42,.7); }
.frame-stormring   { border-color: #8ff0ff; box-shadow: 0 0 0 2px #2fb8d8, inset 0 0 0 2px #143a4a, 0 0 16px rgba(80,240,255,.9); }
.frame-bonecrown   { border-color: #f0e6c8; box-shadow: 0 0 0 2px #c8b890, inset 0 0 0 2px #5a4a30, 0 0 12px rgba(240,230,200,.7); }
.frame-starforge   { border-color: #e8f0ff; box-shadow: 0 0 0 2px #2f4fbf, inset 0 0 0 2px #1a2a6a, 0 0 14px rgba(120,160,255,.9); }
.frame-frostbloom::after  { background-image: url(../images/frames/cut/frostbloom.png); inset: -30%; }
.frame-thornwreath::after { background-image: url(../images/frames/cut/thornwreath.png); inset: -26%; }
.frame-stormring::after   { background-image: url(../images/frames/cut/stormring.png); inset: -30%; }
.frame-bonecrown::after   { background-image: url(../images/frames/cut/bonecrown.png); inset: -26%; }
.frame-starforge::after   { background-image: url(../images/frames/cut/starforge.png); inset: -26%; }
.frame-frostbloom .avatar-frame, .frame-stormring .avatar-frame { width: 160% !important; height: 160% !important; }
.frame-thornwreath .avatar-frame, .frame-bonecrown .avatar-frame, .frame-starforge .avatar-frame { width: 150% !important; height: 150% !important; }
/* THE SUNBURST STANDS STILL (22 Sep 2026, "i dont want it to spin now"): the picture is a dragon ring now, not a sun;
   both turns (the old ::after one and the picture one above) are off. */
.frame-sunburst::after, .frame-sunburst .avatar-frame { animation: none !important; }
/* THE BANNER SHOWS ITS WHOLE PICTURE IN TIME (22 Sep 2026, "i want to see more of the header pictures without taking up
   more space in the book"): the strip is 44px on a phone and the painting scaled to its width is four times that, so
   only a band ever showed. Same height, the band drifts from the top of the painting to the bottom and back over
   forty seconds, and the wash on the left is lighter so more of it reads. Off under reduced motion. */
.ar-banner { animation: banner-drift 40s ease-in-out infinite alternate; }
@keyframes banner-drift { from { background-position: center 0%; } to { background-position: center 100%; } }
.ar-banner::before { background: linear-gradient(90deg, rgba(10,12,30,.6) 0%, rgba(10,12,30,.18) 50%, rgba(10,12,30,0) 100%); }
@media (prefers-reduced-motion: reduce) { .ar-banner { animation: none; background-position: center 35%; } }
body.pref-nomotion .ar-banner { animation: none; background-position: center 35%; }
