/* A graded copy's case: a real box in CSS 3D, not a picture. A front face, a back face and four edges standing in
   the same space, so the case can be turned right round and still be a case.

   Two measuring systems live here, and mixing them is how a drawn slab gives itself away:

   - the box is measured in `cqw`, hundredths of the slab's own width (`container-type: inline-size`), because
     `translateZ()` refuses percentages and the plastic has to keep its thickness at every size;
   - the label is measured in percentages of itself. `.sl-label` is its own container, so every position below is the
     reference sheet's own percentage (500 x 149) and the two line up when laid one over the other. The front label
     is the one exception: a sealed label is .9 in tall, which on a 3.12 x 5.31 in slab is taller than 500 x 149 at
     86% of the width, so its rows spread over a taller box. What is printed on it keeps the reference's size
     because the type is given in `cqw`, hundredths of the label's width, not of its height.

   The slab's proportions are the real ones and `src/boitier-proportions.test.ts` holds them there: 3.12 x 5.31 in
   of plastic, a 2.5 x 3.5 in card centred in a well barely larger, a .9 in label at the top.

   The card's box drives the rest: the well is the card plus one single margin, repeated on the four sides. */

.slab {
  container-type: inline-size;
  position: relative;
  width: 100%;
  max-width: 260px;
  margin: 0 auto;
  /* A real graded slab is 3.12 x 5.31 in: 3.12 / 5.31 = .5876. Every length below is a hundredth of that width, so
     the whole case is one PSA slab scaled to whatever room it is given. Its height is 100 / .5876 = 170.18cqw. */
  aspect-ratio: var(--slab-ar, .5876);
  /* The depth is only asked for while the case turns: see `.slab--3d` below. */
  perspective: none;
  /* A case under plastic is not a page: nothing in it is text to be picked up, dragged or long-pressed. */
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
}

/* Thickness and the plastic's clear border, both read by the faces, the edges and the blades. */
.slab { --th: 5.6cqw; --blade: 5.8cqw; }

/* Chromium rasterizes the subtree of a `perspective` once, at the scale its layer was built at, then stretches that
   bitmap over the device pixels: face on, on a 2× screen, the card inside kept a fifth of its laplacian variance and
   read blurred under its own plastic. So the perspective is given only while the case actually turns — grading.js
   sets `slab--3d` under the pointer, and the reveal carries its own — and at rest the box is drawn at screen scale. */
.slab--3d, .slab--reveal { perspective: 1400px; }

.slab * {
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}

.slab img, .slab svg { -webkit-user-drag: none; pointer-events: none; }

.slab__box {
  position: absolute;
  inset: 0;
  transform-style: preserve-3d;
  transform: rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg));
  transition: transform .18s ease-out;
}

/* Both faces are flat: anything inside them that asked for its own 3D space would fold into the box's space and
   come apart as soon as the case turns. */
.slab__face {
  position: absolute;
  inset: 0;
  backface-visibility: hidden;
  border-radius: 4.2cqw;
  transform-style: flat;
  overflow: hidden;
}

.slab__face--front { transform: translateZ(calc(var(--th) / 2)); }
.slab__face--back { transform: rotateY(180deg) translateZ(calc(var(--th) / 2)); }

/* Clear acrylic, welded: the body is left to the room behind it — a tint spread over the whole face reads as a grey
   plate as soon as the ground is dark — and the border is a lip plus the blades a laminated case is pressed into. */
.slab__face--front, .slab__face--back {
  background:
    linear-gradient(118deg, rgba(255, 255, 255, .13) 0 7%, rgba(255, 255, 255, .02) 18%, rgba(255, 255, 255, 0) 34%),
    linear-gradient(200deg, rgba(255, 255, 255, .06), rgba(255, 255, 255, 0) 26%);
  box-shadow:
    inset 0 0 0 .22cqw rgba(255, 255, 255, .58),
    inset 0 0 0 .34cqw rgba(126, 146, 176, .18);
}

/* An inset box-shadow fills everything from the border inwards, so a stack of them is one wide band, never a set of
   lines: past the lip the blades are two rings with clear plastic between them. */
