/* public/league.css — page-scoped CSS for the public league page (public/league.html).

   Why this file exists (17-21 deviation, documented in 17-21-SUMMARY.md): league.html's own
   acceptance criteria require ZERO <style> blocks and ZERO raw hex literals in the page itself (a
   "compose only" contract matching chat.html/calendar.html), and the waves that built it could not
   edit the shared public/styles.css. A page-scoped stylesheet satisfies both at once: league.html
   stays <style>-free and hex-free, styles.css stays untouched. Everything below is written in
   tokens only (no raw hex, and no keyframe block of its own) so the same rules hold on the light page and
   under the dark ?tv=1 board, where body.light's paper overrides simply do not apply.

   260917-flx: the Moneyball money ticket that used to live at the top of this file
   (.money-feature/.money-inner/.pot-amt/.pot-kicker/.payout-rest/.payout-basis, copied verbatim
   from event.html's own <style> block) is GONE. Owner call 2026-09-17: a flex league's pot reads
   $0 for its whole registration window, and a tilted ink-and-gold ticket is the one-day Moneyball's
   signature, not a season league's. event.html keeps its own copy of those rules, so nothing on the
   tournament side changed. What replaces them here is the flex hero (.flx-*) and one quiet pot line
   inside Standings, which reuses the shared .poster-money component from styles.css rather than
   declaring a second money type style.

   -------------------------------------------------------------------------------------------
   FLEX HERO — the league's own identity, deliberately calm next to a Moneyball poster.
   Green-forward (the green rule down the leading edge, the green season chip, the green mascot
   art); gold appears exactly once on the page, on the Register CTA. Geometry stays print-poster
   (0-4px radii). The lockup is art, never text: it carries alt text and the league name is a real
   <h1> beside it. */
.flx-hero{display:grid;grid-template-columns:auto 1fr;gap:var(--s5);align-items:center;
  background:var(--ink-2);border:1px solid var(--line);border-left:4px solid var(--green);
  border-radius:var(--r-lg);box-shadow:var(--sh-1);
  padding:var(--s5);margin:var(--s3) 0 var(--s6)}
.flx-hero-body{min-width:0}
/* width/height on the <img> keep the intrinsic ratio (0.856 w:h) reserving its space before the SVG
   lands, so the hero never reflows under the reader. */
.flx-mark{display:block;width:clamp(92px,20vw,148px);height:auto;align-self:start}

/* The season, as a chip: a green FILL carrying dark ink text (--on-accent, ~8.4:1 on --green), the
   house rule for brand-as-fill. In TV/dark --on-accent is undeclared and the fallback --ink keeps
   the same near-black on the same green. */
.flx-season{display:inline-block;margin:0 0 var(--s2);padding:3px 10px;border-radius:var(--r-label,2px);
  background:var(--green);color:var(--on-accent,var(--ink));
  font-family:var(--f-cond);font-weight:700;text-transform:uppercase;letter-spacing:.14em;
  font-size:var(--t-xs)}

/* .div-title (styles.css) already sets --t-2xl and steps to --t-3xl under .tv. The clamp only adds
   a phone-width floor so a long league name does not run to four lines at 390px. */
.flx-title{font-size:clamp(1.6rem,6.2vw,var(--t-2xl));overflow-wrap:break-word}
.tv .flx-title{font-size:var(--t-3xl)}
/* The board is read from across a court, so the hero's supporting type steps up with the title
   (de-vibe pass 2026-09-18: only the title did, leaving phone-sized facts on a 1920px screen). */
.tv .flx-promise{font-size:var(--t-lg)}
.tv .flx-facts dt,.tv .flx-potline .k{font-size:var(--t-sm)}
.tv .flx-facts dd{font-size:var(--t-lg)}
.tv .flx-sub{font-size:var(--t-md)}

.flx-promise{margin:var(--s2) 0 var(--s4);max-width:52ch;text-wrap:balance;
  font-family:var(--f-cond);font-weight:600;font-size:var(--t-md);color:var(--cream)}

