srcdev-nuxt-components 9.1.55 → 9.1.56

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/.claude/settings.json +29 -2
  2. package/.claude/skills/components/alert-content-inner.md +60 -0
  3. package/.claude/skills/components/display-dialog.md +80 -0
  4. package/.claude/skills/components/display-prompt.md +163 -0
  5. package/.claude/skills/components/display-toast.md +235 -0
  6. package/.claude/skills/index.md +7 -3
  7. package/.claude/skills/theming-colour-ramps.md +328 -0
  8. package/.claude/skills/theming-override-default.md +115 -186
  9. package/.claude/skills/theming-partial-override.md +88 -75
  10. package/README.md +166 -0
  11. package/app/app.config.ts +44 -0
  12. package/app/assets/styles/setup/01.config/_head.css +3 -3
  13. package/app/assets/styles/setup/02.colours/_amber.css +12 -10
  14. package/app/assets/styles/setup/02.colours/_blue.css +10 -9
  15. package/app/assets/styles/setup/02.colours/_green.css +12 -11
  16. package/app/assets/styles/setup/02.colours/_orange.css +12 -10
  17. package/app/assets/styles/setup/02.colours/_red.css +10 -9
  18. package/app/assets/styles/setup/02.colours/_slate.css +12 -11
  19. package/app/assets/styles/setup/02.colours/_sunset.css +12 -10
  20. package/app/assets/styles/setup/02.colours/_theme-params.css +18 -0
  21. package/app/assets/styles/setup/02.colours/index.css +1 -0
  22. package/app/assets/styles/setup/03.theming/_default.css +87 -0
  23. package/app/assets/styles/setup/03.theming/_error.css +14 -0
  24. package/app/assets/styles/setup/03.theming/_success.css +4 -0
  25. package/app/assets/styles/setup/03.theming/_theme-slots.css +16 -0
  26. package/app/assets/styles/setup/03.theming/_warning.css +13 -0
  27. package/app/assets/styles/setup/03.theming/index.css +6 -4
  28. package/app/assets/styles/setup/03.theming/theme-ramp.css +19 -0
  29. package/app/assets/styles/setup/04.elements/forms/00.element-defaults.css +0 -7
  30. package/app/assets/styles/setup/04.elements/forms/06.button-geometry.css +1 -1
  31. package/app/assets/styles/setup/index.css +1 -1
  32. package/app/components/01.atoms/display-dialog/DisplayDialog.vue +74 -24
  33. package/app/components/01.atoms/display-dialog/tests/DisplayDialog.spec.ts +148 -14
  34. package/app/components/01.atoms/display-dialog/tests/__snapshots__/DisplayDialog.spec.ts.snap +3 -3
  35. package/app/components/01.atoms/prompt/DisplayPrompt.vue +113 -0
  36. package/app/components/01.atoms/prompt/stories/DisplayPrompt.stories.ts +112 -0
  37. package/app/components/01.atoms/prompt/tests/DisplayPrompt.spec.ts +205 -0
  38. package/app/components/01.atoms/toast/DisplayToast.vue +327 -0
  39. package/app/components/01.atoms/toast/DisplayToastProvider.vue +362 -0
  40. package/app/components/01.atoms/toast/stories/DisplayToast.stories.ts +195 -0
  41. package/app/components/01.atoms/toast/stories/DisplayToastProvider.stories.ts +142 -0
  42. package/app/components/01.atoms/toast/tests/DisplayToast.spec.ts +266 -0
  43. package/app/components/01.atoms/toast/tests/DisplayToastProvider.spec.ts +256 -0
  44. package/app/components/02.molecules/action-menu/ActionMenu.vue +8 -1
  45. package/app/components/02.molecules/action-menu/ActionMenuItemCore.vue +11 -3
  46. package/app/components/02.molecules/alert-content/AlertContent.vue +67 -0
  47. package/app/components/02.molecules/alert-content/AlertContentInner.vue +153 -0
  48. package/app/components/02.molecules/alert-content/stories/AlertContent.stories.ts +131 -0
  49. package/app/components/02.molecules/alert-content/tests/AlertContent.spec.ts +135 -0
  50. package/app/components/02.molecules/alert-content/tests/AlertContentInner.spec.ts +135 -0
  51. package/app/components/02.molecules/alert-masked-content/AlertMaskedContent.vue +78 -0
  52. package/app/components/02.molecules/alert-masked-content/stories/AlertMaskedContent.stories.ts +132 -0
  53. package/app/components/02.molecules/alert-masked-content/tests/AlertMaskedContent.spec.ts +149 -0
  54. package/app/components/05.forms/input-button/InputButtonCore.vue +35 -39
  55. package/app/components/05.forms/input-checkbox-radio/InputCheckboxRadioButton.vue +8 -8
  56. package/app/components/05.forms/input-checkbox-radio/InputCheckboxRadioCore.vue +5 -5
  57. package/app/components/05.forms/input-copy/InputCopyCore.vue +7 -7
  58. package/app/components/05.forms/input-number/InputNumberCore.vue +5 -5
  59. package/app/components/05.forms/input-select/InputSelectCore.vue +6 -6
  60. package/app/components/05.forms/input-text/InputTextCore.vue +6 -6
  61. package/app/components/05.forms/input-text/variants/InputTextAsNumberWithLabel.vue +2 -2
  62. package/app/components/05.forms/input-textarea/InputTextareaCore.vue +5 -5
  63. package/app/components/05.forms/pending-effect/PendingEffect.vue +60 -60
  64. package/app/components/05.forms/toggle-switch/ToggleSwitchCore.vue +10 -10
  65. package/app/components/05.forms/triple-toggle-switch/TripleToggleSwitchCore.vue +4 -4
  66. package/app/components/display-theme-switch/DisplayThemeSwitch.vue +4 -4
  67. package/app/components/display-tooltip/DisplayTooltip.vue +4 -4
  68. package/app/composables/useBodyLock.ts +21 -0
  69. package/app/composables/useDialogControls.ts +11 -11
  70. package/app/composables/useToastQueue.ts +39 -0
  71. package/app/layouts/default.vue +1 -1
  72. package/app/pages/ui/display-dialog.vue +275 -127
  73. package/app/pages/ui/display-prompt.vue +255 -52
  74. package/app/pages/ui/display-toast.vue +278 -299
  75. package/app/pages/ui/mask-element.vue +25 -3
  76. package/app/pages/ui/settings.vue +9 -35
  77. package/app/types/app-config.d.ts +41 -0
  78. package/app/types/components/display-prompt.d.ts +11 -0
  79. package/app/types/components/display-toast.d.ts +11 -9
  80. package/app/types/components/index.ts +2 -0
  81. package/app/types/components/semantic-theme.d.ts +1 -0
  82. package/nuxt.config.ts +16 -0
  83. package/package.json +6 -4
  84. package/app/assets/styles/setup/03.theming/default/_dark.css +0 -156
  85. package/app/assets/styles/setup/03.theming/default/_light.css +0 -166
  86. package/app/assets/styles/setup/03.theming/default/index.css +0 -2
  87. package/app/assets/styles/setup/03.theming/error/_dark.css +0 -56
  88. package/app/assets/styles/setup/03.theming/error/_light.css +0 -74
  89. package/app/assets/styles/setup/03.theming/error/index.css +0 -2
  90. package/app/assets/styles/setup/03.theming/success/_dark.css +0 -50
  91. package/app/assets/styles/setup/03.theming/success/_light.css +0 -65
  92. package/app/assets/styles/setup/03.theming/success/index.css +0 -2
  93. package/app/assets/styles/setup/03.theming/warning/_dark.css +0 -50
  94. package/app/assets/styles/setup/03.theming/warning/_light.css +0 -64
  95. package/app/assets/styles/setup/03.theming/warning/index.css +0 -2
  96. package/app/components/display-prompt/DisplayPromptCore.vue +0 -228
  97. package/app/components/display-prompt/variants/DisplayPromptError.vue +0 -53
  98. package/app/components/display-toast/DisplayToast.vue +0 -447
  99. package/app/components/display-toast/molecules/DefaultToastContent.vue +0 -163
  100. package/app/components/display-toast/stories/DisplayToast.stories.ts +0 -380
