/*
  EXTRACTIONS — THE EXTRACTION BAY
  ================================
  What a player is holding, what it is worth, and the one action that turns it
  into SEQS. Plus the OVERCAP bounty board and the record of every extraction
  this account has ever made.

  ── THE REDESIGN, 2026-08-15 ────────────────────────────────────────────────
  His verdict on the shipped page was one word — "hurrendous" — and a widen-the
  -category ruling, not two bug fixes. What was wrong was not the colours or the
  spacing: it was that a page about a MACHINE was drawn as a LIST. A player who
  has just killed a Rex reads a table row about it.

  So the page is now the machine. There is a BED you put skulls into and a
  LEVER you pull, the skulls are DRAWN, and the whole thing boots like a
  terminal coming up cold. His words: "i need actual animations, actual
  placement ... and they place the skull themselves then extract it."

  ★ WHAT SURVIVED THE REDESIGN UNTOUCHED, BECAUSE IT IS PRODUCT TRUTH AND NOT
    DESIGN: the two different missing states (`pending` = not valued, `unnamed`
    = not named) stay worded separately on the skull itself; the bounty board
    still has NO CLOCK IN IT; a locked skull is still held for ever; an unknown
    reading is still an em dash. The look was replaced. The facts were not.

  THE RULES THIS SHEET KEEPS — the site's own, quoted from `_rankings.css`,
  which is where this theme wrote them down.

  1. NEVER THE PALE BLUE. Three tiers — #79D9FF hot, #4BB4FC body, #2C84EE dim
     — over the console's near-black. Nothing drifts toward near-white.
  2. THE SITE'S GROUND IS A PHOTOGRAPH. Every panel takes _term.css's own
     `.panel` seat. This page wears `.plate.deep` because it is a data view and
     the theme's class contract says so.
  3. AMBER IS A SINGLETON, AND ON THIS PAGE IT IS SPENT ON ONE THING: THE
     OVERCAP BOUNTY. Green stays reserved for state (a balance that just moved,
     an extraction that landed). Red is a refusal and nothing else.
  4. AN EMPTY HOLD IS A FINISHED STATE, NOT A HOLE.
  5. UNKNOWN IS NOT ZERO. Never a 0, never a bar drawn at 0%.
  6. REDUCED MOTION REMOVES THE MOTION, NOT THE INFORMATION.
  7. NO SKELETONS. The first read draws the same armed, empty furniture every
     other empty state draws.

  ★ THE ONE THING THIS PAGE ADDS TO THE VOCABULARY, AND WHY
    PLACEMENT IS THE SELECTION. There is no checkbox on this page. A skull is
    selected by being PUT SOMEWHERE — dragged, tapped or keyed onto the bed —
    and the bed is the running total, so the number a player is about to commit
    to is never in a different place from the thing it counts.
    ★★ The bulk case is not lost to the physical one: `MOUNT ALL` fills the bed
    in one press for a player holding forty skulls, because forty drags is not
    a feature. Both doors, one bed.
*/

/* ============================================================== the tokens */
/* Declared on the page root for this feature so every block below — including
   the boot curtain, which sits outside `.screen` — reads the same palette.
   Only #79D9FF is a literal, because the theme spells it out inline too. */
.xb-scope {
  --ex-hot: #79D9FF;
  --ex-val: var(--blue-hot);
  --ex-lab: var(--blue-dim);
  --ex-line: rgba(30, 111, 224, .28);
  --ex-edge: rgba(30, 111, 224, .45);
  --ex-seat: rgba(1, 4, 10, .74);
  --ex-head: rgba(0, 19, 71, .42);
  --ex-settle: cubic-bezier(.16, .84, .28, 1);
  --ex-point: cubic-bezier(.2, .8, .2, 1);
  /* the arrival curve the craft floor asks for: confident, no bounce */
  --ex-arrive: cubic-bezier(.16, 1, .3, 1);
}

/* ── THE TIER RAMP ────────────────────────────────────────────────────────
   Six tiers over three blues is a real problem: the theme has three colours
   and this page has six ranks. Colour alone cannot carry it, so RANK IS
   CARRIED BY THREE THINGS AT ONCE — hue, ink strength, and the skull drawing
   itself. A player who cannot tell #2C84EE from #4BB4FC still sees a bigger
   skull with more teeth. Colour is the third signal here, never the only one. */