.slab__face--front::before, .slab__face--back::before,
.slab__face--front::after, .slab__face--back::after {
  content: "";
  position: absolute;
  border-style: solid;
  pointer-events: none;
}

.slab__face--front::before, .slab__face--back::before {
  inset: 1.7cqw;
  /* Concentric with the face (4.2cqw): a ring rounder than its inset leaves bulges at the corners, and the zoom on
     the grade shows them three times bigger. */
  border-radius: calc(4.2cqw - 1.7cqw);
  border-width: .22cqw;
  border-color: rgba(255, 255, 255, .40);
}

.slab__face--front::after, .slab__face--back::after {
  inset: calc(var(--blade) - 2cqw);
  border-radius: max(.8cqw, calc(6.2cqw - var(--blade)));
  border-width: .20cqw;
  border-color: rgba(255, 255, 255, .26);
}

/* The lugs that hold the two halves together, one at each edge, as on a sealed case. */
.sl-lug {
  position: absolute;
  border-radius: 999px;
  background: linear-gradient(135deg, rgba(255, 255, 255, .92), rgba(170, 192, 220, .38));
  box-shadow: 0 0 .5cqw rgba(255, 255, 255, .45), inset 0 0 0 .12cqw rgba(72, 88, 112, .40);
}

.sl-lug--top { top: 1.5cqw; left: 50%; width: 18cqw; height: 1.9cqw; transform: translateX(-50%); }
.sl-lug--bottom { bottom: 1.5cqw; left: 50%; width: 18cqw; height: 1.9cqw; transform: translateX(-50%); }
.sl-lug--left { left: 1.5cqw; top: 50%; width: 1.9cqw; height: 18cqw; transform: translateY(-50%); }
.sl-lug--right { right: 1.5cqw; top: 50%; width: 1.9cqw; height: 18cqw; transform: translateY(-50%); }

/* ---------- the four edges ---------- */

/* The plastic seen edge on: milky, with a sharp line down each side. This is what is looked at as the case turns. */
.slab__edge {
  position: absolute;
  background: linear-gradient(90deg, rgba(255, 255, 255, .62), rgba(214, 228, 245, .14) 26%, rgba(150, 170, 196, .14) 74%, rgba(255, 255, 255, .54));
  box-shadow: inset 0 0 .6cqw rgba(255, 255, 255, .30);
}

.slab__edge--left, .slab__edge--right { top: .9cqw; bottom: .9cqw; width: var(--th); }
.slab__edge--top, .slab__edge--bottom { left: .9cqw; right: .9cqw; height: var(--th); }
/* The top and bottom edges read the other way round: the gradient has to follow the thickness, not the length. */
.slab__edge--top, .slab__edge--bottom {
  background: linear-gradient(180deg, rgba(255, 255, 255, .62), rgba(214, 228, 245, .14) 26%, rgba(150, 170, 196, .14) 74%, rgba(255, 255, 255, .54));
}

/* Each edge folds onto its own border, then steps back half a thickness so the box is centred on the faces. */
.slab__edge--left { left: 0; transform-origin: left center; transform: rotateY(-90deg) translateX(calc(var(--th) / -2)); }
.slab__edge--right { right: 0; transform-origin: right center; transform: rotateY(90deg) translateX(calc(var(--th) / 2)); }
.slab__edge--top { top: 0; transform-origin: center top; transform: rotateX(90deg) translateY(calc(var(--th) / -2)); }
.slab__edge--bottom { bottom: 0; transform-origin: center bottom; transform: rotateX(-90deg) translateY(calc(var(--th) / 2)); }

/* ---------- the reflection ---------- */

/* One thin white band crossing the case on the diagonal — the window, in the plastic — and a hot spot that follows
   the pointer. It says « this is under plastic »; it must never say it over the card, where a wide, heavy band
   flattens the drawing's contrast and the copy looks blurred under its own case. */
.sl-gloss {
  position: absolute;
  inset: 0;
  border-radius: 4.2cqw;
  pointer-events: none;
  background:
    radial-gradient(26% 17% at var(--mx, 72%) var(--my, 14%), rgba(255, 255, 255, .10), transparent 70%),
    linear-gradient(118deg,
      transparent 26%,
      rgba(255, 255, 255, .04) 30%,
      rgba(255, 255, 255, .13) 33%,
      rgba(255, 255, 255, .04) 36%,
      transparent 41%);
}