@@ -2,255 +2,184 @@
2
2
 
3
3
  ## Overview
4
4
 
5
- The layer ships a default blue theme. This skill covers how to replace it with your own colour palette in a consuming Nuxt app — including adding a new colour scale and remapping all semantic tokens for light and dark modes.
5
+ The layer ships a default blue theme. The recommended way to replace it is to generate your own
6
+ named colour files — this gives you clean step variables (`--gold-09`, `--gold-04`) to reference
7
+ in your theme overrides rather than raw oklch values. Setting `--theme-hue` and `--theme-chroma`
8
+ drives the parametric ramp; the generated files give you named aliases for every step.
9
+
10
+ For the full architecture see `theming-colour-ramps.md`.
6
11
 
7
12
  ## Prerequisites
8
13
 
9
- - Consuming app has `srcdev-nuxt-components` installed as a Nuxt layer
10
- - The consuming app has its own CSS entry point (e.g. `app/assets/styles/main.css`) registered in `nuxt.config.ts` via `css: [...]`
14
+ - `srcdev-nuxt-components` installed as a Nuxt layer
15
+ - A CSS entry point registered in `nuxt.config.ts` (e.g. `app/assets/styles/main.css`)
11
16
 
12
17
  ## Steps
13
18
 
14
- ### 1. Create the colour scale file
19
+ ### 1. Create `ramps.config.mjs` in your project root
15
20
 
