/* ============================================================================
 * The Emberbound GUI skin, built from the OWNER'S PixelLab sheets (see
 * references/pixellab-*-256.png and tools/pixellab/build-sheet-kit.mjs).
 *
 * Scope rule learned the hard way: only widgets the sheets actually cover get
 * skinned. NOTE ON SCALING: this art is anti-aliased/painterly, NOT hard pixel art, so it
 * renders at or BELOW native size with normal (smooth) resampling. Nearest-neighbour
 * upscaling — the first pass — is what turned every soft edge into a hard block.
 * Widgets: vitals, XP, minimap, hotbar dock, windows, item slots, the
 * equipment panel and the three banner buttons. Everything else keeps the
 * plain CSS chrome from hud.css/theme.css.
 *
 * Loads AFTER hud.css / items-window.css and overrides them; the --img-* /
 * --sl-* tokens come from /assets/ui/sheet/sheet.css (generated).
 * ========================================================================= */

/* ---------------------------------------------------------------- vitals: the runic orbs
 * vstyle "orbs": the 512px sheet's two big framed orbs flank a slim XP/stamina column.
 *
 * SMOOTHNESS: the orb art is 188x180 and is drawn DOWN to 108x104 with normal resampling.
 * Downscaling anti-aliased art is what gives clean edges — the previous strip was a 230px
 * image blown up to 460 with nearest-neighbour, which is what "full of edges"
 * was. Nothing here scales up, and nothing is nearest-neighbour. */
body[data-vstyle="orbs"] #vitals{
  width:auto;height:auto;display:flex;align-items:center;gap:14px;padding:0;
  background:none;
  /* the dock sits at bottom:26px in this style; clear it plus a breath */
  bottom:calc(var(--dockh,60px) + 34px);
  filter:drop-shadow(0 8px 16px rgba(0,0,0,.6));
}
body[data-vstyle="orbs"] #vitals::before,
body[data-vstyle="orbs"] #vitals::after{display:none}
/* the key hint climbs above the whole assembly instead of hiding under it */
/* 214px floor: with the slim hotbar --dockh drops far enough that +150 would land the hint
   back inside the chat console */
body[data-vstyle="orbs"] #hint{bottom:max(calc(var(--dockh,60px) + 150px), 214px)}
/* The console must clear the widest thing in the bottom centre. hud.css already keeps it off
 * the hotbar via the measured --dockw; in this style the orb assembly rides ABOVE the dock and
 * can be the wider of the two whenever the player runs a short hotbar, so the clearance is
 * whichever is bigger. The orbs are fixed art (108 + 14 + 190 + 14 + 108 = 434), so unlike the
 * hotbar they can be a constant — 460 leaves the drop shadow room. */
body[data-vstyle="orbs"] #console{
  width:min(560px,46vw,calc(50vw - max(var(--dockw,520px),460px)/2 - 22px))}

/* Each globe: the liquid canvas fills the glass, the artist's punched-hollow ring is painted
 * OVER it by ::after, and the readout sits on top of both. */
body[data-vstyle="orbs"] .orb{position:relative;flex:none;width:108px;height:104px;
  border-radius:0;overflow:visible;background:none;border:none;box-shadow:none}
body[data-vstyle="orbs"] .orb .lq{
  position:absolute;left:8%;top:8%;width:84%;height:84%;
  border-radius:50%;display:block;z-index:0}
body[data-vstyle="orbs"] .orb::after{
  content:'';position:absolute;inset:0;z-index:1;pointer-events:none;
  background:no-repeat center/100% 100%;border:none;box-shadow:none}
body[data-vstyle="orbs"] .orb.hp::after{background-image:var(--img-orb-hp)}
body[data-vstyle="orbs"] .orb.mp::after{background-image:var(--img-orb-mp)}
body[data-vstyle="orbs"] .orb.st::after{background-image:var(--img-orb-hp);filter:hue-rotate(82deg) saturate(.85)}
/* the old dark-veil fill is retired — the canvas is the fill now */
body[data-vstyle="orbs"] .orb i{display:none}
body[data-vstyle="orbs"] .orb b{position:absolute;left:0;right:0;bottom:12%;z-index:2;
  text-align:center;font-size:11px;font-weight:700;color:#fff;
  text-shadow:0 1px 3px #000,0 0 6px #000}

/* The secondary resource globe rides above the XP gauge. Either mana or stamina can be
 * secondary; without Chi there is no secondary globe. */
body[data-vstyle="orbs"] .orb.secondary{width:62px;height:60px}
body[data-vstyle="orbs"] .orb.secondary b{font-size:9px;bottom:10%}

/* between the orbs: XP over stamina, both filled with the artist's own liquid textures */
body[data-vstyle="orbs"] #vitals .tube{
  position:relative;width:190px;height:20px;overflow:hidden;flex:none;
  background:var(--img-fill-xp-empty) repeat-x left center/40px 20px;
  box-shadow:inset 0 0 0 2px #241a33, inset 0 2px 5px #0009}
body[data-vstyle="orbs"] #vitals .tube i{
  position:absolute;left:0;top:0;bottom:0;display:block;
  background:var(--img-fill-xp) repeat-x left center/40px 20px;
  transition:width .3s ease-out}
body[data-vstyle="orbs"] #vitals .tube .txt{
  position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  gap:6px;font-size:9px;color:#e6ecf5;text-shadow:0 1px 2px #000}
body[data-vstyle="orbs"] #vitals .tube .txt span{color:#a9b8cc}

body[data-vstyle="orbs"] #vitals .orbmid{position:static;min-width:0;flex:none;
  display:flex;flex-direction:column;align-items:center;gap:5px}
body[data-bstyle="dock"] .barrow{filter:drop-shadow(0 5px 12px rgba(0,0,0,.55))}

/* in orbs mode the XP sits between the orbs; the dock's own xp row collapses */
body[data-vstyle="orbs"] #xpbar{display:none}

/* narrow screens: shrink the assembly so it stops crowding the console */
@media (max-width:1100px){
  body[data-vstyle="orbs"] #vitals{gap:8px}
  body[data-vstyle="orbs"] .orb{width:78px;height:75px;background-size:78px 75px}
  body[data-vstyle="orbs"] .orb b{font-size:9px}
  body[data-vstyle="orbs"] #vitals .tube{width:140px;height:16px;background-size:32px 16px}
  body[data-vstyle="orbs"] #vitals .tube i{background-size:32px 16px}
  body[data-vstyle="orbs"] #vitals .tube .txt{font-size:8px;gap:4px}
  body[data-vstyle="orbs"] .orb.secondary{width:48px;height:46px}
}

/* ---------------------------------------------------------------- vitals: the banner trough
 * vstyle "banner": the artist's 3-compartment trough at 2x (322x34). The three .sbar fills sit
 * in the punched compartments (local x6/58/108 w47/45/47, y4 h9 — doubled) and the shell is
 * painted over them by the ::after. */
body[data-vstyle="banner"] #vitals .vcol{width:322px;position:relative;gap:0;
  padding-bottom:38px}
body[data-vstyle="banner"] #vitals .vcol::after{
  content:'';position:absolute;left:0;bottom:0;width:322px;height:34px;
  background:var(--img-vitals-shell) no-repeat center/322px 34px;
  image-rendering:auto;pointer-events:none}
body[data-vstyle="banner"] #vitals .sbar{position:absolute;bottom:8px;height:18px;
  border:none;border-radius:0;box-shadow:none;
  background:var(--img-fill-empty) repeat-x left center/16px 18px;image-rendering:auto}
