/* =========================================================================
   THE CORPORATION . brand.css
   One stylesheet generated from three ruled chapters:
     BRAND-GUIDELINES-01-CARDS.md
     BRAND-GUIDELINES-02-TYPE.md
     BRAND-GUIDELINES-03-TABLES.md
   plus the panel ruling (CARD-SYSTEM-PROPOSAL-SPEC.md Part 2, proposal C,
   as already built in src/components/ui/Panel.tsx) and DESIGN-LAWS.md.

   THE GOVERNING RULE
   This sheet is generated FROM the rulesets. It is not written alongside
   them. If a rule cannot be expressed as something the site can actually
   use, nothing is declared for it: it goes in the OUTSTANDING block below
   with what it is, why CSS cannot carry it, and who has to do it. Chapter 2
   found a font family declared in the config, never loaded, with zero uses
   and a comment still calling it real. A guideline stylesheet that is not
   what the site actually uses becomes a fourth artefact everyone reads and
   nothing obeys.

   SAFETY
   Every class is prefixed `b-`. Every custom property is prefixed
   `--brand-`. There are no element selectors anywhere in this file, no
   `!important`, and no rule that fires on anything that has not asked for
   it by class. `.b-scope` is the documented opt-in scope class. This file
   is safe to sit in the repo unimported and safe to drop next to
   globals.css. It converts nothing. Conversion is the next run.

   CITATION GRAMMAR
   Every declaration carries the rule it came from, in brackets, either on
   its own line or on the selector line of a block where every declaration
   in the block comes from that one rule. scripts/check-brand.mjs parses
   these and fails on any declaration with no citation and on any citation
   that points at a section that does not exist.

     [11.9]      a section number exactly as written in its chapter, used
                 when that number appears in only one of the five chapters.
                 The example here has now been rewritten twice for the same
                 reason: it was 2.12 until chapter 3 gained a §2.12, then 6.3
                 until chapter 3 gained a §6.3 on 2026-07-31. An unqualified
                 citation is one chapter away from ambiguous at all times.
                 Prefer the chapter-qualified form below and leave this one
                 to the citations that already exist.
     [3.2.3]     chapter-qualified: leading digit is the chapter, the rest
                 is the section as written there
     [c1.4.1]    explicitly chapter-qualified with a leading c, meaning
                 chapter 1 section 4.1. Chapter 1 numbers its card variants
                 1.x.y, so an unqualified 4.1 and an unqualified 1.4.1 can
                 each point at two real sections. The c form removes the
                 doubt, and the checker fails an ambiguous citation rather
                 than guessing which of the two was meant.
     [DL-5]      DESIGN-LAWS.md section 5
     [PANEL-C]   CARD-SYSTEM-PROPOSAL-SPEC.md Part 2, Proposal C
     [SPEC-FORM] CARD-SYSTEM-PROPOSAL-SPEC.md, "Form rules for the sheet
                 itself". Governs the specimen page only, never the site.

   ========================================================================= */


/* =========================================================================
   OPEN . four known disagreements. NONE of these is resolved here.
   Where the sheet has to emit something anyway it emits the ruled value,
   cites it, and points back at the open item.
   =========================================================================

   CLOSED-1 . THE BUILT TEAM/NUMBER DISAGREED WITH CHAPTER 2 IN THREE PLACES.
     JD CLOSED IT ON 2026-07-28 IN THREE WORDS: "the list does."
     The card is right and the type chapter changed to match it. The three
     values below are now LEGITIMATE, not tolerated — chapter 2 section 2.13
     rules that a role fixes the SIZE and that weight and case belong to the
     job, and section 2.14 rules that fixed-pixel leading is correct where
     lines land on a grid. This sheet emits them with no asterisk.
     His reasoning, recorded as method rule 9a: an approved surface outranks
     an extracted rule. The scale exists to describe the site; the site does
     not exist to satisfy the scale. Where they disagree the surface is the
     evidence and the rule was extracted wrong.
     WHAT IT USED TO SAY:
     The built card (public/team-number-final.html, ruled as the live
     anatomy by chapter 1 section 1.4.8) sets the team name at weight 700
     where chapter 2 section 2.5 rules Dense at 500; sets line-height 13px,
     which is not one of the four values on the chapter 2 section 6.1 list;
     and sets the owner at 8px/400 mixed case where chapter 2 section 2.7
     rules Micro at 8/600/UPPER/0.05em.
     The card side says: values are from the file, not from prose, and JD
     approved this card.
     The type side says: a size or a leading or a weight not on the list is
     a defect, not a variant.
     All three were flagged when the card was ruled and left flagged.
     RESOLVED: the card's values are the rule. Team name Dense at 700
     (ch2 2.13), leading 13px grid-pinned (ch2 2.14), owner Micro at 400
     mixed case (ch2 2.13).

   CLOSED-2 . 95 AGAINST 96 ON THE DRAFT BOARD COLUMN.
     This was open when the sheet was dispatched. JD CLOSED IT ON 2026-07-28,
     while the sheet was being written, by amending chapter 1 section 1.4.0.
     It is recorded here rather than deleted, because the sheet was generated
     across the amendment and a reader needs to know which side it landed on.
     The chapter side had said: the column is 96 and it is derived, so nobody
     widens it and nobody narrows it.
     The board side had said: what renders is 95.
     JD RULED FOR THE BOARD. The card takes its width from the column and
     carries no width of its own. 96 is the column's MINIMUM, held once on the
     board table, not a card width. A per-card 96 floor was considered and
     rejected: it would push the head 1px past its 95px cells at the design
     minimum and reintroduce the defect at the narrow end.
     The sheet emits no card width. See variant 1.4 below.

   CLOSED-3 . WRAP TO TWO AND NEVER TRUNCATE, INSIDE A FIXED 56px BOX.
     CLOSED 2026-07-28. NOT over-constrained — the two rules never met.
     A THIRD LINE CANNOT OCCUR BY CONSTRUCTION: split() returns exactly two
     pieces, and .l1/.l2/.ow all carry white-space:nowrap, so neither line
     can wrap on its own. There is no path to a third line with any name,
     not merely none with these twelve.
     The real residual risk is HORIZONTAL, not vertical: a head too wide
     does not become a third line, it overflows sideways. That is chapter 1
     section 1.4.8.2, where the twelve clear by 27px but pass on margin.
     No guard built and none would help — a guard against three lines
     guards against something that cannot happen.
     Reopens only if split() returns more than two pieces or a nowrap comes
     off a line. NOT on a rename and NOT at a thirteenth team.
     WHAT IT USED TO SAY:
     Chapter 1 section 3.5 rules that a team name wraps to two lines and
     never takes dots, and section 3.4 rules that clipped text is a defect.
     Team/Number is 56 tall with the name on rows one and two and the owner
     on row three.
     A three-line name has nowhere to go: it clips, and clipping text is the
     section 3.4 violation.
     The wrap side says: a team name's tail carries the meaning, so dots
     lose the joke.
     The box side says: the height is pinned so twelve column heads sit in
     one row at one height.
     RESOLVED: nowrap on every line is what makes the question moot. The
     sheet emits nowrap and no clip on text, and that is complete.

   OPEN-4 . TWELVE HARDCODED HUES AGAINST assignTeamHues.
     The reference mock hardcodes twelve hues. The live board takes them
     from assignTeamHues (src/app/draft/board/components/teamHues.ts), and
     DESIGN-LAWS 5b rules one shared module and no second map.
     The palette itself is unruled and pending its own pass (chapter 1
     sections 1.4.7.4 and 1.3.3 both carry a constraint to it: every hue
     must stay legible at 25% as a 50px character and as a filled shape).
     The sheet emits NO team hue. A hue is data and arrives per element.

   ========================================================================= */


/* =========================================================================
   OUTSTANDING . rules that exist and that CSS cannot carry.
   Nothing decorative is declared for any of these.
   =========================================================================

   OUT-1 . SELF-HOSTED FONTS. Chapter 2 section 4.1 rules three weights of
     each family, self-hosted; section 4.2 removes the @import. There are no
     font files in this repo (there is no public/fonts). An @font-face
     pointing at a file that does not exist is exactly the decorative
     declaration this sheet bans, so none is written. The two reference
     cards still pull Barlow Semi Condensed from Google Fonts by <link>,
     which is the mechanism 4.2 removes.
     WHO: Engineering, to add six files (three weights x two families) on
     the same self-hosting path the archive face already uses (4.3), then
     delete the @import at src/app/globals.css line 6.

   OUT-2 . THE ONE SORT CONTROL. Chapter 3 section 2.11 rules one sort
     control that shows an inactive affordance before it is clicked and
     emits aria-sort. CSS carries neither a glyph nor an ARIA attribute.
     The sheet carries nothing for it.
     WHO: Engineering, inside the one shared table component that chapter 3
     section 3.1 says has to exist first.

   OUT-3 . EMPTY STATES. Chapter 3 section 2.9 rules that headers stay and
     one message row sits underneath, spanning the full column count. A
     column count is markup, not a declaration.
     WHO: Engineering, same shared component.

   OUT-4 . UPPERCASE IN CSS, NEVER IN JAVASCRIPT. Chapter 2 section 6.3.
     `.b-label` and `.b-micro` below carry `text-transform`, which is the
     CSS half. The 82 places that uppercase the string itself are a code
     change, and the reason is a screen reader saying the result one letter
     at a time.
     WHO: Engineering.

   OUT-5 . NO FONT SIZE COMPUTED AT RUNTIME. Chapter 2 section 6.4, chapter
     1 section 5.1 and chapter 1 section 3.7. This is a prohibition on
     JavaScript. There is no declaration that expresses it.
     WHO: Engineering, on the draft board's per-card computed size, which
     chapter 1 section 5.1 records as still live on /draft/board through
     four imports and still waiting on one line from JD.

   OUT-6 . NESTING AN INSET INSIDE AN INSET IS OUT. Panel ruling C, as
     built. A composition rule. CSS can only enforce it by firing a visible
     defect marker, which would be a rule that fires without being asked.
     WHO: whoever reviews the conversion.

   OUT-7 . NO ZEBRA STRIPING, EVER. Chapter 3 section 2.5. A prohibition.
     This sheet emits no nth-child rule of any kind, and adding one is the
     defect. Writing `background: transparent` on even rows would be a
     decorative declaration that does nothing.
     WHO: whoever reviews the conversion.

   OUT-8 . THE VIEWER'S ROW TINT HAS NO NUMBER. Chapter 3 section 2.6 rules
     gold as the viewer's row at one alpha, "not the five in use today", and
     no chapter anywhere states which alpha. No value is invented, so no
     row-tint declaration is emitted. `.b-you` below carries the part that
     IS ruled: gold marks the viewer's own thing (DESIGN-LAWS 5, chapter 1
     section 1.3.2).
     WHO: JD, or Taste on his behalf.

   OUT-9 . THE PLAYOFF GREEN HAS NO HEX. Chapter 3 section 2.6 rules green
     as a playoff position. DESIGN-LAWS 5 gives only the action green
     #3FE0A0, and says in the same breath that a green marking a win or a
     value must stay flat so it cannot be confused with the action green. So
     the action green is not the playoff green and no chapter names the
     playoff green. No value is invented.
     WHO: JD, or Taste on his behalf. It is a new colour entering the
     palette, which DESIGN-LAWS lists as a human call.

   OUT-10 . CLOSED 2026-07-30 (JD). THE HOVER RUNG IS #1E2A39, ONE NEW STEP
     ON THE BACKGROUND RAMP.
     He picked a new rung over any of the four alphas in use, because none of
     the four could do the job: the row that needed a hover is already filled
     with the lightest opaque background on the site. `--brand-bg-raised`
     above carries the value and its derivation, and `.b-row-hover` below
     writes it. This IS a new colour entering the palette, which DESIGN-LAWS
     lists as a human call, and it was made as one.
     WHAT IT USED TO SAY:
     Chapter 3 section 2.7 rules one hover alpha where four are in use. It
     does not say which one. No hover declaration is emitted.
     WHO: JD, or Taste on his behalf.
     STILL OPEN AS OF 2026-07-30. DECISIONS-05.md D-11 offered to close it
     by naming bg-corp-bg-hover, and JD HELD D-11 rather than ruling it.
     Nothing about this outlier moved. `.b-row-hover` is not writable.
     RESOLVED: D-11 came back with the ramp drawn (option H1) and he ruled it.

   OUT-11 . CLOSED 2026-07-29 (JD). THE STICKY HEADER TAKES THE PAGE
     BACKGROUND, SOLID.
     He picked the page's own background over a lifted panel, so a heading
     does not change colour when it sticks and there is no second surface
     colour to design or explain. `.b-th-sticky` below now emits
     `background: var(--brand-page-bg)` (#04070B) alongside position and
     top. This is not a new colour entering the palette: the token already
     existed and is the colour the page is already painted.
     WHAT IT USED TO SAY:
     A sticky header needs an opaque backing and no chapter gives one.
     Chapter 3 section 2.10 rules a sticky header. `position: sticky` with
     no background lets the rows scroll through it. `.b-th-sticky` below
     emits position and top and no background.
     RESOLVED: the page background, solid, on every sticky header.

   OUT-12 . CLOSED 2026-07-29 (JD). A LINE IN A CELL TAKES 1.25.
     He picked the tightest of the four ruled ratios (chapter 2 section 6.1,
     `--brand-lh-125`), knowing the cost: every table gets slightly tighter.
     A ratio replaces the pixel, so the row is now produced by the leading
     and `--brand-row: 16px` no longer has a consumer. The two cell classes
     below take the ratio. No padding is emitted and none is needed: a cell
     with 0 vertical padding measures exactly its leading.
     WHAT IT USED TO SAY:
     Table row height cannot be derived. Chapter 3 sections 1.1 to 1.3 rule
     16px and 20px rows; section 1.7 rules that row height is set by padding
     and never by an explicit height. The padding that produces 16 or 20
     depends on the cell's line-height, and no chapter says which of the
     four ruled leadings a table cell takes. Picking one would be an
     invented value.
     RESOLVED: 1.25 on `.b-td` and `.b-td-dense`. The row height is whatever
     that produces, measured rather than targeted: 15px on a 12px Dense cell
     and 17.5px on a 14px Body cell, so the single 16px box does not survive
     the answer.

   OUT-13 . PLAYER/FULL AND PLAYER/ROW HAVE NO RULED ANATOMY. Chapter 1
     section 1.1 and section 1.2 give the box. Section 2.1 gives the
     attribute list (always, sometimes, never) and nothing about
     arrangement. The sheet carries the box and the card scale; which field
     takes which step, and where each sits, is not ruled.
     WHO: Taste, from a render, per chapter 1 section 6.5.

   OUT-14 . THE RESERVED GUTTER HAS EXACTLY ONE RULED WIDTH. Chapter 1
     section 3.1 makes the reserved gutter the preferred overflow mechanism.
     The only width any chapter gives is the chip's 17px (section 1.14.1).
     Every other gutter is per badge and unruled, so there is no general
     `.b-gutter`.
     WHO: Taste, per badge, from a render.

   OUT-15 . THE RECORD ON TEAM/FULL IS AHEAD OF ITS DATA PATH. Chapter 1
     section 2.2.1 rules place and record together on the status line;
     section 2.2.2 records that nothing renders a record on a team card
     today because the records live in standings and do not reach the card.
     The sheet carries the status line. The record is wiring.
     WHO: Engineering and Data.

   OUT-16 . CHAMPION IS RULED AND NOT YET WORN. DESIGN-LAWS 5d rules the
     champion pair, ruled 2026-07-29, and this sheet carries the token and
     both classes. Thirty-nine marks across nine files still render the
     ownership gold #F5C860 for champion. A stylesheet cannot reach into a
     component's Tailwind class, so nothing here changes them. The nine files
     and the thirty-nine lines are listed in 5d.
     WHO: Engineering.

   OUT-17 . THE INACTIVE SORT AFFORDANCE HAS NO ALPHA. Chapter 3 section
     2.11 rules a sort control that shows a reader a column is sortable
     before it is clicked, and the position was ruled 2026-07-29 (JD):
     straight after the heading, inline. Neither says how faint the
     inactive arrow is. `--brand-dim` is chapter 1 section 4.1's "not yet
     real" and means something else, so it is not borrowed. No opacity
     declaration is emitted.
     WHO: JD, or Taste on his behalf.

   ========================================================================= */