/* The fact strip: four columns on a laptop, two on a tablet, one on a phone — auto-fit does all
   three with no media query. Each cell is a <dt>/<dd> pair inside the <dl>, so the labels are
   real markup semantics and not just small grey text. */
.flx-facts{display:grid;grid-template-columns:repeat(auto-fit,minmax(168px,1fr));
  gap:var(--s4);margin:0;padding-top:var(--s4);border-top:1px solid var(--line)}
/* The CTA owns the gap above it rather than the fact strip owning the gap below: under ?tv=1 the
   CTA is not rendered at all (nothing on a venue board is tappable), and a margin on the strip
   would leave a dead band at the bottom of the TV hero. */
.flx-hero .row{margin-top:var(--s5)}
.flx-facts>div{min-width:0}
.flx-facts dt{margin:0 0 3px;font-family:var(--f-cond);font-weight:700;text-transform:uppercase;
  letter-spacing:.1em;font-size:var(--t-xs);color:var(--sage)}
.flx-facts dd{margin:0;overflow-wrap:anywhere}
.flx-sub{display:block;margin-top:2px;font-size:var(--t-sm);color:var(--sage)}
/* The one money claim in the hero rides the shared .poster-money (styles.css): display scale,
   gold-as-text on paper, tabular figures. Only its line-height is nudged so the $ figure and the
   words under it read as one block. */
.flx-facts .poster-money{display:block;line-height:1.1}

@media(max-width:640px){
  .flx-hero{grid-template-columns:1fr;gap:var(--s4);padding:var(--s4)}
  .flx-mark{width:112px}
}

/* ---- The pot, demoted to one quiet line above the standings table -------------------------
   It reuses .poster-money (the same display-scale money type every listing card uses) and the
   shared .pot-fresh freshness indicator. No tilt, no gold rules, no 88px Anton: the number is a
   fact about the table underneath it, not the headline of the league. */
/* Surface note: --ink-2 (white on paper, the raised panel ink in TV/dark) rather than the recessed
   --ink-3. The figures this note used to quote predate the 260917-jj4 token pass; --sage is now
   a darker token that clears AA on both surfaces. --ink-2 stays the choice for its raised-panel
   meaning. */
.flx-potline{display:flex;flex-wrap:wrap;align-items:baseline;gap:var(--s2) var(--s3);
  margin:0 0 var(--s4);padding:var(--s3) var(--s4);
  background:var(--ink-2);border:1px solid var(--line);border-radius:var(--r-md)}
.flx-potline .k{font-family:var(--f-cond);font-weight:700;text-transform:uppercase;
  letter-spacing:.1em;font-size:var(--t-xs);color:var(--sage)}
.flx-potline .split{font-size:var(--t-sm);color:var(--sage);font-variant-numeric:tabular-nums}
.flx-potline .pot-fresh{margin-left:auto}

/* ---- Rules tab: plain-language sections -----------------------------------------------------
   Owner, 2026-09-17: "the point system is unusual and should be laid out plainly with how it
   works." Each section is a .panel card carrying an Anton heading, prose at a readable measure,
   and (where the fact IS a number) either a table.std or a .flx-kv row list. */
.flx-rules{display:grid;gap:var(--s4)}
.flx-sec h2{font-size:var(--t-lg);margin:0 0 var(--s3)}
.flx-sec p{margin:0 0 var(--s3);max-width:64ch}
.flx-sec>p:last-child,.flx-sec>*:last-child{margin-bottom:0}
/* The one-line meaning under each result, inside the points table's left cell. Regular weight and
   muted so the result label and its points stay the scannable pair. */
.flx-mean{margin-top:2px;font-family:var(--f-body);font-weight:400;font-size:var(--t-sm);
  color:var(--sage);white-space:normal}
