Skip to content

Commit 419de61

Browse files
authored
refactor(styles): simplify admin color token vocabulary
1 parent 4c931c7 commit 419de61

243 files changed

Lines changed: 3113 additions & 3121 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/design.md

Lines changed: 114 additions & 115 deletions
Large diffs are not rendered by default.

docs/editor.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ Each iframe `<head>` receives five `<style>` elements (three from `ClassStyleInj
431431

432432
The **unlayered-vs-layered** split is the cascade isolation mechanism: CSS rules outside any `@layer` always beat rules inside `@layer`-d blocks, regardless of specificity. Author CSS (both the class registry and user stylesheets) goes into `@layer user-authored`, so it can never override the editor chrome even with a high-specificity selector.
433433

434-
`EditorChromeInjector` targets chrome elements via **stable data-attribute selectors** (`data-canvas-module-placeholder`, `data-instatic-slot-instance`, `data-instatic-unknown-module`, etc.) rather than hashed CSS-Module class names, which only exist in the parent document. At mount, it copies the required design tokens (`--editor-text-muted`, `--canvas-placeholder-bg`, `--editor-radius`, etc.) from the parent document's `:root` onto the iframe's `:root` so `var(--editor-*)` resolves correctly inside the iframe.
434+
`EditorChromeInjector` targets chrome elements via **stable data-attribute selectors** (`data-canvas-module-placeholder`, `data-instatic-slot-instance`, `data-instatic-unknown-module`, etc.) rather than hashed CSS-Module class names, which only exist in the parent document. At mount, it copies the required design tokens (`--text-subtle`, `--canvas-placeholder-bg`, `--radius`, etc.) from the parent document's `:root` onto the iframe's `:root` so `var(...)` references resolve correctly inside the iframe.
435435

436436
Full details: [`docs/features/canvas-iframe-per-frame.md`](../features/canvas-iframe-per-frame.md).
437437

@@ -580,7 +580,7 @@ The sidebar shell expands/collapses by animating `--*-panel-width`. The panel sl
580580

581581
### Settings modal
582582

583-
`src/admin/modals/Settings/SettingsModal.tsx`. Shares the visual language of the Spotlight palette and Module Inserter: a `--panel-*`-token shell, `--editor-surface-2` rail with categorical rail-tint icon chips, accent-bar section header, card-group rows (`--editor-surface-2` fills, `--panel-radius` corners, 1px gaps showing the darker panel surface through) for section content, and an Esc keycap affordance. Backdrop click and Esc both close — there is no dedicated close button.
583+
`src/admin/modals/Settings/SettingsModal.tsx`. Shares the visual language of the Spotlight palette and Module Inserter: a direct-token panel shell, `--bg-surface-2` rail with categorical accent icon chips, accent-bar section header, card-group rows (`--bg-surface-2` fills, `--panel-radius` corners, 1px gaps showing the darker panel surface through) for section content, and an Esc keycap affordance. Backdrop click and Esc both close — there is no dedicated close button.
584584

585585
**Sections** (rail nav, four entries):
586586

@@ -619,7 +619,7 @@ Data sources:
619619
- **Recent:** per-browser local state in `instatic-module-inserter-v1`, validated with TypeBox before use.
620620
- **Favorites:** per-user server state in `user_preferences` key `module-inserter`, validated with TypeBox by `src/core/persistence/userPreferences.ts` and used by `CanvasNotch`.
621621

622-
The modal uses the tile-card pattern from `docs/design.md`: `--editor-surface` parent, 1px grid gap, `--editor-surface-2` tiles, `--card-radius`, rail-tint accents via `data-accent`, and an achromatic `--editor-focus-ring` selection state. Wireframe image regions reuse `--canvas-placeholder-bg`.
622+
The modal uses the tile-card pattern from `docs/design.md`: `--bg-surface` parent, 1px grid gap, `--bg-surface-2` tiles, `--card-radius`, categorical accents via `data-accent`, and an achromatic `--focus-ring` selection state. Wireframe image regions reuse `--canvas-placeholder-bg`.
623623

624624
### Saved layouts
625625

docs/features/canvas-iframe-per-frame.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ Five `<style>` elements are injected per iframe (three from `ClassStyleInjector`
110110

111111
| Injector | `id` attribute | Cascade layer | Purpose |
112112
|---|---|---|---|
113-
| `EditorChromeInjector` | `instatic-editor-chrome` | **unlayered** | Editor chrome: placeholder, slot-instance, unknown-module styles. Copies design tokens (`--editor-*`) from parent `:root` onto iframe `:root`. The editor UI font is forwarded as a **chrome-namespaced** `--editor-chrome-font-sans` (NOT `--font-sans`): because the injector is unlayered it would otherwise clobber the site's own `--font-sans` and render all canvas content in the editor font. |
113+
| `EditorChromeInjector` | `instatic-editor-chrome` | **unlayered** | Editor chrome: placeholder, slot-instance, unknown-module styles. Copies required design tokens from parent `:root` onto iframe `:root`. The editor UI font is forwarded as a **chrome-namespaced** `--chrome-font-sans` (NOT `--font-sans`): because the injector is unlayered it would otherwise clobber the site's own `--font-sans` and render all canvas content in the editor font. |
114114
| `ClassStyleInjector` | `mc-classes` | `@layer user-authored` | Publisher reset + framework CSS + class registry CSS |
115115
| `ClassStyleInjector` | `mc-classes-preview` | `@layer user-authored` | Higher-specificity preview rule (doubled selector) while a property control is hovered. Empty for state-pseudo rules — those use `mc-classes-force-state` instead. |
116116
| `ClassStyleInjector` | `mc-classes-force-state` | `@layer user-authored` | Force-paints the active state-pseudo rule (`.btn:hover`, `.card:focus`, etc.) onto the selected node via a doubled `[data-node-id]` selector so the state is visible/editable without physically triggering it. Mirrors the full `contextStyles` emission per breakpoint and condition. |

docs/features/dashboard.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ The Dashboard is the **canonical implementation** of the borderless-tile-card pa
1111
- Page entrypoint: `src/admin/pages/dashboard/DashboardPage.tsx`.
1212
- Grid: `DashboardGrid` — 12 columns × 70px row track. `auto-flow: dense` lets widgets backfill earlier gaps.
1313
- Widget registry: `dashboardWidgetRegistry` singleton in `src/core/dashboard/registry.ts`. First-party widgets register on mount; plugins with `dashboard.widgets.register` contribute more.
14-
- Widgets are draggable (move) and resizable (column / row span). Drop targets and resize previews use `--rail-tint-sky` for the dashed indicator.
14+
- Widgets are draggable (move) and resizable (column / row span). Drop targets and resize previews use `--accent-3` for the dashed indicator.
1515
- Customize mode: dashed outline + bottom-docked `<BlockLibrary>` of unused widgets. Toggled by a top-toolbar button.
1616
- Layout persists per-user via `useDashboardLayout` (server-side `user_preferences`).
1717
- Stats stream from `/admin/api/cms/dashboard/<domain>` (`handleDashboardRoutes``server/repositories/audit.ts`, `media.ts`, `data/...`, plus a `fs.stat` walk for plugins and a dialect-aware DB size query for storage).
@@ -86,13 +86,13 @@ src/core/dashboard/
8686

8787
### Customize mode
8888

89-
Customize mode widens the gap from 1px → 16px, animated via `transition: gap 220ms cubic-bezier(0.4, 0, 0.2, 1)`. The grid also gets a dashed sky-tinted outline (`--rail-tint-sky` at low alpha) as the affordance.
89+
Customize mode widens the gap from 1px → 16px, animated via `transition: gap 220ms cubic-bezier(0.4, 0, 0.2, 1)`. The grid also gets a dashed sky-tinted outline (`--accent-3` at low alpha) as the affordance.
9090

9191
The transition works because CSS Grid's `gap` is natively animatable in shipping browsers; the columns are `1fr` so they auto-resize as the gap interpolates, and the cards reflow smoothly.
9292

9393
### 1px gap pattern
9494

95-
Each widget body is `--editor-surface-2` (lighter); the parent is `--editor-surface` (darker). The 1px grid gap reveals the parent and reads as a borderless divider. Hover lifts the widget to `--editor-surface-3` — never recolor a border.
95+
Each widget body is `--bg-surface-2` (lighter); the parent is `--bg-surface` (darker). The 1px grid gap reveals the parent and reads as a borderless divider. Hover lifts the widget to `--bg-surface-3` — never recolor a border.
9696

9797
This is **the canonical implementation** of the tile-card pattern. Build any equivalent surface by reusing `Widget` (`src/ui/components/Widget/`), not by recreating the pattern.
9898

@@ -124,7 +124,7 @@ interface DashboardWidgetDefinition {
124124
| 8 | two-thirds |
125125
| 12 | full |
126126

127-
`tint` maps to one of `--rail-tint-mint/lilac/sky/peach` — used for the widget's title dot and (optionally) the chart series color.
127+
`tint` maps to one of `--accent-1/lilac/sky/peach` — used for the widget's title dot and (optionally) the chart series color.
128128

129129
### First-party widgets
130130

@@ -174,7 +174,7 @@ The ghost is only shown when the destination is valid — if the proposed cell o
174174

175175
### Resize handles
176176

177-
Each cell has 4 edge handles + 1 corner handle. Hover the cell to fade them in; hover a handle to make it brighter. The center accent rail (`--rail-tint-sky`) is the visible affordance; the actual grab box extends 8–14px around the edge.
177+
Each cell has 4 edge handles + 1 corner handle. Hover the cell to fade them in; hover a handle to make it brighter. The center accent rail (`--accent-3`) is the visible affordance; the actual grab box extends 8–14px around the edge.
178178

179179
Edge handles resize column span (left / right) or row span (top / bottom). The corner handle resizes both axes simultaneously and wins over the overlapping edge handles.
180180

@@ -340,7 +340,7 @@ Settings → Reset Dashboard Layout calls `useDashboardLayout(...).reset()`, whi
340340
| Pattern | Use instead |
341341
|--------------------------------------------------------------------|----------------------------------------------------------|
342342
| Recreating the borderless-tile-card look manually | `<Widget tint="...">` |
343-
| Using `--editor-bg` (pure black) as a widget body fill | `--editor-surface-2` — the gap reveals the parent |
343+
| Using `--bg-body` (pure black) as a widget body fill | `--bg-surface-2` — the gap reveals the parent |
344344
| Hovering changes a border instead of a tone | Background tone lift (`-surface-2``-3`) |
345345
| Inventing a new size (e.g. 5 columns) | Stay with the factor-of-12 grid sizes |
346346
| Dispatching dashboard data through the editor store | Use `useDashboardStats` — the dashboard is self-contained|
@@ -356,7 +356,7 @@ Settings → Reset Dashboard Layout calls `useDashboardLayout(...).reset()`, whi
356356
- [docs/editor.md](../editor.md) — broader admin shell
357357
- [docs/design.md](../design.md) — the borderless-tile-card pattern
358358
- [docs/reference/ui-primitives.md](../reference/ui-primitives.md)`Widget`, `WidgetList`, `LiquidProgressRing`, charts
359-
- [docs/reference/design-tokens.md](../reference/design-tokens.md)`--rail-tint-*`, `--editor-surface-*`
359+
- [docs/reference/design-tokens.md](../reference/design-tokens.md)`--accent-*`, `--bg-surface-*`
360360
- Source-of-truth files:
361361
- `src/admin/pages/dashboard/DashboardPage.tsx` — page entrypoint
362362
- `src/admin/pages/dashboard/components/DashboardGrid.tsx` / `.module.css` — canonical grid implementation

docs/features/spotlight.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ src/admin/spotlight/
5555
├── spotlightControls.ts — programmatic controls (open / close / set query)
5656
├── spotlightSearch.ts — search query parsing (scope:, action: prefixes)
5757
├── telemetry.ts — usage logging
58-
├── groupAccent.ts — maps CommandGroup → categorical rail-tint accent
58+
├── groupAccent.ts — maps CommandGroup → categorical accent
5959
├── HelpKeybindingsList.tsx — Cmd+? help screen
6060
├── pendingAction.ts — confirm-destructive flow
6161
├── types.ts — Command, SpotlightProvider, Scope, CommandContext
@@ -257,24 +257,24 @@ When a scope is active:
257257

258258
## The `Spotlight` dialog
259259

260-
`Spotlight.tsx` is the dialog itself — search input, scope chips, result list, footer with keyboard hints. It uses the `--spotlight-*` design tokens (see [docs/reference/design-tokens.md](../reference/design-tokens.md)).
260+
`Spotlight.tsx` is the dialog itself — search input, scope chips, result list, footer with keyboard hints. It uses the global panel, overlay, accent, and state tokens from [docs/reference/design-tokens.md](../reference/design-tokens.md), with only z-index and width scoped to Spotlight.
261261

262262
Key behaviors:
263263

264264
- **Lazy chunk.** `Spotlight` is `React.lazy`-loaded inside `SpotlightRoot`; first-time open downloads the palette code.
265-
- **Backdrop blur** (`--spotlight-backdrop-blur: 8px`).
265+
- **Backdrop blur** (`--backdrop-blur: 8px`).
266266
- **Card rows.** Result rows have a border-radius and are laid out with a 1px gap — the same tile-card language as the module inserter and dashboard.
267-
- **Categorical group accents.** Each command group gets a stable rail-tint identity (e.g. `editor`lilac, `navigation`sky, `media`peach). The accent drives the icon chip color and the group-header accent bar. Mapping lives in `groupAccent.ts`.
268-
- **Row selection** highlight via `--spotlight-row-selected-bg`.
269-
- **Fuzzy match highlighting** — matched characters wrapped in `<mark>` with `--spotlight-mark-bg`.
267+
- **Categorical group accents.** Each command group gets a stable numbered accent identity (e.g. `editor``--accent-2`, `navigation``--accent-3`, `media``--accent-4`). The accent drives the icon chip color and the group-header accent bar. Mapping lives in `groupAccent.ts`.
268+
- **Row selection** highlight via `--overlay-10`.
269+
- **Fuzzy match highlighting** — matched characters wrapped in `<mark>` with `--success-20`.
270270
- **Skeleton shimmer** while providers are in flight.
271271

272272
### Destructive confirm
273273

274274
Commands with `destructive: true` enter a two-press confirm flow:
275275

276276
```text
277-
First Enter: row background turns red (--spotlight-confirm-bg), label shows the confirm prompt
277+
First Enter: row background turns red (--danger-10), label shows the confirm prompt
278278
Second Enter: command runs
279279
Esc / move: resets to the normal state
280280
```
@@ -453,7 +453,7 @@ run: async (ctx) => {
453453
- [docs/architecture.md](../architecture.md) — admin shell mount points
454454
- [docs/editor.md](../editor.md)`SpotlightRoot` placement
455455
- [docs/features/plugin-system.md](plugin-system.md) — plugin commands + providers
456-
- [docs/reference/design-tokens.md](../reference/design-tokens.md)`--spotlight-*` tokens
456+
- [docs/reference/design-tokens.md](../reference/design-tokens.md)global UI token reference
457457
- Source-of-truth files:
458458
- `src/admin/spotlight/SpotlightRoot.tsx` — mount + state
459459
- `src/admin/spotlight/Spotlight.tsx` — the dialog
@@ -466,7 +466,7 @@ run: async (ctx) => {
466466
- `src/admin/spotlight/matcher.ts` — fuzzy match
467467
- `src/admin/spotlight/types.ts``Command`, `SpotlightProvider`, `Scope`, `CommandContext`
468468
- `src/admin/spotlight/keybindings.ts` — keybinding registry
469-
- `src/admin/spotlight/groupAccent.ts` — CommandGroup → rail-tint accent mapping
469+
- `src/admin/spotlight/groupAccent.ts` — CommandGroup → categorical accent mapping
470470
- Gate tests:
471471
- `src/__tests__/architecture/spotlight-no-direct-store-mutation.test.ts`
472472
- `src/__tests__/architecture/keybindings-registry-single-source.test.ts`

docs/reference/canvas-dnd.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,9 @@ The resolver:
103103

104104
The overlay highlights the resolved drop position. Geometry comes from the resolver:
105105

106-
- **Before / After** — a thin sky-tinted line (`--rail-tint-sky` at 0.6 alpha) at the zone position.
106+
- **Before / After** — a thin sky-tinted line (`--accent-3` at 0.6 alpha) at the zone position.
107107
- **Into** — a sky-tinted dashed outline inset 4px from the target's bounding box.
108-
- **Invalid** — a danger-tinted outline (`--editor-danger`) + a tooltip explaining why (`'cannot drop into self'`, `'target is locked'`).
108+
- **Invalid** — a danger-tinted outline (`--danger`) + a tooltip explaining why (`'cannot drop into self'`, `'target is locked'`).
109109

110110
The overlay is a separate React tree positioned with absolute coordinates derived from the canvas zoom/pan transform.
111111

0 commit comments

Comments
 (0)