/* insider
   Split from the single v22 stylesheet. Everything here is scoped to
   .card.insider and this form's own class prefix (rule 14: a change made for one
   card form is scoped to that form, by class). */
.card.open .insider-stat b{font-size:var(--fs-stat-open)}
/* The horizontal inset every other form's root carries and this one did not.
   `.closeviz`, `.ctr`, `.pl-opts`, the price/pricegap readouts, `.mv-head` and
   the shell's own `.rdout` all set `padding:0 15px`; `.insider` set none, so its
   content ran flush to the panel's rounded edge -- and the panel is
   `overflow:hidden`, so this was not merely tight. Measured on the frame before
   this rule: the right-hand values were being CUT, not crowded. `AS OF AUG 10,
   2026`, `$48.90` and `$44.76 - AUG 31, 2026` all ran into the clip, and the
   superseded note's second line lost its last word. The dividers inset with the
   content, which is what `.closeviz` already does. */
/* `.card .insider`, not `.insider`: the card root carries the form's class
   too (`.card.solo.insider`), so a bare `.insider` rule lands on the card as
   well as on the viz box inside it. With `padding:0 15px` that shrank the
   card's content box -- the size container `.cardface` measures 100cqw
   against -- to 363px, and the face drew at 363/393 = 0.92 with a black
   band under the action row. Found 2026-09-03 on the rebuilt Nadella card;
   every other form's viz class is not also the card's class. */
.card .insider{width:100%;flex:1;min-height:0;display:flex;flex-direction:column;padding:0 15px}
/* `.insider-stat` now wraps the hero figure and its price qualifier. The class
   is kept rather than replaced because `BEAT_SEL` in js/motion.js reads
   `.insider-stat b` to shrink a figure too wide for its column, and motion.js
   is not this form's file -- see the note in js/forms/insider.js. It no longer
   carries a rule: the head above it is a label, not a section, and a divider
   under the hero would make three horizontal lines in a 569px panel. */
.insider-stat{display:flex;flex-direction:column}
.insider-stat b{font-size:var(--beat-figure);line-height:.9;color:var(--stance);font-weight:700}

/* ------------------------------------------------------------------ *
   The Insider, phase 2 (docs/insider.md). `.insider` and `.insider-stat`
   above are kept -- they were this form's own, unshared with any other
   form, and `.insider-stat b` is already in BEAT_SEL for the shrink-to-fit
   pass. `.insider-plan`/`.insider-rail`/`.insider-dots`/`.insider-dot`/
   `.insider-flat` are no longer drawn by anything -- the new payload shape
   does not carry `rail` -- and were not declared here at all: they were in
   css/shell.css, which is exactly the leak this file's own header warns
   against (a form's classes belonging in that form's own sheet). This
   lane (fo-008) is the one that added a FORM_SECTIONS row for the Insider
   so the CSS-scope sweep can see this form's tokens at all, measured that
   nothing in js/forms/insider/markup.js or js/forms/insider.js emits any of
   the five, and deleted them from shell.css rather than moving them here --
   dead code has no home to move to. `.railends` (also unproduced) is a bare
   shell class, not one of this form's own, and stayed out of this lane's
   scope.

   Every class below is new and prefixed `ins-`, grepped empty across this
   file before it was written (rule 17), so nothing here can be the second
   of two declarations of the same name. Nothing below touches
   `.insider-sale`/`.insider-sales`/`.legsnote`/`.beat-two`/`.beat-label`/
   `.beat-note`/`.gaugepct`/`.posbar` -- The Gauge still draws every one of
   them, unmoved (rule 14). */
