/* ═══════════════════════════════════════════════════════════════════════
   world-actionbar.css — THE ACTION BAR v2 (GH #3069, slice S4).

   The v7 mock's art-first bar in kit B: the carved slate rail
   (kitb/g-bar.png) with six wells, the card's own art in each, a keycap,
   the cooldown sweep, the socket's shape, BASE on an empty socket, and
   BUILD and CARDS beside it. One row under 1280 wide. Markup:
   prototype/the-hall-3d/web/tpl-actionbar.html; painter:
   public/js/world-actionbar.js; owner: world-wave0.js.

   Every rule sits under `body.hud-v2 #w0worldbar.ab2`: world-hud-v2.js puts
   `hud-v2` on <body> (flag or ?hud=1) and world-wave0.js puts `ab2` on the
   bar only when it mounted the v2 component, so with the flag off this file
   styles nothing and the v1 bar is untouched. The one exception is the
   phone cluster's `corners` block at the foot (#3394 C3-phone), which sits
   under `body.hud-v2.mv-cluster`: world-cluster.js puts that class there
   only while WASD is on and a phone has the cluster up.

   ── THE LAYER ───────────────────────────────────────────────────────────
   `skin`. The v1 bar's BAR_CSS is injected into `module` and styles
   `#w0worldbar` itself (a wrapping flex row, max-width 96vw); this sheet
   outranks it by LAYER, so every one of those properties is restated here
   rather than out-specified. (And `corners` for that last block, whose
   rules answer the chat's and the map corner's own `corners` rules.)

   ── THE RAIL PIXEL, --ab-s ──────────────────────────────────────────────
   g-bar.png is 146x26 at its native pixels and the mock drew it at 4 on
   1920x1080 (584x104). It comes from the first generated sheet, whose art
   pixel is twice kit B's, so it is NOT --hv-k (2 there): it steps on its
   own.

       3    from 1280 wide           (1280, 1440, 1920: 438x78)
       4.5  from 2400x1350           (2560x1440)
       6    from 3360x1890           (3840x2160)

   ⭐THREE QUARTERS OF THE MOCK'S SIZE (Wray, 2026-09-29: "the Spell bar hud
   itself i think is a little oversized anyway", then "lets try 25% then
   if its a perfect resize"). 25% smaller in every band, the doors with
   it. 3 and 6 are whole steps, so every rail pixel is the same size on
   any screen; 4.5 is whole on a 2x screen and a pixel uneven here and
   there on a 1x 2560 monitor. The icon box (16 rail pixels, 48 at 3) sits
   a pixel and a half in from a 15-pixel well, which is whole on a 2x
   screen. It was 4, 6 and 8, then 3.25 (18.75%) for a day (#3401).
   The caps, the badges and the tooltip keep --ab-u: the pixel font is
   only crisp at its own 8px.

   Under 1280 wide (or 540 tall) there is no carved rail: the one-row
   layout at the foot of this file takes over. A half-scale rail (2) was
   tried below 1000 and failed review: 30px wells under a touch on a
   tablet, and the caps and badges, drawn at the mock's pixel, buried
   the art. And between 1000 and 1279 the carved rail cannot clear
   Nerm's column in the bottom-left corner and still keep BUILD and
   CARDS on screen (348 + 584 + 146 > 1024).

   ── CLEAR OF NERM'S COLUMN, --ab-clear-l ────────────────────────────────
   Nerm's ambient strip (.wt-nerm, world-skin.css) and the guide's home
   bubble (nerm-guide.css) both stand at the frame's left + 12, 320 wide.
   The rail's left end never comes nearer than 16px past them: the rail is
   centred, and pushed right when centring would put it under him (a 1024
   or 1152 window: review of #3090). The tooltip keeps to the rail's left
   end for the same reason (world-actionbar.js placeTip).

   ── THE WELLS, measured off g-bar.png, not the mock ────────────────────
   The dark-rimmed hole of each well, in rail pixels (x y w h):

       skill  13 3 17 18      weapon 37 3 15 15      chest 57 3 15 15
       head   78 3 15 15      boots  99 3 15 15      bag  119 3 15 15

   ── ICONS CENTRED ON THEIR OWN PIXELS (Wray, #3069, a build rule) ───────
   The art box (--ab-art) is 16 rail pixels: 64 at 4, where a spell icon
   (64 native) is drawn 1:1 and a base icon (32 native) at exactly 2. It is
   centred on the well by calc, and every well and the art box share a
   parity, so the offsets are whole pixels: -2 on a 60 well, 2 and 4 on
   the skill's 68x72. The two pixels that overhang a well are clipped by
   the well itself (.ab2-ic), so the art sits flush in the carving.
   ═══════════════════════════════════════════════════════════════════════ */
@layer base, module, skin, nerm, corners;

