remarque-tokens 0.16.0 → 0.17.0
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/AGENT_RULES.md +4 -0
- package/CHANGELOG.md +62 -0
- package/REMARQUE.md +39 -0
- package/essay.css +3 -0
- package/package.json +1 -1
- package/scripts/audit.mjs +14 -0
- package/scripts/theme.mjs +137 -0
- package/scripts/tokens-json.mjs +1 -0
- package/theme.css +8 -0
- package/tokens-core.css +16 -0
- package/tokens-palette.css +45 -0
- package/tokens.d.ts +52 -3
- package/tokens.json +92 -1
package/AGENT_RULES.md
CHANGED
|
@@ -62,12 +62,14 @@ These are not guidelines. Agents must follow them literally.
|
|
|
62
62
|
- Within the centered column, use `.content-reading` for prose-width sections (46rem, auto-centered within the 72rem column)
|
|
63
63
|
- Do NOT use Tailwind's `max-w-reading` or `max-w-standard` on page sections — these only set max-width without centering. Use the CSS classes `.content-reading` / `.content-standard` instead, which include `margin-inline: auto`
|
|
64
64
|
- Code blocks (`<pre>`) inherit the width of their parent container — no special wrapping needed when the parent is already constrained
|
|
65
|
+
- Stacking order is structural, not personalization: never author a bare `z-index` number — reference `tokens-core.css`'s `--z-*` scale (`--z-base`/`--z-sticky`/`--z-dropdown`/`--z-overlay`/`--z-modal`/`--z-toast`/`--z-skip-link`). Tailwind v4 has no `--z-index-*` theme namespace, so use arbitrary values (`z-[var(--z-modal)]`) rather than bare Tailwind numbers. See REMARQUE.md "Stacking."
|
|
65
66
|
|
|
66
67
|
### Color
|
|
67
68
|
|
|
68
69
|
- Accent color is used for exactly two things: inline links and one interactive element per viewport
|
|
69
70
|
- Dark mode is not an inverted light mode — it must be independently tuned for readability
|
|
70
71
|
- Background colors use `--color-bg`, never pure white (#fff) or pure black (#000)
|
|
72
|
+
- State colors (`--color-error`/`--color-success`/`--color-warning`/`--color-disabled`, plus the `-subtle` banner-background companions on the first three) are for feedback moments only — form validation, status banners, disabled controls — never for decoration. The one-accent rule above still governs everything else. See REMARQUE.md "State Colors."
|
|
71
73
|
|
|
72
74
|
### Components
|
|
73
75
|
|
|
@@ -212,6 +214,8 @@ Before considering any implementation complete, verify:
|
|
|
212
214
|
- [ ] Muted text placed on `--color-surface` still meets 4.5:1 (check the surface pairing, not just bg)
|
|
213
215
|
- [ ] All transitions use the motion duration tokens (reduced-motion support depends on it)
|
|
214
216
|
- [ ] Skip-to-content link present and functional
|
|
217
|
+
- [ ] If state colors are used (error/success/warning/disabled): only for feedback moments (validation, banners, disabled controls), never decoration; every state text color and `-subtle` companion passes `npm run audit`
|
|
218
|
+
- [ ] No bare `z-index` numbers anywhere in the page's CSS — every stacking layer references `tokens-core.css`'s `--z-*` scale
|
|
215
219
|
- [ ] OG meta tags present (og:title, og:description, og:image)
|
|
216
220
|
- [ ] `<html lang="en">` attribute set
|
|
217
221
|
- [ ] The site looks more like a book than a web app
|
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,68 @@ All notable changes to `remarque-tokens` are documented here. Token value
|
|
|
4
4
|
changes always state the design rationale — downstream sites pin against
|
|
5
5
|
these entries when syncing.
|
|
6
6
|
|
|
7
|
+
## 0.17.0 — 2026-07-23
|
|
8
|
+
|
|
9
|
+
Semantic state colors + z-index scale (closes #26, closes #29).
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
- **State colors (`tokens-palette.css`, PALETTE tier)** — four semantic slots for feedback
|
|
13
|
+
moments (form validation, status banners, disabled controls), never decoration; the
|
|
14
|
+
one-accent rule still governs everything else. Hand-authored from the house ANSI hue
|
|
15
|
+
conventions, both themes, all three dark-mode conventions (`@media
|
|
16
|
+
prefers-color-scheme: dark`, `[data-theme="dark"]`, `:root.dark`):
|
|
17
|
+
- `--color-error` (hue 25, ANSI red) — light `oklch(0.52 0.12 25)` 5.44:1 bg / 5.28:1
|
|
18
|
+
surface; dark `oklch(0.62 0.11 26)` 5.07:1 bg / 4.82:1 surface.
|
|
19
|
+
- `--color-success` (hue 145, ANSI green) — light `oklch(0.51 0.12 145)` 5.08:1 bg /
|
|
20
|
+
4.93:1 surface; dark `oklch(0.61 0.11 145)` 5.36:1 bg / 5.10:1 surface.
|
|
21
|
+
- `--color-warning` (hue 85, ANSI yellow) — light `oklch(0.52 0.105 85)` 5.17:1 bg /
|
|
22
|
+
5.02:1 surface; dark `oklch(0.62 0.11 85)` 5.29:1 bg / 5.03:1 surface. The hard case:
|
|
23
|
+
yellow's low luminance-contrast means this slot solves noticeably darker in light
|
|
24
|
+
mode than error/success, the same shape as `--color-syntax-constant`'s solve.
|
|
25
|
+
- `--color-disabled` — aliased to `var(--color-muted)` in both themes: neutral
|
|
26
|
+
hue-80 muted family, deliberately **not** ANSI-derived.
|
|
27
|
+
- `-subtle` banner-background companions on the first three (`--color-error-subtle`/
|
|
28
|
+
`--color-success-subtle`/`--color-warning-subtle`, modeled on `--color-accent-subtle`
|
|
29
|
+
— near-bg lightness, state hue, low chroma) verified so `--color-fg` stays ≥4.5:1 on
|
|
30
|
+
them (the pairing that matters for callout/banner body text). No `-subtle` for
|
|
31
|
+
`--color-disabled` — a disabled control is quieter, not tinted.
|
|
32
|
+
- Every state text color ≥4.5:1 against `--color-bg` **and** `--color-surface`, both
|
|
33
|
+
themes; `scripts/audit.mjs` gains the 11 new pairings, `scripts/test-audit.mjs`'s
|
|
34
|
+
fixtures cover all seven tokens plus a must-fail case (`state-color-fails.css`).
|
|
35
|
+
- `scripts/theme.mjs` (`remarque-theme`) derives error/success/warning from a source
|
|
36
|
+
theme's red/green/yellow ANSI slots — keep-if-passing lightness checked against the
|
|
37
|
+
**stricter** of `--color-bg`/`--color-surface` at once (a new dual-target solver,
|
|
38
|
+
`keepOrSolveDual`/`solveDual`), not just one target like every other slot. Disabled
|
|
39
|
+
aliases the already-derived `--color-muted`. `-subtle` companions derive like
|
|
40
|
+
`--color-accent-subtle` (fixed 0.95 / bg+0.06 starting lightness — not the theme's
|
|
41
|
+
own solved bg lightness, which can exceed 0.95), nudged toward the extreme only if a
|
|
42
|
+
pathological theme doesn't already clear 4.5:1 against `--color-fg`. Self-verify
|
|
43
|
+
`CHECKS` mirrors `audit.mjs`'s new pairings exactly.
|
|
44
|
+
- `scripts/palette-golden.mjs` golden-gates all seven new tokens for free (it already
|
|
45
|
+
iterates whatever the bridge emits) — ΔE2000 ≤ 2.0 against `remarque-light`/
|
|
46
|
+
`remarque-dark`'s ANSI derivation, same identity/serialization contract as the rest
|
|
47
|
+
of the default palette. All new tokens land at ΔE ≤ 0.5 (see the PR description for
|
|
48
|
+
the full per-token table).
|
|
49
|
+
- REMARQUE.md "State Colors" — semantics, usage table, derivation note; Enforcement
|
|
50
|
+
Checklist gains the state-color pairing line.
|
|
51
|
+
- **Z-index scale (`tokens-core.css`, CORE tier)** — stacking is structural, not
|
|
52
|
+
personalization. A small ordinal scale, sparse gaps of 10: `--z-base` (0), `--z-sticky`
|
|
53
|
+
(10), `--z-dropdown` (20), `--z-overlay` (30), `--z-modal` (40), `--z-toast` (50),
|
|
54
|
+
`--z-skip-link` (60, tops everything). Wired into `essay.css`'s sticky TOC rail
|
|
55
|
+
(`z-index: var(--z-sticky)`) and the demo site's skip-to-content link
|
|
56
|
+
(`focus:z-[var(--z-skip-link)]`, replacing a hardcoded Tailwind `focus:z-50`).
|
|
57
|
+
`theme.css`'s header comment documents the Tailwind v4 workaround — v4 has no
|
|
58
|
+
`--z-index-*` theme namespace, so `z-*` utilities can't map to these directly; use
|
|
59
|
+
arbitrary values (`z-[var(--z-modal)]`) instead, same pattern as the motion durations.
|
|
60
|
+
REMARQUE.md "Stacking" — the scale, and the rule that consumer CSS must never author a
|
|
61
|
+
bare `z-index` number. AGENT_RULES.md's Layout/Quality Checklist sections gain matching
|
|
62
|
+
lines.
|
|
63
|
+
|
|
64
|
+
### Changed
|
|
65
|
+
- **`scripts/tokens-json.mjs`** — `typeOf()` now types `--z-*` tokens as `number`
|
|
66
|
+
(unitless stacking-order integers), matching the existing `--leading-*` treatment,
|
|
67
|
+
instead of falling through to the generic `string` type.
|
|
68
|
+
|
|
7
69
|
## 0.16.0 — 2026-07-23
|
|
8
70
|
|
|
9
71
|
Broadsheet pattern — masthead, lead article, numbered entry list, post-header kicker, graduated from the flagship (closes #36).
|
package/REMARQUE.md
CHANGED
|
@@ -90,6 +90,23 @@ The audit remains the gate regardless of provenance — `remarque-theme` self-ve
|
|
|
90
90
|
|
|
91
91
|
---
|
|
92
92
|
|
|
93
|
+
## State Colors
|
|
94
|
+
|
|
95
|
+
Four semantic slots — `--color-error`, `--color-success`, `--color-warning`, `--color-disabled` — for feedback moments: form validation, status banners, disabled controls. **These are for feedback, not decoration.** The one-accent rule ("Visual Rules" / "Changing the Accent Hue") still governs expressive color everywhere else — a state color says "this specific thing failed/succeeded/needs attention/can't be used right now," not "this section is important." Don't recolor headings, borders, or chrome with a state color; reserve it for the actual feedback element (an inline error message, a success toast, a disabled button's text).
|
|
96
|
+
|
|
97
|
+
Three of the four carry a `-subtle` companion — `--color-error-subtle`, `--color-success-subtle`, `--color-warning-subtle` — a faint tinted background for callout/banner-style feedback (an error banner, a success toast), sized the same way `--color-accent-subtle` is: near-`--color-bg` lightness, the state's hue, low chroma. `--color-disabled` has no `-subtle` companion — a disabled control is quieter than its enabled state, not tinted; use `--color-surface`/`--color-bg-subtle` for a disabled control's background if it needs one.
|
|
98
|
+
|
|
99
|
+
| Slot | Use for | `-subtle` companion |
|
|
100
|
+
|---|---|---|
|
|
101
|
+
| `--color-error` | Validation errors, failure states, destructive-action confirmation text | `--color-error-subtle` (banner/callout background) |
|
|
102
|
+
| `--color-success` | Confirmation messages, completed states | `--color-success-subtle` |
|
|
103
|
+
| `--color-warning` | Caution messages, states needing attention before proceeding | `--color-warning-subtle` |
|
|
104
|
+
| `--color-disabled` | Text/icon color for a disabled control | — (no subtle background; see above) |
|
|
105
|
+
|
|
106
|
+
**Derivation:** hand-authored in `tokens-palette.css` from the house ANSI hue conventions — error hue 25 (red), success hue 145 (green), warning hue 85 (yellow) — the same conventions `--color-syntax-string`/`--color-syntax-constant` already use for green/yellow. `scripts/remarque-theme` derives all three from a source theme's `red`/`green`/`yellow` ANSI slots (keep-if-passing lightness, checked against the **stricter** of `--color-bg` and `--color-surface` at once, not just one), exactly like every other slot in "Color Providers." `--color-disabled` is deliberately **not** ANSI-derived — it aliases the already-derived neutral `--color-muted` family, since a disabled state is a muted/quiet register, not a hue. Warning (hue 85, yellow) is the hard case in light mode — yellow has low luminance-contrast against a light background, so its solved lightness sits noticeably darker than the other two states, the same shape as `--color-syntax-constant`'s solve. Every state text color holds ≥ 4.5:1 against `--color-bg` **and** `--color-surface` in both themes; every `-subtle` background holds `--color-fg` ≥ 4.5:1 on it (the pairing that matters for a callout's body text) — both enforced by `scripts/audit.mjs` and golden-gated (ΔE2000 ≤ 2.0) against the upstream themes like the rest of the default palette.
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
93
110
|
## Font Slots
|
|
94
111
|
|
|
95
112
|
Remarque uses a three-slot font system. Each slot has a strict role, and each slot accepts a small set of approved faces — swap the face, keep the role.
|
|
@@ -365,6 +382,26 @@ Motion in Remarque is nearly invisible. The only permitted motion:
|
|
|
365
382
|
|
|
366
383
|
---
|
|
367
384
|
|
|
385
|
+
## Stacking
|
|
386
|
+
|
|
387
|
+
Stacking order is structural, not personalization — `tokens-core.css` (CORE tier, never overridden) carries a small ordinal `--z-*` scale:
|
|
388
|
+
|
|
389
|
+
| Token | Value | Use for |
|
|
390
|
+
|---|---:|---|
|
|
391
|
+
| `--z-base` | 0 | Default stacking context — the implicit baseline |
|
|
392
|
+
| `--z-sticky` | 10 | Sticky headers/rails (essay.css's TOC rail) |
|
|
393
|
+
| `--z-dropdown` | 20 | Dropdown/select menus |
|
|
394
|
+
| `--z-overlay` | 30 | Overlays/backdrops |
|
|
395
|
+
| `--z-modal` | 40 | Modal dialogs |
|
|
396
|
+
| `--z-toast` | 50 | Toast/notification stacks |
|
|
397
|
+
| `--z-skip-link` | 60 | The skip-to-content link — tops everything; it must never be obscured when focused |
|
|
398
|
+
|
|
399
|
+
**The rule: never a bare `z-index` number in consumer CSS.** Reference one of these seven tokens instead — an unnamed `z-index: 999` (or any other asserted integer) can't be reasoned about against the rest of the page's stacking contexts, and it's the same "hardcoded value bypasses the token system" problem as a literal hex color or a bare font-size. The scale is deliberately sparse (gaps of 10) so a future layer can be inserted between two existing rungs without renumbering everything above it.
|
|
400
|
+
|
|
401
|
+
Tailwind v4 ships `z-*` as a static, non-themable utility scale — there's no `--z-index-*` entry in its default `@theme` to map these into. `theme.css` (the Tailwind v4 adapter) documents the workaround in its header comment: use arbitrary values with the tokens, `z-[var(--z-modal)]` / `focus:z-[var(--z-skip-link)]`, the same pattern already used for motion durations (`duration-[var(--motion-fast)]`).
|
|
402
|
+
|
|
403
|
+
---
|
|
404
|
+
|
|
368
405
|
## USWDS Accessibility Compliance
|
|
369
406
|
|
|
370
407
|
Remarque adopts typography and accessibility standards from the [US Web Design System (USWDS)](https://designsystem.digital.gov/documentation/accessibility/) and [WCAG 2.1](https://www.w3.org/WAI/WCAG21/Understanding/):
|
|
@@ -419,6 +456,8 @@ Every PR that ships Remarque pages MUST pass (`npm run audit` automates the colo
|
|
|
419
456
|
- [ ] No hardcoded hex/rgb colors — only `var(--color-*)` tokens.
|
|
420
457
|
- [ ] Body line-height ≥ 1.5 (Remarque target: 1.75).
|
|
421
458
|
- [ ] Every `--color-syntax-*` slot ≥ 4.5:1 against `--color-code-bg` in both themes (see "Syntax Highlighting").
|
|
459
|
+
- [ ] Every `--color-error`/`--color-success`/`--color-warning`/`--color-disabled` ≥ 4.5:1 against `--color-bg` **and** `--color-surface` in both themes; every `-subtle` background keeps `--color-fg` ≥ 4.5:1 on it (see "State Colors"). State colors used only for feedback moments, never decoration.
|
|
460
|
+
- [ ] No bare `z-index` number in consumer CSS — reference `tokens-core.css`'s `--z-*` scale (see "Stacking").
|
|
422
461
|
|
|
423
462
|
Agents reviewing PRs should reject changes that violate any line above without explicit rationale.
|
|
424
463
|
|
package/essay.css
CHANGED
|
@@ -421,6 +421,9 @@
|
|
|
421
421
|
align-self: start;
|
|
422
422
|
justify-self: start;
|
|
423
423
|
position: sticky;
|
|
424
|
+
/* --z-sticky (tokens-core.css, issue #29) — never a bare z-index
|
|
425
|
+
number in consumer CSS. */
|
|
426
|
+
z-index: var(--z-sticky);
|
|
424
427
|
top: var(--space-6);
|
|
425
428
|
width: 100%;
|
|
426
429
|
max-height: calc(100vh - var(--space-8));
|
package/package.json
CHANGED
package/scripts/audit.mjs
CHANGED
|
@@ -122,6 +122,20 @@ const CHECKS = [
|
|
|
122
122
|
['color-syntax-punctuation', 'color-code-bg', 4.5, 'syntax: punctuation'],
|
|
123
123
|
['color-syntax-variable', 'color-code-bg', 4.5, 'syntax: variable'],
|
|
124
124
|
['color-syntax-link', 'color-code-bg', 4.5, 'syntax: link'],
|
|
125
|
+
// Semantic state colors (issue #26) — feedback moments, not decoration.
|
|
126
|
+
['color-error', 'color-bg', 4.5, 'state: error text'],
|
|
127
|
+
['color-error', 'color-surface', 4.5, 'state: error text on surface'],
|
|
128
|
+
['color-success', 'color-bg', 4.5, 'state: success text'],
|
|
129
|
+
['color-success', 'color-surface', 4.5, 'state: success text on surface'],
|
|
130
|
+
['color-warning', 'color-bg', 4.5, 'state: warning text'],
|
|
131
|
+
['color-warning', 'color-surface', 4.5, 'state: warning text on surface'],
|
|
132
|
+
['color-disabled', 'color-bg', 4.5, 'state: disabled text'],
|
|
133
|
+
['color-disabled', 'color-surface', 4.5, 'state: disabled text on surface'],
|
|
134
|
+
// -subtle banner backgrounds: the pairing that matters is --color-fg on
|
|
135
|
+
// the subtle background (callout/banner body text), not the state color.
|
|
136
|
+
['color-fg', 'color-error-subtle', 4.5, 'state: fg on error-subtle banner bg'],
|
|
137
|
+
['color-fg', 'color-success-subtle', 4.5, 'state: fg on success-subtle banner bg'],
|
|
138
|
+
['color-fg', 'color-warning-subtle', 4.5, 'state: fg on warning-subtle banner bg'],
|
|
125
139
|
];
|
|
126
140
|
|
|
127
141
|
for (const [themeName, decls] of [['light', lightDecls], ['dark', darkDecls]]) {
|
package/scripts/theme.mjs
CHANGED
|
@@ -387,6 +387,101 @@ function deriveSyntaxLink(accent, codeBg, dir) {
|
|
|
387
387
|
return keepOrSolve(accent[0], accent[1], accent[2], codeBg, 4.5, dir);
|
|
388
388
|
}
|
|
389
389
|
|
|
390
|
+
/* ── Semantic state colors (issue #26) ────────────────────────────────
|
|
391
|
+
* error/success/warning are derived from the theme's red/green/yellow ANSI
|
|
392
|
+
* slots — the same "ANSI colors already carry this domain's personality"
|
|
393
|
+
* argument as the syntax slots above, applied to feedback-moment colors
|
|
394
|
+
* instead of code tokens. Unlike every other keep-if-passing slot, the
|
|
395
|
+
* target here is TWO backgrounds at once (--color-bg and --color-surface,
|
|
396
|
+
* per the #26 scope comment: "keep-if-passing vs both") — a state color
|
|
397
|
+
* must hold 4.5:1 against whichever of the two is stricter, not just one.
|
|
398
|
+
* disabled is NOT ANSI — it aliases the already-derived neutral muted
|
|
399
|
+
* family, same as tokens-palette.css's hand-authored default.
|
|
400
|
+
*/
|
|
401
|
+
|
|
402
|
+
/* Dual-target variant of keepOrSolve/solveL: passes only when BOTH bg and
|
|
403
|
+
* surface clear `target` at the candidate L. Mirrors their guarded-nudge
|
|
404
|
+
* fallback shape, just checking two ratios instead of one. */
|
|
405
|
+
function solveLDual(C, H, bg, surface, target, dir) {
|
|
406
|
+
const searchTarget = target * 1.03;
|
|
407
|
+
let lo = 0, hi = 1;
|
|
408
|
+
for (let i = 0; i < 40; i++) {
|
|
409
|
+
const mid = (lo + hi) / 2;
|
|
410
|
+
const c = fitChroma(mid, C, H);
|
|
411
|
+
const passes = ratio([mid, c, H], bg) >= searchTarget && ratio([mid, c, H], surface) >= searchTarget;
|
|
412
|
+
if (dir === 'darker') { if (passes) lo = mid; else hi = mid; }
|
|
413
|
+
else { if (passes) hi = mid; else lo = mid; }
|
|
414
|
+
}
|
|
415
|
+
let L = r3(dir === 'darker' ? lo : hi);
|
|
416
|
+
let c = fitChroma(L, C, H);
|
|
417
|
+
let guard = 0;
|
|
418
|
+
while ((ratio([L, c, H], bg) < target || ratio([L, c, H], surface) < target) && guard < 100) {
|
|
419
|
+
const next = dir === 'darker' ? r3(L - 0.001) : r3(L + 0.001);
|
|
420
|
+
if (next < 0 || next > 1 || next === L) break;
|
|
421
|
+
L = next;
|
|
422
|
+
c = fitChroma(L, C, H);
|
|
423
|
+
guard++;
|
|
424
|
+
}
|
|
425
|
+
const ok = ratio([L, c, H], bg) >= target && ratio([L, c, H], surface) >= target;
|
|
426
|
+
if (ok) return { L, C: c, H: r1(H), ok };
|
|
427
|
+
return { L, C: c, H: r1(H), ok: false };
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
function solveDual(C, H, bg, surface, target, dir) {
|
|
431
|
+
let r = solveLDual(C, H, bg, surface, target, dir);
|
|
432
|
+
if (r.ok) return [r.L, r.C, r.H];
|
|
433
|
+
// Chroma-collapse fallback, same rationale as solveL's.
|
|
434
|
+
r = solveLDual(0, H, bg, surface, target, dir);
|
|
435
|
+
if (r.ok) return [r.L, r.C, r.H];
|
|
436
|
+
die(
|
|
437
|
+
`internal error: cannot solve a state color for a ${target}:1 target against both bg and surface ` +
|
|
438
|
+
`(hue ${H.toFixed(1)}, direction ${dir}) even with chroma collapsed to 0 — pathological theme colors`
|
|
439
|
+
);
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
/* keep-if-passing against BOTH bg and surface at once. */
|
|
443
|
+
function keepOrSolveDual(L0, C, H, bg, surface, target, dir) {
|
|
444
|
+
const L = Math.min(1, Math.max(0, r3(L0)));
|
|
445
|
+
const c = fitChroma(L, C, H);
|
|
446
|
+
if (ratio([L, c, H], bg) >= target && ratio([L, c, H], surface) >= target) return [L, c, r1(H)];
|
|
447
|
+
return solveDual(C, H, bg, surface, target, dir);
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
const STATE_CHROMA_CAP = 0.14; // same restrained ceiling as --color-accent / syntax slots
|
|
451
|
+
|
|
452
|
+
function deriveStateColor(t, ansiName, label, bg, surface, dir) {
|
|
453
|
+
const [L0, C0, H0] = slotLch(t, ansiName, label);
|
|
454
|
+
const C = Math.min(C0, STATE_CHROMA_CAP);
|
|
455
|
+
return keepOrSolveDual(L0, C, H0, bg, surface, 4.5, dir);
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
/* -subtle companions: near-bg lightness (mirrors --color-accent-subtle
|
|
459
|
+
* EXACTLY — same fixed 0.95 / bg+0.06 starting points, not a theme-
|
|
460
|
+
* relative "bg's own lightness" — accent-subtle is the identity this
|
|
461
|
+
* mirrors, and its light-side constant is 0.95 regardless of how high a
|
|
462
|
+
* given theme's own solved bg lightness lands), state hue, low chroma —
|
|
463
|
+
* verified so --color-fg stays >= 4.5:1 on the result (the pairing that
|
|
464
|
+
* matters for a callout/banner's body text), not re-verified against bg/
|
|
465
|
+
* surface (it's a background, not a text color). `dir` 'darker' (light
|
|
466
|
+
* theme): subtle starts at 0.95. 'lighter' (dark theme): subtle starts at
|
|
467
|
+
* bg + 0.06. Nudged further toward the extreme (whiter in light, blacker
|
|
468
|
+
* in dark) only if a pathological theme's hue/chroma combination doesn't
|
|
469
|
+
* already clear 4.5:1 against fg at that starting lightness. */
|
|
470
|
+
function deriveStateSubtle(bgL, H, chromaCap, fg, dir) {
|
|
471
|
+
let L = dir === 'darker' ? 0.95 : r3(Math.min(bgL + 0.06, 1));
|
|
472
|
+
let c = fitChroma(L, chromaCap, H);
|
|
473
|
+
let guard = 0;
|
|
474
|
+
while (ratio(fg, [L, c, H]) < 4.5 && guard < 200) {
|
|
475
|
+
L = dir === 'darker' ? r3(Math.min(1, L + 0.001)) : r3(Math.max(0, L - 0.001));
|
|
476
|
+
c = fitChroma(L, chromaCap, H);
|
|
477
|
+
guard++;
|
|
478
|
+
}
|
|
479
|
+
if (ratio(fg, [L, c, H]) < 4.5) {
|
|
480
|
+
die(`internal error: cannot solve a state-subtle background (hue ${H.toFixed(1)}, dir ${dir}) that holds --color-fg >= 4.5:1 — pathological theme colors`);
|
|
481
|
+
}
|
|
482
|
+
return [L, c, r1(H)];
|
|
483
|
+
}
|
|
484
|
+
|
|
390
485
|
/* ── LIGHT derivation ─────────────────────────────────────────────── */
|
|
391
486
|
|
|
392
487
|
function deriveLight(t) {
|
|
@@ -425,6 +520,15 @@ function deriveLight(t) {
|
|
|
425
520
|
const synPunctuation = deriveSyntaxPunctuation(fgC, fgH, codeBg, 'darker');
|
|
426
521
|
const synVariable = deriveSyntaxVariable(fg, codeBg, 'darker', 0.08);
|
|
427
522
|
const synLink = deriveSyntaxLink(accent, codeBg, 'darker');
|
|
523
|
+
// Semantic state colors (issue #26) — see the derivation helpers above.
|
|
524
|
+
// error/success/warning: keep-if-passing vs BOTH bg and surface at once;
|
|
525
|
+
// disabled: aliased to the already-derived muted family, not ANSI.
|
|
526
|
+
const stateError = deriveStateColor(t, 'red', 'light', bg, surface, 'darker');
|
|
527
|
+
const stateSuccess = deriveStateColor(t, 'green', 'light', bg, surface, 'darker');
|
|
528
|
+
const stateWarning = deriveStateColor(t, 'yellow', 'light', bg, surface, 'darker');
|
|
529
|
+
const stateErrorSubtle = deriveStateSubtle(bg[0], stateError[2], 0.02, fg, 'darker');
|
|
530
|
+
const stateSuccessSubtle = deriveStateSubtle(bg[0], stateSuccess[2], 0.02, fg, 'darker');
|
|
531
|
+
const stateWarningSubtle = deriveStateSubtle(bg[0], stateWarning[2], 0.02, fg, 'darker');
|
|
428
532
|
const raw = {
|
|
429
533
|
'color-bg': bg,
|
|
430
534
|
'color-bg-subtle': [r3(bg[0] - 0.02), bg[1], bg[2]],
|
|
@@ -450,6 +554,13 @@ function deriveLight(t) {
|
|
|
450
554
|
'color-syntax-punctuation': synPunctuation,
|
|
451
555
|
'color-syntax-variable': synVariable,
|
|
452
556
|
'color-syntax-link': synLink,
|
|
557
|
+
'color-error': stateError,
|
|
558
|
+
'color-error-subtle': stateErrorSubtle,
|
|
559
|
+
'color-success': stateSuccess,
|
|
560
|
+
'color-success-subtle': stateSuccessSubtle,
|
|
561
|
+
'color-warning': stateWarning,
|
|
562
|
+
'color-warning-subtle': stateWarningSubtle,
|
|
563
|
+
'color-disabled': { ref: 'color-muted' },
|
|
453
564
|
};
|
|
454
565
|
const tokens = {};
|
|
455
566
|
for (const [name, v] of Object.entries(raw)) tokens[name] = v.ref ? `var(--${v.ref})` : fmt(v);
|
|
@@ -503,6 +614,14 @@ function deriveDark(t, accentHueLight) {
|
|
|
503
614
|
const synPunctuation = deriveSyntaxPunctuation(fgC, fgH, codeBg, 'lighter');
|
|
504
615
|
const synVariable = deriveSyntaxVariable(fg, codeBg, 'lighter', -0.08);
|
|
505
616
|
const synLink = deriveSyntaxLink(accent, codeBg, 'lighter');
|
|
617
|
+
// Semantic state colors (issue #26) — mirrors the light derivation,
|
|
618
|
+
// direction flipped ('lighter': text on a dark bg/surface).
|
|
619
|
+
const stateError = deriveStateColor(t, 'red', 'dark', bg, surface, 'lighter');
|
|
620
|
+
const stateSuccess = deriveStateColor(t, 'green', 'dark', bg, surface, 'lighter');
|
|
621
|
+
const stateWarning = deriveStateColor(t, 'yellow', 'dark', bg, surface, 'lighter');
|
|
622
|
+
const stateErrorSubtle = deriveStateSubtle(bg[0], stateError[2], 0.04, fg, 'lighter');
|
|
623
|
+
const stateSuccessSubtle = deriveStateSubtle(bg[0], stateSuccess[2], 0.04, fg, 'lighter');
|
|
624
|
+
const stateWarningSubtle = deriveStateSubtle(bg[0], stateWarning[2], 0.04, fg, 'lighter');
|
|
506
625
|
const raw = {
|
|
507
626
|
'color-bg': bg,
|
|
508
627
|
'color-bg-subtle': surface,
|
|
@@ -528,6 +647,13 @@ function deriveDark(t, accentHueLight) {
|
|
|
528
647
|
'color-syntax-punctuation': synPunctuation,
|
|
529
648
|
'color-syntax-variable': synVariable,
|
|
530
649
|
'color-syntax-link': synLink,
|
|
650
|
+
'color-error': stateError,
|
|
651
|
+
'color-error-subtle': stateErrorSubtle,
|
|
652
|
+
'color-success': stateSuccess,
|
|
653
|
+
'color-success-subtle': stateSuccessSubtle,
|
|
654
|
+
'color-warning': stateWarning,
|
|
655
|
+
'color-warning-subtle': stateWarningSubtle,
|
|
656
|
+
'color-disabled': { ref: 'color-muted' },
|
|
531
657
|
};
|
|
532
658
|
const tokens = {};
|
|
533
659
|
for (const [name, v] of Object.entries(raw)) tokens[name] = v.ref ? `var(--${v.ref})` : fmt(v);
|
|
@@ -564,6 +690,17 @@ const CHECKS = [
|
|
|
564
690
|
['color-syntax-punctuation', 'color-code-bg', 4.5, 'syntax: punctuation'],
|
|
565
691
|
['color-syntax-variable', 'color-code-bg', 4.5, 'syntax: variable'],
|
|
566
692
|
['color-syntax-link', 'color-code-bg', 4.5, 'syntax: link'],
|
|
693
|
+
['color-error', 'color-bg', 4.5, 'state: error text'],
|
|
694
|
+
['color-error', 'color-surface', 4.5, 'state: error text on surface'],
|
|
695
|
+
['color-success', 'color-bg', 4.5, 'state: success text'],
|
|
696
|
+
['color-success', 'color-surface', 4.5, 'state: success text on surface'],
|
|
697
|
+
['color-warning', 'color-bg', 4.5, 'state: warning text'],
|
|
698
|
+
['color-warning', 'color-surface', 4.5, 'state: warning text on surface'],
|
|
699
|
+
['color-disabled', 'color-bg', 4.5, 'state: disabled text'],
|
|
700
|
+
['color-disabled', 'color-surface', 4.5, 'state: disabled text on surface'],
|
|
701
|
+
['color-fg', 'color-error-subtle', 4.5, 'state: fg on error-subtle banner bg'],
|
|
702
|
+
['color-fg', 'color-success-subtle', 4.5, 'state: fg on success-subtle banner bg'],
|
|
703
|
+
['color-fg', 'color-warning-subtle', 4.5, 'state: fg on warning-subtle banner bg'],
|
|
567
704
|
];
|
|
568
705
|
|
|
569
706
|
function resolveRaw(raw, name, seen = new Set()) {
|
package/scripts/tokens-json.mjs
CHANGED
|
@@ -22,6 +22,7 @@ function typeOf(name, value) {
|
|
|
22
22
|
if (name.startsWith('weight-')) return 'fontWeight';
|
|
23
23
|
if (name.startsWith('motion-') && /ms$/.test(value)) return 'duration';
|
|
24
24
|
if (name.startsWith('leading-')) return 'number';
|
|
25
|
+
if (name.startsWith('z-')) return 'number'; // unitless stacking-order integers, not a length
|
|
25
26
|
if (value === '0') return 'dimension';
|
|
26
27
|
if (/(^|\s)(rem|px|em|%)/.test(value) || /^-?[\d.]+(rem|px|em)$/.test(value) || value.startsWith('clamp(')) return 'dimension';
|
|
27
28
|
return 'string';
|
package/theme.css
CHANGED
|
@@ -27,6 +27,14 @@
|
|
|
27
27
|
* Pair every duration-[var(--motion-*)] utility with ease-remarque
|
|
28
28
|
* (mapped below from --motion-easing) — without it Tailwind falls back
|
|
29
29
|
* to its default `ease` timing function instead of the token (issue #31).
|
|
30
|
+
*
|
|
31
|
+
* Z-index utilities: Tailwind v4 ships z-* as a static, non-themable
|
|
32
|
+
* scale (there is no --z-index-* entry in its default @theme, so there
|
|
33
|
+
* is nothing here to map into). Use arbitrary values with the tokens
|
|
34
|
+
* instead — z-[var(--z-modal)], focus:z-[var(--z-skip-link)] — same
|
|
35
|
+
* pattern as the motion durations above, so every stacking layer stays
|
|
36
|
+
* traceable to tokens-core.css's --z-* scale (issue #29) instead of a
|
|
37
|
+
* bare Tailwind number.
|
|
30
38
|
*/
|
|
31
39
|
|
|
32
40
|
@theme inline {
|
package/tokens-core.css
CHANGED
|
@@ -80,6 +80,22 @@
|
|
|
80
80
|
--motion-fast: 120ms; /* hover states, focus rings */
|
|
81
81
|
--motion-normal: 180ms; /* theme transitions */
|
|
82
82
|
--motion-easing: ease-out;
|
|
83
|
+
|
|
84
|
+
/* Z-Index Scale (issue #29) — stacking is structural, not
|
|
85
|
+
personalization: CORE tier, never overridden. A small ordinal scale,
|
|
86
|
+
sparse gaps of 10 so a future layer can be inserted between two
|
|
87
|
+
existing rungs without renumbering everything above it. Consumer CSS
|
|
88
|
+
must never author a bare z-index number — reference one of these
|
|
89
|
+
seven tokens instead (Tailwind v4 has no --z-index-* theme namespace,
|
|
90
|
+
so its z-* utilities can't reference these directly; see theme.css's
|
|
91
|
+
header comment for the arbitrary-value bridge, z-[var(--z-modal)]). */
|
|
92
|
+
--z-base: 0;
|
|
93
|
+
--z-sticky: 10; /* essay.css's TOC rail, sticky headers/rails */
|
|
94
|
+
--z-dropdown: 20;
|
|
95
|
+
--z-overlay: 30;
|
|
96
|
+
--z-modal: 40;
|
|
97
|
+
--z-toast: 50;
|
|
98
|
+
--z-skip-link: 60; /* tops everything — a focused skip-link must never be obscured */
|
|
83
99
|
}
|
|
84
100
|
|
|
85
101
|
/* ─── Reduced Motion ────────────────────────────────────── */
|
package/tokens-palette.css
CHANGED
|
@@ -94,6 +94,29 @@
|
|
|
94
94
|
--color-syntax-punctuation: oklch(0.52 0.01 80); /* derived neutral, muted family — 4.69:1 */
|
|
95
95
|
--color-syntax-variable: oklch(0.26 0.01 80); /* fg-adjacent (slight L offset) — 13.23:1 */
|
|
96
96
|
--color-syntax-link: var(--color-accent); /* accent already clears code-bg — 4.5:1+ */
|
|
97
|
+
|
|
98
|
+
/* Semantic state colors (issue #26) — feedback moments (error/success/
|
|
99
|
+
warning banners, disabled controls), NOT decoration; the one-accent
|
|
100
|
+
rule still governs expressive color. Hand-authored from the house
|
|
101
|
+
ANSI hue conventions (scripts/theme.mjs derives error/success/warning
|
|
102
|
+
from a theme's red/green/yellow ANSI slots): error hue 25, success
|
|
103
|
+
hue 145, warning hue 85 — restrained chroma, keep-if-passing lightness
|
|
104
|
+
checked against the STRICTER of --color-bg/--color-surface (surface
|
|
105
|
+
is stricter in both themes here, same as --color-muted). Warning at
|
|
106
|
+
hue 85 is the hard case in light mode (low luminance-contrast yellow)
|
|
107
|
+
— solved dark, same register as --color-syntax-constant. Disabled is
|
|
108
|
+
neutral-derived (muted family), NOT ANSI — aliased to --color-muted.
|
|
109
|
+
-subtle companions (error/success/warning only, no disabled-subtle)
|
|
110
|
+
are derived like --color-accent-subtle: near-bg lightness, state hue,
|
|
111
|
+
low chroma — verified so --color-fg stays ≥4.5:1 on them, the pairing
|
|
112
|
+
that matters for callout/banner backgrounds. */
|
|
113
|
+
--color-error: oklch(0.52 0.12 25); /* ANSI red — 5.44:1 bg / 5.28:1 surface */
|
|
114
|
+
--color-error-subtle: oklch(0.95 0.02 25); /* faint red banner background */
|
|
115
|
+
--color-success: oklch(0.51 0.12 145); /* ANSI green — 5.08:1 bg / 4.93:1 surface */
|
|
116
|
+
--color-success-subtle: oklch(0.95 0.02 145); /* faint green banner background */
|
|
117
|
+
--color-warning: oklch(0.52 0.105 85); /* ANSI yellow — 5.17:1 bg / 5.02:1 surface */
|
|
118
|
+
--color-warning-subtle: oklch(0.95 0.02 85); /* faint yellow banner background */
|
|
119
|
+
--color-disabled: var(--color-muted); /* muted family, not ANSI-derived */
|
|
97
120
|
}
|
|
98
121
|
|
|
99
122
|
/* ─── Color: Dark theme ─────────────────────────────────── */
|
|
@@ -139,6 +162,18 @@
|
|
|
139
162
|
--color-syntax-punctuation: oklch(0.60 0.005 80); /* derived neutral, muted family — 4.59:1 */
|
|
140
163
|
--color-syntax-variable: oklch(0.82 0.005 80); /* fg-adjacent (slight L offset) — 10.37:1 */
|
|
141
164
|
--color-syntax-link: var(--color-accent); /* accent already clears code-bg */
|
|
165
|
+
|
|
166
|
+
/* Semantic state colors (issue #26) — see the light-theme block above
|
|
167
|
+
for the full rationale. Same hues (red 25 / green 145 / yellow 85),
|
|
168
|
+
lightened for a dark background; keep-if-passing checked against
|
|
169
|
+
the stricter of bg/surface (surface, here too). */
|
|
170
|
+
--color-error: oklch(0.62 0.11 26); /* 5.07:1 bg / 4.82:1 surface */
|
|
171
|
+
--color-error-subtle: oklch(0.22 0.04 25);
|
|
172
|
+
--color-success: oklch(0.61 0.11 145); /* 5.36:1 bg / 5.10:1 surface */
|
|
173
|
+
--color-success-subtle: oklch(0.22 0.04 145);
|
|
174
|
+
--color-warning: oklch(0.62 0.11 85); /* 5.29:1 bg / 5.03:1 surface */
|
|
175
|
+
--color-warning-subtle: oklch(0.22 0.04 85);
|
|
176
|
+
--color-disabled: var(--color-muted);
|
|
142
177
|
}
|
|
143
178
|
}
|
|
144
179
|
|
|
@@ -182,4 +217,14 @@
|
|
|
182
217
|
--color-syntax-punctuation: oklch(0.60 0.005 80);
|
|
183
218
|
--color-syntax-variable: oklch(0.82 0.005 80);
|
|
184
219
|
--color-syntax-link: var(--color-accent);
|
|
220
|
+
|
|
221
|
+
/* Semantic state colors (issue #26) — see the light-theme :root block
|
|
222
|
+
for the full rationale. */
|
|
223
|
+
--color-error: oklch(0.62 0.11 26);
|
|
224
|
+
--color-error-subtle: oklch(0.22 0.04 25);
|
|
225
|
+
--color-success: oklch(0.61 0.11 145);
|
|
226
|
+
--color-success-subtle: oklch(0.22 0.04 145);
|
|
227
|
+
--color-warning: oklch(0.62 0.11 85);
|
|
228
|
+
--color-warning-subtle: oklch(0.22 0.04 85);
|
|
229
|
+
--color-disabled: var(--color-muted);
|
|
185
230
|
}
|
package/tokens.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* Remarque design tokens — GENERATED from tokens.json by
|
|
3
|
-
* scripts/tokens-json.mjs (v0.
|
|
3
|
+
* scripts/tokens-json.mjs (v0.17.0). Do not edit — the CSS
|
|
4
4
|
* (tokens-core.css + tokens-palette.css) is the source of truth;
|
|
5
5
|
* tokens.json is the intermediate machine-readable form this file is
|
|
6
6
|
* generated from. Regenerate with: node scripts/tokens-json.mjs
|
|
@@ -55,7 +55,14 @@ export type RemarqueCoreToken =
|
|
|
55
55
|
| 'border-style'
|
|
56
56
|
| 'motion-fast'
|
|
57
57
|
| 'motion-normal'
|
|
58
|
-
| 'motion-easing'
|
|
58
|
+
| 'motion-easing'
|
|
59
|
+
| 'z-base'
|
|
60
|
+
| 'z-sticky'
|
|
61
|
+
| 'z-dropdown'
|
|
62
|
+
| 'z-overlay'
|
|
63
|
+
| 'z-modal'
|
|
64
|
+
| 'z-toast'
|
|
65
|
+
| 'z-skip-link';
|
|
59
66
|
|
|
60
67
|
/** All palette-tier token names (tokens-palette.css). The sanctioned personalization surface. */
|
|
61
68
|
export type RemarquePaletteToken =
|
|
@@ -90,7 +97,14 @@ export type RemarquePaletteToken =
|
|
|
90
97
|
| 'color-syntax-type'
|
|
91
98
|
| 'color-syntax-punctuation'
|
|
92
99
|
| 'color-syntax-variable'
|
|
93
|
-
| 'color-syntax-link'
|
|
100
|
+
| 'color-syntax-link'
|
|
101
|
+
| 'color-error'
|
|
102
|
+
| 'color-error-subtle'
|
|
103
|
+
| 'color-success'
|
|
104
|
+
| 'color-success-subtle'
|
|
105
|
+
| 'color-warning'
|
|
106
|
+
| 'color-warning-subtle'
|
|
107
|
+
| 'color-disabled';
|
|
94
108
|
|
|
95
109
|
/** Every Remarque token name, core + palette. */
|
|
96
110
|
export type RemarqueToken = RemarqueCoreToken | RemarquePaletteToken;
|
|
@@ -202,6 +216,13 @@ export interface RemarqueTokenValues {
|
|
|
202
216
|
readonly 'motion-fast': "120ms";
|
|
203
217
|
readonly 'motion-normal': "180ms";
|
|
204
218
|
readonly 'motion-easing': "ease-out";
|
|
219
|
+
readonly 'z-base': 0;
|
|
220
|
+
readonly 'z-sticky': 10;
|
|
221
|
+
readonly 'z-dropdown': 20;
|
|
222
|
+
readonly 'z-overlay': 30;
|
|
223
|
+
readonly 'z-modal': 40;
|
|
224
|
+
readonly 'z-toast': 50;
|
|
225
|
+
readonly 'z-skip-link': 60;
|
|
205
226
|
};
|
|
206
227
|
readonly palette: {
|
|
207
228
|
readonly 'font-display': {
|
|
@@ -332,6 +353,34 @@ export interface RemarqueTokenValues {
|
|
|
332
353
|
readonly light: "var(--color-accent)";
|
|
333
354
|
readonly dark: "var(--color-accent)";
|
|
334
355
|
};
|
|
356
|
+
readonly 'color-error': {
|
|
357
|
+
readonly light: "oklch(0.52 0.12 25)";
|
|
358
|
+
readonly dark: "oklch(0.62 0.11 26)";
|
|
359
|
+
};
|
|
360
|
+
readonly 'color-error-subtle': {
|
|
361
|
+
readonly light: "oklch(0.95 0.02 25)";
|
|
362
|
+
readonly dark: "oklch(0.22 0.04 25)";
|
|
363
|
+
};
|
|
364
|
+
readonly 'color-success': {
|
|
365
|
+
readonly light: "oklch(0.51 0.12 145)";
|
|
366
|
+
readonly dark: "oklch(0.61 0.11 145)";
|
|
367
|
+
};
|
|
368
|
+
readonly 'color-success-subtle': {
|
|
369
|
+
readonly light: "oklch(0.95 0.02 145)";
|
|
370
|
+
readonly dark: "oklch(0.22 0.04 145)";
|
|
371
|
+
};
|
|
372
|
+
readonly 'color-warning': {
|
|
373
|
+
readonly light: "oklch(0.52 0.105 85)";
|
|
374
|
+
readonly dark: "oklch(0.62 0.11 85)";
|
|
375
|
+
};
|
|
376
|
+
readonly 'color-warning-subtle': {
|
|
377
|
+
readonly light: "oklch(0.95 0.02 85)";
|
|
378
|
+
readonly dark: "oklch(0.22 0.04 85)";
|
|
379
|
+
};
|
|
380
|
+
readonly 'color-disabled': {
|
|
381
|
+
readonly light: "var(--color-muted)";
|
|
382
|
+
readonly dark: "var(--color-muted)";
|
|
383
|
+
};
|
|
335
384
|
};
|
|
336
385
|
}
|
|
337
386
|
|
package/tokens.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$description": "Remarque design tokens — GENERATED from tokens-core.css + tokens-palette.css by scripts/tokens-json.mjs. Do not edit; the CSS is the source of truth.",
|
|
3
3
|
"$extensions": {
|
|
4
4
|
"remarque": {
|
|
5
|
-
"version": "0.
|
|
5
|
+
"version": "0.17.0",
|
|
6
6
|
"tiers": {
|
|
7
7
|
"core": "immutable identity — overriding forks the system",
|
|
8
8
|
"palette": "sanctioned personalization surface — override freely, then run remarque-audit"
|
|
@@ -177,6 +177,34 @@
|
|
|
177
177
|
"motion-easing": {
|
|
178
178
|
"$value": "ease-out",
|
|
179
179
|
"$type": "string"
|
|
180
|
+
},
|
|
181
|
+
"z-base": {
|
|
182
|
+
"$value": 0,
|
|
183
|
+
"$type": "number"
|
|
184
|
+
},
|
|
185
|
+
"z-sticky": {
|
|
186
|
+
"$value": 10,
|
|
187
|
+
"$type": "number"
|
|
188
|
+
},
|
|
189
|
+
"z-dropdown": {
|
|
190
|
+
"$value": 20,
|
|
191
|
+
"$type": "number"
|
|
192
|
+
},
|
|
193
|
+
"z-overlay": {
|
|
194
|
+
"$value": 30,
|
|
195
|
+
"$type": "number"
|
|
196
|
+
},
|
|
197
|
+
"z-modal": {
|
|
198
|
+
"$value": 40,
|
|
199
|
+
"$type": "number"
|
|
200
|
+
},
|
|
201
|
+
"z-toast": {
|
|
202
|
+
"$value": 50,
|
|
203
|
+
"$type": "number"
|
|
204
|
+
},
|
|
205
|
+
"z-skip-link": {
|
|
206
|
+
"$value": 60,
|
|
207
|
+
"$type": "number"
|
|
180
208
|
}
|
|
181
209
|
},
|
|
182
210
|
"palette": {
|
|
@@ -502,6 +530,69 @@
|
|
|
502
530
|
"dark": {
|
|
503
531
|
"$value": "var(--color-accent)"
|
|
504
532
|
}
|
|
533
|
+
},
|
|
534
|
+
"color-error": {
|
|
535
|
+
"$type": "color",
|
|
536
|
+
"light": {
|
|
537
|
+
"$value": "oklch(0.52 0.12 25)"
|
|
538
|
+
},
|
|
539
|
+
"dark": {
|
|
540
|
+
"$value": "oklch(0.62 0.11 26)"
|
|
541
|
+
}
|
|
542
|
+
},
|
|
543
|
+
"color-error-subtle": {
|
|
544
|
+
"$type": "color",
|
|
545
|
+
"light": {
|
|
546
|
+
"$value": "oklch(0.95 0.02 25)"
|
|
547
|
+
},
|
|
548
|
+
"dark": {
|
|
549
|
+
"$value": "oklch(0.22 0.04 25)"
|
|
550
|
+
}
|
|
551
|
+
},
|
|
552
|
+
"color-success": {
|
|
553
|
+
"$type": "color",
|
|
554
|
+
"light": {
|
|
555
|
+
"$value": "oklch(0.51 0.12 145)"
|
|
556
|
+
},
|
|
557
|
+
"dark": {
|
|
558
|
+
"$value": "oklch(0.61 0.11 145)"
|
|
559
|
+
}
|
|
560
|
+
},
|
|
561
|
+
"color-success-subtle": {
|
|
562
|
+
"$type": "color",
|
|
563
|
+
"light": {
|
|
564
|
+
"$value": "oklch(0.95 0.02 145)"
|
|
565
|
+
},
|
|
566
|
+
"dark": {
|
|
567
|
+
"$value": "oklch(0.22 0.04 145)"
|
|
568
|
+
}
|
|
569
|
+
},
|
|
570
|
+
"color-warning": {
|
|
571
|
+
"$type": "color",
|
|
572
|
+
"light": {
|
|
573
|
+
"$value": "oklch(0.52 0.105 85)"
|
|
574
|
+
},
|
|
575
|
+
"dark": {
|
|
576
|
+
"$value": "oklch(0.62 0.11 85)"
|
|
577
|
+
}
|
|
578
|
+
},
|
|
579
|
+
"color-warning-subtle": {
|
|
580
|
+
"$type": "color",
|
|
581
|
+
"light": {
|
|
582
|
+
"$value": "oklch(0.95 0.02 85)"
|
|
583
|
+
},
|
|
584
|
+
"dark": {
|
|
585
|
+
"$value": "oklch(0.22 0.04 85)"
|
|
586
|
+
}
|
|
587
|
+
},
|
|
588
|
+
"color-disabled": {
|
|
589
|
+
"$type": "color",
|
|
590
|
+
"light": {
|
|
591
|
+
"$value": "var(--color-muted)"
|
|
592
|
+
},
|
|
593
|
+
"dark": {
|
|
594
|
+
"$value": "var(--color-muted)"
|
|
595
|
+
}
|
|
505
596
|
}
|
|
506
597
|
}
|
|
507
598
|
}
|