/* rip/tier-bar.css — THE pack picker. One stylesheet, five pages.
 *
 * Aaron, 2026-08-10: "wherever a page contains the option to pick a pack, it
 * must use the beautiful new slider we created on the open pack page."
 *
 * That bar was born inline in rip/packs.htm and lived there alone, while four
 * other surfaces that pick a pack (the leaderboard's chip row, the pull-history
 * filter, and the binder tier filter on BOTH /rip/binder and /rip/u/<name>)
 * each hand-rolled their own pill row. Five controls doing one job is how they
 * drift — the same lesson as rip/binder-engine.js ("THERE IS ONE BINDER"). So
 * the rules below were lifted out of packs.htm VERBATIM: same values, same
 * measurements, same comments. The only edit made during the lift was dropping
 * the `.rip-preview` / `html.rip-preview` prefix from every selector, because
 * that class is stamped unconditionally now (see rip/CLAUDE.md, "THE PACK-PAGE
 * REDESIGN IS PUBLIC AS OF 2026-08-10") and no longer selects anything.
 *
 * Behaviour lives in rip/tier-bar.js. A host needs BOTH files.
 *
 * ⚠ NO ?v= AUTOMATION HERE. This file is not in .htaccess's no-cache list (an
 * Apache change needs Aaron's sign-off first — CLAUDE.md's plan gate), so the
 * PHP hosts bust it with a filemtime ?v= and packs.htm — a static .htm — has a
 * hand-typed one. Bump packs.htm's ?v= when you edit this file, or the pack
 * page keeps the old bar for up to a month while every other page updates.
 */

/* ── Tier BAR (preview) — one object, one accent ─────────────────────
   Replaces the 4x2 grid of coloured pills. The grid painted all eight
   packs at once, which is eight accents on one control; the style guide
   allows one. Here the track is neutral and the colour appears ONLY on
   the pack you chose, so the choice is the loudest thing on screen.

   ⚠ COLOUR COMES FROM t.btnText, NOT WHITE. Silver, Gold and Platinum
   are light accents — white on them is unreadable and is most of what
   made the first attempt look cheap. TIERS already carries the right
   foreground per tier; use it rather than inventing one.

   ⚠ EVERY SEGMENT IS flex:1 1 0 SO THE CLOSED ONES ARE EXACTLY EQUAL
   (measured: 0.00px spread). Sizing them to their own text makes "2.5K"
   wider than "25" and the row reads as ragged. The open one takes its
   extra width from flex-grow, so the closed seven stay identical.

   Widths verified with nothing clipped at 320/360/390/412/430/768/1280.
   The narrow-phone steps below shave padding and half a point of type —
   the collapsed prices run out of room before the name does, because the
   name lives in the segment that has the space. */
/* ⚠ width:0 + min-width:100% IS NOT A TYPO — IT IS THE OVERFLOW FIX.
   Found when this bar had a second copy inside the leaderboard's
   .below-2up GRID (both are gone now — the boards moved to
   /rip/leaderboard on 2026-08-10), and a grid track is sized from its
   item's intrinsic width. A flex row of
   eight nowrap segments reports a large intrinsic width even though
   every segment is min-width:0 and shrinks happily in practice, so the
   track resolved to 439px inside a 390px page and the whole leaderboard
   section — and everything below it — hung off the right edge.
   min-width:0 on the item does NOT fix this (measured: still 439px);
   percentages are ignored for intrinsic sizing, so width:0 makes the
   bar contribute nothing while min-width:100% still paints it full
   width. Measured 439px -> 273px, which is what the section is without
   a selector in it at all. contain:inline-size fixes it too but has a
   shorter support tail. */
/* ⚠ box-sizing IS SET HERE, NOT INHERITED FROM THE HOST'S RESET.
   packs.htm carries a global `*{box-sizing:border-box}`; the .rip-ui pages do
   not apply one to this element, and the difference is visible: measured at
   390px the bar came out 62px tall on /rip/packs and 70px on /rip/leaderboard
   from the same rules, because min-height:62px landed on the CONTENT box there
   and the 3px padding + 1px border were added on top. A shared component that
   only lays out correctly on pages that happen to have the right reset is a
   component that will be reported as broken on the sixth page it reaches. */
.tier-bar,.tier-seg{box-sizing:border-box}
.tier-bar{display:flex;gap:2px;padding:3px;border-radius:13px;
    background:#0d1219;border:1px solid rgba(255,255,255,0.07);
    box-shadow:inset 0 1px 0 rgba(255,255,255,0.03);min-height:0;align-content:stretch;
    width:0;min-width:100%;position:relative;overflow:hidden;container-type:inline-size}