@layer skin {
/* ⛔THE LIFT IS PADDING, NOT `bottom`. The legacy arena plank
   (world-legacy-door.js) stands itself --w0bar-h + 12px up from the screen's
   foot, --w0bar-h being this element's offsetHeight: it assumes the bar sits
   on the foot. A bar lifted by `bottom` hid that gap from the measure and the
   plank landed on the phone's row (shot 2026-09-24). Padding is inside
   offsetHeight, so the plank clears the rail; the padding itself takes no
   taps (pointer-events below). */
body.hud-v2 #w0worldbar.ab2 {
  --ab-s: 3;
  --ab-art: 48px;
  --ab-u: 1px;
  /* BUILD and CARDS, square, 48 at --ab-u 1: the mock's 64 at three quarters */
  --ab-door: calc(48 * var(--ab-u));
  /* half the rail's width (146 rail pixels), and the nearest the rail's
     left end may come to the frame's left edge (see the header) */
  --ab-half: calc(73px * var(--ab-s));
  --ab-clear-l: 348px;
  /* ⭐RAIL AND DOORS ARE CENTRED TOGETHER WHERE THERE IS ROOM, as the mock
     drew them (Wray, 2026-09-28). BUILD and CARDS hang off the rail's right
     end (10 + 52 + 8 + 52 bar pixels, half of it 61), so centred alone the
     rail ran them out past its middle; stepped left by half the doors the
     pair is centred, and the mock's 560 Inventory at 1920 runs down beside
     them (world-windows-v2.css).
     ⛔NEVER INTO THE CHAT. The step is only what the chat panel leaves
     (world-chat-v2.css: 12 chrome pixels in, --chat-w wide, then 12 clear):
     the full step at 1920 and 1728, none at 1512, where a rail stepped the
     whole way sat on the chat's last 60px (shot 2026-09-28, at the old size). The chat
     reads the rail's centred place for its own width, and this never takes
     the rail nearer to it than that. The clear-of-Nerm floor below still
     wins on a small laptop. 0 in the one-row layout, where the doors ride
     above the rail instead of beside it. */
  --ab-doors-half: calc(9 * var(--ab-u) + var(--ab-door));
  --ab-shift: max(0px, min(var(--ab-doors-half),
    calc(var(--fw, 100vw) / 2 - var(--ab-half) - 12px * var(--hv-k, 1) - var(--chat-w, 320px) - 12px)));
  position: fixed;
  left: max(calc(var(--fx, 0px) + var(--fw, 100vw) / 2 - var(--ab-shift)),
    calc(var(--fx, 0px) + var(--ab-clear-l) + var(--ab-half)));
  bottom: 0;
  padding: 0 0 calc(var(--wf-safe-bottom, var(--fb, var(--fy, 0px))) + 22px);
  transform: translateX(-50%);
  z-index: 42;
  display: block;
  gap: 0;
  max-width: none;
  flex-wrap: nowrap;
  font-family: var(--hv-f-px);
  pointer-events: none;
}
/* ⭐ON WHOLE PIXELS AT AN ODD WIDTH. Half of an odd frame width is a half
   pixel, and translateX(-50%) of an even bar kept it: at 1365 the rail sat
   at x 390.5 and its gold edges blended (review of #3090). Every bar width
   is even (584, 876, 1168, and 352 in one row), so rounding the centre
   down is enough. round() is recent, so the line above stands wherever it
   is not understood. */
@supports (left: round(down, 1px, 1px)) {
  body.hud-v2 #w0worldbar.ab2 {
    left: max(calc(var(--fx, 0px) + round(down, calc(var(--fw, 100vw) / 2 - var(--ab-shift)), 1px)),
      calc(var(--fx, 0px) + var(--ab-clear-l) + var(--ab-half)));
  }
}
body.hud-v2 #w0worldbar.ab2 .ab2-rail,
body.hud-v2 #w0worldbar.ab2 .ab2-doors { pointer-events: auto; }
/* a tooltip up stands the bar over the PLAY ARENA plank (z 44), which a
   tooltip over a button can reach on a phone */
body.hud-v2 #w0worldbar.ab2:has(.ab2-tip:not([hidden])) { z-index: 45; }
/* --ab-u 2 from 2400: at 1.5 the pixel font drew at 12px, a pixel and a
   half per glyph pixel, with grey fringes on every letter */
@media (min-width: 2400px) and (min-height: 1350px) {
  body.hud-v2 #w0worldbar.ab2 { --ab-s: 4.5; --ab-art: 72px; --ab-u: 2px; }
}
@media (min-width: 3360px) and (min-height: 1890px) {
  body.hud-v2 #w0worldbar.ab2 { --ab-s: 6; --ab-art: 96px; --ab-u: 2px; }
}
/* --ab-u: the mock's pixel at 1920, for everything drawn ON the rail (the
   caps, the badges, the tooltip, the doors): 1 through the 4 band, so those
   read exactly as the mock's there, and 2 above it, always a whole number
   so the pixel font lands on whole pixels. Declared per band beside --ab-s,
   not derived from it (world-hud-v2.css says why a derived token goes
   stale). */

/* the rail is the only thing in flow: the doors and the tooltip hang off it */
body.hud-v2 #w0worldbar.ab2 .ab2-bar {
  position: relative;
  display: block;
}

/* ── the rail: the carved bar, drawn whole at the rail pixel ─────────── */
body.hud-v2 #w0worldbar.ab2 .ab2-rail {
  position: relative;
  flex: 0 0 auto;
  width: calc(146px * var(--ab-s));
  height: calc(26px * var(--ab-s));
  background: url('/assets/ui/kitb/g-bar.png?v=2026-09-24a') 0 0 / 100% 100% no-repeat;
  image-rendering: pixelated;
}

/* ── a slot: the well itself ─────────────────────────────────────────── */
body.hud-v2 #w0worldbar.ab2 .ab2-slot {
  position: absolute;
  top: calc(3px * var(--ab-s));
  width: calc(15px * var(--ab-s));
  height: calc(15px * var(--ab-s));
  box-sizing: border-box;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  color: var(--hv-ink);
  font: inherit;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
body.hud-v2 #w0worldbar.ab2 .ab2-slot[data-part='slot1'] {
  left: calc(13px * var(--ab-s));
  width: calc(17px * var(--ab-s));
  height: calc(18px * var(--ab-s));
}
body.hud-v2 #w0worldbar.ab2 .ab2-slot[data-part='slot2'] { left: calc(37px * var(--ab-s)); }
body.hud-v2 #w0worldbar.ab2 .ab2-slot[data-part='slot3'] { left: calc(57px * var(--ab-s)); }
body.hud-v2 #w0worldbar.ab2 .ab2-slot[data-part='slot4'] { left: calc(78px * var(--ab-s)); }
body.hud-v2 #w0worldbar.ab2 .ab2-slot[data-part='slot5'] { left: calc(99px * var(--ab-s)); }
body.hud-v2 #w0worldbar.ab2 .ab2-slot[data-part='slot6'] { left: calc(119px * var(--ab-s)); }
/* (an empty well keeps the pointer cursor: pressing it opens CARDS) */
body.hud-v2 #w0worldbar.ab2 .ab2-slot:focus-visible {
  outline: 2px solid var(--hv-gold-hi);
  outline-offset: 2px;
}