16
- Create `app/assets/styles/setup/02.colours/_gold.css` (or your colour name).
21
+ Define the palettes you want. You can add brand-new ones, reuse a built-in name to replace
22
+ the layer's values, or both. Consumer CSS loads after the layer, so your generated files win
23
+ the cascade automatically — no `!important` needed:
17
24
 
18
- Colours use the `oklch` colour space. The scale runs from `00` (lightest) to `10` (darkest) — `00` is optional and only needed if you require a near-white tint.
25
+ ```js
26
+ // ramps.config.mjs
27
+ export const ramps = {
28
+ // New palette — adds --gold-00..10 and --palette-gold-* vars
29
+ gold: { hue: 85, chroma: 0.20 },
19
30
 
20
- ```css
21
- :where(html) {
22
- --gold-00: oklch(98% 0.01 85);
23
- --gold-01: oklch(94% 0.04 85);
24
- --gold-02: oklch(88% 0.09 85);
25
- --gold-03: oklch(80% 0.14 85);
26
- --gold-04: oklch(72% 0.18 85);
27
- --gold-05: oklch(64% 0.20 85);
28
- --gold-06: oklch(56% 0.19 85);
29
- --gold-07: oklch(48% 0.17 85);
30
- --gold-08: oklch(40% 0.15 85);
31
- --gold-09: oklch(32% 0.12 85);
32
- --gold-10: oklch(25% 0.09 85);
33
- }
31
+ // Override a built-in — your generated _blue.css replaces the layer's --blue-00..10
32
+ // blue: { hue: 240, chroma: 0.18 },
33
+
34
+ // Override the error/invalid palette — all red error states use your values
35
+ // red: { hue: 15, chroma: 0.26 },
36
+
37
+ // Optional — add hue drift (colour rotates linearly across the 11 steps):
38
+ // copper: { hue: 45, chroma: 0.21, drift: -15 },
39
+ };
34
40
  ```
35
41
 
36
- Adjust the hue angle (third value) to taste `85` is a warm gold. Use an oklch colour picker to preview the scale.
42
+ Choose your hue and peak chroma using [oklch.com](https://oklch.com). The `chroma` value controls
43
+ saturation at the peak step (06); typical range is 0.12–0.25.
37
44
 
38
- ### 2. Create the colours index
45
+ Hue quick reference:
39
46
 
40
- Create `app/assets/styles/setup/02.colours/index.css` and import your scale:
47
+ | Range | Colour |
48
+ |---------|----------------|
49
+ | 0–30 | Red / pink |
50
+ | 30–70 | Orange / amber |
51
+ | 70–100 | Yellow / gold |
52
+ | 100–160 | Green |
53
+ | 220–270 | Blue |
54
+ | 270–310 | Violet |
41
55
 
42
- ```css
43
- @import "./_gold";
56
+ ### 2. Add the generator to `package.json`
57
+
58
+ The script lives in the layer's `node_modules` — no copying required. Prepend it to `dev`,
59
+ `build`, and `generate` so generated CSS never drifts out of sync with `ramps.config.mjs`:
60
+
61
+ ```json
62
+ "scripts": {
63
+ "generate:ramps": "node node_modules/srcdev-nuxt-components/scripts/generate-consumer-ramps.mjs",
64
+ "dev": "npm run generate:ramps && nuxt dev",
65
+ "build": "npm run generate:ramps && nuxt build",
66
+ "generate": "npm run generate:ramps && nuxt generate"
67
+ }
44
68
  ```
45
69
 
46
- ### 3. Create the light theme override
70
+ Also add it to `postinstall` so it runs automatically after every `npm install`:
47
71
 
48
- Create `app/assets/styles/setup/03.theming/default/_light.css`.
72
+ ```json
73
+ "postinstall": "nuxt prepare && npm run generate:ramps && npm run setup:claude"
74
+ ```
49
75
 
50
- This file uses `:where(html)` and maps semantic tokens to your colour scale. Copy the full token list from the layer and replace `--blue-*` references with `--gold-*`:
76
+ > **Do not manually edit generated files.** They carry a `/* GENERATED */` comment at the top
77
+ > and are overwritten every time the generator runs. All changes belong in `ramps.config.mjs`.
51
78
 
