/* ============================================================================
   SNS shared quick-look card — D-EXPCARD-0716 §1 (Q-EXP-1, 2026-07-16)
   ----------------------------------------------------------------------------
   The ONE sitewide drill-down/quick-look standard. Structure:
     .exp-scrim > .exp-card > (.exp-close, [.exp-head], .exp-body, [.exp-actions])
   Loaded per-route via explicit <link> on opt-in routes (NOT chrome-injected).
   Deliberately UNLAYERED: legacy exp-* rules live inside @layer components in
   core.css (dashboard, pre-extraction); unlayered rules win the cascade, so
   every structural property the legacy rules set is restated here.
   Sizes/breakpoint extracted from PR #2632 (merged main). Scrim, ✕≥44px,
   64px head, gray border per D-EXPCARD-0716 §1.
   ========================================================================== */

/* --- Scrim: full viewport incl. under the bottom tab bar; card centered --- */
.exp-scrim{
  position:fixed;
  inset:0;
  z-index:2000; /* above chrome: sidebar/tabbar <100, More sheet 1200 */
  background:rgba(0,0,0,.6);
  -webkit-backdrop-filter:blur(4px);
  backdrop-filter:blur(4px);
  display:flex;
  align-items:center;
  justify-content:center;
  opacity:0;
  transition:opacity .22s cubic-bezier(0.16,1,0.3,1);
}
.exp-scrim.is-open{opacity:1}