/* the well's own clip: the art box overhangs it by a pixel or two */
body.hud-v2 #w0worldbar.ab2 .ab2-ic {
  position: absolute;
  inset: 0;
  overflow: hidden;
}
body.hud-v2 #w0worldbar.ab2 .ab2-art {
  position: absolute;
  left: calc(50% - var(--ab-art) / 2);
  top: calc(50% - var(--ab-art) / 2);
  width: var(--ab-art);
  height: var(--ab-art);
  background-repeat: no-repeat;
  image-rendering: auto;
}
/* a strip: one cell of --ab-cols, the cell the painter names */
body.hud-v2 #w0worldbar.ab2 .ab2-art[data-art='spell'],
body.hud-v2 #w0worldbar.ab2 .ab2-art[data-art='base'] {
  background-size: calc(var(--ab-cols, 1) * var(--ab-art)) var(--ab-art);
  background-position: calc(var(--ab-cell, 0) * var(--ab-art) * -1) 0;
}
/* the base icons are 32px pixel art: nearest neighbour, never smudged */
body.hud-v2 #w0worldbar.ab2 .ab2-art[data-art='base'] { image-rendering: pixelated; }
/* an item's face, cropped to its matted Subject (56,70,128,128 of 240x380):
   the art box is that 128 square, so the face is 240/128 and 380/128 of it */
body.hud-v2 #w0worldbar.ab2 .ab2-art[data-art='face'] {
  background-size: calc(var(--ab-art) * 1.875) calc(var(--ab-art) * 2.96875);
  background-position: calc(var(--ab-art) * -0.4375) calc(var(--ab-art) * -0.546875);
}
body.hud-v2 #w0worldbar.ab2 .ab2-art[data-art='none'] { display: none; }
/* ⭐A BASE ABILITY IS DRAWN AT FULL STRENGTH (#3069 S10, audit HD-12). An
   empty socket fires its piece's own ability, and its icon used to be
   dimmed as well (saturate .6, brightness .9) on top of art that is already
   pale lilac, so a new player's bar, four sockets on BASE, read as mostly
   disabled: Wray's "the action bar squares are terrible". The BASE tag under
   the slot already says what it is; the art says it is ready. */
body.hud-v2 #w0worldbar.ab2 .ab2-slot:hover .ab2-art { filter: brightness(1.15); }

/* ⭐AN EMPTY WELL SAYS IT CAN BE FILLED (#3069 S10, audit C18 / PH-14:
   "doesnt look like i have empty slots"). Slot six with nothing in the bag
   was a plain dark square. Every empty well, slot six included, draws a
   faint plus, 7x7 at the rail pixel (28 in a 60 well, and 28 in the phone's
   40, 16 and 6 each side: whole pixels), brighter under the pointer or the
   keyboard. A press opens CARDS, as it always did.

   ⛔NOT a drawn bag (S10 review). A 7x7 bag is a loop over a box, and at
   that size it read as a PADLOCK: "locked", the opposite of "I can fill
   this". The plus says fill me at any size. */
body.hud-v2 #w0worldbar.ab2 .ab2-slot.is-empty .ab2-ic::before {
  content: '';
  position: absolute;
  left: calc(50% - 3.5px * var(--ab-s));
  top: calc(50% - 3.5px * var(--ab-s));
  width: calc(7px * var(--ab-s));
  height: calc(7px * var(--ab-s));
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 7 7' shape-rendering='crispEdges'%3E%3Cpath fill='%23e3c79a' d='M3 0h1v3H3zM0 3h7v1H0zM3 4h1v3H3z'/%3E%3C/svg%3E") 0 0 / 100% 100% no-repeat;
  opacity: 0.4;
  image-rendering: pixelated;
  pointer-events: none;
}
body.hud-v2 #w0worldbar.ab2 .ab2-slot.is-empty:hover .ab2-ic::before,
body.hud-v2 #w0worldbar.ab2 .ab2-slot.is-empty:focus-visible .ab2-ic::before { opacity: 0.75; }
/* a once-a-life item already used */
body.hud-v2 #w0worldbar.ab2 .ab2-slot.is-spent .ab2-art { filter: grayscale(1) brightness(0.45); }

/* THE LONG PULL's FOIL (#4292 B28, FEATURE_PACKS_LONG_PULL): a card you
   hold as a foil wears a foil rim, the foil look's colours, round the well.
   On the slot itself, over the art (the well's own inset shadow would be
   painted under its child and never show). world-wave0.js marks the slot
   `is-foil` only with the flag on, so off nothing here matches. */
body.hud-v2 #w0worldbar.ab2 .ab2-slot.is-foil::after {
  content: '';
  position: absolute;
  inset: calc(-1px * var(--ab-s));
  z-index: 1;
  box-sizing: border-box;
  border: calc(1px * var(--ab-s)) solid transparent;
  border-image: linear-gradient(135deg, #f08a24, #f2c23a, #44b86a, #2fb3a6, #3a7bd5, #8b3fc0) 1;
  pointer-events: none;
}