/* ---------- the frosted frame and the well ---------- */

/* The frosted frame the card is set into, below the label: light, grained, and only as wide as the margin round the
   well. Filled across its whole surface it used to read as a grey sheet behind the plastic. */
.sl-plate {
  position: absolute;
  left: 4.75cqw;
  top: 41cqw;
  width: 90.5cqw;
  height: 122.5cqw;
  display: grid;
  place-items: center;
  border-radius: 1.6cqw;
  background: repeating-linear-gradient(45deg, rgba(255, 255, 255, .05) 0 1px, rgba(126, 138, 156, .05) 1px 3px);
  box-shadow:
    inset 0 0 0 .25cqw rgba(255, 255, 255, .42),
    inset 0 0 0 4cqw rgba(228, 235, 245, .34);
}

/* The well is the card plus one margin, the same margin on the four sides: 82.5 x 114.54 around a card of
   80.1 x 112.14 leaves 1.2cqw everywhere. A card that floats in its well is the first thing that gives a drawn case
   away. */
.sl-well {
  width: 82.5cqw;
  height: 114.54cqw;
  display: grid;
  place-items: center;
  border-radius: .8cqw;
  box-shadow: inset 0 0 0 .3cqw rgba(0, 0, 0, .35);
}

.sl-well .card, .sl-well .card-back {
  /* A card is 2.5 x 3.5 in: 2.5 / 3.12 = 80.1% of the slab's width, and 80.1 / (2.5 / 3.5) = 112.14cqw tall. */
  width: 80.1cqw;
  height: 112.14cqw;
  max-width: none;
  /* Flat, with a thin black border and nothing else: no halo, the frosted frame does that work. */
  outline: .3cqw solid #0b0d12;
  outline-offset: 0;
}

.sl-well .card__translater, .sl-well .card__rotator, .sl-well .card__front { width: 100%; height: 100%; }

/* Sealed means sealed: inside the case nothing tilts, nothing shimmers, nothing trembles. Only the box turns, and
   the card is solid with it. */
.slab .card, .slab .card__translater, .slab .card__rotator, .slab .card-back {
  transform: none !important;
  animation: none !important;
  transition: none !important;
}

.slab .card__shine, .slab .card__glare { display: none !important; }

/* holo.css gives the face and its art a translate3d of their own: inside the case that made them 3D layers WebKit kept
   at the size they were first drawn at, and a case that then shrank cropped a card still drawn big. */
.slab .card__front, .slab .card__rotator img { transform: none !important; }

/* ---------- the front label ---------- */

/* The sealed label, copied position by position from the reference: a 500 x 149 sheet, a thin red frame, white
   paper tinted the faintest blue and printed with a fine security pattern. The label is its own container, so
   every rule below is the reference's own percentage. */
.sl-label {
  position: absolute;
  left: 7cqw;
  top: 6.3cqw;
  width: 86cqw;
  height: 25.63cqw;
  /* The front label is as tall as a sealed one, .9 in of the slab's 5.31: .9 / 5.31 * 170.18 = 28.84cqw. Its width
     stays 86cqw, because 3 in of a 3.12 in slab would leave no plastic at its sides -- the reference photos show
     about 86%. So the front label is the reference's sheet with its rows spread over a taller box, and the printed
     sizes below are given in cqw, hundredths of the label's own width, to stay exactly the reference's. */
  container-type: size;
  border-radius: 1cqw;
  /* The mark's badge hangs past the bottom edge, as it does on a real label. */
  overflow: visible;
  font-family: sans-serif;
}

.sl-label--front {
  height: 28.84cqw;
  background:
    repeating-linear-gradient(74deg, rgba(36, 66, 132, .055) 0 1px, transparent 1px 5px),
    repeating-linear-gradient(-74deg, rgba(36, 66, 132, .04) 0 1px, transparent 1px 7px),
    #f8fafe;
  box-shadow: inset 0 0 0 2.4cqw #eb1d2f;
}

