Phosphor: One Contract, Two Identities
The dcyfr.ai redesign, and the theme engine that made it a one-line change

The dcyfr.ai redesign, and the theme engine that made it a one-line change

"Phosphor and slate: two identities rendered from one token contract"
Illustration by FLUX.2 Pro (fal.ai)
Feel free to send us a message with your thoughts, or learn more about us!
If you have been here before, you noticed. The cool slate-and-blue that dcyfr.ai wore since launch is gone from this site, replaced by warm paper, vermilion accents, and a serif reading voice. The identity is called phosphor, and this post is about the part of the redesign you cannot see: the engine that let us swap an entire visual identity by changing one attribute.
Most redesigns are rewrites wearing a trench coat. Every hardcoded color, every component with an opinion about its own font, every one-off border radius becomes a migration line item, and the project balloons until someone cuts scope.
We spent the effort somewhere else. Before touching a single color, we extracted a theme engine: a token contract of 37 CSS variables covering surfaces, brand, status, type, motion, and radius. Components consume tokens and only tokens. A theme file supplies the values for one identity, scoped to a data-identity attribute on the root element, with a light block and a dark block. The site stamps that attribute at build time.
Once that held, the redesign collapsed into authoring one new theme file and flipping the stamp from slate to phosphor. The old identity did not die. Slate still ships from the same registry, satisfies the same contract, and renders the same components. It is no longer what this site wears.
Phosphor trades the shadcn-derived cool neutrals for a warmer, more editorial temperament:
A contract nobody enforces is a suggestion. The component registry’s CI enforces this one in both directions: a theme missing a contract variable fails, and a theme defining an off-contract variable also fails, in either scheme. A render matrix then mounts every published primitive under every identity and scheme in a real browser and checks WCAG AA contrast plus an identity-variance gate, which proves the two themes actually look different where they should.
That last check exists because token systems fail quietly. A component that hardcodes a color renders identically under both identities, and no human reviewing a single theme would catch it. The matrix does.
Runtime theme switching is deliberately rare here. Every DCYFR surface pins one identity at build time, which keeps pages fast and keeps the system honest about what it ships. Exactly two surfaces are allowed to switch live, and both exist to show the engine working:
Flip either one and watch the entire page reinterpret itself: same components, same markup, different identity.
The engine and both themes live in our open component registry, installable with npx shadcn add @dcyfr-labs/dcyfr-theme-engine. The satellite sites still pin slate today and will adopt the engine on their own schedule, which is the point: identities are now versioned artifacts a site chooses, not css scattered across a codebase. When the next identity shows up, it will be a theme file and a build-time stamp, and this post will still be accurate.