/* Raw-card shell — the toploader a raw card is presented in.
   ---------------------------------------------------------------------------
   A raw card has no case. Shown bare next to a graded scan it reads as
   unfinished, because every other card on the site arrives inside something.
   This is that something: a rigid toploader with the condition printed into
   its bottom lip, where a real toploader has extra material anyway.

   It must NOT read as a graded slab. A PSA label is a white band across the
   TOP of the case and nothing here goes near that — the label lives in the
   bottom lip, and the frame is grey plastic rather than a cert holder. Same
   line the consignment cert-blurring already holds.

   Sizing is proportional, not fixed. The padding is a percentage of the
   shell's own width, so the same component works at 205px in a Just Pulled
   tile and at 240px in the reveal without a second set of numbers. Only the
   corner radius and the lip's type are set per surface, at the bottom.

   The shell WRAPS the card's existing container rather than becoming it. In
   the reveal that container is .po-card-face, which the pack-tear handoff
   measures to scale the flight card into — putting padding on it directly
   would make the handoff scale the card up to the shell's outer size and land
   it oversized. Wrapping leaves that rect exactly as it was. */

.rawshell {
    --rs-r: 13px;                 /* outer corner; per-surface below */
    --rs-pad: 8.6%;               /* frame, as a share of the shell's width */
    position: relative;
    display: inline-block;
    max-width: 100%;
    padding: var(--rs-pad) var(--rs-pad) 0;
    border-radius: var(--rs-r);
    line-height: 0;
    /* Opaque plastic UNDER the sheen. With only the translucent wash, every
       pixel between the inset highlight and the card was whatever sat behind
       the shell — on a dark page that is black, and it read as the card
       floating over a hole rather than sitting in a holder. */
    background:
        linear-gradient(145deg,
            rgba(255,255,255,0.16) 0%, rgba(255,255,255,0.055) 40%,
            rgba(255,255,255,0.035) 60%, rgba(255,255,255,0.13) 100%),
        linear-gradient(160deg, #343842 0%, #272b33 45%, #1d2026 100%);
    box-shadow:
        inset 0 0 0 2px rgba(255,255,255,0.30),
        inset 0 2px 0 rgba(255,255,255,0.42),
        inset 0 -1px 0 rgba(255,255,255,0.16),
        0 0 0 1.5px rgba(0,0,0,0.6),
        0 2px 0 rgba(255,255,255,0.05);
}

/* Specular streak — the thing that actually reads as rigid plastic rather
   than a border. Painted UNDER the card (z-index 0 against the children's 1),
   so the glare crosses the frame and the lip and stops at the card window
   instead of washing over the art. Masking it into a frame-shaped ring would
   have to be told where the card window is and would break every time the
   card's height or the frame's padding changed; stacking order cannot drift. */
.rawshell::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
    border-radius: var(--rs-r);
    background: linear-gradient(112deg,
        transparent 28%, rgba(255,255,255,0.30) 44%,
        rgba(255,255,255,0.09) 53%, transparent 66%);
    pointer-events: none;
}

.rawshell > * { position: relative; z-index: 1; }

/* The card, seated into the plastic — a hairline dark edge and a small drop
   shadow, so the join reads as a card under a holder rather than a sticker
   laid on top of one. */
.rawshell > :not(.rawshell-lip) {
    box-shadow: 0 0 0 1px rgba(0,0,0,0.5), 0 1px 7px rgba(0,0,0,0.55);
}

/* Bottom lip — the label. Deeper than the side walls, which is true of a real
   toploader and is what gives the label somewhere to live. Two rows: the card
   on the left, what we know about this copy on the right. The name reserves
   two lines whether it needs them or not, so a row of holders stays level and
   the frame doesn't change height depending on which card you pulled. */
/* Bare lip: the holder's bottom, with no label in it. Padding rather than a
   height, because a percentage padding resolves against the WIDTH — so the lip
   stays in proportion at every size the shell is used at, which a percentage
   height (resolved against the parent's height) would not. */
.rawshell-lip-bare { padding: 13% 0 0; }