.xb-scope [data-tier="1"] { --t-ink: rgba(44, 132, 238, .72); --t-glow: none; }
.xb-scope [data-tier="2"] { --t-ink: #2C84EE; --t-glow: none; }
.xb-scope [data-tier="3"] { --t-ink: #4BB4FC; --t-glow: none; }
.xb-scope [data-tier="4"] { --t-ink: #4BB4FC; --t-glow: 0 0 10px -2px rgba(75, 180, 252, .55); }
.xb-scope [data-tier="5"] { --t-ink: #79D9FF; --t-glow: 0 0 12px -2px rgba(121, 217, 255, .6); }
.xb-scope [data-tier="6"] { --t-ink: #79D9FF; --t-glow: 0 0 18px -3px rgba(121, 217, 255, .95); }
.xb-scope [data-tier="overcap"] { --t-ink: var(--amber); --t-glow: 0 0 14px -2px rgba(255, 180, 84, .8); }
.xb-scope [data-tier="unclassed"] { --t-ink: var(--rule); --t-glow: none; }
.xb-scope [data-tier=""] { --t-ink: var(--rule); --t-glow: none; }

/* ★ THE COLD START'S STYLES ARE NOT HERE. `_term.js` + `_term.css` build it
   on every page of the site, so this sheet carries none of it. These 75
   lines survived as DEAD CSS after the JS and the markup were removed —
   found by a validation sweep, 2026-08-15. */

/* ================================================================= the head */
.xb-rails, .xb-rig, .xb-floor, .xb-note {
  position: relative; z-index: 4;
}
.xb-rails {
  display: flex; flex-wrap: wrap; align-items: baseline;
  gap: 10px clamp(16px, 3vw, 40px);
  margin: 14px 0 var(--pad);
  padding: 11px 14px;
  background: var(--ex-seat);
  border: 1px solid var(--ex-line);
  border-left: 1px solid var(--ex-edge);
}
.xb-fig { display: flex; align-items: baseline; gap: 9px; min-width: 0; }
.xb-fig .k {
  font-family: var(--mono); font-size: var(--t-micro);
  letter-spacing: .18em; color: var(--ex-lab); white-space: nowrap;
}
.xb-fig .v {
  font-family: var(--wide); font-size: clamp(17px, 2.4vw, 23px);
  line-height: 1; color: var(--ex-val); letter-spacing: .02em;
  font-variant-numeric: tabular-nums;
}
.xb-fig .u {
  font-family: var(--mono); font-size: 10px; letter-spacing: .16em;
  color: var(--ex-lab);
}
.xb-fig .v.dash { color: var(--rule); }
.xb-fig .v.moved { animation: xb-moved 1.5s var(--ex-settle) both; }
@keyframes xb-moved {
  0%   { color: var(--green); text-shadow: 0 0 16px rgba(91, 255, 166, .8); }
  100% { color: var(--ex-val); text-shadow: none; }
}
.xb-state {
  margin-left: auto; display: flex; align-items: center; gap: 8px;
  font-family: var(--mono); font-size: var(--t-micro);
  letter-spacing: .16em; color: var(--ex-lab);
}
.xb-dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--blue); box-shadow: 0 0 7px var(--blue);
}
.xb-state.busy .xb-dot { background: var(--amber); box-shadow: 0 0 7px var(--amber);
  animation: xb-pulse 1s ease-in-out infinite; }
.xb-state.bad .xb-dot { background: var(--red); box-shadow: 0 0 7px var(--red); }
.xb-state.good .xb-dot { background: var(--green); box-shadow: 0 0 7px var(--green); }
@keyframes xb-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .3; } }

/* ============================================================== THE RIG =====
   The bed and the lever. This is the page's authored moment and the only place
   on the site that is a machine rather than a reading. */
.xb-rig {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 0;
  border: 1px solid var(--ex-edge);
  background:
    linear-gradient(to bottom, rgba(0, 19, 71, .30), rgba(1, 4, 10, .82));
  margin-bottom: var(--pad);
}
/* the corner ticks the theme puts on every instrument */
.xb-rig::before, .xb-rig::after {
  content: ""; position: absolute; width: 13px; height: 13px;
  border: 1px solid var(--ex-hot); pointer-events: none;
}
.xb-rig::before { left: -1px; top: -1px; border-right: 0; border-bottom: 0; }
.xb-rig::after { right: -1px; bottom: -1px; border-left: 0; border-top: 0; }

.xb-rig-main { grid-column: 1; min-width: 0; }
.xb-rh {
  display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap;
  padding: 9px 14px; border-bottom: 1px solid var(--ex-line);
  background: var(--ex-head);
}
.xb-rh h2 {
  margin: 0; font-family: var(--wide); font-size: var(--t-fine);
  letter-spacing: .22em; color: var(--ex-hot); font-weight: 400;
}
.xb-rh .meta {
  margin-left: auto; font-family: var(--mono); font-size: var(--t-micro);
  letter-spacing: .14em; color: var(--ex-lab); font-variant-numeric: tabular-nums;
}
.xb-rh .meta b { color: var(--ex-hot); font-weight: 400; }

/* ── the bed ─────────────────────────────────────────────────────────────
   The drop target. It is a real target with a real hover state, because a
   drop zone that does not answer the pointer is how a drag fails silently. */
.xb-bed {
  position: relative;
  min-height: 152px;
  padding: 16px 14px 14px;
  overflow: hidden;
  /* the rails the skulls sit on */
  background-image:
    repeating-linear-gradient(to right,
      rgba(30, 111, 224, .16) 0 2px, transparent 2px 9px);
  background-size: 100% 1px;
  background-position: 0 calc(100% - 26px);
  background-repeat: no-repeat;
  transition: background-color .18s var(--ex-point), box-shadow .18s var(--ex-point);
}
.xb-bed.hot {
  background-color: rgba(30, 111, 224, .11);
  box-shadow: inset 0 0 0 1px var(--ex-hot), inset 0 0 46px -14px rgba(121, 217, 255, .55);
}
.xb-bed.firing { background-color: rgba(30, 111, 224, .07); }

/* the sweep the lever sends down the bed */
.xb-sweep {
  position: absolute; top: 0; bottom: 0; width: 90px;
  left: 0; opacity: 0; pointer-events: none;
  background: linear-gradient(to right,
    transparent, rgba(121, 217, 255, .30) 62%, rgba(121, 217, 255, .06));
  border-right: 1px solid var(--ex-hot);
  box-shadow: 0 0 26px rgba(121, 217, 255, .45);
}
.xb-bed.firing .xb-sweep { animation: xb-bedsweep .62s linear both; }
@keyframes xb-bedsweep {
  from { transform: translateX(-100px); opacity: 1; }
  to   { transform: translateX(calc(100% + 100vw)); opacity: 1; }
}

/* the sockets are the flex row; the bed is only the case around them */
.xb-sockets {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-wrap: wrap; align-items: flex-start; gap: 12px;
}
.xb-slot { list-style: none; }

/* ── a socket ────────────────────────────────────────────────────────────
   Empty is a dashed cradle. Full is a clamped skull with its own value. */
.xb-socket {
  position: relative;
  width: 104px; min-height: 118px;
  display: grid; grid-template-rows: 1fr auto;
  border: 1px dashed rgba(30, 111, 224, .5);
  background: rgba(1, 4, 10, .55);
  color: var(--ex-lab);
  font-family: var(--mono);
}
.xb-socket.ghost {
  align-content: center; justify-items: center;
  font-size: 10px; letter-spacing: .2em; text-align: center;
  border-color: rgba(30, 111, 224, .3);
}
.xb-socket.ghost .n {
  font-family: var(--wide); font-size: 18px; color: rgba(30, 111, 224, .55);
}
.xb-bed.hot .xb-socket.ghost {
  border-color: var(--ex-hot); color: var(--ex-hot);
  animation: xb-ready .9s ease-in-out infinite;
}
@keyframes xb-ready {
  0%, 100% { box-shadow: inset 0 0 0 0 rgba(121, 217, 255, 0); }
  50%      { box-shadow: inset 0 0 22px -6px rgba(121, 217, 255, .55); }
}

/* the mounted skull is a button — pressing it takes the skull back off */
.xb-mount {
  position: relative;
  width: 104px; min-height: 118px;
  display: grid; grid-template-rows: 1fr auto;
  padding: 0; border: 1px solid var(--t-ink, var(--ex-edge));
  background: rgba(1, 4, 10, .72);
  box-shadow: var(--t-glow, none);
  color: var(--t-ink, var(--blue));
  font-family: var(--mono); text-align: center; cursor: pointer;
  animation: xb-clamp .34s var(--ex-arrive) both;
}
@keyframes xb-clamp {
  0%   { transform: translateY(-16px) scale(.86); opacity: 0; filter: blur(4px); }
  60%  { transform: translateY(2px) scale(1.02); opacity: 1; filter: none; }
  100% { transform: none; opacity: 1; }
}
.xb-mount .art { display: grid; place-items: center; padding: 17px 6px 3px; }
.xb-mount .art svg { width: 68px; height: 74px; display: block; }
.xb-mount .val {
  border-top: 1px solid rgba(30, 111, 224, .3);
  padding: 5px 4px; font-size: 11px; letter-spacing: .08em;
  color: var(--ex-val); font-variant-numeric: tabular-nums;
}
.xb-mount .val i { font-style: normal; font-size: 8.5px; letter-spacing: .16em;
  color: var(--ex-lab); margin-left: 3px; }
.xb-mount .sp {
  position: absolute; left: 0; right: 0; top: 0;
  font-size: 9px; letter-spacing: .1em; color: var(--ex-lab);
  padding: 3px 4px 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap;
}
/* the clamps that hold it down — drawn, so the skull looks held, not stacked */
.xb-mount::before, .xb-mount::after {
  content: ""; position: absolute; bottom: 26px; width: 13px; height: 7px;
  border: 1px solid var(--t-ink, var(--ex-edge)); border-top: 0;
  transition: transform .2s var(--ex-point);
}
.xb-mount::before { left: 7px; }
.xb-mount::after { right: 7px; }
.xb-mount:hover { background: rgba(30, 111, 224, .16); }
.xb-mount:hover::before { transform: translateX(-3px); }
.xb-mount:hover::after { transform: translateX(3px); }
.xb-mount:focus-visible { outline: 1px solid var(--ex-hot); outline-offset: 2px; }
/* same rule as `.onbed` above: hidden from the eye AND from the text tree, or
   every socket announces its hover hint as if it were part of the label */
.xb-mount .off {
  position: absolute; inset: auto 0 26px; text-align: center;
  font-size: 9px; letter-spacing: .18em; color: var(--ex-hot);
  visibility: hidden; opacity: 0; transition: opacity .16s;
}
.xb-mount:hover .off, .xb-mount:focus-visible .off { visibility: visible; opacity: 1; }

/* leaving the bed under the lever: the skull is read, then it is gone */
.xb-mount.fire { animation: xb-fire .5s var(--ex-point) both; }
@keyframes xb-fire {
  0%   { clip-path: inset(0 0 0 0); filter: none; }
  35%  { clip-path: inset(0 0 0 0); filter: brightness(2.6) drop-shadow(0 0 12px currentColor); }
  100% { clip-path: inset(0 0 100% 0); filter: brightness(3) drop-shadow(0 0 20px currentColor);
         opacity: 0; }
}
/* the value leaving toward the balance */
.xb-spark {
  position: fixed; z-index: 500; pointer-events: none;
  font-family: var(--wide); font-size: 15px; letter-spacing: .04em;
  color: var(--green); text-shadow: 0 0 16px rgba(91, 255, 166, .85);
  font-variant-numeric: tabular-nums;
}

/* ── the bed's own line ─────────────────────────────────────────────────── */
.xb-bedline {
  margin: 0;
  padding: 9px 14px; border-top: 1px solid var(--ex-line);
  font-family: var(--mono); font-size: var(--t-micro); letter-spacing: .1em;
  color: var(--ex-lab); line-height: 1.65;
}
.xb-bedline b { color: var(--ex-hot); font-weight: 400; }
.xb-bedline .warn { color: var(--amber); }

/* ── the lever ───────────────────────────────────────────────────────────
   A real lever: it can be dragged down, and it can be pressed or keyed. The
   drag is the delight; the press is the contract. Neither is the only way in. */
.xb-lever {
  grid-column: 2; grid-row: 1 / -1;
  width: clamp(128px, 15vw, 168px);
  border-left: 1px solid var(--ex-line);
  background: linear-gradient(to bottom, rgba(0, 19, 71, .34), rgba(1, 4, 10, .5));
  display: grid; grid-template-rows: auto 1fr auto;
  padding: 12px 12px 14px;
}
.xb-lever .cap {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .2em;
  color: var(--ex-lab); text-align: center;
}
/* ★ IT HAS TO LOOK LIKE A HANDLE ON A SHAFT, NOT LIKE A SCROLLBAR. The first
   build was a thin slot with a small box at the top of it and the word PULL
   struck through by its own grip hatching — which is exactly what a scrollbar
   looks like, so nobody would ever have pulled it. The parts are now the parts
   a lever actually has: a shaft, a knurled handle that rides it, and a stop
   plate at the bottom the handle travels to. */
.xb-track {
  position: relative; justify-self: center; align-self: stretch;
  width: 58px; margin: 14px 0 10px; min-height: 104px;
}
/* the shaft */
.xb-track::before {
  content: ""; position: absolute; left: 50%; top: 10px; bottom: 12px;
  width: 4px; transform: translateX(-50%);
  background: linear-gradient(to right,
    rgba(30, 111, 224, .25), rgba(75, 180, 252, .55), rgba(30, 111, 224, .25));
  border-radius: 2px;
}
/* the stop plate the handle travels down to */
.xb-track::after {
  content: ""; position: absolute; left: 4px; right: 4px; bottom: 0;
  height: 9px; border: 1px solid rgba(30, 111, 224, .5); border-top: 0;
  background: rgba(1, 4, 10, .8);
}
.xb-pull {
  position: absolute; left: -11px; right: -11px; top: 2px;
  height: 50px; padding: 0;
  border: 1px solid var(--ex-edge);
  background: linear-gradient(to bottom,
    rgba(30, 111, 224, .42), rgba(1, 4, 10, .92) 60%, rgba(30, 111, 224, .3));
  color: var(--ex-lab);
  cursor: grab; touch-action: none;
  display: grid; place-items: center;
  box-shadow: 0 3px 10px -4px rgba(0, 0, 0, .95);
  transition: transform .34s var(--ex-arrive), border-color .2s, color .2s,
              box-shadow .2s, background .2s;
}
/* the knurling, on the two edges where a hand would actually grip — never
   across the middle, which is where the chevron lives */
.xb-pull::before, .xb-pull::after {
  content: ""; position: absolute; top: 9px; bottom: 9px; width: 11px;
  background: repeating-linear-gradient(to bottom,
    currentColor 0 1px, transparent 1px 4px);
  opacity: .55;
}
.xb-pull::before { left: 8px; }
.xb-pull::after { right: 8px; }
.xb-pull .chev { width: 22px; height: 22px; display: block; }
.xb-pull[disabled] { cursor: not-allowed; opacity: .5; }
.xb-pull.armed {
  border-color: var(--ex-hot); color: var(--ex-hot);
  background: linear-gradient(to bottom,
    rgba(75, 180, 252, .5), rgba(1, 4, 10, .9) 60%, rgba(75, 180, 252, .34));
  box-shadow: 0 0 22px -4px rgba(121, 217, 255, .85),
              0 3px 10px -4px rgba(0, 0, 0, .95);
}
.xb-pull.armed .chev { animation: xb-nudge 1.8s ease-in-out infinite; }
@keyframes xb-nudge {
  0%, 70%, 100% { transform: translateY(0); opacity: .9; }
  85%           { transform: translateY(3px); opacity: 1; }
}
.xb-pull.armed:hover { background: linear-gradient(to bottom,
  rgba(75, 180, 252, .68), rgba(1, 4, 10, .88) 60%, rgba(75, 180, 252, .4)); }
.xb-pull:active { cursor: grabbing; }
.xb-pull:focus-visible { outline: 1px solid var(--ex-hot); outline-offset: 3px; }
.xb-pull.dragging { transition: none; }
.xb-pull.dragging .chev { animation: none; }
.xb-lever .word {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .16em;
  text-align: center; color: var(--ex-lab); line-height: 1.7; min-height: 3.4em;
}
.xb-lever.ready .word { color: var(--ex-hot); }
.xb-lever.busy .word { color: var(--amber); }
.xb-lever.off .word { color: var(--amber); }

/* ================================================================ the note
   One lane-wide sentence: not armed, cannot read, or the outcome of the last
   press. A paragraph and not a toast — a receipt that vanishes was never
   banked. */
.xb-note {
  display: flex; gap: 9px; margin-bottom: var(--pad);
  padding: 10px 13px;
  border: 1px solid var(--ex-line); border-left: 2px solid var(--blue);
  background: var(--ex-seat);
  font-family: var(--read); font-size: var(--t-fine); line-height: 1.7;
  color: var(--blue);
  animation: xb-note-in .3s var(--ex-arrive) both;
}
@keyframes xb-note-in { from { opacity: 0; transform: translateY(-5px); } to { opacity: 1; } }
.xb-note i { font-style: normal; color: var(--ex-lab); }
.xb-note b { color: var(--ex-hot); font-weight: 400; }
.xb-note.good { border-left-color: var(--green); color: var(--green); }
.xb-note.good b { color: var(--green); }
.xb-note.warn { border-left-color: var(--amber); color: var(--amber); }
.xb-note.warn b { color: var(--amber); }
.xb-note.bad { border-left-color: var(--red); color: var(--red); }
.xb-note.bad b { color: var(--red); }

/* ================================================================ the floor */
.xb-floor {
  display: grid; gap: var(--pad);
  grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr);
  align-items: start;
}
.xb-rail { display: grid; gap: var(--pad); align-content: start; min-width: 0; }