/* in hand: lit in the card's own colour, as v1's glow */
body.hud-v2 #w0worldbar.ab2 .ab2-slot.is-sel {
  filter: drop-shadow(0 0 6px var(--ab-glow, rgba(212, 166, 75, 0.9)));
}
/* the ring sits OVER the art (an inset shadow on the well would be painted
   under its own child, the art, and never show) and under the sweep */
body.hud-v2 #w0worldbar.ab2 .ab2-slot.is-sel .ab2-ic::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  box-shadow: inset 0 0 0 2px var(--hv-gold-hi), inset 0 0 10px 2px var(--ab-glow, rgba(212, 166, 75, 0.9));
  pointer-events: none;
}
/* the keypress dip: stepped, so it stays drawn rather than eased */
body.hud-v2 #w0worldbar.ab2 .ab2-slot.is-press .ab2-ic { animation: ab2-press 140ms steps(2, end); }
@keyframes ab2-press {
  0% { transform: translateY(2px); }
  100% { transform: none; }
}

/* ── the cooldown sweep: what is left, cleared clockwise from twelve ─── */
body.hud-v2 #w0worldbar.ab2 .ab2-cd {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: grid;
  place-items: center;
  font: calc(16 * var(--ab-u))/1 var(--hv-f-px);
  color: #fff;
  text-shadow: 0 2px 0 #000, 2px 0 0 #000, -2px 0 0 #000, 0 -2px 0 #000;
  background: conic-gradient(transparent 0 calc(100% - var(--ab-p, 0%)), rgba(5, 7, 10, 0.78) 0);
  pointer-events: none;
}

/* ── THE CORNER PIECES, placed as the mock placed them ──────────────────
   The mock's offsets (kc -4,-6; sh -4,-4; bs -10; ct 6,5) are from ITS
   slot box, which is the well plus 6px of frame on every side. This slot
   IS the well, so each number here is the mock's less 6: the keycap stands
   off the top-left corner, the shape badge off the bottom-right, BASE hangs
   below the art rather than over it. They scale with --ab-u, the mock's
   pixel. (The first build used the mock's numbers against the well, which
   put all three 6px onto the art, and moved the badge to the top right to
   dodge a BASE tag that was only there because of it: review of #3090.) */

/* ── the keycap, top left, from the bindings ─────────────────────────── */
body.hud-v2 #w0worldbar.ab2 .ab2-kc {
  position: absolute;
  z-index: 3;
  left: calc(-10 * var(--ab-u));
  top: calc(-12 * var(--ab-u));
  min-width: calc(20 * var(--ab-u));
  height: calc(20 * var(--ab-u));
  padding: 0 calc(4 * var(--ab-u));
  box-sizing: border-box;
  display: grid;
  place-items: center;
  font: calc(8 * var(--ab-u))/1 var(--hv-f-px);
  color: var(--hv-ink);
  background: #0b1016;
  box-shadow: 0 0 0 calc(2 * var(--ab-u)) var(--hv-black), inset 0 0 0 calc(2 * var(--ab-u)) #56472f;
  pointer-events: none;
}

/* ── the socket's shape, bottom right, beside BASE (they touch, as the
   mock's do, and do not overlap) ───────────────────────────────────── */
body.hud-v2 #w0worldbar.ab2 .ab2-sh {
  position: absolute;
  z-index: 3;
  right: calc(-10 * var(--ab-u));
  bottom: calc(-10 * var(--ab-u));
  width: calc(20 * var(--ab-u));
  height: calc(20 * var(--ab-u));
  display: grid;
  place-items: center;
  background: #0b1016;
  box-shadow: 0 0 0 calc(2 * var(--ab-u)) var(--hv-black), inset 0 0 0 calc(2 * var(--ab-u)) var(--ab-ring, #56472f);
  pointer-events: none;
}
/* 6 glyph pixels at 2 (3, 4): whole pixels in every band */
body.hud-v2 #w0worldbar.ab2 .ab2-sh svg { width: calc(12 * var(--ab-u)); height: calc(12 * var(--ab-u)); display: block; }

/* ── BASE, under an empty socket ─────────────────────────────────────── */
body.hud-v2 #w0worldbar.ab2 .ab2-bs {
  position: absolute;
  z-index: 3;
  left: 50%;
  bottom: calc(-16 * var(--ab-u));
  transform: translateX(-50%);
  padding: calc(3 * var(--ab-u)) calc(4 * var(--ab-u));
  font: calc(8 * var(--ab-u))/1 var(--hv-f-px);
  color: #c9d4e2;
  background: #2c3645;
  box-shadow: 0 0 0 calc(2 * var(--ab-u)) var(--hv-black);
  white-space: nowrap;
  pointer-events: none;
}

/* ── a charge count, bottom right of the art ───────────────────────────
   16, not the mock's 12: the pixel font is drawn on an 8px grid, and at 8
   the "1" was hard to find on the art (review of #3090) */
body.hud-v2 #w0worldbar.ab2 .ab2-ct {
  position: absolute;
  z-index: 3;
  right: 0;
  bottom: calc(-1 * var(--ab-u));
  font: calc(16 * var(--ab-u))/1 var(--hv-f-px);
  color: #fff;
  text-shadow: 0 2px 0 #000, 2px 0 0 #000, -2px 0 0 #000, 0 -2px 0 #000;
  pointer-events: none;
}

/* ── BUILD and CARDS, beside the rail ──────────────────────────────────
   Hung off the rail's right end rather than laid out beside it, so the
   RAIL is what sits on the frame's centre line (the mock centred rail and
   button together, which put the rail 73px left of centre, and at 1280 its
   first slot under Nerm's guide panel: shot 2026-09-24). */
body.hud-v2 #w0worldbar.ab2 .ab2-doors {
  position: absolute;
  left: calc(100% + 10 * var(--ab-u));
  bottom: calc(2px * var(--ab-s));
  display: flex;
  gap: calc(8 * var(--ab-u));
}
/* the world mounts the bar without its doors (`doors: false`); the rule
   above sets display, which beats the hidden attribute on its own */