body[data-vstyle="banner"] #vitals .sbar.hp{left:12px;width:94px;height:18px}
body[data-vstyle="banner"] #vitals .sbar.mp{left:116px;width:90px;height:18px}
body[data-vstyle="banner"] #vitals .sbar.st{left:216px;width:94px;height:18px}
body[data-vstyle="banner"] #vitals .sbar i{transition:width .15s ease-out}
/* the artist's fill textures beat the inline HP gradient */
body[data-vstyle="banner"] #vitals .sbar.hp i{
  background:var(--img-fill-red) repeat-x left center/48px 18px!important;image-rendering:auto}
body[data-vstyle="banner"] #vitals .sbar.mp i{
  background:var(--img-fill-blue) repeat-x left center/80px 18px;image-rendering:auto}
body[data-vstyle="banner"] #vitals .sbar.st i{
  background:var(--img-fill-green) repeat-x left center/40px 18px;image-rendering:auto}
body[data-vstyle="banner"] #vitals .sbar em{display:none}
body[data-vstyle="banner"] #vitals{background:none;border:none;box-shadow:none;padding:0}
body[data-vstyle="banner"] #vitals::before,
body[data-vstyle="banner"] #vitals::after{display:none}

/* ---------------------------------------------------------------- the XP bar (non-orb styles)
 * The gold-finial trough at 2x: borders 16/54 (slice 8/27), green fill inside. */
body:not([data-vstyle="orbs"]) #xpbar{background:none;border:none;box-shadow:none;padding:0}
body:not([data-vstyle="orbs"]) #xpbar::before,
body:not([data-vstyle="orbs"]) #xpbar::after{display:none}
body:not([data-vstyle="orbs"]) #xpbar .bar.xp{
  height:10px;border-radius:0;box-shadow:none;overflow:visible;
  border-style:solid;border-width:12px 54px;
  border-image:var(--img-trough) 8 27 8 27 fill / 12px 54px;
  image-rendering:auto;background:none}
body:not([data-vstyle="orbs"]) #xpbar .bar.xp i{
  display:block;height:100%;
  background:var(--img-fill-green) repeat-x left center/40px 10px!important;
  image-rendering:auto}
body:not([data-vstyle="orbs"]) #xpbar .bar.xp .txt{font-size:9px}

/* ---------------------------------------------------------------- minimap: the compass ring
 * Ring art is 57px with a punched face of radius 22 — at 2x: 114px ring, 88px round canvas. */
#minimap{width:auto;padding:0;background:none;border:none;box-shadow:none}
#minimap::before,#minimap::after{display:none}
#minimap .mmring{position:relative;width:114px;height:114px;margin:0 auto}
#minimap .mmring::after{content:'';position:absolute;inset:0;
  background:var(--img-minimap-ring) no-repeat center/114px 114px;
  image-rendering:auto;pointer-events:none}
#minimap canvas{position:absolute;left:12px;top:12px;width:90px;height:90px;margin:0;
  border-radius:50%;border:none;box-shadow:none;background:#0b0e14}
#minimap .mmpos{display:block;text-align:center;margin-top:2px;font-size:9px;color:#9fb4c8;
  text-shadow:0 1px 2px #000}

/* ---------------------------------------------------------------- hotbar: the iron dock
 * Native-size cells (40x43) with the artist's end caps on every row. */
/* WHY THIS LOOKS SMOOTH NOW: these PixelLab UI sheets are anti-aliased, painterly art —
 * NOT hard pixel art. The first pass drew the 40x43 iron cell at 2x with
 * `image-rendering:auto`, which turns every soft edge pixel into a hard 2x2 block:
 * that is where "very pixelated, full of edges" came from. The runic sheet is ~2x the real
 * detail (48x60 per cell), and it is drawn at NATIVE size with normal (smooth) resampling,
 * so nothing is invented and nothing is blocked up. */
body[data-bstyle="dock"] #actionbar{background:none;border:none;box-shadow:none;padding:0}
body[data-bstyle="dock"] #actionbar::before,
body[data-bstyle="dock"] #actionbar::after{display:none}
body[data-bstyle="dock"] .barrow{gap:0;align-items:stretch}
body[data-bstyle="dock"] #actionbar .slot{
  width:48px;height:60px;border:none;border-radius:0;box-shadow:none;gap:0;
  background:var(--img-dock-cell) no-repeat center/48px 60px;
  image-rendering:auto;padding:0;justify-content:center}
body[data-bstyle="dock"] #actionbar .slot.empty{border:none;background-image:var(--img-dock-cell)}
body[data-bstyle="dock"] #actionbar .slot.empty .ic::before{font-size:12px;color:#6a4f86}
body[data-bstyle="dock"] #actionbar .slot .nm{display:none}
body[data-bstyle="dock"] #actionbar .slot .k{left:6px;top:6px;font-size:7px;color:#b79ad6}
body[data-bstyle="dock"] #actionbar .ic{font-size:18px}
body[data-bstyle="dock"] #actionbar .ic img{width:26px;height:26px}
body[data-bstyle="dock"] #actionbar .ic img.abico{width:32px;height:32px}
body[data-bstyle="dock"] #actionbar .slot:hover{filter:brightness(1.25)}
body[data-bstyle="dock"] #actionbar .slot.ready{border:none;
  box-shadow:inset 0 0 10px -2px var(--el,var(--gold))}
body[data-bstyle="dock"] #actionbar .slot.drop{border:none;
  box-shadow:inset 0 0 8px -1px var(--gold)}