.flx-steps{margin:0 0 var(--s3);padding-left:1.3em;max-width:64ch}
.flx-steps li{margin-bottom:var(--s2)}
.flx-steps li:last-child{margin-bottom:0}
/* Key/value rows: the same two-column reading as a receipt, wrapping to two lines rather than
   squeezing when a value is long. */
.flx-kv{margin:0 0 var(--s4)}
.flx-kv>div{display:flex;flex-wrap:wrap;justify-content:space-between;align-items:baseline;
  gap:var(--s2) var(--s3);padding:7px 0;border-bottom:1px solid var(--line)}
.flx-kv>div:last-child{border-bottom:0}
.flx-kv dt{font-family:var(--f-cond);font-weight:700;text-transform:uppercase;letter-spacing:.07em;
  font-size:var(--t-xs);color:var(--sage)}
.flx-kv dd{margin:0;text-align:right;font-variant-numeric:tabular-nums}
.flx-kv .poster-money{line-height:1.1}

/* =============================================================================================
   public/league-register.html — the Flex head strip + the receipt-shaped cost panel (260917-flx).
   That page links this stylesheet too; the .flx-* rules above simply never match there.
   ============================================================================================= */

/* The head strip: a small flex mascot beside the product name and the season. The app-shell header
   above it already carries "Register — <league name>" in chrome type, so this says what KIND of
   thing the player is joining, which the chrome cannot. */
.lgr-head{display:flex;align-items:center;gap:var(--s3);margin:0 0 var(--s4)}
.lgr-mascot{display:block;width:44px;height:auto;flex:none}
.lgr-kicker{margin:0;font-family:var(--f-cond);font-weight:700;text-transform:uppercase;
  letter-spacing:.12em;font-size:var(--t-sm);color:var(--green-ink,var(--green))}
.lgr-season{margin:1px 0 0;font-size:var(--t-sm);color:var(--sage)}

/* The cost panel, written as a receipt: the price per player, any discount the server applied, then
   the total. 260918-cf5 removed the "= $30 league fee + $20 into the prize pot" line and its own
   .lgr-made-of/.lgr-op rules with it (owner: one price, never the split). Money itself keeps riding
   the shared .poster-money helper in the page. */
.lgr-receipt{display:block}
.lgr-line{display:flex;flex-wrap:wrap;align-items:baseline;justify-content:space-between;
  gap:var(--s2) var(--s3)}
.lgr-k{font-family:var(--f-cond);font-weight:700;text-transform:uppercase;letter-spacing:.05em}
/* Colour deliberately left to .muted (which every one of these spans also carries): inside a light
   .panel the shared stylesheet darkens .muted past the AA floor for text on the recessed --ink-3
   field the cost panel sits on. Only the type changes here. */
.lgr-what{font-family:var(--f-body);font-weight:400;text-transform:none;letter-spacing:0;
  font-size:var(--t-sm)}
.lgr-cut{padding-top:var(--s2)}
.lgr-total{padding-top:var(--s2);border-top:1px solid var(--line);margin-top:var(--s2)}

/* ---- The cart (260918-cf5) -------------------------------------------------------------------
   Registering creates the row unpaid and lands the player on a cart, so a second division type can
   be added at its discounted price before anything is paid. One card per entry; the pay choice is
   a labelled radio pair; Remove confirms inline inside the same card. Tokens only, no new hex, no
   frame block (this file declares none, pinned by tests/league-page.test.mjs). */
.lgr-item h3{font-family:var(--f-cond);font-weight:700;text-transform:uppercase;letter-spacing:.03em;
  font-size:var(--t-md)}
.lgr-item .sub{color:var(--sage);font-size:var(--t-sm)}
/* The pay choice. Each option is a full-width 44px row, so the whole row is the target rather than
   the radio dot, and the border makes the two options read as one control group. */
.lgr-opts{display:grid;gap:var(--s2);margin-top:var(--s3)}
.lgr-opt{display:flex;align-items:center;gap:var(--s3);min-height:44px;
  padding:var(--s2) var(--s3);border:1px solid var(--line);border-radius:var(--r-md);cursor:pointer}
