|
| 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. |
0 commit comments