interledger / interledger/docs-design-system
Unscoped rules in ilf-docs.css leak onto consumer main-site routes via Starlight middleware chunking
@Infi-Knight is already working on this.
Since May 11, 2026.
- Dominant language
- CSS
- Stars
- 1
- Forks
- 1
- Avg merge
- 9h 12m
- Merged PRs (30d)
- 3
Description
Summary
Three unlayered rules in src/styles/ilf-docs.css use universal-ish selectors and bleed onto every route of a consumer site that uses both Starlight and a separate main-site (Tailwind/Astro). The intended scope is Starlight-rendered docs pages only, but the file ships on every page in practice.
Visible damage from these blocks:
- L61-64:
:focus-visible { outline-color: var(--sl-color-accent); border-radius: var(--border-radius); }. Forces the docs accent color and a 6px corner radius on every focused<button>/<a>on the consumer's main-site. Shadows the consumer's own focus-ring utilities. - L326-328:
img { border-radius: var(--border-radius); }. Rounds every<img>to 6px on the main-site. - L388-394:
thead tr:first-of-type th:first-of-type { border-start-start-radius: var(--border-radius); }and the:last-of-typevariant. Rounds the top corners of every<thead>first row on the main-site.
Reported by @Anca2022 reviewing the new button focus states on https://github.com/interledger/interledger.org-v5/pull/266.
Why the file ships outside docs routes
Not strictly the package's fault. Starlight integration auto-registers an Astro middleware that calls useTranslations from Starlight's internal translations module. Astro middleware runs on every route. Vite groups the translations chunk's CSS dependencies (which include every Starlight customCss file) into a shared CSS chunk that gets linked from every page's HTML.
For a consumer that uses Starlight only on /docs/* and Tailwind elsewhere, this means ilf-docs.css is loaded on every main-site route. Tailwind utilities live in @layer utilities, and any layered rule loses to an unlayered author rule regardless of specificity, so the rules above win.
Suggested fix
Two options, either works:
-
Wrap the rules in a layer (preferred):
@layer ilf-docs.base { :focus-visible { ... } img { ... } thead tr:first-of-type th:first-of-type { ... } thead tr:first-of-type th:last-of-type { ... } }Consumers can then control where the layer falls in their cascade.
-
Scope the selectors to a Starlight wrapper:
:where(.sl-container) :focus-visible { ... } :where(.sl-container) img { ... } :where(.sl-container) thead tr:first-of-type th:first-of-type { ... }.sl-containeris Starlight's docs wrapper. Pages outside docs don't have it.
Option (1) is closer to what Tailwind itself does, lets consumers pick the order in their cascade, and keeps the rules applying on whatever element they target inside docs while losing cleanly to consumer utilities.
Workaround in interledger.org-v5
Until this is fixed upstream, interledger.org-v5 ships an unlayered counter-rule in src/styles/tailwind.css that uses revert-layer to expose the underlying Tailwind utility value (or UA default). Search for @interledger/docs-design-system in that file for context.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.