/* =========================================================================
   CONFLICTS . the chapters against the running code, and against
   themselves. Reported, not resolved.
   =========================================================================

   CONF-1 . GOLD TOKEN COLLISION. VERIFIED.
     Chapter 1 section 1.3.2 reserves gold for the viewer's own thing:
     nothing else may use it, not a heading, not a status, not an accent,
     not a border. DESIGN-LAWS 5 gives gold as #F5C860. But
     src/app/globals.css line 37 sets `--corp-gold: #FF3D2E` with the
     comment "the accent moved from gold to broadcast red", so the legacy
     token changed meaning underneath the code and now maps to RED.
     DESIGN-LAWS 5 records the same trap and says some of its uses are
     correctly red. Two theme blocks then override it again
     (`html.theme-july4` to #cbb069, `html.theme-usa` to #60a5fa), so the
     token has three live meanings.
     THIS SHEET therefore defines its own gold, `--brand-gold: #F5C860`,
     and never reads `--corp-gold`. Anything wired to `--corp-gold`
     expecting gold is wearing red.

   CONF-2 . TEAL AS DATA AGAINST TEAL AS ATMOSPHERE. VERIFIED.
     src/app/globals.css line 31 declares `--cyan:#3BE6FF` with the comment
     "ATMOSPHERE only . depth, distance. Never data." Chapter 1 section
     1.3.1 puts the Team/Full status line, place and record, which is data,
     in that exact colour, and section 1.3.2 rules teal as the general quiet
     highlight that replaces gold everywhere gold is not ownership.
     Both cannot hold. Not settled here.

   CONF-3 . CHIP WIDTH, 148 AGAINST 168. VERIFIED.
     Chapter 1 section 1.14 prose reads "1.7 Team / Chip . 148px fixed" and
     section 1.14.2 reads "At 148px every one of the twelve fits". The
     section 1 variant table and the titled correction at section 1.14.1
     both rule 168px: 151px for "Outkicking the Coverage" plus 17px
     permanently reserved for the response mark. 1.14.1 also records why 148
     was wrong (the measuring page did not inherit the site's global
     letter-spacing, worth about 4px across 23 characters).
     168 wins on the table plus the titled correction. The 148 in 1.14 and
     1.14.2 is stale, and a builder reading 1.14 alone builds the wrong
     width. THIS SHEET emits 168.

   CONF-4 . CARD SCALE EXCLUSIVITY, A WORDING DEFECT NOT AN OPEN DECISION.
     VERIFIED. Chapter 2 section 5 says the five card steps are "the only
     sizes permitted inside a card, and they are permitted nowhere else."
     Section 5.0.1 then rules the Team/Number name to be Dense (12, a page
     role) and section 5.0.2 rules the watermark to be Marker (a page role),
     both inside cards. Section 5.0 resolves the substance and says so; the
     section 5 header sentence was never updated. Wording defect.

   CONF-5 . TRACKING SIGN. FOUND HERE.
     Chapter 2 section 6.2 rules three tracking values: 0.025em, 0.05em,
     0.1em, all positive, and says every other value becomes the nearest of
     the three. Chapter 2 section 2.1 rules Title at MINUS 0.025em, which is
     a listed magnitude at a sign the list does not carry. Chapter 2 section
     2.12 and chapter 1 section 1.3.1 set the Team/Full marker at MINUS
     0.02em, which is not on the list at any sign; 2.12 says tracking at
     that size is optical and belongs to the use.
     Both are emitted, both cited, both declared as exceptions in the
     checker so they are visible rather than silently tolerated.

   CONF-6 . TEAM/FULL LEADING — RESOLVED WITH CLOSED-1, same ruling.
     FOUND HERE. Chapter 1 section 1.3.1 sets the name at 12px with
     line-height 14px (1.167), the manager at 10px with line-height 12px
     (1.2) and the status at 10px with line-height 12px (1.2). Chapter 2
     section 6.1 rules four leadings and says the five near-identical values
     between 1.1 and 1.25 collapse to 1.25. All three of these sit in that
     band. CLOSED-1 rules exactly this class legitimate, and had flagged it only on
     Team/Number. Team/Full has it too and nobody wrote it down.

   CONF-7 . THE SHIPPED SECTION TITLE IS OUTSIDE BOTH TYPE LISTS.
     FOUND HERE. src/components/ui/Panel.tsx sets the Section title at
     fontSize FONT_KICKER (9.5, a CARD step) with letterSpacing '.7px'.
     9.5 is a card step used at page level, which is the wording defect in
     CONF-4 showing up in shipped code, and .7px is on neither the
     letter-spacing list (chapter 2 section 6.2) nor equal to the ruled
     .2px global floor. The panel ruling is already built and shipped on the
     commissioner Settings tab and the instruction is to match it exactly,
     so THIS SHEET emits Panel.tsx's values and records the disagreement.

   CONF-8 . A STYLESHEET CANNOT CARRY A CARD'S FIXED SIZE WITHOUT BREAKING
     CHAPTER 1 SECTION 4.2. FOUND HERE. Section 4.2 rules that a card sets
     its own width and height as an INLINE style so that a parent cannot
     override it, and says this is already true and stays true. A stylesheet
     that carries the eight variants at their fixed sizes puts those numbers
     in a class, which is the thing 4.2 rules out. THIS SHEET emits the
     sizes twice: as custom properties, which a component can read and set
     inline and which satisfies 4.2, and as classes, which the specimen page
     uses. A converting builder sets them inline.

   CONF-9 . THE RULED CHIP WIDTH RESTS ON A MEASUREMENT AT A RETIRED SIZE.
     FOUND HERE. Chapter 1 section 1.14.1 measures all twelve names "at the
     ruled 11px/600" to arrive at 151px and therefore at 168px. 11 is on
     neither type list, and chapter 2 section 5.0.1 rules the same 11px up
     to Dense 12 on Team/Number, calling it "an unchecked size, not a
     considered one". So the ruled 168 was measured in a size the ruleset
     retired. 168 stands (CONF-3); what a chip's text size is has no answer.

   CONF-10 . THE MARKER IS 50 AND TWO PLACES STILL SAY 62. VERIFIED.
     Chapter 2 section 2.12 rules Marker at 50px/700/.78 and records that it
     was tuned down from 62 within the hour, on both cards, because both
     cards carry the same value and that is the point of it being a role.
     Chapter 2 section 5.0.2 still reads "the watermark is an EIGHTH ROLE .
     Marker, 62px", and public/the-ruled-site.html line 92 still renders
     `font-size:62px`. Both are stale. THIS SHEET emits 50.

   CONF-11 . THE SHIPPED TOKENS FILE STILL COMMENTS 800. VERIFIED.
     src/components/ui/tokens.ts lines 17 to 21 comment the five card steps
     as 15/800, 10/800, 8.5/800 and 7.5/800. Chapter 2 section 3.3 retired
     800 and 900 and turned them into 700, and chapter 1 section 4.4 repeats
     it for cards. The constants are right and the comments are stale.
     THIS SHEET emits the post-3.3 weights.

   CONF-12 . 1.4.0's CARD INTERIOR ARITHMETIC DESCRIBES A CARD THAT NO
     LONGER EXISTS. FOUND HERE. Section 1.4.0 is kept alive by the 1.4.x
     banner for one reason, that the column is 96 and derived. The same
     section also states content width 82px and content height 44px, both
     computed from a 58px card with 6px padding. The live card (1.4.8) is 56
     tall and has no padding at all; its text is absolutely positioned. Any
     builder using 82 or 44 is building the superseded card.

   CONF-13 . ONE OF THE TWELVE TEAM HUES IS THE RESERVED GOLD. FOUND HERE.
     public/team-number-final.html gives slot 8, Space Lasers, the hue
     #F5C860. That is exactly the gold DESIGN-LAWS 5 reserves and chapter 1
     section 1.3.2 rules that nothing but the viewer's own thing may wear.
     So one team in twelve wears the ownership colour whoever is looking.
     Chapter 1 section 1.4.7.4 says the twelve hues are placeholders and
     will all change, and the palette pass is where this lands, so it is
     recorded against OPEN-4 rather than treated as a card defect. It is
     visible on public/brand.html: card 8 in the Team/Number row.

   CONF-14 . THE PICK CELL IS RULED BOTH WAYS ON DOTS. FOUND HERE.
     Chapter 1 section 3.5 rules that a team name wraps to two lines and
     never takes dots, section 3.6 gives the reason, and section 1.14.2 says
     "team names never take dots is now true without exception across every
     variant". Chapter 1 section 2.3.2, verifying Pick/Cell against the real
     cell, says the opposite in as many words: "the dots are the rule, not
     the render... The specimen draws dots because dots are the rule." Both
     are in chapter 1. A builder gets a different answer depending on which
     section he opens.

   CONF-15 . RANK ONE IS A THIRD MEANING STILL WEARING THE GOLD. FOUND HERE.
     DESIGN-LAWS 5 rules gold as the viewer's own thing and 5d rules the
     champion pair, so gold and champion each mean one thing now. Neither
     covers first place that is not a title. src/components/sidebets/
     Leaderboard.tsx line 73 fills the rank-1 medallion with the ownership
     gold to mark the leading bettor of a live week. That is not the viewer
     and it is not a champion. 5d names it and deliberately leaves it, because
     a colour for "leading right now" is a ruling and not a builder's pick.
     Nothing is declared for it here.
     WHO: JD, then Taste.

   ========================================================================= */


/* =========================================================================
   TOKENS
   ========================================================================= */