body.hud-v2 #w0worldbar.ab2 .ab2-doors[hidden] { display: none; }
body.hud-v2 #w0worldbar.ab2 .ab2-door {
  width: var(--ab-door);
  height: var(--ab-door);
  box-sizing: border-box;
  margin: 0;
  padding: 0;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: calc(2 * var(--ab-u));
  font: calc(8 * var(--ab-u))/1 var(--hv-f-px);
  color: var(--hv-ink);
  text-shadow: 0 2px 0 #000;
  background: none;
  cursor: pointer;
  border-style: solid;
  border-width: 0;
  border-image: url('/assets/ui/kitb/door.png?v=2026-09-24a') 8 fill / calc(8px * var(--hv-k, 2)) stretch;
  image-rendering: pixelated;
}
body.hud-v2 #w0worldbar.ab2 .ab2-door:hover,
body.hud-v2 #w0worldbar.ab2 .ab2-door:focus-visible {
  border-image: url('/assets/ui/kitb/dooron.png?v=2026-09-24a') 11 fill / calc(11px * var(--hv-k, 2)) / calc(3px * var(--hv-k, 2)) stretch;
  outline: none;
}
body.hud-v2 #w0worldbar.ab2 .ab2-door b { font-weight: normal; }
body.hud-v2 #w0worldbar.ab2 .ab2-door-ic {
  /* nav-icons.png's 16px glyph at 1.5 (3 at --ab-u 2): three device pixels
     a glyph pixel on a retina screen, and three quarters of the mock's 2 */
  width: calc(24 * var(--ab-u));
  height: calc(24 * var(--ab-u));
  background: url('/assets/ui/nav-icons.png?v=2026-09-06b') 0 0 / calc(240 * var(--ab-u)) calc(48 * var(--ab-u)) no-repeat;
  image-rendering: pixelated;
}
body.hud-v2 #w0worldbar.ab2 .ab2-door-ic[data-door='nine'] { background-position: calc(-96 * var(--ab-u)) 0; }
body.hud-v2 #w0worldbar.ab2 .ab2-door-ic[data-door='spellbook'] { background-position: calc(-144 * var(--ab-u)) 0; }

/* ── the tooltip: kit B's tip.png, above the slot, inside the frame ──── */
body.hud-v2 #w0worldbar.ab2 .ab2-tip {
  position: absolute;
  z-index: 5;
  left: 0;
  bottom: calc(100% + 12 * var(--ab-u));
  width: calc(300 * var(--ab-u));
  box-sizing: border-box;
  display: grid;
  gap: calc(6 * var(--ab-u));
  padding: calc(14 * var(--ab-u)) calc(16 * var(--ab-u));
  border-style: solid;
  border-width: 0;
  border-image: url('/assets/ui/kitb/tip.png?v=2026-10-04a') 5 fill / calc(5px * var(--hv-k, 2)) stretch;
  box-shadow: 0 10px 24px rgba(0, 0, 0, 0.45);
  image-rendering: pixelated;
  pointer-events: none;
  text-align: left;
}
body.hud-v2 #w0worldbar.ab2 .ab2-tip b {
  font: calc(8 * var(--ab-u))/1.5 var(--hv-f-px);
  font-weight: normal;
  color: var(--hv-gold-2);
}
body.hud-v2 #w0worldbar.ab2 .ab2-tip span {
  font: calc(20 * var(--ab-u))/1.05 var(--hv-f-vt);
  color: var(--hv-ink);
}
body.hud-v2 #w0worldbar.ab2 .ab2-tip em {
  font: normal calc(17 * var(--ab-u))/1.1 var(--hv-f-vt);
  color: var(--hv-mute);
}

/* ── ONE ROW: the phone, the tablet, a small window ──────────────────────
   Under 1280 wide, or 540 tall (a handset held sideways: world-frame.js
   FILL_MAX_SHORT_EDGE). The carved rail is fixed at six wells and 146 art
   pixels wide, so here the rail is kit B's gold frame instead, holding six
   framed slots: 56 + 5 x 50, the gaps and the rims make 352, inside 390
   with a 16px gutter each side, and every slot is at least 50px square,
   above the 44 a touch needs (a 768 tablet had 30px wells on the half-scale
   rail: review of #3090). No BUILD (the Inventory door is in the top row);
   CARDS rides above the rail's right end, so the socket picker stays one
   tap away. Keycaps only where there is a keyboard: see the block below. */
