/* SNS canonical stylesheet 5/5 — UTILITIES. Atomic composition helpers, loads
   LAST so a utility intentionally wins over a component. Use these to compose
   pages out of canonical components instead of writing per-page CSS.
   DESIGN_SYSTEM_RESET_2026-05-31 §D. */
@layer utilities {
  .u-stack   { display: flex; flex-direction: column; gap: var(--space-fluid-sm, .75rem); }
  .u-cluster { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-fluid-sm, .75rem); }
  .u-center  { text-align: center; }
  .u-mt-lg   { margin-top: var(--space-fluid-lg, 2rem); }
  .u-fill    { width: 100%; }
  .u-hidden  { display: none !important; }
  @media (max-width: 880px) { .u-hide-mobile { display: none !important; } }

  /* Wide-monitor content centering (DESIGN_SYSTEM_RESET §B fix, proof).
     The content column caps at --content-max and CENTERS in the track left by the
     sidebar, so wide screens get balanced gutters (graphic-designer fill) instead of
     a left-anchored block with a lopsided right gap. In full rollout this lives in
     @layer base alongside the grid; here in utilities for the single-page proof. */
  .app > .content, .app .content { justify-self: center; }
}

/* ── Dashboard TOP FANTASY PERFORMERS — row alignment (Pat 2026-07-02) ─────────
   .perf-card is a 5-row grid that defaulted to align-content:stretch, so the
   leftover vertical height was distributed equally across every row. Because each
   card's text wraps to a different number of lines, the per-row stretch differed
   card-to-card and the photo/name/stat rows landed at different Y → ragged,
   "photos don't line up" (worst on the Vanderbilt/PAVIA card, whose short content
   left the most leftover to distribute). Fix, verified spread=0 on every row at
   390 + 1440:
     1. align-content:start — leftover collapses to a single bottom gap instead
        of being sprayed between rows, so a card's own content length no longer
        shifts its rows.
     2. pin line-height + reserve a UNIFORM box on NAME and SCHOOL so those
        rows are the same height on every card. (2026-07-22, Pat "tighten the
        dead space": was a 2-line/2.4em reservation from when these rows could
        wrap — perf-polish.js has since force-one-lined both via fitOneLine
        nowrap+shrink, so the second reserved line was pure dead space. Now a
        1-line/1.2em reservation; alignment guarantee unchanged.)
     3. force the "PPG" unit onto its own line (block) so the PPG row is always
        2 lines — otherwise it wraps by luck of card width and shifts TOTAL.
   Lives unlayered + after components.css (the deployed, un-main'd perf-card
   source) so it wins the cascade. */
.perf-card{align-content:start !important;}
.perf-card .perf-name{line-height:1.2 !important;min-height:1.2em !important;}
.perf-card .perf-school{line-height:1.2 !important;min-height:1.2em !important;}
.perf-card .perf-ppg .perf-unit{display:block !important;}

/* ── Dashboard TOP FANTASY PERFORMERS — avatar to /players spec (Pat 2026-07-02)
   Must match the /players tile EXACTLY:
     • 60px circle, object-fit:cover, background WHITE
     • object-position 50% 50% (CENTERED crop — /players value; the shipped
       perf-avatar cropped 50% 0% / "center top", which read as off-centre)
     • 2px solid #111 inner border  +  2px WHITE ring (box-shadow, = the
       .pl-card-img-wrap::before white disc: 2px of white just outside the border)
     • no-headshot → SNS shield, contained-on-white (--logo, via perf-polish.js)
   These selectors deliberately out-specify (and match, then win on source order)
   the treatment shipped in components.css:
     html[data-route="/"] .perf-card.is-school-colored img.slot-img.perf-avatar
     { border:none !important; object-position:center top }
   which otherwise strips the border and top-crops the photo. `body` in the chain
   guarantees we exceed its (0,5,2) specificity. */
html[data-route="/"] body .perf-card.is-school-colored picture{
  display:block !important;line-height:0 !important;position:relative !important;
  width:60px !important;height:60px !important;
  margin:4px auto 2px !important;overflow:visible !important;
}
/* ring is drawn by box-shadow on the img, not the wrapper — kill any earlier disc */
html[data-route="/"] body .perf-card.is-school-colored picture::before{ content:none !important; }
html[data-route="/"] body .perf-card.is-school-colored img.slot-img.perf-avatar{
  width:60px !important;height:60px !important;min-width:60px;aspect-ratio:1/1;
  border-radius:50% !important;object-fit:cover !important;object-position:50% 50% !important;
  background:#FFFFFF !important;
  border:2px solid #111 !important;
  box-shadow:0 0 0 2px #FFFFFF !important;
  -webkit-mask-image:none !important;mask-image:none !important;filter:none !important;
  margin:0 auto !important;display:block !important;
}
html[data-route="/"] body .perf-card.is-school-colored img.slot-img.perf-avatar.perf-avatar--logo{
  object-fit:contain !important;padding:6px !important;background:#FFFFFF !important;
}
