Also available in Español
The Claim Being Tested
The last piece in this series argued that a system with no declared exclusions will eventually be asked to do everything, because nothing inside it has grounds to refuse. The example was a single line: --is-modal-open sitting next to --spacing-md, syntactically identical, semantically nothing alike.
That's a claim about systems in general. Here's what it looks like inside a file that actually exists, with a mechanism that actually depends on the boundary holding.
The Artifact
quell-base.css declares a ghost_tokens layer. Its job, stated plainly in the file's own header comment, is to provide fully-resolved fallback values for every token the baseline consumes, resolved before paint. That's not decoration — it's a FOUC firewall. Downstream var() calls are never left with an empty string, even if a theme sheet hasn't loaded yet.
Here's a real slice of it:
@layer ghost_tokens {
:root {
--color-accent: #0057cc; /* WCAG AA on white; override freely */
--color-accent-hover: #003fa3;
--color-accent-subtle: #dbeafe;
--color-surface: #ffffff;
--color-surface-subtle: var(--color-neutral-50);
}
}
Now imagine the commit the last essay described actually landing here:
@layer ghost_tokens {
:root {
--color-accent: #0057cc;
--color-accent-hover: #003fa3;
--color-accent-subtle: #dbeafe;
--is-modal-open: 0; /* tracks modal visibility */
}
}
Nothing about the syntax objects. The browser parses --is-modal-open exactly as readily as --color-accent. Nothing in @layer ghost_tokens refuses it. That's the whole point of the last essay, now sitting inside a file with a documented job to protect.
There's another boundary already present in the file: the token naming convention defines the expected vocabulary as font, color, space, size, radius, border, shadow, and motion.
--color-accent belongs to that vocabulary.
--is-modal-open does not.
The browser cannot enforce that distinction. The architecture has to.
What Actually Breaks
ghost_tokens doesn't just hold values — it makes a specific promise about when those values are available: they are resolved as baseline fallbacks before paint, before a theme sheet necessarily exists. For a color, that promise is harmless. --color-accent doesn't change meaning based on application state; blue resolved early is still blue resolved later.
--is-modal-open is different. The moment it lives in this layer, it is being treated as though application state were another baseline value. The fallback value isn't merely a fallback anymore. It's an assertion — the page now has an opinion about modal state before the application has established that state.
That's the FOUC firewall the layer was built to provide, now being asked to protect an application-state assumption instead of a baseline value.
The file also documents three ways downstream authors can take control of the system, in ascending power: re-declare a custom property on an unlayered :root, append to an existing layer, or write an unlayered rule outright. The first is the documented token override; the others operate at the layer and stylesheet levels.
All of these mechanisms assume the underlying contract remains intact: tokens are values that downstream authors are free to replace. A theme author who overrides --color-accent changes what blue means. A theme author who overrides --is-modal-open isn't customizing a design value. They're asserting a fact about application state through a mechanism that was designed to provide baseline values.
The Moment It Actually Diverges
Strip it down to two declarations, same layer, same syntax:
--color-accent: #0057cc; /* a value */
--is-modal-open: 0; /* application state */
At parse time, the browser cannot tell these apart. Nothing in the cascade algorithm distinguishes a design value from an application-state value. Both are custom properties. Both are valid declarations.
That distinction has to be decided before the layer exists, by whoever writes the rule that either token is allowed in.
The browser will never do it for you.
What This Actually Shows
ghost_tokens isn't broken by --is-modal-open. It does exactly what it was built to do — resolve the custom property as part of the baseline before paint. The problem is architectural: the layer's contract is about providing baseline fallback values, while application state is a fact established by the application.
CSS can respond to state. quell does this elsewhere in the system: its forms layer provides accessible defaults for states such as disabled, readonly, and invalid.
The boundary is not therefore "CSS must never contain state."
The boundary is narrower, and more useful:
A baseline token layer should not become the application-state store merely because CSS gives both kinds of information the same syntax.
That's what the --is-modal-open example exposes.
The boundary in the last essay isn't a style preference. It's the difference between a layer that keeps its promise and one that's been quietly repurposed into keeping a promise it was never designed to make.
The Best CSS Architecture Starts by Deciding What CSS Should Never Do
Top comments (0)