/* Marginalia — "royal pixel" theme.
   Cartoon pixel art: chunky stepped borders, hard offset shadows (no blur),
   one pixel font. Royal red + gold on a night-blue castle; no browns. */
:root{
  --night-0:#0b0818;      /* ink: outlines, hard shadows */
  --night-1:#150f33;      /* page background, top */
  --night-2:#241a52;      /* page background, bottom / cool panels */
  --night-3:#35287a;      /* floor tile highlight, hover */
  --royal:#c8102e;        /* royal red: primary */
  --royal-deep:#8e0a22;   /* warm panels */
  --royal-light:#ff4d6a;  /* highlights, active states */
  --gold:#ffd23f;
  --gold-deep:#e0a800;
  --cream:#fff6e8;
  --muted:#c4bde8;        /* secondary text: lavender, reads on red and blue */
  --hp-good:#4ee07a;
  --hp-mid:#ffd23f;
  --hp-low:#ff4d6a;
  --poison:#a6f23a;
  --burn:#ff6f91;          /* burn stacks: a pinker red than a hit's */
  --arcane:#75e3ff;       /* magic, intelligence */
  --violet:#6a2bb8;       /* rare materials */
  --px:4px;               /* one "art pixel" of the UI */
}
/* a fixed night-castle world by design — no light-mode swap */

/* Pixelify Sans (OFL, web/assets/fonts), served from here rather than
   Google Fonts so no visitor's browser calls a third party. */
@font-face{
  font-family:"Pixelify Sans";
  src:url("/assets/fonts/pixelify-sans-latin.woff2") format("woff2");
  font-weight:400 700;
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
  font-display:swap;
}
@font-face{
  font-family:"Pixelify Sans";
  src:url("/assets/fonts/pixelify-sans-latin-ext.woff2") format("woff2");
  font-weight:400 700;
  unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
  font-display:swap;
}

/* Pixelify Sans' digits are hard to read (5 looks like S, 2 like 8), so
   digits alone come from Jersey 10 (OFL, web/assets/fonts), scaled to
   match; letters stay Pixelify Sans. */
@font-face{
  font-family:"Digits";
  src:url("/assets/fonts/jersey10-digits.woff2") format("woff2");
  unicode-range:U+0030-0039;
  size-adjust:125%;
  font-display:swap;
}

*{box-sizing:border-box;}

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

body{
  min-height:100vh;
  background-color:var(--night-1);
  background-image:
    /* faint pixel stars */
    radial-gradient(var(--night-3) 1.5px, transparent 1.6px),
    radial-gradient(rgba(255,210,63,0.35) 1px, transparent 1.2px),
    linear-gradient(180deg, var(--night-1), var(--night-2));
  background-size: 64px 64px, 112px 112px, 100% 100%;
  background-position: 0 0, 40px 24px, 0 0;
  background-attachment: fixed;
  font-family:"Digits", "Pixelify Sans", ui-monospace, monospace;
  font-size:15px;
  color:var(--cream);
  position:relative;
}

/* Pixelify Sans' bold fills the counters (c reads as o, 2 as 8): text
   stays at 400, only titles of 24px and up go to 600. Sizes are whole px,
   14px and up (13px for tiny uppercase labels), so glyphs sit on the grid. */
h1, h2, h3, h4, h5, h6, b, strong, th, dt, legend{ font-weight:400; }

a{ color:var(--gold); }
a:hover{ color:var(--cream); }

/* ---- shared pixel frame ----
   stepped corners come from four 1-px-art offsets instead of a real
   border, so boxes read as drawn on a pixel grid */
.menu-card, .start-card, .battle-log, .menu-btn,
.roster-item, .lineup-slot, .unit-detail,
.auth-form input, .auth-form select, .auth-form textarea{
  border:none;
  border-radius:0;
  box-shadow:
    calc(-1 * var(--px)) 0 0 0 var(--night-0),
    var(--px) 0 0 0 var(--night-0),
    0 calc(-1 * var(--px)) 0 0 var(--night-0),
    0 var(--px) 0 0 var(--night-0),
    0 calc(3 * var(--px)) 0 0 rgba(11,8,24,0.55);
}

/* ---- top bar: the game's pages, gold, bag, settings (language switcher before login) ---- */
.top-bar{
  position:absolute;
  top: calc(12px + env(safe-area-inset-top, 0px));
  right: calc(16px + env(safe-area-inset-right, 0px));
  z-index:20;
  display:flex;
  align-items:center;
  gap:12px;
  padding:6px 8px;
  background:var(--night-0);
  box-shadow: 0 var(--px) 0 0 rgba(11,8,24,0.55);
}
/* the game's pages (the map is home, reached from every page's back link) */
.nav-icons{ display:flex; align-items:center; gap:6px; }
.nav-icon{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  height:40px;
  box-sizing:border-box;
  padding:4px;
  background:var(--night-2);
}
/* every top bar button is as wide as the gold one, counter or not */
.nav-icon, .nav-gold, .nav-items{ min-width:76px; justify-content:center; }
.nav-icon:hover, .nav-icon:focus-visible{ background:var(--night-3); outline:none; }
/* 16x16 art at 2x */
.nav-icon img{ width:32px; height:32px; image-rendering:pixelated; display:block; }
.lang-switch{
  display:flex;
  gap:4px;
  font-weight:400;
  font-size:16px;
  text-transform:uppercase;
}
.lang-switch a, .lang-switch .lang-current{ padding:6px 8px; }
.lang-switch a{ color:var(--muted); text-decoration:none; }
.lang-switch a:hover{ color:var(--gold); }
.lang-switch .lang-current{ color:var(--night-0); background:var(--gold); }

/* ---- page header ---- */
.hud{
  position:absolute;
  top: calc(18px + env(safe-area-inset-top, 0px));
  left:20px;
  right:20px;
  z-index:5;
  pointer-events:none;
}
.hud-back{
  display:inline-block;
  margin-bottom:6px;
  font-weight:400;
  font-size:14px;
  color:var(--muted);
  text-decoration:none;
  pointer-events:auto;
}
.hud-back:hover{ color:var(--gold); }
/* a second link next to the back one (e.g. Edit Team → Store) */
.hud h1{
  font-weight:600;
  font-size:30px;
  margin:0;
  color:var(--cream);
  text-shadow: 3px 3px 0 var(--royal), 6px 6px 0 var(--night-0);
}
.hud-teams{
  margin-top:8px;
  font-weight:400;
  font-size:14px;
  color:var(--muted);
  min-height:1.4em;
}
.hud-teams .vs{ color:var(--royal-light); margin:0 8px; text-transform:uppercase; }
.hud-status{
  margin-top:4px;
  font-weight:400;
  font-size:14px;
  color:var(--gold);
  min-height:1.4em;
}
.eyebrow{
  font-size:14px;
  font-weight:400;
  letter-spacing:0.12em;
  text-transform:uppercase;
  color:var(--gold);
}

/* ---- battle arena ---- */
body.page-play{
  height:100vh;
  overflow:hidden;
}
/* the arena stops above the battle log, so fighter percentages never
   land underneath it */
.arena{
  --log-strip:140px;
  position:relative;
  width:100%;
  height:calc(100% - var(--log-strip));
}
/* the battlefield background (data/levels.json "arenas"), running on
   under the battle log to the bottom of the screen. app.js reads its
   rendered box to keep the fighters on the ground band of the picture. */
.arena-bg{
  position:absolute;
  left:0; top:0;
  width:100%;
  height:calc(100% + var(--log-strip));
  object-fit:cover;
  object-position:center bottom;
  image-rendering:pixelated;
  z-index:0;
}
.arena::after{
  content:"";
  position:absolute;
  inset:0 0 calc(-1 * var(--log-strip)) 0;
  background: radial-gradient(ellipse at 50% 55%, transparent 55%, rgba(11,8,24,0.6) 100%);
  pointer-events:none;
  z-index:1;
}

.fighter{
  position:absolute;
  width:72px;
  height:72px;
  margin-top:-41px; /* lift slightly above true center so shadow reads as ground */
  z-index:3;
}

/* mirrored formation: position 1 stands nearest the middle, position 4
   out at the edge. This is only the pre-match layout — app.js
   (placeInRandomLanes) puts every fighter on the arena picture's ground
   each match. */
.posA1{ left:35%; top:36%; }
.posA2{ left:25%; top:92%; }
.posA3{ left:15%; top:52%; }
.posA4{ left:5%;  top:74%; }
.posB1{ left:65%; top:36%; }
.posB2{ left:75%; top:92%; }
.posB3{ left:85%; top:52%; }
.posB4{ left:calc(95% - 72px); top:74%; }

.shadow{
  position:absolute;
  left:50%;
  bottom:2px;
  width:44px;
  height:8px;
  transform:translateX(-50%);
  background:rgba(11,8,24,0.6);
  z-index:2;
}

.hpbar{
  position:absolute;
  left:50%;
  top:-14px;
  transform:translateX(-50%);
  width:76%;
  height:10px;
  background:var(--night-0);
  border:2px solid var(--night-0);
  z-index:4;
}
.hpbar-fill{
  height:100%;
  width:100%;
  background:var(--hp-good);
  box-shadow: inset 0 -2px 0 rgba(0,0,0,0.25);
  transition:width 0.4s steps(8), background-color 0.4s steps(4);
}

/* a bigger or smaller fighter (a perk's --sprite-scale, see .rig) keeps
   its HP bar and badges just over its head: the rig grows from 88% of its
   height, and a fighter is square, so margins in % of its width match */
.hpbar, .status-row{ margin-top:calc((1 - var(--sprite-scale, 1)) * 88%); }
.shadow{ scale:var(--sprite-scale, 1); }

