diff --git a/.changeset/neutral-surfaces-scale.md b/.changeset/neutral-surfaces-scale.md new file mode 100644 index 000000000..1e14bc118 --- /dev/null +++ b/.changeset/neutral-surfaces-scale.md @@ -0,0 +1,7 @@ +--- +"@tailor-platform/app-shell": minor +--- + +Add a `--backdrop` colour token and the `bg-backdrop` utility for the dim layer behind modals. `Dialog`, `Sheet` and the CsvImporter drawer use it instead of `bg-black/50`. The value is the same (black at 50%), so nothing changes on screen. Override `--backdrop` on `:root` to change every backdrop at once. + +In the default palette, the surface and brand colours now read the internal gray scale and a white step, and the dark-mode lines read white alpha steps. All colours are unchanged. If your code reads these tokens with `getComputedStyle(...).getPropertyValue()`, the string changes notation, for example `#171717` instead of `rgba(23, 23, 23, 1)`, for `--primary`, `--primary-foreground`, `--secondary`, `--secondary-foreground`, `--accent-foreground`, `--background`, `--card`, `--card-foreground`, `--popover`, `--popover-foreground`, `--muted`, `--sidebar`, `--sidebar-foreground`, and light-mode `--sidebar-border`. `--foreground`, `--muted-foreground`, `--border` and `--input` already read the gray scale in 1.17.0, and the dark-mode lines keep the same `rgba(...)` string. The `cream` and `bloom` palettes are not changed. diff --git a/decisions/semantic-color-roles.md b/decisions/semantic-color-roles.md index 8a8735789..1d93ae570 100644 --- a/decisions/semantic-color-roles.md +++ b/decisions/semantic-color-roles.md @@ -120,3 +120,14 @@ The "Danger action" row of the target shape is done. `--destructive` and `--dest - `cream`, `bloom` and `_template.css` no longer set `--destructive` (their values equalled the default). `_template.css` lists it under DO NOT SET. A theme that recolours destructive actions overrides `--danger-solid`. - Visible changes in the default palette: light `text-destructive` goes from `#dc2626` to `#ce0c17` through `text-danger-text`, and dark from `#f87171` to `#ff9083`; the dark invalid border goes from `#f87171` to `#dc2626`; CsvImporter error cells use `bg-danger-surface`, matching the warning cells (`bg-warning-surface`). - Outside this repository: `cp-apps/apps/couturier/src/theme-tailor.css` still overrides `--destructive`, and the Theme Generator still emits `destructive` as a constant. Both stop reaching the shipped components until they move to `--danger-*`. + +## Update 2026-10-12: default surfaces, white and alpha scales + +The default palette's surfaces and brand tokens read scale steps. For the default palette, this supersedes "all surfaces stay literal" and "Gray has no alpha steps" under Hue scales, and the second item under "Out of scope". + +- New primitives, declared once with gray because they are the same in both modes: `--primitive-white` and `--primitive-{white,black}-a1` to `-a12`. The alpha values are Radix `whiteA` / `blackA` (0.05, 0.1, 0.15, 0.2, 0.3, then 0.1 steps to 0.9, and 0.95). They are not bridged, like the other primitives. +- In `default.css`, every BRAND and SYSTEM colour with an exact step now reads it. Light: background, sidebar and primary foreground 50, secondary and muted 100, sidebar border 200, primary and secondary foreground 900, the other foregrounds 950, card and popover white. Dark: primary 200, secondary, popover and muted 800, card and primary foreground 900, background and sidebar 950, the other foregrounds 50, border and sidebar border white a2, input white a3. No values change: every token resolves to the same colour as before in light and dark mode. +- White is its own step. The light page is gray 50 and cards are white; putting cards on gray 50 would remove the difference. +- New role `--backdrop`, `var(--primitive-black-a7)` (50%) in both modes, bridged as `bg-backdrop`. `Dialog`, `Sheet` and the CsvImporter drawer use it instead of `bg-black/50`; the value is the same. The name follows the CSS `::backdrop` pseudo-element and the Base UI `Backdrop` part. It is not `overlay`, because `--z-overlay` already names the modal layer, which holds both the backdrop and the popup. +- `--accent`, the shadows and the chart colours stay literal. They have no matching step. `--destructive` reads `--danger-solid` (see Update 2026-10-06). +- `cream`, `bloom` and `_template.css` keep their own literal values. The header comments now list `--backdrop` among the inherited tokens. diff --git a/docs-manifest.json b/docs-manifest.json index 6fab67f4f..e601fd599 100644 --- a/docs-manifest.json +++ b/docs-manifest.json @@ -609,7 +609,7 @@ "hashes": { "typeSurface": "b1614970f950ceb6", "outline": "bda40376d6e3e008", - "snapshot": "b845d4c54453b0f0", + "snapshot": "ac70f5a7004d3bab", "outputMd": "ec6a0ac098d1d87a", "examples": "934c52d4e8761404" } @@ -1067,9 +1067,9 @@ "symbols": [], "hashes": { "typeSurface": null, - "outline": "16c1723900750d80", + "outline": "72b143b96a554f6e", "snapshot": null, - "outputMd": "f095aa7055b83481", + "outputMd": "bf724842da5a8114", "examples": null } }, @@ -1204,7 +1204,7 @@ "hashes": { "typeSurface": "e760949efcbe4c38", "outline": "464d91acc48f7c9d", - "snapshot": "40d15c3f1003fdb0", + "snapshot": "2c9114c5a81198be", "outputMd": "1f81ebd562c50371", "examples": "b0eebb8c5e2219dc" } @@ -1322,9 +1322,9 @@ "symbols": [], "hashes": { "typeSurface": null, - "outline": "dcf033e2a63f0f03", + "outline": "08ea14945176cd57", "snapshot": null, - "outputMd": "3ebd9f5828c49ed7", + "outputMd": "01cfefbafc469e58", "examples": "4d19f4f688e0f0ac" } }, @@ -1694,7 +1694,7 @@ "packages/core/skills/app-shell-patterns/references/concepts/modules-and-resources.md": "bf15b5460f22d165", "packages/core/skills/app-shell-patterns/references/concepts/routing-navigation.md": "8034c7f885994b29", "packages/core/skills/app-shell-patterns/references/concepts/sidebar-navigation.md": "e342ef02dc2b9b86", - "packages/core/skills/app-shell-patterns/references/concepts/styling-theming.md": "3ebd9f5828c49ed7", + "packages/core/skills/app-shell-patterns/references/concepts/styling-theming.md": "01cfefbafc469e58", "packages/core/skills/app-shell-patterns/references/components/action-panel.md": "71794d4b561e4d4b", "packages/core/skills/app-shell-patterns/references/components/activity-card.md": "4f386e49380fb0b0", "packages/core/skills/app-shell-patterns/references/components/ai-chat.md": "824d1aa36bb7f194", @@ -1775,7 +1775,7 @@ "packages/core/skills/app-shell-patterns/references/patterns/interaction-toast.md": "f68bdab855730f48", "packages/core/skills/app-shell-patterns/references/patterns/list-dense-scan.md": "d2c10cdbb00590a2", "packages/core/skills/app-shell-patterns/references/pages/document-detail.md": "717ef4e7ae835aff", - "packages/core/skills/app-shell-patterns/references/migrations.md": "afad0935852bec9f", + "packages/core/skills/app-shell-patterns/references/migrations.md": "214b43b076a41a86", "packages/core/skills/app-shell-patterns/SKILL.md": "4650734e91fbc858" } } diff --git a/docs-src/concepts/styling-theming.docs.outline.md b/docs-src/concepts/styling-theming.docs.outline.md index 70f6ad9f1..3b2b4087c 100644 --- a/docs-src/concepts/styling-theming.docs.outline.md +++ b/docs-src/concepts/styling-theming.docs.outline.md @@ -142,9 +142,14 @@ Colors follow shadcn-style semantic naming: a surface token and its matching `-f | `--border` | hairlines, dividers | `border-border` | | `--input` | form control borders | `border-input` | | `--ring` | focus rings | `ring-ring` / `outline-ring` | +| `--backdrop` | dim layer behind a modal | `bg-backdrop` | Surfaces are named by **role**, not by depth — there is no numbered `surface-1/2/3` ladder, and no third tier of body text below `muted-foreground`. Stack depth with `background` → `card` → `muted` plus a border or shadow, and reach for `popover` when the surface actually floats. +`--backdrop` is the dim layer behind `Dialog` and `Sheet` (black at 50% in both modes). Use `bg-backdrop` for your own modal layers instead of `bg-black/50`. Palettes inherit it; override it on `:root` to change every backdrop at once. + +In the default palette, the surface, text and line tokens in this table read the internal gray scale, a white step, and white alpha steps (dark-mode lines), so their values match the gray used across the palette. `--backdrop` reads a black alpha step, and `--ring` is mixed from `--primary`. The other palettes set their own values. + #### Brand & action | Token | Use | Tailwind | diff --git a/docs-src/guides/migrations.docs.outline.md b/docs-src/guides/migrations.docs.outline.md index f11e727ed..873f7045a 100644 --- a/docs-src/guides/migrations.docs.outline.md +++ b/docs-src/guides/migrations.docs.outline.md @@ -205,7 +205,7 @@ body { Toggle dark mode and confirm a real surface changes: inspect a `Card` and watch its computed `background-color` go from `rgb(255, 255, 255)` to `rgb(23, 23, 23)` on the default palette. -Reading the token directly also works — `getComputedStyle(document.documentElement).getPropertyValue("--card")` returns the winning declaration, so a stale copy shows up as its own value. Just compare against the authored notation: AppShell writes `rgba(23, 23, 23, 1)`, not `#171717`, and the computed value preserves that form. +Reading the token directly also works — `getComputedStyle(document.documentElement).getPropertyValue("--card")` returns the winning declaration, so a stale copy shows up as its own value. Compare against the value the default palette resolves to: in dark mode `--card` returns `#171717`, the gray step it reads. (1.17.0 and earlier return `rgba(23, 23, 23, 1)`.) A copy in your own CSS shows up in the notation you wrote. ## 1.5.0: `loader` removed from file-based page definitions diff --git a/docs/concepts/styling-theming.md b/docs/concepts/styling-theming.md index 3c7380969..1d02eb3a3 100644 --- a/docs/concepts/styling-theming.md +++ b/docs/concepts/styling-theming.md @@ -159,9 +159,14 @@ Colors follow shadcn-style semantic naming: a surface token and its matching `-f | `--border` | hairlines, dividers | `border-border` | | `--input` | form control borders | `border-input` | | `--ring` | focus rings | `ring-ring` / `outline-ring` | +| `--backdrop` | dim layer behind a modal | `bg-backdrop` | Surfaces are named by **role**, not by depth — there is no numbered `surface-1/2/3` ladder, and no third tier of body text below `muted-foreground`. Stack depth with `background` → `card` → `muted` plus a border or shadow, and reach for `popover` when the surface actually floats. +`--backdrop` is the dim layer behind `Dialog` and `Sheet` (black at 50% in both modes). Use `bg-backdrop` for your own modal layers instead of `bg-black/50`. Palettes inherit it; override it on `:root` to change every backdrop at once. + +In the default palette, the surface, text and line tokens in this table read the internal gray scale, a white step, and white alpha steps (dark-mode lines), so their values match the gray used across the palette. `--backdrop` reads a black alpha step, and `--ring` is mixed from `--primary`. The other palettes set their own values. + #### Brand & action | Token | Use | Tailwind | diff --git a/docs/migrations.md b/docs/migrations.md index 9f25f361e..3d02a06bc 100644 --- a/docs/migrations.md +++ b/docs/migrations.md @@ -205,7 +205,7 @@ body { Toggle dark mode and confirm a real surface changes: inspect a `Card` and watch its computed `background-color` go from `rgb(255, 255, 255)` to `rgb(23, 23, 23)` on the default palette. -Reading the token directly also works — `getComputedStyle(document.documentElement).getPropertyValue("--card")` returns the winning declaration, so a stale copy shows up as its own value. Just compare against the authored notation: AppShell writes `rgba(23, 23, 23, 1)`, not `#171717`, and the computed value preserves that form. +Reading the token directly also works — `getComputedStyle(document.documentElement).getPropertyValue("--card")` returns the winning declaration, so a stale copy shows up as its own value. Compare against the value the default palette resolves to: in dark mode `--card` returns `#171717`, the gray step it reads. (1.17.0 and earlier return `rgba(23, 23, 23, 1)`.) A copy in your own CSS shows up in the notation you wrote. ## 1.5.0: `loader` removed from file-based page definitions diff --git a/packages/core/__snapshots__/src__components__dialog__dialog.test.tsx.snap b/packages/core/__snapshots__/src__components__dialog__dialog.test.tsx.snap index 8a18066e3..2023c299b 100644 --- a/packages/core/__snapshots__/src__components__dialog__dialog.test.tsx.snap +++ b/packages/core/__snapshots__/src__components__dialog__dialog.test.tsx.snap @@ -2,6 +2,6 @@ exports[`Dialog > snapshots > closed dialog (trigger only) 1`] = `""`; -exports[`Dialog > snapshots > open dialog with header 1`] = `"