52
- ```css
53
- :where(html) {
54
- /* Color scale */
55
- --colour-theme-1: var(--gold-01);
56
- --colour-theme-2: var(--gold-02);
57
- --colour-theme-3: var(--gold-03);
58
- --colour-theme-4: var(--gold-04);
59
- --colour-theme-5: var(--gold-05);
60
- --colour-theme-6: var(--gold-06);
61
- --colour-theme-7: var(--gold-07);
62
- --colour-theme-8: var(--gold-08);
63
- --colour-theme-9: var(--gold-09);
64
- --colour-theme-10: var(--gold-10);
65
-
66
- /* Body */
67
- --page-bg: var(--slate-00);
68
- --colour-text-default: var(--slate-09);
69
- --colour-text-accent: var(--gold-09);
70
- --colour-text-eyebrow: var(--gold-09);
71
-
72
- /* Links */
73
- --colour-link-default: var(--gold-10);
74
- --colour-link-hover: var(--gold-09);
75
-
76
- /* Form inputs */
77
- --theme-input-surface: var(--slate-00);
78
- --theme-input-surface-hover: var(--slate-01);
79
- --theme-input-border: var(--gold-06);
80
- --theme-input-border-hover: var(--gold-05);
81
- --theme-input-border-focus: var(--gold-04);
82
- --theme-input-outline: transparent;
83
- --theme-input-outline-focus: var(--gold-04);
84
- --theme-input-visible-outline: var(--gold-10);
85
- --theme-focus-visible-shadow: 0 0 0 2px var(--gold-02);
86
- --theme-input-placeholder: var(--slate-05);
87
- --theme-input-text-color-normal: var(--slate-09);
88
-
89
- /* Checkbox / radio */
90
- --theme-checkbox-symbol-color: var(--gold-08);
91
- --theme-checkbox-symbol-surface: var(--theme-input-surface);
92
- --theme-checkbox-decorator-color: var(--gold-09);
93
-
94
- /* Toggle */
95
- --theme-toggle-symbol-color-default: var(--gold-00);
96
- --theme-toggle-symbol-color-checked: var(--gold-08);
97
-
98
- /* Buttons — primary */
99
- --theme-button-primary-surface: var(--gold-09);
100
- --theme-button-primary-surface-hover: var(--gold-08);
101
- --theme-button-primary-surface-active: var(--gold-07);
102
- --theme-button-primary-border: var(--gold-09);
103
- --theme-button-primary-border-active: var(--gold-09);
104
- --theme-button-primary-outline: var(--gold-01);
105
- --theme-button-primary-outline-active: var(--gold-07);
106
- --theme-button-primary-text: var(--gold-00);
107
- --theme-button-primary-text-hover: var(--gold-00);
108
-
109
- /* Buttons — secondary */
110
- --theme-button-secondary-surface: transparent;
111
- --theme-button-secondary-surface-hover: var(--gold-01);
112
- --theme-button-secondary-surface-active: var(--gold-01);
113
- --theme-button-secondary-border: var(--gold-09);
114
- --theme-button-secondary-border-active: var(--gold-09);
115
- --theme-button-secondary-outline: var(--gold-09);
116
- --theme-button-secondary-outline-active: var(--gold-09);
117
- --theme-button-secondary-text: var(--gold-09);
118
- --theme-button-secondary-text-hover: var(--gold-09);
119
-
120
- /* Buttons — tertiary */
121
- --theme-button-tertiary-surface: var(--slate-01);
122
- --theme-button-tertiary-text: var(--gold-09);
123
- --theme-button-tertiary-border-active: var(--gold-09);
124
- --theme-button-tertiary-outline-active: var(--gold-09);
125
- }
79
+ ### 3. Run the generator
80
+
81
+ ```bash
82
+ npm run generate:ramps
126
83
  ```
127
84
 
128
- ### 4. Create the dark theme override
85
+ Produces in `app/assets/styles/setup/02.colours/`:
129
86
 
130
- Create `app/assets/styles/setup/03.theming/default/_dark.css`.
87
+ - `_gold.css` — `--gold-00` … `--gold-10` (literal oklch values, using the layer's lightness/chroma curve)
88
+ - `_palette-params.css` — `--palette-gold-hue`, `--palette-gold-chroma`
131
89
 
132
- Selector is `:where(html.dark)`. Dark mode typically inverts the scale direction — light values for text/borders, dark values for backgrounds:
90
+ ### 4. Import the generated files
91
+
92
+ Create `app/assets/styles/setup/02.colours/index.css`:
133
93
 
134
94
  ```css