.xb-panel {
  position: relative;
  border: 1px solid var(--ex-line);
  background: var(--ex-seat);
  min-width: 0;
}
.xb-panel::before, .xb-panel::after {
  content: ""; position: absolute; width: 11px; height: 11px;
  border: 1px solid var(--ex-edge); pointer-events: none;
}
.xb-panel::before { left: -1px; top: -1px; border-right: 0; border-bottom: 0; }
.xb-panel::after { right: -1px; bottom: -1px; border-left: 0; border-top: 0; }
.xb-ph {
  display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap;
  padding: 9px 13px; border-bottom: 1px solid var(--ex-line);
  background: var(--ex-head);
}
.xb-ph h2 {
  margin: 0; font-family: var(--wide); font-size: var(--t-fine);
  letter-spacing: .2em; color: var(--ex-hot); font-weight: 400;
}
.xb-ph .meta {
  margin-left: auto; font-family: var(--mono); font-size: var(--t-micro);
  letter-spacing: .13em; color: var(--ex-lab);
}
.xb-ph .meta b { color: var(--ex-hot); font-weight: 400; }
.xb-body { padding: 5px 0 7px; }
.xb-foot {
  padding: 8px 13px; border-top: 1px solid var(--ex-line);
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .09em;
  line-height: 1.75; color: var(--ex-lab);
}
.xb-foot b { color: var(--ex-hot); font-weight: 400; }