body[data-bstyle="dock"] #actionbar .cd i{--cdc:#000c}
body[data-bstyle="dock"] .barrows{gap:2px}
/* the add/remove-row chips: small iron studs beside the bar, not floating white squares */
body[data-bstyle="dock"] .barctl{justify-content:center;gap:3px;margin-right:2px}
body[data-bstyle="dock"] .barctl .barbtn{
  width:16px;height:16px;padding:0;border:1px solid #4a423a;border-radius:3px;
  background:#1d1712;color:#a79a8a;font-size:10px;line-height:1;cursor:pointer}
body[data-bstyle="dock"] .barctl .barbtn:hover:not(:disabled){color:#e8dcc8;border-color:#7a6a52}
body[data-bstyle="dock"] .barctl .barbtn:disabled{opacity:.35;cursor:default}

/* ---------------------------------------------------------------- hotbar: the crimson strip
 * bstyle "runic": the 600px crimson sheet (references/pixellab-hotbar-crimson-600.png), cut
 * into a left cap, one repeatable cell and a right cap — so the bar is a single continuous
 * piece of ironwork with the artist's scrollwork and gem finials closing BOTH ends, at any
 * slot count and any number of rows.
 *
 * THIS SHEET IS THE EXCEPTION TO THE SCALING RULE AT THE TOP OF THIS FILE. Every other piece
 * here is painterly anti-aliased art that must not be upscaled; this one is true 1x pixel art
 * (25 colours over the whole strip), drawn with `image-rendering:pixelated` so the artist's
 * pixels are duplicated, never blended. Every dimension below is `--cbk` times a whole source
 * pixel, so --cbk alone resizes the entire bar.
 *
 * --cbk IS 1.5, NOT THE ORIGINAL 2. At 2x a 12-slot bar is 1004px — two thirds of a 1522px
 * screen, and tall enough to crowd the chat; 1.5 brings it to 760x75, which is the size this
 * HUD actually wants. The honest cost: 1.5 is not an integer, so nearest-neighbour duplicates
 * some source rows and not others and the well's 2px rails alternate 1px/2px. Rendered side by
 * side the strip still reads as one piece of ironwork — the filigree and the gem caps survive
 * — so this is a deliberate trade, not an oversight. Halves are as far as it bends: quarters
 * drop whole rails. Going back to crisp means 2 (too big) or 1 (36x50 slots, at which the
 * keybind and the icons stop being legible), which is why neither is the default.
 *
 * Keep --cbk on a half step, and keep every derived size landing on a whole pixel: the
 * round()s below are what stop a 19.5px icon from being resampled a second time. */
body[data-bstyle="runic"]{--cbk:1.5}
body[data-bstyle="runic"] #actionbar{background:none;border:none;box-shadow:none;padding:0}
body[data-bstyle="runic"] #actionbar::before,
body[data-bstyle="runic"] #actionbar::after{display:none}
body[data-bstyle="runic"] .barrows{gap:calc(2px*var(--cbk))}
body[data-bstyle="runic"] .barrow{
  gap:0;align-items:stretch;
  filter:drop-shadow(0 5px 12px rgba(0,0,0,.55))}
/* the end caps: art the row wears, not slots — they must never take a drop or a click */
body[data-bstyle="runic"] .barrow::before,
body[data-bstyle="runic"] .barrow::after{
  content:'';flex:none;height:calc(50px*var(--cbk));pointer-events:none;
  background:no-repeat center/100% 100%;image-rendering:pixelated}
body[data-bstyle="runic"] .barrow::before{
  width:round(calc(28px*var(--cbk)),1px);background-image:var(--img-cb-cap-l)}
body[data-bstyle="runic"] .barrow::after{
  width:round(calc(29px*var(--cbk)),1px);background-image:var(--img-cb-cap-r)}

/* one cell, butted against its neighbours: the tile is cut divider-to-divider, so the seam
 * between two slots IS the artist's divider and the row reads as one milled strip.
 *
 * THE WELL IS OFF-CENTRE IN THE TILE, by design of the cut: the tile carries the full 6px
 * divider on its left and only the 2px inner rail on its right (the next tile brings the
 * rest), so the dark well runs x6..x33 of 36 — its centre is 2 source px right of the tile's.
 * The padding-left below is that offset, and it is why the icons line up down the row instead
 * of drifting left inside every socket. Vertically the well IS centred (y8..y41 of 50). */
body[data-bstyle="runic"] #actionbar .slot{
  width:calc(36px*var(--cbk));height:calc(50px*var(--cbk));
  border:none;border-radius:0;box-shadow:none;gap:0;
  padding:0 0 0 calc(4px*var(--cbk));
  background:var(--img-cb-cell) no-repeat center/100% 100%;
  image-rendering:pixelated}
body[data-bstyle="runic"] #actionbar .slot.empty{border:none;background-image:var(--img-cb-cell)}
body[data-bstyle="runic"] #actionbar .slot .nm{display:none}
body[data-bstyle="runic"] #actionbar .slot.empty .ic::before{
  font-size:calc(6px*var(--cbk));color:#6b4450}
/* The key hint sits at the tile's top-left, on its own plate.
 *
 * THE 7px FLOOR BELOW IS OVERRULED. It was set as a deliberate minimum ("small but still
 * there"); in use it is not readable — 7px of #d8a9b6 rose over pink-grey filigree is a smudge,
 * and the hint is the one thing on this bar you have to read mid-fight. It is now 11px in near
 * white on a dark plate, which is the whole point of the plate: the hint stops competing with
 * the scrollwork behind it instead of trying to out-contrast it.
 *
 * The plate must clear the icon, which now fills the well. Icon top is y18 (39px centred in the
 * 75px tile); the plate is 11px of text + 1px padding top and bottom = 13px tall, at top:3, so
 * it ends at y16 with 2px to spare. Raising the font or the padding here without lowering
 * `top` will start covering the icon's top-left corner. */
body[data-bstyle="runic"] #actionbar .slot .k{
  left:round(calc(6px*var(--cbk)),1px);top:round(calc(2px*var(--cbk)),1px);
  font-size:max(11px,round(calc(7px*var(--cbk)),1px));line-height:1;
  padding:1px 3px;border-radius:3px;
  background:rgba(18,10,14,.88);box-shadow:0 0 0 1px rgba(0,0,0,.55);
  color:#fff2f6;text-shadow:0 1px 2px #000;z-index:2}
/* `.ic` must be a FLEX BOX, not the base's inline span: an inline <img> sits on the text
 * baseline, so the span is icon-height + descender and centring that box drops the icon
 * several pixels below the well's middle. As a flex box the span IS the icon. */
body[data-bstyle="runic"] #actionbar .ic{
  display:flex;align-items:center;justify-content:center;
  font-size:calc(11px*var(--cbk));line-height:1}
/* The well's flat field is 28x31 source px = 42x46 on screen. The icons used to be 16 source
 * px (24px) — 44% of the tile's width — so the well read as an empty grey socket with a stamp
 * in the middle. 26 source px is 39px: the slot's content box is [6,54] (the 4px padding-left
 * is the well's off-centre offset), so a 39px icon centres at x30, exactly the well's centre,
 * and lands on [10.5,49.5] inside the well's [9,51] — 1.5px of the artist's rail still shows on
 * both sides, and 3.5px top and bottom of the 46px well. That is the largest step that still
 * leaves the filigree visible; 28 source px (42px) would sit flush on the rails.
 * Keep the round()s: 1.5x a whole source px can be fractional and a fractional px gets
 * resampled a second time. */
body[data-bstyle="runic"] #actionbar .ic img{
  width:round(calc(21px*var(--cbk)),1px);height:round(calc(21px*var(--cbk)),1px)}
body[data-bstyle="runic"] #actionbar .ic img.abico{
  width:round(calc(26px*var(--cbk)),1px);height:round(calc(26px*var(--cbk)),1px)}

/* Feedback has to live INSIDE the artist's well, not on the tile's box — the tile's edges are
 * the divider ironwork, so a border or an inset shadow draws over the scrollwork and the row
 * stops reading as one strip. Hover lifts the whole tile; ready and drop are radial glows
 * confined to the well.
 *
 * Only `.ic` is raised over the glow. `.k`, `.cd` and `.q` are ALREADY absolutely positioned
 * by hud.css, so they paint above the ::before by DOM order — giving them `position:relative`
 * here (the first attempt) dropped them back into the flex flow and stacked the keybind on
 * top of the icon. */
body[data-bstyle="runic"] #actionbar .slot:hover{filter:brightness(1.3)}
body[data-bstyle="runic"] #actionbar .slot.ready,
body[data-bstyle="runic"] #actionbar .slot.drop{border:none;box-shadow:none}
body[data-bstyle="runic"] #actionbar .slot.ready::before,
body[data-bstyle="runic"] #actionbar .slot.drop::before{
  content:'';position:absolute;z-index:0;pointer-events:none;
  left:calc(6px*var(--cbk));right:calc(2px*var(--cbk));
  top:calc(8px*var(--cbk));bottom:calc(8px*var(--cbk));
  background:radial-gradient(closest-side,var(--el,var(--gold)) 0%,transparent 78%);
  opacity:.5}
