Design system
The vocabulary, and the five rules that are not negotiable.
Cold achromatic chrome so that colour can arrive from the data. Broadcast strata rather than a card grid. One sheared element and one field metaphor, and everything else orthogonal and quiet.
Colour
The constraint that drives everything: 32 team palettes span the entire hue wheel, so any saturated brand colour clashes with most of them. The chrome is therefore near-achromatic and colour arrives from the data. Values below are read out of the shipped stylesheet at runtime, not transcribed.
Ground
Never text, so they carry no contrast floor — they are what everything else is measured against.
--field--deck--deck-raised--hash
Text
--fog-dim carries a 3.0 floor rather than 4.5 deliberately: lifting disabled text would make it read as enabled.
--chalk--fog--fog-dim
System identity
--verdict appears only where XOCP is expressing an opinion. Never decorative, never a generic highlight.
--signal--verdict
Status
Desaturated so status never competes with a team colour. Three of these were lifted for contrast and the pre-lift values are banned by gate.
--live--warn--out--edge--fade
Type
Three roles. The display face is a self-hosted Archivo subset bound to headings only, so a face that has not painted costs a heading its character and never costs a number its shape.
Display · Archivo 600–900
Start Kamara
Headings and large figures. Self-hosted, preloaded, metric-adjusted fallback.
Body · system-ui
Every opponent’s 2025 points allowed at that player’s position, scored under this league’s own rules.
Running text. Zero bytes, zero load risk, renders instantly on every device.
Data · ui-monospace
405.5
361.5
+44.0
Tabular figures, mandatory. Every stat column, every projection, every price.
--t-heroDefend itHero. Marketing only.--t-displayDefend itDisplay heading.--t-2xlDefend itSection heading.--t-xlDefend itPanel heading.--t-lgDefend itSub-heading.--t-mdDefend itBody.--t-smDefend itSecondary.--t-xsDefend itLabel, tag, table header.Space, edges and measure
A 4 px ramp, because the tap floor is 44 and the team rail is 4. Radii stop at 3 px: the broadcast reference is a cut edge, and rounded card grids are what this direction rejects by name.
--s-1--s-2--s-3--s-4--s-5--s-6--s-7--s-8--r-sm--r-md--shear--w-prose--w-page--w-wide--nav-h--track-label--track-displayPrimitives
Drawn with the real classes from globals.css, so a primitive that has drifted looks wrong on this page before it looks wrong on a route.
Panel
Neutral
The default. No accent rail means no claim is being made about the contents.
Verdict
A recommendation, and the only place violet is permitted.
Live
Current, in progress, or proven. Green never means “good”.
Signal
Interactive or navigational. Also the focus-ring colour.
Warn
A declared gap or a blocked input. Deliberately not the OUT colour.
Out
Inactive, on bye, or cut. A state, not a failure.
Tag
The word inside the chip carries the meaning; the colour only reinforces it. A coloured dot alone would encode state in hue, which the system forbids.
Metric
0.000
max scoring delta
62,201
crosswalk rows
32
depth charts
49
rows with no rank
Data table
| Player | This league | Generic | Delta |
|---|---|---|---|
| Josh Allen | 405.5 | 361.5 | +44.0 |
| A kicker | 128.0 | 128.0 | — |
The em-dash is .gap-mark: an absent value, in --fog-dim so it reads as a hole rather than as a measurement.
Verdict band
The call
Start Alvin Kamara over Tony Pollard.
The one sheared element in the system. Everything around it stays rectilinear.
The rules
Each of these is here because breaking it is silent — none produces a visibly broken page, which is exactly why it needs writing down.
- 01
Violet means XOCP has an opinion. Nothing else.
Violet is nearly absent from the league — two teams — so it never reads as a team signal. A reader must be able to scan any screen and find what the system thinks by looking for one colour. Used decoratively once, it stops meaning anything everywhere.
- 02
A team colour is a fill, a bar or a rail. Never text, never the only carrier of meaning.
Twenty-one of thirty-two NFL primaries fail a naive 3:1 read on the page ground. The 3.0 floor the team rail passes is correct ONLY because the rail always sits beside the team abbreviation set in --chalk. Render a team colour as text and the contrast gate stays green while the board is wrong.
- 03
Every number a reader compares against another number is tabular and right-aligned.
Numerals are the hero content here. 331 and 111 must occupy the same width or a column cannot be scanned. Proportional figures in a stat column is a bug, not a preference.
- 04
Nothing moves inside the application. The marketing page is the single exception.
The draft board is read under a pick clock and the lineup screen on a phone on a Sunday. Motion on either is a cost with no payer. `/` renders no number anyone acts on, its reveals sit behind an @supports guard, and no other route imports its module.
- 05
An absent value renders as a hole, never as a zero.
Never 0, never 999, never "N/A". A missing points-allowed rank is an em-dash in --fog-dim, because a zero is a measurement and this is the absence of one. Forty-nine of 297 board rows are in exactly this state.