/* ── MOUNT ALL, on the hold's header ─────────────────────────────────────── */
.xb-mountall {
  font-family: var(--mono); font-size: 10px; letter-spacing: .16em;
  color: var(--ex-hot); background: transparent;
  border: 1px solid var(--ex-edge); padding: 4px 9px; cursor: pointer;
  transition: background .16s, border-color .16s;
}
.xb-mountall:hover { background: rgba(30, 111, 224, .2); border-color: var(--ex-hot); }
.xb-mountall:focus-visible { outline: 1px solid var(--ex-hot); outline-offset: 2px; }
.xb-mountall[disabled] { opacity: .4; cursor: not-allowed; }

/* ── the tier band ───────────────────────────────────────────────────────── */
.xb-band { border-bottom: 1px solid var(--ex-line); }
.xb-band:last-child { border-bottom: 0; }
.xb-bh {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 8px 13px 7px;
  border-left: 2px solid var(--t-ink, var(--ex-edge));
  box-shadow: var(--t-glow, none);
  background: rgba(0, 19, 71, .2);
}
.xb-bh .tn {
  font-family: var(--wide); font-size: 10px; letter-spacing: .1em;
  color: var(--t-ink, var(--ex-lab));
  border: 1px solid currentColor; padding: 1px 5px;
}
.xb-bh .nm {
  font-family: var(--wide); font-size: var(--t-fine); letter-spacing: .16em;
  color: var(--t-ink, var(--blue));
}
.xb-bh .ct {
  font-family: var(--mono); font-size: var(--t-micro); color: var(--ex-lab);
  letter-spacing: .1em;
}
.xb-bh .sum {
  margin-left: auto; font-family: var(--mono); font-size: var(--t-micro);
  color: var(--ex-val); letter-spacing: .08em; font-variant-numeric: tabular-nums;
}
.xb-bh .sum i { font-style: normal; color: var(--ex-lab); }
.xb-band[data-tier="unclassed"] .xb-bh { border-left-style: dotted; }

