/* ================= GRADED SLABS =================
   Everything inside a slab is sized in cqw (container width units) so one
   component renders identically at grid size or full-screen size. */
.slab{position:relative;width:100%;aspect-ratio:63/100;container-type:inline-size;
  font-family:'Outfit',sans-serif;user-select:none}
/* ---- the outer case: rigid, slightly frosted plastic ---- */
.slab-shell{position:absolute;inset:0;overflow:hidden;border-radius:4cqw;
  background:
    linear-gradient(118deg,rgba(255,255,255,.5) 6%,transparent 22%,transparent 74%,rgba(255,255,255,.34) 94%),
    linear-gradient(160deg,#eef1f6 0%,#dbe0ea 26%,#e9edf4 52%,#ccd2de 78%,#e6eaf2 100%);
  box-shadow:0 4cqw 9cqw rgba(0,0,0,.6),inset 0 0 0 .55cqw rgba(255,255,255,.85)}
/* the sonic-weld seam running just inside the outer edge */
.slab-shell::before{content:'';position:absolute;inset:2.4cqw;border-radius:2.6cqw;pointer-events:none;z-index:6;
  box-shadow:inset 0 0 0 .3cqw rgba(255,255,255,.75),0 0 0 .3cqw rgba(150,160,184,.45)}
/* second, tighter seam — real cases have a stepped edge */
.slab-shell::after{content:'';position:absolute;inset:4.4cqw;border-radius:1.8cqw;pointer-events:none;z-index:6;
  box-shadow:inset 0 0 0 .22cqw rgba(255,255,255,.5),inset 0 0 2.6cqw rgba(120,132,160,.3)}

/* ---- the sealed well the card sits in ---- */
.slab-well{position:absolute;left:6.4cqw;right:6.4cqw;bottom:6.4cqw;z-index:2;
  display:flex;align-items:center;justify-content:center;
  background:linear-gradient(165deg,rgba(190,198,214,.30),rgba(120,130,152,.16));
  border-radius:1.6cqw;box-shadow:inset 0 0 3cqw rgba(90,100,124,.4),inset 0 .4cqw 0 rgba(255,255,255,.5)}
.well-lip{position:absolute;inset:1.5cqw;border-radius:1cqw;pointer-events:none;
  box-shadow:inset 0 0 0 .25cqw rgba(255,255,255,.45)}
/* the clear inner sleeve holding the card */
.slab-holder{position:relative;padding:2.2cqw;border-radius:1.4cqw;max-width:100%;max-height:100%;
  background:linear-gradient(158deg,rgba(255,255,255,.34),rgba(255,255,255,.05) 42%,rgba(255,255,255,.26));
  box-shadow:inset 0 0 0 .3cqw rgba(255,255,255,.6),0 1.2cqw 2.6cqw rgba(0,0,0,.4)}
.slab-card{position:relative;display:flex;align-items:center;justify-content:center}
.slab-card img{max-width:100%;max-height:100%;width:auto;height:auto;border-radius:1cqw;display:block;
  box-shadow:0 .8cqw 2cqw rgba(0,0,0,.45)}
/* moulded tabs that grip the holder */
.prong{position:absolute;z-index:4;border-radius:1cqw;pointer-events:none;
  background:linear-gradient(180deg,rgba(255,255,255,.9),rgba(168,178,198,.55))}
.prong.l,.prong.r{width:.85cqw;height:22%;top:50%;transform:translateY(-50%)}
.prong.l{left:1.6cqw}.prong.r{right:1.6cqw}
.prong.t,.prong.b{height:.85cqw;width:34%;left:50%;transform:translateX(-50%);
  background:linear-gradient(90deg,rgba(255,255,255,.9),rgba(168,178,198,.55))}
.prong.t{top:1.6cqw}.prong.b{bottom:1.6cqw}
/* glare across the whole case */
.slab-gloss{position:absolute;inset:0;pointer-events:none;z-index:8;border-radius:4cqw;
  background:linear-gradient(114deg,transparent 28%,rgba(255,255,255,.30) 41%,rgba(255,255,255,.07) 48%,transparent 62%)}

/* ---------------- PSA ---------------- */
.slab.psa .slab-well{top:31cqw}
.slab.psa .psa-label{position:absolute;left:6cqw;right:6cqw;top:6cqw;height:23cqw;z-index:3;
  border-radius:.8cqw;padding:1.1cqw;
  background:linear-gradient(180deg,#ef4048,#d8202c 55%,#c31c26);
  box-shadow:0 .5cqw 1.4cqw rgba(0,0,0,.35),inset 0 0 0 .2cqw rgba(255,255,255,.35)}
.slab.psa .psa-inner{position:relative;width:100%;height:100%;border-radius:.35cqw;padding:1.3cqw 1.5cqw 1cqw;
  background:linear-gradient(180deg,#fff,#f4f4f2);display:flex;flex-direction:column}
.slab.psa .psa-top{display:flex;align-items:flex-start;gap:1cqw;flex:1;min-height:0}
.slab.psa .psa-txt{flex:1;min-width:0}
.slab.psa .psa-l1{font-family:Arial,Helvetica,sans-serif;font-size:3.4cqw;font-weight:700;color:#0d0d0d;
  line-height:1.2;letter-spacing:-.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.slab.psa .psa-l2{font-family:Arial,Helvetica,sans-serif;font-size:3.4cqw;font-weight:700;color:#0d0d0d;
  line-height:1.2;letter-spacing:-.01em;margin-top:.35cqw;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.slab.psa .psa-gr{flex:none;width:17cqw;text-align:right;line-height:1}
.slab.psa .psa-num{display:block;font-family:Arial,Helvetica,sans-serif;font-size:3.4cqw;font-weight:700;color:#0d0d0d}
.slab.psa .psa-word{display:block;font-family:Arial,Helvetica,sans-serif;font-size:2.85cqw;font-weight:700;
  color:#0d0d0d;margin-top:.9cqw;letter-spacing:-.01em}
.slab.psa .psa-big{display:block;font-family:Arial,Helvetica,sans-serif;font-size:6.4cqw;font-weight:700;
  color:#0d0d0d;line-height:1;margin-top:.1cqw}
.slab.psa .psa-foot{display:flex;align-items:center;justify-content:space-between;gap:1cqw;height:5cqw;flex:none}
.slab.psa .psa-logo{height:4.9cqw;width:auto;flex:none}
.slab.psa .lbl-cert{font-family:Arial,Helvetica,sans-serif;font-size:3cqw;font-weight:700;color:#0d0d0d}
.lbl-barcode{display:flex;align-items:flex-end;gap:.3cqw;height:4.2cqw;overflow:hidden;width:16cqw}
.lbl-barcode i{display:block;height:100%;background:#111}

/* ---------------- BECKETT (BGS) ----------------
   THE REAL BECKETT LAYOUT: four sub-grades in a 2x2 grid, spelled out. That is
   what the slab looks like and it is not up for redesign.

   This label had a rendering problem on phones and I changed the typography
   twice trying to fix it — bigger type, then abbreviated names on one row. Both
   were wrong: the first made it worse and the second stopped it being a Beckett
   label. Reverted to the original proportions.

   STILL NOT FIXED after five attempts. Two changes below are kept because each
   removes a real hazard even though neither turned out to be the cause on its
   own: no auto margin in the info column (see the note there), and a line-height
   with enough clearance that overflow:hidden cannot shave a glyph.
   DO NOT change the type sizes or the 2x2 grid to chase this. Measure first —
   slab-diagnostic.html renders this label from this CSS and prints the real box
   heights off the device. */
.slab.bgs .slab-well{top:28.5cqw}
.slab.bgs .bgs-label{position:absolute;left:5.5cqw;right:5.5cqw;top:5.5cqw;height:20cqw;z-index:3;
  display:flex;align-items:stretch;gap:1.4cqw;border-radius:.6cqw;padding:1.4cqw 1.6cqw;
  background:linear-gradient(180deg,#191919,#000 55%,#0d0d0d);
  box-shadow:0 .5cqw 1.6cqw rgba(0,0,0,.45),inset 0 0 0 .2cqw rgba(255,255,255,.12)}
/* left: just the laurel mark and the BECKETT wordmark, nothing else */
.slab.bgs .bgs-brand{flex:none;width:16.5cqw;display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:.4cqw;color:#fff}
.bgs-laurel{width:9.6cqw;height:9.6cqw;flex:none}
.bgs-word-mark{font-family:Georgia,'Times New Roman',serif;font-size:2.75cqw;font-weight:700;
  letter-spacing:.06em;line-height:1;display:flex;align-items:flex-start}
.bgs-word-mark i{font-style:normal;font-size:1.35cqw;margin-left:.2cqw}
/* right: the gold plate carrying everything else */
.slab.bgs .bgs-panel{flex:1;min-width:0;min-height:0;display:flex;gap:1.2cqw;
  border-radius:.3cqw;padding:1.1cqw 1.3cqw;
  background:linear-gradient(157deg,#efe0b0 0%,#d3ba7f 22%,#c4a869 46%,#e6d6a6 70%,#c9ad6b 100%);
  box-shadow:inset 0 0 0 .18cqw rgba(255,255,255,.4)}
/* ---- NO AUTO MARGINS IN HERE, AND NO overflow:hidden ----
   Kept as a hazard removed, NOT as the diagnosis — the clipping survived this
   change. The reasoning is still sound and worth keeping:

   `.bgs-subs` used `margin-top:auto` to pin the sub-grades to the bottom of this
   column. That is the ordinary way to do it and it is fine while there is free
   space — but the moment the content is even slightly TALLER than the column,
   WebKit resolves the auto margin by CENTRING the overflow, pushing content off
   BOTH ends. Chrome and Firefox clamp it to the top instead. So on a phone the
   first line rode up past the top edge and `overflow:hidden` sheared its
   ascenders off, while everything below stayed put.

   That is also exactly why PSA never broke: it pins its footer with flex:1 /
   flex:none and has no auto margin anywhere.

   So the auto margin is gone, replaced by a fixed offset that cannot be
   reinterpreted under overflow, and the clip is gone with it — with flex:none on
   the rows they cannot collapse into each other anyway, so there is nothing left
   that needs hiding.

   THE OFFSET IS DELIBERATELY SMALL. An auto margin absorbed all 2.3cqw of free
   space to push the sub-grades to the bottom; replacing it with a fixed 1.6cqw
   looked closest to that, and left only 5% headroom — which is the very
   condition that makes the overflow happen. 0.8cqw sits the sub-grades a little
   higher and keeps 11% in hand. Given the choice between the label looking
   exactly as designed and the label never shearing a letter off, the second one
   wins. */
.slab.bgs .bgs-info{flex:1;min-width:0;min-height:0;display:flex;flex-direction:column}
/* ---- line-height 1.35, and it is not a taste decision ----
   These two lines kept having their TOPS sheared off on iOS while everything
   below them rendered perfectly. `.bgs-line` is the only element in this label
   carrying `overflow:hidden` — it needs it, because that is what makes
   text-overflow:ellipsis work on a long set name — and `overflow:hidden` clips
   at the box, whose height is exactly `line-height`.

   At 1.22 that box is 1.22em tall. Arial's own content area is about 1.12em so
   it fits, but a fallback with taller metrics does not: the iOS system sans is
   nearer 1.25em, which overflows a 1.22em box and gets shaved top and bottom.
   Whatever is actually resolving on the device, 1.35 is above every candidate,
   so the glyphs cannot reach the clip edge.

   flex:none stays for the separate reason that a column flex item shrinks by
   default, and a shrunk line box draws its glyphs through the row below it. */
.slab.bgs .bgs-line{flex:none;font-family:Arial,Helvetica,sans-serif;font-size:2.5cqw;font-weight:700;color:#1a1508;
  line-height:1.35;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;letter-spacing:-.01em}
.slab.bgs .bgs-subs{flex:none;margin-top:.8cqw;display:grid;grid-template-columns:1fr 1fr;gap:.15cqw 1.6cqw}
.slab.bgs .bgs-sub{display:flex;align-items:baseline;gap:.8cqw}
.slab.bgs .bgs-sub span{font-family:Arial,Helvetica,sans-serif;font-size:2.05cqw;font-weight:700;color:#1a1508}
.slab.bgs .bgs-sub b{font-family:Arial,Helvetica,sans-serif;font-size:2.15cqw;font-weight:700;color:#1a1508;margin-left:auto}
.slab.bgs .bgs-score{flex:none;width:15cqw;min-height:0;display:flex;flex-direction:column;align-items:center;
  justify-content:center;color:#1a1508;text-align:center}
.slab.bgs .bgs-grade{font-family:Arial,Helvetica,sans-serif;font-size:7cqw;font-weight:700;line-height:.95}
.slab.bgs .bgs-wordg{font-family:Arial,Helvetica,sans-serif;font-size:2.05cqw;font-weight:700;letter-spacing:.01em;margin-top:.25cqw}
.slab.bgs .bgs-cert{font-family:Arial,Helvetica,sans-serif;font-size:1.95cqw;font-weight:700;font-style:normal;margin-top:.35cqw}
/* Black Label: the perfect 10 — the gold plate goes black */
.slab.bgs.black .bgs-panel{background:linear-gradient(157deg,#232323,#000 48%,#1a1a1a);
  box-shadow:inset 0 0 0 .18cqw rgba(255,255,255,.22)}
.slab.bgs.black .bgs-line,.slab.bgs.black .bgs-sub span,.slab.bgs.black .bgs-sub b,
.slab.bgs.black .bgs-score{color:#f4f4f4}
.slab.bgs.black .bgs-grade{color:#fff;text-shadow:0 0 1.6cqw rgba(255,255,255,.4)}

/* ---------------- grading reveal ---------------- */
.ovstage.grading{gap:14px}
.grd-kick{font-family:'Bebas Neue';font-size:20px;letter-spacing:.24em;color:var(--gold)}
.grd-card{height:min(30vh,220px);aspect-ratio:63/88;border-radius:9px;overflow:hidden;
  box-shadow:0 16px 34px rgba(0,0,0,.6);animation:grdcard 2.6s ease-in-out infinite}
.grd-card img{width:100%;height:100%;object-fit:cover;display:block}
@keyframes grdcard{0%,100%{transform:translateY(0) rotate(-1deg)}50%{transform:translateY(-8px) rotate(1deg)}}
.grd-reelwrap{position:relative;width:132px;height:76px;overflow:hidden;border-radius:14px;
  background:linear-gradient(180deg,#12162c,#0a0d1e);border:1px solid #333963;
  box-shadow:inset 0 8px 18px rgba(0,0,0,.7)}
.grd-reel{position:absolute;left:0;right:0;top:0;will-change:transform}
.grd-num{height:76px;display:flex;align-items:center;justify-content:center;
  font-family:'Bebas Neue';font-size:46px;color:#fff;letter-spacing:.02em}
.grd-marker{position:absolute;inset:0;pointer-events:none;
  box-shadow:inset 0 0 0 2px rgba(255,207,51,.55);border-radius:14px}
.grd-hint{font-size:12px;font-weight:700;letter-spacing:.16em;text-transform:uppercase;color:var(--dim);
  animation:pulse 1.5s ease infinite}

/* ---------------- slab reveal screen ---------------- */
/* The trade choice added two more buttons here, and this had no height cap —
   on a short phone the Sell button fell off the bottom with no way to reach
   it. The slab itself keeps touch-action:none so the tilt still works both
   ways; there's plenty of room either side of it to scroll from. */
/* The height cap is here so the buttons stay reachable on a short phone — but
   overflow-y:auto clips on BOTH axes, and the slab tilts with scale(1.05) and up
   to 14deg of rotation, so its top edge was being sliced off mid-drag. The
   padding gives the tilt somewhere to go inside the scroll box. */
.ovstage.slabreveal{gap:12px;width:100%;max-width:420px;
  padding:20px 26px 12px;
  max-height:88vh;max-height:88dvh;overflow-y:auto;overscroll-behavior:contain}
.sr-kick{font-family:'Bebas Neue';font-size:22px;letter-spacing:.2em;color:var(--gold);
  text-shadow:0 0 16px rgba(255,203,5,.6)}
.slabreveal.blk .sr-kick{color:#fff;text-shadow:0 0 18px rgba(255,255,255,.7)}
/* The clearance belongs around the thing that actually moves, not the whole
   stage — otherwise every reveal carries 50px of dead space at the top. */
.sr-slab{width:min(62vw,244px);perspective:900px;touch-action:none;cursor:grab;
  margin:32px 16px}
.sr-slab:active{cursor:grabbing}
.sr-slab .slab{transition:transform .16s ease}
.slabreveal.gem .sr-slab,.slabreveal.blk .sr-slab{animation:srin .6s cubic-bezier(.2,1.4,.3,1) both}
@keyframes srin{0%{opacity:0;transform:scale(.72) rotate(-6deg)}60%{transform:scale(1.05)}100%{opacity:1;transform:none}}
.sr-meta{text-align:center}
.sr-name{font-size:17px;font-weight:800;color:#fff}
.sr-val{font-family:'Bebas Neue';font-size:31px;color:var(--gold);letter-spacing:.02em;margin-top:1px}
.sr-val span{display:block;font-family:'Outfit';font-size:11px;color:var(--dim);font-weight:600;letter-spacing:.02em}
.sr-actions{display:flex;flex-direction:column;gap:8px;width:min(86vw,300px)}
.sr-actions .btn{width:100%}

/* ---------------- grader picker sheet ---------------- */
.grader-pick{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:16px}
.gpick{cursor:pointer;border-radius:16px;padding:14px 10px;text-align:center;transition:.15s;
  border:1px solid var(--line);background:linear-gradient(180deg,#171b33,#10142a);color:var(--txt)}
.gpick:hover{transform:translateY(-2px);border-color:#4a5290}
.gpick .gp-brand{font-family:'Bebas Neue';font-size:23px;letter-spacing:.08em}
.gpick.psa .gp-brand{color:#ff6b6b}
.gpick.bgs .gp-brand{color:#ffcf33}
.gpick .gp-desc{font-size:10.5px;font-weight:700;color:var(--dim);margin-top:1px}
.gpick .gp-odds{font-size:10px;color:var(--dim2);font-weight:600;line-height:1.5;margin-top:8px}
.gpick .gp-cost{font-family:'Bebas Neue';font-size:23px;color:var(--gold);margin-top:9px;letter-spacing:.02em}

/* ---------------- THE CASE: rotating graded stock ---------------- */
.slab-case{margin:0 2px 13px;padding:13px 13px 11px;border-radius:18px;position:relative;overflow:hidden;
  background:linear-gradient(180deg,#171c36,#0f1329);border:1px solid #3a4172;
  box-shadow:0 12px 30px rgba(0,0,0,.42),inset 0 1px 0 rgba(255,255,255,.07)}
.slab-case::before{content:'';position:absolute;top:0;left:0;right:0;height:2px;
  background:linear-gradient(90deg,#c9d2e6,#ffcf33 45%,#c9d2e6)}
.case-head{display:flex;align-items:flex-end;justify-content:space-between;gap:10px;margin-bottom:11px}
.case-ttl{font-family:'Bebas Neue';font-size:21px;letter-spacing:.14em;color:#fff;line-height:1}
.case-ttl span{display:block;font-family:'Outfit';font-size:9px;font-weight:700;letter-spacing:.14em;
  text-transform:uppercase;color:#8b93bd;margin-top:3px}
.case-timer{font-size:10px;font-weight:700;color:var(--dim2);letter-spacing:.04em;white-space:nowrap}
.case-timer b{color:var(--gold);font-variant-numeric:tabular-nums}
/* 32 slabs: a wrapping grid you scroll through, capped so it doesn't eat the page.

   FOUR COLUMNS, PINNED — not auto-fill. This used to be
   repeat(auto-fill,minmax(92px,1fr)), which meant the column count followed the
   viewport: 4 across on desktop, 3 on a phone. No case size is flush at both,
   so the last row was always short somewhere, and 30 slabs left a stranded pair
   under a full row on desktop. Pinning the count is what makes 32 a real
   number — 8 complete rows on every device — rather than one that happens to
   divide on the machine it was chosen on.
   The cost is narrower tiles on a small phone (~67px at 360px wide, against
   ~100px before), which the slab absorbs because it is sized in cqw throughout;
   the caption below it now is too. IF YOU CHANGE THE COLUMN COUNT, CASE_SIZE IN
   js/slabs.js HAS TO STAY DIVISIBLE BY IT — there is a test. */
.case-rail{display:grid;grid-template-columns:repeat(4,1fr);gap:11px 9px;
  max-height:420px;overflow-y:auto;padding:2px 4px 6px 2px;scrollbar-width:thin}
.case-rail::-webkit-scrollbar{width:5px}
.case-rail::-webkit-scrollbar-thumb{background:#2b3160;border-radius:4px}
.case-item{width:100%;cursor:pointer;position:relative;transition:transform .16s cubic-bezier(.2,1.2,.3,1)}
.case-item:hover{transform:translateY(-5px)}
.case-item.cant .slab{filter:grayscale(.4) brightness(.72)}
.case-item.gone{pointer-events:none}
.case-item.gone .slab{filter:grayscale(.85) brightness(.45)}
.case-sold{position:absolute;top:38%;left:50%;transform:translate(-50%,-50%) rotate(-12deg);
  font-family:'Bebas Neue';font-size:19px;letter-spacing:.14em;color:#ff6b6b;border:2px solid #ff6b6b;
  padding:2px 10px;border-radius:6px;background:rgba(10,10,20,.72)}
/* THE CAPTION SCALES WITH THE TILE. At four pinned columns a tile is ~67px on a
   small phone, and "BGS 9.5" + "$1,250" at the old fixed 9px/15px did not fit
   side by side in that — they wrapped, and a wrapped caption pushes every row
   below it out of alignment, which is the exact thing the pinned grid is for.
   cqw between px bounds keeps it proportional down to 67px and stops it growing
   past what it used to be at desktop width. nowrap so a near-miss is a clipped
   glyph rather than a broken row. */
.case-item{container-type:inline-size}
/* ---- STACKED, NOT SIDE BY SIDE ----
   These two used to share one flex row with space-between and `nowrap` on both.
   On a phone the case is four columns of about 85px, and "BGS 10 BL" plus
   "$31,905.60" wants roughly 104px — so flex did what flex does, shrank both,
   and the text clipped at each end. It only showed up once the case started
   holding five-figure slabs, because a $909.90 fits and a $31,905.60 does not.

   A row that works for cheap slabs and breaks for expensive ones is a row that
   is one good pull away from breaking, so this does not tune the sizes. Each
   line gets the whole cell width, which is enough for a price twice as long as
   anything the case can currently hold, and the grid keeps a uniform row height
   because every cell is two lines whatever it costs. */
.case-foot{display:flex;flex-direction:column;align-items:center;
  gap:0;margin-top:6px;min-width:0}
.case-grade{font-size:clamp(7px,9cqw,8.5px);font-weight:800;letter-spacing:.04em;
  color:#c3c9ee;white-space:nowrap;max-width:100%;overflow:hidden;text-overflow:ellipsis;
  line-height:1.3}
.case-grade.blk{color:#fff;text-shadow:0 0 8px rgba(255,255,255,.6)}
.case-price{font-family:'Bebas Neue';font-size:clamp(12px,17cqw,16px);color:var(--gold);
  letter-spacing:.02em;white-space:nowrap;max-width:100%;overflow:hidden;
  text-overflow:ellipsis;line-height:1.15}
.case-item.cant .case-price{color:#ff8484}
.case-loading{display:flex;flex-direction:column;align-items:center;gap:11px;padding:26px 10px;
  color:var(--dim);font-size:12px;font-weight:600}
/* placeholder slabs while the case stocks itself */
.case-item.skel{pointer-events:none;animation:skelin .3s ease both;animation-delay:calc(var(--d,0)*.06s)}
@keyframes skelin{from{opacity:0}to{opacity:1}}
.skel-slab{width:100%;aspect-ratio:63/100;border-radius:8px;
  background:linear-gradient(100deg,#191e38 30%,#242a4a 50%,#191e38 70%);
  background-size:220% 100%;animation:skelshine 1.25s linear infinite}
/* 46px + 34px + the gap is 84px of caption, which fitted the old 92px tile and
   does not fit a pinned-4 tile on a phone. Proportional, like the real caption
   it stands in for — a placeholder that overflows is still a broken row. */
.skel-line{display:block;height:9px;border-radius:5px;width:50cqw;
  background:linear-gradient(100deg,#191e38 30%,#242a4a 50%,#191e38 70%);
  background-size:220% 100%;animation:skelshine 1.25s linear infinite}
.skel-line.w{width:36cqw}
@keyframes skelshine{0%{background-position:120% 0}100%{background-position:-120% 0}}
.sr-note{font-size:10.5px;color:var(--dim2);font-weight:600;text-align:center;margin-top:2px}

/* ---------------- slabs tab ---------------- */
.slabgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(124px,1fr));gap:12px;margin:0 2px}
.slabcell{position:relative;cursor:pointer;transition:transform .16s cubic-bezier(.2,1.2,.3,1)}
.slabcell:hover{transform:translateY(-5px) scale(1.02)}
/* select-to-trade */
/* the old tools row is gone — slabs now use the same .binderbar the binder does */
.slabchk{position:absolute;top:6px;left:6px;z-index:5;width:23px;height:23px;border-radius:50%;display:none;
  align-items:center;justify-content:center;font-size:12px;font-weight:900;
  background:rgba(6,8,18,.8);border:1.5px solid rgba(255,255,255,.45);color:transparent}
.slabgrid.selecting .slabchk{display:flex}
.slabcell.sel .slabchk{background:#2fd573;border-color:#2fd573;color:#06210f}
.slabcell.sel{outline:3px solid #2fd573;outline-offset:3px;border-radius:6px}
.slabtradebar{position:fixed;left:50%;bottom:calc(var(--navh) + 10px + env(safe-area-inset-bottom));transform:translateX(-50%) translateY(20px);
  z-index:70;display:none;align-items:center;gap:12px;justify-content:space-between;width:min(92vw,420px);
  background:linear-gradient(180deg,#1b2140,#12152a);border:1px solid #333963;border-radius:16px;padding:9px 12px;
  box-shadow:0 16px 40px rgba(0,0,0,.5);opacity:0;transition:opacity .22s ease,transform .22s ease}
.slabtradebar.show{display:flex;opacity:1;transform:translateX(-50%) translateY(0)}
.stb-info{font-size:13px;font-weight:600;color:var(--dim);white-space:nowrap}
.stb-info b{color:#fff;font-weight:800}

/* ---------------- trade screen ---------------- */
.ovstage.tradeview{width:100%;max-width:440px;gap:0;padding:6px 0 10px;
  max-height:88vh;max-height:88dvh;overflow-y:auto}
.tv-title{font-family:'Bebas Neue';font-size:30px;letter-spacing:.06em;color:#fff;margin-top:34px}
.tv-sub{font-size:11.5px;color:var(--dim);font-weight:600;margin-top:1px;margin-bottom:14px;text-align:center}
.tv-block{width:100%;background:linear-gradient(180deg,#161b32,#10142a);border:1px solid var(--line);
  border-radius:16px;padding:11px 12px;margin:0 2px}
.tv-head{display:flex;align-items:baseline;justify-content:space-between;gap:10px;margin-bottom:9px}
.tv-head span{font-size:9px;font-weight:800;letter-spacing:.18em;color:#8b93bd}
.tv-head b{font-family:'Bebas Neue';font-size:23px;color:var(--gold);letter-spacing:.02em}
.tv-rail{display:flex;gap:9px;overflow-x:auto;padding-bottom:5px;min-height:96px;scrollbar-width:thin}
.tv-rail::-webkit-scrollbar{height:5px}
.tv-rail::-webkit-scrollbar-thumb{background:#2b3160;border-radius:4px}
.tv-item{position:relative;flex:0 0 auto;width:74px;cursor:pointer;transition:transform .15s cubic-bezier(.2,1.2,.3,1)}
.tv-item:hover{transform:translateY(-4px)}
.tv-val{display:block;text-align:center;font-family:'Bebas Neue';font-size:13px;color:var(--gold);margin-top:4px}
.tv-x{position:absolute;top:-5px;right:-5px;width:19px;height:19px;border-radius:50%;background:#e3350d;color:#fff;
  font-size:10px;font-weight:900;display:flex;align-items:center;justify-content:center;box-shadow:0 3px 8px rgba(0,0,0,.5)}
.tv-item.pick .slab{opacity:.55;transition:opacity .15s}
.tv-item.pick.on .slab{opacity:1}
.tv-item.pick.on{outline:2.5px solid #2fd573;outline-offset:3px;border-radius:5px}
.tv-empty{flex:1;display:flex;align-items:center;justify-content:center;color:var(--dim2);
  font-size:11.5px;font-weight:600;text-align:center;padding:0 10px}
.tv-arrow{font-size:19px;color:#5a6098;margin:7px 0}
.tv-balance{width:100%;text-align:center;font-size:12.5px;font-weight:700;margin:12px 2px 10px;padding:9px;
  border-radius:12px;background:#141834;border:1px solid var(--line);color:var(--dim)}
.tv-balance b{font-variant-numeric:tabular-nums}
.tv-balance.good{color:#3ff08a;border-color:rgba(63,240,138,.35)}
.tv-balance.pay{color:#ffcf33;border-color:rgba(255,203,51,.35)}
.tv-balance.short{color:#ff6a6a;border-color:rgba(255,106,106,.35)}
.tv-go{width:min(92%,340px)}

/* ---------- too valuable to grade ----------
   A refusal is really a valuation, so it looks like one: the card under a
   currency strap, and a meter where the slabbed estimate runs past the insured
   ceiling. No shared modal chrome — this is its own object. */
.tvx-wrap{width:100%;max-width:352px}
.tvx{position:relative;border-radius:18px;overflow:hidden;padding-bottom:13px;
  background:linear-gradient(180deg,#171b36,#0f1226);border:1px solid #2c3260;
  box-shadow:0 30px 70px -20px rgba(0,0,0,.85);
  animation:tvxin .34s cubic-bezier(.2,1.3,.35,1) both}
@keyframes tvxin{from{opacity:0;transform:translateY(14px) scale(.95)}to{opacity:1;transform:none}}
.tvx-head{display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:11px 11px 10px 15px;border-bottom:1px solid rgba(255,255,255,.08);
  background:linear-gradient(180deg,rgba(255,203,5,.08),transparent)}
.tvx-kick{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  font-size:8.5px;letter-spacing:.15em;color:#cba846}
.tvx-x{flex:none;width:26px;height:26px;border-radius:50%;cursor:pointer;
  display:flex;align-items:center;justify-content:center;
  background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.12);color:#aeb4dd;transition:.15s}
.tvx-x svg{width:12px;height:12px}
.tvx-x:hover{background:rgba(255,255,255,.16);color:#fff;transform:rotate(90deg)}

.tvx-body{display:flex;align-items:center;gap:15px;padding:16px 16px 4px}
.tvx-cardwrap{position:relative;flex:none;width:94px}
.tvx-card{width:100%;aspect-ratio:63/88;border-radius:5px;overflow:hidden;transform:rotate(-3deg);
  background:#10142a;box-shadow:0 14px 28px -10px rgba(0,0,0,.95),0 0 0 1px rgba(255,255,255,.08)}
.tvx-card img{width:100%;height:100%;object-fit:cover;display:block}
/* a banknote strap snapped across it */
.tvx-strap{position:absolute;left:-13px;right:-13px;top:56%;transform:rotate(-9deg);
  padding:4px 0;text-align:center;
  background:linear-gradient(180deg,#f5e9c8,#d8c38d);
  box-shadow:0 5px 12px -4px rgba(0,0,0,.8),inset 0 1px 0 rgba(255,255,255,.65);
  animation:tvxstrap .42s .18s cubic-bezier(.2,1.7,.4,1) both}
.tvx-strap span{font-family:'Outfit';font-size:7px;font-weight:800;letter-spacing:.11em;color:#4a3410}
@keyframes tvxstrap{from{opacity:0;transform:rotate(-9deg) scaleX(.15)}
  to{opacity:1;transform:rotate(-9deg) scaleX(1)}}
.tvx-facts{flex:1;min-width:0}
.tvx-name{font-size:17px;font-weight:800;color:#fff;line-height:1.15}
.tvx-set{margin-top:3px;font-size:11px;color:#767ea6}
.tvx-rawrow{display:flex;align-items:baseline;gap:7px;margin-top:11px;
  padding-top:9px;border-top:1px solid rgba(255,255,255,.08)}
.tvx-rawrow i{font-style:normal;font-family:ui-monospace,Menlo,monospace;
  font-size:8.5px;letter-spacing:.14em;text-transform:uppercase;color:#767ea6}
.tvx-rawrow b{font-family:'Bebas Neue';font-size:21px;color:#eef0ff;letter-spacing:.02em}

.tvx-meter{padding:14px 16px 0}
.tvx-track{position:relative;height:9px;border-radius:99px;background:rgba(255,255,255,.06);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.07)}
.tvx-fill{position:absolute;left:0;top:0;bottom:0;width:var(--w);border-radius:99px;
  background:linear-gradient(90deg,#3ecf8e,#ffcb05 58%,#e3350d);
  animation:tvxfill .75s .12s cubic-bezier(.3,1,.4,1) both}
@keyframes tvxfill{from{width:0}to{width:var(--w)}}
/* the ceiling, drawn straight through the bar */
.tvx-cap{position:absolute;left:72%;top:-6px;bottom:-6px;width:2px;border-radius:2px;
  background:#fff;opacity:.8;box-shadow:0 0 9px rgba(255,255,255,.7)}
.tvx-marks{display:flex;align-items:flex-start;justify-content:space-between;gap:10px;margin-top:9px}
.tvx-mk{display:flex;flex-direction:column;gap:1px}
.tvx-mk i{font-style:normal;font-family:ui-monospace,Menlo,monospace;
  font-size:8px;letter-spacing:.12em;text-transform:uppercase;color:#767ea6}
.tvx-mk b{font-family:'Bebas Neue';font-size:18px;color:#c4cbef;letter-spacing:.02em}
.tvx-mk.hi{text-align:right}
.tvx-mk.hi b{color:#ff7a5c}
.tvx-over{margin-top:9px;text-align:center;font-size:11px;font-weight:600;color:#ff8f75}
.tvx-over b{font-family:'Bebas Neue';font-size:16px;letter-spacing:.02em;margin-left:2px}

.tvx-note{padding:12px 18px 0;text-align:center;font-size:12px;line-height:1.5;color:#8992bd}
.tvx-go{display:block;width:calc(100% - 32px);margin:13px 16px 0;padding:12px;border-radius:13px;
  cursor:pointer;background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.14);color:#dfe3ff;
  font-family:'Outfit';font-size:11.5px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;
  transition:.15s}
.tvx-go:hover{background:rgba(255,203,5,.14);border-color:rgba(255,203,5,.42);color:var(--gold)}
.tvx-go:active{transform:scale(.98)}
.tvx-foot{padding:10px 20px 0;text-align:center;font-size:9.5px;line-height:1.45;color:#5d648c}

/* a grade that would breach the ceiling is shown struck through, not hidden */
.gp-odds s{opacity:.42;text-decoration-thickness:1.5px}
.gpick[disabled]{opacity:.42;cursor:not-allowed;filter:saturate(.4)}
.gp-ceiling{margin:12px 2px 0;padding:10px 13px;border-radius:12px;
  background:rgba(255,203,5,.07);border:1px solid rgba(255,203,5,.22);
  font-size:11px;line-height:1.5;color:#b9ab77;text-align:center}
.gp-ceiling b{color:var(--gold)}

/* ===== where a slab can go: destination chooser + friend picker =====
   Deliberately a hairline-separated list, not a pair of matching buttons — the
   two destinations behave differently and the subtitles carry the decision. */
.stc-head{text-align:center;padding:2px 4px 0}
.stc-head h4{font-size:19px;margin:2px 0 0;color:#fff}
.stc-head .sub{font-size:11.5px;color:var(--dim);margin-top:4px;line-height:1.45}
.stc-list{margin:15px 0 2px;border:1px solid var(--line);border-radius:14px;
  background:linear-gradient(180deg,#161b32,#10142a);overflow:hidden}
.stc-row{display:flex;align-items:center;gap:11px;padding:12px 13px;cursor:pointer;
  border-top:1px solid rgba(255,255,255,.055);transition:background .13s}
.stc-row:first-child{border-top:none}
.stc-row:hover{background:rgba(255,255,255,.045)}
.stc-row:active{background:rgba(255,255,255,.075)}
.stc-row.dim{opacity:.44}
.stc-row.dim:hover{background:none}
.stc-ic{flex:0 0 auto;width:38px;height:38px;border-radius:11px;display:flex;
  align-items:center;justify-content:center;background:rgba(255,255,255,.055);
  border:1px solid rgba(255,255,255,.075);color:#aab2e0}
.stc-ic svg{width:20px;height:20px}
.stc-txt{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:2px}
.stc-txt b{font-size:14px;color:#fff;font-weight:700;letter-spacing:.01em}
.stc-txt i{font-style:normal;font-size:11px;color:var(--dim2);line-height:1.35;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.stc-chev{flex:0 0 auto;width:16px;height:16px;color:#5a628f}

/* ===== the two destinations =====
   Grid row 0fr → 1fr eases to the real content height instead of guessing one.
   No padding on the inner: overflow:hidden clips at the PADDING box, not the
   content box, so any padding here leaks that many pixels of button through
   while the panel is shut. That's what was showing a green sliver. */
.trchoice{display:grid;grid-template-rows:0fr;pointer-events:none;
  transition:grid-template-rows .3s cubic-bezier(.22,.9,.24,1)}
.trchoice.on{grid-template-rows:1fr;pointer-events:auto}
.trc-inner{overflow:hidden;min-height:0;display:flex;flex-direction:column;gap:8px}
.trc-inner .btn{width:100%}
.trc-btn{transform:translateY(10px);
  transition:opacity .22s ease,transform .32s cubic-bezier(.2,1.25,.35,1),
             background .15s ease,filter .15s ease}
/* has to out-specify .btn:disabled (0,2,0) or a disabled button stays visible
   at 45% while the panel is closed */
.trchoice:not(.on) .trc-btn{opacity:0}
.trchoice.on .trc-btn{opacity:1;transform:none}
.trchoice.on .trc-btn:nth-child(1){transition-delay:.03s}
.trchoice.on .trc-btn:nth-child(2){transition-delay:.09s}
.trchoice.on .trc-btn:disabled{opacity:.45;cursor:not-allowed}
/* In the select bar they float clear of the panel, so it never resizes.
   Sized to the widest label and right-aligned, so they sit over "Trade these". */
.slabtradebar .trchoice{position:absolute;right:12px;bottom:calc(100% + 8px);width:max-content;min-width:112px}
/* In the slab view it flows inline — the negative margin cancels the parent's
   8px flex gap while shut, so a collapsed panel leaves no dead space */
.sr-actions .trchoice{width:100%;margin-bottom:-8px;
  transition:grid-template-rows .3s cubic-bezier(.22,.9,.24,1),margin-bottom .3s cubic-bezier(.22,.9,.24,1)}
.sr-actions .trchoice.on{margin-bottom:0}
.stc-wait{text-align:center;font-size:12px;color:var(--dim2);font-weight:600;padding:22px 8px}
@media (prefers-reduced-motion:reduce){.trchoice,.trc-btn{transition-duration:.01ms}}
/* a slab that came back over the ceiling: keepable, tradeable, not cashable */
.sr-vault{font-style:normal;margin-left:8px;padding:2px 7px;border-radius:6px;vertical-align:2px;
  background:rgba(255,203,5,.14);color:var(--gold);box-shadow:inset 0 0 0 1px rgba(255,203,5,.4);
  font-size:9px;font-weight:800;letter-spacing:.12em}

/* how much of the pile a filter is showing */
.slabfiltered{font-size:11.5px;font-weight:700;color:var(--dim2);margin:0 4px 9px;letter-spacing:.01em}

/* who you got it from, above the case */
.sr-from{display:inline-flex;align-items:center;gap:6px;
  font-size:11px;font-weight:600;color:#9aa2c8;letter-spacing:.02em;
  background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.11);
  padding:5px 11px;border-radius:99px}
.sr-from b{color:#fff;font-weight:800}
.sr-from svg{width:12px;height:12px;stroke:currentColor;fill:none;stroke-width:2.4;
  stroke-linecap:round;stroke-linejoin:round}