.lgr-opt input{width:auto;min-height:auto;margin:0;flex:none}
.lgr-opt span{font-family:var(--f-cond);font-weight:600}

/* ---- A standings row's "not yet cash-eligible" note. The markup has always emitted .lg-note; no
   stylesheet ever declared it, so it rendered at full body scale directly under the team name and
   competed with it. Muted, small, and never the only signal (the text itself says it). */
.lg-note{margin-top:2px;font-family:var(--f-body);font-weight:400;font-size:var(--t-sm);
  color:var(--sage);white-space:normal}

/* ---- .lg-match / .lg-round-head — read-only schedule rows (Task 2), tokens only, no new hex ---- */
.lg-round-head{font-family:var(--f-cond);font-weight:700;text-transform:uppercase;letter-spacing:.06em;
  font-size:var(--t-sm);color:var(--sage);margin:var(--s5) 0 var(--s2)}
.lg-round-head:first-child{margin-top:0}

/* ---- Team detail sheet (quick-260831-oze, review finding F8) --------------------------------
   Owner ask: "on the league page, we should be able to see point breakdowns so there is no
   question where teams accumulated scores." Owner decision (locked): one tap deeper into a bottom
   sheet, NOT an inline row expansion.

   Why a page-scoped `.lg-sheet` instead of styles.css's shared `.sheet`: this wave's file-ownership
   contract puts public/styles.css (and public/chat.html / public/flex-ui.js, which own the shared
   sheet's only openSheet() call path) in a SIBLING task running in parallel — reusing that
   component here would mean either editing a file this task must not touch or coupling the public
   league page to a chat module being rewritten in another branch right now. The geometry below is
   the same language as `.sheet` (scrim, bottom-anchored panel, pinned head, scrolling body, 44px
   close), expressed in tokens only, and it deliberately REUSES the already-declared pp-fade /
   pp-sheet-up motion pack from styles.css rather than declaring new frames — league.css declares
   no frame block of its own (pinned by tests/league-page.test.mjs).

   TV mode never opens this: league.html renders no activator at all under ?tv=1, so the board
   stays exactly as legible and as untappable as it is today. */
.lg-sheet-backdrop{position:fixed;inset:0;background:rgba(12,14,8,.5);z-index:var(--z-backdrop);
  display:flex;align-items:flex-end;justify-content:center;
  animation:pp-fade var(--dur) var(--ease)}
.lg-sheet{background:var(--ink-2);color:var(--white);width:100%;max-width:560px;
  border:1px solid var(--line);border-bottom:0;border-radius:var(--r-lg) var(--r-lg) 0 0;
  max-height:85svh;display:flex;flex-direction:column;overflow:hidden;
  box-shadow:var(--sh-3);z-index:var(--z-modal);
  animation:pp-sheet-up var(--dur) var(--ease)}
@supports not (height:100svh){.lg-sheet{max-height:85vh}}
/* Reduced motion: the panel FADES in instead of travelling. (styles.css's global
   prefers-reduced-motion block already clamps every duration to .001ms; naming the fade here makes
   the substitution explicit rather than incidental.) */
@media (prefers-reduced-motion:reduce){
  .lg-sheet{animation-name:pp-fade}
}
/* Body scroll lock while the sheet is up — the sheet's own body is the only scroller. */
body.lg-sheet-open{overflow:hidden}

.lg-sheet-head{display:flex;align-items:center;justify-content:space-between;gap:var(--s3);
  padding:var(--s3) var(--s3) var(--s3) var(--s4);border-bottom:1px solid var(--line);flex:none}
.lg-sheet-title{font-family:var(--f-cond);font-weight:700;text-transform:uppercase;letter-spacing:.03em;
  font-size:var(--t-md);margin:0;min-width:0;overflow-wrap:anywhere}
.lg-sheet-close{min-width:44px;min-height:44px;flex:none;display:inline-flex;align-items:center;
  justify-content:center;background:transparent;border:0;color:inherit;cursor:pointer;border-radius:var(--r-md)}
