Four designs, one document
四套设计,同一份文档
The Theme menu swaps the stylesheet while the documents, the DOM and the data stay the same. How the three layers of CSS, the cookie-driven switch, the token-first order and the theme-swap test fit together — and what one client theme costs to write.
Theming
The Theme menu in this site's header swaps the stylesheet. The documents, the DOM and the data do not change. This page explains how the swap is built, because it is the same arrangement a client site uses with one theme.
Three layers of CSS
- plain.css from the package defines a working default for every token and a rule for every block, so a site that ships nothing else still renders legibly
- theme.css in the site holds the chrome that is not part of the contract: header, footer, hero, section heads, the search panels; it is driven by a small set of site variables for background, ink, muted text, rules, accent, fonts and measure
- one pack per theme sets those variables and overrides selectors under a data attribute on the root element
Plain is the package baseline with no pack at all. Theme 1, Institute, is monochrome and geometric with a hairline motif drawn in ink. Theme 2, Desert light, is a warm serif design. Theme 3, Linen and poppy, sets white cards on linen with a poppy accent. Each pack is a single CSS file of a few hundred lines.
How the switch works
A query parameter on any URL sets a cookie through the middleware. The root layout reads the cookie and writes it onto the document as a data attribute. Fonts for all four designs are self-hosted through the framework's font loader and exposed as CSS variables, so switching is instant and does not fetch anything.
Tokens before selectors
A theme overrides tokens on the document and list roots first: fonts, sizes, colours, measure, spacing, photo ratios, motion. Only when a token cannot express the design does it reach for a selector from the DOM contract. The three packs on this site follow that order, and most of their difference is in the token block at the top.
What the contract guarantees
The renderer never emits colours, fonts, widths or animation. Class hooks are for themes and follow a block, element, modifier naming; data attributes are for the editor and for scripts. A theme must not select on data attributes and an editor must not select on classes. The only inline style is a custom property carrying a fact, such as a photograph's aspect ratio.
The theme-swap test
The test suite renders one fixture document, strips class and style attributes, and asserts the DOM is identical under every theme. That test is what "change the design without touching content" means in code rather than in a sales sentence.
What a client theme costs
For a client site the developer writes one pack. On the sites this package grew out of that was one to two days of work for a complete design including chrome. The client never sees the stylesheet and cannot alter it from the editor, which is the point.