@media (max-width: 1279px), (max-height: 540px) {
  /* 16: the rail's foot used to stand 26 up to clear the old Chat tab
     (.wp-tab, review of #3090), which the HUD pass hides (world-chat-v2.css),
     and the empty foot strip that took taps there is gone too (below), so
     the rail stands the safe area plus 16 off the bottom, near the mock's 18
     (#3069 S10, audit PH-7). The plank and the chat read its height
     (--w0bar-h) and move down with it. */
  body.hud-v2 #w0worldbar.ab2 {
    --ab-half: 176px;
    --ab-doors-half: 0px;
    padding-bottom: calc(var(--wf-safe-bottom, var(--fb, var(--fy, 0px))) + 16px);
  }
  body.hud-v2 #w0worldbar.ab2 .ab2-rail {
    width: auto;
    height: auto;
    display: flex;
    align-items: flex-end;
    gap: 6px;
    padding: 8px;
    background: none;
    border-style: solid;
    border-width: 0;
    border-image: url('/assets/ui/kitb/door.png?v=2026-09-24a') 8 fill / 8px stretch;
  }
  /* --ab-art 32: a base icon (32 native) at exactly 1 and a spell (64) at
     exactly a half, centred on whole pixels in the 40 and 46 wells (4 and 7
     each side). The first build drew them at 40 and 46, 1.25x and 1.44x,
     and the base icons' pixels came out in two sizes. */
  body.hud-v2 #w0worldbar.ab2 .ab2-slot,
  body.hud-v2 #w0worldbar.ab2 .ab2-slot[data-part] {
    --ab-art: 32px;
    position: relative;
    left: auto;
    top: auto;
    width: 50px;
    height: 50px;
    flex: 0 0 auto;
    border-style: solid;
    border-width: 0;
    border-image: url('/assets/ui/kitb/slot1.png?v=2026-09-24a') 5 fill / 5px stretch;
  }
  body.hud-v2 #w0worldbar.ab2 .ab2-slot[data-part='slot1'] {
    width: 56px;
    height: 56px;
  }
  body.hud-v2 #w0worldbar.ab2 .ab2-ic { inset: 5px; }
  body.hud-v2 #w0worldbar.ab2 .ab2-kc { display: none; }
  /* the mock's phone badge: 14 square, the glyph at 8 inside its 2px ring.
     TOP right here, not the mock's bottom right: the mock's BASE was 5px
     type, and at the pixel font's own 8 the tag is 38 wide on a 50 slot and
     covered the badge (shot 2026-09-24). The top right is free: no keycaps
     on a phone, and a small window's cap is top left. */
  body.hud-v2 #w0worldbar.ab2 .ab2-sh { width: 14px; height: 14px; right: -3px; top: -3px; bottom: auto; }
  body.hud-v2 #w0worldbar.ab2 .ab2-sh svg { width: 8px; height: 8px; }
  body.hud-v2 #w0worldbar.ab2 .ab2-bs { bottom: -8px; padding: 2px 3px; }
  body.hud-v2 #w0worldbar.ab2 .ab2-ct { right: 3px; bottom: 3px; font-size: 8px; }
  body.hud-v2 #w0worldbar.ab2 .ab2-doors {
    left: auto;
    right: 0;
    bottom: calc(100% + 4px);
  }
  body.hud-v2 #w0worldbar.ab2 .ab2-door[data-part='build'] { display: none; }
  body.hud-v2 #w0worldbar.ab2 .ab2-door {
    width: auto;
    height: 28px;
    padding: 0 8px;
    grid-auto-flow: column;
    align-items: center;
    gap: 4px;
    border-image-width: 8px;
  }
  body.hud-v2 #w0worldbar.ab2 .ab2-door-ic {
    width: 16px;
    height: 16px;
    background-size: 160px 32px;
  }
  body.hud-v2 #w0worldbar.ab2 .ab2-door-ic[data-door='spellbook'] { background-position: -96px 0; }
  body.hud-v2 #w0worldbar.ab2 .ab2-tip { width: min(300px, calc(100vw - 32px)); }

  /* a short screen (a phone held sideways) has the phone's minimap and its
     one-line list in the right-hand corner, just above the bar's right end,
     so CARDS rides above the bar's LEFT end there instead: at 844x390 it sat
     on the list's foot (#3069 S10, audit PH-1).
     ⛔ONLY WHERE THE RAIL CLEARS THE CHAT (S10 review). At 707 wide or less
     the bar is centred (below), its left end over the chat panel, and at
     667x375 CARDS landed on the chat's corner; the right end is free there,
     since under 380 tall the list is hidden. */
  @media (max-height: 540px) and (min-width: 708px) {
    body.hud-v2 #w0worldbar.ab2 .ab2-doors { left: 0; right: auto; }
  }

  /* a screen too narrow to keep the row right of Nerm's column (348 + 352
     + 8) centres it; Nerm's strip and the guide's bubble stand above the
     bar there instead (world-skin.css, nerm-guide.css) */
  @media (max-width: 707px) {
    body.hud-v2 #w0worldbar.ab2 { --ab-clear-l: 0px; }
  }

  /* a small window on a computer still has the keys: small caps, off the
     frame's top-left corner, as the mock's desktop caps are */
  @media (hover: hover) and (pointer: fine) {
    body.hud-v2 #w0worldbar.ab2 .ab2-kc {
      display: grid;
      left: -4px;
      top: -6px;
      min-width: 16px;
      height: 16px;
      padding: 0 3px;
    }
  }
}

/* ── A THUMB'S REACH ON A TOUCH SCREEN (#3069 S10, audit PH-8 / C8) ──────
   CARDS draws 28 tall on a phone, under the 44 floor, and it is the one way
   to the socket picker there. A transparent box round it takes the press,
   the way the door row's tiles do (world-doors-v2.css), so the art is
   unchanged. */
@media (pointer: coarse) {
  body.hud-v2 #w0worldbar.ab2 .ab2-door { position: relative; }
  body.hud-v2 #w0worldbar.ab2 .ab2-door::before {
    content: '';
    position: absolute;
    left: 50%;
    top: 50%;
    width: max(100%, 44px);
    height: max(100%, 44px);
    transform: translate(-50%, -50%);
  }
}

/* the keypress dip is motion: none for a player who asked for less */
@media (prefers-reduced-motion: reduce) {
  body.hud-v2 #w0worldbar.ab2 .ab2-slot.is-press .ab2-ic { animation: none; }
}

/* LAST, so it beats every `display` above: a part the painter hid stays
   hidden (an author `display` outranks the browser's own [hidden] rule) */
body.hud-v2 #w0worldbar.ab2 [hidden] { display: none; }