/* ── a skull in the hold ─────────────────────────────────────────────────
   A grabbable card, not a table row. The drawing is the point: a player
   recognises their Rex before they read the word. */
/* ★ THE MINIMUM IS MEASURED, NOT GUESSED. 54px of drawing + the gap + a row
   that has to fit "100%", a grade chip and a five-figure value on one line
   without any of them being crushed. At 184px the value column collapsed to
   nine pixels and the species name ran out of the tile — a number cut in half
   is a wrong number, and this page is about money. */
.xb-tiles {
  display: grid; gap: 9px; padding: 10px 13px 13px;
  grid-template-columns: repeat(auto-fill, minmax(272px, 1fr));
}
.xb-tile {
  position: relative; display: grid;
  grid-template-columns: 66px minmax(0, 1fr);
  align-items: center; gap: 10px;
  padding: 8px 10px 8px 8px;
  border: 1px solid var(--ex-line);
  border-left: 2px solid var(--t-ink, var(--ex-edge));
  background: rgba(1, 4, 10, .6);
  color: var(--blue); text-align: left;
  font-family: var(--mono); cursor: grab; touch-action: none;
  transition: background .16s var(--ex-point), transform .16s var(--ex-point),
              border-color .16s, box-shadow .16s;
}
.xb-tile:hover {
  background: rgba(30, 111, 224, .16);
  transform: translateY(-2px);
  box-shadow: var(--t-glow, 0 4px 14px -6px rgba(0, 0, 0, .9)), 0 5px 16px -8px rgba(0, 0, 0, .95);
}
.xb-tile:focus-visible { outline: 1px solid var(--ex-hot); outline-offset: 2px; }
.xb-tile:active { cursor: grabbing; }
.xb-tile .art { color: var(--t-ink, var(--blue)); display: grid; place-items: center; }
.xb-tile .art svg { width: 66px; height: 71px; display: block; }
.xb-tile .det { display: block; min-width: 0; }
/* ★ `overflow:hidden` DOES NOTHING ON AN INLINE BOX. These were spans with an
   ellipsis rule that could never fire, so a long species name walked straight
   out of the tile. They are blocks now and the ellipsis works. */