body[data-bstyle="runic"] #actionbar .slot.drop::before{--el:var(--gold);opacity:.7}
body[data-bstyle="runic"] #actionbar .slot .ic{position:relative;z-index:1}
body[data-bstyle="runic"] #actionbar .cd i{--cdc:#000c}
/* the row-add/remove chips, matched to the strip's rose-iron instead of the dock's brass */
body[data-bstyle="runic"] .barctl{justify-content:center;gap:3px;margin-right:3px}
body[data-bstyle="runic"] .barctl .barbtn{
  width:16px;height:16px;padding:0;border:1px solid #4c3640;border-radius:3px;
  background:#1a1216;color:#a98795;font-size:10px;line-height:1;cursor:pointer}
body[data-bstyle="runic"] .barctl .barbtn:hover:not(:disabled){color:#f0d3dc;border-color:#7d5967}
body[data-bstyle="runic"] .barctl .barbtn:disabled{opacity:.35;cursor:default}

/* ---------------------------------------------------------------- windows: the iron panel
 * Every draggable window wears the artist's empty panel as a 9-slice (source slice 24 at 1x:
 * the corner filigree stays crisp, the interior brown is the window's own surface). */
.box.nw, .gm-box.nw{
  border-style:solid;border-width:24px;
  border-image:var(--img-window-panel) 24 fill / 24px;
  image-rendering:auto;
  background:none;box-shadow:0 14px 40px -12px #000c;border-radius:0;padding:0}
.box.nw::before,.box.nw::after,
.gm-box.nw::before,.gm-box.nw::after{display:none}
/* square window furniture inside the square frame */
.box.nw .winbar, #itemsWin .winbar{margin:0;border-radius:0;background:#00000042}

/* ---------------------------------------------------------------- item slots
 * The small square socket from the equipment panel, 9-sliced for every item cell.
 * (#itemsWin .is2 repeated for specificity over items-window.css.) */
.slotcell, #itemsWin .is2{
  border-style:solid;border-width:7px;border-radius:0;
  border-image:var(--img-slot-cell) 7 fill / 7px;
  image-rendering:auto;background:none;box-shadow:none}
.slotcell.empty, #itemsWin .is2.empty{
  background:none;border-image:var(--img-slot-cell) 7 fill / 7px;opacity:.9}

/* ---------------------------------------------------------------- the gear column
 * The artist's socketed panel (assets/ui/sheet/equip-panel.png, 262x306 at 2x) is no longer
 * drawn: the Character window's left column is the SOCKETS themselves over a stat readout, so
 * there is no mannequin to stand in its round portrait well and no baked sockets to line cells
 * up with. What survives from the skin is the part that was doing real work — the slot-cell
 * sprite as each socket's border. Scoped to #itemsWin because items-window.css styles these by
 * id and would out-rank plain class selectors. */
#itemsWin .gearslots .eq2{border-radius:0;font-size:20px;background:none;
  border-style:solid;border-width:7px;border-image:var(--img-slot-cell) 7 fill / 7px;
  image-rendering:auto}
#itemsWin .gearslots .eq2.empty{background:none;border-style:solid;color:#5b5148}
#itemsWin .gearslots .eq2:hover{background:none;box-shadow:inset 0 0 10px -2px var(--gold)}

/* ---------------------------------------------------------------- banner buttons
 * Only where the baked label genuinely says what the button does. Text is hidden (the art
 * carries it); focus/hover get a brightness lift so they still feel like buttons. */
.btn.banner{
  width:158px;height:56px;padding:0;border:none;border-radius:0;
  background:no-repeat center/158px 56px;image-rendering:auto;
  color:transparent;font-size:0;text-shadow:none;box-shadow:none}
.btn.banner:hover,.btn.banner:focus-visible{filter:brightness(1.2);border:none;background-color:transparent}
.btn.banner:active{transform:translateY(1px)}
.btn.banner.play{background-image:var(--img-btn-play)}
.btn.banner.options{background-image:var(--img-btn-options)}
.btn.banner.quit{background-image:var(--img-btn-quit)}

/* character select: the lilac sky stays on the login screen only — behind the roster the
 * backdrop goes near-black to match the iron/blood chrome (the dark meadow strip and the
 * drifting motes stay for depth). */