/* --- Card (restates every property the legacy @layer .exp-card sets) ------ */
.exp-scrim .exp-card{
  position:relative;
  left:auto;
  top:auto;
  margin:0;
  z-index:auto;
  display:flex;
  flex-direction:column;
  gap:14px;
  width:min(760px,92vw);
  max-width:100%;
  max-height:86vh;
  overflow:hidden;               /* .exp-body is the ONLY scroll region */
  padding:28px;
  background:var(--bg-surface,#0A0A0A);
  border:1px solid var(--gray-border,#2A2A2A);
  border-radius:12px;
  box-shadow:0 16px 56px rgba(0,0,0,.75);
  pointer-events:auto;
  will-change:transform,opacity;
  /* fade+scale ~0.22s per spec */
  transform:scale(.96);
  opacity:0;
  transition:transform .22s cubic-bezier(0.16,1,0.3,1),opacity .22s cubic-bezier(0.16,1,0.3,1);
}
.exp-scrim.is-open .exp-card{transform:none;opacity:1}

/* Breakpoint flip per PR #2632 (880/881) */
@media (max-width:880px){
  .exp-scrim .exp-card{
    width:min(92vw,420px);
    max-height:78dvh;
    border-radius:16px;
    padding:24px 18px 18px;
  }
}

/* --- Close: >=44x44 tap target, pinned to the card (never scrolls) -------- */
.exp-scrim .exp-close{
  position:absolute;
  top:8px;
  right:8px;
  z-index:3;
  width:44px;
  height:44px;
  min-width:44px;
  min-height:44px;
  padding:0;
  display:flex;
  align-items:center;
  justify-content:center;
  background:rgba(255,0,0,.15);
  border:1px solid rgba(255,0,0,.5);
  border-radius:8px;
  color:var(--white-bright,#F5F5F5);
  cursor:pointer;
  font-size:18px;
  line-height:1;
  transition:background .2s ease,transform .15s ease;
}
.exp-scrim .exp-close:hover{background:rgba(255,0,0,.35);transform:scale(1.06)}
.exp-scrim .exp-close:active{transform:scale(.94)}
.exp-scrim .exp-close:focus-visible{outline:2px solid var(--red-bright,#FF3B30);outline-offset:2px}

/* --- Head: non-scrolling; 64px round headshot (shield onerror fallback) --- */
.exp-scrim .exp-head{
  flex:0 0 auto;
  display:flex;
  align-items:center;
  gap:14px;
  min-width:0;
  padding-right:52px; /* clear the pinned ✕ */
}
.exp-scrim .exp-head .exp-headshot{
  width:64px;
  height:64px;
  flex:0 0 64px;
  border-radius:50%;
  /* Tile crop (2026-07-30, Pat): cover + center-top, same framing as the
     small tile avatars — the quick-look is the tile scaled up. */
  object-fit:cover;
  object-position:center top;
  border:2px solid var(--red-primary,#FF1A1A);
  background:var(--black-soft,#111111);
  box-shadow:none;
}
.exp-scrim .exp-head .exp-headline{display:flex;flex-direction:column;gap:4px;min-width:0;flex:1 1 auto}
.exp-scrim .exp-head .exp-name{
  font-family:var(--f-display,"Graduate","Oswald",sans-serif);
  font-size:24px;
  line-height:1.1;
  letter-spacing:.04em;
  margin:0;
  color:var(--text-primary,#F5F5F5);
  text-align:left;
}
.exp-scrim .exp-head .exp-meta{
  font-family:var(--f-mono,ui-monospace,monospace);
  font-size:14px;
  color:var(--text-muted,#C2C2C2);
  margin:0;
  letter-spacing:.08em;
  display:flex;
  align-items:center;
  flex-wrap:wrap;
  gap:8px;
}

/* --- Body: the ONLY scroll region ----------------------------------------- */
.exp-scrim .exp-body{
  flex:1 1 auto;
  min-height:0;
  overflow-y:auto;
  -webkit-overflow-scrolling:touch;
  overscroll-behavior:contain;
}

/* --- Actions: <=3 context buttons; 1-col <=480px (pl-modal precedent) ----- */
.exp-scrim .exp-actions{
  flex:0 0 auto;
  display:grid;
  grid-template-columns:repeat(auto-fit,minmax(0,1fr));
  gap:10px;
  margin-top:4px;
}
@media (max-width:480px){
  .exp-scrim .exp-actions{grid-template-columns:1fr}
}

/* --- School-colour treatment (was html[data-route="/"]-scoped in route.css) --
   Any route that adds .is-school-colored + --team to the card gets the tile
   look: school colour up top ramping to black by the stat grid, and the TILE
   avatar treatment on the headshot — photo on WHITE, thin black inner ring,
   white outer ring (replaces core.css's red ring/glow). Unlayered, so it
   outranks the legacy @layer .exp-headshot rule. Shared by the dashboard
   quick-look and the /players quick-look. */
.exp-scrim .exp-card.is-school-colored{
  background:linear-gradient(180deg,
    var(--team) 0%,
    color-mix(in srgb,var(--team) 42%,#000000) 44%,
    #000000 100%);
  border-color:rgba(255,255,255,.22);
}
/* On school-coloured cards the avatar keeps the same tile treatment, just a
   neutral ring (the white-circle-on-white treatment made the head look tiny
   and floating — retired 2026-07-30, Pat). */
.exp-scrim .exp-card.is-school-colored .exp-headshot{
  background:linear-gradient(135deg,var(--bg-surface-3,#1A1A1A),var(--black-card,#0A0A0A));
  border:2px solid rgba(255,255,255,.35);
  box-shadow:none;
  filter:drop-shadow(0 4px 12px rgba(0,0,0,.35));
}
/* light school colours (e.g. UNC blue) sit behind the name — same legibility
   shadow the tiles use */
.exp-scrim .exp-card.is-school-colored .exp-name,
.exp-scrim .exp-card.is-school-colored .exp-meta,
.exp-scrim .exp-card.is-school-colored .exp-school{
  text-shadow:0 1px 3px rgba(0,0,0,.6);
}
/* A school logo standing in for a missing headshot is contained, not cropped,
   and skips the photo fade (a faded logo reads as broken). */
.exp-scrim .exp-card .exp-headshot--logo{
  object-fit:contain;
  padding:12px;
  -webkit-mask-image:none;
  mask-image:none;
}

/* --- Legacy .exp-top head (dashboard markup) inside the shared shell -------- */
.exp-scrim .exp-body > .exp-top{padding-right:52px} /* clear the pinned ✕ */
/* Headshot framing (2026-07-30, Pat): the quick-look avatar is the TILE
   avatar scaled up — same crop, same soft radial fade — so opening a tile
   reads as the small circle growing, not a different treatment. The earlier
   contain-with-inset pass (7/27, re-padded 7/30) shrank the photo to fit its
   whole frame inside the ring, which left the head tiny and floating in an
   oversized circle. Tile rules mirrored from route.css .perf-avatar/.hw-avatar:
   cover + center-top (fills the circle edge-to-edge; the side-crop is the
   tile's own framing) + the radial fade that melts the hard crop into the
   card. */
.exp-scrim .exp-card .exp-top > .exp-headshot{
  object-fit:cover;
  object-position:center top;
  padding:0;
  border:2px solid rgba(255,45,45,.35);
  background:linear-gradient(135deg,var(--bg-surface-3,#1A1A1A),var(--black-card,#0A0A0A));
  box-shadow:none;
  -webkit-mask-image:radial-gradient(ellipse at center,black 55%,transparent 95%);
  mask-image:radial-gradient(ellipse at center,black 55%,transparent 95%);
  filter:drop-shadow(0 4px 12px rgba(255,26,26,.25));
}
.exp-scrim .exp-meta a.exp-school{color:inherit;text-decoration:underline;text-underline-offset:3px}
.exp-scrim .exp-meta a.exp-school:hover{color:var(--white-bright,#F5F5F5)}

/* Action row appended as a card-level footer (outside the scrolling body). */
.exp-scrim .exp-card > .exp-actions-pinned{flex:0 0 auto;margin-top:4px}

/* Eyebrow above a secondary stat block ("2026 PROJECTION"). */
.exp-scrim .exp-eyebrow{
  font-family:var(--f-mono,ui-monospace,monospace);
  font-size:14px;
  letter-spacing:.16em;
  text-transform:uppercase;
  color:var(--text-faint,#8A8A8A);
  margin:16px 0 -2px;
}
/* Stat row that carries 1-3 tiles — auto-fit so it never leaves a hole the way
   the fixed 4-col .exp-stats-4 grid would. */
.exp-scrim .exp-stats-4.exp-stats-auto{
  grid-template-columns:repeat(auto-fit,minmax(120px,1fr));
}

/* --- Stat-tile gloss ------------------------------------------------------- */
/* FPPG / VOR / EXP ADP / TIER are fantasy jargon. The tile has room to say
   what the number means, so it does rather than assume the reader knows. */
.exp-scrim .exp-stat-hint{
  font-family:var(--f-body,"Inter",system-ui,sans-serif);
  font-size:11px;
  line-height:1.25;
  letter-spacing:.01em;
  text-transform:none;
  color:var(--text-faint,#8A8A8A);
  margin-top:3px;
}
/* On a school-coloured card the tile sits on the team hue, where the faint
   grey drops below readable contrast. */
.exp-scrim .exp-card.is-school-colored .exp-stat-hint{color:rgba(255,255,255,.72)}

/* Identity detail (class, hometown) promoted into the header line. */
.exp-scrim .exp-meta .exp-idmeta{
  font-family:var(--f-body,"Inter",system-ui,sans-serif);
  opacity:.75;
}
/* Separator between run-on stat values in a season row. */
.exp-scrim .exp-form .exp-sep{font-style:normal;opacity:.4;padding:0 2px}

/* --- Game-by-game strip ---------------------------------------------------- */
.exp-scrim .pl-gs-hdr{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap}
.exp-scrim .pl-gs-legend{
  font-family:var(--f-body,"Inter",system-ui,sans-serif);
  font-size:11px;letter-spacing:0;text-transform:none;
  color:var(--text-faint,#8A8A8A);
}
.exp-scrim .exp-card.is-school-colored .pl-gs-legend{color:rgba(255,255,255,.72)}
/* Spans the full card width; deliberately short so it reads as a summary
   strip rather than taking over the card. */
.exp-scrim .pl-gs{position:relative;width:100%;height:78px;margin-top:8px}
/* The plot box = the strip minus the 14px week-label gutter, so a bar at N%
   and the average baseline at N% land on the same pixel row. */
.exp-scrim .pl-gs-plot{position:absolute;left:0;right:0;top:0;bottom:14px;pointer-events:none}
.exp-scrim .pl-gs-cols{position:absolute;inset:0;display:flex;align-items:flex-end;gap:3px}
.exp-scrim .pl-gs-col{
  flex:1 1 0;min-width:0;height:100%;
  display:flex;flex-direction:column;justify-content:flex-end;align-items:stretch;
}
.exp-scrim .pl-gs-barwrap{flex:1 1 auto;min-height:0;display:flex;align-items:flex-end}
/* D-GREEN1: --green-positive is the one sanctioned positive token and
   --red-bright its negative counterpart. Beating your own average is exactly
   the "positive" case that decision reserves it for. */
.exp-scrim .pl-gs-bar{
  display:block;width:100%;
  border-radius:2px 2px 0 0;
  background:var(--red-bright,#FF3B30);
  opacity:.55;
  transition:opacity .15s ease;
}
.exp-scrim .pl-gs-bar.is-over{background:var(--green-positive,#3DBA6E);opacity:.85}
.exp-scrim .pl-gs-bar.is-best{opacity:1}
.exp-scrim .pl-gs-col:hover .pl-gs-bar{opacity:1}
.exp-scrim .pl-gs-wk{
  flex:0 0 14px;line-height:14px;text-align:center;
  font-family:var(--f-mono,ui-monospace,monospace);font-size:9px;
  color:var(--text-faint,#8A8A8A);overflow:hidden;
}
.exp-scrim .exp-card.is-school-colored .pl-gs-wk{color:rgba(255,255,255,.6)}
.exp-scrim .pl-gs-base{
  position:absolute;left:0;right:0;height:0;
  border-top:1px dashed rgba(255,255,255,.4);
  pointer-events:none;
}

/* --- Scroll-lock while open ------------------------------------------------ */
body.exp-open{overflow:hidden}

/* --- Reduced motion -------------------------------------------------------- */
@media (prefers-reduced-motion:reduce){
  .exp-scrim,
  .exp-scrim .exp-card,
  .exp-scrim .exp-close{transition:none}
  .exp-scrim .exp-card{transform:none}
}