.tier-seg{flex:1 1 0;min-width:0;display:flex;flex-direction:column;
    align-items:center;justify-content:center;gap:1px;
    padding:11px var(--tb-px,5px);border:0;border-radius:9px;background:transparent;
    cursor:pointer;white-space:nowrap;overflow:hidden;font-family:var(--rip-body);
    line-height:1.15;color:#7d8b9c;min-height:44px;position:relative;isolation:isolate;z-index:1;
    transition:flex-grow .42s cubic-bezier(.32,.72,0,1),background .28s ease,color .28s ease}
.tier-seg:hover:not(.on){background:rgba(255,255,255,0.05);color:#aab6c4}
.tier-seg .tb-p{font-size:var(--tb-fp,11px);font-weight:700;letter-spacing:0.01em}
.tier-seg .tb-n{font-size:8.5px;font-weight:800;letter-spacing:0.09em;
    text-transform:uppercase;max-height:0;opacity:0;overflow:hidden;
    transition:max-height .42s cubic-bezier(.32,.72,0,1),opacity .26s ease .08s}
/* One fill, one hairline top-light, one soft drop. Not a fill AND a ring
   AND a glow — three effects doing one job is the tacky tell. */
/* ⚠ THE FILL OPENS FROM THE CENTRE; THE BOX CANNOT.
   Aaron asked for the selected segment to expand outward from its middle.
   Geometrically it cannot: the row is a fixed width and the closed
   segments are already at their minimum — measured spare width before
   "2.5K" clips is 5.1px at 390px and 3.0px at 412px, against the ~66px
   the open segment would need to take from its left. Shrinking the
   neighbour to buy that room clips it immediately.
   So the WIDTH still resolves rightward (flex has no other option) while
   the COLOUR scales out from the centre over the same 420ms. The eye
   tracks the fill, so it reads as opening centrally — which is the
   effect asked for, delivered the only way the width budget allows.
   The paint lives on ::before rather than the segment so it can be
   transformed without touching the label. */
.tier-seg.on{flex-grow:var(--tb-g,3.4);color:var(--tb-fg)}
.tier-seg.on::before{content:'';position:absolute;inset:0;z-index:-1;border-radius:9px;
    background:linear-gradient(180deg,color-mix(in srgb,#fff 13%,var(--tb-ac)) 0%,var(--tb-ac) 100%);
    box-shadow:inset 0 1px 0 rgba(255,255,255,0.30),0 6px 16px -7px var(--tb-ac);
    transform-origin:center;animation:tbOpen .42s cubic-bezier(.32,.72,0,1)}
@keyframes tbOpen{from{transform:scaleX(0.26);opacity:0.35}to{transform:scaleX(1);opacity:1}}

/* ⚠ ONE SWEEP ACROSS THE WHOLE BAR — IT BELONGS TO THE TRACK, NOT THE
   SEGMENTS. The first version put a sheen on each closed segment,
   staggered by index. Even staggered it read as eight separate boxes
   lighting up in turn, which is the opposite of the point: this control
   is meant to look like ONE bar. A single band on the track travels
   unbroken from the left edge of "25" to the right edge of "5K", the way
   a progress bar fills.
   It sits at z-index 0 with the segments at 1, so it shows through the
   transparent closed segments and passes BEHIND the selected tab rather
   than washing its colour out.
   ~1.9s of sweep in a 6s cycle: mostly still, because this lives under a
   live pack-opening screen and must never compete with it. */
.tier-bar::after{content:'';position:absolute;top:0;bottom:0;left:0;
    width:40%;z-index:0;pointer-events:none;border-radius:13px;
    background:linear-gradient(100deg,transparent 0%,rgba(255,255,255,0.11) 50%,transparent 100%);
    animation:tbShine 4.4s linear infinite}
/* ⚠ THE PAUSE IS NOT JUST THE HOLD — MOST OF IT WAS INVISIBLE TRAVEL.
   The band was 34% wide and ran translateX(-110%) -> 400%, but it leaves
   the right edge of the bar at +294% and keeps travelling to +400%. That
   last stretch is 21% of the distance spent entirely off-screen, and an
   ease-out curve spends far longer than 21% of the TIME on it. Add the
   38% hold and the real gap was roughly three seconds, not the 1.7 the
   keyframes suggested.
   Now the band is 40% wide and travels only as far as it needs to:
   -100% puts its right edge exactly on the left edge of the bar, +250%
   puts its left edge exactly on the right edge. Nothing is spent off-
   screen. linear, because this is meant to read like a progress bar
   filling, and an eased sweep lingers at both ends.
   ⚠ 270%, NOT 250%. 250% is the exact arithmetic boundary — the band's
   left edge lands ON the bar's right edge — but the ::after spans the
   PADDING box while the bar measures as a border box, so at 250% it
   stopped 3px INSIDE and sat there through the whole hold: a visible
   sliver parked at the right end, and no rest at all. Measured 4390ms of
   a 4400ms cycle with the band on screen. 270% clears it with ~20px to
   spare, at the cost of 0.2s of off-screen tail.
   4.4s cycle: ~3.2s crossing, ~1.2s genuinely dark. */
@keyframes tbShine{0%{transform:translateX(-100%)}78%,100%{transform:translateX(270%)}}
.tier-seg.on .tb-p{font-size:var(--tb-fpa,14px);font-weight:800}
.tier-seg.on .tb-n{max-height:14px;opacity:0.74}
/* ⚠ CONTAINER QUERIES, NOT MEDIA QUERIES. There are TWO of these bars and
   they are not the same width: the page-top one spans the column, the
   leaderboard's mirror sits in a narrower grid cell. Sizing off the
   VIEWPORT got the wide one right and clipped the narrow one on the same
   screen — measured at 390px, the mirror clipped "2.5K" and
   "Neutronium" while the top bar was clean. The bar now reads its own
   width, so both are correct wherever they are put.
   container-type also contains intrinsic size, which is a second belt on
   the width:0/min-width:100% fix above.
   ⚠ AND THAT IS WHY THIS IS THE SHAREABLE FILE. Five hosts now, at five
   different widths — the binder's row sits in a .col-toolbar, history's
   in a .history-toolbar, the leaderboard's spans a 1120px section. A
   media query would have to be right for all five at once; a container
   query is right for each of them by construction. */
@container (max-width:400px){.tier-seg{--tb-px:3px;--tb-fp:10.5px;--tb-fpa:13px}}
@container (max-width:344px){.tier-seg{--tb-px:2px;--tb-fp:10px;--tb-fpa:12px}}
/* ⚠ A NINTH AND TENTH SEGMENT NEED THEIR OWN STEPS — THE PACK PAGE'S EIGHT
   DO NOT SURVIVE BEING SQUEEZED TWICE.
   The pack page picks from eight. The filter bars add "All", and the binder
   adds "Off-set" when a collector has homeless cards, so the same row can carry
   ten. The closed segments are flex:1 1 0, so each extra one takes width off
   every other one, and "2.5K" is the longest closed label and the first to go.
   Measured (headless, the real /rip/binder toolbar, .tb-p width against the
   segment's content box):

       viewport   9 segs   10 segs      ← how far "2.5K" overflows
       320px      +1.5px   +3.6px
       344px      -0.6px   +1.7px
       390px      -2.0px   +0.7px
       412px      -3.9px   -1.1px

   i.e. the eight-segment steps above are simply not enough once there are nine.
   ripTierBar adds .tier-bar--wide at >8 segments and these take over: half a
   point of type and 1px of padding, which buys the 4px the table above is
   short. 9px is small, and it is deliberately confined to a 320-360px phone
   holding a TEN-way control — at 390px, where Aaron reviews, this is 10px. */
@container (max-width:400px){.tier-bar--wide .tier-seg{--tb-px:2px;--tb-fp:10px;--tb-fpa:13px}}
@container (max-width:344px){.tier-bar--wide .tier-seg{--tb-px:1px;--tb-fp:9px;--tb-fpa:11.5px}}
/* ⚠ NOTE FOR THE NARROW CASE: @container styles a container's DESCENDANTS,
   never the container itself, so a `flex-wrap:wrap` written on .tier-bar
   inside an @container block is silently dead — measured as still nowrap
   at a 241px container. If a wrap fallback is ever needed, it has to be
   set from outside the query or from a wrapper element. */

/* ⚠ THE 2-UP SECTIONS MUST BE TOLD TO FILL THEIR TRACK.
   Each carries an inline `margin:0 auto`, and on a GRID ITEM auto margins
   are resolved before alignment and beat the default stretch — so the
   panel is sized shrink-to-fit and centred instead of filling the column.
   That is the trap already written up in rip/CLAUDE.md, and it is why the
   leaderboard's tier bar had 241px to work with while the identical bar
   at the top of the page had 358px on the same screen. width:100% costs
   nothing (max-width:600px still caps it) and needs no !important, since
   the inline style sets margin and max-width but not width. */
@media(prefers-reduced-motion:reduce){.tier-seg,.tier-seg .tb-n{transition:none}
    .tier-seg.on::before{animation:none}
    .tier-bar::after{animation:none;display:none}}

/* ⚠ THE HEIGHT FLOOR IS SHARED, BECAUSE NOT EVERY SEGMENT HAS TWO LINES.
   A priced segment opens to two lines ("$250" over "SENSEI"); the "All" and
   "Off-set" segments on the filter bars have no price, so they open to one.
   Without a floor the whole row loses ~10px the moment "All" is the selected
   segment and gains it back on the next click — a filter row that twitches
   every time you use it. 62px is what the pack page's bar measures with a
   priced tier open (headless, 390px and 1280px, both 62.00px), so pinning it
   here makes every other host match the original exactly.
   packs.htm keeps its own `#tier-scroll.tier-bar{min-height:62px}` on top of
   this: that element is ALSO .tier-scroll (min-height:140px, the pill grid's
   fold reservation), and only an id-weighted selector beats it. */
.tier-bar{min-height:62px}