body:has(#selectScreen.on) #loginScene{background:#0a090c}
body:has(#selectScreen.on) #loginScene :is(.sky,.sun,.ridge,.wall){display:none}

/* character select: the whole roster panel is one 436x542 artwork whose top border carries
 * the baked "Select character" plaque, so the text header is retired and the 9-slice keeps
 * the plaque and the corner ironwork crisp while the middle stretches to the roster's
 * height. Drawn at native slice widths and resampled smoothly — the 128px header sheet this
 * replaces had to be doubled, which is what made it look coarse.
 *
 * THE PANEL IS 357px WIDE ON PURPOSE — its native width, so the gem-plaqued corners and
 * their crystal sprays (the 64px corner slices) land 1:1 and the frame bars never squash.
 * The height is free to stretch — the interior was wiped to featureless stone at build
 * time, and `round` keeps the edge bands tiling instead of smearing. */
.cs-left .cs-panel{
  width:357px;max-width:100%;box-sizing:border-box;
  border-style:solid;border-width:64px;
  border-image:var(--img-cs-panel) 64 fill / 64px;
  border-image-repeat:round;
  image-rendering:pixelated;background:none;box-shadow:none;border-radius:0;
  backdrop-filter:none;padding:0;
  overflow:visible;   /* the plaque overhangs the content box; .cs-panel clips by default */
  /* natural height, NOT the column's: the frame closes just under the last roster row
     instead of stretching floor-length down the screen. It may still SHRINK when the
     window is short — the roster's fit logic then trims the create stack to what fits. */
  flex:0 1 auto;min-height:230px;display:flex;flex-direction:column}
.cs-left .cs-panel::before,.cs-left .cs-panel::after{display:none}
/* the "SELECT CHARACTER" plaque: 312x100 art (rays + flanking crystals baked in), placed
   exactly where the artist composed it — 22px into the interior, so it pulls up over the
   64px border band and overhangs the 229px content box on both sides */
.cs-left .cs-hdr{display:block;flex:none;align-self:center;width:312px;height:100px;
  margin:-42px 0 0;padding:0;border:none;
  background:var(--img-cs-header) no-repeat center/312px 100px;
  image-rendering:pixelated;font-size:0;color:transparent;letter-spacing:0}
.cs-left .cs-server{flex:none;border-bottom-color:#00000055;padding:5px 6px 8px;
  font-size:12.5px;color:#b9a88c;letter-spacing:.02em}
.cs-left .cs-server .cnt{color:#e9d3a4;font-variant-numeric:tabular-nums}
.cs-left .cs-server .ico{width:22px;height:22px;border-radius:4px;border-color:#5a4a34;
  color:#b9a88c;background:#00000040}
.cs-left .cs-server .ico:hover{border-color:var(--gold);color:var(--gold2);background:#00000060}
.cs-left .cs-roster{flex:1 1 auto;min-height:0;overflow-y:auto;overflow-x:hidden;
  padding:8px 4px 8px 2px;gap:7px;scrollbar-width:thin}

/* the "+ CREATE" banner is 214x64 art: pin the BUTTON to that size and centre it, otherwise
   the plate floats inside a full-width box and reads as misaligned against the roster cards */
.cs-create{
  width:214px;height:64px;flex:none;padding:0;border:none;border-radius:0;
  margin:3px auto 1px;display:block;
  background:var(--img-cs-create) no-repeat center/214px 64px;
  image-rendering:pixelated;color:transparent;font-size:0;transition:filter .12s,transform .12s}
/* hover must RE-ASSERT the banner art: the base sheet's hover is `background:#10162b`, a
   shorthand that wipes background-image, which is what made the button vanish under the
   cursor. The feedback is a gold glow hugging the art's silhouette (drop-shadow, not a
   border — the banner's corners are transparent, a box border would read as a crate). */
.cs-create:hover{
  background:var(--img-cs-create) no-repeat center/214px 64px;border:none;
  filter:brightness(1.18) drop-shadow(0 0 3px #ffd76acc) drop-shadow(0 0 9px #e0a44c88)}
.cs-create:active{transform:translateY(1px)}
.cs-create .plus{display:none}

/* the character-select PLAY: the artist's banner at NATIVE 158x56. It used to be blown up to
   316x112 — a 2x upscale of anti-aliased painterly art, which is precisely the "soft edges
   turned into hard blocks" failure this whole sheet is written to avoid. The CTA keeps its
   weight from the ember glow beneath it instead of from raw size. */
#csPlay{
  width:158px;height:56px;padding:0;border:none;border-radius:0;
  background:var(--img-btn-play) no-repeat center/158px 56px;
  image-rendering:auto;color:transparent;font-size:0;text-shadow:none;
  box-shadow:none;animation:none;
  filter:drop-shadow(0 6px 16px #000a) drop-shadow(0 0 14px #e0a44c3d);
  transition:filter .14s,transform .1s}
#csPlay:hover:not(:disabled),#csPlay:focus-visible{
  filter:drop-shadow(0 6px 16px #000a) drop-shadow(0 0 20px #ffd38a7a) brightness(1.14)}
#csPlay:disabled{filter:grayscale(.7) brightness(.6)}
#csPlay:active:not(:disabled){transform:translateY(1px)}

/* ============================================================================
 * The warm retheme — kill the old navy.
 * The artist sheets are blackened iron, umber leather and blood red; the old theme's
 * cool navy surfaces fought them in every window. Surfaces move to the warm family via
 * the theme tokens (most chrome uses them), plus targeted overrides for the hardcoded
 * navy gradients in hud.css / items-window.css / login.css.
 * ========================================================================= */
:root{
  --panel:#15131aee; --panel2:#0c0b10ee; --panel3:#131118;
  --line:#332f3a; --line2:#4a4454; --edge:#221f29;
  --ink:#e6e2dc; --dim:#a9a2b0; --faint:#7b7488;
  --acc:#e0a44c; --acc2:#ffd991;             /* the purple accent becomes ember gold */
}

/* the scrollbars were the last navy left: a blue pill riding down warm iron panels */
::-webkit-scrollbar-thumb{background:#3a2f22;background-clip:padding-box}
::-webkit-scrollbar-thumb:hover{background:#584631;background-clip:padding-box}

/* ---- game menu internals -------------------------------------------------- */
.gm-box{background:linear-gradient(#1b1512f7,#120e0bf9)}
.gm-head{background:linear-gradient(#241c15,#171210)}
.gm-x{background:#171210}
.gm-rail{background:linear-gradient(180deg,#1d1712,#120e0b)}
.gm-tab:hover{background:#241c15}
.gm-foot{background:#120e0bcc}
.optrow.sel select{background:#171210}

/* ---- items window internals ----------------------------------------------- */
#itemsWin .box{background:linear-gradient(#1b1512f7,#120e0bf9)}
#itemsWin .winbar{background:linear-gradient(#241c15,#171210)}
#itemsWin .winbar .wx{background:#171210;border-color:var(--line2)}
#itemsWin .invtabs{background:#00000030}
#itemsWin .invtabs button.on{color:var(--gold2);border-bottom-color:var(--gold)}
#itemsWin .s2{background:#00000038;border-color:#00000048}
#itemsWin .attrbox{background:#00000030;border-color:var(--line)}
#itemsWin .eq2:hover{background:none}
/* The one context menu, both surfaces (was #itemsCtx for the Items window and .ctxmenu for the
   floating bags — two widgets, two skins, and two different sets of actions). */
.ctxmenu{background:#191310f5;border-color:var(--line2)}
.cm-item:hover{background:#2a2115;color:var(--gold2)}
.cm-item.danger:hover{background:#3a1a14;color:#ffd7c9}

/* ---- character select ----------------------------------------------------- */
/* announcements-side header keeps text but goes warm */
.cs-hdr{background:linear-gradient(180deg,#241c15ee,#171210)}
/* the green signal glyph rendered as a smear next to the realm name — gone */
.cs-server .sig{display:none}
/* Square-ish cards, because they sit inside a hard-edged iron frame: 10px pills read as a
   different UI kit bolted into the artwork. 3px keeps the corner from looking chipped. */
.cs-card{background:#171210;border-color:var(--line);border-radius:3px;
  padding:9px 10px;transition:background .13s,border-color .13s,box-shadow .13s}
.cs-card:hover{background:#221a14;border-color:var(--line2)}
.cs-card.sel{border-color:var(--gold);background:linear-gradient(180deg,#2c2114,#1b1409);
  box-shadow:0 0 0 1px var(--gold) inset,0 8px 22px -14px var(--gold)}
.cs-card.sel:before{background:var(--gold);box-shadow:0 0 10px var(--gold3);border-radius:0}
.cs-card .more{border-radius:3px;align-self:center;padding:3px 7px}
.cs-card .more:hover{background:#ffffff14}
/* the roster now has real horizontal room: let the name breathe and drop the class line onto
   its own baseline instead of ellipsising both at 212px */
.cs-card .cs-info{flex:1 1 auto}
.cs-card .cs-info .nm{font-size:14.5px;letter-spacing:.01em;color:#efe4d2}
.cs-card .cs-info .cls{margin-top:2px;color:#a1907a}

/* the roster's own scrollbar: the global one is a navy pill that showed up as a blue stripe
   down the stonework */
.cs-left .cs-roster{scrollbar-color:#4a3b28 transparent}
.cs-left .cs-roster::-webkit-scrollbar{width:6px}
.cs-left .cs-roster::-webkit-scrollbar-thumb{background:#4a3b28;border:0;border-radius:3px}
.cs-left .cs-roster::-webkit-scrollbar-thumb:hover{background:#6d5638}

/* ---- character select: the right column ------------------------------------
 * Announcements and the equipped set were the only framed things on this screen with NO
 * frame — `.box.nw` never matched them, so they rendered as floating text on the backdrop
 * beside a fully painted roster panel. They wear the window 9-slice now (24px corners at
 * native size, plain interior stretched), which is what every in-game window already uses. */
.cs-right .nw{
  border-style:solid;border-width:24px;
  border-image:var(--img-window-panel) 24 fill / 24px;
  image-rendering:auto;background:none;border-radius:0;
  /* the 24px slice ends ON the frame's inner bevel, so the content needs its own inset or
     the first line of text sits on the moulding */
  padding:4px 6px 8px;overflow:visible;
  box-shadow:0 14px 40px -16px #000c;backdrop-filter:none}
.cs-right .nw::before,.cs-right .nw::after{display:none}
/* The ANNOUNCEMENTS panel wears the SAME gem-cornered frame as the roster ("make it equal
 * to select character"). Layout borders stay at the frame's true 22px bar so the interior
 * keeps its width; the 64px ornament band is painted inward over the padding, which is how
 * the corner crystal sprays get to overhang the interior exactly like the big panel. */
.cs-right .cs-panel{
  border-style:solid;border-width:22px;
  border-image:var(--img-cs-panel) 64 fill / 64px;border-image-repeat:round;
  image-rendering:pixelated;background:none;box-shadow:none;
  padding:12px 18px 16px;overflow:visible}
/* the header echoes the roster's plaque: gold caps on a dark riveted plate */
.cs-right .cs-hdr{margin:0 6px 12px;padding:7px 2px;font-size:12px;letter-spacing:2.5px;
  text-align:center;color:#ffd76a;background:#1c1120;
  border:2px solid #8a6d3b;border-bottom-width:3px}
.cs-right .cs-ann-body{padding:0 2px}
.cs-right .cs-ann-item .k{color:#e9b869}
.cs-right .cs-ann-item .d{color:#c3b6a2}
/* the call-to-action sits on the kit's gold-rimmed plate, like the stage chips */
.cs-right .cs-ann-btn{
  border-radius:0;box-sizing:border-box;padding:0 8px;
  border-style:solid;border-width:12px 16px 13px 16px;
  border-image:var(--img-lg-btn) 12 16 13 16 fill / 12px 16px 13px 16px;
  image-rendering:auto;background:none;color:#e9b869;transition:filter .12s}
.cs-right .cs-ann-btn:hover{filter:brightness(1.22);color:#ffe3ab;border-color:transparent}
.cs-right .cs-equip{padding:4px 6px 8px}
.cs-right .cs-equip .eh{margin:0 2px 9px;padding-bottom:7px;border-bottom:1px solid #00000066}
.cs-right .cs-slots{padding:0 2px}

/* ---- character select: the stage furniture ---------------------------------
 * The zoom/rotate chips were 8-10px rounded glass pills — the one remaining piece of the old
 * theme's chrome on this screen. They reuse the login sheet's small plate so they belong to
 * the same kit as everything else, at the plate's native 12/16/13/16 slice. */
/* 40x37 is not arbitrary: 37 is the plate's native height, so the 12/13 top and bottom slices
   land 1:1 and only the 8px flat middle is squeezed. */
.cs-zoom button,.cs-rotate button{
  width:40px;height:37px;box-sizing:border-box;padding:0;border-radius:0;
  border-style:solid;border-width:12px 16px 13px 16px;
  border-image:var(--img-lg-btn) 12 16 13 16 fill / 12px 16px 13px 16px;
  image-rendering:auto;background:none;backdrop-filter:none;box-shadow:none;
  color:#c9a678;font-size:14px;line-height:1;transition:filter .12s}
.cs-zoom button:hover,.cs-rotate button:hover{
  filter:brightness(1.22);color:#ffe3ab;border-color:transparent;box-shadow:none}
.cs-zoom button:active,.cs-rotate button:active{transform:translateY(1px)}
/* The hero preview is a 112px cell drawn at scale(2) with image-rendering:pixelated — so its
 * position has to be whole pixels or every second source row doubles unevenly and the sprite
 * shimmers as it bobs. Two things were pushing it off the grid: the 24%-of-viewport stage
 * anchor (172.8px at 720 tall) and a continuously interpolated idle float. Round the anchor,
 * and make the float a stepped 2px hop — which is how a sprite would be animated anyway.
 * (`bottom`, not margin-bottom — see login.css: the margin percentage resolved against the
 * column's WIDTH and floated the hero off his platform on wide windows.) */
.cs-hero{bottom:calc(24% + 40px);
  bottom:calc(round(24%, 1px) + 40px);
  animation:idleHop 4.2s steps(1,end) infinite}
@keyframes idleHop{
  0%,100%{transform:translateY(0)}
  12.5%{transform:translateY(-2px)}   25%{transform:translateY(-4px)}
  37.5%{transform:translateY(-6px)}   50%{transform:translateY(-8px)}
  62.5%{transform:translateY(-6px)}   75%{transform:translateY(-4px)}
  87.5%{transform:translateY(-2px)}}

/* the turn buttons hang off the stage's 24% anchor, which is a fraction of the viewport
   height and lands them on y=552.2 at 720px tall — half a pixel is enough to resample a
   9-sliced plate. Round the anchor; the plate stays put, the blurry glow ring does not care.
   (Plain calc first so a browser without CSS round() keeps the old placement.) */
.cs-rotate{bottom:calc(24% - 42px);bottom:calc(round(24%, 1px) - 42px)}
.cs-logout{border-radius:3px;border-color:#4a3b28;background:#171210e8;color:#a1907a}
.cs-logout:hover{border-color:var(--gold);color:var(--gold2)}

/* INTEGER LINE HEIGHTS, on every text run whose box decides where a 9-sliced frame ends.
 * `line-height:normal` and unitless multipliers give fractional box heights, and a frame that
 * lands on y=469.88 has its bottom rail resampled across two device rows — a one-pixel blur
 * along the stonework that reads as a soft edge. Rounding the type rounds the frames. */
.cs-right .cs-hdr{line-height:14px}
.cs-right .cs-ann-item .k{line-height:14px}
.cs-right .cs-ann-item .d{line-height:18px}
.cs-right .cs-ann-btn{line-height:14px}
.cs-right .cs-equip .eh{line-height:14px}
.cs-card .cs-info .nm{line-height:18px}
.cs-card .cs-info .cls{line-height:14px}
.cs-play-sub{line-height:16px;height:32px}
.cs-play-wrap{gap:8px}
/* ---- the create / delete modals -------------------------------------------
 * They ride the same 9-sliced window frame as every in-game window, but their contents were
 * still the pre-retheme navy: #0b0f1e cards and a violet focus ring inside a blackened-iron
 * panel. Same warm family as the roster, and square-ish corners to match the frame. */
.cs-modal .box{background:none}
.cs-modal .au-fld label{color:#8a7a63;letter-spacing:1.2px}
.cs-modal .au-box{border-radius:4px;border-color:#4a3b28;background:#0d0a08d8}
.cs-modal .au-box:focus-within{border-color:var(--gold);box-shadow:0 0 0 3px #e0a44c22}
.cs-modal .au-box .ic{color:#8a7a63}
.cs-modal .au-box input::placeholder{color:#6b5c48}
.cs-modal :is(.cc-weap,.cc-class,.cc-bg){border-radius:4px;border-color:#39301f;background:#171210}
.cs-modal :is(.cc-weap,.cc-class,.cc-bg):hover{border-color:#5f4d31;background:#221a14}
.cs-modal .cc-bg-custom textarea{border-radius:4px;border-color:#4a3b28;background:#0d0a08d8;
  color:#e6dccb}
.cs-modal .cc-arrow{border-radius:3px;border-color:#4a3b28;background:#0d0a08}
.cs-modal .cc-sw{border-radius:2px}
.cs-modal #ccPrevCv{border-radius:4px;border-color:#4a3b28;
  background:radial-gradient(circle at 50% 40%,#241a12,#0c0907)}
.cs-modal .cc-class .cb{color:#8a7a63}
.cs-modal .cc-weap .ws{color:#8a7a63}

.cs-modal h2{line-height:24px}
.cs-modal .sub{line-height:17px}
.cs-modal .au-fld label{line-height:15px}
.cs-modal :is(.cc-rot,.cc-rand) .btn{line-height:16px}
.cs-modal .cc-count{line-height:15px}
.cc-hint{line-height:15px}
.cc-class .cn{line-height:17px}
.cc-class .cb{line-height:15px}
.cc-weap .wn,.cc-bg .wn{line-height:15px}
.cc-weap .ws{line-height:12px}
.cc-lab,.cc-val{line-height:16px}

/* the hero name plate: 30px semibold over a black vignette read as a browser heading next to
   the artist's lettering — give it the same warm ink and a tighter, carved shadow */
.cs-heroname .n{color:#f2e6cf;text-shadow:0 2px 3px #000,0 0 18px #000,0 0 34px #e0a44c22}
.cs-heroname .s{color:#c9a678;letter-spacing:2.4px;font-size:11.5px}
.cs-play-sub{color:#9c8b73;letter-spacing:.8px}

/* ---- character-select hero stage ------------------------------------------ */
/* the pedestal glow was purple; ember gold to match the chrome and the hero art */
.cs-platform .disc{background:radial-gradient(50% 60% at 50% 45%, #e0a44c2e, transparent 72%)}
.cs-platform .ring{border-color:#e0a44c4d;box-shadow:0 0 30px -6px #e0a44c55,0 0 0 1px #ffffff08 inset}
.cs-platform .ring.r2{border-color:#ffd38a3d}
@keyframes spinGlow{50%{box-shadow:0 0 22px -4px #ffd38a77}}

/* The .shine gloss sweep is a rectangle clipped to the element's BOX, which on a banner —
 * pointed ends, skull finial, transparent corners — slides visibly outside the artwork as a
 * grey slab. Pixel-art buttons don't want a CSS gloss anyway. */
#csPlay::after, .btn.banner::after{content:none;display:none;animation:none}

/* ============================================================================
 * The sign-in screen, rebuilt on the owner's login sheet
 * (references/pixellab-login-panel-512.png).
 *
 * The sheet is a whole composed screen — stone panel, EMBERBOUND banner, mountain and
 * castle flanks — with a dummy form painted onto the panel. build-sheet-kit.mjs stamps that
 * dummy form out with the panel's own stone and lifts the plates as empty 9-slices, so the
 * real inputs, buttons and checkbox sit exactly where the artist drew theirs.
 *
 * THE CARD IS 292px WIDE ON PURPOSE — the panel's native width. Only then do the top and
 * bottom borders render unstretched, which matters because the artist composed the banner
 * INTO the panel's top rail: the logo overlay's lower 41px is that same rail, so it lands
 * on itself with no seam. Widen the card and the baked gem smears out from behind the logo.
 * ========================================================================= */
body:has(#authScreen.on) #loginScene{background:#0a090c}
body:has(#authScreen.on) #loginScene :is(.sky,.sun,.ridge,.wall,.ground){display:none}

.au-brand{display:none}                    /* the wordmark is artwork now, not text */
.au-wrap{padding:126px 0 28px;align-content:center}   /* headroom for the banner, which hangs 123px above the card */
.au-stage{position:relative}

/* the flanks hang off the stage so they track the card instead of the viewport; their
 * offsets are the artist's own — both scenes bottom out 58/60px below the panel's top rail */
.au-mount,.au-castle{position:absolute;display:block;pointer-events:none;
  background:no-repeat center/100% 100%;image-rendering:auto}
.au-mount{right:100%;top:-94px;width:110px;height:152px;background-image:var(--img-lg-mount)}
.au-castle{left:100%;top:-104px;width:110px;height:164px;background-image:var(--img-lg-castle)}

.au-card{
  width:292px;max-width:96vw;box-sizing:border-box;
  border-style:solid;border-width:50px 40px 50px 40px;
  border-image:var(--img-lg-panel) 50 40 50 40 fill / 50px 40px 50px 40px;
  image-rendering:auto;background:none;box-shadow:none;border-radius:0;
  backdrop-filter:none;padding:0;overflow:visible;margin-top:0}
/* the banner: 216x114, centred on the panel and overlapping its top rail by 41px */
.au-card::before{
  content:'';position:absolute;left:-2px;right:auto;top:-123px;width:216px;height:114px;
  background:var(--img-lg-logo) no-repeat center/216px 114px;
  opacity:1;pointer-events:none;z-index:2}

/* ---- the plates ----------------------------------------------------------- */
.au-tabs{background:none;border:0;border-radius:0;padding:0;gap:6px;margin:0 0 14px}
.au-tab,.au-social button{
  flex:1;height:37px;padding:0;border-radius:0;background:none;
  display:flex;align-items:center;justify-content:center;
  box-sizing:border-box;border-style:solid;border-width:12px 16px 13px 16px;
  border-image:var(--img-lg-btn) 12 16 13 16 fill / 12px 16px 13px 16px;
  image-rendering:auto;font-size:12px;letter-spacing:.5px;color:#c9a678;
  text-shadow:0 1px 0 #000;box-shadow:none;transition:filter .12s}
.au-tab:hover,.au-social button:hover{filter:brightness(1.2);color:#f0d9a8;
  border-color:transparent;background:none}
.au-tab.sel{color:#ffe3ab;filter:brightness(1.25) saturate(1.15)}

/* 10px, not 9: the card is vertically centred in the stage, so an ODD card height puts it on
   a half pixel and resamples the panel's rails. An even field rhythm keeps both the login and
   the (one field taller) register height even. */
.au-card .au-fld{margin-bottom:10px}
/* Scoped to the sign-in card: on THAT panel the field name lives in the placeholder. The
 * create-character modal reuses .au-fld for sections that have no placeholder to fall back on
 * — unscoped, this rule silently erased "Background", "Class", "Starting weapon", "Body" and
 * "Appearance" from the form. */
.au-card .au-fld label{display:none}
.au-card .au-box{
  width:204px;height:48px;margin:0 auto;box-sizing:border-box;gap:0;
  border-style:solid;border-width:14px 26px 15px 26px;
  border-image:var(--img-lg-field) 14 26 15 26 fill / 14px 26px 15px 26px;
  image-rendering:auto;background:none;border-radius:0;padding:0}
/* the rest of the plate treatment is scoped to the card for the same reason as the label
 * rule above — .au-box/.au-peek are shared with the create-character modal */
.au-card .au-box:focus-within{box-shadow:0 0 12px -2px #ff6a4a66;border-color:transparent}
.au-card .au-box .ic{display:none}
.au-card .au-box input{color:#f3dcae;font-size:13px;padding:0;text-align:center}
.au-card .au-box input::placeholder{color:#9c7550;letter-spacing:1px}
.au-card .au-peek{color:#9c7550;padding:0;font-size:13px}
.au-card .au-peek:hover,.au-card .au-peek.on{color:#ffd991}

.au-row{width:204px;margin:6px auto 14px;font-size:11.5px;color:#a98d6a}
.au-chk{color:#c9a678}
.au-chk input{appearance:none;-webkit-appearance:none;width:20px;height:22px;margin:0;
  border:0;border-radius:0;background:var(--img-lg-check-off) no-repeat center/20px 22px;
  image-rendering:auto;cursor:pointer}
.au-chk input:checked{background-image:var(--img-lg-check-on)}
.au-link{color:#d9a24c}
.au-link:hover{color:#ffd991}

/* width-scoped to the card: #ccErr in the create modal is an .au-err too, and 204px centred
   truncated its (much longer) validation messages */
.au-card .au-err{width:204px;margin:0 auto 12px}
.au-err{border-color:#6b2a24;background:#2a1310;color:#f0a58f}

.au-go.btn.prime{
  width:204px;height:42px;margin:0 auto;box-sizing:border-box;
  display:flex;align-items:center;justify-content:center;
  border-style:solid;border-width:14px 24px 15px 24px;
  border-image:var(--img-lg-btn2) 14 24 15 24 fill / 14px 24px 15px 24px;
  image-rendering:auto;background:none;border-radius:0;padding:0;
  color:#f5deb0;font-size:12.5px;letter-spacing:1.2px;box-shadow:none}
.au-go.btn.prime:hover:not([disabled]){filter:brightness(1.18);background:none;border-color:transparent}
.au-go:active:not([disabled]){transform:translateY(1px)}
.au-go.btn.prime[disabled]{filter:grayscale(.6) brightness(.65)}
.au-go::after{content:none;display:none}    /* the gloss sweep slides off pixel-art plates */

/* line-height:14px, not `normal` (14.5): the divider is the only fractional row in the card,
   and half a pixel there is enough to land the whole 9-sliced panel on y=199.75 — where its
   top and bottom rails get resampled across two device rows and read soft. */
.au-div{width:204px;margin:14px auto 10px;color:#8a7050;font-size:10px;line-height:14px;
  text-transform:uppercase;letter-spacing:1px}
.au-div:before,.au-div:after{background:#4a3a28}
/* gap:6 divides 204 into three whole 64px plates; gap:5 left them on 64.23/65.53 */
.au-social{width:204px;margin:0 auto;gap:6px}
/* flex-basis 0, not auto: growing from each label's own width gave the three plates 62.3 /
   65.5 / 64.1px — three differently-sized copies of the same artwork, each off the pixel grid */
.au-social button{font-size:10px;letter-spacing:0;flex:1 1 0;min-width:0}

.au-foot{color:#6b5a44}
.au-foot a{color:#8a7050}
.au-foot a:hover{color:#ffd991}

/* the music toggle rides the panel's right edge, where the sheet drew its own pair of little
 * plates — those are only ~9px tall, so their lettering is unreadable at any size we'd ship;
 * the button reuses the readable in-panel plate and carries real text instead */
.au-audio{
  position:absolute;left:calc(100% + 34px);bottom:30px;width:92px;height:30px;
  box-sizing:border-box;display:flex;align-items:center;justify-content:center;
  border-style:solid;border-width:12px 16px 13px 16px;
  border-image:var(--img-lg-btn) 12 16 13 16 fill / 12px 16px 13px 16px;
  image-rendering:auto;background:none;border-radius:0;padding:0;cursor:pointer;
  white-space:nowrap;font-size:10px;letter-spacing:.3px;color:#c9a678;
  text-shadow:0 1px 0 #000;transition:filter .12s}
.au-audio:hover{filter:brightness(1.2);color:#f0d9a8}
.au-audio.off{filter:grayscale(.5) brightness(.8);color:#8a7050}
.au-audio:active{transform:translateY(1px)}
/* narrow viewports have no room beside the panel — tuck it under instead */
@media (max-width:700px){.au-audio{left:auto;right:0;bottom:-40px}}

/* ---------------------------------------------------------------- the top menu strip
 * Four of the artist's bevelled plates (`tb-btn`, the de-lettered button cut from the 688px
 * runic sheet) floating as one compact strip: Character / Discoveries / Options / Quit. The
 * gem-cornered frame is retired — that is what took the bar from 148px tall down to the
 * plates' own 61px. Each plate carries a PixelLab-generated 32px pixel glyph
 * (assets/ui/icons/tb_*.png, the icon-concepts.json `topbar` batch) instead of an emoji.
 *
 * SECOND EXCEPTION TO THE SCALING RULE AT THE TOP OF THIS FILE — like the crimson hotbar the
 * plate is true 1x pixel art, so it renders with `image-rendering:pixelated`, drawn at 1x.
 *
 * EVERY NUMBER HERE IS A SOURCE PIXEL:
 *   61    plate height (sheet y87..147) — fixed, so the 0/14/0/14 border-image only ever
 *         stretches the plate horizontally across its uniform face and never resamples it
 *   14    the octagonal chamfer slices, kept 1:1 at every width
 *   32    the glyphs' native size, drawn 1:1
 * fitTopbar() (ui/hud.js) sizes the strip to its plates and pins the strip — and every
 * plate — to whole pixels: a half-pixel origin smears every nearest-neighbour edge. */
#topbar{
  /* left and width are whole pixels set by fitTopbar(); see the note there on why not 50% */
  left:0;right:auto;transform:none;top:6px;
  height:61px;padding:0;gap:0;border:none;border-radius:0;box-shadow:none;
  background:none;image-rendering:pixelated;backdrop-filter:none;
  filter:drop-shadow(0 6px 14px rgba(0,0,0,.6));
  display:block;
}

#topbar .tbtns{display:flex;align-items:stretch;justify-content:flex-start;gap:10px;margin-left:0}

/* one plate. `fill` paints the (de-lettered, uniform) face; the 14px side slices are the
   artist's octagonal chamfers and stay 1:1 at every width. */
#topbar .tbtns .tplate{
  flex:0 0 auto;height:61px;min-width:96px;padding:0 18px;
  display:flex;align-items:center;justify-content:center;gap:8px;
  border-style:solid;border-width:0 14px;
  border-image:var(--img-tb-btn) 0 14 fill / 0 14px;
  image-rendering:pixelated;background:none;border-radius:0;box-shadow:none;
  white-space:nowrap;cursor:pointer;transition:filter .12s}
#topbar .tbtns .tplate .ti{width:32px;height:32px;image-rendering:pixelated;
  filter:drop-shadow(0 1px 1px #000)}
/* the sheet's lettering is heavy blood-red with a black keyline; this is the nearest the UI
   font gets to it without pretending to be the same pixel type */
#topbar .tbtns .tplate .tl{
  font-size:12px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:#f2334c;
  text-shadow:1px 0 0 #33000c,-1px 0 0 #33000c,0 1px 0 #33000c,0 -1px 0 #33000c,0 2px 3px #000a}
#topbar .tbtns .tplate:hover{filter:brightness(1.22)}
#topbar .tbtns .tplate:active{filter:brightness(.92);transform:translateY(1px)}
#topbar .tbtns .tplate.on{filter:brightness(1.3) saturate(1.15)}

/* the HUD's top row clears the 67px strip (top:6 + 61 plates). The arcs and gauges vitals
   rules in hud.css carry their own (higher-specificity) top, so they need their own
   overrides — a bare #vitals{top} loses to them and would leave them under the bar. */
#frames,#minimap{top:80px}
#battle{top:270px;max-height:30vh}
#vitals{top:76px}
body[data-vstyle="arcs"] #vitals{top:80px}
body[data-vstyle="gauges"] #vitals{left:12px;top:80px}
/* the fight menu rides the left rail below the portrait frame (80 + 77 + 12) */
#combatstrip{top:169px}
/* …and the strip must never reach the world's edges. fitTopbar() sets .compact when the
   lettered strip would not fit the viewport — a media query cannot do it, because the cut-off
   is the measured length of four translated labels, not a fixed breakpoint */
#topbar.compact .tbtns{gap:6px}
/* one min-width, no padding: label advances differ, and the artist drew plates of one size —
   four differently-sized copies of the same plate would read as a bug */
#topbar.compact .tbtns .tplate{min-width:76px;padding:0}
#topbar.compact .tbtns .tplate .tl{display:none}

/* ---------------------------------------------------------------- the fight-modes menu
 * The artist's combat-menu mock-up (references/pixellab-combat-menu-256.png), cut into
 * `menu-panel` (the open menu, 176x192) and `menu-plate` (the "collapsed menu" name plate,
 * 225x30). THIRD EXCEPTION TO THE SCALING RULE AT THE TOP OF THIS FILE — true 1x pixel art,
 * so `image-rendering:pixelated`, drawn at 1:1 like the top bar.
 *
 * The four modes are PAINTED INTO the panel — icon, lettering and cell frame all belong to
 * the art. So the buttons hold no markup: each is a transparent rectangle parked over the
 * quadrant the artist drew, and the only thing CSS contributes is the lit ring on the chosen
 * one. EVERY NUMBER BELOW IS A SOURCE PIXEL, measured off the sheet and stated piece-local
 * (the panel is cut at sheet 67,54):
 *   30 / 159   the content area's top and bottom rows (sheet y84..214)
 *   92 / 95    the horizontal rule between the two mode rows (sheet y146..149)
 *   60 / 105   the two columns' left edges (sheet x127 and x172), 43 wide each, split by
 *              the vertical groove the artist drew at sheet x169..172
 * The top frame band (rows 0..29, above the content) is the fold handle: clicking it swaps
 * the panel for the plate, which is the state the artist drew the plate FOR. */
#combatstrip{width:176px;height:192px;image-rendering:pixelated;
  filter:drop-shadow(0 6px 14px rgba(0,0,0,.6))}
#combatstrip.folded{width:225px;height:30px}
.cm-panel{position:relative;width:176px;height:192px;
  background:var(--img-menu-panel) no-repeat left top/176px 192px}
.cm-plate{display:none;width:225px;height:30px;padding:0;border:none;border-radius:0;
  background:var(--img-menu-plate) no-repeat left top/225px 30px;
  image-rendering:pixelated;cursor:pointer;transition:filter .12s}
.cm-plate:hover{filter:brightness(1.18)}
#combatstrip.folded .cm-panel{display:none}
#combatstrip.folded .cm-plate{display:block}

/* the fold handle: the frame's top band, crystals and all */
.cm-fold{position:absolute;left:0;top:0;width:176px;height:30px;
  padding:0;border:none;background:none;cursor:pointer}

/* one mode. No text, no icon, no box — the artist drew all three. */
.cmode{position:absolute;padding:0;border:none;background:none;border-radius:5px;
  cursor:pointer;transition:background .12s,box-shadow .12s}
.cmode.tl,.cmode.bl{left:60px;width:43px}
.cmode.tr,.cmode.br{left:105px;width:43px}
.cmode.tl,.cmode.tr{top:30px;height:62px}
.cmode.bl,.cmode.br{top:95px;height:65px}
.cmode:hover{background:rgba(255,255,255,.055);box-shadow:inset 0 0 0 1px #6f625c}
/* chosen: the sheet has no lit state, so the cell is ringed and washed in its own blood red */
.cmode.on{background:radial-gradient(ellipse at 50% 40%,rgba(200,50,39,.42),transparent 72%);
  box-shadow:inset 0 0 0 1px #e0483a,inset 0 0 10px rgba(176,44,34,.7)}