/* debuff badges over the HP bar (app.js setStunned/setPoison) */
.status-row{
  position:absolute;
  left:50%;
  top:-32px;
  transform:translateX(-50%);
  display:flex;
  gap:4px;
  z-index:4;
}
.status{
  display:flex;
  align-items:center;
  gap:2px;
  padding:1px 3px;
  background:var(--night-0);
  font-size:13px;
  font-weight:400;
  line-height:1;
}
.status[hidden]{ display:none; }
.status img{ width:12px; height:12px; image-rendering:pixelated; }
.status--poison{ color:var(--poison); }
.status--burn{ color:var(--burn); }
/* a unit's stars (app.js setStars) lead the row */
.fighter-stars{ display:flex; align-items:center; gap:1px; padding:2px 3px; background:var(--night-0); }
.fighter-stars[hidden]{ display:none; }
.fighter-stars img{ width:9px; height:9px; image-rendering:pixelated; }
/* the statuses (app.js setStatuses) sit in the same row as the debuffs */
.status-set{ display:contents; }
.status--ward{ color:#a078dc; }

/* .rig is the rigid body: wobble/strike/recoil rotation and the defeated
   pose all apply here, so the weapon (nested inside) rides along for free */
.rig{
  position:absolute;
  inset:0;
  width:100%;
  height:100%;
  transform-origin:50% 88%;
  /* a unit's perks may draw it bigger or smaller (app.js applyRoster);
     scale composes with the transforms the animations set */
  scale:var(--sprite-scale, 1);
}

/* a perk may scale a unit's sprite (inline --sprite-scale): it grows up
   from its feet, and the margins make room for its extra width (half of
   it on each side) or height, so it never covers its name */
.roster-item-sprite, .lineup-sprite, .unit-detail-sprite, .store-reveal-sprite{
  transform-origin:50% 100%;
  scale:var(--sprite-scale, 1);
}
.roster-item-sprite{ margin-inline:max(0px, (var(--sprite-scale, 1) - 1) * 20px); }
.unit-detail-sprite{
  margin-inline:max(0px, (var(--sprite-scale, 1) - 1) * 40px);
  margin-top:max(0px, (var(--sprite-scale, 1) - 1) * 80px);
}
.lineup-sprite{ margin-top:max(0px, (var(--sprite-scale, 1) - 1) * 56px); }
.store-reveal-sprite{ margin-top:max(0px, (var(--sprite-scale, 1) - 1) * 80px); }

.knight-img, .sword-img, .shield-img, .char-card-sprite,
.roster-item-sprite, .lineup-sprite, .unit-detail-sprite{
  image-rendering:pixelated;
  image-rendering:-moz-crisp-edges;
  image-rendering:crisp-edges;
}
.knight-img{
  position:absolute;
  inset:0;
  width:100%;
  height:100%;
}

/* named tints let two characters share one sprite file but still read as
   distinct combatants (see Character.SpriteTint in data/characters.json) */
.tint-violet{ filter:hue-rotate(60deg) saturate(2.2) brightness(1.05); }

.sword-holder{
  position:absolute;
  width:58%;
  height:85%;
  bottom:14%;
  transform-origin:50% 100%;
  pointer-events:none;
}
.sword-holder.sideA{ left:78%; transform: translateX(-50%) rotate(8deg); }
.sword-holder.sideB{ left:22%; transform: translateX(-50%) rotate(-8deg); }
.sword-img{ width:100%; height:100%; }
/* the bow is drawn facing left, toward team A: team A's faces right */
.sword-holder.sideA .sword-img[src$="/bow.png"]{ transform:scaleX(-1); }

/* the shield (app.js applyRoster) sits on the free hand, opposite the
   weapon, in front of the body */
.shield-img{
  position:absolute;
  width:44%;
  height:44%;
  bottom:6%;
  pointer-events:none;
}
.shield-img[hidden]{ display:none; }
.shield-img.sideA{ left:0; }
.shield-img.sideB{ right:0; }

/* ---- projectiles (ranged and magic skills, see app.js fireProjectile) ----
   Positioned at a point inside .arena and moved with transforms; the
   translate(-50%,-50%) in every keyframe keeps that point at their center. */
.projectile, .impact{
  position:absolute;
  z-index:12;
  pointer-events:none;
  transform:translate(-50%,-50%);
}
.projectile--ranged{
  width:32px;
  height:32px;
  background:url("/assets/fx/arrow.png") center / 100% 100% no-repeat;
  image-rendering:pixelated;
  filter:drop-shadow(0 3px 0 rgba(11,8,24,0.55));
}
/* a square pixel orb: bright core, cyan rim, hard glow steps */
.projectile--magic{
  width:14px;
  height:14px;
  background:var(--cream);
  box-shadow:
    0 0 0 3px #75e3ff,
    0 0 0 6px rgba(117,227,255,0.45),
    0 0 0 9px rgba(117,227,255,0.18);
}
.projectile--magic.projectile--heal{
  box-shadow:
    0 0 0 3px var(--hp-good),
    0 0 0 6px rgba(78,224,122,0.45),
    0 0 0 9px rgba(78,224,122,0.18);
}
/* a ranged strength weapon throws its head: the flail's spiked ball */
.projectile--thrown{
  width:28px;
  height:28px;
  background:url("/assets/fx/ball.png") center / 100% 100% no-repeat;
  image-rendering:pixelated;
  filter:drop-shadow(0 3px 0 rgba(11,8,24,0.55));
}
.impact{
  width:44px;
  height:44px;
  box-shadow: inset 0 0 0 4px var(--cream);
}
.impact--magic{ box-shadow: inset 0 0 0 4px #75e3ff, 0 0 0 4px rgba(117,227,255,0.35); }
.impact--heal{ box-shadow: inset 0 0 0 4px var(--hp-good), 0 0 0 4px rgba(78,224,122,0.35); }
/* crit / dodge / stun callouts over a fighter (app.js floatText) */
.float-text{
  position:absolute;
  z-index:14;
  pointer-events:none;
  transform:translate(-50%,0);
  font-weight:400;
  font-size:15px;
  white-space:nowrap;
  text-shadow: 2px 2px 0 var(--night-0);
}
.float-text--crit{ color:var(--gold); font-size:18px; }
.float-text--combo{ color:var(--arcane); font-size:18px; }
.float-text--dodge{ color:var(--cream); }
.float-text--stun{ color:var(--gold); }
.float-text--poison{ color:var(--poison); font-size:17px; }
.float-text--burn{ color:var(--burn); font-size:17px; }
.float-text--burst{ color:var(--gold); font-size:21px; }
.float-text--damage{ color:var(--royal-light); font-size:17px; }
.float-text--damage-crit{ color:var(--gold); font-size:21px; }
.float-text--heal{ color:var(--hp-good); font-size:17px; }
.float-text--ward{ color:#a078dc; font-size:17px; }
.float-text--status{ color:var(--arcane); }
.float-text--idle{ color:var(--muted); font-size:21px; }
.impact--thrown{ width:28px; height:28px; box-shadow: inset 0 0 0 3px var(--cream); }
.impact--ranged{ width:28px; height:28px; box-shadow: inset 0 0 0 3px var(--cream); }

/* a line a unit shouts in battle (app.js showBubble, from its perks):
   over its badges, shifted by --shift to stay on screen, its tail still
   pointing at the fighter; a speaking fighter is lifted over its
   neighbours so they don't cover it */
.fighter.speaking{ z-index:9; }
.speech{
  position:absolute;
  left:50%;
  bottom:calc(100% + 40px);
  margin-bottom:calc((var(--sprite-scale, 1) - 1) * 88%);
  transform:translateX(calc(-50% + var(--shift, 0px)));
  transform-origin:50% 100%;
  width:max-content;
  max-width:180px;
  padding:4px 8px;
  background:var(--cream);
  color:var(--night-0);
  border:2px solid var(--night-0);
  box-shadow:3px 3px 0 var(--night-0);
  font-size:14px;
  font-weight:400;
  line-height:1.3;
  text-align:center;
  pointer-events:none;
}
/* an encounter's meeting (/play?meet=…): nobody fights, so no HP bars,
   and its lines are longer than a battle shout */
.arena--meeting .hpbar{ display:none; }
.arena--meeting .speech{ max-width:240px; }
.speech::after{
  content:"";
  position:absolute;
  left:calc(50% - var(--shift, 0px));
  top:100%;
  width:8px;
  height:8px;
  margin-left:-4px;
  background:var(--cream);
  border:2px solid var(--night-0);
  border-top:none;
  box-shadow:3px 3px 0 var(--night-0);
}

/* a bystander (app.js setBystanders): an NPC who never fights, smaller
   and behind the fighters; a caged one hangs in a cage (ui/cage.png, 20x20
   art around the 16x16 sprite) */
.bystander{ z-index:2; --sprite-scale:0.8; }
.bystander.speaking{ z-index:9; }
.cage-img{
  position:absolute;
  left:-12.5%;
  top:-6.25%;
  width:125%;
  height:125%;
  image-rendering:pixelated;
}
/* the script's skip button, in the header while lines are said */
.script-skip{
  margin-top:6px;
  padding:4px 12px;
  font-size:14px;
  pointer-events:auto;
  display:inline-block;
}
.script-skip[hidden]{ display:none; }
/* the fight's speed and an admin's "resolve", under the heading (the top
   right is the top bar's) */
.fight-controls{
  display:flex;
  gap:8px;
  margin-top:6px;
}
.fight-btn{
  padding:4px 12px;
  font-size:14px;
  pointer-events:auto;
}
.fight-btn[hidden]{ display:none; }
.fight-speed--fast{ color:var(--gold); }

/* the walk/strike/recoil/heal motions are computed per-event in app.js via
   the Web Animations API; "defeated" is the one persistent state, so it
   stays a plain CSS transition */
.rig.defeated{
  transition: transform 0.6s steps(6), filter 0.6s steps(6), opacity 0.6s steps(6);
  transform: rotate(90deg) translateY(12px);
  filter: grayscale(1) brightness(0.7);
  opacity:0.5;
}

.battle-log{
  position:absolute;
  left:20px;
  right:20px;
  bottom: calc(22px + env(safe-area-inset-bottom, 0px));
  z-index:5;
  max-width:560px;
  height:108px;
  overflow-y:auto;
  padding:10px 14px;
  background:rgba(11,8,24,0.9);
  color:var(--cream);
  font-size:14px;
  line-height:1.5;
}
.battle-log .log-line.log-header{ color:var(--gold); opacity:1; font-weight:400; }
.battle-log .log-line.log-outcome{ color:var(--royal-light); font-weight:400; }
.battle-log .log-line.log-quip{ color:var(--muted); }
.battle-log .log-line.log-idle{ color:var(--muted); }

/* the whole log, in a window over the result card, opened from its corner */
.start-card{ position:relative; }
.full-log-open{ position:absolute; top:6px; right:6px; padding:2px; border:0; background:none; cursor:pointer; opacity:0.75; }
.full-log-open:hover, .full-log-open:focus-visible{ opacity:1; }
.full-log-open[hidden]{ display:none; }
.full-log-open img{ display:block; width:32px; height:32px; image-rendering:pixelated; }
.store-popup .store-reveal.full-log-card{ width:min(640px, 100%); max-height:calc(100% - 32px); align-items:stretch; }
.full-log-card .map-panel-eyebrow{ text-align:center; }
.battle-log.full-log-lines{ position:static; max-width:none; height:auto; min-height:0; flex:1 1 auto; }

/* over everything in the arena, a speaking fighter's bubble (.speaking)
   and the floating numbers (.float-text) included */
.start-panel{
  position:fixed;
  inset:0;
  z-index:15;
  display:flex;
  align-items:center;
  justify-content:center;
  background:rgba(11,8,24,0.55);
}
.start-panel[hidden]{ display:none; }
/* "preparing the fight" only shows when the match is slow to come (app.js
   drops the class once it's here), so a quick one never flashes it */
.start-panel--preparing{ animation:preparing-in 0s 600ms both; }
@keyframes preparing-in{ from{ visibility:hidden; } to{ visibility:visible; } }
.start-card{
  background:var(--royal-deep);
  padding:24px 28px;
  text-align:center;
  max-width:320px;
}
.start-card p{
  margin:0 0 18px;
  color:var(--cream);
  font-weight:400;
  font-size:15px;
  line-height:1.5;
}
.start-error{
  margin-top:14px;
  color:var(--gold);
  font-weight:400;
  font-size:14px;
  line-height:1.5;
}
/* end-of-match result: the outcome big, what it earned under it */
/* on a ribbon (assets/ui/ribbon.png, 50x18): its 17-pixel ends stay put,
   the plain middle stretches under the word */
.start-card p.overlay-outcome{
  margin:0 -36px 10px;
  height:calc(18 * var(--px));
  line-height:calc(18 * var(--px));
  border-style:solid;
  border-width:0 calc(17 * var(--px));
  border-image:url("/assets/ui/ribbon.png") 0 17 fill / 0 calc(17 * var(--px)) stretch;
  image-rendering:pixelated;
  font-size:30px;
  font-weight:600;
  white-space:nowrap;
  text-shadow: 3px 3px 0 var(--night-0);
}
.start-card p.overlay-outcome--team_a{ color:var(--gold); }
.start-card p.overlay-outcome--team_b{ color:var(--cream); }
.start-card p.overlay-outcome--draw{ color:var(--muted); }
.start-card p.overlay-reward{
  color:var(--gold);
  font-weight:400;
  font-family:"Digits", "Pixelify Sans", monospace;
  font-size:28px;
  display:flex;
  justify-content:center;
  gap:18px;
}
.start-card p.overlay-reward[hidden]{ display:none; }
.reward-chip{ display:inline-flex; align-items:center; gap:6px; }
.start-card p.overlay-reward:has(.reward-chip--star){ flex-wrap:wrap; }
.reward-chip--star{ flex-basis:100%; justify-content:center; font-family:"Pixelify Sans", monospace; font-size:18px; }

/* a unit's stars (earned missions, see missions.go) and its career */
.unit-stars{ display:inline-flex; gap:2px; margin-left:6px; vertical-align:middle; }
.unit-stars img{ width:14px; height:14px; image-rendering:pixelated; }
.career{ margin-top:12px; }
.career-grade{ display:flex; gap:6px; align-items:center; margin:0 0 8px; color:var(--gold); }
.career-grade img{ width:14px; height:14px; image-rendering:pixelated; }
.career-record{ display:flex; flex-wrap:wrap; gap:6px 16px; margin:0 0 8px; }
.career-record div{ display:flex; gap:6px; align-items:baseline; }
.career-record dt{ font-size:13px; text-transform:uppercase; opacity:.8; }
.career-record dd{ margin:0; font-family:"Digits", "Pixelify Sans", ui-monospace, monospace; font-size:20px; color:var(--gold); }
.career-tree{ list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:8px; }
.career-star{ display:flex; gap:8px; align-items:flex-start; }
.career-star-icon{ width:18px; height:18px; image-rendering:pixelated; filter:grayscale(1); opacity:.55; }
.career-star--earned .career-star-icon{ filter:none; opacity:1; }
.career-star-text{ display:flex; flex-direction:column; gap:2px; flex:1; }
.career-star-title{ color:var(--gold); }
.career-star-reward{ font-size:14px; }
.career-goal{ display:flex; flex-direction:column; gap:2px; font-size:14px; }
.career-goal-bar{ display:block; height:8px; background:var(--night-0); box-shadow:0 0 0 2px var(--night-3); }
.career-goal-bar span{ display:block; height:100%; background:var(--gold); }
/* end-of-match damage and healing per fighter (statsTable in app.js) */
/* the two teams sit side by side (stacked only when there's no room), so
   the card stays short enough not to scroll */
.start-card:has(.overlay-stats:not([hidden])){ max-width:none; width:min(760px, 100%); max-height:100%; overflow-y:auto; }
.overlay-stats{ margin:0 0 18px; }
.overlay-stats[hidden]{ display:none; }
.match-stats-grid{ display:grid; grid-template-columns:repeat(auto-fit, minmax(290px, 1fr)); gap:10px 24px; align-items:start; }
.match-stats{ width:100%; border-collapse:collapse; font-size:14px; color:var(--cream); }
.match-stats th, .match-stats td{ padding:1px 6px; font-weight:400; text-align:left; }
.match-stats td + td, .match-stats-head th + th{ text-align:right; }
.match-stats td + td{ font-family:"Digits", "Pixelify Sans", monospace; font-size:18px; color:var(--gold); }
.match-stats-head th{ padding-bottom:3px; font-size:13px; text-transform:uppercase; color:var(--muted); border-bottom:var(--px) solid var(--night-0); }
.match-stats-head th:first-child{ font-size:14px; text-transform:none; color:var(--royal-light); }
.match-stats-poison td, .match-stats-poison td + td{ color:var(--poison); }
.match-stats-burn td, .match-stats-burn td + td{ color:var(--burn); }
/* short windows: tighten the result card rather than scroll it */
@media (max-height: 600px){
  .start-card:has(.overlay-stats:not([hidden])){ padding:14px 20px; }
  .start-card p.overlay-outcome{ margin-bottom:4px; font-size:24px; }
  .start-card p.overlay-reward{ margin-bottom:8px; font-size:24px; }
  .overlay-stats{ margin-bottom:10px; }
  .overlay-actions{ gap:8px; }
}
.reward-icon{ width:24px; height:24px; object-fit:contain; image-rendering:pixelated; }
/* the gear a win gave (showLoot in app.js): big, named, framed in gold,
   popping in one after the other, so nobody misses it */
.overlay-loot{ margin:0 0 18px; text-align:center; }
.overlay-loot[hidden]{ display:none; }
.start-card p.overlay-loot-title{ margin:0 0 10px; color:var(--gold); font-size:24px; font-weight:600; text-shadow:3px 3px 0 var(--night-0); }
.overlay-loot-items{ display:flex; flex-wrap:wrap; justify-content:center; gap:16px; }
.loot-card{
  display:flex; flex-direction:column; align-items:center; gap:8px;
  width:128px; padding:12px 8px 10px;
  background:var(--night-2);
  border:var(--px) solid var(--gold);
  box-shadow: 0 0 0 var(--px) var(--night-0), var(--px) var(--px) 0 var(--px) var(--night-0), inset 0 0 0 var(--px) var(--gold-deep);
  animation: loot-pop 0.36s steps(4) both, loot-glow 1.2s steps(2) 0.4s 3;
}
.loot-icon{ width:64px; height:64px; object-fit:contain; image-rendering:pixelated; }
.loot-name{ color:var(--cream); font-size:16px; line-height:1.2; }
@keyframes loot-pop{
  from{ transform:scale(0.4); opacity:0; }
  70%{ transform:scale(1.12); opacity:1; }
  to{ transform:scale(1); opacity:1; }
}
@keyframes loot-glow{
  50%{ border-color:var(--cream); }
}
@media (prefers-reduced-motion: reduce){
  .loot-card{ animation:none; }
}
@media (max-height: 600px){
  .overlay-loot{ margin-bottom:10px; }
  .loot-card{ width:112px; padding:8px 6px; }
  .loot-icon{ width:48px; height:48px; }
}
.overlay-actions{
  display:flex;
  flex-direction:column;
  align-items:stretch;
  gap:16px;
}

/* ---- buttons ---- */
.menu-btn{
  font-family:inherit;
  font-weight:400;
  font-size:17px;
  color:var(--night-0);
  background:var(--gold);
  padding:10px 22px;
  cursor:pointer;
  text-decoration:none;
  display:block;
  text-align:center;
  box-shadow:
    calc(-1 * var(--px)) 0 0 0 var(--night-0),
    var(--px) 0 0 0 var(--night-0),
    0 calc(-1 * var(--px)) 0 0 var(--night-0),
    0 var(--px) 0 0 var(--night-0),
    inset 0 calc(-1 * var(--px)) 0 0 var(--gold-deep),
    0 calc(2 * var(--px)) 0 0 var(--night-0);
  transition: transform 0.05s steps(1);
}
.menu-btn:hover:not(:disabled){ background:#ffe066; color:var(--night-0); }
.menu-btn:active:not(:disabled){ transform:translateY(var(--px)); }
.menu-btn--secondary{
  color:var(--cream);
  background:var(--royal);
  box-shadow:
    calc(-1 * var(--px)) 0 0 0 var(--night-0),
    var(--px) 0 0 0 var(--night-0),
    0 calc(-1 * var(--px)) 0 0 var(--night-0),
    0 var(--px) 0 0 var(--night-0),
    inset 0 calc(-1 * var(--px)) 0 0 var(--royal-deep),
    0 calc(2 * var(--px)) 0 0 var(--night-0);
}
.menu-btn--secondary:hover{ background:var(--royal-light); color:var(--cream); }

/* ---- menu / auth / settings / about cards ---- */
.menu-shell{
  min-height:100vh;
  display:flex;
  align-items:center;
  justify-content:center;
  padding:88px 16px 40px;
  position:relative;
  z-index:2;
}
.menu-card{
  background:var(--royal-deep);
  background-image: linear-gradient(var(--royal) 0 var(--px), transparent var(--px));
  padding:30px 32px;
  text-align:center;
  max-width:380px;
  width:100%;
}
.menu-card h1{
  font-weight:600;
  font-size:36px;
  line-height:1.1;
  margin:0;
}
.logo{
  color:var(--cream);
  text-shadow: 3px 3px 0 var(--royal), 6px 6px 0 var(--night-0);
}
.logo-sub{
  margin:10px 0 0;
  color:var(--cream);
  font-size:16px;
}
.menu-tagline{
  margin:12px 0 22px;
  color:var(--muted);
  font-size:14px;
  line-height:1.6;
}

.auth-form{
  display:flex;
  flex-direction:column;
  gap:16px;
  text-align:left;
}
.auth-form label{ display:flex; flex-direction:column; gap:6px; }
.auth-form label span{ font-weight:400; font-size:14px; color:var(--cream); }
.auth-form small{ color:var(--muted); font-size:14px; }
.auth-form input{
  font:inherit;
  font-size:16px;
  color:var(--cream);
  background:var(--night-1);
  padding:9px 10px;
  outline:none;
}
.auth-form input:focus, .auth-form select:focus, .auth-form textarea:focus{
  background:var(--night-2);
  box-shadow:
    calc(-1 * var(--px)) 0 0 0 var(--gold),
    var(--px) 0 0 0 var(--gold),
    0 calc(-1 * var(--px)) 0 0 var(--gold),
    0 var(--px) 0 0 var(--gold);
}
.auth-form .menu-btn{ margin-top:8px; }
.auth-switch{ margin:26px 0 0; font-size:14px; }
.form-error{
  margin:0 0 18px;
  padding:8px 10px;
  background:var(--night-0);
  color:var(--royal-light);
  font-weight:400;
  font-size:14px;
  text-align:left;
}

/* settings: labelled sections, top-aligned, buttons one width */
.settings-shell{
  position:relative;
  z-index:2;
  max-width:420px;
  margin:0 auto;
  padding: calc(104px + env(safe-area-inset-top, 0px)) 16px calc(40px + env(safe-area-inset-bottom, 0px));
}
html.framed .settings-shell{ padding-top:72px; }
.settings-card{ max-width:none; text-align:left; padding:8px 24px 24px; }
.settings-section{ padding-top:16px; }
.settings-section + .settings-section{ margin-top:16px; border-top:2px dashed rgba(196,189,232,0.35); }
.settings-label{ margin:0 0 10px; font-size:13px; text-transform:uppercase; letter-spacing:2px; color:var(--gold); }
.settings-text{ margin:0 0 10px; font-size:14px; line-height:1.6; color:var(--cream); }
.settings-text:last-child{ margin-bottom:0; }
.settings-player{ margin:0 0 12px; font-size:24px; line-height:1.2; color:var(--gold); overflow-wrap:anywhere; }
.settings-text a{ color:var(--gold); }
.settings-credits .settings-text{ color:var(--muted); line-height:1.5; }
.settings-actions{ display:flex; flex-direction:column; gap:14px; margin-top:14px; }
.settings-actions form{ margin:0; }
.settings-actions .menu-btn{ display:block; width:100%; box-sizing:border-box; text-align:center; text-decoration:none; }
/* a volume (static/audio.js): a square gold knob on a night-blue groove */
.settings-volume{ display:flex; align-items:center; gap:14px; margin-top:12px; font-size:14px; color:var(--cream); }
.settings-volume span{ flex:0 0 72px; }
.settings-volume input[type=range]{ flex:1; min-width:0; height:24px; margin:0; background:transparent; appearance:none; -webkit-appearance:none; cursor:pointer; }
.settings-volume input[type=range]::-webkit-slider-runnable-track{ height:8px; background:var(--night-2); border:2px solid var(--night-0); }
.settings-volume input[type=range]::-moz-range-track{ height:8px; background:var(--night-2); border:2px solid var(--night-0); }
.settings-volume input[type=range]::-webkit-slider-thumb{ -webkit-appearance:none; width:16px; height:20px; margin-top:-8px; background:var(--gold); border:2px solid var(--night-0); border-radius:0; box-shadow:2px 2px 0 var(--night-0); }
.settings-volume input[type=range]::-moz-range-thumb{ width:16px; height:20px; background:var(--gold); border:2px solid var(--night-0); border-radius:0; box-shadow:2px 2px 0 var(--night-0); }
.settings-volume input[type=range]:focus-visible{ outline:2px solid var(--gold); outline-offset:2px; }

/* ---- edit team ---- */
.team-shell{
  position:relative;
  z-index:2;
  max-width:920px;
  margin:0 auto;
  padding: calc(104px + env(safe-area-inset-top, 0px)) 20px calc(40px + env(safe-area-inset-bottom, 0px));
}
.team-intro{
  color:var(--muted);
  font-size:14px;
  line-height:1.6;
  max-width:680px;
}
.team-flash{ color:var(--hp-good); font-weight:400; }
.team-error{ color:var(--royal-light); font-weight:400; }
.char-card-sprite{ width:56px; height:56px; }
.char-card-name{ font-size:14px; font-weight:400; }
.char-card-stats{ font-size:14px; color:var(--muted); line-height:1.4; }
/* save bar: always on screen, top of the builder; gold and blinking in
   hard steps once there's something to save */
.team-savebar{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:16px;
  padding:10px 12px 10px 16px;
  background:var(--night-2);
  box-shadow: inset 0 0 0 2px var(--night-3);
}
.team-save-status{ margin:0; font-size:14px; font-weight:400; color:var(--muted); }
.team-savebar[hidden]{ display:none; }
.team-savebar .team-save-btn{ flex:none; font-size:18px; padding:10px 28px; }
.team-savebar--dirty{ background:var(--royal-deep); box-shadow: inset 0 0 0 var(--px) var(--gold); }
.team-savebar--dirty .team-save-status{ color:var(--gold); }
.team-savebar--dirty .team-save-btn:not(:disabled){ animation: save-blink 1.2s steps(1) infinite; }
@keyframes save-blink{
  0%, 100%{ background:var(--gold); }
  50%{ background:var(--cream); }
}
.team-count{ font-weight:400; color:var(--muted); }
/* disabled: flat night-blue, never a translucent gold (reads orange on red) */
.menu-btn:disabled, .menu-btn:disabled:hover{ background:var(--night-3); color:var(--muted); cursor:default; }
.char-card-class{ font-size:14px; color:var(--gold); margin-top:-4px; }
.team-store-hint{ margin-top:18px; color:var(--muted); font-size:14px; }

/* team builder: roster on the left; team, then the picked unit's details,
   on the right */
.builder{
  display:grid;
  grid-template-columns:minmax(220px, 280px) 1fr;
  gap:32px;
  margin-top:22px;
  align-items:start;
}
.builder-heading{
  margin:0 0 14px;
  font-size:16px;
  color:var(--gold);
  text-transform:uppercase;
  letter-spacing:1px;
}
.builder-main{ display:flex; flex-direction:column; gap:28px; min-width:0; }

.roster-list{
  list-style:none;
  margin:0;
  padding:4px 8px 4px 4px;
  display:flex;
  flex-direction:column;
  gap:14px;
  max-height:min(62vh, 560px);
  overflow-y:auto;
}
.roster-item{
  width:100%;
  display:flex;
  align-items:center;
  gap:10px;
  padding:8px 10px;
  background:var(--night-2);
  color:var(--cream);
  font:inherit;
  text-align:left;
  cursor:pointer;
}
.roster-item:hover{ background:var(--night-3); }
.roster-item--in-team{ background:var(--royal-deep); }
.roster-item--active, .lineup-slot--active{
  box-shadow:
    calc(-1 * var(--px)) 0 0 0 var(--gold),
    var(--px) 0 0 0 var(--gold),
    0 calc(-1 * var(--px)) 0 0 var(--gold),
    0 var(--px) 0 0 var(--gold),
    0 calc(3 * var(--px)) 0 0 rgba(11,8,24,0.55);
}
.roster-item-sprite{ width:40px; height:40px; flex:none; }
.roster-item-text{ display:flex; flex-direction:column; min-width:0; flex:1; }
.roster-item-name{ font-weight:400; font-size:14px; }
.roster-item-class{ font-size:14px; color:var(--muted); }
.roster-item-pos{
  flex:none;
  width:24px;
  height:24px;
  line-height:24px;
  text-align:center;
  background:var(--gold);
  color:var(--night-0);
  font-weight:400;
}
.roster-item-pos:empty{ display:none; }
/* each owned unit's reset: items back in the bag, base skills back on */
.roster-row{ display:flex; align-items:stretch; gap:6px; }
.roster-row .roster-item{ flex:1; min-width:0; }
.roster-reset{
  flex:none;
  padding:0 8px;
  border:none;
  border-radius:0;
  font:inherit;
  font-size:13px;
  font-weight:400;
  text-transform:uppercase;
  letter-spacing:1px;
  color:var(--muted);
  background:var(--night-2);
  cursor:pointer;
  box-shadow: inset 0 0 0 2px var(--night-3);
}
.roster-reset:hover, .roster-reset:focus-visible{ outline:none; color:var(--cream); background:var(--royal); box-shadow: inset 0 0 0 2px var(--gold); }

.lineup-head{ display:flex; align-items:baseline; justify-content:space-between; gap:12px; }
.lineup-ends{
  display:flex;
  justify-content:space-between;
  font-size:14px;
  color:var(--muted);
  text-transform:uppercase;
  letter-spacing:1px;
  margin-bottom:10px;
}
.lineup-slots{
  list-style:none;
  margin:0;
  padding:0;
  display:grid;
  grid-template-columns:repeat(4, minmax(0, 1fr));
  gap:16px;
}
.lineup-slot{
  position:relative;
  min-height:150px;
  padding:26px 6px 8px;
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:6px;
  background:var(--night-2);
  cursor:grab;
}
.lineup-slot--empty{
  cursor:default;
  background:transparent;
  box-shadow:
    inset 0 0 0 2px var(--night-3);
}
.lineup-slot--over{ background:var(--night-3); outline:var(--px) dashed var(--gold); outline-offset:2px; }
.lineup-pos{
  position:absolute;
  top:0;
  left:0;
  width:24px;
  height:24px;
  line-height:24px;
  text-align:center;
  background:var(--royal);
  color:var(--cream);
  font-weight:400;
}
.lineup-sprite{ width:56px; height:56px; }
.lineup-name{ font-weight:400; font-size:14px; text-align:center; overflow-wrap:anywhere; }
.lineup-empty{ margin:auto; color:var(--muted); font-size:14px; }
.lineup-moves{ display:flex; gap:4px; margin-top:auto; }
.lineup-move, .skill-move{
  width:26px;
  height:26px;
  padding:0;
  border:none;
  border-radius:0;
  background:var(--night-0);
  color:var(--gold);
  font:inherit;
  font-size:13px;
  cursor:pointer;
}
.lineup-move:hover:not(:disabled), .skill-move:hover:not(:disabled){ background:var(--gold); color:var(--night-0); }
.lineup-move:disabled, .skill-move:disabled{ opacity:0.3; cursor:default; }
.lineup-move--out{ color:var(--royal-light); }

.detail-empty{ color:var(--muted); font-size:14px; }
.unit-detail{ background:var(--night-2); padding:18px 20px 20px; }
.unit-detail-head{ display:flex; align-items:center; gap:16px; flex-wrap:wrap; }
.unit-detail-sprite{ width:80px; height:80px; flex:none; }
.unit-detail-id{ flex:1; min-width:160px; display:flex; flex-direction:column; gap:4px; }
.unit-detail-name{ margin:0; font-size:20px; }
.unit-detail-id .char-card-class{ margin-top:0; }
/* stats and gear on the left, abilities on the right */
.unit-detail-body{ display:grid; grid-template-columns:repeat(2, minmax(0, 1fr)); gap:0 28px; }
.unit-detail-col{ min-width:0; }
.unit-detail-col > .skills-heading:first-child{ margin-top:18px; }
.gear-row{ display:grid; grid-template-columns:repeat(2, minmax(0, 1fr)); gap:12px; }
/* the four macro stats as big tiles, what they derive to underneath */
.unit-stats{ display:grid; grid-template-columns:repeat(5, 1fr); gap:10px; margin:18px 0 10px; }
.unit-stats div{ display:flex; flex-direction:column; align-items:center; gap:2px; padding:8px 4px; background:var(--night-1); cursor:help; }
.unit-stats dt{ color:var(--gold); font-size:14px; font-weight:400; letter-spacing:1px; }
.unit-stats dd{ margin:0; font-size:20px; font-weight:400; display:flex; align-items:baseline; gap:4px; }
.stat-bonus{ font-size:14px; }
.stat-bonus--up{ color:var(--hp-good); }
.stat-bonus--down{ color:var(--royal-light); }
.unit-derived{ display:flex; flex-wrap:wrap; gap:6px 16px; margin:0; font-size:14px; }
.unit-derived div{ display:flex; gap:5px; }
.unit-derived dt{ color:var(--muted); }
.unit-derived dd{ margin:0; font-weight:400; }
.unit-power{ margin:6px 0 0; font-size:14px; color:var(--muted); }
.unit-power b{ color:var(--cream); }
.detail-toggle{ flex:none; }
.skills-heading{ margin:22px 0 4px; color:var(--gold); font-size:14px; text-transform:uppercase; letter-spacing:1px; }
.skills-hint{ margin:0 0 12px; color:var(--muted); font-size:14px; }

/* a unit's perks (layout.html.tmpl's perkList): a hard stripe on the left
   says whether each one helps (gold), hurts (red) or trades (lavender) */
.perks{ width:100%; margin-top:16px; }
.perks .skills-heading{ margin-top:0; }
.perk-list{ list-style:none; margin:0 0 12px; padding:0; display:flex; flex-direction:column; gap:6px; }
.perk{
  display:flex;
  flex-direction:column;
  padding:6px 10px;
  background:var(--night-1);
  border-left:var(--px) solid var(--muted);
  text-align:left;
}
.perk--positive{ border-left-color:var(--gold); }
.perk--negative{ border-left-color:var(--royal-light); }
.perk-name{ font-weight:400; font-size:14px; color:var(--cream); }
.perk--positive .perk-name{ color:var(--gold); }
.perk--negative .perk-name{ color:var(--royal-light); }
.perk-effects{ font-size:14px; color:var(--cream); }
.perk-desc{ font-size:14px; color:var(--muted); font-style:italic; }
.store-reveal .perks{ margin-top:6px; max-width:320px; }
.store-reveal .skills-hint{ color:var(--cream); margin:0; text-align:center; }
.skill-list{ list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:8px; }
.skill-row{
  display:flex;
  align-items:center;
  gap:12px;
  padding:8px 10px;
  background:var(--night-1);
}
.skill-rank{ width:20px; flex:none; text-align:center; font-weight:400; color:var(--gold); }
.skill-info{ flex:1; display:flex; flex-direction:column; min-width:0; }
.skill-name{ font-weight:400; font-size:14px; }
.skill-meta{ font-size:14px; color:var(--muted); }
/* a skill's power, attributes and cooldown on one line, icons and digits */
.skill-stats{ display:flex; flex-wrap:wrap; align-items:center; gap:4px 6px; }
.skill-icon-num{ display:inline-flex; align-items:center; gap:3px; font-family:"Digits", "Pixelify Sans", monospace; font-size:18px; line-height:1; color:var(--cream); }
.skill-icon-num img{ height:16px; image-rendering:pixelated; }
.skill-cooldown{ margin-left:6px; }
/* an attribute as a small filled label, in the colour of its stat bar */
.stat-badge{
  display:inline-block;
  padding:0 4px;
  font-size:13px;
  letter-spacing:1px;
  color:var(--night-0);
  background:var(--stat, var(--muted));
}
.stat-badge--strength{ --stat:var(--royal-light); }
.stat-badge--agility{ --stat:var(--hp-good); }
.stat-badge--intelligence{ --stat:var(--arcane); }
.stat-badge--stamina{ --stat:var(--gold); }
.stat-badge--initiative{ --stat:var(--muted); }
/* + between the attributes a skill adds up; the label of each amount when it has several (damage, then the heal of a drain) */
.stat-plus{ font-size:14px; color:var(--muted); }
.skill-amount-label{ font-size:13px; color:var(--gold); text-transform:uppercase; letter-spacing:1px; }
.skill-moves{ display:flex; gap:4px; flex:none; }
/* equipped skills get ▲ ▼ ✕, the rest of the repertoire gets + */
.skill-list--equipped .skill-equip,
.skill-list--available [data-dir],
.skill-list--available .skill-unequip{ display:none; }
.skill-unequip{ color:var(--royal-light); }
.skill-list--available{ margin-bottom:4px; }
.skill-list--available .skill-row{ background:transparent; box-shadow: inset 0 0 0 2px var(--night-1); }
.skill-list--available .skill-rank{ color:var(--muted); }
.skill-list-empty[hidden]{ display:none; }

.skill-needs{ font-size:13px; color:var(--gold); text-transform:uppercase; letter-spacing:1px; margin-top:2px; }
.skill-row--locked{ opacity:0.55; }
.skill-row--locked .skill-needs{ color:var(--royal-light); }
.skill-taught{ display:block; font-size:13px; color:var(--gold); text-transform:uppercase; letter-spacing:1px; }
.skill-effects{ font-size:14px; color:var(--cream); }

/* a skill's school (see engine.Schools): a small label in its colour */
.school-tag{
  display:inline-block;
  padding:0 4px;
  font-size:13px;
  text-transform:uppercase;
  letter-spacing:1px;
  vertical-align:middle;
  color:var(--school, var(--muted));
  box-shadow: inset 0 0 0 2px var(--school, var(--muted));
}
.school--impact{ --school:#8b9bb4; }
.school--blade{ --school:#c0cbdc; }
.school--precision{ --school:var(--cream); }
.school--fire{ --school:var(--royal-light); }
.school--ice{ --school:var(--arcane); }
.school--arcane{ --school:#a078dc; }
.school--occult{ --school:#8a6fc7; }
.school--poison{ --school:var(--poison); }
.school--holy{ --school:var(--gold); }
.school--spirit{ --school:var(--hp-good); }
.school--guard{ --school:#6f8fe8; }
.school--sabotage{ --school:var(--muted); }
.grimoire-school-desc{ margin:0 0 8px; color:var(--muted); font-size:14px; }

/* the loadout's rhythm: which skill each coming turn uses, – for a lost one */
.skill-rhythm{ display:flex; flex-wrap:wrap; align-items:baseline; gap:4px 10px; margin:6px 0 12px; font-size:14px; }
.skill-rhythm-label{ font-size:13px; color:var(--gold); text-transform:uppercase; letter-spacing:1px; cursor:help; }
.skill-rhythm-turns{ font-family:"Digits", "Pixelify Sans", monospace; font-size:18px; letter-spacing:2px; }
.skill-rhythm-lost{ color:var(--muted); }
.skill-rhythm-lost--some{ color:var(--royal-light); }
.skill-row[hidden]{ display:none; }
.weapon-pick{ display:flex; align-items:center; gap:12px; margin:8px 0 4px; }
.gear-row .weapon-slot-text{ font-size:14px; min-width:0; overflow-wrap:anywhere; }

/* edit team on a big enough screen: the whole page scrolls (so a gear
   picker opened low down is never cut off by a panel), and the save bar
   stays stuck to the top of the window */
@media (min-width: 761px) and (min-height: 600px){
  .page-team .team-shell{ max-width:1180px; }
  .page-team .team-intro{ max-width:none; margin:0; font-size:14px; line-height:1.5; }
  .page-team .builder{ margin-top:16px; }
  .page-team .builder-roster{ position:sticky; top:12px; }
  .page-team .builder-main{ gap:18px; }
  .page-team .team-savebar{
    position:sticky;
    top:12px;
    z-index:30;
    box-shadow: inset 0 0 0 2px var(--night-3), 0 var(--px) 0 0 var(--night-0);
  }
  .page-team .team-savebar--dirty{ box-shadow: inset 0 0 0 var(--px) var(--gold), 0 var(--px) 0 0 var(--night-0); }
  .page-team .lineup-slot{ min-height:124px; padding-top:24px; }
  .page-team .lineup-sprite{ width:48px; height:48px; }
  .page-team .unit-detail-sprite{ width:64px; height:64px; }
}
/* no room for two columns in the details: stack them */
@media (max-width: 1000px){
  .unit-detail-body{ grid-template-columns:1fr; }
}
/* where the page has to scroll, the save bar stays pinned to the bottom
   of the screen instead */
@media (max-width: 760px), (max-height: 599px){
  .page-team .team-shell{ padding-bottom: calc(96px + env(safe-area-inset-bottom, 0px)); }
  .team-savebar{
    position:fixed;
    left:8px;
    right:8px;
    bottom: calc(8px + env(safe-area-inset-bottom, 0px));
    z-index:30;
    box-shadow: inset 0 0 0 2px var(--night-3), 0 var(--px) 0 0 var(--night-0);
  }
  .team-savebar--dirty{ box-shadow: inset 0 0 0 var(--px) var(--gold), 0 var(--px) 0 0 var(--night-0); }
  .team-savebar .team-save-btn{ padding:10px 18px; }
}

/* ---- inventory: a bag of square slots; hovering (or focusing) a weapon
   pops up its card ---- */
.item-grid{
  list-style:none;
  margin:24px 0 0;
  padding:0;
  display:grid;
  grid-template-columns:repeat(6, 64px);
  gap:10px;
}
.item-slot{
  position:relative;
  width:64px;
  height:64px;
  display:flex;
  align-items:center;
  justify-content:center;
  padding:0;
  border:none;
  border-radius:0;
  font:inherit;
  color:inherit;
  background:var(--night-2);
  box-shadow: inset 0 0 0 var(--px) var(--night-3), 0 var(--px) 0 0 var(--night-0);
}
button.item-slot{ cursor:pointer; }
.item-slot:not(.item-slot--empty):hover, .item-slot:focus-visible{
  outline:none;
  background:var(--night-3);
  box-shadow: inset 0 0 0 var(--px) var(--gold), 0 var(--px) 0 0 var(--night-0);
}
.item-slot--empty{ background:rgba(11,8,24,0.45); box-shadow: inset 0 0 0 2px var(--night-2); }
.item-sprite{ width:40px; height:40px; image-rendering:pixelated; }
.item-tip{
  display:none;
  position:absolute;
  bottom:calc(100% + 10px);
  left:50%;
  transform:translateX(-50%);
  z-index:40;
  width:max-content;
  max-width:220px;
  flex-direction:column;
  gap:3px;
  padding:8px 10px;
  text-align:left;
  background:var(--night-0);
  box-shadow: 0 0 0 2px var(--gold), 0 6px 0 0 rgba(11,8,24,0.55);
  pointer-events:none;
}
.item-slot:hover .item-tip, .item-slot:focus-visible .item-tip{ display:flex; }
.item-tip-name{ font-weight:400; font-size:14px; color:var(--cream); }
.item-tip-cat{ font-size:14px; color:var(--gold); text-transform:uppercase; letter-spacing:1px; }
.item-tip-mods{ font-size:14px; font-weight:400; color:var(--hp-good); }
.item-tip-reduction{ font-size:14px; font-weight:400; color:var(--gold); }
.item-tip-hint{ font-size:14px; color:var(--royal-light); line-height:1.4; }
.item-tip-lore{ font-size:14px; color:var(--muted); line-height:1.4; }
/* a stack of crafting materials: how many, in the bottom right corner */
.item-count{
  position:absolute;
  right:4px;
  bottom:2px;
  font-family:"Digits", "Pixelify Sans", monospace;
  font-size:20px;
  line-height:1;
  color:var(--cream);
  text-shadow: 2px 2px 0 var(--night-0);
}
.item-slot--rare{ box-shadow: inset 0 0 0 var(--px) var(--violet), 0 var(--px) 0 0 var(--night-0); }
/* an item the unit can't wear with its current weapon (a shield next to a bow) */
.item-slot--locked{ opacity:0.4; cursor:not-allowed; }

/* the bag as a window over any page (the top bar's inventory button, see
   static/inventory.js); the dialog has no padding of its own, so a click
   landing on it is a click on the backdrop */
.inventory-modal{
  width:min(480px, calc(100vw - 24px));
  max-height:none;
  overflow:visible;
  padding:0;
  border-radius:0;
  color:var(--cream);
  background:var(--night-0);
  box-shadow: 0 8px 0 0 rgba(11,8,24,0.6);
}
/* the windows' frame and the result card's: a 16x16 nine-slice
   (assets/ui/frame.png), 5 art pixels a side */
.inventory-modal, .start-card{
  border:calc(5 * var(--px)) solid transparent;
  border-image:url("/assets/ui/frame.png") 5 / calc(5 * var(--px)) round;
  background-clip:padding-box;
  image-rendering:pixelated;
}
.inventory-modal::backdrop{ background:rgba(11,8,24,0.72); }
.inventory-modal-head{
  display:flex;
  justify-content:space-between;
  align-items:center;
  padding:14px 16px 0;
  font-size:14px;
  font-weight:400;
  color:var(--gold);
  text-transform:uppercase;
  letter-spacing:1px;
}
.inventory-modal-close{ border:none; background:none; color:var(--muted); font:inherit; cursor:pointer; }
.inventory-modal-close:hover{ color:var(--cream); }
.inventory-modal-body{ padding:4px 16px 20px; }
.inventory-modal-body .team-intro{ margin:8px 0 0; font-size:14px; line-height:1.5; }
.inventory-modal-body .item-grid{ margin-top:16px; grid-template-columns:repeat(auto-fill, 64px); }
/* too short a window for the whole bag: let it scroll (hover cards may
   then be cut at its edges) */
@media (max-height: 599px){
  .inventory-modal{ max-height:calc(100dvh - 24px); overflow-y:auto; }
}
/* the top bar's pages (Edit Team, grimoire, settings) in the same kind of
   window, as big as the screen allows but with backdrop left around it */
.inventory-modal.page-modal{
  width:min(1280px, calc(100vw - 64px));
  height:calc(100dvh - 64px);
  max-height:none;
  overflow:hidden;
  display:none;
  flex-direction:column;
}
.inventory-modal.page-modal[open]{ display:flex; }
.inventory-modal.page-modal--small{ width:min(560px, calc(100vw - 64px)); height:min(620px, calc(100dvh - 64px)); }
/* the page's own heading sits top left, where its back link was; ✕ takes
   the corner its top bar leaves free */
.page-modal-close{ position:absolute; top:10px; right:14px; z-index:1; font-size:20px; padding:4px 8px; }
.page-modal-frame{ flex:1; width:100%; border:none; display:block; background:var(--night-1); }
/* page-modal.js: until the page in the window has loaded, the window
   shows dots instead of a page drawing itself; then it steps in */
.page-modal--loading .page-modal-frame{ visibility:hidden; }
.page-modal:not(.page-modal--loading) .page-modal-frame{ animation:page-modal-in 0.16s steps(4); }
@keyframes page-modal-in{ from{ opacity:0; } }
.page-modal--loading::after{
  content:"..."; position:absolute; inset:0; display:flex; align-items:center; justify-content:center;
  font-size:32px; color:var(--gold); animation:page-modal-wait 0.9s steps(3) infinite;
}
@keyframes page-modal-wait{ from{ opacity:0.3; } }
@media (prefers-reduced-motion: reduce){ .page-modal-frame, .page-modal--loading::after{ animation:none !important; } }
@media (max-width: 480px){
  .inventory-modal.page-modal, .inventory-modal.page-modal--small{ width:calc(100vw - 16px); height:calc(100dvh - 16px); }
}
/* a page inside that window: the window has the way back, and the
   game's buttons stay in the real top bar */
html.framed .top-bar, html.framed .hud-back{ display:none; }
html.framed .hud{ top:14px; }

/* team builder: a unit's weapon slot and the mini inventory it opens */
.weapon-slot{
  width:56px;
  height:56px;
  display:flex;
  align-items:center;
  justify-content:center;
  padding:0;
  border:none;
  border-radius:0;
  font:inherit;
  font-size:24px;
  color:var(--muted);
  background:var(--night-1);
  cursor:pointer;
  box-shadow: inset 0 0 0 var(--px) var(--gold-deep);
}
.weapon-slot:hover, .weapon-slot:focus-visible, .weapon-slot[aria-expanded="true"]{
  outline:none;
  background:var(--night-3);
  box-shadow: inset 0 0 0 var(--px) var(--gold);
}
.weapon-slot--empty{ box-shadow: inset 0 0 0 2px var(--night-3); }
.weapon-slot .item-sprite{ width:40px; height:40px; }
.weapon-slot-text{ font-size:14px; font-weight:400; }
.weapon-popover{
  position:fixed;
  z-index:50;
  width:min(320px, calc(100vw - 24px));
  padding:12px;
  background:var(--night-0);
  box-shadow: 0 0 0 var(--px) var(--gold), 0 8px 0 0 rgba(11,8,24,0.6);
}
.weapon-popover-head{
  display:flex;
  justify-content:space-between;
  align-items:center;
  margin-bottom:10px;
  font-size:14px;
  font-weight:400;
  color:var(--gold);
  text-transform:uppercase;
  letter-spacing:1px;
}
.weapon-popover-close{
  border:none;
  background:none;
  color:var(--muted);
  font:inherit;
  cursor:pointer;
}
.weapon-popover-close:hover{ color:var(--cream); }
.weapon-popover-grid{ display:grid; grid-template-columns:repeat(4, 64px); gap:8px; justify-content:start; }
/* in the picker the card opens below the item, clear of the slot above */
.weapon-popover .item-tip{ top:calc(100% + 10px); bottom:auto; }
/* opened above the slot: the card goes up too, off the slot below */
.weapon-popover--above .item-tip{ top:auto; bottom:calc(100% + 10px); }
.weapon-popover-empty{ margin:0; font-size:14px; color:var(--muted); }
.weapon-popover-unequip{
  margin-top:12px;
  width:100%;
  border:none;
  font:inherit;
  font-size:14px;
  color:var(--cream);
  background:var(--night-2);
  padding:6px 10px;
  cursor:pointer;
}
.weapon-popover-unequip:hover{ background:var(--royal); }
.weapon-popover-unequip[hidden]{ display:none; }

/* ---- store ----
   The shop's picture is the background (darkened so the text reads), and
   its shelves hang on the bare wall to its right: every item with its
   stats and buy button, in two columns where they fit. */
/* a shop's or a tavern's picture (data/shops.json, data/taverns.json),
   filling the screen behind the page */
.scene-bg{
  position:fixed;
  inset:0;
  z-index:0;
  width:100%;
  height:100%;
  object-fit:cover;
  object-position:left center;
  image-rendering:pixelated;
  filter:brightness(0.8);
}
.shop-shell{ max-width:none; margin:0; display:flex; justify-content:flex-end; }
.shop-shelves{
  width:min(700px, 100%);
  padding:14px 16px 16px;
  background:rgba(11,8,24,0.86);
  box-shadow:
    calc(-1 * var(--px)) 0 0 0 var(--night-0),
    var(--px) 0 0 0 var(--night-0),
    0 calc(-1 * var(--px)) 0 0 var(--night-0),
    0 var(--px) 0 0 var(--night-0);
}
.shop-shelf-label{ margin:12px 0 8px; font-size:14px; color:var(--gold); text-transform:uppercase; letter-spacing:1px; }
.shop-shelf-label:first-child{ margin-top:0; }
.shop-items{
  list-style:none;
  margin:0;
  padding:0;
  display:grid;
  grid-template-columns:repeat(auto-fill, minmax(300px, 1fr));
  gap:6px;
}
/* sprite, name and stats, price: one row per item */
.shop-item{
  display:grid;
  grid-template-columns:36px 1fr auto;
  align-items:center;
  column-gap:10px;
  padding:6px 8px;
  background:var(--royal-deep);
}
.shop-item-sprite{ width:36px; height:36px; image-rendering:pixelated; }
.shop-item-body{ display:flex; flex-direction:column; min-width:0; line-height:1.3; }
.shop-item-name{ font-size:15px; color:var(--cream); }
.shop-item-stat{ font-size:14px; color:var(--cream); opacity:0.85; }
/* gear tiers (storage.Tier): the label under an item's name, and the
   name itself coloured from intermediate up */
.item-tip-tier, .shop-item-tier{ font-size:13px; text-transform:uppercase; letter-spacing:1px; color:var(--muted); }
.item-tip-name.tier--intermediate, .item-tip-tier.tier--intermediate,
.shop-item-name.tier--intermediate, .shop-item-tier.tier--intermediate{ color:var(--hp-good); }
.item-tip-name.tier--advanced, .item-tip-tier.tier--advanced,
.shop-item-name.tier--advanced, .shop-item-tier.tier--advanced{ color:var(--arcane); }
.item-tip-name.tier--legendary, .item-tip-tier.tier--legendary,
.shop-item-name.tier--legendary, .shop-item-tier.tier--legendary{ color:var(--gold); }
.shop-item-hint{ font-size:14px; color:var(--royal-light); }
.shop-item form{ margin:0; }
.shop-item-buy{ font-size:14px; padding:6px 10px; white-space:nowrap; }
/* selling a material: one, or the whole stack */
.shop-sell{ display:flex; flex-direction:column; gap:6px; }
.shop-empty{ margin:0; font-size:14px; color:var(--cream); opacity:0.85; }
/* what a recipe takes: have/need per ingredient, the missing ones in red */
.craft-needs{ display:flex; flex-wrap:wrap; gap:2px 10px; margin-top:4px; }
.craft-need{ display:inline-flex; align-items:center; gap:3px; font-family:"Digits", "Pixelify Sans", monospace; font-size:18px; color:var(--gold); }
.craft-need img{ width:20px; height:20px; image-rendering:pixelated; }
.craft-need--missing{ color:var(--royal-light); }
@media (min-width: 1000px){
  /* on the wall, clear of the smith */
  .shop-shell{ padding-right:4%; }
}

/* the tavern has a single panel: recruiting, over the tavern's picture
   (a .scene-bg, see the store). On a wide screen it hangs on the bare wall
   to the right, leaving the innkeeper in sight. */
.tavern-shell{ max-width:480px; }
@media (min-width: 1000px){
  .tavern-shell{ margin-right:6%; }
}
/* the candidates a recruit offers, side by side (stacked on a phone) */
.tavern-offer{
  position:relative;
  width:min(900px, 100%);
  max-height:100%;
  overflow-y:auto;
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:6px;
  animation: store-pop 0.24s steps(3) both;
}
.tavern-offer .map-panel-eyebrow{ font-size:24px; font-weight:600; color:var(--gold); }
.tavern-offer-list{
  list-style:none;
  margin:8px 0 0;
  padding:0;
  width:100%;
  display:grid;
  grid-template-columns:repeat(auto-fit, minmax(220px, 1fr));
  gap:14px;
}
.store-popup .store-reveal.tavern-candidate{ width:auto; animation:none; margin:0; padding:16px 14px; display:flex; flex-direction:column; align-items:center; }
.tavern-candidate form{ margin-top:auto; padding-top:10px; }
.tavern-candidate .menu-btn{ font-size:14px; padding:8px 20px; }
@media (prefers-reduced-motion: reduce){
  .tavern-offer{ animation:none; }
}
/* the tavern's panel */
.store-section{ background:var(--royal-deep); padding:16px 18px 18px; min-width:0; }
.store-section .builder-heading{ margin-bottom:8px; }
.store-section .store-hint:first-of-type{ margin:0 0 12px; font-size:14px; line-height:1.4; }

/* what was just bought, over the store or the tavern: a click anywhere
   outside the card closes it (the backdrop is a link back to the page) */
.store-popup{
  position:fixed;
  inset:0;
  z-index:40;
  display:flex;
  align-items:center;
  justify-content:center;
  padding:16px;
}
.store-popup[hidden]{ display:none; }
.store-popup-backdrop{ position:absolute; inset:0; background:rgba(11,8,24,0.72); }
.store-popup .store-reveal{
  position:relative;
  width:min(340px, 100%);
  margin:0;
  padding:20px 18px;
  animation: store-pop 0.24s steps(3) both;
}
.store-popup .store-reveal--error{ background:var(--night-2); }
.store-popup-msg{ margin:4px 0; text-align:center; font-size:14px; line-height:1.5; }
.store-popup-actions{ display:flex; flex-direction:column; align-items:center; gap:10px; margin-top:10px; }
.store-popup-actions .menu-btn{ text-decoration:none; font-size:14px; padding:8px 16px; }
.store-popup-close{ font-size:14px; color:var(--cream); }
@keyframes store-pop{
  from{ transform:scale(0.6); opacity:0; }
  to{ transform:scale(1); opacity:1; }
}
@media (prefers-reduced-motion: reduce){
  .store-popup .store-reveal{ animation:none; }
}

@media (max-width: 760px){
  .builder{ grid-template-columns:1fr; }
  .roster-list{ max-height:none; }
  .lineup-slots{ gap:8px; }
  .lineup-slot{ min-height:128px; }
  .lineup-sprite{ width:44px; height:44px; }
}

/* ---- gold & store ---- */
.nav-gold{
  display:inline-flex;
  align-items:center;
  gap:8px;
  height:40px;
  box-sizing:border-box;
  padding:0 12px 0 10px;
  background:var(--night-2);
  color:var(--gold);
  font-weight:400;
  font-size:20px;
}
/* coin.png is 8x8 art: 3x here */
.nav-gold .gold-coin{ width:24px; height:24px; }
.nav-items{
  display:inline-flex;
  align-items:center;
  gap:6px;
  height:40px;
  box-sizing:border-box;
  padding:0 12px 0 4px;
  background:var(--night-2);
  color:var(--cream);
  font-weight:400;
  font-size:20px;
  text-decoration:none;
}
.nav-items:hover{ background:var(--night-3); color:var(--gold); }
.nav-items img{ width:32px; height:32px; image-rendering:pixelated; }
.gold-chip{
  display:inline-flex;
  align-items:center;
  gap:8px;
  margin:0 0 22px;
  padding:6px 12px;
  background:var(--night-0);
  color:var(--gold);
  font-weight:400;
}
/* web/assets/ui/coin.png (8x8 art pixels) drawn at 2x */
.gold-coin{ width:16px; height:16px; image-rendering:pixelated; }
.store-card .menu-tagline{ margin-top:0; }
.store-buy{ width:100%; font-size:15px; padding:10px 12px; }
.store-hint{ margin:14px 0 0; color:var(--muted); font-size:14px; }
.store-reveal{
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:6px;
  margin:0 0 24px;
  padding:16px 12px;
  background:var(--royal);
  box-shadow:
    calc(-1 * var(--px)) 0 0 0 var(--gold),
    var(--px) 0 0 0 var(--gold),
    0 calc(-1 * var(--px)) 0 0 var(--gold),
    0 var(--px) 0 0 var(--gold);
}
.store-reveal .map-panel-eyebrow{ color:var(--gold); }
.store-reveal .char-card-stats{ color:var(--cream); }
.store-reveal-sprite{ width:80px; height:80px; }

/* ---- world map ("/map", and the village) ----
   The picture fills the whole screen, like a background cropped with
   "cover": the box keeps the image's 11:6 ratio
   (web/assets/maps/main.jpg, 1408×768; maps/village.jpeg has the same)
   so points stay on their x/y percentages, and whatever sticks out of
   the screen is reached by scrolling (map.js drags it with the mouse and
   starts it centred). Panels, notices and buttons float over it. */
body.page-map{ height:100vh; height:100dvh; overflow:hidden; }
.map-shell{
  position:fixed;
  inset:0;
  z-index:2;
  overflow:auto;
  scrollbar-width:none;
  overscroll-behavior:none;
}
.map-shell::-webkit-scrollbar{ display:none; }
.map-shell--dragging{ cursor:grabbing; }
.map-notice{
  position:fixed;
  top:calc(76px + env(safe-area-inset-top, 0px));
  left:50%;
  transform:translateX(-50%);
  z-index:4;
  width:max-content;
  max-width:calc(100% - 20px);
  margin:0;
  padding:8px 14px;
  background:var(--night-0);
  color:var(--cream);
  font-size:14px;
  text-align:center;
}
.map-wrap{
  position:relative;
  width:max(100vw, 100dvh * 11 / 6);
  aspect-ratio:11 / 6;
  background:var(--night-2);
}
.map-bg{
  position:absolute;
  inset:0;
  width:100%;
  height:100%;
  object-fit:cover;
  display:block;
  image-rendering:pixelated;
}
.map-pins{ position:absolute; inset:0; }
.map-pin{
  position:absolute;
  transform:translate(-50%, -50%);
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:2px;
  padding:6px 12px;
  font-family:inherit;
  font-weight:400;
  color:var(--cream);
  background:var(--royal);
  border:none;
  cursor:pointer;
  box-shadow:
    calc(-1 * var(--px)) 0 0 0 var(--night-0),
    var(--px) 0 0 0 var(--night-0),
    0 calc(-1 * var(--px)) 0 0 var(--night-0),
    0 var(--px) 0 0 var(--night-0),
    0 calc(2 * var(--px)) 0 0 var(--night-0);
}
a.map-pin{ text-decoration:none; }
.map-pin--level{ background:var(--gold); color:var(--night-0); }
.map-pin--skirmish{ background:var(--night-3); color:var(--gold); }
.map-pin--village, .map-pin--place{ background:var(--night-0); color:var(--gold); }
.map-pin--dialogue{ background:var(--night-3); color:var(--cream); }
.map-pin--shop{ background:var(--night-0); color:var(--gold); }
.map-pin--pvp{ background:var(--arcane); color:var(--night-0); }
.map-pin:hover, .map-pin:focus-visible{ transform:translate(-50%, calc(-50% - var(--px))); outline:none; }
/* pins of nearby places may overlap: the one pointed at (or open) comes on top */
.map-pin:hover, .map-pin:focus-visible, .map-pin--active{ z-index:1; }
.map-pin--active, .map-pin:focus-visible{
  box-shadow:
    calc(-1 * var(--px)) 0 0 0 var(--cream),
    var(--px) 0 0 0 var(--cream),
    0 calc(-1 * var(--px)) 0 0 var(--cream),
    0 var(--px) 0 0 var(--cream),
    0 calc(2 * var(--px)) 0 0 var(--night-0);
}
.map-pin-icon{ font-size:20px; line-height:1; }
/* 12x12 art drawn at 2x (web/assets/ui/pins/) */
.map-pin-img{ display:block; width:24px; height:24px; image-rendering:pixelated; }
.map-pin-label{ font-size:14px; white-space:nowrap; }

.map-panel{
  position:fixed;
  left:12px;
  right:12px;
  bottom:calc(12px + env(safe-area-inset-bottom, 0px));
  z-index:5;
  max-width:760px;
  max-height:calc(100dvh - 100px);
  margin:0 auto;
  overflow:auto;
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:20px;
  flex-wrap:wrap;
  padding:18px 22px;
  background:var(--royal-deep);
  background-image: linear-gradient(var(--royal) 0 var(--px), transparent var(--px));
  box-shadow:
    calc(-1 * var(--px)) 0 0 0 var(--night-0),
    var(--px) 0 0 0 var(--night-0),
    0 calc(-1 * var(--px)) 0 0 var(--night-0),
    0 var(--px) 0 0 var(--night-0),
    0 calc(3 * var(--px)) 0 0 rgba(11,8,24,0.55);
}
.map-panel[hidden]{ display:none; }
.map-panel-body{ flex:1; min-width:220px; }
.map-panel-eyebrow{
  display:inline-block;
  padding:2px 8px;
  font-size:14px;
  font-weight:400;
  background:var(--royal);
  color:var(--cream);
}
.map-panel--level .map-panel-eyebrow{ background:var(--gold); color:var(--night-0); }
.map-panel h2{ margin:8px 0 6px; font-size:22px; }
.map-panel p{ margin:0; color:var(--muted); font-size:14px; line-height:1.6; max-width:56ch; }
.map-enemies{ margin-top:12px; }
.map-enemies-label{ font-size:14px; font-weight:400; color:var(--gold); }
.map-enemies-row{ display:flex; gap:10px; margin-top:6px; }
.map-enemy-slot{ display:flex; flex-direction:column; align-items:center; justify-content:flex-end; gap:2px; }
.map-enemy{ width:40px; height:40px; image-rendering:pixelated; }
.map-enemy-stars{ display:flex; gap:1px; padding:2px 3px; background:var(--night-0); }
.map-enemy-stars img{ width:9px; height:9px; image-rendering:pixelated; }
.map-enemies-boost{ display:block; margin-top:6px; font-size:14px; color:var(--royal-light); }
.map-panel-actions{ display:flex; align-items:center; gap:12px; }
.map-panel-close{
  font:inherit;
  font-size:18px;
  color:var(--cream);
  background:none;
  border:none;
  padding:4px 8px;
  cursor:pointer;
}
.map-panel-close:hover{ color:var(--gold); }

/* the village's way out, where other pages have their back link */
.map-nav{
  position:fixed;
  top:calc(18px + env(safe-area-inset-top, 0px));
  left:calc(20px + env(safe-area-inset-left, 0px));
  z-index:6;
}
.map-nav .menu-btn{ font-size:14px; padding:8px 14px; }

/* ---- mail (/mail, every player) and the admin page (/admin) ---- */
.nav-mail--unread #nav-mail{ color:var(--royal-light); }
.mail-shell{
  position:relative;
  z-index:2;
  max-width:720px;
  margin:0 auto;
  padding: calc(104px + env(safe-area-inset-top, 0px)) 16px calc(40px + env(safe-area-inset-bottom, 0px));
}
html.framed .mail-shell{ padding-top:72px; }
.mail-shell h2{ font-weight:400; font-size:20px; color:var(--gold); margin:0 0 12px; }
.mail-empty{ color:var(--muted); font-size:14px; }
.mail-list{ list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:6px; }
.mail-item{
  display:flex;
  flex-direction:column;
  gap:4px;
  padding:10px 12px;
  background:var(--night-2);
  color:var(--muted);
  text-decoration:none;
}
.mail-item:hover, .mail-item:focus-visible{ background:var(--night-3); outline:none; }
.mail-item-subject{ font-size:16px; overflow-wrap:anywhere; }
.mail-item--unread .mail-item-subject{ color:var(--cream); }
.mail-item-meta{ font-size:14px; }
.mail-new{ font-size:13px; text-transform:uppercase; letter-spacing:1px; color:var(--night-0); background:var(--gold); padding:0 4px; }
.letter{ background:var(--night-2); padding:18px 20px; }
/* the window hides the header's way back: the letter brings its own */
.letter-back{ display:none; font-size:14px; color:var(--muted); text-decoration:none; margin-bottom:12px; }
html.framed .letter-back{ display:inline-block; }
.letter-back:hover{ color:var(--gold); }
.letter .letter-subject{ font-size:24px; color:var(--cream); margin:0 0 6px; overflow-wrap:anywhere; }
.letter-meta{ margin:0 0 16px; font-size:14px; color:var(--muted); }
.letter-body{ font-size:16px; line-height:1.6; color:var(--cream); white-space:pre-wrap; overflow-wrap:anywhere; }
/* a letter's gift: what it gives, and the button that collects it */
.mail-gift{ font-size:13px; text-transform:uppercase; letter-spacing:1px; color:var(--cream); background:var(--royal); padding:0 4px; }
.letter-gift{
  margin-top:20px;
  padding:12px 14px;
  background:var(--night-1);
  border:2px solid var(--gold);
  box-shadow:4px 4px 0 var(--night-0);
}
.letter-gift h3{ margin:0 0 8px; font-weight:400; font-size:16px; text-transform:uppercase; letter-spacing:1px; color:var(--gold); }
.letter-gift ul{ margin:0 0 12px; padding-left:20px; font-size:16px; color:var(--cream); }
.letter-gift li + li{ margin-top:4px; }
.letter-gift form{ margin:0; }
.letter-gift--claimed{ border-color:var(--muted); }
.letter-gift--claimed h3{ color:var(--muted); }
.letter-gift-done{ margin:0; font-size:14px; color:var(--hp-good); }

/* ---- achievements (/achievements): every feat, how far along, its reward ---- */
.nav-achievements--ready #nav-achievements{ color:var(--gold); }
.achievements-summary{ margin:0 0 20px; font-size:16px; color:var(--muted); }
.achievements-group + .achievements-group{ margin-top:24px; }
.achievements-list{ list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:6px; }
.achievement{
  display:grid;
  grid-template-columns:32px 1fr auto;
  align-items:center;
  gap:12px;
  padding:10px 12px;
  background:var(--night-2);
  border:2px solid transparent;
}
.achievement--ready{ border-color:var(--gold); box-shadow:4px 4px 0 var(--night-0); }
.achievement-icon{ width:32px; height:32px; image-rendering:pixelated; filter:grayscale(1); opacity:.4; }
.achievement--unlocked .achievement-icon{ filter:none; opacity:1; }
.achievement-text{ display:flex; flex-direction:column; gap:4px; min-width:0; }
.achievement-name{ font-size:16px; color:var(--muted); overflow-wrap:anywhere; }
.achievement--unlocked .achievement-name{ color:var(--cream); }
.achievement-goal{ font-size:14px; color:var(--muted); overflow-wrap:anywhere; }
.achievement-bar{ display:block; height:8px; background:var(--night-0); max-width:240px; }
.achievement-bar-fill{ display:block; height:100%; background:var(--gold-deep); }
.achievement--unlocked .achievement-bar-fill{ background:var(--gold); }
.achievement-count{ font-family:"Digits", "Pixelify Sans", ui-monospace, monospace; font-size:16px; color:var(--muted); }
.achievement-reward{ display:flex; flex-direction:column; align-items:flex-end; gap:6px; }
.achievement-rewards{ display:flex; gap:10px; font-family:"Digits", "Pixelify Sans", ui-monospace, monospace; font-size:18px; color:var(--gold); }
.achievement-reward form{ margin:0; }
.achievement-reward .menu-btn{ font-size:14px; padding:6px 12px; }
.achievement-done{ font-size:14px; color:var(--hp-good); }
@media (max-width:520px){
  .achievement{ grid-template-columns:32px 1fr; }
  .achievement-reward{ grid-column:2; align-items:flex-start; }
}

/* ---- pvp (/pvp): the player's rating, the ladder, their last fights ---- */
.pvp-intro{ margin:0 0 16px; font-size:16px; color:var(--muted); }
.pvp-me{
  display:flex;
  flex-wrap:wrap;
  align-items:center;
  gap:12px 24px;
  margin-bottom:28px;
  padding:14px 16px;
  background:var(--night-2);
  border:2px solid var(--gold);
  box-shadow:4px 4px 0 var(--night-0);
}
.pvp-me-figures{ display:flex; gap:24px; flex-wrap:wrap; }
.pvp-figure{ display:flex; flex-direction:column; gap:2px; }
.pvp-figure-label{ font-size:13px; text-transform:uppercase; letter-spacing:1px; color:var(--muted); }
.pvp-figure-value{ font-family:"Digits", "Pixelify Sans", ui-monospace, monospace; font-size:28px; color:var(--gold); }
.pvp-fight{ margin-left:auto; }
.pvp-hint{ flex-basis:100%; margin:0; font-size:14px; color:var(--muted); }
.pvp-hint a{ color:var(--gold); }
.pvp-section + .pvp-section{ margin-top:28px; }
.pvp-ladder, .pvp-history{ list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:4px; }
.pvp-row, .pvp-fight{
  display:grid;
  align-items:center;
  gap:12px;
  padding:8px 12px;
  background:var(--night-2);
  font-size:16px;
  color:var(--cream);
}
.pvp-row{ grid-template-columns:40px 1fr auto 56px; cursor:pointer; list-style:none; }
.pvp-row::-webkit-details-marker{ display:none; }
.pvp-row:hover, .pvp-row:focus-visible{ background:var(--night-3); outline:none; }
.pvp-entry{ background:var(--night-2); }
.pvp-entry--mine, .pvp-entry--mine .pvp-row{ background:var(--royal-deep); }
.pvp-entry--mine{ box-shadow:4px 4px 0 var(--night-0); }
.pvp-entry details[open] .pvp-row{ border-bottom:2px solid var(--night-0); }
.pvp-gap{ padding:0 12px; color:var(--muted); }
.pvp-who{ display:flex; flex-direction:column; gap:4px; min-width:0; }
.pvp-team-strip{ display:flex; gap:2px; }
.pvp-mini{ width:32px; height:32px; image-rendering:pixelated; }
/* an opened row: each hero of the team, with its gear */
.pvp-team{ list-style:none; margin:0; padding:8px 12px 12px 64px; display:flex; flex-direction:column; gap:8px; }
.pvp-member{ display:grid; grid-template-columns:48px 1fr auto; align-items:center; gap:12px; }
.pvp-member-sprite{ width:48px; height:48px; image-rendering:pixelated; }
.pvp-member-text{ display:flex; flex-direction:column; gap:2px; min-width:0; }
.pvp-member-name{ font-size:16px; color:var(--cream); overflow-wrap:anywhere; }
.pvp-member-class{ font-size:14px; color:var(--muted); }
.pvp-member-gear{ display:flex; flex-direction:column; align-items:flex-start; gap:4px; }
.pvp-gear{ display:inline-flex; align-items:center; gap:6px; font-size:14px; color:var(--muted); }
.pvp-gear img{ width:24px; height:24px; image-rendering:pixelated; }
.pvp-rank, .pvp-rating, .pvp-record, .pvp-delta{ font-family:"Digits", "Pixelify Sans", ui-monospace, monospace; font-size:18px; }
.pvp-rank{ color:var(--muted); }
.pvp-name{ overflow-wrap:anywhere; }
.pvp-record{ color:var(--muted); }
.pvp-rating{ text-align:right; color:var(--gold); }
.pvp-fight{ grid-template-columns:1fr auto 48px; border-left:4px solid var(--muted); }
.pvp-fight--won{ border-left-color:var(--hp-good); }
.pvp-fight--lost{ border-left-color:var(--royal-light); }
.pvp-fight-text{ overflow-wrap:anywhere; }
.pvp-fight-when{ font-size:14px; color:var(--muted); }
.pvp-delta{ text-align:right; color:var(--muted); }
.pvp-delta--up{ color:var(--hp-good); }
.pvp-delta--down{ color:var(--royal-light); }
/* the result card's rating line, after a fight against another player */
.start-card p.overlay-reward:has(.rating-chip){ flex-wrap:wrap; }
.rating-chip{ flex-basis:100%; justify-content:center; font-family:"Pixelify Sans", monospace; font-size:18px; }
.rating-chip--up{ color:var(--hp-good); }
.rating-chip--down{ color:var(--royal-light); }

/* ---- expeditions (/expedition): the path, the stage reached, the party ---- */
.exp-intro{ margin:0 0 16px; font-size:16px; color:var(--muted); }
.exp-hint{ margin:0 0 12px; font-size:14px; color:var(--muted); }
.exp-hint a{ color:var(--gold); }
.exp-error{
  margin:0 0 16px;
  padding:8px 12px;
  background:var(--royal-deep);
  border:2px solid var(--royal-light);
  color:var(--cream);
  font-size:14px;
}
.exp-result, .exp-stage{
  margin-bottom:20px;
  padding:14px 16px;
  background:var(--night-2);
  box-shadow:4px 4px 0 var(--night-0);
}
.exp-result{ border-left:4px solid var(--hp-good); }
.exp-result p{ margin:8px 0 0; font-size:16px; color:var(--cream); }
.exp-result-line{ display:flex; align-items:center; gap:8px; }
.exp-result-line img{ width:32px; height:32px; image-rendering:pixelated; }
.exp-stage{ border:2px solid var(--gold); }
.exp-stage--boss{ border-color:var(--royal-light); }
.exp-stage h2{ margin:4px 0 8px; }
.exp-stage p{ margin:0 0 12px; font-size:16px; color:var(--cream); }
.exp-stage > .menu-btn{ display:inline-block; margin-top:16px; }
.exp-stage .map-enemies{ margin-bottom:4px; }
.exp-choices{ display:flex; flex-direction:column; gap:8px; }
.exp-choice{
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  gap:4px;
  padding:10px 14px;
  background:var(--night-1);
  border:2px solid var(--gold-deep);
  box-shadow:3px 3px 0 var(--night-0);
  color:var(--cream);
  font:inherit;
  text-align:left;
  cursor:pointer;
}
.exp-choice:hover, .exp-choice:focus-visible{ background:var(--night-3); border-color:var(--gold); outline:none; }
.exp-choice:active{ transform:translateY(var(--px)); }
.exp-choice-label{ font-size:18px; color:var(--gold); }
a.exp-choice{ text-decoration:none; }
.exp-choice:disabled, .exp-choice.menu-btn--off{ opacity:.5; cursor:not-allowed; }
.exp-choice:disabled:hover, .exp-choice.menu-btn--off:hover{ background:var(--night-1); border-color:var(--gold-deep); }
.exp-choice-effects{ font-size:14px; color:var(--muted); }
.exp-party{ margin-bottom:20px; }
.exp-members{ list-style:none; margin:0 0 12px; padding:0; display:flex; flex-direction:column; gap:4px; }
.exp-member{
  display:grid;
  grid-template-columns:48px 1fr auto;
  align-items:center;
  gap:12px;
  padding:8px 12px;
  background:var(--night-2);
}
.exp-member--reserve{ background:var(--night-1); }
.exp-member--fallen{ background:var(--night-1); opacity:0.6; }
.exp-member--fallen .exp-member-sprite{ filter:grayscale(1); }
.exp-member-sprite{ width:48px; height:48px; image-rendering:pixelated; }
.exp-member-text{ display:flex; flex-direction:column; gap:2px; min-width:0; }
.exp-member-name{ font-size:16px; color:var(--cream); overflow-wrap:anywhere; }
.exp-member-class{ font-size:14px; color:var(--muted); }
.exp-hp{ display:block; height:8px; max-width:200px; margin-top:4px; background:var(--night-0); }
.exp-hp-fill{ display:block; height:100%; background:var(--hp-good); }
.exp-hp-fill--mid{ background:var(--hp-mid); }
.exp-hp-fill--low{ background:var(--hp-low); }
.exp-hp-text{ font-family:"Digits", "Pixelify Sans", ui-monospace, monospace; font-size:16px; color:var(--muted); }
.exp-pick{ display:contents; cursor:pointer; }
.exp-pick input{ grid-column:3; grid-row:1; width:20px; height:20px; accent-color:var(--gold); }
.exp-member:has(.exp-pick input:checked){ background:var(--royal-deep); }
.exp-abandon{ margin-top:28px; text-align:right; }
.exp-abandon-btn{
  background:none;
  border:none;
  padding:0;
  font:inherit;
  font-size:14px;
  color:var(--muted);
  text-decoration:underline;
  cursor:pointer;
}
.exp-abandon-btn:hover{ color:var(--royal-light); }
/* the report at an expedition's end (/expedition/report): how it ended,
   all it paid, the party as it came back */
.exp-report{
  margin-bottom:20px;
  padding:14px 16px;
  background:var(--night-2);
  border:2px solid var(--gold);
  box-shadow:4px 4px 0 var(--night-0);
}
.exp-report--failed{ border-color:var(--royal-light); }
.exp-report--abandoned{ border-color:var(--muted); }
.mail-shell .exp-report-outcome{ margin:4px 0 12px; font-size:24px; font-weight:600; color:var(--gold); }
.mail-shell .exp-report--failed .exp-report-outcome{ color:var(--royal-light); }
.mail-shell .exp-report--abandoned .exp-report-outcome{ color:var(--cream); }
.exp-report-figures{ display:flex; flex-wrap:wrap; gap:8px 28px; margin:0; }
.exp-report-figures div{ display:flex; flex-direction:column; gap:2px; }
.exp-report-figures dt{ font-size:13px; text-transform:uppercase; color:var(--muted); }
.exp-report-figures dd{
  display:flex;
  align-items:center;
  gap:6px;
  margin:0;
  font-family:"Digits", "Pixelify Sans", ui-monospace, monospace;
  font-size:24px;
  color:var(--cream);
}
.exp-report-figures dd img{ width:20px; height:20px; image-rendering:pixelated; }
.exp-report-loot{ margin-bottom:20px; }
.exp-report-heading{ margin:12px 0 6px; font-weight:400; font-size:16px; color:var(--cream); }
.exp-loot{ list-style:none; margin:0; padding:0; display:grid; grid-template-columns:repeat(auto-fill, minmax(200px, 1fr)); gap:6px; }
.exp-loot-piece{
  display:flex;
  align-items:center;
  gap:8px;
  padding:6px 10px;
  background:var(--night-2);
  box-shadow:3px 3px 0 var(--night-0);
}
.exp-loot-piece img{ width:32px; height:32px; flex:none; image-rendering:pixelated; }
.exp-loot-name{ flex:1; min-width:0; font-size:14px; color:var(--cream); overflow-wrap:anywhere; }
.exp-loot-count{ font-family:"Digits", "Pixelify Sans", ui-monospace, monospace; font-size:18px; color:var(--gold); }
.exp-shell > .menu-btn{ display:inline-block; }
/* Edit Team on an expedition: the party's HP under each name; the fallen
   can't be seated */
.roster-item .exp-hp{ max-width:none; }
.roster-item--fallen{ opacity:0.55; }
.roster-item--fallen .roster-item-sprite{ filter:grayscale(1); }
.exp-order-prepare{ display:block; margin-top:12px; text-align:center; }
.map-panel-underway{ color:var(--gold); }
/* under way the page fills the screen and never scrolls: on the left the
   scene (the expedition's picture, its path on top, the party standing in
   it, the first in the formation in front, on the right), what the last
   stage gave and the stage to play; on the right, all the way down, the
   formation. A narrow screen stacks them and scrolls. */
.exp-shell--wide{
  max-width:1200px;
  height:100vh;
  height:100dvh;
  display:flex;
  flex-direction:column;
  padding-bottom:calc(16px + env(safe-area-inset-bottom, 0px));
}
html.framed .exp-shell--wide{ padding-top:72px; }
.exp-layout{
  flex:1;
  min-height:0;
  display:grid;
  grid-template-columns:minmax(0, 1fr) 320px;
  gap:20px;
}
.exp-main{ display:flex; flex-direction:column; gap:16px; min-height:0; overflow-y:auto; }
.exp-main > .exp-result, .exp-main > .exp-stage{ margin-bottom:0; flex-shrink:0; }
.exp-main > .exp-abandon{ margin-top:auto; flex-shrink:0; }
body.page-expedition:has(.exp-shell--wide){ overflow:hidden; }
@media (max-width:820px){
  body.page-expedition:has(.exp-shell--wide){ overflow:auto; }
  .exp-shell--wide{ height:auto; }
  .exp-layout{ grid-template-columns:minmax(0, 1fr); }
  .exp-main{ overflow:visible; }
  .exp-scene{ flex:none; aspect-ratio:1408 / 768; }
}
.exp-scene{
  position:relative;
  flex:1 1 220px;
  min-height:220px;
  overflow:hidden;
  background:var(--night-0);
  border:2px solid var(--gold);
  box-shadow:4px 4px 0 var(--night-0);
}
.exp-scene-bg{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; image-rendering:pixelated; }
.exp-path{
  position:absolute;
  top:10px;
  left:10px;
  right:10px;
  margin:0;
  padding:0;
  list-style:none;
  display:flex;
  flex-wrap:wrap;
  justify-content:center;
  gap:4px;
}
.exp-node{
  display:flex;
  align-items:center;
  justify-content:center;
  width:34px;
  height:34px;
  background:rgba(11, 8, 24, 0.75);
  border:2px solid var(--night-3);
  box-shadow:2px 2px 0 var(--night-0);
}
.exp-node img{ width:22px; height:22px; image-rendering:pixelated; }
.exp-node--done{ opacity:0.5; }
.exp-node--current{ border-color:var(--gold); background:var(--royal-deep); }
.exp-node-mark{ font-size:18px; color:var(--muted); }
/* a stage still to draw: its pool's icon, dimmed, with the "?" in its corner */
.exp-node--hidden{ position:relative; }
.exp-node--hidden img{ opacity:0.6; }
.exp-node--hidden img + .exp-node-mark{
  position:absolute;
  right:-4px;
  bottom:-6px;
  font-size:14px;
  color:var(--gold);
  text-shadow:1px 1px 0 var(--night-0);
}
.exp-walkers{
  position:absolute;
  left:4%;
  right:4%;
  bottom:8%;
  display:flex;
  flex-direction:row-reverse;
  justify-content:center;
  align-items:flex-end;
  gap:8px;
}
/* a fixed size, whatever the scene's: sized on it, the sprites stretched */
.exp-walker{ position:relative; flex:none; width:72px; height:72px; }
.exp-walker--reserve{ width:56px; height:56px; opacity:0.75; }
.exp-walker::after{
  content:"";
  position:absolute;
  left:22%;
  right:22%;
  bottom:2px;
  height:5px;
  background:var(--night-0);
  border-radius:50%;
  opacity:0.45;
}
.exp-walker-sprite{
  position:relative;
  z-index:1;
  display:block;
  width:100%;
  height:100%;
  object-fit:contain;
  image-rendering:pixelated;
  transform-origin:50% 92%;
  transform:scale(var(--sprite-scale, 1));
  filter:drop-shadow(2px 2px 0 var(--night-0));
}
.exp-walker-hp{ position:absolute; z-index:2; top:-6px; left:18%; right:18%; height:5px; background:var(--night-0); }
.exp-walker-hp .exp-hp-fill{ height:100%; }
/* beside it, the formation, dragged */
.exp-order{
  min-height:0;
  overflow-y:auto;
  padding:14px 16px;
  background:var(--night-2);
  box-shadow:4px 4px 0 var(--night-0);
}
.exp-order h2{ margin:0 0 6px; }
.exp-zone-label{ display:block; font-size:13px; text-transform:uppercase; letter-spacing:1px; color:var(--muted); }
.exp-zone{
  list-style:none;
  margin:4px 0 12px;
  padding:4px;
  min-height:60px;
  display:flex;
  flex-direction:column;
  gap:4px;
  background:var(--night-1);
  border:2px dashed var(--night-3);
  counter-reset:seat;
}
.exp-zone[data-zone="field"]{ border-color:var(--gold-deep); }
.exp-zone--fallen{ border-style:solid; }
.exp-zone:not(:has(.exp-row))::after{
  content:attr(data-empty);
  padding:14px 8px;
  text-align:center;
  font-size:14px;
  color:var(--muted);
}
.exp-row{
  position:relative;
  display:grid;
  grid-template-columns:40px 1fr auto;
  align-items:center;
  gap:10px;
  padding:6px 8px;
  background:var(--night-2);
  cursor:grab;
  touch-action:none;
  user-select:none;
  -webkit-user-select:none;
}
.exp-row:hover{ background:var(--night-3); }
.exp-row:focus-visible{ outline:2px solid var(--gold); outline-offset:-2px; }
.exp-zone[data-zone="field"] .exp-row:not(.exp-row--ghost){ counter-increment:seat; }
.exp-zone[data-zone="field"] .exp-row:not(.exp-row--ghost)::before{
  content:counter(seat);
  position:absolute;
  top:2px;
  left:2px;
  min-width:16px;
  padding:0 3px;
  background:var(--gold);
  color:var(--night-0);
  font-family:"Digits", "Pixelify Sans", ui-monospace, monospace;
  font-size:14px;
  text-align:center;
}
.exp-row-sprite{ width:40px; height:40px; image-rendering:pixelated; }
.exp-row .exp-hp{ max-width:none; }
.exp-row .exp-hp-text{ font-size:14px; }
.exp-row--fallen{ cursor:default; opacity:0.55; }
.exp-row--fallen:hover{ background:var(--night-2); }
.exp-row--fallen .exp-row-sprite{ filter:grayscale(1); }
.exp-row--dragging{
  position:fixed;
  z-index:1000;
  pointer-events:none;
  border:2px solid var(--gold);
  box-shadow:6px 6px 0 var(--night-0);
  cursor:grabbing;
}
.exp-row--ghost{ background:transparent; border:2px dashed var(--gold); }
body.exp-dragging{ cursor:grabbing; user-select:none; -webkit-user-select:none; }
.exp-order-status{ min-height:18px; margin:0; font-size:14px; color:var(--hp-good); }
.exp-order-status--bad{ color:var(--royal-light); }
.menu-btn.menu-btn--off, .menu-btn.menu-btn--off:hover{ background:var(--night-3); color:var(--muted); cursor:default; }
/* the result card's line on what the fight did to the expedition */
.start-card p.overlay-reward:has(.expedition-chip){ flex-wrap:wrap; }
.expedition-chip{ flex-basis:100%; text-align:center; font-size:18px; color:var(--cream); }
.expedition-chip--next, .expedition-chip--complete{ color:var(--hp-good); }
.expedition-chip--failed{ color:var(--royal-light); }
.expedition-chip--retry{ color:var(--gold); }
@media (max-width:520px){
  .pvp-team{ padding-left:12px; }
  .pvp-member{ grid-template-columns:48px 1fr; }
  .pvp-member-gear{ grid-column:2; }
  .pvp-row{ grid-template-columns:32px 1fr auto; }
  .pvp-row .pvp-record{ display:none; }
  .pvp-fight{ grid-template-columns:1fr 48px; }
  .pvp-fight-when{ grid-column:1; grid-row:2; }
  .pvp-fight .pvp-delta{ grid-row:1 / span 2; grid-column:2; }
  .pvp-fight{ grid-template-rows:auto auto; }
}

.admin-compose{ margin-bottom:32px; }
.admin-compose .auth-form{ max-width:none; }
.auth-form select, .auth-form textarea{
  font:inherit;
  font-size:16px;
  color:var(--cream);
  background:var(--night-1);
  padding:9px 10px;
  outline:none;
}
.auth-form textarea{ resize:vertical; line-height:1.5; }
.admin-gift{
  display:flex;
  flex-wrap:wrap;
  gap:12px 16px;
  margin:0;
  padding:10px 12px 14px;
  border:2px dashed var(--night-3);
}
.admin-gift legend{ padding:0 6px; font-size:14px; color:var(--gold); }
.admin-gift label{ flex:1 1 160px; min-width:0; }
.admin-gift-hint{ flex:1 0 100%; margin:0; font-size:14px; color:var(--muted); }
.auth-form .menu-btn{ align-self:flex-start; }
.form-ok{
  margin:0 0 18px;
  padding:8px 10px;
  background:var(--night-0);
  color:var(--hp-good);
  font-size:14px;
}
.admin-table-wrap{ overflow-x:auto; }
.admin-table{ width:100%; border-collapse:separate; border-spacing:0 4px; font-size:14px; }
.admin-table th{ padding:4px 10px; font-weight:400; font-size:13px; text-transform:uppercase; letter-spacing:1px; color:var(--muted); text-align:left; white-space:nowrap; }
.admin-table td{ padding:8px 10px; background:var(--night-2); color:var(--cream); white-space:nowrap; }
.admin-table a{ color:var(--gold); }
.admin-badge{ font-size:13px; text-transform:uppercase; color:var(--night-0); background:var(--gold); padding:0 4px; }
.admin-unknown{ color:var(--muted); }

/* admins only: developer tools on the world map, folded until opened */
.debug-panel{
  position:fixed;
  left:calc(16px + env(safe-area-inset-left, 0px));
  bottom:calc(16px + env(safe-area-inset-bottom, 0px));
  z-index:20;
  padding:6px 12px;
  background:rgba(11,8,24,0.85);
  border:2px dashed var(--muted);
}
.debug-panel[open]{ padding-bottom:10px; }
.debug-panel form{ margin:8px 0 0; }
.debug-panel-title{ font-size:13px; font-weight:400; color:var(--muted); text-transform:uppercase; letter-spacing:2px; cursor:pointer; list-style:none; }
.debug-panel-title::-webkit-details-marker{ display:none; }
.debug-panel-title::before{ content:"▸ "; }
.debug-panel[open] .debug-panel-title::before{ content:"▾ "; }
.debug-panel-title:hover{ color:var(--cream); }
.debug-panel button{
  width:100%;
  font:inherit;
  font-size:14px;
  color:var(--cream);
  background:var(--night-2);
  border:none;
  padding:5px 10px;
  cursor:pointer;
  text-align:left;
}
.debug-panel button:hover{ background:var(--royal); }

/* /map?coords=1 helper for placing points in data/levels.json */
.map-wrap--coords{ cursor:crosshair; }
.map-coords{
  position:fixed;
  left:10px;
  bottom:10px;
  z-index:6;
  padding:6px 10px;
  background:rgba(11,8,24,0.85);
  color:var(--hp-good);
  font-size:14px;
  pointer-events:none;
}
.map-coords-marker{
  position:absolute;
  width:12px;
  height:12px;
  margin:-6px 0 0 -6px;
  background:var(--royal-light);
  box-shadow:0 0 0 2px var(--night-0);
  pointer-events:none;
}

/* ---- landing page ("/": the way in and the news) ---- */
.landing{
  padding:0 0 56px;
  position:relative;
  z-index:2;
}
/* the hero, wall to wall: the plains under a night veil, the picture
   fading out at the bottom into the page's starry sky */
.landing-hero{
  position:relative;
  isolation:isolate;
  text-align:center;
  padding:112px 16px 96px;
}
.landing-hero::before{
  content:"";
  position:absolute;
  inset:0;
  z-index:-1;
  background:
    linear-gradient(180deg, rgba(11,8,24,0.55) 0%, rgba(11,8,24,0.3) 50%, rgba(11,8,24,0.1) 100%),
    url("/assets/arenas/plains-arena.jpeg") center 60% / cover;
  image-rendering:pixelated;
  -webkit-mask-image:linear-gradient(180deg, #000 55%, transparent 100%);
  mask-image:linear-gradient(180deg, #000 55%, transparent 100%);
}
.landing-hero-inner{ max-width:760px; margin:0 auto; }
.landing-hero .landing-pitch{ color:var(--cream); text-shadow:2px 2px 0 var(--night-0); }
.landing-hero .logo-sub{ font-size:18px; text-shadow:2px 2px 0 var(--night-0); }
.landing-body{ max-width:960px; margin:0 auto; padding:0 16px; }
.landing-logo{ font-weight:600; font-size:64px; line-height:1.1; margin:0; }
.landing-pitch{
  max-width:600px;
  margin:20px auto 0;
  color:var(--muted);
  font-size:17px;
  line-height:1.6;
}
/* a match about to start: the front line nearest the VS */
.landing-lineup{
  display:flex;
  align-items:flex-end;
  justify-content:center;
  gap:20px;
  margin:36px 0 32px;
}
.landing-side{ display:flex; flex-direction:row-reverse; gap:8px; }
.landing-side--enemy{ flex-direction:row; }
.landing-side img{
  width:64px;
  height:64px;
  image-rendering:pixelated;
  filter:drop-shadow(4px 4px 0 var(--night-0));
}
.landing-side--enemy img{ transform:scaleX(-1); filter:drop-shadow(-4px 4px 0 var(--night-0)); }
.landing-vs{
  font-size:32px;
  font-weight:600;
  color:var(--gold);
  text-shadow:3px 3px 0 var(--royal), 6px 6px 0 var(--night-0);
  align-self:center;
}
.landing-actions{
  display:flex;
  flex-wrap:wrap;
  justify-content:center;
  gap:20px;
}
.landing-section{ padding:32px 0; }
.landing-heading{
  margin:0 0 24px;
  text-align:center;
  font-size:28px;
  font-weight:600;
  color:var(--cream);
  text-shadow:3px 3px 0 var(--night-0);
}
.landing-features{
  list-style:none;
  margin:0;
  padding:0;
  display:grid;
  grid-template-columns:repeat(auto-fit, minmax(200px, 1fr));
  gap:24px;
}
.landing-card{ background:var(--night-2); padding:20px; }
.landing-card h3{ margin:12px 0 8px; font-size:20px; color:var(--gold); }
.landing-card p{ margin:0; color:var(--muted); font-size:15px; line-height:1.6; }
/* 12x12 pin art at 3x */
.landing-icon{ width:36px; height:36px; image-rendering:pixelated; display:block; }
.landing-steps{
  list-style:none;
  margin:0 auto;
  padding:0;
  max-width:600px;
  display:flex;
  flex-direction:column;
  gap:16px;
}
.landing-steps li{
  display:flex;
  align-items:center;
  gap:16px;
  background:var(--royal-deep);
  padding:14px 18px;
  font-size:16px;
  line-height:1.5;
}
.landing-step-num{
  flex:none;
  width:36px;
  height:36px;
  display:flex;
  align-items:center;
  justify-content:center;
  background:var(--gold);
  color:var(--night-0);
  font-size:22px;
}
.landing-card, .landing-steps li{
  box-shadow:
    calc(-1 * var(--px)) 0 0 0 var(--night-0),
    var(--px) 0 0 0 var(--night-0),
    0 calc(-1 * var(--px)) 0 0 var(--night-0),
    0 var(--px) 0 0 var(--night-0),
    0 calc(3 * var(--px)) 0 0 rgba(11,8,24,0.55);
}
/* the news: cards in a row, scrolled sideways and snapping to a card;
   the arrows (static/landing.js) beside the heading */
.landing-news-head{ position:relative; }
.landing-news-nav{
  position:absolute;
  right:0;
  top:0;
  display:flex;
  gap:12px;
}
.landing-news-nav[hidden]{ display:none; }
.landing-news-arrow{
  width:40px;
  height:40px;
  padding:0;
  border:0;
  font-family:inherit;
  font-size:28px;
  line-height:1;
  color:var(--night-0);
  background:var(--gold);
  cursor:pointer;
  box-shadow:
    calc(-1 * var(--px)) 0 0 0 var(--night-0),
    var(--px) 0 0 0 var(--night-0),
    0 calc(-1 * var(--px)) 0 0 var(--night-0),
    0 var(--px) 0 0 var(--night-0);
}
.landing-news-arrow:disabled{ background:var(--night-3); color:var(--muted); cursor:default; }
.landing-news{
  display:flex;
  gap:24px;
  overflow-x:auto;
  scroll-snap-type:x mandatory;
  scroll-padding-inline:var(--px);
  scroll-behavior:smooth;
  /* room for the cards' stepped borders and hard shadows */
  padding:var(--px) var(--px) calc(4 * var(--px));
  scrollbar-width:thin;
  scrollbar-color:var(--gold) var(--night-0);
}
.landing-news:focus-visible{ outline:var(--px) solid var(--gold); outline-offset:var(--px); }
/* two and a half cards in view: the cut one says the row goes on */
.news-post{
  flex:0 0 calc((100% - 2 * 24px) / 2.5);
  scroll-snap-align:start;
  display:flex;
  flex-direction:column;
  gap:12px;
}
/* the row's end is a snap point too, or the last cards could never be
   reached when their starts lie past it */
.news-post:last-child{ scroll-snap-align:end; }
.news-image{
  width:64px; height:64px; flex:none;
  image-rendering:pixelated;
  filter:drop-shadow(4px 4px 0 var(--night-0));
}
.news-text{ min-width:0; }
.news-date{ font-size:13px; text-transform:uppercase; letter-spacing:1px; color:var(--royal-light); }
.news-post h3{ margin:4px 0 8px; }
.news-post p{ margin:0 0 8px; }
.news-post p:last-child{ margin-bottom:0; }
/* the author's letter: one person talking, signed at the bottom */
.landing-letter{ max-width:640px; margin:0 auto; padding:24px 28px; }
.landing-letter .landing-icon{ margin:0 auto 16px; }
.landing-letter p{ margin:0 0 14px; color:var(--cream); font-size:16px; line-height:1.7; }
.landing-letter .landing-signature{
  margin:20px 0 0;
  text-align:right;
  font-size:24px;
  font-weight:600;
  color:var(--gold);
  text-shadow:2px 2px 0 var(--royal);
}
/* the cast: every recruitable hero, drawn with their name */
.landing-cast{
  list-style:none;
  margin:0;
  padding:0;
  display:grid;
  grid-template-columns:repeat(auto-fill, minmax(104px, 1fr));
  gap:16px;
}
.landing-cast li{
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:8px;
  text-align:center;
  font-size:14px;
  color:var(--cream);
}
.landing-cast img{ width:64px; height:64px; image-rendering:pixelated; }
.landing-cast + .landing-pitch{ text-align:center; }
.landing-final{ text-align:center; }
.landing-final .landing-pitch{ margin:0 auto 24px; color:var(--cream); }
/* the auth card's title leads back to the landing page */
.logo-link{ color:inherit; text-decoration:none; }
.logo-link:hover{ color:inherit; }
@media (max-width: 480px){
  .landing-logo{ font-size:40px; }
  .landing-lineup{ gap:10px; }
  .landing-side{ gap:4px; }
  .landing-side img{ width:32px; height:32px; }
  .landing-vs{ font-size:24px; }
  .landing-actions .menu-btn{ width:100%; }
  .landing-hero{ padding:96px 16px 72px; }
  .news-post{ flex-basis:85%; }
  .news-image{ width:48px; height:48px; }
  .landing-letter{ padding:20px 16px; }
  .landing-cast{ grid-template-columns:repeat(auto-fill, minmax(80px, 1fr)); gap:12px; }
  .landing-cast img{ width:48px; height:48px; }
}

@media (prefers-reduced-motion: reduce){
  .rig.defeated, .hpbar-fill{ transition:none; }
  .team-savebar--dirty .team-save-btn:not(:disabled){ animation:none; }
  /* the WAAPI-driven walk/strike/recoil/heal animations check this same
     media query in app.js before playing, so nothing further to disable here */
}

@media (max-width: 480px){
  .hud h1{ font-size:24px; }
  .menu-card h1{ font-size:28px; }
  .fighter{ width:50px; height:50px; margin-top:-29px; }
  .posB4{ left:calc(95% - 50px); }
  .shadow{ width:30px; height:6px; }
  .hpbar{ top:-12px; height:8px; }
  .status-row{ top:-28px; }
  .arena{ --log-strip:118px; }
  .battle-log{ height:88px; font-size:14px; max-width:none; }
  .hud-teams{ display:none; }
  /* a phone keeps the art at 1x so the bar leaves room for the back link */
  .top-bar{ gap:4px; padding:4px; right:calc(8px + env(safe-area-inset-right, 0px)); top:calc(10px + env(safe-area-inset-top, 0px)); }
  .nav-icons{ gap:4px; }
  .nav-icon img, .nav-items img{ width:16px; height:16px; }
  .nav-gold, .nav-items{ height:24px; font-size:14px; padding:0 6px 0 4px; gap:4px; }
  .nav-icon{ height:24px; }
  .nav-icon, .nav-gold, .nav-items{ min-width:44px; }
  .nav-gold .gold-coin{ width:16px; height:16px; }
  .lang-switch{ gap:2px; font-size:14px; }
  .lang-switch a, .lang-switch .lang-current{ padding:3px 5px; }
  .map-pin{ padding:4px 8px; }
  .map-notice{ top:calc(48px + env(safe-area-inset-top, 0px)); padding:4px 8px; font-size:13px; }
  /* on a phone the panel spans the screen's width */
  .map-panel{ left:8px; right:8px; bottom:8px; max-height:70dvh; padding:14px 16px; }
  .map-pin-icon{ font-size:16px; }
  .map-pin-label{ font-size:13px; }
}

/* ---- grimoire: a guide, then every character and skill, a page each ---- */
.grimoire-shell{ max-width:1280px; padding-top: calc(52px + env(safe-area-inset-top, 0px)); }
html.framed .grimoire-shell{ padding-top:20px; }
.grimoire-tabs{ display:flex; gap:12px; flex-wrap:wrap; margin:18px 0 8px; }
.grimoire-tabs .menu-btn{ text-decoration:none; font-size:14px; padding:8px 16px; }
.grimoire-tabs .menu-btn[aria-current]{ cursor:default; }
.grimoire-section{ margin-top:20px; padding:16px 18px 18px; background:var(--royal-deep); }
.grimoire-pager{ display:flex; gap:12px; margin-top:18px; }
.grimoire-pager .menu-btn{ text-decoration:none; font-size:14px; padding:8px 16px; }
.grimoire-pager-next{ margin-left:auto; }
.grimoire-chars{ list-style:none; margin:0; padding:0; display:grid; grid-template-columns:repeat(auto-fill, minmax(280px, 1fr)); gap:12px; }
.grimoire-char{ padding:14px 16px 16px; background:var(--night-2); scroll-margin-top:96px; }
.grimoire-char:target, .grimoire-skill:target{ box-shadow: inset 0 0 0 var(--px) var(--gold); }
.grimoire-sprite{ width:64px; height:64px; flex:none; image-rendering:pixelated; }
.grimoire-name{ margin:0; font-size:18px; }
.grimoire-desc{ margin:12px 0 0; font-size:15px; line-height:1.5; color:var(--cream); }
/* a monster not met yet: its silhouette on a blank page */
.grimoire-char--hidden .grimoire-name{ color:var(--muted); }
.grimoire-char--hidden .grimoire-desc{ color:var(--muted); font-style:italic; }
.grimoire-sprite--unknown{ filter:brightness(0); opacity:0.55; }
.grimoire-met-count{ margin:0 0 8px; font-size:14px; color:var(--muted); }
/* the Owl's note on a beast, its verdict in the colour of its kind */
.grimoire-owl{
  margin:12px 0 0; padding:8px 12px;
  background:var(--night-1);
  border-left:var(--px) solid var(--muted);
}
.grimoire-owl p{ margin:4px 0 0; font-size:15px; line-height:1.5; color:var(--cream); font-style:italic; }
.grimoire-owl-head{ display:flex; align-items:center; gap:8px; font-size:14px; color:var(--muted); }
.grimoire-owl-head img{ width:32px; height:32px; image-rendering:pixelated; }
.grimoire-owl-verdict{ font-weight:400; font-size:13px; text-transform:uppercase; letter-spacing:1px; }
.grimoire-owl--dangerous{ border-left-color:var(--royal-light); }
.grimoire-owl--dangerous .grimoire-owl-verdict{ color:var(--royal-light); }
.grimoire-owl--harmless{ border-left-color:var(--hp-good); }
.grimoire-owl--harmless .grimoire-owl-verdict{ color:var(--hp-good); }
.grimoire-owl--leave_alone{ border-left-color:var(--arcane); }
.grimoire-owl--leave_alone .grimoire-owl-verdict{ color:var(--arcane); }
/* the equipment page: a grid per tier and kind, like the skills' */
.grimoire-item-kind{ margin:14px 0 8px; font-size:14px; }
.grimoire-item-head{ display:flex; align-items:center; gap:10px; margin-bottom:4px; }
.grimoire-char .unit-stats{ margin:14px 0 8px; }
.grimoire-char .skills-heading{ margin:14px 0 4px; font-size:14px; }
.grimoire-links{ margin:0; font-size:14px; color:var(--muted); line-height:1.5; }
.grimoire-skills{ list-style:none; margin:0; padding:0; display:grid; grid-template-columns:repeat(auto-fill, minmax(260px, 1fr)); gap:8px; }
.grimoire-skill{ display:flex; flex-direction:column; gap:2px; padding:10px 12px; background:var(--night-1); scroll-margin-top:96px; }
.grimoire-skill .grimoire-links{ margin-top:4px; font-size:14px; }
.grimoire-zone{ margin:18px 0 8px; scroll-margin-top:96px; }

/* the guide: a chapter per page, each with an illustration ("scene")
   built from the game's own sprites (grimoire_scenes.go) */
.guide-layout{ display:grid; grid-template-columns:220px 1fr; gap:16px; align-items:start; }
.guide-toc ol{ margin:0; padding:0; list-style:none; counter-reset:chapter; display:flex; flex-direction:column; gap:4px; }
.guide-toc li{ counter-increment:chapter; }
.guide-toc a{ display:block; padding:8px 10px; background:var(--night-1); color:var(--cream); text-decoration:none; font-size:14px; }
.guide-toc a::before{ content:counter(chapter) ". "; color:var(--gold); }
.guide-toc a:hover{ background:var(--night-3); }
.guide-toc a[aria-current]{ background:var(--gold); color:var(--night-0); }
.guide-toc a[aria-current]::before{ color:var(--night-0); }
.guide-toc--plain a::before{ content:none; }
.grimoire-entries{ min-width:0; }
.grimoire-entries > .grimoire-zone:first-child{ margin-top:0; }
.guide-chapter{ min-width:0; padding:16px 18px 18px; background:var(--night-2); }
.guide-figure{ margin:0 0 16px; padding:14px; background:var(--night-1); box-shadow: inset 0 0 0 var(--px) var(--night-0); }
.guide-figure figcaption{ margin-top:12px; font-size:14px; color:var(--muted); }
.guide-text{ font-size:15px; line-height:1.65; max-width:760px; }
.guide-text p{ margin:0 0 12px; }
.guide-text ul{ margin:0 0 12px; padding-left:20px; }
.guide-text li{ margin-bottom:6px; }
.guide-tip{ padding:10px 14px; background:var(--night-1); border-left:var(--px) solid var(--gold); }

.scene-sprite{ width:48px; height:48px; flex:none; image-rendering:pixelated; }
.scene-label{ margin:14px 0 8px; font-size:14px; color:var(--muted); }
.scene-legend{ display:flex; flex-wrap:wrap; align-items:center; gap:6px 10px; margin:10px 0 0; font-size:14px; color:var(--muted); }
.legend-swatch{ display:inline-block; width:12px; height:12px; margin-left:4px; background:var(--night-3); }
.legend-swatch--fired{ background:var(--gold); }
.legend-swatch--ally{ background:var(--royal); }
.legend-swatch--enemy{ background:var(--night-3); }
.legend-swatch--dead{ background:var(--night-0); }
.legend-swatch--wait{ background:var(--royal-deep); }
.legend-swatch--ready{ background:var(--night-2); box-shadow: inset 0 0 0 2px var(--night-3); }
.legend-icon{ width:12px; height:12px; margin-right:6px; vertical-align:middle; image-rendering:pixelated; }
.scene-legend--text{ display:block; }
.scene-scroll{ overflow-x:auto; }

/* stats: three hero cards with stat bars */
.scene-stats{ display:grid; grid-template-columns:repeat(auto-fit, minmax(min(220px, 100%), 1fr)); gap:12px; }
.scene-card{ padding:12px; background:var(--night-2); }
.scene-card-head{ display:flex; align-items:center; gap:10px; font-size:16px; }
.scene-card-head .scene-sprite{ width:64px; height:64px; }
.stat-bars{ display:flex; flex-direction:column; gap:6px; margin:10px 0; }
.stat-bar{ display:grid; grid-template-columns:34px 1fr 26px; align-items:center; gap:6px; font-size:14px; }
.stat-bar b{ text-align:right; }
.bar{ height:12px; background:var(--night-0); }
.bar-fill{ display:block; height:100%; }
.bar-fill--strength{ background:var(--royal-light); }
.bar-fill--agility{ background:var(--hp-good); }
.bar-fill--intelligence{ background:var(--arcane); }
.bar-fill--stamina{ background:var(--gold); }
.bar-fill--initiative{ background:var(--muted); }
.scene-derived{ display:grid; grid-template-columns:1fr 1fr; gap:4px; margin:0; font-size:14px; }
.scene-derived div{ display:flex; justify-content:space-between; gap:6px; padding:3px 6px; background:var(--night-1); }
.scene-derived dt{ color:var(--muted); }
.scene-derived dd{ margin:0; font-weight:400; }
.scene-derived-wide{ grid-column:1 / -1; }

/* damage: a hit as an equation, then a meter strip */
.dmg-equation{ display:flex; flex-wrap:wrap; align-items:center; gap:6px; }
.dmg-chip{ display:flex; flex-direction:column; align-items:center; min-width:52px; padding:4px 8px; background:var(--night-2); font-size:20px; font-weight:400; }
.dmg-chip small{ font-size:13px; font-weight:400; color:var(--muted); }
.dmg-chip--shield{ flex-direction:row; gap:4px; font-size:14px; }
.dmg-chip--shield .scene-sprite{ width:32px; height:32px; }
.dmg-chip--hit{ background:var(--royal); }
.dmg-chip--hit small{ color:var(--cream); }
.dmg-op{ color:var(--gold); font-size:20px; font-weight:400; }
.meter-strip{ display:flex; flex-wrap:wrap; gap:8px; margin:0; padding:0; list-style:none; counter-reset:attempt; }
.meter-step{ counter-increment:attempt; display:flex; flex-direction:column; align-items:center; gap:4px; width:44px; padding:6px 4px; background:var(--night-2); font-size:14px; }
.meter-step::before{ content:"#" counter(attempt); color:var(--muted); font-size:13px; }
.meter{ position:relative; width:14px; height:48px; background:var(--night-0); }
.meter-fill{ position:absolute; left:0; right:0; bottom:0; background:var(--night-3); }
.meter-amount{ font-weight:400; font-size:14px; }
.meter-step.is-fired{ background:var(--gold); color:var(--night-0); }
.meter-step.is-fired::before{ color:var(--night-0); }
.meter-step.is-fired .meter-fill{ background:var(--royal); }

/* turn order: the round's queue, numbered */
.turn-queue{ display:flex; flex-wrap:wrap; gap:8px; margin:0; padding:0; list-style:none; counter-reset:turn; }
.turn-slot{ counter-increment:turn; display:flex; flex-direction:column; align-items:center; gap:2px; width:78px; padding:6px 4px 8px; background:var(--royal); font-size:14px; }
.turn-slot::before{ content:counter(turn); font-size:18px; font-weight:400; color:var(--gold); }
.turn-slot.is-enemy{ background:var(--night-3); }
.turn-agi{ font-weight:400; }
.turn-pos{ color:var(--muted); }

/* targets: a small arena per rule */
.scene-targets{ display:flex; flex-direction:column; gap:10px; }
.target-row .scene-label{ display:block; margin:0 0 4px; color:var(--gold); }
.target-field{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.target-side{ display:flex; gap:4px; }
.target-vs{ color:var(--muted); font-size:14px; }
.target-slot{ position:relative; display:flex; flex-direction:column; align-items:center; gap:2px; padding:4px; background:var(--night-2); }
.target-slot .scene-sprite{ width:40px; height:40px; }
.target-slot.is-target{ background:var(--gold); }
.target-slot.is-dead{ background:var(--night-0); }
.target-slot.is-dead .scene-sprite{ opacity:0.3; filter:grayscale(1); }
.mini-hp{ display:block; width:36px; height:4px; background:var(--night-0); }
.mini-hp span{ display:block; height:100%; background:var(--hp-good); }
.slot-pos{ position:absolute; top:2px; left:4px; font-size:13px; font-weight:400; color:var(--cream); text-shadow:1px 1px 0 var(--night-0); }

/* skill queue: skills by turn */
.queue-table, .weapons-table{ border-collapse:separate; border-spacing:4px; font-size:14px; }
.queue-table th, .weapons-table th{ padding:4px 8px; background:var(--night-2); font-weight:400; text-align:left; white-space:nowrap; }
.queue-table th small, .weapons-table th small{ display:block; font-weight:400; font-size:13px; color:var(--muted); }
.queue-table thead th{ text-align:center; }
.queue-table td{ width:40px; height:36px; text-align:center; font-weight:400; font-size:15px; }
.queue-table td.is-used{ background:var(--gold); color:var(--night-0); }
.queue-table td.is-wait{ background:var(--royal-deep); color:var(--cream); }
.queue-table td.is-ready{ background:var(--night-2); color:var(--muted); box-shadow: inset 0 0 0 2px var(--night-3); }
.queue-table th.is-lost{ background:var(--royal-deep); }
.legend-lost{ margin:0 4px 0 12px; color:var(--royal-light); }

/* weapons: can this weapon use that skill */
.weapons-table thead th{ min-width:64px; max-width:120px; text-align:center; vertical-align:bottom; white-space:normal; }
.weapons-table td{ min-width:44px; text-align:center; font-size:16px; font-weight:400; }
.weapons-table td.is-yes{ background:var(--hp-good); color:var(--night-0); }
.weapons-table td.is-no{ background:var(--night-0); color:var(--royal-light); }
.weapons-weapon{ display:flex; align-items:center; gap:6px; }
.weapons-weapon .scene-sprite, .weapons-shield .scene-sprite{ width:32px; height:32px; }
.teacher-list{ display:flex; flex-wrap:wrap; gap:8px; margin:0; padding:0; list-style:none; font-size:14px; }
.teacher-list li{ display:flex; align-items:center; gap:6px; padding:4px 10px 4px 4px; background:var(--night-2); }
.teacher-list .scene-sprite{ width:32px; height:32px; }

/* debuffs: stun meter and poison stacks */
.scene-debuffs{ display:grid; grid-template-columns:repeat(auto-fit, minmax(min(320px, 100%), 1fr)); gap:12px; }
.debuff-panel{ padding:12px; background:var(--night-2); }
.debuff-panel .meter-step{ background:var(--night-1); }
.debuff-panel .meter-step.is-fired{ background:var(--gold); }
.debuff-head{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; font-size:16px; }
.debuff-head strong{ margin-right:auto; }
.debuff-icon{ width:24px; height:24px; image-rendering:pixelated; }
.debuff-head .scene-sprite{ width:40px; height:40px; }
.poison-rounds{ display:flex; flex-direction:column; gap:4px; margin:0; padding:0; list-style:none; }
.poison-rounds li{ display:grid; grid-template-columns:72px 1fr auto; align-items:center; gap:8px; padding:4px 8px; background:var(--night-1); font-size:14px; }
.poison-stacks{ display:flex; gap:3px; }
.poison-stacks img{ width:16px; height:16px; image-rendering:pixelated; }
.poison-damage{ color:var(--poison); font-weight:400; font-size:15px; }

@media (max-width: 760px){
  .guide-layout{ grid-template-columns:1fr; }
  .guide-toc ol{ flex-direction:row; flex-wrap:wrap; }
  .guide-toc a{ font-size:14px; padding:6px 8px; }
  .guide-chapter{ padding:12px; }
  .guide-figure{ padding:10px; }
  .debuff-head .scene-sprite{ width:32px; height:32px; }
}
.grimoire-zone .school-tag{ font-size:16px; padding:2px 8px; }

/* ---- the tutorial (static/tutorial.js): a light on one element, the
   rest darkened, a pointing hand (assets/ui/hand.png) and a bubble ---- */
.tour-spot{
  position:fixed;
  z-index:1000;
  pointer-events:none;
  box-shadow:
    0 0 0 var(--px) var(--gold),
    0 0 0 calc(2 * var(--px)) var(--night-0),
    0 0 0 9999px rgba(11,8,24,0.72);
}
.tour-blocker{ position:fixed; inset:0; z-index:1001; }
.tour-blocker--dark{ background:rgba(11,8,24,0.72); }
.tour-hand{
  position:fixed;
  z-index:1002;
  width:48px;
  height:48px;
  pointer-events:none;
  animation:tour-nudge-up 0.8s steps(1) infinite;
}
.tour-hand--down{ animation-name:tour-nudge-down; }
.tour-hand-img{ width:48px; height:48px; display:block; image-rendering:pixelated; }
.tour-hand--down .tour-hand-img{ transform:rotate(180deg); }
@keyframes tour-nudge-up{ 50%{ transform:translateY(calc(-1 * var(--px))); } }
@keyframes tour-nudge-down{ 50%{ transform:translateY(var(--px)); } }
@media (prefers-reduced-motion: reduce){ .tour-hand{ animation:none; } }
.tour-bubble{
  position:fixed;
  z-index:1003;
  width:min(340px, calc(100vw - 32px));
  padding:14px 16px 12px;
  color:var(--cream);
  background:var(--night-2);
  box-shadow: 0 0 0 var(--px) var(--gold), 0 0 0 calc(2 * var(--px)) var(--night-0), 0 12px 0 0 rgba(11,8,24,0.6);
}
.tour-text{ margin:0 0 12px; font-size:16px; line-height:1.4; }
.tour-foot{ display:flex; align-items:center; gap:10px; }
.tour-count{ margin-right:auto; font-size:14px; color:var(--muted); }
.tour-btn{ font-size:15px; padding:6px 12px; }
.tour-spot[hidden], .tour-hand[hidden], .tour-btn[hidden]{ display:none; }

/* ---- privacy notice and account deletion (privacy.go, account.go) ---- */
.legal-shell{ position:relative; z-index:2; display:flex; justify-content:center; padding:88px 16px 48px; }
.legal-card{ max-width:720px; text-align:left; }
.legal-card h1{ color:var(--cream); text-shadow:3px 3px 0 var(--royal), 6px 6px 0 var(--night-0); }
.legal-card p, .legal-card li{ margin:0 0 10px; font-size:14px; line-height:1.6; color:var(--cream); }
.legal-card ul{ margin:0 0 10px; padding-left:20px; }
.legal-card section{ margin-top:20px; padding-top:16px; border-top:2px dashed rgba(196,189,232,0.35); }
.legal-card code{ font-family:inherit; color:var(--gold); }
.legal-card .auth-form{ margin-top:18px; }
.legal-updated{ color:var(--muted); }
.auth-form .auth-privacy{ line-height:1.5; }

/* the goodbye after deleting an account, over the landing page */
.landing-farewell{
  position:relative; z-index:3; margin:72px auto 0; max-width:640px; padding:10px 14px;
  background:var(--night-0); color:var(--gold); font-size:14px; text-align:center;
}
.landing-footer{ padding:24px 0 40px; text-align:center; font-size:14px; }

/* the cookie notice (static/cookie-notice.js): a strip at the bottom
   until dismissed */
.cookie-notice{
  position:fixed; left:16px; right:16px; bottom:16px; z-index:10000;
  display:flex; align-items:center; gap:16px; max-width:720px; margin:0 auto; padding:12px 16px;
  background:var(--night-1); color:var(--cream); font-size:14px; line-height:1.5;
  box-shadow:
    calc(-1 * var(--px)) 0 0 0 var(--night-0),
    var(--px) 0 0 0 var(--night-0),
    0 calc(-1 * var(--px)) 0 0 var(--night-0),
    0 var(--px) 0 0 var(--night-0),
    0 calc(3 * var(--px)) 0 0 rgba(11,8,24,0.55);
}
.cookie-notice[hidden]{ display:none; }
.cookie-notice p{ margin:0; flex:1; }
.cookie-notice .menu-btn{ flex:none; padding:8px 18px; font-size:14px; }
@media (max-width:520px){
  .cookie-notice{ flex-direction:column; align-items:stretch; }
}
