Consume design tokens as CSS custom properties - #3261
Merged
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"> |
Contributor
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. |
borland
approved these changes
Jul 28, 2026
borland
left a comment
Contributor
There was a problem hiding this comment.
I had a look at the staging site and all looks well. Approved
enf0rc3
added a commit
that referenced
this pull request
Jul 28, 2026
#3261 added the token CSS, which defines its custom properties only under [data-theme='light'] and [data-theme='dark'] with nothing at :root, and added a server-rendered data-theme="light" on <html> so the attribute is present even without scripting. Both are kept: ThemeScript.astro resolves the real value before first paint on top of that default. - Point the HtmlHead token comment at ThemeScript.astro rather than HEADER_SCRIPTS, which no longer holds the theme script. - Spell out in theme.ts why the attribute has to be unconditional. - Add a javaScriptEnabled: false test so the server-rendered default cannot be dropped again without a failure. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This was referenced Jul 28, 2026
enf0rc3
added a commit
that referenced
this pull request
Jul 28, 2026
#3261 added the token CSS, which defines its custom properties only under [data-theme='light'] and [data-theme='dark'] with nothing at :root, and added a server-rendered data-theme="light" on <html> so the attribute is present even without scripting. Both are kept: ThemeScript.astro resolves the real value before first paint on top of that default. - Point the HtmlHead token comment at ThemeScript.astro rather than HEADER_SCRIPTS, which no longer holds the theme script. - Spell out in theme.ts why the attribute has to be unconditional. - Add a javaScriptEnabled: false test so the server-rendered default cannot be dropped again without a failure. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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