/* ⭐THE EMPTY FOOT STRIP GOES (#3069 S10, audit PH-7). #wt-foot is the old
   HUD's foot bar: a full-width, transparent strip over the bottom 38px that
   takes pointer events. Under the pass it holds nothing (the say line moved
   into the chat panel, Nerm's strip stands down, the Albion corner took the
   camera pad), yet it swallowed every tap on the ground there, which on a
   phone held sideways is a tenth of the screen. The ONE rule in this sheet
   that is not the bar's: it stands where the bar's lift is decided, and it
   waits for the say line to be inside the chat panel, so a page where the
   panel never came keeps its strip. */
body.nav-albion.hud-v2:has(#world-chat-panel #world-chat) #wt-foot { display: none; }

/* ── THE PHONE CLUSTER (#3394 C3-phone, tasks/prd-combat.md §4, W10 ruling
   2 A) ────────────────────────────────────────────────────────────────────
   Under WASD on a phone, world-cluster.js lays this bar out as the lab's
   touch cluster: the attack in the corner, the special straight above it,
   the four spells round an arc to the left, the consumable over the
   special, the dodge under the arc beside the attack. Its pure layout
   hands every part a rect, which the painter writes as --cl-x/-y/-w/-h
   (relative to the cluster's frame, which #w0worldbar takes, so its
   measured height is what the chat and the plank stand on).

   ⭐EVERY RULE HERE NEEDS `.is-cluster` on the bar's root, which only the
   cluster's layout puts there, so with WASD off not one of them applies
   and the row above is exactly as it was.

   The art is the kit's: the six ability buttons keep the phone row's slot
   (kitb/slot1.png, 5px rim) and everything drawn in it (art, sweep, BASE,
   the shape badge, the charge); the two VERBS, set apart and larger, take
   kit B's gold frame (kitb/door.png, the .hv-frame, 8px rim), the attack
   with the Raven attributes' sword (stat-icons.png cell 0, the ATK stat's)
   at exactly 2, 64 in the 68 inside its rim. */
body.hud-v2 #w0worldbar.ab2:has(> .ab2-bar.is-cluster) {
  left: var(--cl-x);
  top: var(--cl-y);
  right: auto;
  bottom: auto;
  width: var(--cl-w);
  height: var(--cl-h);
  padding: 0;
  transform: none;
}
body.hud-v2 #w0worldbar.ab2 .ab2-bar.is-cluster {
  position: absolute;
  inset: 0;
}
/* the rail is only the slots' parent here: no carving, no frame, and no
   press of its own, so a thumb between two buttons meets the world */
body.hud-v2 #w0worldbar.ab2 .ab2-bar.is-cluster .ab2-rail {
  position: static;
  display: block;
  width: auto;
  height: auto;
  padding: 0;
  background: none;
  border-width: 0;
  border-image: none;
  pointer-events: none;
}
body.hud-v2 #w0worldbar.ab2 .ab2-bar.is-cluster .ab2-slot[data-part],
body.hud-v2 #w0worldbar.ab2 .ab2-bar.is-cluster .ab2-verb {
  --ab-art: 32px;
  position: absolute;
  left: var(--cl-x);
  top: var(--cl-y);
  width: var(--cl-w);
  height: var(--cl-h);
  margin: 0;
  padding: 0;
  flex: none;
  box-sizing: border-box;
  pointer-events: auto;
  /* the thumb's drag aims the button (world-cluster.js), never scrolls or
     calls up the long-press menu */
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
  background: none;
  border-style: solid;
  border-width: 0;
  border-image: url('/assets/ui/kitb/slot1.png?v=2026-09-24a') 5 fill / 5px stretch;
  image-rendering: pixelated;
}
/* the art centred on its own pixels: 32 in a 48 slot's 38 (3 each side),
   in the consumable's 34 (1) */
body.hud-v2 #w0worldbar.ab2 .ab2-bar.is-cluster .ab2-ic { inset: 5px; }
/* the phone row's badges, whatever the screen, but INSIDE the slot's
   corner: on the arc a spell can stand 6 px under another, and a badge
   overhanging its top by 3 met the BASE tag hanging from the one above,
   whose E it ate ("BASF", shot 2026-09-29) */
body.hud-v2 #w0worldbar.ab2 .ab2-bar.is-cluster .ab2-sh { width: 14px; height: 14px; right: 1px; top: 1px; bottom: auto; }
body.hud-v2 #w0worldbar.ab2 .ab2-bar.is-cluster .ab2-sh svg { width: 8px; height: 8px; }
/* BASE hangs 4 under its slot, not the row's 8: with its 2 px ring it ends
   exactly where a neighbour 6 below begins */
body.hud-v2 #w0worldbar.ab2 .ab2-bar.is-cluster .ab2-bs { bottom: -4px; padding: 2px 3px; font-size: 8px; }
body.hud-v2 #w0worldbar.ab2 .ab2-bar.is-cluster .ab2-ct { right: 3px; bottom: 3px; font-size: 8px; }
/* a touch screen has no keys to name */
@media (pointer: coarse) {
  body.hud-v2 #w0worldbar.ab2 .ab2-bar.is-cluster .ab2-kc { display: none; }
}

/* ── the two verbs: kit B's gold frame ── */
body.hud-v2 #w0worldbar.ab2 .ab2-bar.is-cluster .ab2-verb {
  display: grid;
  place-items: center;
  color: var(--hv-ink);
  font: 8px/1 var(--hv-f-px);
  text-shadow: 0 2px 0 #000;
  cursor: pointer;
  border-image: url('/assets/ui/kitb/door.png?v=2026-09-24a') 8 fill / 8px stretch;
}
body.hud-v2 #w0worldbar.ab2 .ab2-bar.is-cluster .ab2-verb:focus-visible {
  outline: 2px solid var(--hv-gold-hi);
  outline-offset: 2px;
}
body.hud-v2 #w0worldbar.ab2 .ab2-bar.is-cluster .ab2-verb-ic {
  display: block;
  width: 64px;
  height: 64px;
  background: url('/assets/ui/stat-icons.png?v=2026-09-25a') 0 0 / 320px 64px no-repeat;
  image-rendering: pixelated;
  pointer-events: none;
}
body.hud-v2 #w0worldbar.ab2 .ab2-bar.is-cluster .ab2-dodge b { font-weight: normal; pointer-events: none; }
/* W26 (C9b, #4228): GUARD fills as a gauge of the bubble's pool, from the
   bottom, the share in --ab2-guard (world-actionbar.js paintGauge); it
   empties on a burst. Under the word and the icon, inside the gold frame */
