Skip to content

Commit 49c209c

Browse files
authored
Merge pull request #5 from shellui-dev/feat/design-tokens
feat: extract ShellDocs.Tokens - shared CSS variable layer
2 parents 57603f7 + ad5f848 commit 49c209c

20 files changed

Lines changed: 658 additions & 176 deletions

File tree

docs/ROADMAP.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ Ships to `ShellDocs.Components`.
8181
- Prism.js syntax highlighting (via CDN for now — Shiki lands in the next branch)
8282
- Neutral fumadocs-shaped palette (`--background`, `--foreground`, `--primary`, `--muted`, `--accent`, `--border`) — will move to `ShellDocs.Tokens` in the next branch
8383

84-
### `feat/design-tokens`**next**
84+
### `feat/design-tokens`shipped
8585
Ships to new package `ShellDocs.Tokens`.
8686

8787
Extracts the palette + scale from `ShellDocs.Components/wwwroot/shelldocs-theme.css` into its own package so ShellUI (and any third-party consumer) can depend on the *tokens* without pulling in the whole components RCL.

docs/TOKENS.md

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
# ShellDocs Design Tokens
2+
3+
`ShellDocs.Tokens` is a tiny NuGet package that ships **one file**: `tokens.css`. It defines the CSS custom properties every ShellDocs component reads, and is the same surface any third-party Blazor UI library (ShellUI, custom) can consume to share the visual system.
4+
5+
Split out from `ShellDocs.Components` in `feat/design-tokens` so consumers who want *just the tokens* (custom-styled docs sites, or ShellUI users who don't need the docs chrome) can depend on it without pulling the whole components RCL.
6+
7+
## What's in it
8+
9+
A single stylesheet — `_content/ShellDocs.Tokens/tokens.css` — that defines two `:root` blocks: one for light mode and one scoped to `.dark`. That's the whole package.
10+
11+
```html
12+
<link rel="stylesheet" href="_content/ShellDocs.Tokens/tokens.css" />
13+
```
14+
15+
Add the `.dark` class to `<html>` and every dark-mode variable takes over — no additional file, no attribute selector wiring.
16+
17+
## Token contract
18+
19+
Names below are **stable** — renaming any of them is a breaking change (major version bump). Values are free to shift for palette refinement (patch or minor).
20+
21+
### Surface
22+
23+
| Token | Purpose |
24+
|---|---|
25+
| `--background` | Page background |
26+
| `--foreground` | Page text |
27+
| `--card` | Slightly-elevated surface (feature cards, code blocks) |
28+
| `--card-foreground` | Text on `--card` |
29+
| `--popover` | Floating surfaces (dropdowns, mega-menu, package selector menu) |
30+
| `--popover-foreground` | Text on `--popover` |
31+
32+
### Actions
33+
34+
| Token | Purpose |
35+
|---|---|
36+
| `--primary` | Primary action colour (the coloured TOC thumb, primary buttons) |
37+
| `--primary-foreground` | Text on `--primary` |
38+
| `--secondary` | Secondary action bg |
39+
| `--secondary-foreground` | Text on `--secondary` |
40+
41+
### Neutrals
42+
43+
| Token | Purpose |
44+
|---|---|
45+
| `--muted` | Backgrounds for muted UI (nav-link hover, code inline bg, kbd) |
46+
| `--muted-foreground` | Muted text (page descriptions, hints, breadcrumbs) |
47+
| `--accent` | Subtle translucent grey — sidebar active-item bg, hover accents |
48+
| `--accent-foreground` | Text on `--accent` |
49+
50+
### Borders + form
51+
52+
| Token | Purpose |
53+
|---|---|
54+
| `--border` | Default border (all rounded chrome — cards, buttons, inputs) |
55+
| `--border-strong` | Elevated border for interactive-hover state |
56+
| `--input` | Form input background |
57+
| `--ring` | Focus ring colour (2-pixel outline) |
58+
59+
### Semantic
60+
61+
The **only** vibrant tokens — reserved for meaning, never decoration.
62+
63+
| Token | Purpose |
64+
|---|---|
65+
| `--info` | Info callouts, informational badges |
66+
| `--warning` | Warning callouts, deprecated markers |
67+
| `--error` | Error callouts, destructive actions |
68+
| `--success` | Success callouts, checkmark indicators |
69+
70+
### Scale
71+
72+
| Token | Default | Purpose |
73+
|---|---|---|
74+
| `--radius` | `0.5rem` | Base corner radius. Larger surfaces use `calc(var(--radius) + 2px)`; small chips use `calc(var(--radius) - 3px)`. |
75+
| `--sidebar-width` | `17.5rem` | Docs sidebar width |
76+
| `--toc-width` | `14rem` | Right-rail TOC width |
77+
| `--header-height` | `3.5rem` | Sticky header offset |
78+
79+
### Typography
80+
81+
| Token | Purpose |
82+
|---|---|
83+
| `--font-sans` | Body text (`Inter var` first, then system stack) |
84+
| `--font-mono` | Code (`ui-monospace`, JetBrains Mono, then system) |
85+
86+
`tokens.css` also `@import`s the Inter font from `rsms.me/inter/inter.css`. If you don't want Inter, override `--font-sans` in your own stylesheet loaded after `tokens.css` — the browser will just skip the unused font-face rules.
87+
88+
## Overriding
89+
90+
Load `tokens.css` first, then your override stylesheet. Any variable you re-declare on `:root` wins via the cascade.
91+
92+
```html
93+
<link rel="stylesheet" href="_content/ShellDocs.Tokens/tokens.css" />
94+
<link rel="stylesheet" href="my-overrides.css" />
95+
```
96+
97+
```css
98+
/* my-overrides.css */
99+
:root {
100+
--primary: hsl(220, 90%, 55%); /* switch primary to blue */
101+
--radius: 0.75rem; /* softer corners */
102+
--sidebar-width: 20rem; /* wider sidebar */
103+
}
104+
105+
:root.dark {
106+
--primary: hsl(220, 80%, 65%); /* dark-mode primary */
107+
}
108+
```
109+
110+
Per-page or per-scope overrides work too — anywhere the cascade applies.
111+
112+
## Integration paths
113+
114+
### With ShellDocs.Components (default)
115+
116+
`ShellDocs.Components` transitively depends on `ShellDocs.Tokens`, so a project that installs `ShellDocs.Components` gets tokens available at `_content/ShellDocs.Tokens/tokens.css`. Add the `<link>` tag once in your `App.razor` head.
117+
118+
### With ShellUI (Tailwind install)
119+
120+
ShellUI's Tailwind config reads the same variable names (`--primary`, `--muted`, `--border`, `--radius`, etc.). Load `tokens.css` once and ShellUI components inherit the palette automatically. This is the recommended path for Phase 1/2.
121+
122+
### With ShellUI (NuGet, future)
123+
124+
Deferred to `feat/shellui-nuget-interop` (Phase 3). ShellUI's RCL will offer an `AddShellUI(o => o.UseSharedTokens())` opt-in that suppresses its own token emission when `ShellDocs.Tokens` is on the classpath, avoiding duplicate `:root` blocks.
125+
126+
### Standalone (no components RCL)
127+
128+
You can depend on `ShellDocs.Tokens` alone if you want *just the palette* for a custom-styled Blazor site — no ShellDocs sidebar, no ShellDocs header. The tokens are all you get.
129+
130+
## Stability
131+
132+
- **Names** — stable across major versions. Renames are breaking.
133+
- **Values** — may shift between minor versions as the palette is refined. If your site depends on a specific hue, override the token in your own stylesheet.
134+
- **Add-only** — new tokens can appear in minor versions without breaking existing consumers.
135+
- **Deprecations** — flagged one minor version ahead of removal, with a fallback alias for the transition.
136+
137+
## What's NOT in tokens.css
138+
139+
- Base HTML resets (`html`, `body`, `*` box-sizing) — those live in `ShellDocs.Components/wwwroot/shelldocs-theme.css` alongside the prose typography and code-block chrome.
140+
- Component-specific styles (`.shelldocs-prose`, `.shelldocs-codeblock`, scrollbar overrides, Prism overrides) — same location.
141+
- Font files — the Inter font is `@import`ed from `rsms.me`; hosted assets aren't shipped in the package.
142+
143+
If you use `ShellDocs.Components`, you get both files. If you use *just* `ShellDocs.Tokens`, you get variables only — bring your own component styles.

examples/ShellDocs.Preview/Components/App.razor

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
77
<title>ShellDocs — the docs framework for .NET</title>
88
<base href="/" />
9+
<link rel="stylesheet" href="_content/ShellDocs.Tokens/tokens.css" />
910
<link rel="stylesheet" href="_content/ShellDocs.Components/shelldocs-theme.css" />
1011
<link rel="stylesheet" href="ShellDocs.Preview.styles.css" />
1112
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism-tomorrow.min.css" media="(prefers-color-scheme: dark)" />

examples/ShellDocs.Preview/Components/Pages/Blog.razor

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,9 @@
6969
.blog-hero { text-align: center; margin-bottom: 3.5rem; }
7070
.blog-hero .eyebrow {
7171
display: inline-block;
72-
font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.1em;
73-
color: var(--muted-foreground); font-weight: 600;
74-
padding: 0.2rem 0.6rem; border: 1px solid var(--border); border-radius: 9999px;
72+
font-size: 0.75rem; letter-spacing: -0.005em;
73+
color: var(--muted-foreground); font-weight: 500;
74+
padding: 0.2rem 0.7rem; border: 1px solid var(--border); border-radius: 9999px;
7575
margin-bottom: 1rem;
7676
}
7777
.blog-hero h1 { font-size: 2.5rem; font-weight: 700; letter-spacing: -0.03em; margin: 0 0 0.75rem; line-height: 1.1; }

0 commit comments

Comments
 (0)