Consume design tokens as CSS custom properties - #3261
Open
enf0rc3 wants to merge 1 commit into
Open
Conversation
@octopusdeploy/design-system-tokens now publishes its tokens as four stylesheets, so the docs site can consume them directly instead of generating its own copy from the package's TypeScript exports. HtmlHead.astro imports them. Vite resolves the ./css/*.css subpath export and bundles them into one hashed stylesheet, so nothing is vendored and nothing can drift from the installed package version. The theme attribute moves from <body> to <html>. lightTheme.css and darkTheme.css select on an unscoped [data-theme="..."] so that any element can be a theme root. The site's own CSS scopes to html[data-theme='dark'], which made the hardcoded data-theme="dark" on <body> inert - but the token stylesheets do match it, and would force dark tokens on every page regardless of the toggle. <html> also gains data-theme="light" as a no-JS default, since the inline script in HEADER_SCRIPTS is what normally sets it. No visual change: 1,184 custom properties are defined and nothing consumes them yet. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
enf0rc3
commented
Jul 28, 2026
| <html dir={textDirection} lang={lang} class="initial"> | ||
| <html dir={textDirection} lang={lang} class="initial" data-theme="light"> | ||
| <Head frontmatter={frontmatter} headings={headings} lang={lang} /> | ||
| <body data-theme="dark"> |
Author
There was a problem hiding this comment.
This actually caused a "flash-bang" on load for dark-mode, have a side pr to tidy the component up (plus we can also improve it to support browser / system defaults too.
The current js theme selector will set the data-theme="dark" on the element, overwriting this one.
|
Pull request environment is available at https://stoctodocspr3261.z22.web.core.windows.net. You can view the ephemeral environment status in Octopus Deploy. This environment will be automatically deprovisioned when the pull request is closed, or after 7 days of inactivity. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
@octopusdeploy/design-system-tokensnow ships its tokens as four stylesheets (added in OctopusDeploy/OctopusDeploy#45543). This site is Astro with no React runtime, so it has noThemecomponent to paint them and the package's TypeScript exports are unusable here.HtmlHead.astroimports the four files. Vite resolves the./css/*.csssubpath export and bundles them into one hashed stylesheet, so nothing is vendored and nothing can drift from the installed version.globals.css:roottextTheme.css:rootlightTheme.css[data-theme="light"]darkTheme.css[data-theme="dark"]Why the theme attribute moves from
<body>to<html>lightTheme.cssanddarkTheme.cssselect on an unscoped[data-theme="..."], by design, so any element can be a theme root. Our own CSS scopes tohtml[data-theme='dark'], which made the hardcodeddata-theme="dark"on<body>inert — but the token stylesheets do match it, and would force dark tokens on every page regardless of the toggle.<html>also gainsdata-theme="light"as a no-JS default. The inline script inHEADER_SCRIPTSnormally sets it before paint; without the attribute, neither theme stylesheet matches and no colour token resolves.Testing
Verified locally that a site variable can point at a token and that both themes follow, by temporarily pointing
--color-textat--colorTextPrimaryand--octo-blueat--colorTextLinkDefault:#282F38#282F38rgb(40, 47, 56)#F4F6F8#F4F6F8rgb(244, 246, 248)The token themes itself, so the matching
html[data-theme='dark']override invars.cssbecame redundant — two declarations collapse to one.vars.cssloads before the token stylesheet and still resolves correctly, becausevar()resolves at use time rather than declaration time.Those experiments were reverted. This PR is a visual no-op: 1,184 custom properties are defined and nothing consumes them yet. Production build verified — 2,697 pages, one 48.5KB stylesheet (7KB gzipped) in
dist/_astro/,:rootplus both[data-theme]blocks present.Follow-ups
Migrating
vars.cssonto tokens will come as separate PRs, grouped so each is independently reviewable and revertible: links, then text, then surfaces and borders.🤖 Generated with Claude Code