/* `.ins-mid`, `.ins-position`, `.ins-pos-head`, `.ins-pos-figs`, `.ins-note`,
   `.ins-plan` and `.ins-remaining*` were declared here and are DELETED rather
   than left, which is the opposite of the call made above for the phase-1
   leftovers. The difference is that those were orphaned by an earlier change
   and merely unused; these were orphaned by THIS one, and their comments argue
   in detail for a layout the panel no longer has -- `.ins-mid`'s explained why
   the slack should be pooled and centred, which is the exact mechanism the
   block at the foot of this file replaces. Dead CSS is cheap; a stylesheet
   that reasons for two contradictory layouts is how the wrong one gets
   restored by someone reading the comments. The rail classes below stay: they
   are still drawn, for `per_leg`. */
.ins-rail{width:100%}
/* The rail follows the hero directly on a `per_leg` card and nothing else
   separates them. Caught on the fixture's frame, not in the markup: the track
   sat hard against the descenders of "at a $121.33 average price" and the two
   read as one block. Only applied where the rail actually follows the hero, so
   a card without one is unaffected. */
.ins-hero + .ins-rail{margin-top:30px}
/* STAGE pass (session 37): the hero is gone from the panel wherever the
   zoom draws (js/forms/insider.js's `showHero`), so a `per_leg` card that
   also zooms -- still unexercised by any stored card, see that file's own
   header comment -- has the rail follow `.ins-head` directly instead. */
.ins-head + .ins-rail{margin-top:20px}
.ins-track{position:relative;height:6px;border-radius:var(--radius-xs);background:var(--line)}
.ins-track i{position:absolute;inset:0;border-radius:var(--radius-xs);background:var(--stance-wash);
  transform:scaleX(0);transform-origin:left;transition:transform .8s cubic-bezier(.16,1,.3,1) .18s}
.card.in .ins-track i{transform:scaleX(1)}
.ins-mark{position:absolute;top:50%;width:11px;height:11px;border-radius:50%;
  background:var(--ground);border:2px solid var(--stance);
  transform:translate(-50%,-50%) scale(.35);opacity:0;
  transition:opacity .26s ease-out var(--d),transform .38s cubic-bezier(.34,1.56,.64,1) var(--d)}
.card.in .ins-mark{opacity:1;transform:translate(-50%,-50%) scale(1)}
/* The average mark reads as a single measurement, not a fill: smaller than
   a per-leg dot, filled solid rather than hollow, no per-mark stagger. */
.ins-track-band b{position:absolute;top:50%;width:9px;height:9px;border-radius:50%;
  background:var(--stance);transform:translate(-50%,-50%);box-shadow:0 0 0 4px var(--ground);
  opacity:0;transition:opacity .3s ease-out .5s}
.card.in .ins-track-band b{opacity:1}
.ins-rail-ends{display:flex;justify-content:space-between;align-items:baseline;margin-top:9px;
  font-size:var(--fs-9-5);letter-spacing:var(--ls-13);text-transform:uppercase;color:var(--dim)}
.ins-rail-ends em{font-style:normal;opacity:.8}
.ins-rail-flat{display:flex;align-items:baseline;gap:9px}
.ins-flat-price{font-size:18px;font-weight:700;color:var(--ink)}
.ins-rail-flat span{font-size:var(--fs-9-5);letter-spacing:var(--ls-13);text-transform:uppercase;color:var(--dim)}


