You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/design.md
+26-3Lines changed: 26 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -13,7 +13,7 @@ The design is a **two-layer color model**: an achromatic base (surfaces, borders
13
13
-**Bordered transparent inputs.** Inputs have a 1px white-alpha border, transparent background, and a pill 1em radius. Focus adds an inset achromatic glow.
14
14
-**Floating overlay panels.** Spotlight, popovers, and modals use direct globals: `--bg-surface`, `--overlay-10`, `--panel-radius`, `--panel-blur`, and `--shadow-panel`.
15
15
-**Editor controls** (toolbar buttons, chips) use `--radius` (6px) for default and `--radius-sm` (3px) for tight badges.
16
-
-**One source of truth: `src/styles/globals.css`.** No hardcoded hex / rgb / hsl in admin / ui CSS modules — gated by `css-token-policy.test.ts`. Admin font sizes use the fluid `--text-*` scale— gated by `admin-typography-token-policy.test.ts`.
16
+
-**One source of truth: `src/styles/globals.css`.** No hardcoded hex / rgb / hsl in admin / ui CSS modules — gated by `css-token-policy.test.ts`. Admin font sizes use the fluid `--text-*` scale, and admin spacing uses the fluid `--space-*` scale — gated by `admin-typography-token-policy.test.ts` and `admin-spacing-token-policy.test.ts`.
17
17
-**CSS Modules only.** No Tailwind utility classes — gated by `noTailwindUtilities.test.ts`. No Tailwind ecosystem deps — gated by `no-tailwind-deps.test.ts`.
18
18
-**Every interactive control goes through a UI primitive** from `src/ui/components/`. Bare `<button>` is gated.
19
19
-**Icons come from `pixel-art-icons`.** Deep-imported for tree-shaking. No `lucide-react`, no inline SVG strings.
@@ -122,7 +122,7 @@ Animations are short, purposeful, and never block content. The `@media (prefers-
122
122
123
123
## Tokens
124
124
125
-
All tokens live in `src/styles/globals.css`. Anywhere you need a color, radius, shadow, font, or z-index, use a token. If the right token doesn't exist, **add one to `globals.css`** — never inline a value.
125
+
All tokens live in `src/styles/globals.css`. Anywhere you need a color, radius, shadow, font, spacing value, or z-index, use a token. If the right token doesn't exist, **add one to `globals.css`** — never inline a value.
@@ -210,6 +217,12 @@ Admin UI font sizes use a Core Framework-style fluid scale: `--text-3xs` through
210
217
211
218
These are admin tokens. The published-site Framework engine also emits short text-size tokens such as `--text-s`; that is a separate scope. Editor chrome injected into the canvas iframe maps admin sizes to `--chrome-text-*` before using them so it does not overwrite the site's Framework typography.
212
219
220
+
### Spacing tokens — fluid size scale
221
+
222
+
Admin UI spacing uses a Core Framework-style fluid scale: `--space-px`, then `--space-4xs` through `--space-12xl`. CSS Modules in `src/admin/` and `src/ui/` should use the scale for `margin`, `padding`, `gap`, `row-gap`, `column-gap`, and CSS-authored SVG dimensions, never a hardcoded pixel value. `--space-px` stays fixed for true 1px hairline gaps.
223
+
224
+
These are admin tokens. The published-site Framework engine also emits short spacing tokens such as `--space-s`; that is a separate scope. Editor chrome injected into the canvas iframe maps admin spacing to `--chrome-space-*` before using it so it does not overwrite the site's Framework spacing.
225
+
213
226
### Radius
214
227
215
228
| Token | Value | Use |
@@ -462,6 +475,15 @@ Every color, gradient, and shadow in `src/admin/`, `src/admin/pages/site/`, and
462
475
463
476
**Exception:**`src/modules/*` is intentionally exempt — those CSS files ship to the published page output where admin tokens are not guaranteed to exist.
464
477
478
+
### No hardcoded spacing in admin / ui CSS modules
479
+
480
+
Admin spacing values in `margin*`, `padding*`, `gap`, `row-gap`, `column-gap`, and CSS-authored SVG dimensions use `var(--space-*)` tokens from `src/styles/globals.css`. Gated by `admin-spacing-token-policy.test.ts`.
481
+
482
+
❌ `padding: 12px 0;`
483
+
✅ `padding: var(--space-l) 0;`
484
+
485
+
**Exception:**`src/modules/*` is intentionally exempt — those CSS files ship to the published page output where admin tokens are not guaranteed to exist.
486
+
465
487
### No `var(--name, fallback)` in admin / ui CSS modules
466
488
467
489
Use bare `var(--name)` — never `var(--name, fallback)`. A fallback is either dead code (the token exists — drop the fallback) or a mask for a missing token (define the token in `globals.css` instead). Defaults for JS-driven custom properties belong in a CSS rule (`[data-x]` selector or `:root`), not scattered in every `var()` reader. Gated by `no-css-var-fallbacks.test.ts`.
@@ -556,7 +578,7 @@ The HTML `title` attribute is banned for hover hints — gated by `no-native-tit
556
578
557
579
1. Create `src/ui/components/<Name>/<Name>.tsx`, `<Name>.module.css`, and `index.ts`.
558
580
2. Re-export from `src/ui/components/index.ts` so consumers import from `@ui/components`.
559
-
3. The primitive must work with the existing tokens — do not introduce new colorsor radii to support it. If you need new tokens, see "Adding a new design token" first.
581
+
3. The primitive must work with the existing tokens — do not introduce new colors, radii, font sizes, or spacing values to support it. If you need new tokens, see "Adding a new design token" first.
560
582
4. If it replaces a bare HTML control (`button`, `input`, etc.), update the matching architecture test's allowlist or gate.
561
583
5. Document it in the components table above and (if it has non-obvious usage) write a short [docs/reference/ui-primitives.md](reference/ui-primitives.md) entry.
562
584
@@ -588,6 +610,7 @@ The HTML `title` attribute is banned for hover hints — gated by `no-native-tit
588
610
-`vendor/pixel-art-icons/` — vendored icon set
589
611
- Gate tests:
590
612
-`src/__tests__/architecture/css-token-policy.test.ts` — no hardcoded colors in admin / ui CSS modules
613
+
-`src/__tests__/architecture/admin-spacing-token-policy.test.ts` — admin / ui margin, padding, gap, and CSS-authored SVG dimensions use fluid `--space-*` tokens
591
614
-`src/__tests__/architecture/no-css-var-fallbacks.test.ts` — no `var(--name, fallback)` in admin / ui CSS modules
592
615
-`src/__tests__/architecture/scrollbar-chrome.test.ts` — scrollbar tokens declared in `globals.css`; both Firefox and WebKit/Blink implementations use them; properties panel uses `scrollbar-gutter: stable`
593
616
-`src/__tests__/architecture/noTailwindUtilities.test.ts` — no Tailwind utility classes (covers all palette names)
Copy file name to clipboardExpand all lines: docs/editor.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -431,7 +431,7 @@ Each iframe `<head>` receives five `<style>` elements (three from `ClassStyleInj
431
431
432
432
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.
433
433
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 safe 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. Admin font and text-sizetokens are remapped to `--chrome-font-sans`and `--chrome-text-*` before use; they are never copied as `--font-sans`or `--text-*`, because those short names belong to the rendered site's Framework tokens inside the canvas.
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 safe 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. Admin font, text-size, and spacing tokens are remapped to `--chrome-font-sans`, `--chrome-text-*`, and `--chrome-space-*` before use; they are never copied as `--font-sans`, `--text-*`, or `--space-*`, because those short names belong to the rendered site's Framework tokens inside the canvas.
435
435
436
436
Full details: [`docs/features/canvas-iframe-per-frame.md`](../features/canvas-iframe-per-frame.md).
437
437
@@ -663,7 +663,7 @@ See [docs/features/plugin-system.md](features/plugin-system.md) for the plugin S
663
663
## Styling
664
664
665
665
-**CSS Modules only.**`Component.module.css` next to `Component.tsx`. Gated by `noTailwindUtilities.test.ts`.
666
-
-**Tokens from `src/styles/globals.css`** — no hardcoded hex / rgb / hsl in admin or ui CSS modules. Gated by `css-token-policy.test.ts`.
666
+
-**Tokens from `src/styles/globals.css`** — no hardcoded hex / rgb / hsl in admin or ui CSS modules, and no hardcoded pixel font sizes or spacing for admin chrome. Gated by `css-token-policy.test.ts`, `admin-typography-token-policy.test.ts`, and `admin-spacing-token-policy.test.ts`.
667
667
-**UI primitives from `src/ui/components/`** — see [docs/design.md](design.md) for the full catalog.
668
668
-**In-house `cn`** from `@ui/cn` — no `clsx`, `tailwind-merge`, `cva`, `@radix-ui/*`. Gated by `no-tailwind-deps.test.ts`.
|`EditorChromeInjector`|`instatic-editor-chrome`|**unlayered**| Editor chrome: placeholder, slot-instance, unknown-module styles. Copies safe required design tokens from parent `:root` onto iframe `:root`. The editor UI font and admin text-size tokensare forwarded as **chrome-namespaced**`--chrome-font-sans`and `--chrome-text-*` aliases, not as `--font-sans`or `--text-*`, because the injector is unlayered and would otherwise clobber the site's own Framework tokens. |
113
+
|`EditorChromeInjector`|`instatic-editor-chrome`|**unlayered**| Editor chrome: placeholder, slot-instance, unknown-module styles. Copies safe required design tokens from parent `:root` onto iframe `:root`. The editor UI font, admin text-size tokens, and admin spacing tokens are forwarded as **chrome-namespaced**`--chrome-font-sans`, `--chrome-text-*`, and `--chrome-space-*` aliases, not as `--font-sans`, `--text-*`, or `--space-*`, because the injector is unlayered and would otherwise clobber the site's own Framework tokens. |
|`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. |
116
116
|`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. |
Copy file name to clipboardExpand all lines: docs/reference/design-tokens.md
+33-2Lines changed: 33 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,13 +1,13 @@
1
1
# Design Tokens
2
2
3
-
The complete catalog of design tokens declared in `src/styles/globals.css`. Every color, radius, shadow, font, font size, and z-index used by the admin / editor / UI primitives is here. CSS Modules in `src/admin/`, `src/admin/pages/site/`, and `src/ui/` MUST reference these via `var(--*)` — hardcoded hex / rgb / hsl is gated by `css-token-policy.test.ts`, and hardcoded font-size pixels are gated by `admin-typography-token-policy.test.ts`.
3
+
The complete catalog of design tokens declared in `src/styles/globals.css`. Every color, radius, shadow, font, font size, spacing value, and z-index used by the admin / editor / UI primitives is here. CSS Modules in `src/admin/`, `src/admin/pages/site/`, and `src/ui/` MUST reference these via `var(--*)` — hardcoded hex / rgb / hsl is gated by `css-token-policy.test.ts`, hardcoded font-size pixels are gated by `admin-typography-token-policy.test.ts`, and hardcoded margin / padding / gap pixels are gated by `admin-spacing-token-policy.test.ts`.
4
4
5
5
---
6
6
7
7
## TL;DR
8
8
9
9
- One file: `src/styles/globals.css`.
10
-
- Grouped by role: fonts/fluid type, core surfaces/text/borders, overlays/scrims, identity accents, semantic state, radii, shadows, canvas, syntax, and z-index.
-**Two-layer color model**: achromatic base + semantic / categorical color layer on top. See [docs/design.md](../design.md) for the rationale.
12
12
- Add a new token by editing `globals.css`. Reference it with `var(--your-token)` in CSS Modules.
13
13
- The `src/modules/` directory is **exempt** from the no-hardcoded-color rule — module CSS ships to published pages where admin tokens are not guaranteed to exist.
@@ -49,6 +49,37 @@ These are admin tokens. The published-site Framework engine also emits short nam
49
49
50
50
---
51
51
52
+
## Fluid spacing scale
53
+
54
+
Admin UI spacing uses the Core Framework-style `--space-*` scale directly. Use these tokens for CSS-authored `margin`, `padding`, `gap`, `row-gap`, `column-gap`, and SVG width/height values in admin and shared UI CSS modules. Keep true hairlines on `--space-px`.
These are admin tokens. The published-site Framework engine also emits short names such as `--space-s`; those belong to the generated site CSS, not admin chrome. Editor chrome injected into the canvasiframe maps admin spacing to `--chrome-space-*` before using it so it cannot override the site's Framework spacing.
80
+
81
+
---
82
+
52
83
## Surface hierarchy (achromatic base)
53
84
54
85
Six surface tones for depth. Lighter is higher in the stack.
Copy file name to clipboardExpand all lines: docs/reference/ui-primitives.md
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -11,7 +11,7 @@ Every interactive control in `src/admin/` goes through one of these. Bare `<butt
11
11
- Import from `@ui/components/<Name>` — each primitive lives in its own folder with `Component.tsx`, `Component.module.css`, and `index.ts`.
12
12
- The 30 primitives below cover every interactive control in the admin. If something's missing, add a new primitive (see "Adding a new primitive" below) — don't reach for a third-party library.
13
13
- Composition uses `cn` from `@ui/cn` — a 3-line in-house helper. **Never**`clsx` / `tailwind-merge` / `cva` / `@radix-ui/*` — gated by `no-tailwind-deps.test.ts`.
14
-
- All colors, radii, and admin font sizes come from CSS custom properties in `src/styles/globals.css` — see [docs/reference/design-tokens.md](design-tokens.md).
14
+
- All colors, radii, admin font sizes, and admin spacing values come from CSS custom properties in `src/styles/globals.css` — see [docs/reference/design-tokens.md](design-tokens.md).
2. Re-export from `src/ui/components/index.ts` so consumers import from `@ui/components`.
594
-
3. CSS uses tokens from `src/styles/globals.css` — never hardcoded colors.
594
+
3. CSS uses tokens from `src/styles/globals.css` — never hardcoded colors, font sizes, or spacing values.
595
595
4. Composition uses `cn` from `@ui/cn`.
596
596
5. Icons come from `pixel-art-icons/icons/<name>` (deep-imported).
597
597
6. If it replaces a bare HTML control (`<button>` etc.), update the matching architecture test (e.g. `button-primitive-usage.test.ts`).
598
598
7. Add a row to the table above in this doc.
599
599
8. Add a one-line entry to [docs/design.md](../design.md) "Components" table.
600
600
601
-
The primitive must work entirely with existing design tokens. If you need a new token, add it to `globals.css` first and update [docs/reference/design-tokens.md](design-tokens.md).
601
+
The primitive must work entirely with existing design tokens. If you need a new color, radius, font-size, or spacing token, add it to `globals.css` first and update [docs/reference/design-tokens.md](design-tokens.md).
0 commit comments