/* ===================================================================
   HOT BOARDS -- matchup.css  v1
   Matchup 1-pager: one 11x17 LANDSCAPE sheet per direction.
   Top half = Team A DEFENSE, bottom half = Team B OFFENSE, trenches
   facing each other across the line-of-scrimmage divider. Page 2 is
   always the reverse pairing.

   The page root is .pb-page.pb-mu -- it reuses print-offense.css's
   .pb-page fixed 1632x1056 box (and therefore the server PDF's
   existing landscape branch + per-page clamp) with zero backend
   changes. Everything inside uses its own .pbmu-* vocabulary so the
   print-board healers/self-test card scans never touch these cards.

   Quick-reference design (owner spec): big numbers + names, season /
   last-week / availability stats, game-status badge, blank ruled
   write space. NO auto-populated notes of any kind.
   =================================================================== */

/* ---------------- screen shell ---------------- */
/* The 84px of bottom room clears the always-on .pb-viewctl (styled in
   print-offense.css and reused verbatim here), which is fixed over the last
   ~66px of the viewport — without it the foot of the sheet can never be
   scrolled out from under the bar. Reset to 0 in @media print below. */
.mu-pad { padding: 14px 18px 84px; overflow: auto; }
.mu-blank {
  color: var(--t3, #8895aa); font-family: Archivo, sans-serif; font-size: 14px;
  padding: 60px 0; text-align: center;
}
.pbmu-pages { display: flex; flex-direction: column; align-items: flex-start; gap: 26px; }
/* The box is a pure sizer (JS sets width/height to the scaled visual size); the
   PAGE inside carries the transform. See _fitPages -- transforming the box too
   would double-scale it. @media print resets both, and print-offense.css's
   `.pb-page { transform: scale(.95) !important }` overrides the inline one. */
.pbmu-pagebox > .pb-page { transform-origin: top left; }

/* ---------------- toolbar (screen only) ---------------- */
.mu-toolbar {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  background: var(--s1, #11151c); border: 1px solid var(--b2, #2a2f3a);
  border-radius: 10px; padding: 10px 14px; margin: 0 0 14px; max-width: 1180px;
}
/* Toolbar buttons now reuse print-offense.css's .pb-ctrl-btn/.pb-print-btn/
   .pb-settings-* classes directly (same components as My Hotboard's toolbar,
   not a lookalike) -- see matchup.js _toolbar(). */

/* ---------------- page ---------------- */
.pb-page.pb-mu {
  display: flex; flex-direction: column; padding: 6px;
  --mufs: 1;   /* A-/A+ multiplier, set inline by matchupFont */
}
.pb-mu .pbmu-half { display: flex; gap: 6px; flex: 1 1 0; min-height: 0; }
.pb-mu .pbmu-side { flex: none; display: flex; min-height: 0; }

/* sidebar reuse: same shared component as the print board, but scoped ONLY to
   .pb-mu -- the shared 276px base rule (print-offense.css) stays untouched for
   Grid and Formation, which both also call _pbMkSidebarShared().
   200px rendered narrower than a card column (214px vs ~279px measured), and
   naively setting it to match today's column width doesn't work: the sidebar
   and the 5 columns share one row, so widening the sidebar narrows the columns,
   which moves the target. Solved as the two-variable system it actually is
   (page 1632px, 6px page padding, 6px half-gap, the sidebar's own 6px+6px
   padding + 2px right border, the 5-column row's 4x4px gaps) and confirmed
   live against the real stylesheet: 254.33px is the one value where both
   sides converge on the same rendered width instead of chasing each other. */
.pb-mu .pb-sidebar { width: 254.33px; border-right: 2px solid #111; }
.pb-mu .pb-sb-teamname { font-size: 18px; }
.pb-mu .pb-sb-record { font-size: 15px; }
.pb-mu .pb-sb-notes-area { min-height: 40px; font-size: 9.5px; line-height: 15px; }
.pb-mu .pb-sbc-notes { min-height: 56px; }
.pb-mu .pb-sb-co-nm { font-size: 15px; }
.pb-mu .pb-sb-co-bio { font-size: 10.5px; }
.pb-mu .pb-sb-co-note { font-size: 11px; }
.pb-mu .pb-sb-inj-nm { font-size: 10.5px; }

/* LOS divider between the halves */
.pbmu-los {
  flex: none; height: 18px; display: flex; align-items: center; gap: 10px; padding: 0 6px;
}
.pbmu-los .pbmu-los-cap { width: 44px; height: 5px; flex: none; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
.pbmu-los .pbmu-los-rule { flex: 1; border-top: 2px dashed #a9a395; }
.pbmu-los .pbmu-los-lbl {
  font-family: 'Oswald', 'Arial Narrow', 'DejaVu Sans Condensed', sans-serif; font-size: 9.5px; font-weight: 600; letter-spacing: .18em;
  color: #6b675d; white-space: nowrap; text-transform: uppercase;
  /* Team names + a week label (which isn't always a bare number -- a
     playoff round like "AFC Divisional Round" reads through uppercased
     as-is, no shortening) make this the one line on the whole sheet whose
     length isn't bounded by a fixed roster of short tokens. A flex item's
     default min-width is auto, which for nowrap text resolves to its own
     full content width -- meaning without min-width:0 here, this label
     can't actually shrink at all when the row runs tight; it just spills
     past its own box with no clipping boundary of its own, eventually
     hard-clipped by .pb-page's own overflow:hidden wherever that lands --
     a jagged, mid-character cut, not a deliberate one. min-width:0 lets it
     shrink like every other flexible element in the row; overflow:hidden +
     text-overflow:ellipsis makes that shrink a clean "…" instead, the
     same guard every other variable-length line on this sheet already
     has (.pbmu-line, .pbmu-namebio). */
  min-width: 0; overflow: hidden; text-overflow: ellipsis;
}
/* Wordmark in brass. Heavier and tighter than the descriptive label beside it
   so it reads as a MARK, not as more sheet metadata, at broadcast distance.
   flex:none inside the existing strip -- adds no height to the page box. */
.pbmu-los .pbmu-los-mark {
  flex: none; font-family: 'Saira Condensed', 'Oswald', 'Arial Narrow', 'DejaVu Sans Condensed', sans-serif;
  font-size: 10.5px; font-weight: 700; letter-spacing: .22em;
  color: #B68A4E; white-space: nowrap; text-transform: uppercase;
  -webkit-print-color-adjust: exact; print-color-adjust: exact;
}

/* ---------------- grid area ---------------- */
/* justify-content:space-between -- the three defense strips (155px each)
   never added up to the full stretched height of this container, so the
   D-line strip (last child) sat wherever its own fixed height landed
   instead of touching the LOS divider the way it was designed to, and the
   leftover room piled up as dead space below it instead of between the
   rows. This spreads that same leftover space out as growing gaps BETWEEN
   the three strips instead: secondary stays flush at the top, D-line lands
   flush at the bottom (touching the divider, matching the O-line strip
   directly across from it), and the two gaps between rows grow to fill
   whatever's left -- each strip's own small fixed margin is gone below,
   redundant now that this owns the spacing. Offense's own grid (OL strip +
   header row + skill columns, all flex:1) already fills this container on
   its own and is unaffected. */
.pbmu-grid { flex: 1; min-width: 0; display: flex; flex-direction: column; justify-content: space-between; min-height: 0; }
.pbmu-hdrs { flex: none; display: flex; gap: 4px; padding: 0 1px 2px; }
/* THE plated-box column-header style, shared by every position group on
   the sheet -- O-line, offense skill columns, and now every defense
   strip's own per-column header plus both reserve pockets' labels (see
   .pbmu-dl-res-lbl/.pbmu-lb-res-lbl below), all rendered with this SAME
   class instead of each row inventing its own header treatment. Used to
   be .pbmu-olhdr, OL-only; renamed once every other position group
   needed the identical box, so there's one declaration to keep in sync
   instead of several that could quietly drift apart from each other.
   flex:none is the right default for the overwhelming majority of uses
   (a header sitting as the first child inside its own fixed-width
   column) -- .pbmu-hdr below is the one exception, a SEPARATE header ROW
   that needs to distribute width across itself instead. */
.pbmu-colhdr {
  flex: none; text-align: center; font-family: 'Oswald', 'Arial Narrow', 'DejaVu Sans Condensed', sans-serif; font-weight: 600;
  font-size: calc(11px * var(--mufs)); letter-spacing: .14em; text-transform: uppercase;
  /* Flat black plate, same as roster-sheet's .rs-hdr -- no border, no
     per-team color. (A team-colored version of this shipped and got
     reverted; flat black across both sides is the direction that stuck.) */
  color: #fff; background: #111; border: none; padding: 1px 0;
  -webkit-print-color-adjust: exact; print-color-adjust: exact;
}
/* Offense skill row's header is a SEPARATE row (.pbmu-hdrs) sitting above
   .pbmu-cols, not nested inside each column the way every other position
   group's header is -- flex:1 here is what distributes it evenly across
   that row instead of collapsing to content width. Every visual property
   still comes from .pbmu-colhdr above (used together, see matchup.js). */
.pbmu-hdr { flex: 1; }
/* RESERVES label -- the one .pbmu-colhdr inverted from the rest: black text
   on white instead of white on black, with its own border since white on
   the page's own white doesn't read as a plate without one. Flags the
   reserve pocket as visually distinct from the real position columns
   beside it, same two classes matchup.js already renders together. */
.pbmu-colhdr.pbmu-dl-res-lbl, .pbmu-colhdr.pbmu-lb-res-lbl {
  color: #111; background: #fff; border: 1.4px solid #111;
}
.pbmu-rows { flex: 1; display: flex; flex-direction: column; gap: 4px; min-height: 0; }
.pbmu-row { display: flex; gap: 4px; min-height: 0; }
.pbmu-row > .pbmu-card { flex: 1 1 0; }
.pbmu-cols { flex: 1; display: flex; gap: 4px; min-height: 0; }
.pbmu-col { flex: 1 1 0; display: flex; flex-direction: column; gap: 4px; min-width: 0; min-height: 0; }
.pbmu-col > .pbmu-card { min-height: 0; }

/* row-weight tiers (defense rows / offense skill tiers) */
.pbmu-row.pbmu-t-bk { flex: 1.2 1 0; }
.pbmu-row.pbmu-t-st { flex: 1.6 1 0; }
.pbmu-col > .pbmu-t-st { flex: 2 1 0; }
.pbmu-col > .pbmu-t-bk { flex: 1.15 1 0; }
.pbmu-col > .pbmu-t-qbst { flex: 2.4 1 0; }
.pbmu-col > .pbmu-t-qbbk { flex: 1.2 1 0; }

/* OL strip (top of the offense half, trenches touching the divider) */
.pbmu-olstrip { flex: none; display: flex; gap: 4px; margin-bottom: 4px; }
.pbmu-olcol { flex: 1 1 0; display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.pbmu-olcol .pbmu-ol-st { height: calc(96px * var(--mufs)); flex: none; }
.pbmu-olcol .pbmu-ol-bk { height: calc(56px * var(--mufs)); flex: none; }
/* The wrapper's own display:flex (set inline in matchup.js) defaults to row, so
   its card child gets the cross-axis (height) stretch for free but NOT the
   main-axis (width) one -- confirmed live: the card shrank to its text content,
   40px wide, while every skill card next to it filled its column at 197px. This
   is the only rule that was missing; the wrapper's own height was already correct. */
.pbmu-ol-st > .pbmu-card, .pbmu-ol-bk > .pbmu-card { flex: 1 1 0; min-width: 0; }

/* Secondary strip: LCB, slot corner, SAF, SAF, RCB -- 5 columns, identical
   sizing to the D-line strip below it (both match OL's own row, 322px).
   This is the TOPMOST row of the defense half: secondary is the deepest
   position group on a real field, farthest from the LOS divider, opposite
   end from the D-line. Same starter-bottom/backup-top stacking as the
   D-line, and for the identical reason -- this row also sits above the
   divider, so "nearest the LOS" still means the bottom of a column. */
.pbmu-secstrip { flex: none; display: flex; gap: 4px; }
.pbmu-seccol { flex: 1 1 0; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.pbmu-sec-bk { height: calc(50px * var(--mufs)); flex: none; }
.pbmu-sec-st { height: calc(96px * var(--mufs)); flex: none; }
.pbmu-sec-bk > .pbmu-card, .pbmu-sec-st > .pbmu-card { flex: 1 1 0; min-width: 0; }

/* Linebacker strip: the SECOND row, between the secondary above and the
   D-line below -- same middle position they actually play. THREE columns
   (WLB/MLB/SLB) + one reserve pocket, same starter-bottom/backup-top
   stacking as the other two strips, assigned by depth-chart rank like
   everywhere else on this sheet (see _dlSeqFill in matchup.js) rather than
   by matching a player's own WLB/MLB/SLB tag.
   align-self:center, not flex:1 1 0 -- unlike the Secondary/D-line strips
   (5 elements, flex:1 1 0, stretched to the FULL row width), this strip
   only has 4 elements (reserve + 3 columns). Filling the same full row
   width with only 4 flex:1 1 0 items would divide it into FOUR shares
   instead of five, making each one WIDER than a Secondary/D-line column --
   exactly the opposite of matching them. (Predates the 3-column layout: a
   single flex:1 column with no siblings at all once ballooned to 1626px,
   the whole row, before that was caught.)
   322px below is a fallback only, for the brief pre-JS paint and as a sane
   default if JS ever fails -- matchup.js's _fitLbWidth measures a REAL
   Secondary/D-line column's rendered width after render and overrides it
   via inline style, since a hand-picked fixed number here can't stay
   correct on its own: it has to track the same page-width/sidebar/gap
   arithmetic that actually determines their width, and 322px had already
   drifted from that by the time this was caught. Centering the (now
   correctly-sized) group matches how the position actually lines up on a
   real field, same as the reserve pocket's own placement being a
   deliberate choice, not a default. */
.pbmu-lbstrip { flex: none; align-self: center; display: flex; gap: 4px; }
.pbmu-lbcol { flex: 0 0 322px; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.pbmu-lb-bk { height: calc(50px * var(--mufs)); flex: none; }
.pbmu-lb-st { height: calc(96px * var(--mufs)); flex: none; }
.pbmu-lb-bk > .pbmu-card, .pbmu-lb-st > .pbmu-card { flex: 1 1 0; min-width: 0; }
/* Mirrors .pbmu-dl-res exactly -- same label/cards-wrapper split, same 60px
   border-box cards, same 155px max-height cap (56+96+3 gap, this strip's own
   column height) so a deep ILB bench clips within its own cell instead of
   growing the whole .pbmu-lbstrip taller than the other two rows and
   shoving the D-line strip below it down the page -- this is the bug that
   made a real roster's page look broken (Seahawks-deep ILB bench rendered
   at uncapped full-card height, six reserves stacked past 400px in a 155px
   row). Width is the same JS-measured-fallback split as .pbmu-lbcol above --
   see that rule's own comment; _fitLbWidth treats this and .pbmu-lbcol
   identically. */
/* overflow:hidden on the OUTER wrapper (not just .pbmu-lb-res-cards below)
   -- the label just below has no width constraint of its own, so without
   this, "RESERVES" at whatever the real font stack actually measures could
   push past the fixed 322px and read as a wider pocket than its own 3
   sibling columns, even though .pbmu-lb-res-cards' own cards were already
   correctly clipped to 322px on their own. min-width:0 alone (kept as
   belt-and-suspenders) only stops the FLEX ITEM's own min-content size from
   growing the box -- it doesn't clip an already-oversized CHILD spilling
   past it, which is what overflow:hidden here actually does. */
.pbmu-lb-res { flex: 0 0 322px; display: flex; flex-direction: column; max-height: calc(155px * var(--mufs)); min-width: 0; overflow: hidden; }
/* Visual box comes from .pbmu-colhdr (matchup.js renders both classes
   together) -- this rule is now just the overflow guard "RESERVES" needs
   that a real position label never does: without a width constraint of
   its own, the word could measure wider than the pocket's fixed 322px
   and read as a wider column than its 3 sibling columns even though the
   cards below it were already correctly clipped. */
.pbmu-lb-res-lbl { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Stacked directly under each other -- no justify-content:space-between
   spreading them apart with growing gaps between cards. Each .pbmu-strip's
   own border-bottom is the only separator, same as roster-sheet's own
   reserve list. Leftover pocket height (if any) lands as dead space below
   the last card instead of being distributed as gaps between them. */
.pbmu-lb-res-cards { flex: 1 1 0; display: flex; flex-direction: column; min-height: 0; width: 100%; overflow: hidden; }
/* --resfs (set by matchup.js's _fitReserves, default 1 if that hasn't run
   yet) scales the card AND its own text together when 3+ reserves don't
   fit at full size -- see the shared comment block on .pbmu-dl-res-cards'
   own copy of these rules below for the full reasoning. */
.pbmu-lb-res-cards > .pbmu-card { box-sizing: border-box; height: calc(42px * var(--mufs) * var(--resfs, 1)); flex: none; width: 100%; min-width: 0; }

/* D-line strip -- mirrors the OL strip exactly (same 5-column shape, same
   starter/backup stacking, same uniform-width fix applied from the start this
   time), but sits at the BOTTOM of the defense half so it touches the LOS
   divider from above, directly across from the O-line. Column order left to
   right: EDGE, DT, DT, EDGE, reserve pocket.
   Vertical order is DELIBERATELY the reverse of OL's: backup markup renders
   FIRST (top) and starter markup SECOND (bottom), because the starter needs to
   be the card nearest the physical LOS line -- and for this row, "nearest the
   divider" means the BOTTOM of the column, not the top, since defense sits
   above the line while offense sits below it. Same rule as the row-level
   ordering (deepest bench at the outer edge, starters last, touching the
   divider), just applied one level deeper, inside a single column. */
.pbmu-dlstrip { flex: none; display: flex; gap: 4px; }
/* Back to flex:1 1 0 -- same width as everyone else, confirmed live against
   OL's own row (322px) two commits ago. The width-narrowing tried here in
   between was a misreading of "thinner" as narrower; the actual ask was
   shorter, i.e. height, reverted below instead. */
.pbmu-dlcol { flex: 1 1 0; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.pbmu-dl-bk { height: calc(50px * var(--mufs)); flex: none; }
.pbmu-dl-st { height: calc(96px * var(--mufs)); flex: none; }
.pbmu-dl-bk > .pbmu-card, .pbmu-dl-st > .pbmu-card { flex: 1 1 0; min-width: 0; }
/* Reserve pocket: same width as the core columns (see above), same total
   height too (stretched to match via the row's default align-items:stretch).
   Label and cards are TWO separate flex children, not siblings in one flex
   run -- see .pbmu-dl-res-cards below for why. max-height hard-caps the
   pocket at the core columns' own 155px (56+96+3 gap) regardless of how
   many reserves it holds -- without it, a deep bench stretches THIS row
   taller than the other two and pushes whichever strip comes after it
   down the page (this is what broke a real roster's page once: linebacker
   depth this same shape ballooned tall enough to shove the D-line strip
   below it off the printable page entirely). overflow:hidden on the cards
   wrapper below does the actual clipping once the cap is reached. */
/* overflow:hidden here too, same reason as .pbmu-lb-res's own copy of this
   rule: the label below has no width constraint of its own, so without
   this it could push past the pocket's real width and read as wider than
   its sibling EDGE/DT columns even though the cards themselves were
   already correctly clipped. */
.pbmu-dl-res { flex: 1 1 0; display: flex; flex-direction: column; max-height: calc(155px * var(--mufs)); min-width: 0; overflow: hidden; }
/* Visual box comes from .pbmu-colhdr (matchup.js renders both classes
   together, same as .pbmu-lb-res-lbl's own copy of this rule) -- this is
   now just the overflow guard "RESERVES" needs that a real position
   label never does: without a width constraint of its own, the word
   could measure wider than the pocket's own fixed width and read as a
   wider column than its sibling DT/EDGE columns even though the cards
   below it were already correctly clipped. */
.pbmu-dl-res-lbl { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Own nested flex column, separate from the label above it, so ITS OWN
   stacking doesn't also have to make room for the label. Cards stack
   directly underneath each other -- no justify-content:space-between
   spreading them apart -- with each .pbmu-strip's own border-bottom as the
   only separator, same as roster-sheet's own reserve list. Leftover pocket
   height (if any) lands as dead space below the last card. */
.pbmu-dl-res-cards { flex: 1 1 0; display: flex; flex-direction: column; min-height: 0; width: 100%; overflow: hidden; }
/* Pinned to a fixed height shorter than every other tier on the sheet
   (backup's own 50px included) -- these are 3rd-string-and-deeper, styled
   as a roster-sheet-style strip (.pbmu-strip below): number + name/bio,
   no stat line, so the box shouldn't cost more room than that.
   box-sizing:border-box explicitly, not left to the global print-only
   `* { box-sizing:border-box !important }` override -- without it the 1.2px
   border adds on top of the declared height (measured 2px taller than the
   declaration on screen -- established earlier on this same pocket, see
   commit history), so print would match the declared value exactly but the
   on-screen preview would run visibly taller. A pocket with enough reserves
   to exceed the pocket's own max-height (above) just clips at the bottom --
   the row itself no longer stretches to accommodate it, unlike before.
   --resfs SHRINKS that clip point instead of hitting it: matchup.js's
   _fitReserves measures whether N reserves fit at full (42px) size and, if
   not, sets --resfs on the wrapper to whatever ratio DOES fit -- inherited
   down into every scaled rule below (.pbmu-strip-n/.pbmu-fullname/
   .pbmu-namebio), so text shrinks proportionally with the box instead of
   just getting clipped inside a box that shrank out from under it. A
   genuinely deep bench still floors out (_fitReserves clamps at 0.55) and
   clips beyond that, same as before -- three reserves specifically (a
   normal EDGE+DT or ILB depth, not a rare edge case) is the shape this was
   built to fit cleanly. */
.pbmu-dl-res-cards > .pbmu-card { box-sizing: border-box; height: calc(42px * var(--mufs) * var(--resfs, 1)); flex: none; width: 100%; min-width: 0; }
/* Every reserve-pocket-scoped override that used to live here (.pbmu-strip-n,
   .pbmu-fullname[data-tier="res"], .pbmu-namebio, .pbmu-body's padding/gap)
   is gone -- each one now computes the exact same value from ITS OWN base
   rule above/below, since --resfs was added there directly instead of only
   at this reserve-scoped override. Two duplicate declarations of the same
   formula is how they'd have silently drifted apart the next time only one
   got edited; one declaration each, still correctly scoped by --resfs's own
   default (1, a no-op) everywhere it isn't explicitly set, is the same
   behavior with one source of truth. Unrestricted drag (_muCanSwap has no
   tier guard) is why this generalized: a reserve card can now land OUTSIDE
   these two pockets (e.g. dropped into a starter/backup wrapper elsewhere),
   and needed the exact same shrink-with-its-box treatment there too -- a
   wrapper-scoped override could never have reached that case; the base
   rules can. */

/* ---------------- card ---------------- */
.pbmu-card {
  position: relative; background: #fff; border: 1.2px solid #c9ccd2;
  display: flex; flex-direction: column; min-width: 0; overflow: hidden;
  -webkit-print-color-adjust: exact; print-color-adjust: exact;
}
/* Starter used to carry a near-black #1a1a1a border against everyone else's
   light #c9ccd2 -- both were already the SAME declared 1.2px weight, but the
   dark/light contrast read as a heavier outline regardless, the same
   inconsistency the 2px-vs-1.2px fix above was meant to remove in the first
   place. Tier is already unambiguous from position (bottom of the column
   for defense, top for O-line) and content (full GP/season/LW lines vs a
   short stat or nothing) without a third, competing cue on the border --
   so starter no longer overrides color either, not just width. */
.pbmu-card.pbmu-ghost { border-style: dashed; background: #fcfcfb; }
/* Reserve/deep-bench strip -- roster-sheet's .rs-strip look (see
   roster-sheet.css), not a shorter version of the plated starter/backup
   card above. No border-box, no team-color plate: just a number beside a
   name/bio stack, separated from the next reserve by a hairline rule. Row
   direction overrides the base rule's column; the base's position/overflow/
   print-color-adjust still apply unchanged. Last card in a pocket drops its
   own border-bottom below -- nothing follows it to separate from, so that
   copy of the rule was a dangling line under the group, not a divider. */
.pbmu-card.pbmu-strip {
  flex-direction: row; align-items: stretch; gap: calc(4px * var(--mufs) * var(--resfs, 1));
  background: none; border: none; border-bottom: 1.4px solid #c9c4b8;
  padding: calc(1px * var(--mufs) * var(--resfs, 1)) calc(3px * var(--mufs) * var(--resfs, 1));
}
.pbmu-dl-res-cards > .pbmu-card:last-child,
.pbmu-lb-res-cards > .pbmu-card:last-child { border-bottom: none; }
.pbmu-strip-n {
  flex: none; font-family: 'Oswald', 'Arial Narrow', 'DejaVu Sans Condensed', sans-serif; font-weight: 700;
  font-size: calc(15px * var(--mufs) * var(--resfs, 1)); min-width: calc(20px * var(--mufs) * var(--resfs, 1));
  color: #111; font-variant-numeric: tabular-nums; line-height: 1;
  display: flex; align-items: center; justify-content: flex-end;
}
.pbmu-strip-stack { display: flex; flex-direction: column; justify-content: center; flex: 1; min-width: 0; overflow: hidden; }
/* Smaller than the shared .pbmu-namebio base (starters/backups) -- a
   reserve's whole row is already the smallest tier on the sheet. */
.pbmu-strip-stack .pbmu-namebio { font-size: calc(7.5px * var(--mufs) * var(--resfs, 1)); }
/* Gameday-inactive: a hard, unambiguous strike -- NOT a fade.
   opacity:.45 renders as "faint" on paper, which is indistinguishable from a
   light print or low toner; the announcer cannot tell "ruled out" from "my
   printer is dying." A rule through the name is unmistakable in mono.
   Dropping the filter also matters for PRINT: filter/opacity force a card into
   its own raster layer, so headless Chrome can emit it as a bitmap while its
   neighbours stay vector -- the one visibly-soft card on an otherwise sharp sheet. */
.pbmu-card.pbmu-inactive { background: #f4f4f2; border-color: #9a958a; }
/* .pbmu-num is deliberately absent: its colours come from pbNumStyle() as an
   INLINE style, which a stylesheet rule cannot win against. The team plate
   stays true; the strike below carries the signal. */
.pbmu-card.pbmu-inactive .pbmu-namebio,
.pbmu-card.pbmu-inactive .pbmu-line { color: #6b6b66; }
.pbmu-card.pbmu-inactive .pbmu-fullname {
  color: #6b6b66;
  text-decoration: line-through;
  text-decoration-thickness: 1.5px;
  text-decoration-color: #c03020;
}
/* Trench tint -- same #f2f2f2 Formation already uses for this exact
   purpose ("OL / DL differentiator", formation.css) reused here rather
   than picked fresh, so the two sheets read the same way. Scoped to the
   two strips, not a specific tier or column, so it covers the D-line
   reserve pocket too (.pbmu-dl-res sits inside .pbmu-dlstrip) -- same
   position group, same tint. :not() excludes the two states that already
   carry their own background and outrank this one: a ghost/placeholder
   slot should still read as empty regardless of which strip it's in, and
   gameday-inactive is a status signal that shouldn't get diluted by a
   group-membership tint sharing the same visual channel. */
.pbmu-olstrip .pbmu-card:not(.pbmu-ghost):not(.pbmu-inactive),
.pbmu-dlstrip .pbmu-card:not(.pbmu-ghost):not(.pbmu-inactive) {
  background: #f2f2f2;
}

.pbmu-top { display: flex; align-items: stretch; flex: none; }
.pbmu-num {
  position: relative; flex: none; display: flex; align-items: center; justify-content: center;
  font-family: 'Oswald', 'Arial Narrow', 'DejaVu Sans Condensed', sans-serif; font-weight: 500; line-height: 1; padding: 2px 3px;
  min-width: calc(38px * var(--mufs) * var(--resfs, 1)); font-size: calc(22px * var(--mufs) * var(--resfs, 1));
  -webkit-print-color-adjust: exact; print-color-adjust: exact;
}
/* No starter-size bump -- every card's number is the same size now. Kept at
   the smaller/base value on purpose: it's what the majority of cards (every
   backup and reserve) already render at, so unifying UP to the old starter
   size would have shrunk nothing but risked overflow on the shallowest
   reserve slots; unifying DOWN touches only the starter row and nothing else. */
.pbmu-names { flex: 1; min-width: 0; padding: 1px 4px 1px 5px; display: flex; flex-direction: column; justify-content: center; overflow: hidden; }
/* One line, big, the card's single most prominent element -- replaces the
   old two-line first-name-small/last-name-bold stack, per a direct
   side-by-side comparison against a live Formation card (which already
   made this exact change). _fitFullNames (matchup.js) shrinks the
   font-size, not a scaleX() squeeze, if a name is too long to fit --
   condensing letterforms on something this prominent reads as squished,
   not compact. Tier-specific base size below: starters have the most
   .pbmu-top height to spend (96px cards), backups/reserves less, so each
   gets its own natural starting size rather than one value shrinking
   unnecessarily on the roomier tiers. */
.pbmu-fullname {
  font-family: 'Oswald', 'Arial Narrow', 'DejaVu Sans Condensed', sans-serif; font-weight: 700;
  color: #000; text-transform: uppercase; line-height: 1; white-space: nowrap; overflow: hidden;
  transform-origin: left center; display: block; max-width: 100%;
}
/* --resfs (default 1, a no-op) on every size/spacing rule below, not just
   the reserve-pocket-scoped block further down -- unrestricted drag-to-
   swap (_muCanSwap has no tier guard) can now put ANY tier's card in ANY
   slot, including a denser starter's card in a shorter backup/reserve
   box. Without this, that card's BOX shrinks (every wrapper's height is
   forced by the SLOT, not the card) while its TEXT stays full-size --
   guaranteed clipping/overlap in the one place overflow:hidden exists
   specifically to hide it. At --resfs:1 (every card that's still sitting
   in a slot sized for its own tier -- the overwhelming majority) this is
   a genuine no-op, computed identically to before. */
.pbmu-fullname[data-tier="st"]  { font-size: calc(20px * var(--mufs) * var(--resfs, 1)); }
.pbmu-fullname[data-tier="bk"]  { font-size: calc(15px * var(--mufs) * var(--resfs, 1)); }
.pbmu-fullname[data-tier="res"] { font-size: calc(13px * var(--mufs) * var(--resfs, 1)); }
/* Directly under the name -- height/weight/college/draft, the same bio
   line that used to live down in the stat body (reserves) or nowhere at
   all (starters/backups). Muted so it reads as identity/background
   context, not competing with the production stats below it. */
.pbmu-namebio {
  font-family: 'Oswald', 'Arial Narrow', 'DejaVu Sans Condensed', sans-serif; font-weight: 500;
  font-size: calc(8.5px * var(--mufs) * var(--resfs, 1)); line-height: 1.2; color: #6b6b66; margin-top: 1px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Game-status badge (O / D / Q / IR / NA), anchored to the CARD's top-right.
   It used to be a .pbmu-num child, which put it on top of the jersey numeral --
   the one defect on this sheet that could hand you a wrong number on air.
   Every dimension scales with --mufs: at 8.5px fixed it grew proportionally
   LARGER as the sheet zoomed out, which is backwards. */
.pbmu-badge {
  position: absolute; top: -1px; right: -1px; z-index: 2;
  min-width: calc(13px * var(--mufs)); height: calc(13px * var(--mufs));
  padding: 0 calc(2px * var(--mufs)); border-radius: 0 0 0 3px;
  font-family: 'Oswald', 'Arial Narrow', 'DejaVu Sans Condensed', sans-serif; font-weight: 700;
  font-size: calc(8.5px * var(--mufs)); line-height: calc(13px * var(--mufs));
  color: #fff; text-align: center;
  -webkit-print-color-adjust: exact; print-color-adjust: exact;
}
.pbmu-badge.out { background: #c03020; }
.pbmu-badge.d   { background: #d97a2e; }
.pbmu-badge.q   { background: #d4a12a; color: #241a02; }
.pbmu-badge.ir  { background: #5a5d63; }
.pbmu-badge.na  { background: #9a958a; }

.pbmu-body {
  flex: 1; min-height: 0; display: flex; flex-direction: column;
  padding: calc(1px * var(--mufs) * var(--resfs, 1)) calc(5px * var(--mufs) * var(--resfs, 1)) calc(3px * var(--mufs) * var(--resfs, 1));
  gap: calc(1px * var(--mufs) * var(--resfs, 1));
}
.pbmu-line {
  flex: none; font-family: 'Oswald', 'Arial Narrow', 'DejaVu Sans Condensed', sans-serif; font-weight: 500;
  font-size: calc(10.5px * var(--mufs) * var(--resfs, 1)); line-height: 1.3; color: #111;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pbmu-line .pbmu-sl {
  font-weight: 600; font-size: calc(7.5px * var(--mufs) * var(--resfs, 1)); color: #999;
  letter-spacing: .4px; margin-right: 3px;
}
.pbmu-line.pbmu-gp { color: #58402a; }
.pbmu-line.pbmu-lw { color: #2f3f56; }

/* Blank slack absorber -- starters. Used to be a ruled handwriting strip
   (repeating-linear-gradient); dropped per direct request -- the sheet
   reads cleaner with no guide lines inside any player box at all, same
   blank treatment .pbmu-air already gives backups. Still flex:1 1 auto: a
   starter card still needs something to soak up whatever the GP/season/LW
   lines don't use, it just no longer draws anything in that space. */
.pbmu-write { flex: 1 1 auto; min-height: calc(8px * var(--mufs) * var(--resfs, 1)); margin-top: calc(2px * var(--mufs) * var(--resfs, 1)); }
/* small unruled breathing space -- backups */
.pbmu-air { flex: 1 1 auto; min-height: calc(5px * var(--mufs) * var(--resfs, 1)); }

/* ---------------- drag-to-swap (screen only; see _muSetupDrag) ---------------- */
/* Same visual language as Formation's own .fm-mini-dragging/-dragover
   (formation.css) -- #C79A56 is that sheet's drag-highlight brass, reused
   here rather than picked fresh so a drag reads identically on both
   sheets. cursor:grab excludes .pbmu-ghost the same way Formation excludes
   .fm-mini-empty -- a placeholder card carries no data-mupid to drag. */
.pbmu-card[data-mupid] { cursor: grab; }
.pbmu-card.pbmu-dragging { opacity: .4; }
.pbmu-card.pbmu-dragover { outline: 2px dashed #C79A56; outline-offset: -2px; }

/* screen-only affordances stripped on print */
@media print {
  .mu-toolbar { display: none !important; }
  .mu-pad { padding: 0; overflow: visible; }
  .pbmu-pagebox { transform: none !important; margin: 0 !important; width: auto !important; height: auto !important; }
  .pbmu-pagebox > .pb-page { transform-origin: center center !important; }
  .pbmu-pages { gap: 0; }
  .pbmu-card[data-mupid] { cursor: default; }
}

/* keyboard focus — the toolbar's buttons had no visible focus indicator */
.mu-toolbar button:focus-visible {
  outline: 2px solid var(--border-focus, var(--heat-500, #B68A4E));
  outline-offset: 2px;
}
