/* =============================================================================
   live-instruments.css — THE IN-GLASS INSTRUMENT GRAMMAR
   terminal-theme, owner-neutral, 2026-08-10

   WHAT THIS IS FOR
   ----------------
   A page whose centre of gravity is a 3D specimen has one hard design problem:
   the readings have to be ON the animal's glass without becoming a card that
   floats over a render. The owner's words on the Sequence live page, which is
   why this file exists:

     "add them here somewhere with the actual ui design. i dont want it feeling
      like a text on top. i want it feeling like the text is within the 3d
      preview."

   So nothing in here is a panel. There is no rounded translucent box, no drop
   shadow, no blurred plate. Every reading is drawn the way an instrument is
   etched into its own bezel:

     · a GRATICULE - one hairline down the inner edge of each rail, with a tick
       at every row, so the readings are ruled onto the frame's own geometry
     · a BEZEL RAMP painted on the stage itself (`.stage.instr`), darkest at the
       frame and gone by ~22% in. It is the instrument's shading, anchored to
       the frame - not a scrim, and never a rectangle behind the type
     · the per-glyph INK STROKE the theme already owns (`--sh-micro/-body`),
       which is what lets a value sit on a lit render with nothing behind it
     · values riding the BASELINE of their label, at the rail's inner edge

   PERCENT LEADS (owner ruling): the headline of a gauge is always the percent.
   The raw current/max pair is subordinate - it appears on hover / focus-within
   and lives in the row's `title` at all times, so it is never lost.

   COLOUR LAW, KEPT
   ----------------
   `--green` stays RESERVED for ONLINE-class state. A healthy gauge is BLUE.
   Caution is amber, danger is red, an unknown reading has NO fill at all - it
   shows the bare graticule and a dash, because a health of unknown drawn as a
   0% bar reads "about to die".

   NAMING
   ------
   Every class here is prefixed `ins-` (instrument) except the two modifiers it
   adds to classes the theme already ships (`.stage.instr`, `.stage .sclip`).
   Nothing here restates a token `terminal.css` already defines.
   ========================================================================= */

/* =========================================================================
   1. THE STAGE, WEARING ITS INSTRUMENT
   ------------------------------------------------------------------------
   `.instr` is opt-in: a stage that only wants a specimen keeps the plain
   `.stage` it always had. The wrap exists so the rails can LEAVE the glass on
   a narrow screen without leaving the instrument - see §6.
   ========================================================================= */
.ins-wrap{position:relative;display:grid;grid-template-columns:minmax(0,1fr);min-width:0}

/* the bezel ramp: three edges, no box. `pointer-events:none` so the reader can
   still drag the specimen through it. */
.stage.instr::after{content:"";position:absolute;inset:0;z-index:2;pointer-events:none;
  background:
    linear-gradient(90deg,rgba(1,5,13,.88) 0,rgba(1,5,13,.55) 9%,rgba(1,5,13,0) 24%),
    linear-gradient(270deg,rgba(1,5,13,.88) 0,rgba(1,5,13,.55) 9%,rgba(1,5,13,0) 24%),
    linear-gradient(0deg,rgba(1,5,13,.86) 0,rgba(1,5,13,.42) 8%,rgba(1,5,13,0) 22%)}

/* the two rails and the bottom strip sit OVER the ramp, under the busy veil */
.ins-l,.ins-r{position:absolute;z-index:3;top:38px;bottom:52px;width:136px;
  display:grid;gap:11px;align-content:start;pointer-events:none}
.ins-l{left:14px;padding-right:11px;
  border-right:1px solid rgba(75,180,252,.30)}
/* THE DERIVED READINGS SIT LOW, ON PURPOSE. The top-right corner belongs to
   the clip chip, and two gauges hanging under it read as an afterthought; sunk
   to the floor they close the bracket the left rail opens.
   ★ 2026-08-10, owner ruling: on Sequence's live page fracture and bleeding
   moved to the LEFT rail with the vitals, so this rail renders empty there.
   A rail is its readings — with nothing in it the border below is a hairline
   ruled down the glass for no reason, which reads as a drawing bug. So an
   empty rail is not a thin rail, it is NO rail. Kept generic rather than
   deleted: a surface that does use the right rail still gets it. */
.ins-r{right:14px;padding-left:11px;align-content:end;
  border-left:1px solid rgba(75,180,252,.30)}
.ins-l:empty,.ins-r:empty{display:none}

/* the graticule tick — one per row, on the rail's ruled edge */
.ins-g{position:relative;display:grid;gap:3px;min-width:0}
.ins-g::before{content:"";position:absolute;top:5px;width:5px;height:1px;
  background:rgba(75,180,252,.65)}
.ins-l .ins-g::before{right:-11px}
.ins-r .ins-g::before{left:-11px}

/* label row: name left, value on the same baseline at the ruled edge */
.ins-hd{display:flex;align-items:baseline;gap:6px;min-width:0;
  font-family:var(--mono);font-size:9.5px;letter-spacing:.19em;
  color:var(--blue-dim);text-shadow:var(--sh-micro);white-space:nowrap}
.ins-k{overflow:hidden;text-overflow:ellipsis;min-width:0}
.ins-v{margin-left:auto;font-size:12.5px;letter-spacing:.04em;color:#79D9FF;
  text-shadow:var(--sh-body);font-variant-numeric:tabular-nums}