.xb-tile .sp {
  display: block; font-family: var(--read); font-size: var(--t-fine);
  color: var(--blue); letter-spacing: .02em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.xb-tile .sp small {
  display: block; font-family: var(--mono); font-size: 9.5px;
  letter-spacing: .1em; color: var(--ex-lab); margin-top: 2px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.xb-tile .fig {
  display: flex; align-items: center; gap: 8px; margin-top: 6px;
}
.xb-tile .gw {
  flex: 0 0 auto;
  font-size: 10px; letter-spacing: .08em; color: var(--ex-lab);
  font-variant-numeric: tabular-nums;
}
/* the value never shrinks: it is the last thing on this page allowed to be
   ambiguous */
.xb-tile .xb-v {
  margin-left: auto; flex: 0 0 auto; white-space: nowrap;
  font-family: var(--wide); font-size: 13px;
  color: var(--ex-val); font-variant-numeric: tabular-nums; letter-spacing: .02em;
}
.xb-tile .xb-v i { font-style: normal; font-size: 8.5px; letter-spacing: .16em;
  color: var(--ex-lab); margin-left: 3px; }

/* the grade chip */
.xb-g {
  flex: 0 0 auto;
  font-family: var(--wide); font-size: 9.5px; letter-spacing: .08em;
  border: 1px solid var(--ex-edge); color: var(--ex-lab);
  padding: 0 4px; line-height: 1.55;
}
.xb-g[data-g="C"], .xb-g[data-g="B"] { color: var(--blue-hot); border-color: rgba(75, 180, 252, .5); }
.xb-g[data-g="A"], .xb-g[data-g="A+"] { color: var(--ex-hot); border-color: rgba(121, 217, 255, .65); }
.xb-g[data-g="S"], .xb-g[data-g="S+"] {
  color: var(--ex-hot); border-color: var(--ex-hot);
  box-shadow: 0 0 9px -2px rgba(121, 217, 255, .9);
}
.xb-g.none { border-style: dotted; }

/* mounted: the tile stays in place as an empty berth, so the hold never
   reflows under the player's hand mid-drag. */
.xb-tile.mounted {
  cursor: default; opacity: .34; border-left-style: dotted;
  background: rgba(1, 4, 10, .3);
}
.xb-tile.mounted:hover { transform: none; box-shadow: none; background: rgba(1, 4, 10, .3); }
.xb-tile.mounted .art { opacity: .3; }
/* ★ TOP-RIGHT, NOT BOTTOM-RIGHT: at the foot of the tile this sat exactly on
   top of the value and printed two different things in the same pixels. */
/* ★★ `opacity:0` HIDES A LABEL FROM THE EYE AND NOT FROM THE TEXT TREE. Every
   tile carries this tag and only a mounted one should say it — with opacity
   alone a screen reader read "ON THE BED" on all twelve skulls, including the
   ones sitting in the hold, which is the page telling a blind player the exact
   opposite of the truth about their own property. `visibility` takes it out of
   the tree and still animates. */
.xb-tile .onbed {
  position: absolute; top: 6px; right: 8px;
  font-size: 8.5px; letter-spacing: .16em; color: var(--ex-hot);
  background: rgba(1, 4, 10, .9); padding: 1px 4px;
  border: 1px solid rgba(121, 217, 255, .45);
  visibility: hidden; opacity: 0; pointer-events: none;
  transition: opacity .16s var(--ex-point);
}
.xb-tile.mounted .onbed { visibility: visible; opacity: 1; }

/* ★ LOCKED SKULLS. Two different missing things, and the tile says which.
   Not draggable, not mountable — and NOT hidden, because it is the player's
   property and it is safe. Dotted border is this theme's word for "unknown". */
.xb-tile.locked {
  cursor: help; border-style: dotted; border-left-style: dotted;
  border-left-color: var(--rule);
  background: rgba(1, 4, 10, .4);
}
.xb-tile.locked:hover { transform: none; box-shadow: none; background: rgba(30, 111, 224, .1); }
.xb-tile.locked .art { opacity: .45; }
.xb-tile.locked .xb-v { color: var(--ex-lab); font-size: 11px; letter-spacing: .12em;
  font-family: var(--mono); }
.xb-tile .lock {
  position: absolute; right: 7px; top: 6px;
  width: 11px; height: 11px; opacity: .8; color: var(--ex-lab);
}
.xb-tile:not(.locked) .lock { display: none; }
.xb-tile.deny { animation: xb-deny .3s var(--ex-point) both; }
@keyframes xb-deny {
  0%, 100% { transform: none; }
  25% { transform: translateX(-4px); }
  75% { transform: translateX(4px); }
}

/* the thing that follows the pointer during a drag */
.xb-ghost {
  position: fixed; z-index: 800; pointer-events: none;
  width: 92px; height: 92px;
  display: grid; place-items: center;
  color: var(--t-ink, var(--ex-hot));
  filter: drop-shadow(0 10px 22px rgba(0, 0, 0, .95));
  transform-origin: 50% 50%;
}
.xb-ghost svg { width: 84px; height: 91px; }
.xb-ghost::after {
  content: ""; position: absolute; inset: -6px;
  border: 1px solid currentColor; opacity: .5;
}

/* ── the quiet lists on the rail ─────────────────────────────────────────── */
.xb-list { list-style: none; margin: 0; padding: 0; }
.xb-list li {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 13px; border-bottom: 1px solid rgba(30, 111, 224, .16);
  font-family: var(--mono); font-size: var(--t-fine);
}
.xb-list li:last-child { border-bottom: 0; }
.xb-list .l { color: var(--blue); letter-spacing: .06em; min-width: 0; }
.xb-list .l small {
  display: block; font-size: 9.5px; letter-spacing: .1em; color: var(--ex-lab);
  margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.xb-list .r {
  margin-left: auto; font-family: var(--wide); font-size: 12.5px;
  font-variant-numeric: tabular-nums; letter-spacing: .02em;
}
.xb-list .r.plus { color: var(--green); }
.xb-list .r.minus { color: var(--ex-lab); }
.xb-list .mini { flex: 0 0 auto; color: var(--t-ink, var(--ex-lab)); }
.xb-list .mini svg { width: 28px; height: 30px; display: block; }

/* the bounty row — the page's only amber */
.xb-bty li .l { color: var(--amber); }
.xb-bty li .r { color: var(--amber); }
.xb-bty .over {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .12em;
  color: var(--amber); border: 1px solid rgba(255, 180, 84, .45); padding: 0 4px;
}

/* ── the designed empty state ────────────────────────────────────────────── */
.xb-empty {
  padding: 20px 16px 22px; text-align: center;
  font-family: var(--read); font-size: var(--t-fine); line-height: 1.75;
  color: var(--ex-lab);
}
.xb-empty h3 {
  margin: 12px 0 8px; font-family: var(--wide); font-size: var(--t-fine);
  letter-spacing: .2em; color: var(--blue); font-weight: 400;
}
.xb-empty p { margin: 0 auto 8px; max-width: 56ch; }
.xb-empty .mark { display: block; color: rgba(30, 111, 224, .55); }
.xb-empty .mark svg { width: 64px; height: 69px; margin: 0 auto; display: block; }
.xb-act {
  display: inline-block; margin-top: 12px;
  font-family: var(--mono); font-size: 11px; letter-spacing: .16em;
  color: var(--ex-hot); background: transparent; text-decoration: none;
  border: 1px solid var(--ex-edge); padding: 7px 14px; cursor: pointer;
  transition: background .16s, border-color .16s;
}
.xb-act:hover { background: rgba(30, 111, 224, .2); border-color: var(--ex-hot); }
.xb-act:focus-visible { outline: 1px solid var(--ex-hot); outline-offset: 2px; }

/* ============================================================== responsive */
@media (max-width: 1080px) {
  .xb-floor { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 720px) {
  .xb-rig { grid-template-columns: minmax(0, 1fr); }
  .xb-lever {
    grid-column: 1; grid-row: auto;
    width: auto; border-left: 0; border-top: 1px solid var(--ex-line);
    grid-template-rows: auto auto auto;
  }
  /* ON A PHONE THE LEVER IS A BAR YOU PRESS, NOT A SHAFT YOU PULL. A vertical
     drag inside a scrolling column fights the scroll, and losing that fight
     means the page moves instead of the lever. Same control, same words, same
     handler — the drag simply has nowhere to travel, so it falls through to
     the press. */
  .xb-track { width: 100%; margin: 10px 0; min-height: 56px; }
  .xb-track::before, .xb-track::after { display: none; }
  .xb-pull { left: 0; right: 0; top: 0; height: 56px; }
  .xb-pull::before { left: 14px; }
  .xb-pull::after { right: 14px; }
  .xb-pull .chev { transform: rotate(-90deg); width: 24px; height: 24px; }
  .xb-pull.armed .chev { animation: none; }
  .xb-socket, .xb-mount { width: 88px; min-height: 104px; }
  .xb-mount .art svg { width: 58px; height: 63px; }
  .xb-tiles { grid-template-columns: minmax(0, 1fr); }
  .xb-rails { gap: 9px 18px; }
  .xb-fig .v { font-size: 18px; }
}

/* ============================================================ reduced motion
   RULE 6: the motion goes, the information stays. Every state this page can be
   in is readable from text and colour with every animation removed — the boot
   curtain never even mounts, skulls appear in their sockets instead of arcing,
   and the extraction still prints its receipt. */
@media (prefers-reduced-motion: reduce) {
  .xb-mount, .xb-note, .xb-tile.deny, .xb-bed.firing .xb-sweep,
  .xb-mount.fire, .xb-fig .v.moved, .xb-bed.hot .xb-socket.ghost,
  .xb-state.busy .xb-dot {
    animation: none !important;
  }
  .xb-tile, .xb-pull, .xb-mount::before, .xb-mount::after, .xb-bed {
    transition: none !important;
  }
  .xb-tile:hover { transform: none; }
  .xb-mount.fire { opacity: 0; }
}