body.hud-v2 #w0worldbar.ab2 .ab2-bar.is-cluster .ab2-dodge.is-guard::after {
  content: '';
  position: absolute;
  left: 6px;
  right: 6px;
  bottom: 6px;
  height: calc(var(--ab2-guard, 0) * (100% - 12px));
  background: rgba(159, 211, 255, 0.38);
  pointer-events: none;
  z-index: 0;
}
body.hud-v2 #w0worldbar.ab2 .ab2-bar.is-cluster .ab2-dodge.is-guard > * { position: relative; z-index: 1; }
/* the press, as a slot's dip */
body.hud-v2 #w0worldbar.ab2 .ab2-bar.is-cluster .ab2-verb.is-press > * { animation: ab2-press 140ms steps(2, end); }

/* ── CARDS rides on the cluster, as it rode on the row's right end. Its
   rect is its press box (44 tall), the door drawn 28 tall in the middle of
   it, where a coarse pointer's reach (below) already makes it 44 ── */
body.hud-v2 #w0worldbar.ab2 .ab2-bar.is-cluster .ab2-doors {
  position: absolute;
  left: var(--cl-x);
  top: var(--cl-y);
  right: auto;
  bottom: auto;
  width: var(--cl-w);
  height: var(--cl-h);
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 0;
}
body.hud-v2 #w0worldbar.ab2 .ab2-bar.is-cluster .ab2-door[data-part='build'] { display: none; }
body.hud-v2 #w0worldbar.ab2 .ab2-bar.is-cluster .ab2-door {
  width: auto;
  height: 28px;
  padding: 0 8px;
  grid-auto-flow: column;
  align-items: center;
  gap: 4px;
  font-size: 8px;
  border-image-width: 8px;
}
body.hud-v2 #w0worldbar.ab2 .ab2-bar.is-cluster .ab2-door-ic {
  width: 16px;
  height: 16px;
  background-size: 160px 32px;
}
body.hud-v2 #w0worldbar.ab2 .ab2-bar.is-cluster .ab2-door-ic[data-door='spellbook'] { background-position: -96px 0; }
body.hud-v2 #w0worldbar.ab2 .ab2-bar.is-cluster .ab2-tip { width: min(300px, calc(100vw - 32px)); }

@media (prefers-reduced-motion: reduce) {
  body.hud-v2 #w0worldbar.ab2 .ab2-bar.is-cluster .ab2-verb.is-press > * { animation: none; }
}
/* LAST in the cluster too, for the reason the row's own rule is last: a
   part the painter hid (a verb not yet honoured, an empty badge) stays
   hidden against the `display` rules above, which out-specify that rule */
body.hud-v2 #w0worldbar.ab2 .ab2-bar.is-cluster [hidden] { display: none; }
}
/* end of @layer skin */

@layer corners {
/* ── WHAT STANDS CLEAR OF THE CLUSTER (#3394 C3-phone) ─────────────────────
   body.mv-cluster is on only while world-cluster.js has the cluster up, and
   it publishes four measures there: --mv-chat-bottom (where the chat
   stands, px above the foot: above the stick's resting ring, and above the
   cluster where the two share columns), --mv-claim-r and --mv-claim-h (how
   far the cluster reaches in from the right edge and up from the foot), and
   --mv-ring-right (where the stick's resting ring ends, px from the left:
   Nerm's home bubble stands right of it, world-phone.css).
   `corners`, because the chat's numbers are the chat's corner rules
   (world-chat-v2.css), and the map's corner is world-map-v2.css's.

   ⭐THE THUMBS OWN THE FOOT OF THE SCREEN. The chat panel stood on the
   row's foot on a phone (the bottom-left corner), exactly where the left
   thumb rests and C3-client's stick waits; under the cluster it stands
   above that ring instead. The plank and the guide's bubble stand on the
   chat (--chat-lift), so they rise with it. */
body.hud-v2.mv-cluster {
  --chat-bottom: var(--mv-chat-bottom, calc(var(--w0bar-h, 110px) + 8px));
}
/* ...and on a short screen, where there is no room for the resting panel
   between the thumbs and the plate or the quest list above them, it rests
   folded to its tab row, as it folds for the guide (world-chat-v2.css): the
   tabs keep their badges and a tap opens it as before */
@media (max-height: 699px) {
  body.hud-v2.mv-cluster #world-chat-panel[data-state='rest'] { height: var(--chat-h-fold, 20px); }
  body.hud-v2.mv-cluster #world-chat-panel[data-state='rest'] .wc2-body { display: none; }
  body.hud-v2.mv-cluster:has(#world-chat-panel[data-state='rest']) {
    --chat-lift: calc(var(--chat-bottom) + var(--chat-h-fold, 20px));
  }
}
/* A PHONE HELD SIDEWAYS: the cluster rises into the right-hand column, so
   the minimap and the quest list under it step left of what it claims. The
   door row above them stays where it is. */
@media (max-height: 540px) {
  body.hud-v2.mv-cluster .an-tr > .wt-map,
  body.hud-v2.mv-cluster .an-tr > .wtk {
    transform: translateX(calc(-1 * var(--mv-claim-r, 0px)));
  }
}
}
/* end of @layer corners */
