The claim PolyFish has made since the first release is that a theme is a stylesheet, not a fork. Components read roles — background, surface, text, accent — never colours, so redeclaring a dozen custom properties retints everything. That is easy to say. This release makes it easy to check.
One page, seven times
The examples section now has seven pages whose component markup is byte-identical. Strip the
five short passages that name the palette, hash what is left, and all seven produce the same value.
The only difference between them is a single <link> in the head. Open any two side
by side and view source; the diff is the argument.
Two new themes
Paper is an editorial palette: warm off-white stock, a serif display face, rust and pine accents and almost no radius. It exists because the framework's main user is a publication, and long-form reading deserves a palette that gets out of the way. Mono is the opposite end: terminal black, a monospace display face, lime and cyan, square corners. Both carry their measured contrast figures in the file header — body text 14:1 and 16:1 respectively — so the next person to edit one knows what they are keeping.
A note on the site
This release also adds analytics to polyfish.org. The framework you download is unaffected and still loads nothing from anywhere; the site's Content-Security-Policy now names exactly one extra origin, and the about page explains why that script carries no integrity hash.
Update: the claim was only half true
Seven palettes producing identical markup proved the structural half. The colour half did not
survive its first real test. When the suite finally ran in a browser, about sixty component
declarations turned out to read palette tokens rather than roles, which meant that on five of the
six themes the primary button hovered to the default green. The focus ring was a hard-coded
rgba(143, 224, 106, 0.35), so every theme focused green too. Both were true for every
release this post describes.
The fix was not sixty edits. Hover, wash, line and ring colours are derived from the accent now, so the interesting half of a theme is one declaration:
:root { --pf-accent: #d9734e; }
Deriving them raised a question the hand-written themes had hidden: what does "darker on
hover" mean when half the palettes put dark text on a light accent? Mixing toward black cut button
text contrast from 11.3:1 to 6.7:1 on slate and from 10.2:1 to 6.0:1 on dusk. Mixing toward
--pf-text can only improve the pairing, because the text colour always sits on the
far side of the scale from the ink that sits on the accent.
The contrast figures we published were not all right either. Measured in a browser, on every palette: cream's accent was 3.96:1 — below AA — for links and button text, its second accent 3.6:1, and the default light scheme's links 5.4:1, on a site whose home page said AAA throughout. All of them now measure at least 7:1, and the numbers come from a test that runs on every palette rather than a script someone remembered to run.
What this post does not cover
- Colour theory. The contrast maths here is WCAG ratios, not perceptual design advice.
- Automatic palette generation from a brand colour — the accent still has to be chosen by a person.
- Print colour, which the print stylesheet forces to black on white regardless of theme.
Checked against color-mix(), custom properties, below AA. Code blocks are reproduced from the PolyFishCSS source files, not reconstructed from description. Figures are measured from the build they describe.
What this doesn’t cover
A palette is colour. It does not move a single component, change a measure, or alter the type scale, and no amount of retinting makes a layout suit a different kind of site. The contrast figures here are for the pairs we test — body text, links, buttons and code — not for every combination you could build from the tokens.
Sources: MDN on color-mix() and W3C on contrast minimums. The derived-token block is reproduced from PolyFishCSS-Core.css; the contrast ratios are measured in Chromium.