/* ------------------------------------------------------------------ *
   The deck, and why this form stops drawing it.

   This card was shipped baselined -- knowingly overflowing -- since session 18:
   its action row ended at y=1013.77, 181.4px past the pinned bottom at 832.36.
   The deck was the whole of it, and the reason is not that this deck is long.
   It is that the closed media_first column has no line item for a deck at all.

   Measured in the page on 2026-09-01-feed-4, this card, by emptying `.hook .sub`
   and re-reading the action row:

     deck emptied (91 -> 0 chars)   action row 832.36   over by   0.00
     one beat     (35 chars, 2 ln)  action row 905.53   over by  73.17
     two beats    (65 chars, 4 ln)  action row 977.69   over by 145.33
     as shipped   (91 chars, 5 ln)  action row 1013.77  over by 181.41

   An empty deck lands EXACTLY on the pinned bottom. The column is full without
   one. The 17px `.actions{margin-top:auto}` reserves is the only give in it,
   and `.card.solo .hook .sub` carries an 18px margin-top before it sets a single
   line -- so a deck of zero height still overflows, and the shortest one-line
   deck the fit floor can produce (0.68 x 32.23 = 21.9px, a 24.5px line) costs
   18 + 24.5 - 17 = 25.5px. There is no length, no `--band` and no font size that
   fits. That is why a length bound at the builder is not the fix here and a band
   is not either: both assume a slot with some height, and this slot has none.

   `.vizsec` cannot absorb it. It is `flex:none;height:var(--panelh)` on closed
   solo cards, deliberately (see shell.css: fixing the panel is what glues the
   claim to its credit line). Confirmed rather than assumed -- forcing
   `.ins-mid{flex:none}`, `.insider{min-height:0}` and `.insider{flex:1}` in the
   page, singly and together, left the panel at 569px and the overflow at
   181.41px in every combination.

   So the fix is the one The Move and The Habit already made, for the same
   reason and in the same words: the deck's figures are already inside the
   panel, so the form no longer draws it. Here that is literally every figure --
   $2,502,684 is the hero count-up, $48.89 sits between the rail's disclosed
   endpoints, and `1,378,226 shares, 3.86% larger` is the position row verbatim
   and better, because the panel dates it and carries the superseded caveat the
   deck cannot. The deck was the third printing of one set of numbers.

   The payload keeps `sub`, exactly as `.card.replay` and `.card.habit` keep
   theirs: v21 draws the stored aptv card and still wants a sentence there, and
   the card contract refuses an edit that CREATES a path ("adding a `sub` where
   the builder wrote none is a new claim, not a rewording"), so deleting the
   field would close that door permanently.

   This is a third form reaching the same conclusion by overflowing first, which
   says the finding is the column's and not this form's. fo-007
   (docs/reviews/foundry-2026-09-11.md) is that finding stated plainly: the
   closed solo column has no line item for a deck at all, and three forms'
   own `display:none` (this one's, The Move's, The Habit's -- for a while
   consolidated into one rule in shell.css, still three local fixes) were
   one structural omission answered three times. `.card.insider .hook
   .sub{display:none}` no longer exists anywhere, consolidated or not:
   js/cardhtml.js never emits `.hook .sub` for a solo card, so there is
   nothing to hide. Nothing here changes what this card renders; the numbers
   above -- showing this deck at one line (37.09px over) and at its real
   five-line length (181.41px over) -- still stand as what re-opening that
   slot would cost. */

/* ------------------------------------------------------------------ *
   The panel, placed rather than pooled.

   WHAT WAS WRONG. `.ins-mid{flex:1;justify-content:center}` pooled every unused
   pixel in the panel into the hero group and split it symmetrically. Measured
   on 2026-09-01-feed-4-007 before this rule: `.ins-mid` was 366.56px tall
   around 138.38px of content, so 228.18px of nothing, as 114.09px above the
   rail and 114.09px below the position block. Two holes rather than one, and
   neither chosen -- `justify-content:center` picked them, and it would pick
   different ones on a card with a plan line. (The brief called this ~500px in
   two ~250px gaps; measured it is 228.18 in two of 114.09. The mechanism named
   was exactly right, the magnitude was not.)

   WHAT REPLACES IT. Three blocks, each with a stated position, and the slack
   lands in ONE place because only one place is left free:

     .ins-head      top of the panel. Label over date.
     .ins-hero      a fixed 74px below the head. The one primary fact.
     .ins-holding   margin-top:auto, so it takes the bottom -- less a chosen
                    44px, so the block stops above the panel's edge instead of
                    sitting on it.

   `margin-top:auto` on the last block is what takes the slack out of the hero's
   hands: it collects in the single gap between the hero and the divider, which
   is the breathing room the composition is built around rather than an
   accident of how many optional rows this filing happened to have. It is the
   same device `.actions{margin-top:auto}` uses in the shell's own column.

   Targets, in card coordinates (the panel is 569px at y=16-585, and
   `.card.solo .vizsec` pads it 16px top / 12px bottom, so the content box is
   y=32 to y=573):

     head       32 - 71        hero      145 - 252
     free       252 - 405      divider   ~405
     holding    426 - 529      padding   529 - 573

   These are a target and not a contract -- measure the frame, not this comment.

   SECOND PASS (docs/insider-animation.md, "Second pass"): the block above
   described a panel that pooled the eyebrow, the figure and two qualifier
   lines at the top. Reviewer, 2026-09-03: *"needs to compare to the other
   bottom third stuff. I don't think we need as much info at the very top."*
   The eyebrow is now ONE line, not two (`.ins-head` below), and the hero is
   the figure alone -- no `SALE VALUE` label, no average-price note, no share
   count. All three still print, once, on the sold row inside `.ins-zoom`
   further down this file, which is also where "the other bottom third
   stuff" (The Close's `BEST`/`WORST` rows, `forms/close.css`'s `.cl-end`) is
   answered. What that frees at the top goes to the stage's own height --
   see the zoom block below for the measurement. */
