srcdev-nuxt-components 9.1.54 → 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.
- package/.claude/settings.json +29 -2
- package/.claude/skills/components/alert-content-inner.md +60 -0
- package/.claude/skills/components/display-dialog.md +80 -0
- package/.claude/skills/components/display-prompt.md +163 -0
- package/.claude/skills/components/display-toast.md +235 -0
- package/.claude/skills/index.md +7 -3
- package/.claude/skills/theming-colour-ramps.md +328 -0
- package/.claude/skills/theming-override-default.md +115 -186
- package/.claude/skills/theming-partial-override.md +88 -75
- package/README.md +166 -0
- package/app/app.config.ts +44 -0
- package/app/assets/styles/setup/01.config/_head.css +3 -3
- package/app/assets/styles/setup/02.colours/_amber.css +12 -10
- package/app/assets/styles/setup/02.colours/_blue.css +10 -9
- package/app/assets/styles/setup/02.colours/_green.css +12 -11
- package/app/assets/styles/setup/02.colours/_orange.css +12 -10
- package/app/assets/styles/setup/02.colours/_red.css +10 -9
- package/app/assets/styles/setup/02.colours/_slate.css +12 -11
- package/app/assets/styles/setup/02.colours/_sunset.css +12 -10
- package/app/assets/styles/setup/02.colours/_theme-params.css +18 -0
- package/app/assets/styles/setup/02.colours/index.css +1 -0
- package/app/assets/styles/setup/03.theming/_default.css +87 -0
- package/app/assets/styles/setup/03.theming/_error.css +14 -0
- package/app/assets/styles/setup/03.theming/_success.css +4 -0
- package/app/assets/styles/setup/03.theming/_theme-slots.css +16 -0
- package/app/assets/styles/setup/03.theming/_warning.css +13 -0
- package/app/assets/styles/setup/03.theming/index.css +6 -4
- package/app/assets/styles/setup/03.theming/theme-ramp.css +19 -0
- package/app/assets/styles/setup/04.elements/forms/00.element-defaults.css +0 -7
- package/app/assets/styles/setup/04.elements/forms/06.button-geometry.css +1 -1
- package/app/assets/styles/setup/index.css +1 -1
- package/app/components/01.atoms/display-dialog/DisplayDialog.vue +74 -24
- package/app/components/01.atoms/display-dialog/tests/DisplayDialog.spec.ts +148 -14
- package/app/components/01.atoms/display-dialog/tests/__snapshots__/DisplayDialog.spec.ts.snap +3 -3
- package/app/components/01.atoms/page-row/PageRow.vue +5 -0
- package/app/components/01.atoms/prompt/DisplayPrompt.vue +113 -0
- package/app/components/01.atoms/prompt/stories/DisplayPrompt.stories.ts +112 -0
- package/app/components/01.atoms/prompt/tests/DisplayPrompt.spec.ts +205 -0
- package/app/components/01.atoms/toast/DisplayToast.vue +327 -0
- package/app/components/01.atoms/toast/DisplayToastProvider.vue +362 -0
- package/app/components/01.atoms/toast/stories/DisplayToast.stories.ts +195 -0
- package/app/components/01.atoms/toast/stories/DisplayToastProvider.stories.ts +142 -0
- package/app/components/01.atoms/toast/tests/DisplayToast.spec.ts +266 -0
- package/app/components/01.atoms/toast/tests/DisplayToastProvider.spec.ts +256 -0
- package/app/components/02.molecules/action-menu/ActionMenu.vue +8 -1
- package/app/components/02.molecules/action-menu/ActionMenuItemCore.vue +11 -3
- package/app/components/02.molecules/alert-content/AlertContent.vue +67 -0
- package/app/components/02.molecules/alert-content/AlertContentInner.vue +153 -0
- package/app/components/02.molecules/alert-content/stories/AlertContent.stories.ts +131 -0
- package/app/components/02.molecules/alert-content/tests/AlertContent.spec.ts +135 -0
- package/app/components/02.molecules/alert-content/tests/AlertContentInner.spec.ts +135 -0
- package/app/components/02.molecules/alert-masked-content/AlertMaskedContent.vue +78 -0
- package/app/components/02.molecules/alert-masked-content/stories/AlertMaskedContent.stories.ts +132 -0
- package/app/components/02.molecules/alert-masked-content/tests/AlertMaskedContent.spec.ts +149 -0
- package/app/components/05.forms/input-button/InputButtonCore.vue +35 -39
- package/app/components/05.forms/input-checkbox-radio/InputCheckboxRadioButton.vue +8 -8
- package/app/components/05.forms/input-checkbox-radio/InputCheckboxRadioCore.vue +5 -5
- package/app/components/05.forms/input-copy/InputCopyCore.vue +7 -7
- package/app/components/05.forms/input-number/InputNumberCore.vue +5 -5
- package/app/components/05.forms/input-select/InputSelectCore.vue +6 -6
- package/app/components/05.forms/input-text/InputTextCore.vue +6 -6
- package/app/components/05.forms/input-text/variants/InputTextAsNumberWithLabel.vue +2 -2
- package/app/components/05.forms/input-textarea/InputTextareaCore.vue +5 -5
- package/app/components/05.forms/pending-effect/PendingEffect.vue +60 -60
- package/app/components/05.forms/toggle-switch/ToggleSwitchCore.vue +10 -10
- package/app/components/05.forms/triple-toggle-switch/TripleToggleSwitchCore.vue +4 -4
- package/app/components/display-theme-switch/DisplayThemeSwitch.vue +4 -4
- package/app/components/display-tooltip/DisplayTooltip.vue +4 -4
- package/app/composables/useBodyLock.ts +21 -0
- package/app/composables/useDialogControls.ts +11 -11
- package/app/composables/useToastQueue.ts +39 -0
- package/app/layouts/default.vue +1 -1
- package/app/pages/ui/display-dialog.vue +275 -127
- package/app/pages/ui/display-prompt.vue +255 -52
- package/app/pages/ui/display-toast.vue +278 -299
- package/app/pages/ui/mask-element.vue +25 -3
- package/app/pages/ui/settings.vue +9 -35
- package/app/types/app-config.d.ts +41 -0
- package/app/types/components/display-prompt.d.ts +11 -0
- package/app/types/components/display-toast.d.ts +11 -9
- package/app/types/components/index.ts +2 -0
- package/app/types/components/semantic-theme.d.ts +1 -0
- package/nuxt.config.ts +16 -0
- package/package.json +6 -4
- package/app/assets/styles/setup/03.theming/default/_dark.css +0 -156
- package/app/assets/styles/setup/03.theming/default/_light.css +0 -166
- package/app/assets/styles/setup/03.theming/default/index.css +0 -2
- package/app/assets/styles/setup/03.theming/error/_dark.css +0 -56
- package/app/assets/styles/setup/03.theming/error/_light.css +0 -74
- package/app/assets/styles/setup/03.theming/error/index.css +0 -2
- package/app/assets/styles/setup/03.theming/success/_dark.css +0 -50
- package/app/assets/styles/setup/03.theming/success/_light.css +0 -65
- package/app/assets/styles/setup/03.theming/success/index.css +0 -2
- package/app/assets/styles/setup/03.theming/warning/_dark.css +0 -50
- package/app/assets/styles/setup/03.theming/warning/_light.css +0 -64
- package/app/assets/styles/setup/03.theming/warning/index.css +0 -2
- package/app/components/display-prompt/DisplayPromptCore.vue +0 -228
- package/app/components/display-prompt/variants/DisplayPromptError.vue +0 -53
- package/app/components/display-toast/DisplayToast.vue +0 -447
- package/app/components/display-toast/molecules/DefaultToastContent.vue +0 -163
- package/app/components/display-toast/stories/DisplayToast.stories.ts +0 -380
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
# Colour Ramp System
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
The layer uses a parametric oklch colour ramp system. A single formula computes an 11-step colour
|
|
6
|
+
scale (`--colour-theme-0` to `--colour-theme-10`) from two CSS custom properties: `--theme-hue`
|
|
7
|
+
and `--theme-chroma`. Changing those two variables on any element switches the entire colour theme
|
|
8
|
+
for that element's subtree — buttons, inputs, prompts, and toasts all respond automatically.
|
|
9
|
+
|
|
10
|
+
Named palettes are pre-defined in `ramps.config.mjs` and generated to CSS. Themes swap palettes by
|
|
11
|
+
reassigning `--theme-hue` and `--theme-chroma`.
|
|
12
|
+
|
|
13
|
+
## How the formula works
|
|
14
|
+
|
|
15
|
+
`theme-ramp.css` (generated) declares the formula on every potential theme host:
|
|
16
|
+
|
|
17
|
+
```css
|
|
18
|
+
:where(html, [data-theme], [data-invalid]) {
|
|
19
|
+
--colour-theme-0: oklch(98% calc(var(--theme-chroma) * 0.045) var(--theme-hue));
|
|
20
|
+
--colour-theme-1: oklch(94% calc(var(--theme-chroma) * 0.18) var(--theme-hue));
|
|
21
|
+
--colour-theme-2: oklch(88% calc(var(--theme-chroma) * 0.32) var(--theme-hue));
|
|
22
|
+
--colour-theme-3: oklch(80% calc(var(--theme-chroma) * 0.50) var(--theme-hue));
|
|
23
|
+
--colour-theme-4: oklch(72% calc(var(--theme-chroma) * 0.68) var(--theme-hue));
|
|
24
|
+
--colour-theme-5: oklch(64% calc(var(--theme-chroma) * 0.86) var(--theme-hue));
|
|
25
|
+
--colour-theme-6: oklch(56% calc(var(--theme-chroma) * 1.00) var(--theme-hue));
|
|
26
|
+
--colour-theme-7: oklch(48% calc(var(--theme-chroma) * 0.95) var(--theme-hue));
|
|
27
|
+
--colour-theme-8: oklch(40% calc(var(--theme-chroma) * 0.86) var(--theme-hue));
|
|
28
|
+
--colour-theme-9: oklch(32% calc(var(--theme-chroma) * 0.77) var(--theme-hue));
|
|
29
|
+
--colour-theme-10: oklch(25% calc(var(--theme-chroma) * 0.64) var(--theme-hue));
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Scale direction: **00 = lightest, 10 = darkest**. Chroma tapers at both extremes and peaks at
|
|
34
|
+
step 06.
|
|
35
|
+
|
|
36
|
+
The formula is declared on every potential theme host (not just `html`) so that `[data-theme]`
|
|
37
|
+
elements get direct declarations — not inherited ones. This is critical: inherited `--colour-theme-*`
|
|
38
|
+
values would not re-evaluate when `--theme-hue` changes on a child element.
|
|
39
|
+
|
|
40
|
+
### Hue drift
|
|
41
|
+
|
|
42
|
+
Ramps can declare `drift` to rotate the hue angle linearly across steps. The `sunset` palette uses
|
|
43
|
+
`drift: -25`, producing:
|
|
44
|
+
|
|
45
|
+
```css
|
|
46
|
+
var(--theme-hue) + var(--theme-hue-drift, 0) * (i / 10)
|
|
47
|
+
/* step 00: 50 + (-25 × 0.0) = 50° (amber) */
|
|
48
|
+
/* step 05: 50 + (-25 × 0.5) = 37° (orange) */
|
|
49
|
+
/* step 10: 50 + (-25 × 1.0) = 25° (red-orange) */
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Named palettes
|
|
53
|
+
|
|
54
|
+
Defined in `ramps.config.mjs`, generated to `_theme-params.css` as `--palette-{name}-hue`,
|
|
55
|
+
`--palette-{name}-chroma`, and (if drift is set) `--palette-{name}-drift`:
|
|
56
|
+
|
|
57
|
+
| Name | Hue | Max chroma | Notes |
|
|
58
|
+
|--------|-----|------------|-------------------------------|
|
|
59
|
+
| blue | 255 | 0.22 | Layer default |
|
|
60
|
+
| red | 30 | 0.24 | Error/danger theme |
|
|
61
|
+
| green | 157 | 0.19 | Success theme |
|
|
62
|
+
| amber | 75 | 0.19 | |
|
|
63
|
+
| orange | 60 | 0.15 | |
|
|
64
|
+
| sunset | 50 | 0.22 | Warning theme — drift: -25 |
|
|
65
|
+
| slate | 260 | 0.02 | Near-neutral grey |
|
|
66
|
+
|
|
67
|
+
Also generates one named-step file per palette, e.g. `_blue.css` with `--blue-00` … `--blue-10`.
|
|
68
|
+
These are used by components that need a specific step by name (e.g. error state colours in
|
|
69
|
+
`_error.css` reference `--red-06`).
|
|
70
|
+
|
|
71
|
+
## Semantic slots
|
|
72
|
+
|
|
73
|
+
Nine shared colour roles are declared in `_theme-slots.css` on the same selector as the ramp.
|
|
74
|
+
All themed components (buttons, inputs, prompts, toasts) read only these tokens:
|
|
75
|
+
|
|
76
|
+
| Token | Light (step) | Dark (step) | Role |
|
|
77
|
+
|-------------------------|--------------|-------------|-----------------------------------|
|
|
78
|
+
| `--theme-surface` | 7 | 9 | Filled button/chip surface |
|
|
79
|
+
| `--theme-surface-hover` | 9 | 7 | Hover state of filled surface |
|
|
80
|
+
| `--theme-accent` | 5 | 4 | Decorative accent strip (prompt/toast left edge) |
|
|
81
|
+
| `--theme-surface-subtle`| 1 | 9 | Subtle body bg for prompt/toast, outline element hover |
|
|
82
|
+
| `--theme-border` | 6 | 5 | Input/card border |
|
|
83
|
+
| `--theme-border-focus` | 4 | 3 | Focused border |
|
|
84
|
+
| `--theme-ring` | 1 | 9 | Focus ring (outline) |
|
|
85
|
+
| `--theme-on-surface` | 0 | 0 | Text/icon on filled surface |
|
|
86
|
+
| `--theme-text` | 9 | 2 | Text on page, outline element text|
|
|
87
|
+
|
|
88
|
+
Additional context tokens (declared in `_default.css`):
|
|
89
|
+
|
|
90
|
+
| Token | Role |
|
|
91
|
+
|--------------------------------|----------------------------------|
|
|
92
|
+
| `--theme-input-surface` | Input field background |
|
|
93
|
+
| `--theme-input-surface-hover` | Input field hover background |
|
|
94
|
+
| `--theme-input-text-color-normal` | Input text colour |
|
|
95
|
+
| `--theme-input-placeholder` | Placeholder text colour |
|
|
96
|
+
| `--theme-checkbox-symbol-surface` | Checkbox/radio symbol surface |
|
|
97
|
+
| `--page-bg` | Page background |
|
|
98
|
+
| `--colour-text-default` | Body text |
|
|
99
|
+
| `--colour-text-accent` | Accent / heading text |
|
|
100
|
+
| `--colour-text-eyebrow` | Eyebrow text |
|
|
101
|
+
|
|
102
|
+
## Built-in component themes
|
|
103
|
+
|
|
104
|
+
| `data-theme` value | Palette | Notes |
|
|
105
|
+
|--------------------|---------|----------------------------------------------|
|
|
106
|
+
| `"default"` | blue | Page-level default |
|
|
107
|
+
| `"success"` | green | |
|
|
108
|
+
| `"warning"` | sunset | Overrides surface to step 5 for warm feel |
|
|
109
|
+
| `"error"` | red | Also applied on `[data-invalid]` elements |
|
|
110
|
+
|
|
111
|
+
## Generator
|
|
112
|
+
|
|
113
|
+
### Key files
|
|
114
|
+
|
|
115
|
+
| File | Description |
|
|
116
|
+
|-------------------------------------------------------------|------------------------------------------------|
|
|
117
|
+
| `ramps.config.mjs` | Source of truth — hue/chroma/drift per palette |
|
|
118
|
+
| `scripts/generate-ramps.mjs` | Generator — reads config, emits CSS |
|
|
119
|
+
| `scripts/check-ramps.mjs` | CI check — errors if CSS is out of date |
|
|
120
|
+
| `app/assets/styles/setup/02.colours/_<name>.css` | Named steps `--name-00` … `--name-10` |
|
|
121
|
+
| `app/assets/styles/setup/02.colours/_theme-params.css` | `--palette-*` vars |
|
|
122
|
+
| `app/assets/styles/setup/03.theming/theme-ramp.css` | Formula (the `--colour-theme-*` declarations) |
|
|
123
|
+
|
|
124
|
+
### Scripts
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
npm run generate:ramps # rebuild all generated CSS from ramps.config.mjs
|
|
128
|
+
npm run check:ramps # CI: fail if generated CSS is out of date
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Adding a new named palette
|
|
132
|
+
|
|
133
|
+
1. Open `ramps.config.mjs` and add an entry:
|
|
134
|
+
|
|
135
|
+
```js
|
|
136
|
+
export const ramps = {
|
|
137
|
+
// existing entries...
|
|
138
|
+
gold: { hue: 85, chroma: 0.20 },
|
|
139
|
+
// with hue drift across steps:
|
|
140
|
+
// copper: { hue: 45, chroma: 0.21, drift: -15 },
|
|
141
|
+
};
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
1. Regenerate:
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
npm run generate:ramps
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Produces `_gold.css` with `--gold-00` … `--gold-10`, and adds `--palette-gold-hue` /
|
|
151
|
+
`--palette-gold-chroma` to `_theme-params.css`.
|
|
152
|
+
|
|
153
|
+
1. Reference from a theme selector:
|
|
154
|
+
|
|
155
|
+
```css
|
|
156
|
+
[data-theme="gold"] {
|
|
157
|
+
--theme-hue: var(--palette-gold-hue);
|
|
158
|
+
--theme-chroma: var(--palette-gold-chroma);
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Consumer app: generating a custom palette
|
|
163
|
+
|
|
164
|
+
The recommended approach is to generate named colour files so you can reference clean step
|
|
165
|
+
variables (`--gold-09`, `--gold-04`) in your theme overrides rather than raw oklch values.
|
|
166
|
+
|
|
167
|
+
### 1. Create `ramps.config.mjs` in your project root
|
|
168
|
+
|
|
169
|
+
Define the palettes you want. You can add new ones, reuse a built-in name to override the
|
|
170
|
+
layer's values, or both. Consumer CSS loads after the layer, so generated files win the
|
|
171
|
+
cascade automatically:
|
|
172
|
+
|
|
173
|
+
```js
|
|
174
|
+
// ramps.config.mjs
|
|
175
|
+
export const ramps = {
|
|
176
|
+
// New palette — adds --gold-00..10 and --palette-gold-* vars
|
|
177
|
+
gold: { hue: 85, chroma: 0.20 },
|
|
178
|
+
|
|
179
|
+
// Override a built-in — replaces the layer's --blue-00..10 with your values
|
|
180
|
+
// blue: { hue: 240, chroma: 0.18 },
|
|
181
|
+
|
|
182
|
+
// Override the error/invalid palette — all error states use your red
|
|
183
|
+
// red: { hue: 15, chroma: 0.26 },
|
|
184
|
+
|
|
185
|
+
// Optional — hue drift rotates colour linearly across the 11 steps:
|
|
186
|
+
// copper: { hue: 45, chroma: 0.21, drift: -15 },
|
|
187
|
+
};
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### 2. Add the generator to `package.json`
|
|
191
|
+
|
|
192
|
+
The script lives in the layer's `node_modules` — no copying required. Prepend it to `dev`,
|
|
193
|
+
`build`, and `generate` so generated CSS never drifts out of sync with `ramps.config.mjs`:
|
|
194
|
+
|
|
195
|
+
```json
|
|
196
|
+
"scripts": {
|
|
197
|
+
"generate:ramps": "node node_modules/srcdev-nuxt-components/scripts/generate-consumer-ramps.mjs",
|
|
198
|
+
"dev": "npm run generate:ramps && nuxt dev",
|
|
199
|
+
"build": "npm run generate:ramps && nuxt build",
|
|
200
|
+
"generate": "npm run generate:ramps && nuxt generate"
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
Also add it to `postinstall` so it runs automatically after every `npm install`:
|
|
205
|
+
|
|
206
|
+
```json
|
|
207
|
+
"postinstall": "nuxt prepare && npm run generate:ramps && npm run setup:claude"
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
> **Do not manually edit generated files.** They carry a `/* GENERATED */` comment at the top
|
|
211
|
+
> and are overwritten every time the generator runs. All changes belong in `ramps.config.mjs`.
|
|
212
|
+
|
|
213
|
+
### 3. Run the generator
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
npm run generate:ramps
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Produces in `app/assets/styles/setup/02.colours/`:
|
|
220
|
+
|
|
221
|
+
- `_gold.css` — `--gold-00` … `--gold-10` (literal oklch values, same lightness/chroma curve as the layer)
|
|
222
|
+
- `_palette-params.css` — `--palette-gold-hue`, `--palette-gold-chroma`
|
|
223
|
+
|
|
224
|
+
### 4. Import the generated files
|
|
225
|
+
|
|
226
|
+
In `app/assets/styles/setup/02.colours/index.css` (create if it doesn't exist):
|
|
227
|
+
|
|
228
|
+
```css
|
|
229
|
+
@import "./_palette-params";
|
|
230
|
+
@import "./_gold";
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### 5. Set the palette as the theme default
|
|
234
|
+
|
|
235
|
+
```css
|
|
236
|
+
/* app/assets/styles/setup/03.theming/_default.css */
|
|
237
|
+
:where(html) {
|
|
238
|
+
--theme-hue: var(--palette-gold-hue);
|
|
239
|
+
--theme-chroma: var(--palette-gold-chroma);
|
|
240
|
+
|
|
241
|
+
/* Page-level tokens — readable named steps, not raw oklch */
|
|
242
|
+
--colour-text-accent: light-dark(var(--gold-09), var(--gold-04));
|
|
243
|
+
--colour-text-eyebrow: light-dark(var(--gold-09), var(--gold-04));
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/* Optional: make it available as a data-theme variant too */
|
|
247
|
+
[data-theme="gold"] {
|
|
248
|
+
--theme-hue: var(--palette-gold-hue);
|
|
249
|
+
--theme-chroma: var(--palette-gold-chroma);
|
|
250
|
+
}
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### 6. Wire up in your setup index
|
|
254
|
+
|
|
255
|
+
```css
|
|
256
|
+
/* app/assets/styles/setup/index.css */
|
|
257
|
+
@import "./02.colours/";
|
|
258
|
+
@import "./03.theming/_default.css";
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
```css
|
|
262
|
+
/* app/assets/styles/main.css */
|
|
263
|
+
@import "./setup/";
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### Quick palette-only override (no generator)
|
|
267
|
+
|
|
268
|
+
If you only need to shift the hue without named step references, you can skip the generator and
|
|
269
|
+
set the params directly. All components recalculate automatically:
|
|
270
|
+
|
|
271
|
+
```css
|
|
272
|
+
:where(html) {
|
|
273
|
+
--theme-hue: 85;
|
|
274
|
+
--theme-chroma: 0.20;
|
|
275
|
+
}
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
This works for components but gives you no named steps for page-level tokens — use the generator
|
|
279
|
+
approach whenever you need `--gold-09` style references in your CSS.
|
|
280
|
+
|
|
281
|
+
## Light / dark mode
|
|
282
|
+
|
|
283
|
+
Semantic slots use `light-dark()`, which responds to `color-scheme` on `html` (set by the layer's
|
|
284
|
+
`_head.css`):
|
|
285
|
+
|
|
286
|
+
```css
|
|
287
|
+
html {
|
|
288
|
+
color-scheme: light dark; /* OS preference */
|
|
289
|
+
&.light { color-scheme: light; }
|
|
290
|
+
&.dark { color-scheme: dark; }
|
|
291
|
+
}
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
Use `light-dark()` in your own override values too:
|
|
295
|
+
|
|
296
|
+
```css
|
|
297
|
+
:where(html) {
|
|
298
|
+
--theme-hue: 85;
|
|
299
|
+
--theme-chroma: 0.20;
|
|
300
|
+
--page-bg: light-dark(var(--slate-00), var(--slate-08));
|
|
301
|
+
}
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
**Multi-value caveat**: `light-dark()` cannot contain comma-separated values (e.g. box-shadow
|
|
305
|
+
lists). Use intermediate scalar vars:
|
|
306
|
+
|
|
307
|
+
```css
|
|
308
|
+
--_shadow-a: light-dark(0.08, 0.5);
|
|
309
|
+
--my-shadow: 0 8px 32px rgba(0, 0, 0, var(--_shadow-a));
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
The `useColourScheme()` composable toggles the `.light` / `.dark` class on `<html>`. See
|
|
313
|
+
`composable-colour-scheme.md` for the full API.
|
|
314
|
+
|
|
315
|
+
## Hue angle reference
|
|
316
|
+
|
|
317
|
+
| Range | Colour |
|
|
318
|
+
|--------|------------------|
|
|
319
|
+
| 0–30 | Red / pink |
|
|
320
|
+
| 30–70 | Orange / amber |
|
|
321
|
+
| 70–100 | Yellow / gold |
|
|
322
|
+
| 100–160| Green |
|
|
323
|
+
| 160–220| Cyan / teal |
|
|
324
|
+
| 220–270| Blue |
|
|
325
|
+
| 270–310| Violet / purple |
|
|
326
|
+
| 310–360| Magenta / rose |
|
|
327
|
+
|
|
328
|
+
Use [oklch.com](https://oklch.com) to preview values before committing.
|