.rawshell-lip {
    --rs-fs: 13px;
    padding: 6.2% 1.4% 8%;
    line-height: 1;
    text-align: left;
}
.rs-r1, .rs-r2 {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
}
.rs-r2 { margin-top: 4px; }
.rs-name {
    font-weight: 800;
    font-size: var(--rs-fs);
    line-height: 1.22;
    letter-spacing: -0.005em;
    color: rgba(255,255,255,0.93);
    min-height: 2.44em;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.rs-set {
    min-width: 0;
    font-size: calc(var(--rs-fs) * 0.71);
    line-height: 1.2;
    color: rgba(255,255,255,0.40);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.rawshell-cond, .rs-cond {
    flex: none;
    font-weight: 800;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    font-size: calc(var(--rs-fs) * 0.85);
    /* Fixed, NOT rgb(var(--glow-rgb)). The reveal sets --glow-rgb to the pull's
       tier energy and the cinematic sets nothing, so the same label came out
       amber on the rip and purple on the decision screen. Worse than
       inconsistent: a tier-coloured condition reads as a rarity signal, when
       what it actually says is that the sleeve is clean. It's printed on the
       holder, so it's the same colour on every card. */
    color: #f59e0b;
}
.rs-sku {
    flex: none;
    font: 700 calc(var(--rs-fs) * 0.72)/1 ui-monospace, SFMono-Regular, Menlo, monospace;
    letter-spacing: 0.03em;
    color: rgba(255,255,255,0.42);
}

/* ── per-surface ─────────────────────────────────────────────────────────── */

/* Reveal. The shell sits INSIDE .po-card-face rather than around it, because
   that element is what the pack-tear hand-off measures at BOTH ends — the flip
   front it leaves and the slot it lands in. If the shell were a wrapper, the
   two ends would be measuring different shapes (holder vs bare card) and the
   card would land at the wrong size. Inside, every measurement is the same
   thing: a card in a toploader. The face keeps its own tier glow and pulse, so
   the halo lights the holder. */
.po-card-face > .rawshell {
    --rs-r: 14px;
    display: block;
    width: 100%;
}
.po-card-face > .rawshell > img { width: 100%; height: auto; display: block; }

/* ── surfaces shaped for a graded slab ───────────────────────────────────────
   Several card boxes on the site are pinned to a PSA slab scan's proportions
   (7/12 = 0.583, or the rip engine's 277x470 = 0.589) and fill them with
   object-fit:cover. That was right when every card came in a case. A raw card
   is 2.5x3.5 = 0.714, so cover crops ~18% off its sides — its own border and
   part of the art — which is exactly what it looked like. These put the box
   back to the card's shape wherever a raw card can appear. */

/* Decision grid — session summary and /my-pulls. */
.ss-card[data-raw="1"] .ss-card-slab,
[data-celebrate] .ss-card[data-raw="1"] .ss-card-slab { aspect-ratio: 5 / 7; }
[data-celebrate] .ss-card[data-raw="1"] .ss-card-slab .ss-flip-face { object-fit: contain; }

/* Multi-pack session: the card sitting under the sealed pack. The reveal's own
   faces already override to aspect-ratio:auto + contain, so only this one is
   still carrying the slab shape. */
[data-raw="1"] .sr-card-shape { aspect-ratio: 5 / 7; }

/* Grid tiles elsewhere (.card-img) crop with object-position:center 65%, which
   is deliberate for a slab — it pushes the PSA label out of frame. On a raw
   card there is no label to lose, so that same crop eats the card's name. */
.is-raw .card-img, .card-img.is-raw {
    aspect-ratio: 5 / 7;
    object-fit: contain;
    object-position: center;
}

/* ── the rip card ───────────────────────────────────────────────────────────
   The toploader is part of the CARD, not a wrapper around wherever the card
   happens to be — so it has to survive the hand-off, where the tear engine's
   card element is re-parented out of .pt-root and into the reveal slot
   (_homeFlightCard: slot.appendChild(ptCard)). That move is why this lives
   here and not in pack-tear.js's injected stylesheet: once the card lands, a
   run of `#stage-result .po-card-face.po-slot-hosts-flight ...` rules take it
   over, and an injected rule cannot out-specify an id. Each block below is
   written twice for that reason — once for the flight, once, louder, for the
   landing. They must stay identical. */

.pt-card.pt-raw .pt-face,
#stage-result .po-card-face.po-slot-hosts-flight .pt-card.pt-raw .pt-face {
    padding: 8.6% 8.6% 0;
    display: block;
    background:
        linear-gradient(145deg, rgba(255,255,255,0.16) 0%, rgba(255,255,255,0.055) 40%,
            rgba(255,255,255,0.035) 60%, rgba(255,255,255,0.13) 100%),
        linear-gradient(160deg, #343842 0%, #272b33 45%, #1d2026 100%);
    box-shadow:
        inset 0 0 0 2px rgba(255,255,255,0.30),
        inset 0 2px 0 rgba(255,255,255,0.42),
        inset 0 -1px 0 rgba(255,255,255,0.16),
        0 0 0 1.5px rgba(0,0,0,0.6),
        0 0 46px var(--pt-accent-70, transparent),
        0 0 116px var(--pt-accent-40, transparent);
}

/* The scan sits INSIDE the holder, so it must not be stretched to fill the
   face. pack-opening.css pins the landed card's picture to width/height 100%
   + object-fit:cover on purpose — that was right when the image WAS the whole
   face; here it fills the plastic and crops the card. */
.pt-card.pt-raw .pt-face img,
#stage-result .po-card-face.po-slot-hosts-flight .pt-card.pt-raw .pt-face img {
    width: 100%;
    height: auto;
    max-height: none;
    object-fit: contain;
    border-radius: 6px;
    background: none;
    box-shadow: 0 0 0 1px rgba(0,0,0,0.5), 0 1px 7px rgba(0,0,0,0.55);
}

/* The slot's OWN holder, while a flight card is sitting in it. It stays in the
   DOM because it is what gives the slot its height — the info column's layout
   is measured against that — but it must not paint, or the card is drawn twice,
   slightly out of register, with two lips. pack-opening.css already does this
   for the bare `> img` strut; the shell made that image a grandchild, so the
   rule stopped reaching it and the ghost came back. */
#stage-result .po-card-face.po-slot-hosts-flight > .rawshell {
    visibility: hidden;
}

/* Mobile, decision screen. The width cap that keeps the card from filling a
   phone is written as `#stage-result .po-card-face > img` — DIRECT child, and
   deliberately so: as a descendant selector its !important declarations also
   hit .pt-face img on the landed flight card and collapsed its picture in one
   frame (see the note on that rule in pack-opening.css). The holder makes the
   image a GRANDCHILD, so the cap stopped reaching it and the card went
   full-bleed.

   Cap the FACE, not the holder inside it. .po-card-face is what the hand-off
   measures to scale the flight card into the slot, so capping only the holder
   would leave the slot full-width and the landed card would go full-bleed
   again a beat later. Same number as the graded cap, so a raw pull takes the
   same footprint on screen as a slab — the card inside ends up a little
   smaller than a slab scan, because the holder's frame and label are part of
   that footprint. The cinematic sizes itself and is not touched. */
@media (max-width: 900px) {
    #stage-result .po-card-face.po-raw {
        width: min(49.5vw, 215px);
        max-width: 100%;
        margin-left: auto;
        margin-right: auto;
    }
}