:root {
  /* Families. Two, not three. */
  --brand-font-display: 'Oswald', ui-sans-serif, system-ui, sans-serif;                    /* [c2.1.1] */
  --brand-font-text: 'Barlow Semi Condensed', ui-sans-serif, system-ui, sans-serif;        /* [c2.1.2] */
  /* [c2.1.3] the third family, Barlow Condensed, is retired, and so is the
     --font-cond name. Nothing here emits it. */

  /* The nine page type roles. Data (2.6) has no size of its own: it takes
     the size of the row it is in, so there is no token for it.
     Panel (2.22) is 18 like Heading (2.2) and is a SEPARATE token on purpose.
     A role is size, family, weight and tracking together [c2.2.21], so the two
     are different roles that happen to share a number today. Aliasing panel to
     heading would mean moving one moves the other, which is the opposite of
     what nine roles are for. */
  --brand-size-title: 30px;                                                                /* [c2.2.1] */
  --brand-size-title-step2: 24px;                                                          /* [c2.2.1] */
  --brand-size-title-step1: 20px;                                                          /* [c2.2.1] */
  --brand-size-heading: 18px;                                                              /* [c2.2.2] */
  --brand-size-panel: 18px;                                                                /* [c2.2.22] */
  --brand-size-label: 10px;                                                                /* [c2.2.3] */
  --brand-size-body: 14px;                                                                 /* [c2.2.4] */
  --brand-size-dense: 12px;                                                                /* [c2.2.5] */
  --brand-size-micro: 8px;                                                                 /* [c2.2.7] */
  --brand-size-marker: 50px;                                                               /* [c2.2.12] */

  /* THE PAGE SHELL WIDTH. RULED 2026-07-31 (JD). Chapter 4 section 12.

     Twenty call sites typed the 1152 into a max-w utility by hand, across nine
     surfaces. The
     number is derived and the derivation was already written down at
     LiveDraftBoard.tsx:319 - the draft grid is twelve columns and a column has
     a 96px design minimum, so 96 x 12 = 1152. Every other page was matched to
     the board so the site sits on one measure.

     NOT --brand-measure, which is 680px. That is a prose measure (how wide a
     paragraph may run); this is the content column. Two jobs, two numbers, and
     reaching for the wrong one halves the page. */
  --brand-page-max: 1152px;                                                                /* [c4.12] */

  /* The five card steps, at their post-3.3 weights. */
  --brand-card-size-name: 15px;                                                            /* [c2.5] */
  --brand-card-size-chip: 10px;                                                            /* [c2.5] */
  --brand-card-size-kicker: 9.5px;                                                         /* [c2.5] */
  --brand-card-size-owner: 8.5px;                                                          /* [c2.5] */
  --brand-card-size-mark: 7.5px;                                                           /* [c2.5] */

  /* Weights. Three, plus 400 on running prose only. 800 and 900 are gone. */
  --brand-weight-500: 500;                                                                 /* [c2.3.1] */
  --brand-weight-600: 600;                                                                 /* [c2.3.1] */
  --brand-weight-700: 700;                                                                 /* [c2.3.1] */
  --brand-weight-prose: 400;                                                               /* [c2.3.2] */

  /* THE TABLE VOICE. RULED 2026-07-31 (JD): every table on the site goes
     uniformly heavier, standings and schedule and players together, and it
     moves from one line. `.b-td` reads this and nothing else does, so this IS
     that line.

     It is a token of its own rather than a change to --brand-weight-prose,
     which .b-td used to read. That token has five other consumers and not one
     of them is a table: .b-body, the two .b-person rules, .b-team-full-manager,
     .b-team-number-ow, and .b-w400 — the utility whose entire meaning is the
     number 400. Flipping it would have moved all six and made .b-w400 emit
     500. See chapter 3 section 2.2.2. */
  --brand-weight-td: 500;                                                                  /* [c3.2.2.2] */

  /* Line heights. Four. Marker's .78 is ruled by its own role. */
  --brand-lh-1: 1;                                                                         /* [c2.6.1] */
  --brand-lh-125: 1.25;                                                                    /* [c2.6.1] */
  --brand-lh-1375: 1.375;                                                                  /* [c2.6.1] */
  --brand-lh-1625: 1.625;                                                                  /* [c2.6.1] */
  --brand-lh-marker: .78;                                                                  /* [c2.2.12] */

  /* Tracking. Three, plus the global .2px floor everything inherits. */
  --brand-track-1: .025em;                                                                 /* [c2.6.2] */
  --brand-track-2: .05em;                                                                  /* [c2.6.2] */
  --brand-track-3: .1em;                                                                   /* [c2.6.2] */
  --brand-track-floor: .2px;                                                               /* [c2.6.2] */

  /* Colour. See CONF-1: this sheet defines its own gold and never reads
     --corp-gold, which now maps to red. */
  --brand-gold: #F5C860;                                                                   /* [DL-5] */
  --brand-red: #FF3D2E;                                                                    /* [DL-5] */
  /* Champion. One meaning, two forms: the sheen on type, the flat where there
     is no type. The flat is also the sheen's fallback. Angle and stops are not
     arithmetic — JD picked them off five drawn options, 2026-07-29. See DL-5d.
     The -rgb triplet exists so a row tint can keep the alpha it already had;
     no champion alpha is ruled. */
  --brand-champion-sheen: linear-gradient(100deg, #C9A24A 0%, #FFE9A8 42%, #F5C860 58%, #C9A24A 100%); /* [DL-5d] */
  --brand-champion-flat: #F7E7B4;                                                          /* [DL-5d] */
  --brand-champion-flat-rgb: 247, 231, 180;                                                /* [DL-5d] */
  --brand-green-action: #3FE0A0;                                                           /* [DL-5] */
  /* Violet, the rare exception. RULED 2026-08-12. Hue 276 is the midpoint of the
     only empty arc left on the wheel, saturation 94 is the median of the five
     named colours, and lightness 78 is set by contrast: 8.87:1 against the
     inverse ink, between red's 5.73 and teal's 13.41, the two badge fills it
     shares the play card with. No alpha ramp — one call site, no dilution asked
     for, and chapter 5 section 1.5 rules against emitting steps nothing uses. */
  --brand-violet: #D192FC;                                                                 /* [DL-5f] */
  --brand-teal: #3BE6FF;                                                                   /* [c1.1.3.1] */
  --brand-ink: #F5F7FA;                                                                    /* [c1.1.4.8] */
  --brand-ink-muted: #7E838C;                                                              /* [c1.1.4.8] */
  --brand-card-bg: #0d131d;                                                                /* [c1.1.4.8] */
  --brand-hair: rgba(147,164,182,.14);                                                     /* [c1.1.4.8] */
  --brand-page-bg: #04070B;                                                                /* [SPEC-FORM] */

  /* ============================================================
     THE ALPHA RAMP. RULED 2026-07-31 (JD). Chapter 5 section 1.

     183 sites across src were diluting the four ruled accents by hand, at 5 to
     13 different opacities each. This is the ladder they come onto: six steps,
     one ladder, four colours.

     THE STEP NAMES THE JOB BECAUSE THE DATA NAMED IT. Fills live between .05
     and .22, edges between .30 and .80, and only three sites out of 183 cross
     between the bands. See chapter 5 section 1.2.

     EACH STEP CARRIES A WHOLE rgba() AND THAT IS NOT A STYLE CHOICE. A var()
     holding a hex cannot take a Tailwind /alpha modifier: the modifier is
     resolved at build time, var() is not, and the modifier is silently dropped.
     83 sites would have rendered fully opaque with no error anywhere. Chapter 5
     section 1.4. A call site writes bg-[color:var(--brand-teal-fill-medium)].

     Two of the 24 have no call site today, deliberately, and chapter 5 section
     1.5 names them: --brand-gold-edge-faint and --brand-green-fill-strong.
     ============================================================ */
  /* teal #3BE6FF at the six ruled steps. */
  --brand-teal-fill-faint: rgba(59,230,255,.07);                                          /* [c5.1.1.1] */
  --brand-teal-fill-medium: rgba(59,230,255,.12);                                         /* [c5.1.1.2] */
  --brand-teal-fill-strong: rgba(59,230,255,.20);                                         /* [c5.1.1.3] */
  --brand-teal-edge-faint: rgba(59,230,255,.30);                                          /* [c5.1.1.4] */
  --brand-teal-edge-medium: rgba(59,230,255,.45);                                         /* [c5.1.1.5] */
  --brand-teal-edge-strong: rgba(59,230,255,.70);                                         /* [c5.1.1.6] */
  /* red #FF3D2E at the six ruled steps. */
  --brand-red-fill-faint: rgba(255,61,46,.07);                                            /* [c5.1.1.1] */
  --brand-red-fill-medium: rgba(255,61,46,.12);                                           /* [c5.1.1.2] */
  --brand-red-fill-strong: rgba(255,61,46,.20);                                           /* [c5.1.1.3] */
  --brand-red-edge-faint: rgba(255,61,46,.30);                                            /* [c5.1.1.4] */
  --brand-red-edge-medium: rgba(255,61,46,.45);                                           /* [c5.1.1.5] */
  --brand-red-edge-strong: rgba(255,61,46,.70);                                           /* [c5.1.1.6] */
  /* gold #F5C860 at the six ruled steps. */
  --brand-gold-fill-faint: rgba(245,200,96,.07);                                          /* [c5.1.1.1] */
  --brand-gold-fill-medium: rgba(245,200,96,.12);                                         /* [c5.1.1.2] */
  --brand-gold-fill-strong: rgba(245,200,96,.20);                                         /* [c5.1.1.3] */
  --brand-gold-edge-faint: rgba(245,200,96,.30);                                          /* [c5.1.1.4] */
  --brand-gold-edge-medium: rgba(245,200,96,.45);                                         /* [c5.1.1.5] */
  --brand-gold-edge-strong: rgba(245,200,96,.70);                                         /* [c5.1.1.6] */
  /* green #3FE0A0 at the six ruled steps. */
  --brand-green-fill-faint: rgba(63,224,160,.07);                                         /* [c5.1.1.1] */
  --brand-green-fill-medium: rgba(63,224,160,.12);                                        /* [c5.1.1.2] */
  --brand-green-fill-strong: rgba(63,224,160,.20);                                        /* [c5.1.1.3] */
  --brand-green-edge-faint: rgba(63,224,160,.30);                                         /* [c5.1.1.4] */
  --brand-green-edge-medium: rgba(63,224,160,.45);                                        /* [c5.1.1.5] */
  --brand-green-edge-strong: rgba(63,224,160,.70);                                        /* [c5.1.1.6] */
  /* The hover rung. RULED 2026-07-30 (JD, DECISIONS-05 D-11, option H1), and it
     closes OUT-10. Section 2.7 rules one hover alpha and names no number, and
     the reason none of the four in use could be it: the row that needed a hover
     is filled `bg-corp-bg-subtle` #18222f, which is the LIGHTEST opaque
     background on the site. There was no rung above it, so the two values D-11
     offered failed from opposite ends — `bg-corp-bg-hover` #121a25 is one rung
     DOWN and the row you point at goes darker, `bg-corp-bg-subtle` repaints the
     colour already there.
     THE VALUE IS DERIVED, NOT PICKED BY EYE. The ramp is #04070B → #0d131d →
     #121a25 → #18222f and each step adds +6 / +8 / +10 per channel. #1E2A39 is
     the next one by that same arithmetic. It is a new value and this sheet says
     so rather than burying it: the ramp had nothing above the row's own fill,
     so one had to be added or nothing lifts. Written by `.b-row-hover` below. */
  --brand-bg-raised: #1E2A39;                                                              /* [c3.2.7] */
  --brand-panel: rgba(15,21,31,.975);                                                      /* [PANEL-C] */
  --brand-panel2: rgba(11,16,25,.985);                                                     /* [PANEL-C] */
  --brand-dim: .55;                                                                        /* [c1.4.1] */

  /* Card geometry. Emitted as properties as well as classes so a component
     can set them inline and satisfy chapter 1 section 4.2. See CONF-8. */
  --brand-player-full-w: 220px;                                                            /* [c1.1.1] */
  --brand-player-full-h: 62px;                                                             /* [c1.1.1] */
  --brand-player-row-h: 28px;                                                              /* [c1.1.2] */
  /* Player/Line, the ninth variant (JD 2026-07-29). 32 is the rendered rule on
     his sheet; the 36 in that sheet's summary panel has no derivation and is
     not emitted. 254 is a MAXIMUM, from the longest real name plus an injury,
     not a pin — the list takes its width from its container below that. The
     38px rail is derived: 16 + 6 + 16. See chapter 1 sections 1.17.1 and
     1.17.2. */
  --brand-player-line-h: 32px;                                                             /* [c1.1.17.2] */
  --brand-player-line-max-w: 254px;                                                        /* [c1.1.17.1] */
  --brand-player-line-rail-w: 38px;                                                        /* [c1.1.17] */
  --brand-player-line-rail-gap: 6px;                                                       /* [c1.1.17] */
  --brand-player-line-mark: 16px;                                                          /* [c1.1.17] */
  --brand-player-line-pos: 20px;                                                           /* [c1.1.17] */
  --brand-player-line-inj: 12px;                                                           /* [c1.1.17] */
  /* The row's air, ruled onto the sheet 2026-07-31 (JD) with DESIGN-LAWS 11.
     Both are EXTRACTED — what the row has rendered since it was built, carried
     over value for value. Neither derives from anything and section 1.17.11
     does not invent a derivation for them. */
  --brand-player-line-gap: 5px;                                                            /* [c1.1.17.11] */
  --brand-player-line-pad-x: 5px;                                                          /* [c1.1.17.11] */
  --brand-player-line-name-gap: 3px;                                                       /* [c1.1.17.11] */
  /* Lineup/Slot, the tenth variant (JD 2026-07-30, chapter 4 section 10.1).
     56 is DERIVED and is the only derived number here: the face is 46 and the
     row gives it 5 of air top and bottom. The face is the constraint, so if
     the face moves this number moves with it and nothing else does. The rest
     are the numbers the ruled card drew at true size, and each carries its
     reason in the 10.1.1 table: the chip is 32 wide because a three-letter
     slot code does not fit the 20px square of 1.17, and the game-time column
     is 64 because that holds the longest real value without wrapping. */
  --brand-lineup-slot-h: 56px;                                                             /* [c4.10.1.1] */
  --brand-lineup-slot-chip-w: 32px;                                                        /* [c4.10.1.1] */
  --brand-lineup-slot-chip-h: 24px;                                                        /* [c4.10.1.1] */
  --brand-lineup-slot-face: 46px;                                                          /* [c4.10.1.1] */
  --brand-lineup-slot-mark: 20px;                                                          /* [c4.10.1.1] */
  --brand-lineup-slot-time-w: 64px;                                                        /* [c4.10.1.1] */
  --brand-lineup-slot-gap: 8px;                                                            /* [c4.10.1.1] */
  --brand-lineup-slot-pad: 8px;                                                            /* [c4.10.1.1] */
  --brand-team-full-w: 220px;                                                              /* [c1.1.3] */
  --brand-team-full-h: 62px;                                                               /* [c1.1.3] */
  /* AMENDED 2026-07-28 by JD. Team/Number carries NO width of its own: it
     takes its width from the column. 96 is the column's MINIMUM and the floor
     lives once, on the board table (BOARD_DESIGN_MIN), never on the card.
     This property is the board's floor, not a card width. Do not restore the
     pin: a 96 floor on the card pushes the head 1px past its 95px cells at
     the design minimum, which is the defect the ruling removed. */
  --brand-board-column-min: 96px;                                                          /* [c1.1.4.0] */
  --brand-team-number-h: 56px;                                                             /* [c1.1.4.8] */
  --brand-team-chip-w: 168px;                                                              /* [c1.1.14.1] */
  --brand-team-chip-mark-reserve: 17px;                                                    /* [c1.1.14.1] */
  --brand-pick-cell-h: 28px;                                                               /* [c1.1.9] */
  --brand-card-radius: 8px;                                                                /* [c1.1.4.8] */

  /* THE TABLE DEFINITION. One cell padding and one header padding for every
     table on the site. These are consumed, not targets: see the TABLES
     block below. Values are what the front page rendered on 2026-07-28,
     measured off page.tsx, so nothing moved when the definition landed.

     --brand-row IS NO LONGER CONSUMED. JD ruled the cell's leading on
     2026-07-29 (see OUT-12): a line in a cell takes the ratio 1.25, so the
     row height is now PRODUCED by the ruled leading instead of pinned by
     this pixel. The declaration stays because five comments in two files
     under src/ still name it (src/app/page.tsx lines 2122 and 2234;
     src/components/dashboard/DashboardStandingsCard.tsx lines 309, 320 and
     443) and those comments are now stale. Nothing reads the value.
     Changing it moves nothing. Change --brand-lh-125 to move every row. */
  --brand-row: 16px;                                                                       /* [c3.1] */
  --brand-cell-x: 12px;                                                                    /* [c3.2.2] */
  --brand-header-y: 12px;                                                                  /* [c3.2.1] */

  /* --brand-sort-gap (4px) and --brand-sort-inactive (.45) STOOD HERE and are
     DELETED, 2026-07-31. Both were extracted on 07-29 for the sort arrow, and
     chapter 3 section 2.11.2 killed the arrow, so both lost their only
     consumer. Left declared they would be a second --brand-row: a variable
     nothing reads, which section 1.8 already names as the mistake to not
     repeat. The sorted column is lit instead; see .b-sort below. */

  /* The game row. Chapter 3 section 6, RULED 2026-07-31 (JD), design A.
     38 is EXTRACTED — BracketView.tsx:131 already rendered its team rows at 38
     and does so unchanged after the conversion (section 6.2). 56 is EXTRACTED —
     MyMatchupCard's shipped desktop rail, 3.5rem, and the median of the seven
     rail widths the inventory found (section 6.3). 76 is JD's off the rendered
     page and has no derivation; section 6.3 says so rather than inventing one. */
  --brand-game-line: 38px;                                                                 /* [c3.6.2] */
  --brand-game-score: 56px;                                                                /* [c3.6.3] */
  --brand-game-status: 76px;                                                               /* [c3.6.3] */
}


/* =========================================================================
   THE OPT-IN SCOPE
   `.b-scope` is the one place this sheet sets anything that inherits. Put
   it on a wrapper and everything inside picks up the text family and the
   global letter-spacing floor. Nothing else in this file inherits.
   ========================================================================= */

.b-scope {
  font-family: var(--brand-font-text);                                                     /* [c2.1.2] */
  letter-spacing: var(--brand-track-floor);                                                /* [c2.6.2] */
  color: var(--brand-ink);                                                                 /* [c1.1.4.8] */
}


/* =========================================================================
   THE NINE PAGE TYPE ROLES
   Nine, and only nine, plus the five card steps below. A size on neither
   list is a defect, not a variant [c2.8]. It was eight until 2026-07-29,
   when JD ruled Panel in [c2.2.22].
   ========================================================================= */

.b-title { /* [c2.2.1] */
  font-family: var(--brand-font-display);
  font-size: var(--brand-size-title);
  font-weight: var(--brand-weight-600);
  letter-spacing: -.025em;
}

.b-title-step2 { /* [c2.2.1] */
  font-family: var(--brand-font-display);
  font-size: var(--brand-size-title-step2);
  font-weight: var(--brand-weight-600);
  letter-spacing: -.025em;
}

.b-title-step1 { /* [c2.2.1] */
  font-family: var(--brand-font-display);
  font-size: var(--brand-size-title-step1);
  font-weight: var(--brand-weight-600);
  letter-spacing: -.025em;
}

/* THE TRACKING FLOOR IS NOT DECLARED AWAY.
   Chapter 2 section 2.19 rules that `0` in the roles table means the role
   ADDS no tracking, not that it REMOVES the floor. `letter-spacing: 0` is
   not one of the three values section 6.2 permits, so declaring it was a
   defect in this sheet. A role that does not change tracking now declares
   none and the .2px floor on `.b-scope` inherits, which is what it is for.
   Only the roles that genuinely move it declare it: Title, Label, Micro. */
.b-heading { /* [c2.2.2] */
  font-family: var(--brand-font-display);
  font-size: var(--brand-size-heading);
  font-weight: var(--brand-weight-600);
}

/* PANEL IS THE NINTH ROLE. 18 IN THE TEXT FAMILY [c2.2.22].
   The line that names a block of interface inside a page: a panel title, a
   modal title, a step in a flow. Heading (2.2) is one level out, above a
   region, and it is Oswald.
   It exists because a role is taken whole [c2.2.21] — fifteen call sites want
   18 in the text family, and giving them Heading would drag the display face
   onto all fifteen. Weight 600 and mixed case are extracted from those fifteen,
   not chosen, and they are defaults the job may override [c2.2.13].
   No tracking declared: the role adds none and the .2px floor inherits
   [c2.2.19]. No leading: leading is not part of a role [c2.2.18]. */
.b-panel { /* [c2.2.22] */
  font-family: var(--brand-font-text);
  font-size: var(--brand-size-panel);
  font-weight: var(--brand-weight-600);
}

.b-label { /* [c2.2.3] */
  font-family: var(--brand-font-text);
  font-size: var(--brand-size-label);
  font-weight: var(--brand-weight-600);
  text-transform: uppercase;
  letter-spacing: var(--brand-track-2);
}

.b-body { /* [c2.2.4] */
  font-family: var(--brand-font-text);
  font-size: var(--brand-size-body);
  font-weight: var(--brand-weight-prose);
}

.b-dense { /* [c2.2.5] */
  font-family: var(--brand-font-text);
  font-size: var(--brand-size-dense);
  font-weight: var(--brand-weight-500);
}

/* Data is a treatment, not a size [c2.2.11]. It takes the size of the row it
   is in, so this block sets no font-size on purpose. */
.b-data { /* [c2.2.6] */
  font-family: var(--brand-font-display);
  font-weight: var(--brand-weight-600);
  font-variant-numeric: tabular-nums;
}

.b-micro { /* [c2.2.7] */
  font-family: var(--brand-font-text);
  font-size: var(--brand-size-micro);
  font-weight: var(--brand-weight-600);
  text-transform: uppercase;
  letter-spacing: var(--brand-track-2);
}

.b-marker { /* [c2.2.12] */
  font-family: var(--brand-font-text);
  font-size: var(--brand-size-marker);
  font-weight: var(--brand-weight-700);
  line-height: var(--brand-lh-marker);
}

/* A PERSON'S NAME IS NOT A LABEL.
   Chapter 2 section 2.13 rules that a role fixes the SIZE, and that weight
   and case belong to the job. It names one precedent by hand: a person's
   name takes 400 and mixed case where the role's default is 600 UPPER,
   because capitals shout a name. Inside a card that is already carried, by
   .b-team-number-ow and .b-team-full-manager. This is the same precedent at
   page level, and it is the only one of them.

   IT IS A MODIFIER, NOT A ROLE. It sets no size, so the role beside it keeps
   the size, which is the half 2.13 fixes. It only subtracts: the default
   weight and the default case go off, and nothing is added.

   WHY IT IS WRITTEN AS TWO CLASSES. `.b-label` alone is specificity 0,1,0
   and so is a Tailwind `font-normal`, which means load order decides which
   one renders and brand.css and Tailwind arrive by different routes. That is
   the fighter this replaces. `.b-label.b-person` is 0,2,0 and beats the role
   on specificity, so the answer does not depend on which sheet loads first.

   Both roles that carry an UPPER default are listed, because 2.13's named
   precedent is on Micro and the use that needed it is on Label.

   NAMED FOR THE JOB, NEVER FOR AN ARBITRARY VALUE [c2.2.15, narrowed by
   c2.2.17]. `.b-person` says what the text IS, not what it measures, and a
   job name beats a value name wherever both would work: if person-names ever
   move to 500 they move in one place, here. Reach for this one first.

   2.15 read as banning `.b-w400` and `.b-upper` outright. Section 2.17
   narrows that to what it was aimed at — a class named after a value a
   builder PICKED. Weight, case and leading are closed lists the chapter
   already ruled, and a class per member of a closed list is the list. Those
   ten classes are below, fenced, and they do not reach size or tracking.

   IT IS THE ONLY JOB MODIFIER. Not because a person's name is the only job
   that could have one, but because it is the only one that has been ruled.
   New ones are added by Taste, deliberately, as part of the guide. */
.b-label.b-person,
.b-micro.b-person { /* [c2.2.15] */
  font-weight: var(--brand-weight-prose);
  text-transform: none;
}


/* =========================================================================
   THE LIST MODIFIERS — weight, case, leading. Ten, and only ten.
   Chapter 2 section 2.13 rules that a role fixes the SIZE and that weight
   and case belong to the job. Section 2.17 rules the mechanism: weight, case
   and leading are each a list the chapter already CLOSED — three weights
   plus prose (section 3), two cases, four ratios (section 6.1). A class per
   member of a closed list IS the list, not a utility, which is exactly what
   the role classes above are for the size list.

   THE FENCE. These ten are the complete set and an eleventh is a defect.
   Size is not one of them: a role fixes the size, the half 2.13 kept.
   Tracking is not one: section 6.2's three values are carried by the roles
   that move them, and a nested case needing the floor back is a gap to
   report, not to fill.

   ONLY LEGAL BESIDE A ROLE. Alone, one of these sets a property with no size
   beside it, which is a value floating free — the thing this sheet exists to
   end.

   WHY EACH SELECTOR IS DOUBLED. `.b-w500` alone is 0,1,0, exactly like the
   role it must beat and exactly like a Tailwind `font-medium`, so load order
   would decide and brand.css and Tailwind arrive by different routes.
   `.b-w500.b-w500` is 0,2,0 and wins outright. It is the same specificity
   `.b-label.b-person` gets by naming its role. Doubled is used here because
   these apply against every role AND every card step, and a hand-listed set
   of sixty pairs would rot silently the first time a role was added.
   ========================================================================= */

/* WEIGHT — section 3's complete list. 400 is here because 2.13 names it as a
   job weight (the owner on Team / Number), which is narrower than 3.2's
   "browser default on running prose" and does not contradict it. */
.b-w400.b-w400 { font-weight: var(--brand-weight-prose); }                                 /* [c2.2.17] */
.b-w500.b-w500 { font-weight: var(--brand-weight-500); }                                   /* [c2.2.17] */
.b-w600.b-w600 { font-weight: var(--brand-weight-600); }                                   /* [c2.2.17] */
.b-w700.b-w700 { font-weight: var(--brand-weight-700); }                                   /* [c2.2.17] */

/* CASE — two. `.b-upper` is also the destination section 6.3 needs: the 82
   places that uppercase the string in JavaScript move the transform here,
   where a screen reader reads the word instead of spelling it out. */
.b-upper.b-upper { text-transform: uppercase; }                                            /* [c2.2.17] */
.b-mixed.b-mixed { text-transform: none; }                                                 /* [c2.2.17] */

/* LEADING — section 6.1's four RATIOS, for flowing text. Text that lands on
   fixed marks takes a pixel value instead and carries it on its own component
   class, never one of these; see section 2.14 and `.b-team-number-l1` below.
   Leading is not part of a role on purpose: the same role runs at different
   densities, Body at 1.625 in a paragraph and 1.25 in a tight row. */
.b-lh-1.b-lh-1       { line-height: var(--brand-lh-1); }                                   /* [c2.2.18] */
.b-lh-125.b-lh-125   { line-height: var(--brand-lh-125); }                                 /* [c2.2.18] */
.b-lh-1375.b-lh-1375 { line-height: var(--brand-lh-1375); }                                /* [c2.2.18] */
.b-lh-1625.b-lh-1625 { line-height: var(--brand-lh-1625); }                                /* [c2.2.18] */


/* =========================================================================
   THE FIVE CARD STEPS
   Scoped to cards. Weights are post-3.3: where these read 800 before, they
   read 700 [c2.5.1].
   ========================================================================= */

.b-step-name { /* [c2.5] */
  font-size: var(--brand-card-size-name);
  font-weight: var(--brand-weight-700);
}

.b-step-chip { /* [c2.5] */
  font-size: var(--brand-card-size-chip);
  font-weight: var(--brand-weight-700);
}

.b-step-kicker { /* [c2.5] */
  font-size: var(--brand-card-size-kicker);
  font-weight: var(--brand-weight-600);
}

.b-step-owner { /* [c2.5] */
  font-size: var(--brand-card-size-owner);
  font-weight: var(--brand-weight-700);
}

.b-step-mark { /* [c2.5] */
  font-size: var(--brand-card-size-mark);
  font-weight: var(--brand-weight-700);
}


/* =========================================================================
   THE CARD SHELL
   Ruled at 1.4.8 and repeated verbatim at 1.3.1 ("same shell as 1.4.8").
   No other variant has a ruled shell, so no other variant gets one here.
   ========================================================================= */

.b-card-shell { /* [c1.1.4.8] */
  position: relative;
  isolation: isolate;
  box-sizing: border-box;
  background-color: var(--brand-card-bg);
  border: 1px solid var(--brand-hair);
  border-radius: var(--brand-card-radius);
  overflow: hidden;
}


/* =========================================================================
   VARIANT 1.1 . PLAYER / FULL . 220 x 62 fixed
   The box is ruled. The anatomy is not. See OUT-13.
   ========================================================================= */

.b-player-full { /* [c1.1.1] */
  width: var(--brand-player-full-w);
  height: var(--brand-player-full-h);
  box-sizing: border-box;
}


/* =========================================================================
   VARIANT 1.2 . PLAYER / ROW . 28px tall, width from the grid
   No width is declared: the grid owns it.
   ========================================================================= */

.b-player-row { /* [c1.1.2] */
  height: var(--brand-player-row-h);
  box-sizing: border-box;
}


/* =========================================================================
   VARIANT 1.17 . PLAYER / LINE . 32 tall, width from the list, 254 max
   The ninth variant, ruled in by JD on 2026-07-29. Geometry only.

   WHAT IS NOT HERE, AND WHY
   The row's type is off the chapter 2 section 5 card scale in three places
   (12.5 last name, 10.5 first name, 7 on the FA pill) and chapter 1 section
   1.17.4 records that as a question for the type pass rather than answering
   it. Emitting those sizes here would fail check 3 of the checker, which is
   the checker doing its job. No font-size is declared for this variant.
   Colours are the same: the POS hue and the owner hue are data and arrive
   per element, as everywhere else. See OPEN-4.
   ========================================================================= */

.b-player-line-list { /* [c1.1.17.1] */
  width: 100%;
  max-width: var(--brand-player-line-max-w);
  box-sizing: border-box;
  overflow: hidden;
}

/* No width: the list owns it. The height is the ruled part. */
.b-player-line { /* [c1.1.17.2] */
  height: var(--brand-player-line-h);
  box-sizing: border-box;
}

/* The row as a flex line, with its air. Ruled 2026-07-31 (JD): the last four
   numbers Player/Line wrote at its call site come here, so no number in this
   variant is written in src/ any more.

   It carries NO height and NO max-width. Those are already `.b-player-line`
   and `.b-player-line-list` above, and a second copy beside them would be the
   thing section 1.17.11 exists to stop. A row wears all three. */
.b-player-line-row { /* [c1.1.17.11] */
  display: flex;
  align-items: center;
  gap: var(--brand-player-line-gap);
  padding: 0 var(--brand-player-line-pad-x);
}

/* The first name, the last name and the injury badge as one group. The
   alignment is flex-END, not centre: the first name renders a step smaller
   than the last name and the two share a baseline. Centre is the obvious
   guess and it moves the render. */
.b-player-line-name-rail { /* [c1.1.17.11] */
  display: flex;
  align-items: flex-end;
  gap: var(--brand-player-line-name-gap);
  flex: 1 1 0%;
  min-width: 0;
}

/* Leading, fixed, never shrinks. Two-letter position code. */
.b-player-line-pos { /* [c1.1.17] */
  flex: 0 0 auto;
  width: var(--brand-player-line-pos);
  height: var(--brand-player-line-pos);
}

/* Inline after the last name, not a corner badge. */
.b-player-line-inj { /* [c1.1.17] */
  flex: 0 0 auto;
  width: var(--brand-player-line-inj);
  height: var(--brand-player-line-inj);
}

/* The trailing rail is fixed at 16 + 6 + 16 so both marks land on the same
   two x-positions down the whole list whether or not a player carries both.
   Same reserved-gutter mechanism as section 3.1. */
.b-player-line-rail { /* [c1.1.17] */
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  width: var(--brand-player-line-rail-w);
  gap: var(--brand-player-line-rail-gap);
}

.b-player-line-mark { /* [c1.1.17] */
  flex: 0 0 auto;
  width: var(--brand-player-line-mark);
  height: var(--brand-player-line-mark);
}


/* =========================================================================
   VARIANT 1.3 . TEAM / FULL . 220 x 62 fixed
   Anatomy from 1.3.1. Values are from public/team-full-final.html, not from
   prose. The two marks sit at the edges and the text runs over them.
   ========================================================================= */

.b-team-full { /* [c1.1.3.1] */
  width: var(--brand-team-full-w);
  height: var(--brand-team-full-h);
  box-sizing: border-box;
}

/* Manager initials at Marker. Tracking -.02em closes up a two-letter pair;
   that value is on no list, see CONF-5. Colour is the team hue and arrives
   per element, see OPEN-4. */
.b-team-full-mono { /* [c1.1.3.1] */
  position: absolute;
  left: 4px;
  top: 50%;
  transform: translateY(-50%);
  font-family: var(--brand-font-text);
  font-size: var(--brand-size-marker);
  font-weight: var(--brand-weight-700);
  line-height: var(--brand-lh-marker);
  letter-spacing: -.02em;
  opacity: .25;
  z-index: 1;
  pointer-events: none;
  user-select: none;
}

/* The portrait mask is the 1.4.8 mask reversed. */
.b-team-full-oil { /* [c1.1.3.1] */
  position: absolute;
  right: -8px;
  top: 0;
  width: 62px;
  height: 62px;
  object-fit: cover;
  object-position: 50% 30%;
  opacity: .25;
  z-index: 1;
  pointer-events: none;
  -webkit-mask-image: linear-gradient(to left, #000 0%, #000 45%, transparent 100%);
  mask-image: linear-gradient(to left, #000 0%, #000 45%, transparent 100%);
}

.b-team-full-text { /* [c1.1.3.1] */
  position: absolute;
  left: 6px;
  right: 6px;
  top: 50%;
  transform: translateY(-50%);
  z-index: 2;
  text-align: center;
}

/* 12/700 is the Dense size at a weight Dense does not carry, exactly as
   CLOSED-1 covers on Team/Number. line-height 14px is in the band chapter 2
   section 6.1 collapses to 1.25. See CONF-6. */
.b-team-full-name { /* [c1.1.3.1] */
  font-size: var(--brand-size-dense);
  font-weight: var(--brand-weight-700);
  line-height: 14px;
  color: var(--brand-ink);
  white-space: nowrap;
}

/* Label's size, not Label's treatment. Chapter 1 section 1.3.3 records this
   so the next reader does not "fix" it. line-height 12px, see CONF-6. */
.b-team-full-manager { /* [c1.1.3.1] */
  font-size: var(--brand-size-label);
  font-weight: var(--brand-weight-prose);
  line-height: 12px;
  color: var(--brand-ink-muted);
  white-space: nowrap;
  margin-top: 1px;
}

/* Teal, not gold. Gold means yours [c1.1.3.2]. See CONF-2. */
.b-team-full-status { /* [c1.1.3.1] */
  font-size: var(--brand-size-label);
  font-weight: var(--brand-weight-600);
  line-height: 12px;
  color: var(--brand-teal);
  letter-spacing: var(--brand-track-2);
  white-space: nowrap;
  margin-top: 1px;
}

/* Division block. The half-pixel margin is compensation for the half-pixel
   outline, not spacing. Division colour comes from the existing
   divisionPill helper and arrives per element. */
.b-team-full-div { /* [c1.1.3.1] */
  display: inline-block;
  width: 12px;
  height: 7px;
  border-radius: 2px;
  box-sizing: border-box;
  box-shadow: 0 0 0 .5px rgba(59,230,255,.55);
  margin-right: .5px;
  vertical-align: middle;
  position: relative;
  top: -1px;
}


/* =========================================================================
   VARIANT 1.4 . TEAM / NUMBER . 56 TALL, WIDTH FROM THE COLUMN
   THE LIVE ANATOMY IS 1.4.8 AND NOTHING ELSE. 1.4.1 through 1.4.7 is
   superseded trail. There is no circle. Values are from
   public/team-number-final.html, not from prose.
   AMENDED 2026-07-28 by JD [c1.1.4.0]: the card stretches with its column so
   the head and the cells below it share an edge at every viewport. 96 is the
   column's minimum, 1152 divided by 12, and it lives on the board table.
   Every measurement here is quoted at that 96 minimum. See CLOSED-2.
   ========================================================================= */

/* No width rule. The card takes its width from the column it sits in, and the
   height is the one fixed dimension. What does not grow: the Marker numeral,
   the oil portrait, and this height. */
.b-team-number { /* [c1.1.4.8] */
  height: var(--brand-team-number-h);
  box-sizing: border-box;
}

/* THE FLOOR, AND IT LIVES HERE ONLY. The board table carries the minimum for
   all twelve columns at once, which is what BOARD_DESIGN_MIN already does:
   2rem + 12 x 6rem + 1rem, where the 6rem is 1152 divided by 12. Never put a
   floor on a card. */
.b-board-table { /* [c1.1.4.0] */
  min-width: calc(2rem + 12 * var(--brand-board-column-min) + 1rem);
}

/* SPECIMEN DEVICE, NOT A CARD WIDTH. The proof page puts every card in a 96px
   box so the diff against JD's approved mock still means something. This is
   that box. It belongs to a specimen page and never to the board. */
.b-spec-column { /* [c1.1.4.0] */
  width: var(--brand-board-column-min);
}

/* The same specimen device at the far end of the range: the head measures
   154.33px at 2560, which is what "it stretches" looks like. */
.b-spec-column-wide { /* [c1.1.4.0] */
  width: 154px;
}

/* The manager's oil portrait is the card's ground: clipped by the card and
   masked to transparent from 45% across so it fades rather than cutting. */
.b-team-number-oil { /* [c1.1.4.8] */
  position: absolute;
  left: -10px;
  top: 0;
  width: 56px;
  height: 56px;
  object-fit: cover;
  object-position: 50% 30%;
  opacity: .15;
  z-index: 1;
  pointer-events: none;
  user-select: none;
  -webkit-mask-image: linear-gradient(to right, #000 0%, #000 45%, transparent 100%);
  mask-image: linear-gradient(to right, #000 0%, #000 45%, transparent 100%);
}

/* The number is a watermark, not a chip: full card height, team hue at 25%,
   behind everything, bottom-right anchored and vertically centred. Real
   text, never an image. The hue arrives per element, see OPEN-4. */
.b-team-number-marker { /* [c1.1.4.8] */
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  box-sizing: border-box;
  padding-right: 4px;
  padding-bottom: 8px;
  font-family: var(--brand-font-text);
  font-size: var(--brand-size-marker);
  font-weight: var(--brand-weight-700);
  line-height: var(--brand-lh-marker);
  /* KEPT, and ch2 section 2.19 does not reach it. That rule deletes
     `letter-spacing: 0` from the ROLE classes, where it was switching off the
     .2px floor. This is a component class on an approved surface, and section
     2.12 rules by name that Marker does not fix tracking: at 50px it is optical
     and belongs to the use. Team / Full closes a letter pair at -.02em, this one
     sets none. That is the use saying "none", not a role dropping the floor. */
  letter-spacing: 0;
  opacity: .25;
  pointer-events: none;
  user-select: none;
}

/* Nothing sits beside the text, so the text centres on the card itself.
   The approved mock writes left 47px and an 86px span. AMENDED 2026-07-28
   [c1.1.4.0]: both are percentages of the padding box now, so they widen with
   the column. At the 96 minimum they compute to exactly the approved numbers
   (94px padding box: 50% = 47, 100% - 8px = 86) and grow from there. DO NOT
   PUT THE LITERAL NUMBERS BACK. That is the pin the ruling removed. */
.b-team-number-line { /* [c1.1.4.8] */
  position: absolute;
  left: 50%;
  width: calc(100% - 8px);
  transform: translateX(-50%);
  white-space: nowrap;
  text-align: center;
  z-index: 2;
}

/* 12/700 and line-height 13px. Dense is 500 and 13px is on none of the four
   ruled leadings. Both now RULED LEGITIMATE — ch2 2.13 (weight belongs to
   the job) and ch2 2.14 (grid-pinned leading). See CLOSED-1. */
.b-team-number-l1 { /* [c1.1.4.8] */
  top: 10px;
  font-size: var(--brand-size-dense);
  font-weight: var(--brand-weight-700);
  line-height: 13px;
  color: var(--brand-ink);
}

.b-team-number-l2 { /* [c1.1.4.8] */
  top: 23px;
  font-size: var(--brand-size-dense);
  font-weight: var(--brand-weight-700);
  line-height: 13px;
  color: var(--brand-ink);
}

/* 8/400 mixed case. Micro's DEFAULT is 8/600/UPPER/.05em; weight and case
   belong to the job (ch2 2.13), and a person's name is not a label. See
   CLOSED-1.
   line-height 10px is 1.25 at 8px, which is on the ruled list. */
.b-team-number-ow { /* [c1.1.4.8] */
  top: 37px;
  font-size: var(--brand-size-micro);
  font-weight: var(--brand-weight-prose);
  line-height: 10px;
  color: var(--brand-ink-muted);
}


/* =========================================================================
   VARIANT 1.7 . TEAM / CHIP . 168px fixed
   168 = 151 for "Outkicking the Coverage" plus 17px permanently reserved
   for the response mark [c1.1.14.1]. The mark is leading [c1.2.3], so the
   reserve sits at the start of the line. Short names take the slack as
   trailing space: a column of chips is read down its left edge, so they are
   not padded to centre. See CONF-3 and CONF-9.
   ========================================================================= */

.b-team-chip { /* [c1.1.14.1] */
  width: var(--brand-team-chip-w);
  box-sizing: border-box;
  text-align: left;
  padding-left: var(--brand-team-chip-mark-reserve);
}


/* =========================================================================
   VARIANT 1.13 . TEAM / MENTION . intrinsic, hugs its name
   A fixed-width chip mid-sentence tears a hole in the line and reads as a
   button rather than a name.
   ========================================================================= */

.b-team-mention { /* [c1.1.13] */
  display: inline-block;
}


/* =========================================================================
   VARIANT 1.8 . PICK / ASSET . intrinsic, grows
   ========================================================================= */

.b-pick-asset { /* [c1.1.8] */
  display: inline-block;
}


/* =========================================================================
   VARIANT 1.9 . PICK / CELL . 28px tall, width from the grid
   Height and "width from the grid" both verified against the real cell at
   chapter 1 section 2.3.2 (h-7, w-full min-w-0).
   ========================================================================= */

.b-pick-cell { /* [c1.2.3.2] */
  height: var(--brand-pick-cell-h);
  width: 100%;
  min-width: 0;
  box-sizing: border-box;
}


/* =========================================================================
   OVERFLOW . the doctrine, as the per-field mechanisms in 3.5
   Four mechanisms exist and every text field uses exactly one.
     player last name, first name . ellipsis
     player status kicker         . reserved gutter, then ellipsis
     team name                    . wrap to two, then stop. Never dots.
     manager, owner, subtitle, place . ellipsis
     NFL watermark                . clip
   The reserved gutter has one ruled width in the whole ruleset, the chip's
   17px, which is emitted on .b-team-chip above. See OUT-14.
   ========================================================================= */

.b-ellipsis { /* [c1.3.5] */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Team names wrap and never take dots. "Then stop" cannot be expressed
   without clipping the third line, and clipped text is a section 3.4
   violation, so nothing here clips. A third line cannot occur at all —
   see CLOSED-3. */
.b-wrap-two { /* [c1.3.5] */
  white-space: normal;
  overflow-wrap: normal;
}

/* Clip is permitted for decoration only, never for text. */
.b-clip-decoration { /* [c1.3.4] */
  overflow: hidden;
}


/* =========================================================================
   APPEARANCE
   Brightness is the only permitted appearance variable. Dim is 0.55 and it
   means NOT YET REAL: not started, on the bench, inactive. It never means
   "less important". One meaning, whole site.
   ========================================================================= */

.b-dim { /* [c1.4.1] */
  opacity: var(--brand-dim);
}


/* =========================================================================
   TABLES
   A table is not a <table> [c3.0]: five of the ordinary tables are built out
   of grid and every rule here applies to them too. Type comes entirely from
   chapter 2.

   REACH, RULED 2026-07-29 (JD): ORDINARY TABLES ONLY. Two worlds are
   permanently outside these rules, the same way /sidebets' red caution box
   and the draft grid's Pick/Cell square are outside the card rules: the
   /history page, including its heat map, and the hall of champions. The heat
   map is a grid of equal coloured squares rather than a list, and centring is
   what makes it read as a grid; the hall is a deliberately different world
   and follows the hall. So "every rule here" means every ordinary table,
   whether it is a <table> or a grid — never those two. Nothing in this block
   is emitted at them and nothing here should be read as reaching them.
   ========================================================================= */

/* One hairline, one alpha. Collapsed borders are what make the line between
   two rows one line instead of two. No zebra striping, ever: this sheet
   emits no nth-child rule of any kind. See OUT-7. */
.b-table { /* [c3.2.5] */
  border-collapse: collapse;
}

/* ---- THE ROW ------------------------------------------------------------
   One leading, one cell padding, for every table on the site. Height is
   carried by line-height rather than by padding, because a cell with no
   vertical padding measures exactly its leading and a padding value would
   have to be re-derived per font size.

   THE ROW IS A RESULT, NOT A PIN. RULED 2026-07-29 (JD), see OUT-12: a line
   in a cell takes the ratio 1.25 [c2.6.1]. A ratio does NOT produce one box
   from two font sizes — measured on this page, a 12px Dense cell comes out at
   15 and a 14px Body cell at 17.5. JD ruled it knowing that: his option read
   "every table, slightly tighter". So there is one LEADING for every table,
   and the old claim of one 16px box from both sizes is gone with the pixel
   that made it.

   The row still grows: two lines of a wrapped team name [c3.2.4] measure
   double, and a taller child (the rank medallion on the front page) measures
   the row as it always did.

   ONE CELL DOES NOT DROP BELOW ITS ROW. RULED 2026-07-29 (JD). Ten cells in
   the standings table were at Body and the eleventh, Breakdown, was at the
   compact size, on the standings page and on the GM desk both, with nothing
   saying why. It comes up to the row. The row's size is the cell's size: a
   cell holding a lot of text is a NARROW COLUMN, not a smaller cell. Do not
   re-drop it, and do not read `.b-td-dense` below as licence to — Dense is a
   whole table's choice [c3.2.2], never one cell's escape from its row.

   Addressed by class, never by element. A `.b-table td` selector would
   outrank a Tailwind utility and so would also catch the cells that are not
   cells: the td that exists only to hold an expanded row, which wants p-0
   and would silently gain 12px. A class asks to be a cell. That also makes
   this one rule serve both kinds of table, since the five built out of grid
   with no <table> in them [c3.0] carry the same classes. */
/* The header. One treatment, the Label role: 10, 600, uppercase, .05em,
   muted.

   Alignment: RULED 2026-07-28 (JD) — a column header takes the alignment of
   the cells under it. CSS cannot see down a column, so the rule is carried
   the only way it can be: the header takes the same alignment class its
   column's cells take. There are now THREE cases, not two: `.b-num` (right)
   for numbers, `.b-marks` (centre) for the column of result marks, ruled
   2026-07-29, and no class at all for text, which is start-aligned. The
   `inherit` below is what gives a header the same start the cell already had.
   Without it the browser would centre the th and every unclassed header would
   disagree with its column. So this declaration IS the rule for the third
   case, not a refusal to pick a value. See [c3.2.3].

   THE TWO CASES THAT WERE LEFT ALONE ARE RULED, 2026-07-29 (JD), and
   `inherit` is already both of them:

   A HEADING SPANNING COLUMNS THAT DISAGREE TAKES THE START. When a colSpan
   header sits over columns with no shared alignment there is no single answer
   to inherit, so the answer is left. `text-align: inherit` on a th with no
   alignment class IS that: it takes the start of the row's direction. Nothing
   further is emitted, because a second declaration saying left would say the
   same thing twice and would then have to be kept in step with this one.

   IN A TRANSPOSED TABLE THE ROW DECIDES, NOT THE COLUMN. Where the fields run
   down and the entities run across, one column holds text on one row and a
   number on the next, so the column cannot decide anything. The alignment
   class goes on the cells of a row, and the row's leading label carries no
   class and starts. Also carried by `inherit` and by putting `.b-num` on
   cells rather than on columns — this sheet has never had a column selector
   and must not gain one. See the Compare table on the specimen page. */
.b-th { /* [c3.2.1] */
  padding: var(--brand-header-y) var(--brand-cell-x);
  font-family: var(--brand-font-text);
  font-size: var(--brand-size-label);
  font-weight: var(--brand-weight-600);
  text-transform: uppercase;
  letter-spacing: var(--brand-track-2);
  color: var(--brand-ink-muted);
  text-align: inherit;
}

/* The cell. Both sizes take the same leading; only the type differs, so the
   two boxes differ by exactly the difference between 12 and 14. Body for text
   read as language, Dense for numbers and compact lists [c3.2.2]. A table
   picks one of the two and every cell in it takes that one: see ONE CELL DOES
   NOT DROP BELOW ITS ROW above. */
.b-td,
.b-td-dense { /* [c3.2.2] */
  padding: 0 var(--brand-cell-x);
  line-height: var(--brand-lh-125);                                            /* [c2.6.1] */
  font-family: var(--brand-font-text);
}

/* 500, ruled 2026-07-31 (JD). Was --brand-weight-prose at 400; a cell is not
   running prose, and the two cell classes now carry the same weight. */
.b-td { /* [c3.2.2] */
  font-size: var(--brand-size-body);
  font-weight: var(--brand-weight-td);                                         /* [c3.2.2.2] */
}

.b-td-dense { /* [c3.2.2] */
  font-size: var(--brand-size-dense);
  font-weight: var(--brand-weight-500);
}

/* Numbers are right-aligned with tabular figures, always. One of the THREE
   alignment classes this sheet emits (`.b-num`, `.b-marks`, and none), and
   between them they are the only things that ever set a cell's alignment: a
   th and its column take the same class, which is what replaced the inline
   text-align that used to be written per cell. Since 2026-07-28 that shared
   class is the ruling, not a convention — a header over a `.b-num` column
   carries `.b-num`, and a header that fights it with a utility or an inline
   style loses the alignment to stylesheet order. Delete the fighter; do not
   stack it. The Oswald Data treatment [c2.2.11] applies to the body cell
   only, so a header stays the Label role. */
.b-num { /* [c3.2.3] */
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.b-td.b-num,
.b-td-dense.b-num { /* [c2.2.11] */
  font-family: var(--brand-font-display);
  font-weight: var(--brand-weight-600);
}

/* THE COLUMN OF RESULT MARKS IS CENTRED, heading and marks together. RULED
   2026-07-29 (JD): the last-five-games column is coloured squares, which are
   neither numbers nor text, and five marks in a fixed column read as a band
   down the page when they are centred. That band is the thing being scanned.
   The third alignment case, and the one that also settles the Trend column,
   which carried no alignment class at all and in one of the three places it
   is built had a centred heading over a cell aligned by nothing.

   Named for the job, never for the value: `.b-center` is banned outright by
   [c2.2.15], the same way `.b-w400` would be if weight were not a closed
   list. It sets alignment and nothing else — the marks themselves are shapes
   and colour, and neither is in scope here. */
.b-marks { /* [c3.2.12] */
  text-align: center;
}

/* Separation: one hairline, one alpha. */
.b-tr { /* [c3.2.5] */
  border-bottom: 1px solid var(--brand-hair);
}

/* A row you can click is a row you can reach from the keyboard, ch4 §13.
   Derived, not picked (§13.3): DESIGN-LAWS §2 rules that everything but the
   next action wears a steady ring, never a glow, so focus is a ring; ch5
   §1.1.6 names edge-strong as the edge that carries attention, so the ring
   is that token, at the 2px offset the row's own hairline leaves room for.
   :focus-visible, not :focus, so a mouse click leaves nothing behind. */
.b-focus-row:focus-visible { /* [c4.13.3] */
  outline: 2px solid var(--brand-teal-edge-strong);
  outline-offset: -2px;
}

/* Names follow the chapter 1 overflow doctrine: team names wrap to two
   lines and never take dots. */
.b-table-name { /* [c3.2.4] */
  white-space: normal;
}

/* Overflow is horizontal scroll. Clipping is a defect: a table too wide for
   its space must show that something is missing. */
.b-table-scroll { /* [c3.2.8] */
  overflow-x: auto;
}

/* Sticky header wherever a table can be longer than a screen. The backing is
   the page's own background, solid: RULED 2026-07-29 (JD), which CLOSES
   OUT-11. Without it the rows print through the words. A lifted panel was the
   other option and was rejected — a heading that changes colour when it
   sticks is a second surface to design and a second thing to explain. The
   token is not new and the colour is not new: it is what the page is already
   painted. */
.b-th-sticky { /* [c3.2.10] */
  position: sticky;
  top: 0;
  background: var(--brand-page-bg);
}

/* THE SORT ARROW IS DEAD AND THE SORTED COLUMN IS LIT INSTEAD. RULED
   2026-07-31 (JD), chapter 3 §2.11.2, OVERTURNING the 07-29 ruling that put
   an always-present faint arrow straight after the heading. His reason: the
   glyph was continually in the way. It is deleted site-wide and nothing is
   drawn in its place.

   WHAT REPLACES IT IS INK, NOT A MARK. The active column's heading takes full
   ink where every other heading sits at the muted Label ink `.b-th` already
   sets, and the cells under it take the same full ink. One column is lit and
   the rest are not. That contrast is the entire control.

   DIRECTION GETS NO GLYPH, DELIBERATELY. Ascending against descending is
   already on screen in the order the rows print, so a caret would be drawing a
   second time the fact the reader is looking at. `aria-sort` stays in the
   markup and is now the only place direction is stated, which is where a
   screen reader was taking it from anyway. Glyph sets and `aria-sort` stay
   markup, not CSS: OUT-2.

   NO NUMBER ENTERS THE SHEET FOR THIS. Full ink is `--brand-ink`, already
   declared in chapter 1's palette; muted is what `.b-th` already carries.
   `--brand-sort-gap` (4px) and `--brand-sort-inactive` (.45), both extracted
   on 07-29 for the arrow, are DELETED with it, and OUT-17 closes — not
   because it finally got a number but because the thing it measured no longer
   exists. Deleting the two variables is the honest close; leaving them
   declared and unconsumed would repeat `--brand-row`'s mistake (§1.8, OUT-12).

   `.b-sort` KEEPS ITS FLEX AND LOSES ITS GAP. It stays so markup can still
   name which thing this is, on the same precedent as `.b-section`, and so a
   heading that pairs a word with anything else still centres it. With no
   second child the gap had nothing to sit between. */
.b-sort { /* [c3.2.11] */
  display: inline-flex;
  align-items: center;
}

/* The lit heading. Full ink against `.b-th`'s muted, and nothing else: no
   weight change, no underline, no background. The heading is already 600
   uppercase Label, so a second signal on top of the ink would be the column
   shouting rather than being on. */
.b-sort-on { /* [c3.2.11.2] */
  color: var(--brand-ink);
}

/* The lit cells. Same ink, on the cell rather than the heading, so the sorted
   column reads as one lit band from its header down through its numbers —
   which is what makes the direction legible without a caret. Opt-in per cell,
   because CSS cannot see down a column (§2.1.1's own constraint) and the
   markup is the only thing that knows which column is active. */
.b-td-sorted { /* [c3.2.11.2] */
  color: var(--brand-ink);
}


/* =========================================================================
   THE GAME ROW . chapter 3 section 6, RULED 2026-07-31 (JD), design A, the
   Stack, off staging/card-inventory/game-row.html.

   Twenty-three call sites drew a game or a matchup in six score sizes, seven
   name treatments, seven rail widths and six row heights. This is the one
   shape that replaces all of them.

   IT IS NOT A TABLE AND IT IS NOT CONVERGING ONTO ONE. Section 6.7. The
   literal-<table> branch was built and measured: at 393 five of the twelve
   league names truncate and a 32px row cannot let them wrap instead, which
   breaks section 2.4 everywhere to buy density. Converting this to a <table>
   later is a defect, not diligence.

   NO NEW COLOUR, NO NEW SIZE, NO BREAKPOINT. The hairline is the table's own
   --brand-hair, the hover is the ruled rung, the horizontal padding is the
   table's own --brand-cell-x, and every piece of type inside comes off a role
   class in the markup rather than being set here. There is one markup branch
   and it renders identically at 393 and at desktop (section 6.5).
   ========================================================================= */

/* The game. It owns the hairline, and it owns it BECAUSE the game is the unit
   and the team is not (section 6.1). A rule between the two lines turns four
   games into eight rows; a rule under the pair reads as one object. */
.b-game { /* [c3.6.1] */
  border-bottom: 1px solid var(--brand-hair);
}

.b-game:last-child { /* [c3.6.1] */
  border-bottom: 0;
}

/* Hover belongs to the game too, for the same reason: you point at a game,
   not at half of one. Section 2.7's single rung, reached here rather than by
   .b-row-hover because that class is scoped to a <tr>. */
.b-game:hover { /* [c3.2.7] */
  background-color: var(--brand-bg-raised);
}

/* One team. Fixed 38px, extracted from the bracket rows that already stood at
   it (section 6.2), so eleven of the twenty-three call sites take this class
   with nothing about them changing.
   HEIGHT AND NOT MIN-HEIGHT, DELIBERATELY: section 6.5 holds because the
   longest name in the league fits one line at 393, so there is no second line
   to grow into, and a fixed line is what keeps the score rail reading as a
   straight column down the page. */
.b-game-line { /* [c3.6.2] */
  display: flex;
  align-items: center;
  height: var(--brand-game-line);
  padding-left: var(--brand-cell-x);
  padding-right: var(--brand-cell-x);
  gap: 8px;
}

/* Name takes what is left. min-width:0 is the flex-child override without
   which a long team name refuses to shrink and pushes the rail off the row —
   the browser's default is min-width:auto and that is the bug it causes. */
.b-game-name { /* [c3.6.3] */
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* The score rail. Right and tabular are section 2.3, which already rules every
   number on the site and reaches this row unchanged. */
.b-game-score { /* [c3.6.3] */
  flex: 0 0 var(--brand-game-score);
  width: var(--brand-game-score);
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* The status column. Right-aligned so it and the rail make one edge down the
   right of the list; section 2.1.1's alignment rule read onto a grid. */
.b-game-status { /* [c3.6.3] */
  flex: 0 0 var(--brand-game-status);
  width: var(--brand-game-status);
  text-align: right;
}

/* The viewer's own game. Gold, inset from the left, DL-5. It is on the GAME
   and not on the line, because both teams in your game are your game. No
   alpha is composed: OUT-8 still has no ruled row tint, so this draws the one
   edge chapter 1 already rules and no fill. */
.b-game-you { /* [DL-5] */
  box-shadow: inset 2px 0 0 var(--brand-gold);
}

/* The team mark, and it gets its own class after a wrong turn worth recording.
   This first reused `.b-player-line-mark`, on the reasoning that a 16px mark
   already existed in the sheet and a second class holding the same number is
   waste. That was reading the number and not the ROLE. `.b-player-line-mark`
   is chapter 1 §1.17's NFL LOGO slot — 16 x 16, object-fit contain, no radius,
   an image well. This is the OWNER mark: a hue fill with two letters on it.
   Same pixel, different object, and the sheet should not make one stand for
   the other.

   THE GEOMETRY IS §1.17's OWNER MARK, WITH ONE DELIBERATE DIFFERENCE. §1.17's
   rail rules it at 16 x 14, radius 3, owner hue fill. The radius and the fill
   come straight across. The HEIGHT does not: this is square, because the page
   JD ruled off draws it square, and an approved surface outranks an extracted
   rule — the same precedent §2.11.1 was written under. A 16 x 14 in a 38px
   line beside a two-line name would also not be the thing he approved.

   NO COLOUR AND NO TYPE SIZE ARE SET HERE. The hue is per-row data and arrives
   on a `style` attribute (§6.6); the type comes off a role class in the markup.
   This class is geometry and nothing else. */
.b-game-mark { /* [c3.6.6] */
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--brand-player-line-mark);
  height: var(--brand-player-line-mark);
  border-radius: 3px;
}

/* =========================================================================
   THE NFL BOARD CARD . chapter 4 §14. The card itself is chapter 1 §1.15.1's
   named exception ("no rule here reaches them") and stays one — only these
   two rulings leave the card's own inline Tailwind and land here, because
   both compose tokens this sheet already owns rather than inventing
   anything for the card. Full derivation in BRAND-GUIDELINES-04-VIEWS.md §14.
   ========================================================================= */

/* ONE HOVER, DRAWN ONCE, OVER THE WHOLE CARD. §14.1. `.glass-card`'s own
   background-color is `!important` (globals.css), and this sheet carries
   none, so the card cannot lift its own box on hover — the lift is drawn on
   the card's two content boxes instead, both plain divs with nothing
   contesting them. `.b-game` nested inside answers to the card's hover now,
   not its own independent one: one authority for the lift, not two. */
.b-nfl-game-card:hover { /* [c4.14.1] */
  border-color: var(--brand-teal-edge-medium);
}
.b-nfl-game-card:hover .b-nfl-game-card-panel { /* [c4.14.1] */
  background-color: var(--brand-bg-raised);
}
.b-nfl-game-card:hover .b-game { /* [c4.14.1] */
  background-color: transparent;
}

/* NAMES NEVER WRAP ON THIS CARD. §14.2. The card drops the per-team status
   cell entirely (NflGameCard.tsx), so `.b-game-status`'s reserved rail sits
   empty on every row this card draws — dead space fighting the name for
   room. Hidden outright, and the score rail narrows from 56px (plenty for a
   two-line fantasy score) to 40px (plenty for a whole NFL score), and both
   are scoped to this card: `.b-game-status` / `.b-game-score` keep their
   general values everywhere else. `text-overflow: ellipsis` is the
   fallback, not the mechanism — §14.2 in the chapter has the measurements
   that say nothing real is expected to reach it. */
.b-nfl-game-card .b-game-status { /* [c4.14.2] */
  display: none;
}
.b-nfl-game-card .b-game-score { /* [c4.14.2] */
  flex: 0 0 40px;
  width: 40px;
}
.b-nfl-game-card .b-game-name > * { /* [c4.14.2] */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* =========================================================================
   THE FRONT-PAGE SCHEDULE CARD . chapter 4 §15. Scoped exactly the way §14
   above scopes the NFL board card, and for the same reason: the general
   values are right everywhere else and do not move. Full derivation in
   BRAND-GUIDELINES-04-VIEWS.md §15.
   ========================================================================= */

/* §15.1 AND §15.2 ARE RETIRED, AND THE RULE THEY WROTE IS DELETED (§15.3, JD
   d610, 2026-08-14). This card no longer draws `.b-game-*` at all: its rows
   are the canonical `TeamCard` at its ruled 220 x 62, so there is no status
   rail here to narrow and no name column left to buy pixels for. The
   derivation below is kept as the record of why three passes of width tuning
   could not have worked — every one of them measured in Chromium with the
   webfont loaded, and the name column was 160px against a name that measures
   164 on the iOS fallback face.

   The general `--brand-game-status` (76px) was never touched by any of it and
   is unchanged everywhere else.

   ── RETIRED ──────────────────────────────────────────────────────────────
   THE STATUS RAIL NARROWS SO THE NAME STOPS WRAPPING. §15.1. The rail
   reserved 76px, and the longest word it ever held was `Upcoming` at 45.5 —
   now deleted from this card, leaving `Final` at 26.2 as the widest label
   the cell can draw. Thirty of those 76 pixels were unreachable by any
   label, while three of the league's twelve names needed more than the 124
   left over and wrapped to a second line inside a 38px box that cannot grow.

   The budget at 390, before and after:

     card 342 → line box 320
       − padding 12 + 12          = 296
       − mark 16                  = 280
       − 3 gaps × 8               = 256
       − .b-game-score  56        = 200
       − .b-game-status 76 → 40   = 124 → 160   ← the name column

   40 clears `Final` at 26.2 with 13.8 to spare. 160 clears the longest name
   in the league, 136, with 24. `--brand-game-status` stays 76px everywhere
   else — this is a card-scoped override, not a change to the token, and
   /schedule is where that is checked.

   §15.2 (JD, d597, same day) replaced the weekday word in that cell with the
   gameday as `M/D`. It changes nothing here: the widest date the cell can
   draw is `12/28`, which measures between `Final` and `Upcoming` and nearer
   to `Final`, so 40 was already the right number for it. Recorded because a
   reader of these 40 pixels will find dates in the cell and not the labels
   the derivation above names.
   ── END RETIRED ─────────────────────────────────────────────────────────── */

/* =========================================================================
   THE FRONT-PAGE STANDINGS CARD, PHONE TABLE . chapter 4 §16. Scoped the way
   §14 and §15 above are scoped, and for the same reason: 12px of cell padding
   is right on every table wide enough to pay for it. Full derivation in
   BRAND-GUIDELINES-04-VIEWS.md §16.
   ========================================================================= */

/* CELL PADDING GOES 12 -> 5 ON THIS TABLE ONLY. §16.1. `--brand-cell-x` is
   12px, and a table spends it twice per column. Seven columns on a 342px
   phone table is 168px of padding against 174px of everything else — half the
   table was air, and the team name was the column paying for it. Three of the
   twelve names wrapped at 430, seven at 390, nine at 360.

   The budget at 390, before and after. Table 342 (a 390 viewport less the
   page's 24px each side):

     BEFORE   9% + 36% + 9% + 9% + 7% + 10% + 20%, cell-x 12
       padding 7 cols x 24        = 168
       Sd      30.8 - 24 =   6.8  ← a 20px badge in 6.8px of room
       Team   123.1 - 24 =  99.1, less mark 12 and gap 6 =  81.1
       name needs 138.25.                                   WRAPS

     AFTER    30 + auto + 24 + 24 + 24 + 36, cell-x 5
       padding 6 cols x 10        =  60
       Sd      30   - 10 =  20    ← exactly the badge
       Team   204   - 10 = 194, less mark 12 and gap 6    = 176
       name needs 138.25.                                   CLEARS BY 37.8

   Measured, not derived: 176 at 390 and 146 at 360, against the 138.25 the
   longest name asks for. 360 is the narrowest width this is ruled to hold and
   it clears by 7.8. Below that it wraps again; 344 is the first width where
   it does. No cell clips and the seed badge fits its own column at every
   width from 360 up, which it did not before.

   Vertical header padding is untouched: `--brand-header-y` still sets the
   12px above and below every `.b-th`, so the header row keeps its height and
   only the gutters close. */
.b-phone-standings .b-th, /* [c4.16.1] */
.b-phone-standings .b-td { /* [c4.16.1] */
  padding-left: 5px;
  padding-right: 5px;
}

/* `.b-sort-arrow` and `.b-sort-arrow-on` STOOD HERE AND ARE DELETED, 2026-07-31,
   with the ruling that drew them (§2.11.2). They carried the faint-until-used
   opacity pair. Recorded rather than silently removed, because five `src/` files
   referenced them by name and a builder finding those references needs to land
   on this note rather than assume the classes were lost. */

/* The four role variants that sat here are deleted. Each set a
   --brand-row-height that nothing read, from a 16/20 pair that never
   reached a pixel. There is one leading for every table and it is
   --brand-lh-125, on the two cell classes above; --brand-row is left
   declared but consumed by nothing, see OUT-12. Sorting and stickiness are
   behaviour and keep their own classes. */


/* =========================================================================
   THE PANEL RULING . proposal C, as built in src/components/ui/Panel.tsx
   A Section is NOT a box. Page-level regions lose the border, the
   background, the radius and the shadow. A title plus a hairline above the
   content is the whole treatment. The Inset is the ONE legal box inside a
   Section. Nesting an Inset in an Inset is out, see OUT-6.
   These values match Panel.tsx exactly. It is built and shipped on the
   commissioner Settings tab, so where this sheet and that file would
   disagree, this sheet is wrong.
   ========================================================================= */

/* There is nothing to declare for a Section. Writing `border: none` here
   would be the decorative declaration this sheet bans. The class exists so
   a page can name the region. */
.b-section { /* [PANEL-C] */
}

.b-section-head { /* [PANEL-C] */
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 8px;
}

/* 9.5 is a CARD step used at page level and .7px is on no tracking list.
   Both are what ships. See CONF-7. */
.b-section-title { /* [PANEL-C] */
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: .7px;
  text-transform: uppercase;
  color: var(--brand-ink-muted);
}

.b-section-rule { /* [PANEL-C] */
  border-top: 1px solid var(--brand-hair);
  margin-bottom: 12px;
}

/* -------------------------------------------------------------------------
   THE SECOND FORM OF THE SECTION RULE. ch4 11.2.2, RULED 2026-07-30 (JD,
   option A on Taste's drawn page).

   Same instrument, same colour, same weight, SECOND PLACEMENT. The line
   inside a box has two jobs and they need different DOM:
     .b-section-rule  its own element, line on TOP, 12px pushed below it.
                      5 uses on the front page, unchanged.
     .b-section-edge  the header's own bottom edge, NO MARGIN.

   WHY THE SECOND FORM EXISTS. All 57 headers, strips and banners draw the
   line as their own border-bottom over a body that is already padded. The
   standalone form would land its 12px on top of that padding: 16 -> 28 at a
   card header, 24 -> 36 at a modal, and 24px in two places where a section
   strip sits between two rules. That is a loosening nobody ruled. This form
   converts all 57 with ZERO PIXELS MOVED.

   THE FIVE TAB RAILS ARE EXCLUDED BY NAME and keep what they have. A rail is
   the track an active tab is marked on, not a line parting a header from a
   body. Different object, and it waits for a tab component ruling.

   THE THEMES COME WITH IT. This carries --brand-hair, which the
   .border-corp-border overrides in globals.css do not reach . and gm-light
   and pc-paper match on [class*="border-corp-border"], so they would miss it
   entirely. The same four overrides .b-row-divide took (10.3.4) are added for
   this class at globals.css 787, 1181, 1525 and 1569. Preservation, not a
   colour ruling.
   ------------------------------------------------------------------------- */

.b-section-edge { /* [c4.11.2.2] */
  border-bottom: 1px solid var(--brand-hair);
}

/* The one legal box: 8px radius, 10px padding, 1px hairline, the existing
   gradient over an opaque base. The base is pinned because --panel and
   --panel2 are about 97% opaque, so without it whatever sits behind bleeds
   through. */
.b-inset { /* [PANEL-C] */
  border-radius: 8px;
  padding: 10px;
  border: 1px solid var(--brand-hair);
  background-color: var(--brand-card-bg);
  background-image: linear-gradient(180deg, var(--brand-panel), var(--brand-panel2));
}


/* =========================================================================
   CHAPTER 4 . RECURRING VIEWS . the shell a list sits in
   Seven decisions, all ruled by JD on 2026-07-30 against a drawn card. This
   block carries the three that have a shape. The other four are conversion
   with no new class behind them:
     10.2  a row you read carries no button. A boundary, not a shape. The
           picking row's own anatomy is NOT ruled (10.2.1) and nothing is
           emitted for it.
     10.4  the label above a block is `Label`, and .b-label already exists
           from chapter 2 section 2.3. Ruling it here adds a call site, not a
           class.
     10.6  an empty view has three answers. All three are words at roles that
           already exist. Nothing to emit.
     10.7  a loading view shows pulsing shapes. The pulse and the shape's
           fill are an animation and a colour, neither in scope. What 10.7.1
           rules is that the shape is the row's true silhouette, so a lineup
           skeleton takes the 10.1.1 geometry below and needs no second set
           of numbers. That is the rule working: a skeleton with its own
           sizes is the defect.
   ========================================================================= */

/* -------------------------------------------------------------------------
   VARIANT 10.1 . LINEUP / SLOT . 56 tall, the tenth variant
   Geometry only, on the same terms as 1.17: the type comes from the roles
   and the card scale, the POS hue and the state colours are data and arrive
   per element. No font-size and no colour is declared here.

   The border is NOT emitted either, and that is deliberate. 10.1.3 rules
   that a slot draws its state on its border, so the border's colour changes
   with the state and belongs to the component. What is ruled is that the
   border is there.
   ------------------------------------------------------------------------- */

.b-lineup-slot { /* [c4.10.1.1] */
  height: var(--brand-lineup-slot-h);
  box-sizing: border-box;
  display: flex;
  align-items: center;
  gap: var(--brand-lineup-slot-gap);
  padding-left: var(--brand-lineup-slot-pad);
  padding-right: var(--brand-lineup-slot-pad);
}

/* Wider than 1.17's 20px square because it carries a three-letter slot code
   (WRT, WT), not a two-letter position. 10.1.4: 1.17.5 does not reach it. */
.b-lineup-slot-chip { /* [c4.10.1.4] */
  flex: 0 0 auto;
  width: var(--brand-lineup-slot-chip-w);
  height: var(--brand-lineup-slot-chip-h);
}

/* The one list row on the site that carries a headshot, and the reason the
   row is 56. PlayerFace sizes its own render at .pfx--roster; this class is
   for anything standing in for the face at the same size, which today means
   the loading silhouette (10.7.1). */
.b-lineup-slot-face { /* [c4.10.1.1] */
  flex: 0 0 auto;
  width: var(--brand-lineup-slot-face);
  height: var(--brand-lineup-slot-face);
}

/* Both marks in the row, the player's NFL team and the opponent's, at one
   size. Two uses of one number, which is why it is one token. */
.b-lineup-slot-mark { /* [c4.10.1.1] */
  flex: 0 0 auto;
  width: var(--brand-lineup-slot-mark);
  height: var(--brand-lineup-slot-mark);
}

.b-lineup-slot-name { /* [c4.10.1.1] */
  flex: 1 1 auto;
  min-width: 0;
}

/* Fixed and right-aligned so the times form a column down fourteen rows
   whether a row shows a time, BYE, or a lock. */
.b-lineup-slot-time { /* [c4.10.1.1] */
  flex: 0 0 auto;
  width: var(--brand-lineup-slot-time-w);
  text-align: right;
}

/* -------------------------------------------------------------------------
   10.3 . THE DIVIDER . one hairline, and a box only where a row has a state
   Six mechanisms collapse to one class. The colour is not new: --brand-hair
   is what .b-tr already draws for a table and what corp-border already
   resolves to in the Tailwind config, so mechanisms 1, 2 and 3 were one line
   wearing three spellings.

   THE THEMES COME WITH IT. globals.css overrides .divide-corp-border and
   .border-corp-border under theme-july4, theme-usa, gm-light and pc-paper.
   This class carries --brand-hair, which those overrides do not reach, so
   the same four overrides are added for it there. That is preservation, not
   a colour ruling: see 10.3.4.
   ------------------------------------------------------------------------- */

.b-row-divide > * + * { /* [c4.10.3.1] */
  border-top: 1px solid var(--brand-hair);
}

/* -------------------------------------------------------------------------
   10.5 . A PICKING LIST FILLS WHATEVER ROOM IS LEFT
   No height. 160, 55vh and 60vh all go, and there is now no number to carry
   anywhere, which is why this beat the answer with three uses behind it.

   The host has to be a column with a bounded height for this to mean
   anything (10.5.1). Where a popup does not bound its own height, that popup
   is a stopping point and not a place to invent one.
   ------------------------------------------------------------------------- */

.b-pick-list { /* [c4.10.5] */
  min-height: 0;
  flex: 1 1 auto;
  overflow-y: auto;
  overscroll-behavior: contain;
}


/* =========================================================================
   COLOUR
   Gold is reserved for the viewer's own thing. Nothing else may use it, not
   a heading, not a status, not an accent, not a border. A surface needing a
   quiet highlight that is not ownership uses teal.
   Red is data: a loss, an injury, an alarm, a reach above consensus. Red
   never means "this row is yours".
   Row colour only ever means something. A row is never tinted for rhythm.
   The viewer's row alpha (OUT-8) and the playoff green (OUT-9) have no ruled
   values, so nothing is emitted for them. The hover rung (OUT-10) was ruled
   2026-07-30 and `.b-row-hover` below emits it.
   ========================================================================= */

.b-you { /* [c1.1.3.2] */
  color: var(--brand-gold);
}

/* One hover, one value. Section 2.7 rules a single hover and JD gave it a
   number 2026-07-30 (D-11, option H1): the ramp's next rung, #1E2A39, held in
   `--brand-bg-raised`. A row lifts under the pointer. It never goes darker,
   which is what every existing background token would have done to a row
   already filled at #18222f. */
.b-row-hover:hover { /* [c3.2.7] */
  background-color: var(--brand-bg-raised);
}

.b-data-red { /* [DL-5] */
  color: var(--brand-red);
}

.b-quiet { /* [c1.1.3.2] */
  color: var(--brand-teal);
}

/* Champion, on type. The colour is set first and the fill is knocked out over
   it, so an engine that will not clip a gradient to text shows the champagne
   rather than nothing. Never `color: transparent` here. DL-5d. */
.b-champion { /* [DL-5d] */
  color: var(--brand-champion-flat);
  background-image: var(--brand-champion-sheen);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

/* Champion, where there is no type: a border, a ring, a dot, an icon, a filled
   badge. Takes the flat because a text-clipped gradient has nothing to clip to.
   A row tint composes its own alpha off the triplet and keeps the alpha it
   already had — no champion alpha is ruled. DL-5d. */
.b-champion-flat { /* [DL-5d] */
  color: var(--brand-champion-flat);
}

.b-champion-border { /* [DL-5d] */
  border-color: var(--brand-champion-flat);
}

.b-action { /* [DL-5] */
  color: var(--brand-green-action);
}


/* =========================================================================
   SPECIMEN PAGE SCAFFOLDING
   Everything below this line belongs to public/brand.html and to nothing
   else. It carries no brand rule. It is governed only by the sheet's own
   form rules: dark, the real page background, everything at true size, the
   longest real value beside the happy case, no explainer prose under a
   drawing. The numbers in it are the page's furniture, not brand values,
   and they are held to 8px, 12px and 40px so nothing new enters the system
   through the back door.
   ========================================================================= */

.b-page { /* [SPEC-FORM] */
  background-color: var(--brand-page-bg);
  min-height: 100vh;
  margin: 0;
  padding: 40px;
  box-sizing: border-box;
}

.b-stack { /* [SPEC-FORM] */
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: flex-start;
}

.b-stack-wide { /* [SPEC-FORM] */
  display: flex;
  flex-direction: column;
  gap: 12px;
  align-items: stretch;
}

.b-row { /* [SPEC-FORM] */
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: flex-start;
}

.b-col { /* [SPEC-FORM] */
  flex: 1 1 0;
  min-width: 0;
}

.b-row-tight { /* [SPEC-FORM] */
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
}

.b-gap-40 { /* [SPEC-FORM] */
  margin-bottom: 40px;
}

.b-gap-12 { /* [SPEC-FORM] */
  margin-bottom: 12px;
}

.b-muted { /* [SPEC-FORM] */
  color: var(--brand-ink-muted);
}

.b-measure { /* [SPEC-FORM] */
  max-width: 680px;
}

.b-swatch { /* [SPEC-FORM] */
  width: 40px;
  height: 40px;
  border-radius: 8px;
  border: 1px solid var(--brand-hair);
  flex: none;
}

.b-cell-pad { /* [SPEC-FORM] */
  padding-left: 8px;
  padding-right: 8px;
  padding-top: 0;
  padding-bottom: 0;
}

/* Specimen only. A sticky header cannot be shown standing still: the box has
   to be shorter than its table so the reader can scroll the rows behind it and
   see the solid page background doing its job. 64 is the specimen's height,
   measured: the five-row table renders 93 tall here, so two rows have
   somewhere to scroll from. It is not a table's height — no table on the site
   is capped. */
.b-spec-scroll-y { /* [SPEC-FORM] */
  max-height: 64px;
  overflow-y: auto;
}

.b-spec-box { /* [SPEC-FORM] */
  border: 1px dashed var(--brand-hair);
  padding: 8px;
  box-sizing: border-box;
}