135
- :where(html.dark) {
136
- /* Color scale */
137
- --colour-theme-1: var(--gold-01);
138
- --colour-theme-2: var(--gold-02);
139
- --colour-theme-3: var(--gold-03);
140
- --colour-theme-4: var(--gold-04);
141
- --colour-theme-5: var(--gold-05);
142
- --colour-theme-6: var(--gold-06);
143
- --colour-theme-7: var(--gold-07);
144
- --colour-theme-8: var(--gold-08);
145
- --colour-theme-9: var(--gold-09);
146
- --colour-theme-10: var(--gold-10);
147
-
148
- /* Body */
149
- --page-bg: var(--slate-08);
150
- --colour-text-default: var(--slate-01);
151
- --colour-text-accent: var(--gold-05);
152
- --colour-text-eyebrow: var(--gold-05);
153
-
154
- /* Links */
155
- --colour-link-default: var(--gold-03);
156
- --colour-link-hover: var(--gold-04);
157
-
158
- /* Form inputs */
159
- --theme-input-surface: var(--slate-10);
160
- --theme-input-surface-hover: var(--slate-09);
161
- --theme-input-border: var(--gold-06);
162
- --theme-input-border-hover: var(--gold-05);
163
- --theme-input-border-focus: var(--gold-04);
164
- --theme-input-outline: var(--gold-06);
165
- --theme-input-outline-focus: var(--gold-04);
166
- --theme-input-visible-outline: var(--gold-04);
167
- --theme-focus-visible-shadow: 0 0 0 2px var(--gold-02);
168
- --theme-input-placeholder: var(--slate-04);
169
- --theme-input-text-color-normal: var(--slate-01);
170
-
171
- /* Checkbox / radio */
172
- --theme-checkbox-symbol-surface: var(--theme-input-surface);
173
- --theme-checkbox-symbol-color: var(--gold-02);
174
- --theme-checkbox-decorator-color: var(--gold-02);
175
-
176
- /* Buttons — primary */
177
- --theme-button-primary-border: var(--gold-07);
178
- --theme-button-primary-border-active: var(--gold-07);
179
- --theme-button-primary-text: var(--gold-00);
180
- --theme-button-primary-text-hover: var(--gold-00);
181
-
182
- /* Buttons — secondary */
183
- --theme-button-secondary-surface: var(--gold-01);
184
- --theme-button-secondary-border-active: var(--gold-01);
185
- --theme-button-secondary-text: var(--gold-09);
186
-
187
- /* Buttons — tertiary */
188
- --theme-button-tertiary-surface: transparent;
189
- --theme-button-tertiary-text: var(--gold-01);
190
- --theme-button-tertiary-border-active: var(--gold-01);
191
- --theme-button-tertiary-outline-active: var(--gold-09);
192
- }
95
+ @import "./_palette-params";
96
+ @import "./_gold";
193
97
  ```
194
98
 
195
- ### 5. Create the theming index
99
+ ### 5. Set the palette as the theme default
196
100
 
197
- Create `app/assets/styles/setup/03.theming/default/index.css`:
101
+ Create `app/assets/styles/setup/03.theming/_default.css`:
198
102
 
199
103
  ```css
200
- @import "./_light";
201
- @import "./_dark";
104
+ :where(html) {
105
+ --theme-hue: var(--palette-gold-hue);
106
+ --theme-chroma: var(--palette-gold-chroma);
107
+
108
+ /* Page-level tokens — readable named steps, not raw oklch */
109
+ --page-bg: light-dark(var(--slate-00), var(--slate-08));
110
+ --colour-text-default: light-dark(var(--slate-09), var(--slate-01));
111
+ --colour-text-accent: light-dark(var(--gold-09), var(--gold-04));
112
+ --colour-text-eyebrow: light-dark(var(--gold-09), var(--gold-04));
113
+ }
202
114
  ```
203
115
 
116
+ Only `--theme-hue` and `--theme-chroma` are strictly required — all component tokens update
117
+ automatically from there. Add page-level overrides only for tokens that reference the old blue
118
+ palette by name.
119
+
204
120
  ### 6. Create the setup index
205
121
 
206
- Create `app/assets/styles/setup/index.css` that imports colours then theming (order matters — colours must be defined before theming references them):
122
+ `app/assets/styles/setup/index.css`:
207
123
 
208
124
  ```css
209
125
  @import "./02.colours/";
210
- @import "./03.theming/default/";
126
+ @import "./03.theming/_default.css";
211
127
  ```
212
128
 
213
129
  ### 7. Wire up the CSS entry point
214
130
 
215
- In your consuming app's `app/assets/styles/main.css` (or equivalent), import your setup after the layer's styles are applied:
131
+ `app/assets/styles/main.css`:
216
132
 
217
133
  ```css
218
134
  @import "./setup/";
219
135
  ```
220
136
 
221
- Then register it in `nuxt.config.ts`:
137
+ Registered in `nuxt.config.ts`:
222
138
 
223
139
  ```ts
224
140
  export default defineNuxtConfig({
225
141
  extends: "srcdev-nuxt-components",
226
- css: ["~/assets/styles/main.css"],
142
+ css: [
143
+ "srcdev-nuxt-components/app/assets/styles/main.css",
144
+ "~/assets/styles/main.css",
145
+ ],
227
146
  });