.ins-g.warn .ins-v{color:var(--amber)}
.ins-g.crit .ins-v{color:#FF8B8B}
.ins-g.off .ins-v{color:var(--blue-dim)}

/* the track IS a scale: a hairline baseline plus a repeating graticule, so an
   empty gauge still reads as an instrument rather than a missing thing */
.ins-t{position:relative;height:4px;
  background:
    repeating-linear-gradient(90deg,rgba(75,180,252,.34) 0 1px,transparent 1px 9px),
    linear-gradient(0deg,rgba(75,180,252,.30) 0 1px,transparent 1px);
  background-position:0 100%,0 100%;background-repeat:repeat-x}
.ins-t i{position:absolute;left:0;bottom:0;top:1px;width:0;background:var(--blue-hot);
  box-shadow:0 0 10px -1px rgba(75,180,252,.85);
  transition:width .55s cubic-bezier(.16,.84,.28,1)}
.ins-g.warn .ins-t i{background:var(--amber);box-shadow:0 0 10px -1px rgba(255,180,84,.7)}
.ins-g.crit .ins-t i{background:var(--red);box-shadow:0 0 10px -1px rgba(255,90,90,.7)}
/* UNKNOWN IS NOT ZERO. No fill, and the baseline goes dotted so the row reads
   "this island does not report it" rather than "this is empty". */
.ins-g.off .ins-t{background:
  repeating-linear-gradient(90deg,rgba(44,132,238,.42) 0 1px,transparent 1px 5px);
  background-position:0 100%;background-repeat:repeat-x}
.ins-g.off .ins-t i{display:none}

/* the subordinate pair — present in `title` always, drawn on hover/focus */
.ins-x{position:absolute;right:0;top:-1px;font-family:var(--mono);font-size:9px;
  letter-spacing:.1em;color:var(--blue-dim);text-shadow:var(--sh-micro);
  opacity:0;transform:translateY(-2px);pointer-events:none;white-space:nowrap;
  transition:opacity .14s linear,transform .14s cubic-bezier(.2,.8,.2,1)}
.ins-l .ins-g:hover .ins-x,.ins-l .ins-g:focus-within .ins-x,
.ins-r .ins-g:hover .ins-x,.ins-r .ins-g:focus-within .ins-x,
.ins-below .ins-g:hover .ins-x,.ins-below .ins-g:focus-within .ins-x{opacity:1;transform:none}
.ins-l,.ins-r,.ins-below{pointer-events:none}
.ins-g{pointer-events:auto}

/* =========================================================================
   2. THE DIET STRIP — one scale across the floor of the glass
   ========================================================================= */
.ins-diet{position:absolute;z-index:3;left:14px;right:14px;bottom:30px;
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(10px,2vw,26px);
  padding-top:7px;border-top:1px solid rgba(75,180,252,.30);pointer-events:none}
.ins-diet .ins-g{pointer-events:auto}
.ins-diet .ins-g::before{content:"";top:-7px;left:0;right:auto;width:1px;height:5px}
.ins-diet .ins-hd{font-size:9px;letter-spacing:.16em}
.ins-diet .ins-v{font-size:11.5px}

/* =========================================================================
   3. THE CLIP CHIP AS A CONTROL
   ------------------------------------------------------------------------
   The chip was a label. It is now a button, and it has to look like one
   without becoming a second grammar: same size, same tracking, plus a hairline
   box and a drawn caret.
   ========================================================================= */
.stage .sclip.ins-pick{display:inline-flex;align-items:center;gap:7px;cursor:pointer;
  background:transparent;border:1px solid rgba(75,180,252,.45);padding:4px 8px;
  font-family:var(--pixel);font-size:10.5px;letter-spacing:.16em;color:#79D9FF;
  box-shadow:0 0 0 1px rgba(1,5,11,.85);
  transition:border-color .14s linear,color .14s linear,background .14s linear}
.stage .sclip.ins-pick:hover:not(:disabled){border-color:#79D9FF;background:rgba(30,111,224,.16)}
.stage .sclip.ins-pick:disabled{opacity:.5;cursor:not-allowed}
.stage .sclip.ins-pick svg{width:9px;height:9px;flex:none;
  transition:transform .16s cubic-bezier(.2,.8,.2,1)}
.stage .sclip.ins-pick[aria-expanded="true"] svg{transform:rotate(180deg)}
.stage .sclip.ins-pick[aria-expanded="true"]{border-color:#79D9FF}

.ins-menu{position:absolute;z-index:9;right:14px;top:44px;width:min(252px,calc(100% - 28px));
  border:1px solid var(--rule);background:rgba(1,5,13,.97);
  box-shadow:0 0 0 1px rgba(1,5,11,.9),0 24px 60px -28px #000;
  padding:7px;max-height:min(310px,72%);overflow:auto;scrollbar-width:thin}
.ins-menu[hidden]{display:none}
.ins-menu .ins-mh{padding:3px 6px 7px;margin-bottom:5px;
  border-bottom:1px solid rgba(30,111,224,.5);
  font-family:var(--mono);font-size:9.5px;letter-spacing:.2em;color:var(--blue-dim);
  text-shadow:var(--sh-micro)}
.ins-mi{display:flex;align-items:center;gap:9px;width:100%;text-align:left;cursor:pointer;
  font-family:var(--mono);font-size:11.5px;letter-spacing:.07em;color:#4BB4FC;
  text-shadow:var(--sh-micro);background:transparent;border:1px solid transparent;
  padding:7px 8px;transition:background .12s linear,border-color .12s linear,color .12s linear}
.ins-mi:hover{background:rgba(30,111,224,.16);border-color:rgba(75,180,252,.45);color:#A8E7FF}
.ins-mi[aria-current="true"]{color:#79D9FF;border-color:rgba(75,180,252,.5)}
.ins-mi .ins-sec{margin-left:auto;font-size:9px;letter-spacing:.14em;color:var(--blue-dim);
  font-variant-numeric:tabular-nums}
.ins-mi .ins-dot{width:5px;height:5px;flex:none;background:rgba(75,180,252,.4)}
.ins-mi[aria-current="true"] .ins-dot{background:var(--blue-hot);
  box-shadow:0 0 7px rgba(75,180,252,.9)}
/* prose, so it drops the display tracking - .1em on sentence case reads as a
   different voice rather than as the same one speaking quietly */
.ins-mnote{padding:8px 6px 3px;margin-top:5px;border-top:1px solid rgba(30,111,224,.4);
  font-family:var(--read);font-size:11px;line-height:1.65;letter-spacing:.01em;
  color:#6BC6FF;text-shadow:var(--sh-micro)}
.ins-mnote b{font-weight:400;color:var(--amber)}

/* =========================================================================
   4. THE IDENTITY BAR + THE GROWTH LADDER
   ------------------------------------------------------------------------
   His ruling is a LADDER with three edges (25 / 50 / 75), so the band draws
   those edges. A number beside a name is a fact; a number on a scale that
   shows the edges is an instrument, and it is the same pixels.
   ========================================================================= */
.ins-id{display:flex;align-items:flex-end;gap:clamp(10px,1.6vw,20px);flex-wrap:wrap;
  min-width:0}
.ins-name{min-width:0;display:grid;gap:4px}
/* SHOUT IN CSS, NOT IN JS (terminal-theme rule 15): the screen reads
   TYRANNOSAURUS and the DOM still carries `Tyrannosaurus`, so a copy-paste, a
   search and a screen reader all get the animal's real name. */
.ins-sp{font-family:var(--pixel);font-size:clamp(18px,1.9vw,27px);letter-spacing:.05em;
  line-height:1.05;color:#79D9FF;text-shadow:var(--sh-lead);text-transform:uppercase;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ins-nick{font-family:var(--mono);font-size:12.5px;letter-spacing:.1em;color:var(--blue);
  text-shadow:var(--sh-micro);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ins-nick em{font-style:normal;color:var(--blue-dim)}
.ins-grow{margin-left:auto;text-align:right;flex:none}
.ins-gnum{display:block;font-family:var(--pixel);font-size:clamp(26px,3.1vw,42px);
  line-height:.92;letter-spacing:.02em;color:#79D9FF;text-shadow:var(--sh-lead);
  font-variant-numeric:tabular-nums}
.ins-gnum u{text-decoration:none;font-size:.46em;color:var(--blue-dim);margin-left:2px}
.ins-gst{display:block;margin-top:5px;font-family:var(--pixel);font-size:11px;
  letter-spacing:.22em;color:#4BB4FC;text-shadow:var(--sh-body);white-space:nowrap}
.ins-gst.is-prime{color:var(--amber)}

.ins-band{position:relative;margin-top:13px;height:5px;
  background:linear-gradient(0deg,rgba(75,180,252,.32) 0 1px,transparent 1px);
  background-position:0 100%;background-repeat:repeat-x}
.ins-band i{position:absolute;left:0;bottom:0;top:1px;background:var(--blue-hot);width:0;
  box-shadow:0 0 12px -2px rgba(75,180,252,.9);
  transition:width .6s cubic-bezier(.16,.84,.28,1)}
.ins-band i.is-prime{background:var(--amber);box-shadow:0 0 12px -2px rgba(255,180,84,.75)}
.ins-band s{position:absolute;bottom:0;width:1px;height:9px;background:rgba(75,180,252,.55);
  text-decoration:none}
.ins-rungs{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));margin-top:6px;
  font-family:var(--mono);font-size:9px;letter-spacing:.18em;color:var(--blue-dim);
  text-shadow:var(--sh-micro)}
.ins-rungs span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ins-rungs span.on{color:#79D9FF}

/* the state tags */
.ins-tags{display:flex;align-items:center;gap:6px;flex-wrap:wrap;min-width:0}
.ins-tag{font-family:var(--mono);font-size:10px;letter-spacing:.18em;color:var(--blue-dim);
  border:1px solid rgba(30,111,224,.6);padding:2px 7px;white-space:nowrap;
  text-shadow:var(--sh-micro)}
.ins-tag.hot{color:var(--amber);border-color:rgba(255,180,84,.55)}
.ins-tag.warn{color:#FF8B8B;border-color:rgba(255,90,90,.5)}

/* =========================================================================
   5. THE STATUS CHIP STRIP — honesty, compressed
   ------------------------------------------------------------------------
   A preview flag, an island state and a feed age used to be three sentences.
   They are facts about the reading, so they belong beside the reading as
   chips. The amber one is still unmissable: it is the only amber on the page
   until something goes wrong.
   ========================================================================= */
.ins-chips{display:flex;align-items:center;gap:8px;flex-wrap:wrap;min-width:0}
.ins-chip{display:inline-flex;align-items:center;gap:7px;
  font-family:var(--mono);font-size:10px;letter-spacing:.17em;white-space:nowrap;
  padding:4px 9px;border:1px solid rgba(30,111,224,.55);color:var(--blue-dim);
  text-shadow:var(--sh-micro);box-shadow:0 0 0 1px rgba(1,5,11,.85)}
.ins-chip b{font-weight:400;color:#79D9FF;letter-spacing:.09em}
.ins-chip i{width:6px;height:6px;flex:none;background:currentColor;font-style:normal}
.ins-chip.on{color:var(--green);border-color:rgba(91,255,166,.5)}
.ins-chip.on b{color:var(--green)}
.ins-chip.hot{color:var(--amber);border-color:rgba(255,180,84,.6);
  background:rgba(255,180,84,.07)}
.ins-chip.hot b{color:var(--amber)}
.ins-chip.bad{color:#FF8B8B;border-color:rgba(255,90,90,.55)}
.ins-chip.bad b{color:#FF8B8B}

/* =========================================================================
   6. NARROW — the rails leave the GLASS, never the INSTRUMENT
   ------------------------------------------------------------------------
   Below 560 the frame is ~400px wide and a 136px rail on each side leaves the
   animal a slot. So the gauges step out of the glass and sit directly against
   the stage's own bottom edge, sharing its border, with the same graticule.
   It is one continuous instrument that changed shape - not a card that
   appeared.
   ========================================================================= */
.ins-below{display:none}
@media(max-width:560px){
  .ins-l,.ins-r,.ins-diet{display:none}
  .stage.instr::after{background:
    linear-gradient(0deg,rgba(1,5,13,.8) 0,rgba(1,5,13,0) 18%)}
  .ins-below{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
    gap:11px clamp(12px,4vw,26px);
    border:1px solid var(--rule);border-top:0;padding:12px 13px 13px;
    background:rgba(1,4,10,.62)}
  .ins-below .ins-g::before{top:5px;left:-13px;right:auto;width:5px;height:1px}
  .ins-below .ins-sub{grid-column:1/-1;display:grid;
    grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;
    padding-top:11px;border-top:1px solid rgba(30,111,224,.45)}
}
@media(max-width:760px) and (min-width:561px){
  .ins-l,.ins-r{width:112px;top:34px;bottom:46px}
  .ins-l{padding-right:9px}.ins-r{padding-left:9px}
  .ins-l .ins-g::before{right:-9px}.ins-r .ins-g::before{left:-9px}
  .ins-v{font-size:11.5px}
}
/* ★ THE TIGHT BAND. A rail is an ABSOLUTE band (top/bottom offsets) inside a
   stage whose height follows its width, so the room for rows is not constant
   across the page's breakpoints - and the number of rows is not constant
   either. Moving fracture and bleeding onto the left rail on 2026-08-10 took it
   from five rows to seven, and at the width where the two columns stack the
   last row ran 9px past the band: measured, not guessed, and invisible at every
   other width tested. A vital half off the bottom of the glass is exactly the
   kind of defect that ships because nobody resized to the one width that shows
   it. Tightened here rather than everywhere, so the wide layout keeps the
   spacing it was designed with.
   ★ WHEN ADDING A ROW TO EITHER RAIL, RE-MEASURE THE BAND AT EVERY BREAKPOINT.
   The overflow is silent: nothing throws, nothing scrolls, the row is just
   drawn where the glass has already ended. */
@media(max-width:1200px) and (min-width:761px){
  .ins-l,.ins-r{top:32px;bottom:44px;gap:8px}
}

/* =========================================================================
   7. THE PRIME BOARD
   ------------------------------------------------------------------------
   A score against its ceiling AND the named conditions, because "3 of 5" does
   not tell a player which two they still owe. PENDING is a real state and is
   drawn as a clock and a dash - never as ten failures.
   ========================================================================= */
.ins-prime{display:grid;gap:11px;min-width:0}
.ins-phd{display:flex;align-items:baseline;gap:12px;min-width:0}
.ins-phd .ins-pk{font-family:var(--mono);font-size:10px;letter-spacing:.2em;
  color:var(--blue-dim);text-shadow:var(--sh-micro)}
.ins-score{margin-left:auto;font-family:var(--pixel);font-size:20px;letter-spacing:.05em;
  color:#79D9FF;text-shadow:var(--sh-body);white-space:nowrap;
  font-variant-numeric:tabular-nums}
.ins-score u{text-decoration:none;font-size:.58em;color:var(--blue-dim);margin-left:5px}
.ins-score.pend{color:var(--amber)}
.ins-seg{display:flex;gap:4px}
.ins-seg i{flex:1;height:7px;background:rgba(12,42,80,.9);
  box-shadow:inset 0 0 0 1px rgba(30,111,224,.6)}
.ins-seg i.f{background:var(--blue-hot);box-shadow:0 0 10px -2px rgba(75,180,252,.9)}
.ins-seg i.p{background:repeating-linear-gradient(135deg,
  rgba(255,180,84,.5) 0 3px,transparent 3px 6px)}
.ins-rows{display:grid;gap:0;min-width:0}
.ins-row{display:flex;align-items:center;gap:10px;min-width:0;padding:6px 0;
  border-bottom:1px solid rgba(30,111,224,.28);
  font-family:var(--mono);font-size:11.5px;letter-spacing:.05em;color:#4BB4FC;
  text-shadow:var(--sh-micro)}
.ins-row:last-child{border-bottom:0}
.ins-row .ins-rk{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ins-st{margin-left:auto;display:inline-flex;align-items:center;gap:6px;flex:none;
  font-size:10px;letter-spacing:.14em;white-space:nowrap;color:var(--blue-dim);
  font-variant-numeric:tabular-nums}
.ins-st svg{width:13px;height:13px;flex:none}
.ins-st.met{color:#79D9FF}
.ins-row.met .ins-rk{color:#79D9FF}
.ins-st.unmet{color:var(--blue-dim)}
.ins-st.na{color:var(--blue-dim);opacity:.72}
.ins-st.pend{color:var(--amber)}
.ins-pnote{margin:0;font-family:var(--read);font-size:11.5px;line-height:1.65;
  color:var(--amber);text-shadow:var(--sh-micro);max-width:60ch}

/* the two figure cells whose NUMBER is the information */
.ins-figs{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
.ins-fig{border:1px solid rgba(30,111,224,.55);padding:10px 12px;min-width:0}
.ins-fig u{text-decoration:none;display:block;font-family:var(--mono);font-size:9.5px;
  letter-spacing:.2em;color:var(--blue-dim);text-shadow:var(--sh-micro)}
.ins-fig b{display:block;margin-top:4px;font-family:var(--pixel);font-size:19px;
  font-weight:400;letter-spacing:.04em;color:#79D9FF;text-shadow:var(--sh-body);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-variant-numeric:tabular-nums}
.ins-fig b s{text-decoration:none;font-size:.58em;color:var(--blue-dim);margin-left:4px}
/* the subordinate scale: the figure leads, the percent rides under it */
.ins-fig .ins-ft{position:relative;display:block;height:3px;margin-top:9px;
  background:linear-gradient(0deg,rgba(75,180,252,.3) 0 1px,transparent 1px);
  background-position:0 100%;background-repeat:repeat-x}
.ins-fig .ins-ft i{position:absolute;left:0;bottom:0;top:0;background:var(--blue-hot);
  box-shadow:0 0 9px -2px rgba(75,180,252,.85);
  transition:width .55s cubic-bezier(.16,.84,.28,1)}
.ins-fig .ins-fp{display:block;margin-top:5px;font-family:var(--mono);font-size:9.5px;
  letter-spacing:.16em;color:var(--blue-dim);text-shadow:var(--sh-micro);
  font-variant-numeric:tabular-nums}

/* =========================================================================
   8. THE VAULT
   ------------------------------------------------------------------------
   NOT a card inside a card: the vault section is a heading and a rule, and the
   slot is the only bordered object in it.
   ========================================================================= */
.ins-vhd{display:flex;align-items:center;gap:14px;flex-wrap:wrap;min-width:0;
  margin-bottom:14px}
.ins-vhd .ins-vt{margin:0;font-family:var(--wide);font-size:16px;font-weight:560;
  letter-spacing:.06em;color:var(--blue);text-shadow:var(--sh-body)}
.ins-vhd .ins-vc{font-family:var(--mono);font-size:11px;letter-spacing:.15em;
  color:var(--blue-dim);text-shadow:var(--sh-micro);white-space:nowrap}
.ins-vhd .ins-vc b{font-weight:400;color:#79D9FF}
.ins-vhd .ins-vsp{margin-left:auto}

/* ★ THE SECTIONS LINE UP ACROSS CARDS, NOT JUST INSIDE ONE.
   The mutation block is a different size on every animal - three families on
   an entombed Tyrannosaurus, none at all on a fresh Dryosaurus - so with
   independent cards every one bottomed out somewhere different and a row of
   five read as misaligned rather than as a rhythm.
   `subgrid` is the fix and it is the only one that is not a lie: the five
   sections (head / well / mutations / readings / actions) become rows of the
   SHELF's grid, so mutations start at one y across the whole row, readings
   start at one y, and the actions sit on one line. The empty-state row
   ("NO MUTATIONS ON THIS ANIMAL") holds the same slot as a filled one because
   it IS the same row.
   Guarded by @supports because a DROPPED DECLARATION IS SILENT: without the
   guard, a browser that ignores `grid-template-rows:subgrid` would still take
   `grid-row:span 5` and lay every card across five auto rows it does not
   control. Unsupported browsers keep exactly the independent-height cards
   they have today. */
/* ★ HIS RULING 2026-08-10: "for the vault have species stack on top of each
   other, however if they click preview card style pops up".
   So the shelf is a STACKED LIST of one-line rows, and the detail is a card
   that opens on demand. This replaced a grid of tall cards, and it fixed three
   things at once that the grid could only ever paper over:
     * the ragged bottoms are gone because a row has ONE height, not a height
       that depends on how many mutations the animal happens to carry - the
       subgrid machinery this rule replaced existed only to fight that;
     * the resting preview well is gone from the shelf entirely, so the page no
       longer shows four large empty rectangles waiting to be asked;
     * a full vault is READABLE at a glance - five rows of one line each,
       scanned top to bottom, instead of five columns scanned in two directions.
   A list also scales: the twentieth parked animal costs one more line. */
.ins-slots{display:grid;grid-template-columns:minmax(0,1fr);gap:7px}

/* THE ROW. Identity, then what it is, then the levers - one line at any width
   that can hold it, wrapping to two rather than truncating a name. */
.ins-slot{position:relative;border:1px solid var(--rule);min-width:0;
  display:flex;align-items:center;gap:10px 14px;flex-wrap:wrap;
  padding:9px 12px 9px 13px;
  background:rgba(1,4,10,.62);backdrop-filter:blur(8px);
  box-shadow:inset 3px 0 0 rgba(75,180,252,.5);
  transition:border-color .18s linear,box-shadow .18s linear,background .18s linear}
.ins-slot:hover{border-color:var(--rule-hot);background:rgba(3,10,22,.72)}
.ins-slot.ent{box-shadow:inset 3px 0 0 var(--amber)}

.ins-stop{display:flex;align-items:baseline;gap:9px;min-width:0;flex:1 1 210px}
.ins-sn{font-family:var(--mono);font-size:13px;letter-spacing:.09em;color:#79D9FF;
  text-shadow:var(--sh-body);min-width:0;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap}
.ins-sn em{font-style:normal;color:var(--blue-dim)}
.ins-ssp{flex:none;font-family:var(--pixel);font-size:10.5px;
  letter-spacing:.14em;color:var(--blue-dim);text-shadow:var(--sh-micro);
  max-width:52%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ins-smeta{display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  font-family:var(--mono);font-size:10px;letter-spacing:.16em;color:var(--blue-dim);
  text-shadow:var(--sh-micro)}
.ins-smeta b{font-weight:400;color:#4BB4FC;font-variant-numeric:tabular-nums}

/* THE WHOLE ROW OPENS THE CARD, and the explicit control is still there for a
   keyboard and for anyone who does not guess that a row is pressable. The
   levers keep their own click - `slotAction` stops the bubble - so pressing
   REDEEM does not also open the card behind the confirm. */
.ins-slot[data-open]{cursor:pointer}
.ins-sopen{flex:none;display:inline-flex;align-items:center;gap:7px;cursor:pointer;
  font-family:var(--pixel);font-size:10.5px;letter-spacing:.14em;padding:7px 11px;
  color:#79D9FF;text-shadow:var(--sh-body);background:transparent;
  border:1px solid rgba(75,180,252,.5)}
.ins-sopen svg{width:13px;height:13px;flex:none}
.ins-slot:hover .ins-sopen{border-color:#79D9FF;color:#A8E7FF;
  background:rgba(30,111,224,.14)}

/* =========================================================================
   THE CARD — the detail, on demand
   ------------------------------------------------------------------------
   ONE card at a time, which is also what bounds the specimens: the old shelf
   could hold several live mounts and needed an LRU that once hid a control it
   had taken away. A single card cannot have that bug.
   ========================================================================= */
/* ★ THE LAYER ORDER IS THE WHOLE TRICK, AND IT IS NOT OPTIONAL.
   `shopview` paints every specimen on ONE shared canvas pinned at
   `position:fixed;inset:0;z-index:5`, scissored per mount. So ANY opaque paint
   above z-index 5 over the well hides the animal - the first build put the
   dimming backdrop on the overlay itself and produced a card with a live mount
   and an empty stage, with every probe reporting success.
   Hence: the scrim is its own element UNDER the canvas (4), the card sits above
   it (80), and the card is TRANSPARENT - its sections carry the panel paint
   individually so the well stays a genuine hole for the canvas to show through.
   ★ Never give `.ins-sheet` a background again. */
/* It has to do the work a stage background would have done, because the well
   above it is a genuine hole - at .86 the page's own neon read straight through
   the specimen. Blur belongs here and only here: it is UNDER the canvas, so it
   softens the page and never touches the animal. */
.ins-scrim{position:fixed;inset:0;z-index:4;background:rgba(0,3,9,.945);
  backdrop-filter:blur(7px)}
/* ★ AND THE PAGE'S OWN SPECIMEN HAS TO STAND DOWN WHILE THE CARD IS UP.
   The scrim dims the DOCUMENT, but the live stage's animal is painted on the
   same shared canvas at z-index 5 - ABOVE the scrim - so it went on walking
   over the dimmed page beside the card, two animals on screen and only one of
   them asked for. `display:none` is what does it: the engine draws only mounts
   with a real on-screen rectangle, so a hidden host is skipped rather than torn
   down, and it comes straight back when the card closes. */
body.sheet-on .stage .shopview{display:none}
.ins-scrim[hidden]{display:none}
.ins-sheetwrap{position:fixed;inset:0;z-index:80;display:grid;place-items:center;
  padding:clamp(10px,3vw,34px);overflow:auto;pointer-events:auto}
.ins-sheetwrap[hidden]{display:none}
.ins-sheet{position:relative;width:min(760px,100%);max-height:100%;overflow:auto;
  border:1px solid var(--rule-hot);background:none;
  box-shadow:0 26px 70px -28px rgba(0,0,0,.9),inset 3px 0 0 rgba(75,180,252,.5);
  animation:ins-sheet-in .26s cubic-bezier(.16,.84,.28,1) both}
.ins-sheet.ent{box-shadow:0 26px 70px -28px rgba(0,0,0,.9),inset 3px 0 0 var(--amber)}
@keyframes ins-sheet-in{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
@media(prefers-reduced-motion:reduce){.ins-sheet{animation:none}}
/* every section paints itself; the well between them does not */
.ins-sheet .ins-shhd,.ins-sheet .ins-smut,
.ins-sheet .ins-sstat,.ins-sheet .ins-sacts{background:rgba(1,5,12,.97)}
/* the well is the hole: no ground, no floor grid, because both would be drawn
   OVER the canvas rather than under it. The scrim is the ground. */
.ins-sheet .ins-well{background:none}
.ins-sheet .ins-well::before{content:none}
.ins-shhd{display:grid;gap:7px;padding:14px 15px 12px;
  border-bottom:1px solid rgba(30,111,224,.42)}
.ins-shx{position:absolute;top:9px;right:10px;z-index:5;cursor:pointer;
  font-family:var(--pixel);font-size:10.5px;letter-spacing:.14em;padding:6px 10px;
  color:var(--blue-dim);text-shadow:var(--sh-micro);background:rgba(1,5,12,.9);
  border:1px solid rgba(30,111,224,.5)}
.ins-shx:hover{border-color:#79D9FF;color:#A8E7FF}

/* the slot's own well — an aspect box that stays put whether or not a
   specimen has been asked for, so opening a preview never reflows the grid.
   The floor grid is drawn in CSS, so an UNASKED well is a lit stage waiting
   for an animal rather than a black hole in the card. */
.ins-well::before{content:"";position:absolute;left:-25%;right:-25%;bottom:-6%;height:44%;
  background:
    repeating-linear-gradient(90deg,rgba(75,180,252,.2) 0 1px,transparent 1px 38px),
    repeating-linear-gradient(0deg,rgba(75,180,252,.17) 0 1px,transparent 1px 26px);
  transform:perspective(300px) rotateX(66deg);transform-origin:50% 100%;
  -webkit-mask-image:linear-gradient(180deg,transparent,#000 42%,#000 78%,transparent);
          mask-image:linear-gradient(180deg,transparent,#000 42%,#000 78%,transparent);
  pointer-events:none}
/* ★ A RESTING WELL IS A NORMAL STATE, NOT AN EDGE CASE - the concurrency bound
   guarantees at least two of five are resting at any moment - so it must not
   look like a hole. Resting it is a SHORT strip carrying its floor grid and a
   full-width control that says what pressing it will do; a mounted specimen
   opens it to the full 16/10. Under subgrid the whole row opens together, so
   the shelf stays aligned. */
.ins-well{position:relative;overflow:hidden;
  height:clamp(112px,9vw,148px);
  border-top:1px solid rgba(30,111,224,.5);border-bottom:1px solid rgba(30,111,224,.5);
  background:
    radial-gradient(120% 80% at 50% 108%,rgba(20,90,180,.24),transparent 62%),
    linear-gradient(180deg,rgba(1,6,16,.9),rgba(1,4,10,.97))}
.ins-well.on{height:clamp(172px,14.6vw,232px)}
/* ★ AND IT HAS TO FILL ITS SHARED ROW. Under subgrid the wells of one shelf
   all sit in ONE row, sized by the tallest - so a resting well left at its own
   height opened an 82px seam under itself while its neighbours were mounted
   (measured, not guessed). `min-height` states the two sizes, `align-self`
   stretches every well to whatever the row became, and the shelf opens as one
   object. An explicit height rather than `aspect-ratio` because a ratio-sized
   box reports a definite height and refuses to stretch. */
@supports (grid-template-rows: subgrid){
  .ins-well{align-self:stretch;height:auto;min-height:clamp(112px,9vw,148px)}
  .ins-well.on{height:auto;min-height:clamp(172px,14.6vw,232px)}
}
.ins-well canvas{position:absolute;inset:0;width:100%;height:100%;display:block}
.ins-wbtn{position:absolute;inset:0;z-index:3;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:6px;width:100%;cursor:pointer;
  background:transparent;border:0;color:#79D9FF;text-shadow:var(--sh-body);
  font-family:var(--pixel);font-size:11px;letter-spacing:.19em;
  transition:background .15s linear,color .15s linear}
.ins-wbtn .ins-wrow{display:flex;align-items:center;gap:9px}
.ins-wbtn u{text-decoration:none;font-family:var(--mono);font-size:9px;
  letter-spacing:.16em;color:var(--blue-dim);text-shadow:var(--sh-micro)}
.ins-wbtn:hover{background:rgba(30,111,224,.14);color:#A8E7FF}
.ins-wbtn:hover u{color:#4BB4FC}
.ins-wbtn svg{width:15px;height:15px;flex:none}
.ins-wbtn[hidden]{display:none}
.ins-wnote{position:absolute;left:0;right:0;bottom:8px;z-index:4;text-align:center;
  font-family:var(--mono);font-size:9px;letter-spacing:.19em;color:var(--blue-dim);
  text-shadow:var(--sh-micro);pointer-events:none}
.ins-wnote.hot{color:var(--amber)}

/* the three body sections are DIRECT children of the slot, because subgrid
   only aligns a grid's own rows - a wrapper would collapse all three into one */
.ins-smut{padding:12px 13px 11px;min-width:0;align-content:start;display:grid}
.ins-sstat{padding:0 13px 12px;min-width:0;align-content:start;display:grid;gap:11px}
.ins-fam{display:grid;gap:6px;min-width:0;align-content:start}
/* ★ A GRID, NOT A WRAPPING FLEX ROW. As a flex row the family label sat on the
   first line only and every chip that wrapped fell back to the card's left
   edge - so "OWN / PARENT / ELDER" stopped saying which family the chips
   underneath belonged to, which is the whole point of grouping them. */
.ins-famrow{display:grid;grid-template-columns:52px minmax(0,1fr);gap:8px;
  align-items:start;min-width:0}
.ins-famrow .ins-muts{display:flex;flex-wrap:wrap;gap:5px;min-width:0}
.ins-famk{font-family:var(--mono);font-size:9.5px;letter-spacing:.2em;line-height:1.9;
  color:var(--blue-dim);text-shadow:var(--sh-micro)}
.ins-mut{font-family:var(--mono);font-size:10px;letter-spacing:.07em;color:#4BB4FC;
  text-shadow:var(--sh-micro);border:1px solid rgba(30,111,224,.5);padding:2px 6px;
  max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ins-mut.p{border-color:rgba(30,111,224,.34);color:var(--blue-dim)}
.ins-mut.e{border-color:rgba(255,180,84,.42);color:var(--amber)}
.ins-none{font-family:var(--mono);font-size:10px;letter-spacing:.14em;
  color:var(--blue-dim);opacity:.75;text-shadow:var(--sh-micro)}

.ins-sgauges{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:9px 14px;
  padding-top:11px;border-top:1px solid rgba(30,111,224,.42)}
.ins-sgauges .ins-g::before{content:none}
/* the actions sit on the FLOOR of the card, on one line across the shelf */
.ins-sacts{display:flex;gap:7px;flex-wrap:wrap;align-items:end;align-content:end;
  padding:11px 13px 13px;margin-top:-1px;
  border-top:1px solid rgba(30,111,224,.42)}
/* ON A ROW they are not a floor, they are the row's right-hand end: no rule
   above them, no padding of their own, and they do not stretch. */
.ins-slot .ins-sacts{padding:0;margin:0;border-top:0;flex:none;gap:6px}
.ins-slot .ins-sb{flex:none;min-width:0;padding:7px 10px;font-size:10px}
.ins-sb{flex:1 1 auto;min-width:84px;cursor:pointer;text-align:center;
  font-family:var(--pixel);font-size:10.5px;letter-spacing:.13em;padding:8px 9px;
  color:#79D9FF;text-shadow:var(--sh-body);background:transparent;
  border:1px solid rgba(75,180,252,.5);box-shadow:0 0 0 1px rgba(1,5,11,.85);
  transition:border-color .14s linear,color .14s linear,background .14s linear}
.ins-sb:hover:not(:disabled){border-color:#79D9FF;color:#A8E7FF;background:rgba(30,111,224,.12)}
.ins-sb:disabled{opacity:.42;cursor:not-allowed}
/* ★ MARKED, NOT DISABLED (2026-08-15). When the server can already see that a
   redeem cannot land - not in game, riding a different species - the button
   goes amber and the reason is printed above it. It is NOT disabled: the
   island re-reads the roster at the moment of the press, so a player who
   spawned in two seconds ago has to be able to try, and a dead control
   explains nothing to the one who cannot. */
.ins-sb.waiting{border-color:rgba(255,180,84,.6);color:var(--amber)}
.ins-sb.waiting:hover:not(:disabled){border-color:var(--amber);color:#FFD9A0;
  background:rgba(255,180,84,.09)}
/* THE REASON ITSELF. On a ROW it takes a whole line of the flex wrap and the
   levers drop below it; in the CARD it is an ordinary paragraph above the
   action floor. It exists only when there is something to say. */
.ins-swhy{flex:1 1 100%;margin:0;font-family:var(--mono);font-size:10.5px;
  letter-spacing:.06em;line-height:1.65;color:var(--amber);
  text-shadow:var(--sh-micro)}
.ins-sheet .ins-swhy{padding:9px 13px 0}
.ins-sb.danger:hover:not(:disabled){border-color:rgba(255,90,90,.75);color:#FF8B8B;
  background:rgba(255,90,90,.08)}

/* the empty vault, the unreachable vault, the loading vault */
.ins-vempty{border:1px solid rgba(30,111,224,.5);padding:clamp(18px,3vw,30px);
  display:grid;gap:9px;justify-items:start;max-width:66ch}
.ins-vempty h4{margin:0;font-family:var(--wide);font-size:14px;font-weight:560;
  letter-spacing:.06em;color:#79D9FF;text-shadow:var(--sh-body)}
.ins-vempty p{margin:0;font-family:var(--read);font-size:13px;line-height:1.75;
  color:#6BC6FF;text-shadow:var(--sh-body)}
.ins-vempty.bad h4{color:#FF8B8B}

/* =========================================================================
   9. THE ONE AUTHORED MOMENT
   ------------------------------------------------------------------------
   Not an entrance on every section - the specimen ARRIVING is the moment, and
   the instrument settles with it: every gauge sweeps from the graticule to its
   reading once, exponentially eased, from an already-visible default. The
   default IS visible: the rails and their ticks are drawn before the sweep, so
   nothing on this page is hidden waiting for an animation to run.
   ========================================================================= */
@keyframes ins-settle{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}
.ins-arrive .ins-g{animation:ins-settle .34s cubic-bezier(.16,.84,.28,1) both;
  animation-delay:calc(var(--i,0) * 34ms)}
@media(prefers-reduced-motion:reduce){
  .ins-arrive .ins-g{animation:none}
  .ins-t i,.ins-band i{transition:none}
  .ins-x{transition:none}
  .stage .sclip.ins-pick svg{transition:none}
}