.lg-sheet-body{padding:var(--s4);overflow:auto;-webkit-overflow-scrolling:touch}

/* The number the visitor came to check, at display scale (DESIGN.md: points/money lead, never
   set at body size). It restates the exact Pts cell that was tapped — never a client-side sum. */
.lg-sheet-sum{display:flex;align-items:flex-end;justify-content:space-between;gap:var(--s3);
  flex-wrap:wrap;margin-bottom:var(--s4)}
.lg-sheet-pts{display:block;font-family:var(--f-display);font-size:var(--t-3xl);line-height:.9;
  letter-spacing:0;font-variant-numeric:tabular-nums;color:var(--gold-ink,var(--gold))}
.lg-sheet-meta{font-family:var(--f-cond);font-weight:600;text-transform:uppercase;letter-spacing:.06em;
  font-size:var(--t-sm);color:var(--sage);font-variant-numeric:tabular-nums}

/* Form strip (Premier League form-guide convention, 17-RESEARCH-UI-CONVENTIONS topic 6): oldest to
   newest, left to right. Every chip carries its LETTER, so the result is never signalled by colour
   alone; each also carries the full sentence for screen readers and on hover. The two forfeit
   flavours differ by fill AND border style (solid vs dashed), not by hue. */
.lg-form{display:flex;flex-wrap:wrap;gap:6px;margin:0 0 var(--s4)}
.lg-chip{width:28px;height:28px;min-width:28px;display:inline-flex;align-items:center;
  justify-content:center;border-radius:var(--r-label,2px);font-family:var(--f-cond);font-weight:700;
  font-size:var(--t-sm);background:var(--ink-3);color:var(--white);border:1px solid var(--line-2)}
.lg-chip.w{background:var(--green);color:var(--on-accent,var(--ink));border-color:var(--green-deep)}
.lg-chip.fw{background:var(--gold);color:var(--on-accent,var(--ink));border-color:var(--gold-deep)}
.lg-chip.fl{background:var(--ink-3);color:var(--gold-ink,var(--gold));border:1px dashed var(--gold-deep)}
.lg-chip.p{background:transparent;color:var(--sage);border:1px dashed var(--line-2)}

/* Round-by-round table — extends table.std verbatim (same component the standings table uses), so
   the breakdown reads as the same object the visitor tapped, one level in. */
.lg-rounds tr.pending td{color:var(--sage)}
.lg-rounds tfoot td{border-top:2px solid var(--line-2);border-bottom:none;font-weight:700;
  color:var(--white)}

/* The standings row's activator. A real <button> (keyboard + :focus-visible for free) filling the
   team cell, so the practical tap target is the row, at the 44px floor. */
.lg-team-btn{display:flex;align-items:center;justify-content:space-between;gap:var(--s2);width:100%;
  min-height:44px;padding:0;background:transparent;border:0;color:inherit;font:inherit;
  text-align:left;cursor:pointer;border-radius:var(--r-md)}
.lg-team-cue{flex:none;display:inline-flex;align-items:center;color:var(--sage)}
.lg-team-cue svg{transform:rotate(180deg)}

/* ---- Second-type discount on the register receipt (260918-cf5 follow-up) ---------------------
   The full price is struck through beside the price paid, at the same display scale, so the saving
   reads at a glance ("$50 then $30"). The struck figure is muted; the sr-only "was" carries the
   meaning for a screen reader. The pot note is the one sentence that says what the discount is NOT. */
.lgr-price{display:inline-flex;align-items:baseline;gap:var(--s2);flex-wrap:wrap;justify-content:flex-end}
.lgr-was .poster-money{text-decoration:line-through;text-decoration-thickness:2px;color:var(--sage);font-size:var(--t-lg)}
.lgr-potnote{margin:var(--s3) 0 0;padding-top:var(--s3);border-top:1px dashed var(--line);
  font-size:var(--t-sm);color:var(--sage);max-width:52ch}