228
147
  ```
229
148
 
230
- The consuming app's CSS loads after the layer's, so your token overrides win via the cascade.
149
+ ## How it works
150
+
151
+ The layer's `theme-ramp.css` declares the formula on `:where(html, [data-theme], [data-invalid])`.
152
+ When your override sets `--theme-hue`/`--theme-chroma` on `:where(html)`, every `--colour-theme-*`
153
+ step recalculates to your palette. Semantic slots (`--theme-surface`, `--theme-text`, etc.) are
154
+ declared on that same selector using `light-dark()` — light/dark mode continues to work without
155
+ any extra declarations.
156
+
157
+ The generated `_gold.css` gives you a named alias for each step (`--gold-09` etc.) so your
158
+ page-level token values stay readable. The values match what the formula would produce for
159
+ that hue/chroma pair.
160
+
161
+ ## What you do NOT need to do
162
+
163
+ - Define `--colour-theme-0` through `--colour-theme-10` — the formula handles it
164
+ - Redeclare `--theme-surface`, `--theme-border`, `--theme-ring` etc. — they auto-update
165
+ - Write separate light/dark files — use `light-dark()` in a single file
166
+ - Override any button or input component tokens — they all consume semantic slots
231
167
 
232
168
  ## rem sizing
233
169
 
234
- `html` has `font-size: 62.5%` set in `app/assets/styles/setup/01.config/_head.css`, making `1rem = 10px`. Use this when writing any rem values in your theme or component styles:
170
+ `html` has `font-size: 62.5%` set by the layer, making `1rem = 10px`:
235
171
 
236
172
  | px | rem |
237
- | ---- | ------ |
173
+ |------|--------|
238
174
  | 8px | 0.8rem |
239
175
  | 12px | 1.2rem |
240
176
  | 16px | 1.6rem |
241
177
  | 24px | 2.4rem |
242
178
  | 32px | 3.2rem |
243
179
 
244
- ## Token reference
245
-
246
- See `CONSUMER-STYLING.md` in the layer package root for the full list of available tokens grouped
247
- by category. This is the authoritative reference when deciding which tokens to include in your
248
- override files.
249
-
250
180
  ## Notes
251
181
 
252
- - The `--slate-*` scale comes from the layer and does not need to be redefined keep all neutral/background tokens pointing at `--slate-*`.
253
- - Only redefine tokens that change. You do not need to copy tokens that stay identical between layer and your override.
254
- - Dark mode is triggered by the `dark` class on `<html>`. The layer handles toggling this via `data-color-scheme` and the colour scheme store.
255
- - If you need additional component-specific tokens (e.g. `--stepper-list-*`, `--glass-panel-*`), add them to `_light.css` and `_dark.css` following the same pattern.
256
- - Use an oklch colour picker (e.g. oklch.com) to build and preview your scale before committing values.
182
+ - `--slate-*` neutrals ship with the layer no need to redefine for page backgrounds/text
183
+ - To add a custom `[data-theme]` variant using your generated palette, see `theming-colour-ramps.md`
184
+ - The `warning` theme overrides `--theme-surface` and `--theme-surface-hover` to lighter steps (5/4 and 7/5) so warning buttons read as warm/alert rather than the default dark surface — this pattern is available for any custom theme that needs a non-default surface step
185
+ - `--theme-accent` (step 5/4) is separate from `--theme-surface` (step 7/9) accent is for decorative strips in `DisplayPrompt` and `DisplayToast`; surface is for interactive elements like buttons
@@ -2,130 +2,143 @@
2
2
 
3
3
  ## Overview
4
4
 
5
- Use this skill when you need to override a specific category of tokens (e.g. form inputs, buttons,
6
- colours) without replacing the entire default theme. The full token reference is in
7
- `CONSUMER-STYLING.md` at the root of the layer package.
5
+ Use this skill when you need to tweak a specific colour role (page background, text, buttons,
6
+ inputs) without replacing the entire default theme. For a full palette swap see
7
+ `theming-override-default.md`. For the full architecture see `theming-colour-ramps.md`.
8
8
 
9
9
  ## How it works
10
10
 
11
11
  All library tokens are declared inside `@layer theming`. Any CSS written outside a layer wins
12
- automatically — no `!important` or specificity tricks required. Override files just need to be
13
- imported **after** the layer styles.
12
+ automatically — no `!important` or specificity tricks required. Override files just need to load
13
+ after the layer styles.
14
+
15
+ ## Semantic slots — the tokens to override
16
+
17
+ All themed components share a 9-slot vocabulary. Overriding these affects buttons, inputs,
18
+ prompts, and toasts simultaneously:
19
+
20
+ | Token | Default (light → dark) | Role |
21
+ |-------------------------|----------------------------|-----------------------------------|
22
+ | `--theme-surface` | `--colour-theme-7` / `9` | Filled button/chip surface |
23
+ | `--theme-surface-hover` | `--colour-theme-9` / `7` | Hover state of filled surface |
24
+ | `--theme-accent` | `--colour-theme-5` / `4` | Decorative accent strip (prompt/toast left edge) |
25
+ | `--theme-surface-subtle`| `--colour-theme-1` / `9` | Subtle body bg for prompt/toast, outline element hover |
26
+ | `--theme-border` | `--colour-theme-6` / `5` | Input/card border |
27
+ | `--theme-border-focus` | `--colour-theme-4` / `3` | Focused border |
28
+ | `--theme-ring` | `--colour-theme-1` / `9` | Focus ring (outline) |
29
+ | `--theme-on-surface` | `--colour-theme-0` | Text/icon on filled surface |
30
+ | `--theme-text` | `--colour-theme-9` / `2` | Text on page, outline element text|
31
+
32
+ Input-specific tokens:
33
+
34
+ | Token | Role |
35
+ |---------------------------------|---------------------------|
36
+ | `--theme-input-surface` | Input field background |
37
+ | `--theme-input-surface-hover` | Input hover background |
38
+ | `--theme-input-text-color-normal` | Input text colour |
39
+ | `--theme-input-placeholder` | Placeholder text colour |
40
+ | `--theme-checkbox-symbol-surface` | Checkbox surface |
41
+
42
+ Page-level tokens:
43
+
44
+ | Token | Role |
45
+ |--------------------------|-----------------------|
46
+ | `--page-bg` | Page background |
47
+ | `--colour-text-default` | Body text |
48
+ | `--colour-text-accent` | Accent / heading text |
49
+ | `--colour-text-eyebrow` | Eyebrow text |
14
50
 
15
51
  ## Steps
16
52
 
17
53
  ### 1. Create your override file
18
54
 
19
- Create a CSS file for the category you want to override. Place it anywhere in your app's assets —
20
- `app/assets/styles/` is conventional.
55
+ #### Shift the default palette hue (amber instead of blue)
21
56
 
22
- **Example: form input overrides**
57
+ ```css
58
+ /* app/assets/styles/overrides.css */
59
+ :where(html) {
60
+ --theme-hue: 75; /* amber */
61
+ --theme-chroma: 0.19;
62
+ }
63
+ ```
64
+
65
+ #### Override button surface only
23
66
 
24
67
  ```css