/* One size, one weight, capitals, black: the whole typography of a sealed label. Nothing here is bold, nothing is
   condensed, and the grade's figure is the size of everything else. */
.sl-label p {
  position: absolute;
  margin: 0;
  color: #000;
  font-size: 4.479cqw;
  font-weight: 400;
  line-height: 105%;
  text-transform: uppercase;
  white-space: pre-wrap;
}

.sl-left { top: 17.8%; left: 6%; max-width: 54%; text-align: left; }

.sl-num { top: 17.8%; right: 5.5%; text-align: right; }
.sl-word { top: 35.8%; right: 5.5%; text-align: right; }
.sl-digit { top: 50.8%; right: 5.5%; text-align: right; }
.sl-cert { top: 67.8%; right: 5.5%; text-align: right; font-variant-numeric: tabular-nums; }

/* A real Code 128 of the certificate number (grading.js). Its viewBox counts its own modules, so this width is
   the reference's module width exactly: 79 modules of 1.5px on a 500px label. */
.sl-bars {
  position: absolute;
  top: 66.8%;
  left: 6%;
  width: 23.7%;
  height: 16.8%;
  fill: #000;
}

/* The house's mark, in a grained silver badge at the middle of the bottom edge, hanging past the red frame. */
.sl-badge {
  position: absolute;
  left: 43.31%;
  bottom: -1.2342cqw;
  width: 13.28%;
  height: 9.8348cqw;
  display: grid;
  place-items: center;
  border-radius: .3576cqw;
  background:
    repeating-linear-gradient(68deg, rgba(255, 255, 255, .35) 0 1px, rgba(90, 98, 112, .10) 1px 3px),
    linear-gradient(135deg, #ffffff, #dde2ea 18%, #f8fafc 34%, #c3cad4 52%, #f2f4f8 68%, #d2d8e1 84%, #fdfdff);
  box-shadow: 0 .1192cqw .2384cqw rgba(0, 0, 0, .35), inset 0 0 0 .0894cqw rgba(255, 255, 255, .55);
}

/* The mark is drawn in text (styles.css `.lg`), so it stays sharp at any size instead of blurring like a picture.
   It fills its badge the way the reference's does — the badge is a thirteenth of the label, so a mark that leaves a
   margin inside it is unreadable — and it is inked almost black: a grey mark on grained silver reads as a smudge. */
.sl-badge-mark { font-size: 3.696cqw; color: #11161f; }
.sl-badge-mark .lg-meme, .sl-badge-mark .lg-cards { -webkit-text-stroke-width: .04em; }

/* ---------- the back label ---------- */

/* The navy band and, under it, the white strip a case is checked on without being turned over. */
.sl-label--back {
  background: linear-gradient(#221449 0 79.5%, #f7f8fb 79.5% 100%);
  box-shadow: inset 0 0 0 .2cqw rgba(255, 255, 255, .10);
  overflow: visible;
}

/* Pressed into the band, not printed on it: the mark is the colour of the ground, and only its hollow and its
   light draw it. Big enough to read at arm's length. */
.sl-emboss {
  position: absolute;
  left: 6.33%;
  top: 22.78%;
  width: 26.14%;
  height: 34.09%;
  display: grid;
  place-items: center;
}

.sl-emboss-mark {
  font-size: 13cqh;
  color: rgba(228, 232, 242, .72);
  text-shadow: 0 .6cqh 0 rgba(0, 0, 0, .45), 0 -.3cqh 0 rgba(255, 255, 255, .22);
}

/* Three smaller copies above and three below, the way a sealed back repeats the house's name across the band. */
.sl-tone {
  position: absolute;
  left: 6.33%;
  width: 26.14%;
  height: 16%;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.sl-tone--high { top: 5%; }
.sl-tone--low { top: 58.5%; }
.sl-tone-mark { font-size: 5.6cqh; color: rgba(222, 228, 242, .30); }

/* The silver shield hangs point down from the top edge of the band, overflowing it, with the mark inside. Its
   silver moves with the angle: the gradient is re-aimed by `--ry`, the case's own rotation. A degree is the only
   unit that may be added to one here — mixing in the pointer's percentage voids the whole declaration and the
   shield loses its silver entirely. */
.sl-shield {
  position: absolute;
  left: 40.46%;
  top: -7%;
  width: 19.6%;
  height: 64.2%;
  display: grid;
  place-items: center;
  padding-bottom: 14%;
  clip-path: polygon(0 0, 100% 0, 100% 62%, 50% 100%, 0 62%);
  background:
    repeating-linear-gradient(66deg, rgba(255, 255, 255, .22) 0 1px, rgba(80, 90, 108, .16) 1px 3px),
    linear-gradient(calc(118deg + var(--ry, 0deg) * .6),
      #ffffff, #b9c0cc 16%, #f6f8fc 30%, #8f98a6 46%, #dfe6f2 58%, #a9b2c0 74%, #ffffff 92%);
}

.sl-shield-mark { font-size: 9cqh; color: #2b3240; }

/* The QR is scanned off the back by a phone: white ground, black modules, a clear margin all round, and it opens
   this certificate's own page. */
.sl-qrbox {
  position: absolute;
  left: 72%;
  top: 7.82%;
  width: 18.9%;
  height: 64.2%;
  display: grid;
  place-items: center;
  border-radius: 12%;
  background: #fff;
  box-shadow: 0 .5cqh 1cqh rgba(0, 0, 0, .35);
}

.sl-qrbox svg { display: block; width: 80%; height: 80%; }

.sl-bars--back { top: 83%; left: 6.5%; width: 23.7%; height: 14%; }
.sl-certnum { top: 81.8%; right: 6.5%; text-align: right; font-variant-numeric: tabular-nums; }

/* The back of the card is the shared `.mmc-back` drawing; nothing vibrates inside a sealed case (see .sl-well
   below, which freezes its animations). */

/* ---------- the drop shadow ---------- */

/* The shadow does not turn with the box: it stays on the ground, under it. */
.slab::after {
  content: "";
  position: absolute;
  left: 8%;
  right: 8%;
  bottom: -4cqw;
  height: 7cqw;
  border-radius: 50%;
  background: radial-gradient(50% 50%, rgba(0, 0, 0, .45), transparent 70%);
  filter: blur(.6cqw);
  z-index: -1;
}

/* ---------- the full turn, at the reveal ---------- */

/* The grade has just landed: the case turns once right round on its vertical axis — face, edge, back, edge, face —
   and slows into the face the player goes on looking at. */
@keyframes sl-turn {
  0% { transform: rotateY(0deg) rotateX(0deg) scale(.94); }
  45% { transform: rotateY(220deg) rotateX(6deg) scale(1); }
  100% { transform: rotateY(360deg) rotateX(0deg) scale(1); }
}

.slab--reveal .slab__box { animation: sl-turn 4s cubic-bezier(.16, .84, .22, 1) both; }

/* ---------- the flat thumbnail of the grids ---------- */

/* In a grid there is no box: the label and the card flat, no edges, no back, no holo, and a plastic reduced to its
   blades so a graded tile weighs what a card tile weighs. Its box is the card's box to the pixel — same aspect,
   same maximum width — so a graded tile and the tile beside it line up in the same row. */
.slab--tile {
  --th: 0px;
  --blade: 2cqw;
  --slab-ar: .7466;
  max-width: var(--coll-w, 130px);
  perspective: none;
}

.slab--tile .slab__box { transform: none; transition: none; }
.slab--tile .slab__face--front { transform: none; border-radius: 3cqw; }
.slab--tile .slab__face--front, .slab--tile .slab__face--back {
  box-shadow:
    inset 0 0 0 .3cqw rgba(255, 255, 255, .52),
    inset 0 0 0 .42cqw rgba(126, 146, 176, .18);
}

/* A tile is a hundred pixels wide: one blade, and the second ring would land on the first. */
.slab--tile .slab__face--front::before, .slab--tile .slab__face--back::before { inset: 1.1cqw; border-radius: 2.2cqw; }
.slab--tile .slab__face--front::after, .slab--tile .slab__face--back::after { display: none; }

.slab--tile .sl-label { left: 4cqw; top: 2cqw; width: 92cqw; height: 27.42cqw; }
.slab--tile .sl-plate { left: 10.5cqw; top: 32cqw; width: 79cqw; height: 100.5cqw; }
.slab--tile .sl-plate { box-shadow: inset 0 0 0 .2cqw rgba(255, 255, 255, .40), inset 0 0 0 2cqw rgba(228, 235, 245, .34); }
.slab--tile .sl-well { width: 75cqw; height: 100.5cqw; box-shadow: none; }
.slab--tile .sl-well .card { width: 75cqw; height: 100.5cqw; outline-width: .2cqw; }
.slab--tile .sl-lug { display: none; }
.slab--tile .sl-gloss { background: linear-gradient(150deg, rgba(255, 255, 255, .16), transparent 46%); }
.slab--tile::after { display: none; }

@media (min-width: 720px) {
  .slab { max-width: 300px; }
}

/* A reader who asked for less movement keeps the box, not the turn: nothing moves — not the rotation, not the
   reflection — and the face stays readable. */
@media (prefers-reduced-motion: reduce) {
  .slab__box, .slab--reveal .slab__box { animation: none; transition: none; transform: none; }
}

/* On a light ground the plastic returns the grey of the room, not the black of the night, and the shadow tightens. */
:root[data-theme="light"] .slab__face--front, :root[data-theme="light"] .slab__face--back {
  background:
    linear-gradient(118deg, rgba(255, 255, 255, .30) 0 7%, rgba(255, 255, 255, .05) 18%, rgba(255, 255, 255, 0) 34%),
    linear-gradient(200deg, rgba(255, 255, 255, .12), rgba(255, 255, 255, 0) 26%);
  box-shadow:
    inset 0 0 0 .22cqw rgba(255, 255, 255, .72),
    inset 0 0 0 .34cqw rgba(120, 138, 166, .26);
}

:root[data-theme="light"] .slab::after { background: radial-gradient(50% 50%, rgba(28, 34, 44, .32), transparent 70%); }

/* ---------- where the slab shows: the grid, the sheets, a market lot ---------- */

/* In the collection's grid a graded copy takes the place of a card tile: the case is the whole tile, with nothing
   written under it — the label already carries the name, the grade and the certificate. */
.coll-tile.slab-tile .tile-open { display: block; width: 100%; padding: 0; border: 0; background: none; }
.coll-tile.slab-tile .slab { margin: 0 auto; }

/* A copy graded in this session leads the grid for a few minutes: its mark says why it is there and a halo fades out
   behind it, inside the tile so the row keeps its alignment. */
.coll-tile.slab-tile.fresh-grade { position: relative; animation: fresh-grade-in 1.6s ease-out; }
.coll-tile.slab-tile .fresh-pill { position: absolute; top: 6px; right: 6px; z-index: 2; }
/* A slab that also wears the count pill (« ×2 · 1 gradée », top right): « Nouvelle » steps down, under it. */
.coll-tile.slab-tile .count + .fresh-pill { top: 24px; }
@keyframes fresh-grade-in {
  from { box-shadow: 0 0 0 3px var(--gold); }
  to { box-shadow: 0 0 0 3px transparent; }
}
@media (prefers-reduced-motion: reduce) {
  .coll-tile.slab-tile.fresh-grade { animation: none; }
}

/* "Have it graded": everything has to fit without scrolling, the pay button included, from 375 x 667 to
   1440 x 900. Hence the card bounded in height, the price detail on one line and the ten grades as a 5 x 2 grid
   rather than a ten-row table - scripts/gradation_shots.mjs measures it and refuses anything else. */
/* .sheet-body is itself a grid with an automatic column, so the sheet's min-content width sizes that column: the
   grading sheet blew it out to 508 px and at 375/390 px the detail line, the fifth grade and the pay button were
   cut off on the right (@scolver, 05/10/2026). Clamping the track makes the column follow the window, not the
   content; min-width: 0 then lets the head's text column shrink instead of pushing the head wider. */
.sheet-body:has(.grade-sheet) { grid-template-columns: minmax(0, 1fr); }
.grade-sheet { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; min-width: 0; }
.grade-sheet .gr-head { display: flex; align-items: flex-start; gap: 12px; min-width: 0; }
.grade-sheet .gr-visual { flex: none; width: 96px; }
.grade-sheet .gr-id { min-width: 0; }
.grade-sheet .gr-id h2 { margin: 0 0 4px; font-size: 19px; }
.grade-sheet .gr-price { display: flex; align-items: baseline; flex-wrap: wrap; gap: 8px; margin: 0; }
/* An amount never wraps (.amt), so on a legendary Full Art the price alone was wider at 26 px than the text
   column left by the 96 px visual: it ran past the right edge at 375 px. The size follows the window instead. */
.grade-sheet .gr-price b { font-size: clamp(20px, 5.2vw, 26px); font-weight: 900; color: var(--gold-text); }
.grade-sheet .gr-price small { color: var(--muted); }
/* An EXPERT grades for free: the price it would have cost, struck, then the gift in gold. */
.grade-sheet .gr-price s { font-size: 15px; font-weight: 800; color: var(--muted); text-decoration-thickness: 2px; text-decoration-color: #e5484d; }
.grade-sheet .gr-xp { justify-self: center; margin: 0; color: var(--gold-text-deep); font-size: 13px; }
/* The price detail holds one line: cut the text, never the size of the ink (charte). */
/* The detail line used to be clipped with an ellipsis: at 375/390 px that is what cut « +67 M Pa… » off the
   right edge (@scolver, 05/10/2026). It wraps instead — two short lines say the whole price, an ellipsis hides it. */
.grade-sheet .gr-parts { margin: 2px 0 0; color: var(--muted); font-size: 12px; }
.grade-sheet .gr-rest { display: grid; gap: 10px; min-width: 0; }
.grade-sheet .gr-rest > h3 { margin: 0; font-size: 15px; }
.gr-odds { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 6px; margin: 0; padding: 0; list-style: none; }
.gr-odd { display: grid; align-content: start; gap: 1px; padding: 6px 2px; border: 1px solid var(--line); border-radius: 10px; background: var(--surface-2); text-align: center; }
.gr-odd b { font-size: 19px; font-weight: 900; line-height: 1.1; }
.gr-odd span { display: block; color: var(--muted); font-size: 9px; line-height: 1.15; }
.gr-odd em { color: var(--text); font-size: 11px; font-style: normal; font-variant-numeric: tabular-nums; }
/* What the copy would be worth with this grade, under the chance. An amount is a `<span>`, so `.gr-odd span` above
   both sizes it (9px, like the wear word) and blockifies it: the coin fell onto a second line under the number.
   It gets its row back here, coin tightened — five cells across 390px leave only ~62px each, and that is what makes
   an eight-digit amount and its coin fit whole (test/cote-par-note.test.ts). */
.gr-cote { display: block; margin-top: 1px; font-style: normal; line-height: 1.2; }
.gr-cote .amt { display: inline-flex; gap: .1em; }
.gr-cote .coin-mark { width: .8em; height: .8em; }
/* The two grades worth playing for: gold on the 10, a discreet silver on the 9. */
.gr-odd.g10 { border-color: var(--gold); background: var(--surface); }
.gr-odd.g10 b { color: var(--gold-text); }
.gr-odd.g9 { border-color: var(--muted); }
/* The warning is the sentence that changes a decision: framed, never in pale grey. */
.gr-warn { margin: 0; padding: 8px 10px; border: 1px solid var(--line); border-left: 3px solid var(--gold); border-radius: 10px; background: var(--surface-2); font-size: 12px; }
/* Stuck to the bottom of the sheet: should a very short window still force some scrolling, the payment stays on
   screen instead of going below the fold. */
.gr-pay { position: sticky; bottom: 0; width: 100%; min-height: 48px; margin: 0; }
/* The cross at the top already closes the sheet: the "Close" sheet() appends would cost 48 px of height. */
.sheet-body:has(.grade-sheet) > .close:last-child { display: none; }

@media (min-width: 720px) {
  .grade-sheet { grid-template-columns: minmax(0, 220px) minmax(0, 1fr); gap: 18px; align-items: start; }
  /* The card takes the left column across both rows, the text and the payment the right one. */
  .grade-sheet .gr-head { display: contents; }
  .grade-sheet .gr-visual { grid-column: 1; grid-row: 1 / span 2; width: auto; max-width: 220px; }
  .grade-sheet .gr-id { grid-column: 2; grid-row: 1; }
  .grade-sheet .gr-rest { grid-column: 2; grid-row: 2; }
  .grade-sheet .gr-id h2 { font-size: 22px; }
  .gr-odd span { font-size: 10px; }
  .gr-warn { font-size: 13px; }
}

/* La fiche d'une copie gradée : son boîtier en grand, ses faits, sa cote, puis la vente.
   « Mettre aux enchères » doit être sous les yeux à l'ouverture, sans défiler. Le boîtier fait .5876 de large
   pour 1 de haut : à ses 300 px pleins il en prend 510 de haut, et empilé avec le titre, les quatre lignes et
   l'avertissement il chassait le bouton hors de l'écran. Sa largeur descend donc de la hauteur de la feuille
   (min(92dvh, 820px), la même que .sheet-card), moins la place que prend le reste sous lui. */
.graded-sheet { --gs-slab-w: min(260px, (min(92dvh, 820px) - 470px) * .5876); display: grid; gap: 12px; }
.graded-sheet .gs-visual { width: var(--gs-slab-w); margin: 0 auto; }
/* The sheet scrolls, so it clips whatever leaves its box: a case turning under the pointer (perspective, rotateX and
   the spin) grows ~8% past its own edges and lost its top to the sheet's header. The padding is that room; the
   --gs-slab-w formulas above take its 2 x 20px out of the height they hand the case. */
.graded-sheet .gs-visual { box-sizing: content-box; padding: 20px 0; }
.graded-sheet .gs-visual .slab { max-width: 100%; }
.graded-sheet .gs-side { display: grid; gap: 12px; align-content: start; min-width: 0; }
.graded-sheet h2 { margin: 0; font-size: 18px; }
.gs-facts { list-style: none; margin: 0; padding: 0; }
.gs-facts li { display: flex; justify-content: space-between; gap: 12px; padding: 5px 0; border-bottom: 1px solid var(--line); font-size: 14px; }
.gs-facts span { color: var(--muted); }
.gs-facts b { font-variant-numeric: tabular-nums; }
.gs-held { margin: 0; font-weight: 700; }
.gs-side a.btn { text-decoration: none; }
/* « Lancer l'enchère » et « Annuler » sur une ligne : empilés ils coûtaient 75 px de hauteur, et le bouton
   d'envoi passait sous le pli dès que le formulaire s'ouvrait. */
.graded-sheet .sell { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.graded-sheet .sell > label, .graded-sheet .sell > .durations { grid-column: 1 / -1; }
/* The cross at the top already closes the sheet: the "Close" sheet() appends would cost 63 px of height.
   Not :last-child — sheet() appends the "continues below" hint after it. */
.sheet-body:has(.graded-sheet) > .close { display: none; }

@media (min-width: 860px) {
  .sheet-card:has(.graded-sheet) { width: min(860px, 100%); max-height: min(92dvh, 820px); }
  /* Le boîtier à gauche, les infos et la vente à droite : à côté du texte, il n'a plus qu'à tenir en hauteur. */
  .graded-sheet { --gs-slab-w: min(300px, (min(92dvh, 820px) - 120px) * .5876); grid-template-columns: var(--gs-slab-w) minmax(0, 1fr); align-items: start; gap: 24px; }
  .graded-sheet .gs-visual { position: sticky; top: 0; }
  .graded-sheet h2 { font-size: 22px; }
}

/* Là où le boîtier est trop petit pour lire la note — un lot du marché, une ligne de l'historique — la pastille la
   dit en mots. L'or du thème clair est orange : l'encre dessus est --on-gold, jamais du noir. */
.grade-pill {
  display: inline-block; padding: 2px 8px; border-radius: 999px;
  background: var(--gold-grad); color: var(--on-gold);
  font-size: 12px; font-weight: 700; white-space: nowrap;
}

/* The slab in place of the bare card on a graded lot's sheet: the card is in its slab and it stays there.
   Same width as the bare card it replaces, so the sheet keeps its two columns. */
.sheet-visual.cs-slab .slab { width: 100%; max-width: var(--card-w, 260px); }