.ins-head{display:flex;flex-direction:row;align-items:baseline;gap:0}
/* Session 38: `.ins-role` shares `.ins-kind`'s type exactly -- one more word
   on the same line, not a second kind of label. */
.ins-role,.ins-kind{font-size:var(--fs-10);letter-spacing:var(--ls-15);text-transform:uppercase;color:var(--dim)}
/* The middot is CSS content, not a text node -- `review/formcheck.mjs`
   reads `.ins-when`'s/`.ins-kind`'s `textContent`, which does not include
   `::before` generated content, so the join here cannot be mistaken for a
   second date or a second role by anything that asserts the string. */
.ins-when{font-size:var(--fs-10);letter-spacing:var(--ls-15);text-transform:uppercase;color:var(--dim);opacity:.75}
.ins-when::before{content:"\00a0\00b7\00a0"}
/* `.ins-kind` only gets a LEADING dot when a role actually precedes it --
   the adjacent-sibling combinator is what keeps a pre-v3 stored card (no
   `role`, so `.ins-role` never renders) from drawing a dot with nothing
   before it. */
.ins-role + .ins-kind::before{content:"\00a0\00b7\00a0"}
/* Reviewer's decision on a role the closed table cannot shorten
   (session/headline.mjs's isShortRole()): the kicker still leads with it,
   but ONLY `.ins-role` may ever give -- never the kind or the date, and
   never the row. `max-width` plus `overflow:hidden` on a flex item is what
   makes that true: overflow other than `visible` zeroes a flex item's
   automatic minimum width (CSS Flexbox §4.5), so `.ins-role` alone can
   shrink past its own content and ellipsis, while `.ins-kind`/`.ins-when`
   keep the default content-based minimum -- `flex-shrink:0` on both pins
   them at full size regardless of how long the role is. Every value the
   closed table actually produces (CEO .. "10% owner", <=10 characters) sits
   well under 130px and never triggers the ellipsis; only a genuinely
   unmapped filed title does. */