25
- /* app/assets/styles/form-overrides.css */
26
- :root {
27
- --theme-input-surface: oklch(0.98 0.005 250);
28
- --theme-input-border: oklch(0.45 0.08 270);
29
- --theme-input-border-focus: oklch(0.55 0.18 280);
30
- --theme-input-outline-focus: oklch(0.55 0.18 280);
31
- --theme-focus-visible-shadow: 0 0 0 2px oklch(0.80 0.12 280);
32
- --theme-input-placeholder: oklch(0.60 0.02 255);
33
- --theme-input-text-color-normal: oklch(0.20 0.02 255);
68
+ /* Make primary buttons darker/more saturated (step-7/9 defaults, step-9/7 hover) */
69
+ :where(html) {
70
+ --theme-surface: light-dark(oklch(48% 0.18 85), oklch(32% 0.20 85));
71
+ --theme-surface-hover: light-dark(oklch(32% 0.18 85), oklch(48% 0.20 85));
34
72
  }
35
73
  ```
36
74
 
37
- **Example: add a red colour scale and remap accent tokens**
75
+ #### Override input colours only
38
76
 
39
77
  ```css
40
- /* app/assets/styles/red-palette.css */
41
- :root {
42
- /* Red scale 00 (lightest) to 10 (darkest) */
43
- --red-00: oklch(0.99 0.005 20);
44
- --red-01: oklch(0.96 0.020 20);
45
- --red-02: oklch(0.90 0.055 20);
46
- --red-03: oklch(0.82 0.105 20);
47
- --red-04: oklch(0.72 0.155 20);
48
- --red-05: oklch(0.62 0.185 20);
49
- --red-06: oklch(0.53 0.185 20);
50
- --red-07: oklch(0.44 0.165 20);
51
- --red-08: oklch(0.36 0.140 20);
52
- --red-09: oklch(0.28 0.110 20);
53
- --red-10: oklch(0.20 0.080 20);
54
-
55
- /* Remap semantic accent tokens to red */
56
- --colour-text-accent: var(--red-08);
57
- --colour-text-eyebrow: var(--red-08);
58
- --colour-link-default: var(--red-09);
59
- --colour-link-hover: var(--red-08);
78
+ :where(html) {
79
+ --theme-input-surface: light-dark(oklch(0.99 0 0), oklch(0.12 0.01 255));
80
+ --theme-input-text-color-normal: light-dark(oklch(0.20 0.01 255), oklch(0.95 0.01 255));
81
+ --theme-input-placeholder: light-dark(oklch(0.60 0.01 255), oklch(0.40 0.01 255));
60
82
  }
61
83
  ```
62
84
 
63
- **Example: button overrides only**
85
+ #### Override page-level tokens for a different neutral palette
64
86
 
65
87
  ```css
66
- /* app/assets/styles/button-overrides.css */
67
- :root {
68
- --theme-button-primary-surface: oklch(0.55 0.20 280);
69
- --theme-button-primary-surface-hover: oklch(0.48 0.22 280);
70
- --theme-button-primary-surface-active: oklch(0.42 0.22 280);
71
- --theme-button-primary-text: oklch(1 0 0);
72
- --theme-button-primary-text-hover: oklch(1 0 0);
88
+ :where(html) {
89
+ --page-bg: light-dark(oklch(0.98 0 0), oklch(0.10 0 0));
90
+ --colour-text-default: light-dark(oklch(0.20 0 0), oklch(0.93 0 0));
91
+ --colour-text-accent: light-dark(oklch(0.30 0.16 85), oklch(0.65 0.18 85));
73
92
  }
74
93
  ```
75
94
 
76
95
  ### 2. Register it in nuxt.config.ts
77
96
 
78
- Import your override file **after** the layer styles:
79
-
80
97
  ```ts
81
98
  export default defineNuxtConfig({
82
99
  extends: "srcdev-nuxt-components",
83
100
  css: [
84
- "~/assets/styles/form-overrides.css", // or whichever file(s) you created
101
+ "srcdev-nuxt-components/app/assets/styles/main.css",
102
+ "~/assets/styles/overrides.css",
85
103
  ],
86
104
  });
87
105
  ```
88
106
 
89
- The layer's own CSS loads via the `extends` mechanism before app CSS, so your unlayered overrides
90
- always win.
107
+ The layer's own CSS loads via `extends` before app CSS, so your unlayered overrides always win.
91
108
 
92
- ### 3. Dark mode (optional)
109
+ ## Scoped overrides (section or component level)
93
110
 
94
- If you need dark mode variants of your overrides, add them in the same file using the `html.dark`
95
- class selector:
111
+ To restrict an override to a specific section, scope to a wrapper class instead of `:where(html)`:
96
112
 
97
113
  ```css
98
- :root {
99
- --theme-input-surface: oklch(0.98 0.005 250);
114
+ .pricing-section {
115
+ /* Entire section uses green theme */
116
+ --theme-hue: 157;
117
+ --theme-chroma: 0.19;
100
118
  }
101
119
 
102
- :where(html.dark) {
103
- --theme-input-surface: oklch(0.15 0.02 255);
120
+ .hero-cta {
121
+ /* Just these buttons use a different surface colour */
122
+ --theme-surface: light-dark(oklch(48% 0.16 85), oklch(32% 0.18 85));
123
+ --theme-surface-hover: light-dark(oklch(32% 0.14 85), oklch(48% 0.16 85));
104
124
  }
105
125
  ```
106
126
 
107
- ## Scoped overrides (section or component level)
127
+ ## Overriding a specific component theme
108
128
 
109
- To restrict an override to a specific section of the page, scope to a wrapper class instead of
110
- `:root`:
129
+ To change how `data-theme="success"` looks without affecting other themes:
111
130
 
112
131
  ```css
113
- .pricing-section {
114
- --theme-button-primary-surface: oklch(0.55 0.20 140); /* green for pricing CTA */
132
+ [data-theme="success"] {
133
+ /* Shift to teal instead of green */
134
+ --theme-hue: 185;
135
+ --theme-chroma: 0.17;
115
136
  }
116
137
  ```
117
138
 
118
- ## Token reference
119
-
120
- See `CONSUMER-STYLING.md` in the layer package for the full list of available tokens, grouped
121
- by category (typography, colours, form inputs, buttons, checkboxes, toggle, glass panel,
122
- StepperList).
123
-
124
139
  ## Notes
125
140
 
126
- - Only override the tokens you actually need — unset tokens fall back to layer defaults.
127
- - Use oklch for all colour values. Use an oklch colour picker (e.g. oklch.com) to build scales.
128
- - For a full palette replacement (replacing the entire default theme), use
129
- `theming-override-default.md` instead.
130
- - `--slate-*` neutral tokens come from the layer and do not need to be redefined unless you
131
- genuinely want different neutrals.
141
+ - Only override the tokens you actually need — everything else falls back to layer defaults
142
+ - Use `light-dark()` in a single rule rather than separate `:where(html.light)` / `:where(html.dark)` blocks the layer's `color-scheme` infrastructure handles mode switching
143
+ - `--slate-*` neutral tokens come from the layer and do not need to be redefined unless you genuinely want different neutrals
144
+ - For a full palette replacement (changing the layer default), use `theming-override-default.md` instead