.ins-role{max-width:130px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
.ins-kind,.ins-when{flex-shrink:0}
/* The hero is one child now (just the figure), so the flex gap the
   multi-line version needed is gone -- `margin-top` alone places it under
   the eyebrow. 10px is the smallest gap already in use on this face that
   still reads as a break between two different kinds of line rather than
   one crowded block. Only reached on the fallback path now (`showHero`). */
.ins-hero{margin-top:10px}
/* A panel that draws the fills-rail has one more block below the hero
   (`.ins-hero + .ins-rail`'s own 30px) -- unaffected by this pass, kept for
   the one stored card that exercises it (2026-09-01-insider-fixture). */
.ins-hero:has(+ .ins-rail){margin-top:8px}
/* `.ins-hero-label` is deleted (nothing draws it any more). `.ins-hero-note`/
   `.ins-txn` stay, narrowed to the fallback path: `js/forms/insider.js`'s
   `showHero` draws this whole hero block only where the zoom does not draw
   -- a pre-v19 payload, or a modern one whose `remaining.value` is null --
   and these two are the only place the price qualifier and the share count
   can still appear when that happens. No stored card exercises the second
   case today. */
.ins-hero-note{margin-top:8px;font-size:var(--fs-14);line-height:1.3;color:var(--dim)}
.ins-txn{margin-top:9px;font-size:var(--fs-13-5);line-height:1.35;color:var(--ink);opacity:.74}
/* The grounded comparison, at the foot. One rule in the panel, and it is here:
   it separates the magnitude from what the magnitude was against, which is the
   only boundary on this face that carries meaning. */
/* `padding-top` is how the divider is positioned, and it is worth saying so
   because it reads backwards: the block is anchored from the BOTTOM
   (margin-top:auto, then a chosen 44px off the panel's edge), so its content
   sits where it sits and growing the padding moves the RULE up, not the text
   down. At 21px the divider measured y=441 against a target of ~405 and the
   free space above it was 219px rather than ~152 -- one hole big enough to
   read as the hero having been stranded at the top. 52px puts the rule at
   y=411 and gives the label the blank line above it the composition wants. */
.ins-holding{margin-top:auto;margin-bottom:44px;padding-top:52px;
  border-top:1px solid var(--line);display:flex;flex-direction:column;gap:7px}
/* STAGE pass: `.ins-holding` and `.ins-zoom` no longer coexist on one card
   -- js/forms/insider.js's `showHero` gate draws exactly one of them, never
   both (the block is now the fallback for a payload the zoom cannot draw
   from at all) -- so the `.ins-zoom + .ins-holding` tightened variant this
   comment used to describe is unreachable and was deleted rather than left:
   the reasoning it argued from (a stage sitting directly above the divider)
   is no longer a shape this file ever produces. The base rule above, tuned
   for the panel `.ins-holding` alone occupies, is the only one left. */
.ins-holding-label{font-size:var(--fs-10);letter-spacing:var(--ls-14);text-transform:uppercase;color:var(--dim)}
.ins-holding-figs{display:flex;align-items:baseline;justify-content:space-between;gap:9px}
.ins-holding-figs b{font-size:var(--fs-22);font-weight:700;color:var(--ink);line-height:1}
.card.open .ins-holding-figs b{font-size:var(--fs-28)}
/* The direction reads in the stance colour, which is the only colour on this
   card that means anything. Brand colour is identity and never direction. */
.ins-holding-figs i{font-style:normal;font-size:var(--fs-13);font-weight:700;white-space:nowrap}
.ins-holding-figs i.up{color:var(--up)}
.ins-holding-figs i.down{color:var(--down)}
/* The two quiet lines under the position figure, one weight and one colour so
   they read as a pair of footnotes to it rather than as two more figures.
   Declared together rather than as a second block: adding a rule can retire a
   guard as surely as deleting one, and this file has already paid for a
   `min-height` block sliding between two declarations that had to stay
   adjacent.

   `-prev` is what makes the percentage legible without a paragraph: 3.86% of
   WHAT. It carried the transaction date until session 22 -- the comment here
   used to explain why -- and the date came off because the eyebrow two inches
   above already prints it, and a date beside a superseded figure reads as an
   older, different one.

   `-worth` is the only line on the face in the position's own currency. Every
   other figure in this block is a share count. */
.ins-holding-prev,.ins-holding-worth{font-size:var(--fs-11-5);line-height:1.35;color:var(--dim)}

/* ------------------------------------------------------------------ *
   The zoom, STAGE pass (session 37, review/rules.jsonl C57). Two bars, one
   scale that changes -- unchanged from the second pass this replaces (see
   docs/insider-animation.md for that history) -- but the two boxed rows
   below the stage are gone, and with them the ~300ms hold-then-fade
   captions they carried. PACING pass, session 38: the reviewer's own
   storyboard is two beats of EQUAL weight, each with its own rest and hold
   (js/forms/insider.js's own timeline comment carries the shot list and the
   exact ms) -- the headline above the panel states the sale while the sale
   bar grows and counts, then a beat 2 hold, then the headline under the
   panel states the surviving position while the stage rescales and the
   stake bar grows in and counts, then a final hold. ~7.4s total. The panel is
   eyebrow-then-stage now -- js/forms/insider.js's `showHero` drops the
   hero wherever the zoom draws it a second time on the bar's own label
   (see that file's header comment) -- so the stage gets everything below
   the two dates: `flex:1` rather than a chosen pixel height, the same
   "whatever the window leaves" rule the panel itself already follows
   (AGENTS.md, session 33 amendment) rather than a number reasoned about in
   the abstract and then not revisited on a taller or shorter phone.

   `ins-zoom` and every child below are grepped-empty names (rule 17), same
   discipline the rest of this file uses instead of a literal `.card.insider`
   prefix on every rule -- the blast radius is the same grep either way. */
.ins-zoom{margin-top:34px;display:flex;flex-direction:column;flex:1;min-height:0}
/* The stage. Absolutely positioned bars, not a flex row -- flex gives every
   child a share of the row's width whether or not it has any height, which
   is exactly the "square in a shared column" defect docs/insider-animation.md
   measured against the first build. `left` is set once per bar and never
   moves (0 for the sale, the far side of the gutter for the stake); only
   `width` and `height` ever change. `js/forms/insider.js` reads this box's
   own `offsetWidth`/`offsetHeight` back (layout, not `getBoundingClientRect`
   -- see that file's comment on why it has to be the unscaled ones) rather
   than assuming a number, so this is the one and only place the stage's
   size is decided -- `flex:1` here rather than a height, so whatever room
   the removed rows freed goes to the bars rather than to a number this file
   would otherwise have to keep re-measuring by hand. */
/* `overflow:hidden` (camera-pull pass, session 38): beat two now draws the
   stake bar at its TRUE height relative to the sale bar the moment beat two
   starts -- for the common filing (stake >> sale) that is many times the
   stage's own height, clipped from above rather than fitted, and the beat
   zooms the frame out around it until it fits (js/forms/insider.js's
   `runBeat2`, the reviewer's "we are just walking backwards from the main
   red bar chart", NEXT.md ~949). Every prior beat kept both bars inside
   `avail` by construction (`barPx()`'s own floor/cap), so nothing here ever
   needed to clip before -- without this, an oversized bar paints over the
   headline above the panel rather than being cropped by its own stage. */
.ins-zoom-stage{position:relative;margin-top:6px;flex:1;min-height:60px;overflow:hidden}
/* The one card shape that draws the fills-rail ABOVE the zoom
   (2026-09-01-insider-fixture -- `p.method === "per_leg"`, both blocks true
   at once, the stacking `js/forms/insider.js`'s own header comment already
   flagged as unverified) spends ~58px on the rail before the stage starts --
   `flex:1` already gives the stage whatever is left rather than a second
   hardcoded height to keep in sync with the first, so no companion rule is
   needed here the way the fixed-height stage used to require one. */
/* `transition:none` on purpose (PACING pass, session 38) -- both bars are
   driven every animation frame by js/forms/insider.js's own `runBeat1`/
   `runBeat2` now, not by a CSS transition. A CSS transition handed a new
   `style.height` every ~16ms (what a rAF loop does) does not carry the loop's
   own eased curve; it starts a fresh, separate tween toward whatever the
   current frame's target happens to be and fights the next frame's write --
   and the ORIGINAL defect was exactly a CSS timing curve (`cubic-bezier
   (.16,1,.3,1)`, ease-out-expo) finishing ~90% of the beat's height change
   in its first third and going visibly flat for the rest (see that file's
   header comment, "why the stake bar randomly got taller at the end"). The
   fix is for CSS to get out of the way and let the JS curve be the only one. */
.ins-bar{position:absolute;bottom:0;transition:none}
.ins-bar-sale{background:var(--stance)}
/* `overflow:hidden` (LABEL-ON-BOX pass, session 38: reviewer on the phone,
   "the stake's amount arrives from the top" -- the old `bottom:100%` stake
   label, above a bar whose TRUE height is many stage-heights tall for most
   of beat two under the CAMERA model, dropped in from off-frame full width
   over a sliver instead of building up with the bar). Sale is untouched --
   its label still sits above its own bar, `bottom:100%`, and never needs
   clipping. Only the stake bar clips: it is now the label's own containing
   block AND its mask, so as the box enters from the right and widens, the
   box's own edge is what reveals the label underneath it, piece by piece,
   never the whole string over a not-yet-there bar. */
.ins-bar-stake{background:var(--muted);overflow:hidden}

/* The label. Two different anchors now, by design (LABEL-ON-BOX pass,
   session 38) -- the sale's stays `bottom:100%` of its own bar (session
   37: "labels ON the bars"; untouched, still correct: the sale bar is
   always short enough at rest for its label to sit above it with room to
   spare, and the label riding up with the bar as it shrinks IS beat two's
   own "the sale is shrinking" cue). The stake's moved INSIDE its own bar,
   bottom-anchored (see `.ins-bar-label-stake` below) -- js/forms/
   insider.js's own `geometry()`/`setStakeLabel` comments carry why. One
   text node either way, "N shares · $V", both bars the same shape (C57:
   "each beat's title counts the same unit... each figure prices in the
   same unit"). Sale carries the stance colour -- the sale bar's own figure
   is a claim about direction, the same reason `.ins-holding-figs i` does;
   the stake is plain ink, matching the grey bar it sits on (and, now, the
   grey fill behind it). */
/* `--fs-15`, not `--fs-companion`: the latter is `clamp(22px,6vw,30px)` --
   a real viewport unit inside `.cardface`, which is laid out at a fixed 393
   design px and scaled (AGENTS.md, "TYPE inside .cardface is design px,
   never vw" -- a `vw` token resolves against the true viewport and gets
   scaled a second time). Sized down from the companion scale on purpose
   too: "N shares · $V" runs longer than a bare companion figure, and at
   19px+ it wrapped to three lines at the half-stage width beat 2 leaves it
   -- `INS_LABEL_RESERVE` in js/forms/insider.js is sized against two lines
   at THIS font, so the two numbers have to move together if either changes. */
.ins-bar-label{position:absolute;left:0;right:0;bottom:100%;margin-bottom:9px;
  text-align:center;font-size:var(--fs-15);font-weight:700;line-height:1.25;
  font-variant-numeric:tabular-nums;color:var(--stance);white-space:normal;padding:0 4px}
/* Overrides the shared rule's `bottom:100%;margin-bottom:9px` -- this label
   sits INSIDE its own bar now, not above it (LABEL-ON-BOX pass). `bottom:0`
   here is the pre-JS fallback only: js/forms/insider.js's own
   `setStakeLabel` sets an inline `bottom` every time it paints (always wins
   over this rule regardless of specificity), placed at the SALE's resting
   height above the stage floor rather than anything read off this box's
   own -- see that function's header comment for why fixing it there, not
   relative to the stake bar's own (still-animating, off-frame-tall) top,
   is what lands both labels on one shared baseline at the settled frame.
   `margin-bottom:0` cancels the shared rule's 9px, which this label
   accounts for itself, in `INS_LABEL_GAP`, rather than stacking a second
   copy of the same gap on top of it. No opacity/transition any more: the
   label is never toggled, only clipped, so the old "vertical clearance"
   reveal rule this rule used to carry a fade for is gone with it
   (js/forms/insider.js's own header comment on the retired
   `INS_STAKE_LABEL_GAP`).

   `overflow:hidden` here too, belt-and-suspenders alongside the stake bar's
   own (`.ins-bar-stake` above): the shared rule's `left:0;right:0` already
   stretches THIS element exactly to the bar's own current box (its
   containing block), so its own `getBoundingClientRect()` is always the
   bar's -- trivially "inside" it, which is what review/formcheck.mjs's film
   check now asserts. `text-align:left` overrides the shared rule's own
   `center`: the actual text lives one level deeper, in `.ins-bar-label-
   stake-inner` below, an in-flow `inline-block` this element's own text-
   align is what places -- CENTER would slide that child rightward inside
   whatever (narrow, still-growing) width this box currently has, which is
   exactly the re-centring-as-it-grows bug this pass exists to avoid; LEFT
   is what keeps the inner span flush against this box's own left edge
   (== the bar's left edge) for the beat's entire length.

   `padding:0` overrides the shared rule's `0 4px` -- measured live
   (session 38 lane, `review/simdrive.mjs`): with the padding still in
   place, an absolutely positioned box with `left:0;right:0` cannot shrink
   its OWN width below its horizontal padding sum (8px here) even where
   the containing block -- the bar -- is genuinely narrower, so for the
   first ~8px of the bar's growth this element's rect was measurably wider
   than the bar's, poking past its right edge by design-space pixels a
   reviewer would never see (the padding is transparent) but that failed
   review/formcheck.mjs's own "label rect is inside the bar rect" check at
   exactly the film check's earliest sampled frame. Moving the padding to
   `.ins-bar-label-stake-inner` below keeps the same visual breathing room
   around the TEXT without giving the element formcheck measures a floor
   under the bar's own width. */
.ins-bar-label-stake{color:var(--ink);bottom:0;margin-bottom:0;overflow:hidden;text-align:left;padding:0}
/* The text itself, an in-flow `inline-block` rather than a second
   absolutely-positioned layer -- position:absolute here would pull it out
   of flow entirely and collapse `.ins-bar-label-stake`'s own auto height to
   0 (nothing left in-flow to size the line against). Normal flow keeps
   that height (one line at `js/forms/insider.js`'s own `INS_LABEL_FLOOR_PX`)
   while still doing exactly what's needed: `js/forms/insider.js`'s own
   `setStakeLabel` fixes this element's WIDTH to the stake bar's RESTING
   footprint, never its current, still-growing one, so once that width
   exceeds the (narrower) outer box's own current width, it simply overflows
   the outer's right edge rather than shrinking to fit -- and whatever
   overflows is clipped by the outer's own `overflow:hidden` above. Because
   it stays flush against the outer's LEFT edge the whole time (that rule's
   own `text-align:left`), the part that survives the clip is always this
   span's own LEFT portion, revealed further as the outer (and therefore
   the visible window) widens with the bar (reviewer: "it shows up piece by
   piece"). `text-align:center`, inherited from the shared `.ins-bar-label`
   rule, centres the actual text WITHIN this fixed width -- exactly where
   it will sit once the bar reaches its own resting size and the two widths
   coincide, so nothing about the text's own position shifts at that
   moment; only the clip stops moving. */
.ins-bar-label-stake-inner{display:inline-block;vertical-align:top;padding:0 4px;text-align:center}
/* text-align:center on the INNER span, whose width is the bar's resting
   width: the words sit centred in the finished box and are still revealed
   left to right as the outer clip widens (session 38, the reviewer: "the
   wording should be centered too"). */
/* `vertical-align:top`, not the inline-block default `baseline`: baseline
   alignment leaves a small gap below an inline-block for the line's own
   descent, which would sit BELOW this span inside `.ins-bar-label-stake`
   and throw off that element's own `bottom`-anchored position by a few px
   -- exactly the sub-pixel precision the settled-frame baseline match
   (js/forms/insider.js's `INS_LABEL_GAP`) depends on. */
