fractalstyler2 0.4.0 → 0.7.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/README.md +114 -95
- package/dist/cli.js +105 -25
- package/dist/components/Accordion.svelte +44 -0
- package/dist/components/Accordion.svelte.d.ts +23 -0
- package/dist/components/AccordionItem.svelte +44 -0
- package/dist/components/AccordionItem.svelte.d.ts +21 -0
- package/dist/components/AppShell.svelte +86 -0
- package/dist/components/AppShell.svelte.d.ts +39 -0
- package/dist/components/ColorPicker.svelte +38 -0
- package/dist/components/ColorPicker.svelte.d.ts +6 -0
- package/dist/components/Hero.svelte +14 -0
- package/dist/components/Hero.svelte.d.ts +9 -0
- package/dist/components/LayoutPicker.svelte +34 -0
- package/dist/components/LayoutPicker.svelte.d.ts +6 -0
- package/dist/components/MotionPicker.svelte +34 -0
- package/dist/components/MotionPicker.svelte.d.ts +6 -0
- package/dist/components/PageShell.svelte +14 -0
- package/dist/components/PageShell.svelte.d.ts +9 -0
- package/dist/components/PageSplit.svelte +26 -0
- package/dist/components/PageSplit.svelte.d.ts +18 -0
- package/dist/components/ShapePicker.svelte +37 -0
- package/dist/components/ShapePicker.svelte.d.ts +6 -0
- package/dist/css/fractalstyler.css +10643 -0
- package/dist/css/fractalstyler.min.css +2 -0
- package/dist/index.d.ts +18 -6
- package/dist/index.js +30 -12
- package/dist/mcp/schemas/compile_fractals.json +3 -3
- package/dist/mcp/schemas/css_to_fractals.json +1 -1
- package/dist/mcp/schemas/generate_component.json +2 -2
- package/dist/mcp/schemas/instructions.md +41 -14
- package/dist/mcp/schemas/list_fractals.json +9 -7
- package/dist/mcp/schemas/validate_recipe.json +2 -2
- package/dist/mcp/server.d.ts +1 -1
- package/dist/mcp/server.js +334 -237
- package/dist/presets.core.d.ts +42 -0
- package/dist/presets.core.js +190 -0
- package/dist/presets.svelte.d.ts +6 -0
- package/dist/presets.svelte.js +21 -0
- package/dist/styles/_00_presets.sass +111 -0
- package/dist/styles/_00_themes.sass +1061 -0
- package/dist/styles/_00_tokens.sass +57 -17
- package/dist/styles/_01_config.sass +77 -70
- package/dist/styles/_02_dimensions.sass +174 -0
- package/dist/styles/_03_containers.sass +105 -0
- package/dist/styles/_04_layouts.sass +100 -0
- package/dist/styles/_05_shells.sass +374 -0
- package/dist/styles/_06_visuals.sass +236 -0
- package/dist/styles/_07_interactions.sass +112 -0
- package/dist/styles/_08_own.sass +4 -0
- package/dist/styles/canonical-markups.md +160 -0
- package/dist/styles/index.sass +11 -18
- package/dist/themes.d.ts +7 -0
- package/dist/themes.js +45 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +2 -0
- package/package.json +26 -15
- package/plugin.json +11 -10
- package/registry.json +2002 -0
- package/skills/fractal-styler/SKILL.md +137 -50
- package/skills/fractal-styler/references/fractals.md +416 -28
- package/skills/fractal-styler/references/tokens.md +110 -36
- package/dist/styles/_02_fonts.sass +0 -13
- package/dist/styles/_03_responsive.sass +0 -31
- package/dist/styles/_04_atoms.sass +0 -155
- package/dist/styles/_05_molecules.sass +0 -97
- package/dist/styles/_06_recipes.sass +0 -189
- package/dist/styles/_07_base.sass +0 -44
- package/dist/styles/_08_blocks.sass +0 -433
- package/dist/styles/_09_utilities.sass +0 -208
- package/dist/styles/_10_layouts.sass +0 -373
- package/dist/styles/_11_own.sass +0 -21
- package/dist/styles/_fractals.sass +0 -14
- package/skills/style-migration/SKILL.md +0 -45
- package/templates/_00_tokens.sass +0 -136
- package/templates/_01_config.sass +0 -66
- package/templates/_02_fonts.sass +0 -13
- package/templates/_03_responsive.sass +0 -31
- package/templates/_04_atoms.sass +0 -155
- package/templates/_05_molecules.sass +0 -97
- package/templates/_06_recipes.sass +0 -189
- package/templates/_07_base.sass +0 -44
- package/templates/_08_blocks.sass +0 -433
- package/templates/_09_utilities.sass +0 -207
- package/templates/_10_layouts.sass +0 -373
- package/templates/_11_own.sass +0 -21
- package/templates/_fractals.sass +0 -14
- package/templates/index.sass +0 -18
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export { themes, themeIds, type ThemeMeta } from './themes.js';
|
|
2
|
+
export declare const presetAxes: {
|
|
3
|
+
readonly layout: readonly ["tight", "comfortable", "sprawling"];
|
|
4
|
+
readonly shape: readonly ["round", "curved", "pro", "sharp"];
|
|
5
|
+
readonly color: readonly ["clean", "general", "vibrant"];
|
|
6
|
+
readonly motion: readonly ["reduced", "heavy", "active", "springy"];
|
|
7
|
+
};
|
|
8
|
+
export declare const presetDefaults: {
|
|
9
|
+
readonly layout: "comfortable";
|
|
10
|
+
readonly shape: "curved";
|
|
11
|
+
readonly color: "general";
|
|
12
|
+
readonly motion: "active";
|
|
13
|
+
};
|
|
14
|
+
export type PresetAxis = keyof typeof presetAxes;
|
|
15
|
+
export declare const STORAGE_KEY = "fs2.presets";
|
|
16
|
+
export declare const THEME_KEY = "fs2.theme";
|
|
17
|
+
/** Current value of every axis. Read it; mutate through setPreset. */
|
|
18
|
+
export declare const presetState: Record<PresetAxis, string>;
|
|
19
|
+
type Listener = (axis: PresetAxis, value: string) => void;
|
|
20
|
+
/** Subscribe to preset changes — for hand-rolled pickers. Returns an unsubscribe. */
|
|
21
|
+
export declare function onPresetChange(fn: Listener): () => void;
|
|
22
|
+
export declare function isDefault(axis: PresetAxis, value: string): boolean;
|
|
23
|
+
/** Read the saved blob and apply it. Call once, on load. */
|
|
24
|
+
export declare function initPresets(): void;
|
|
25
|
+
/** Set one axis. Ignores values outside the axis. */
|
|
26
|
+
export declare function setPreset(axis: PresetAxis, value: string): void;
|
|
27
|
+
export declare function getPreset(axis: PresetAxis): string;
|
|
28
|
+
/** Cycle an axis to its next value — what a single toggle button wants. */
|
|
29
|
+
export declare function cyclePreset(axis: PresetAxis): string;
|
|
30
|
+
/** Inline head script — stamps saved presets before first paint (no flicker).
|
|
31
|
+
* Axes and defaults are derived from the constants above — one source, no
|
|
32
|
+
* second hardcoded copy to drift. */
|
|
33
|
+
export declare function getPresetScript(): string;
|
|
34
|
+
/** Apply a built-in palette. Pass null to fall back to the mode defaults. */
|
|
35
|
+
export declare function setTheme(id: string | null): void;
|
|
36
|
+
/** The active palette, or null when none is applied. */
|
|
37
|
+
export declare function getTheme(): string | null;
|
|
38
|
+
/** Swap to the light/dark counterpart of the active theme, if it has one. */
|
|
39
|
+
export declare function toggleThemeMode(): string | null;
|
|
40
|
+
/** Set the colour mode marker. Light/dark is a mode, not a preset axis. */
|
|
41
|
+
export declare function setMode(mode: 'light' | 'dark'): void;
|
|
42
|
+
export declare function toggleMode(): 'light' | 'dark';
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
// fs2 preset runtime — framework-free.
|
|
2
|
+
//
|
|
3
|
+
// The four preset languages are the styling system's own physics, so fs2 owns
|
|
4
|
+
// their application, persistence and anti-flicker. Nothing here imports Svelte:
|
|
5
|
+
// this is the module a vanilla CSS consumer gets, and it is also the single
|
|
6
|
+
// implementation the Svelte wrapper (presets.svelte.ts) delegates to.
|
|
7
|
+
//
|
|
8
|
+
// Attribute contract: data-layout / data-shape / data-color / data-motion on
|
|
9
|
+
// <html>. An absent attribute means that axis's default. A palette is a class
|
|
10
|
+
// on the same element, paired with data-mode.
|
|
11
|
+
import { themes } from './themes.js';
|
|
12
|
+
export { themes, themeIds } from './themes.js';
|
|
13
|
+
// Axis arrays are the canonical value order — monotonic (shape: roundest →
|
|
14
|
+
// sharpest) — and are what pickers render. Default-ness is declared separately
|
|
15
|
+
// in presetDefaults; it does not dictate array position.
|
|
16
|
+
export const presetAxes = {
|
|
17
|
+
layout: ['tight', 'comfortable', 'sprawling'],
|
|
18
|
+
shape: ['round', 'curved', 'pro', 'sharp'],
|
|
19
|
+
color: ['clean', 'general', 'vibrant'],
|
|
20
|
+
motion: ['reduced', 'heavy', 'active', 'springy']
|
|
21
|
+
};
|
|
22
|
+
export const presetDefaults = {
|
|
23
|
+
layout: 'comfortable',
|
|
24
|
+
shape: 'curved',
|
|
25
|
+
color: 'general',
|
|
26
|
+
motion: 'active'
|
|
27
|
+
};
|
|
28
|
+
export const STORAGE_KEY = 'fs2.presets';
|
|
29
|
+
export const THEME_KEY = 'fs2.theme';
|
|
30
|
+
/** Current value of every axis. Read it; mutate through setPreset. */
|
|
31
|
+
export const presetState = { ...presetDefaults };
|
|
32
|
+
const listeners = new Set();
|
|
33
|
+
/** Subscribe to preset changes — for hand-rolled pickers. Returns an unsubscribe. */
|
|
34
|
+
export function onPresetChange(fn) {
|
|
35
|
+
listeners.add(fn);
|
|
36
|
+
return () => listeners.delete(fn);
|
|
37
|
+
}
|
|
38
|
+
export function isDefault(axis, value) {
|
|
39
|
+
return value === presetDefaults[axis];
|
|
40
|
+
}
|
|
41
|
+
function isValid(axis, value) {
|
|
42
|
+
return presetAxes[axis].includes(value);
|
|
43
|
+
}
|
|
44
|
+
/** Default values remove the attribute — absent IS the default. */
|
|
45
|
+
function applyAttr(axis, value) {
|
|
46
|
+
const root = document.documentElement;
|
|
47
|
+
if (isDefault(axis, value))
|
|
48
|
+
root.removeAttribute(`data-${axis}`);
|
|
49
|
+
else
|
|
50
|
+
root.setAttribute(`data-${axis}`, value);
|
|
51
|
+
}
|
|
52
|
+
function persist() {
|
|
53
|
+
const nonDefaults = {};
|
|
54
|
+
for (const axis of Object.keys(presetAxes)) {
|
|
55
|
+
if (!isDefault(axis, presetState[axis]))
|
|
56
|
+
nonDefaults[axis] = presetState[axis];
|
|
57
|
+
}
|
|
58
|
+
try {
|
|
59
|
+
if (Object.keys(nonDefaults).length)
|
|
60
|
+
localStorage.setItem(STORAGE_KEY, JSON.stringify(nonDefaults));
|
|
61
|
+
else
|
|
62
|
+
localStorage.removeItem(STORAGE_KEY);
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
/* storage unavailable — presets stay session-local */
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/** Read the saved blob and apply it. Call once, on load. */
|
|
69
|
+
export function initPresets() {
|
|
70
|
+
if (typeof document === 'undefined')
|
|
71
|
+
return;
|
|
72
|
+
try {
|
|
73
|
+
const savedTheme = localStorage.getItem(THEME_KEY);
|
|
74
|
+
if (savedTheme)
|
|
75
|
+
setTheme(savedTheme);
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
/* storage unavailable — defaults stand */
|
|
79
|
+
}
|
|
80
|
+
try {
|
|
81
|
+
const saved = JSON.parse(localStorage.getItem(STORAGE_KEY) || '{}');
|
|
82
|
+
for (const axis of Object.keys(presetAxes)) {
|
|
83
|
+
const v = saved[axis];
|
|
84
|
+
if (v && isValid(axis, v)) {
|
|
85
|
+
presetState[axis] = v;
|
|
86
|
+
applyAttr(axis, v);
|
|
87
|
+
for (const fn of listeners)
|
|
88
|
+
fn(axis, v);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
/* corrupt blob — defaults stand */
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/** Set one axis. Ignores values outside the axis. */
|
|
97
|
+
export function setPreset(axis, value) {
|
|
98
|
+
if (typeof document === 'undefined')
|
|
99
|
+
return;
|
|
100
|
+
if (!isValid(axis, value))
|
|
101
|
+
return;
|
|
102
|
+
presetState[axis] = value;
|
|
103
|
+
applyAttr(axis, value);
|
|
104
|
+
persist();
|
|
105
|
+
for (const fn of listeners)
|
|
106
|
+
fn(axis, value);
|
|
107
|
+
}
|
|
108
|
+
export function getPreset(axis) {
|
|
109
|
+
return presetState[axis];
|
|
110
|
+
}
|
|
111
|
+
/** Cycle an axis to its next value — what a single toggle button wants. */
|
|
112
|
+
export function cyclePreset(axis) {
|
|
113
|
+
const values = presetAxes[axis];
|
|
114
|
+
const next = values[(values.indexOf(presetState[axis]) + 1) % values.length];
|
|
115
|
+
setPreset(axis, next);
|
|
116
|
+
return next;
|
|
117
|
+
}
|
|
118
|
+
/** Inline head script — stamps saved presets before first paint (no flicker).
|
|
119
|
+
* Axes and defaults are derived from the constants above — one source, no
|
|
120
|
+
* second hardcoded copy to drift. */
|
|
121
|
+
export function getPresetScript() {
|
|
122
|
+
const axes = JSON.stringify(presetAxes).replaceAll('"', "'");
|
|
123
|
+
const defs = JSON.stringify(presetDefaults).replaceAll('"', "'");
|
|
124
|
+
return `(function(){try{var v=${axes};var d=${defs};var r=document.documentElement;var s=JSON.parse(localStorage.getItem('${STORAGE_KEY}')||'{}');for(var k in v){var val=s[k];if(val&&val!==d[k])r.setAttribute('data-'+k,val);}var t=localStorage.getItem('${THEME_KEY}');if(t){r.classList.add(t);r.setAttribute('data-mode',t.indexOf('-dark')>-1?'dark':'light');}}catch(e){}})();`;
|
|
125
|
+
}
|
|
126
|
+
// ─── themes ────────────────────────────────────────────────────────────────
|
|
127
|
+
// A theme is one class on <html>, always paired with its data-mode: the colour
|
|
128
|
+
// preset's dark variants key off prefers-color-scheme, so an unpaired theme can
|
|
129
|
+
// end up tuned against the OS preference rather than against itself.
|
|
130
|
+
/** Apply a built-in palette. Pass null to fall back to the mode defaults. */
|
|
131
|
+
export function setTheme(id) {
|
|
132
|
+
if (typeof document === 'undefined')
|
|
133
|
+
return;
|
|
134
|
+
const root = document.documentElement;
|
|
135
|
+
for (const t of themes)
|
|
136
|
+
root.classList.remove(t.id);
|
|
137
|
+
if (!id) {
|
|
138
|
+
root.removeAttribute('data-mode');
|
|
139
|
+
try {
|
|
140
|
+
localStorage.removeItem(THEME_KEY);
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
/* storage unavailable */
|
|
144
|
+
}
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
const theme = themes.find((t) => t.id === id);
|
|
148
|
+
if (!theme)
|
|
149
|
+
return;
|
|
150
|
+
root.classList.add(theme.id);
|
|
151
|
+
root.setAttribute('data-mode', theme.mode);
|
|
152
|
+
try {
|
|
153
|
+
localStorage.setItem(THEME_KEY, theme.id);
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
156
|
+
/* storage unavailable — the theme stays session-local */
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
/** The active palette, or null when none is applied. */
|
|
160
|
+
export function getTheme() {
|
|
161
|
+
if (typeof document === 'undefined')
|
|
162
|
+
return null;
|
|
163
|
+
const root = document.documentElement;
|
|
164
|
+
return themes.find((t) => root.classList.contains(t.id))?.id ?? null;
|
|
165
|
+
}
|
|
166
|
+
/** Swap to the light/dark counterpart of the active theme, if it has one. */
|
|
167
|
+
export function toggleThemeMode() {
|
|
168
|
+
const active = getTheme();
|
|
169
|
+
if (!active) {
|
|
170
|
+
toggleMode();
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
const want = themes.find((t) => t.id === active).mode === 'dark' ? 'light' : 'dark';
|
|
174
|
+
const twin = themes.find((t) => t.mode === want);
|
|
175
|
+
if (twin)
|
|
176
|
+
setTheme(twin.id);
|
|
177
|
+
return twin?.id ?? null;
|
|
178
|
+
}
|
|
179
|
+
/** Set the colour mode marker. Light/dark is a mode, not a preset axis. */
|
|
180
|
+
export function setMode(mode) {
|
|
181
|
+
if (typeof document === 'undefined')
|
|
182
|
+
return;
|
|
183
|
+
document.documentElement.setAttribute('data-mode', mode);
|
|
184
|
+
}
|
|
185
|
+
export function toggleMode() {
|
|
186
|
+
const current = typeof document !== 'undefined' ? document.documentElement.getAttribute('data-mode') : null;
|
|
187
|
+
const next = current === 'dark' ? 'light' : 'dark';
|
|
188
|
+
setMode(next);
|
|
189
|
+
return next;
|
|
190
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type PresetAxis } from './presets.core.js';
|
|
2
|
+
export { presetAxes, presetDefaults, getPreset, cyclePreset, getPresetScript, setMode, toggleMode, setTheme, getTheme, toggleThemeMode, themes, themeIds, type ThemeMeta, onPresetChange, type PresetAxis } from './presets.core.js';
|
|
3
|
+
/** Reactive mirror of presetState, for pickers and any $derived reading it. */
|
|
4
|
+
export declare const presets: Record<"color" | "layout" | "shape" | "motion", string>;
|
|
5
|
+
export declare function initPresets(): void;
|
|
6
|
+
export declare function setPreset(axis: PresetAxis, value: string): void;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// Svelte wrapper over the framework-free runtime in presets.core.ts.
|
|
2
|
+
//
|
|
3
|
+
// The logic lives there so the vanilla CSS distribution and the Svelte package
|
|
4
|
+
// share one implementation. All this adds is a reactive mirror of the state so
|
|
5
|
+
// the bundled pickers re-render.
|
|
6
|
+
import { presetAxes, presetDefaults, initPresets as coreInit, setPreset as coreSet, onPresetChange, presetState } from './presets.core.js';
|
|
7
|
+
export { presetAxes, presetDefaults, getPreset, cyclePreset, getPresetScript, setMode, toggleMode, setTheme, getTheme, toggleThemeMode, themes, themeIds, onPresetChange } from './presets.core.js';
|
|
8
|
+
/** Reactive mirror of presetState, for pickers and any $derived reading it. */
|
|
9
|
+
export const presets = $state({ ...presetDefaults });
|
|
10
|
+
// Keep the mirror in step with the core, however the core was driven.
|
|
11
|
+
onPresetChange((axis, value) => {
|
|
12
|
+
presets[axis] = value;
|
|
13
|
+
});
|
|
14
|
+
export function initPresets() {
|
|
15
|
+
coreInit();
|
|
16
|
+
for (const axis of Object.keys(presetAxes))
|
|
17
|
+
presets[axis] = presetState[axis];
|
|
18
|
+
}
|
|
19
|
+
export function setPreset(axis, value) {
|
|
20
|
+
coreSet(axis, value);
|
|
21
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// presets — the four preset languages, as pure token remaps.
|
|
3
|
+
//
|
|
4
|
+
// Emitted AFTER _00_themes.sass on purpose. data-color remaps the same three
|
|
5
|
+
// surface tokens every theme sets, so if themes came last a chosen theme would
|
|
6
|
+
// silently cancel the colour axis. The intended layering is:
|
|
7
|
+
//
|
|
8
|
+
// :root defaults -> [data-mode] -> theme class -> preset attributes
|
|
9
|
+
//
|
|
10
|
+
// i.e. a theme beats the mode default, and a preset tunes whatever theme is
|
|
11
|
+
// active. Do not reorder these three in index.sass.
|
|
12
|
+
// ============================================================================
|
|
13
|
+
|
|
14
|
+
// Applied by setting one attribute per language on <html>; fs2 owns
|
|
15
|
+
// application, persistence, and anti-flicker (Amendment A2). Absent attributes
|
|
16
|
+
// = the defaults above (comfortable layout, curved radius channels, general
|
|
17
|
+
// color, active motion).
|
|
18
|
+
// =============================================================================
|
|
19
|
+
|
|
20
|
+
// --- Layout — data-layout: tight / sprawling (comfortable is the default) ---
|
|
21
|
+
// Density = two factors: gaps/margins × --gap-scale, paddings × --pad-scale.
|
|
22
|
+
// Pads and gaps scale at DIFFERENT rates — uniform scaling is a perceptual
|
|
23
|
+
// no-op; breathing opens when padding outgrows gap (sprawling) and closes
|
|
24
|
+
// when it shrinks faster (tight). Element sizes, heights, and widths never
|
|
25
|
+
// move: control heights stay authored at their comfortable values.
|
|
26
|
+
[data-layout='tight']
|
|
27
|
+
--gap-scale: 0.85
|
|
28
|
+
--pad-scale: 0.7
|
|
29
|
+
|
|
30
|
+
[data-layout='sprawling']
|
|
31
|
+
--gap-scale: 1.2
|
|
32
|
+
--pad-scale: 1.5
|
|
33
|
+
|
|
34
|
+
// --- Shape — data-shape: round / curved / pro / sharp ------------------------
|
|
35
|
+
[data-shape='round']
|
|
36
|
+
--radius-sm: 16px
|
|
37
|
+
--radius-md: 24px
|
|
38
|
+
--radius-lg: 32px
|
|
39
|
+
|
|
40
|
+
[data-shape='curved']
|
|
41
|
+
--radius-sm: 8px
|
|
42
|
+
--radius-md: 16px
|
|
43
|
+
--radius-lg: 24px
|
|
44
|
+
|
|
45
|
+
[data-shape='pro']
|
|
46
|
+
--radius-sm: 4px
|
|
47
|
+
--radius-md: 8px
|
|
48
|
+
--radius-lg: 16px
|
|
49
|
+
|
|
50
|
+
[data-shape='sharp']
|
|
51
|
+
--radius-sm: 0
|
|
52
|
+
--radius-md: 0
|
|
53
|
+
--radius-lg: 0
|
|
54
|
+
|
|
55
|
+
// --- Color — data-color: clean / vibrant (general is the default) ------------
|
|
56
|
+
// Layer tint on the surface ladder only: clean flattens separation toward the
|
|
57
|
+
// page bg, vibrant deepens it. Light values are the mode default; dark values
|
|
58
|
+
// override under both dark paths. General ships in the theme mixins.
|
|
59
|
+
[data-color='clean']
|
|
60
|
+
--bg-surface: #fbfbfb
|
|
61
|
+
--bg-raised: #f5f7f9
|
|
62
|
+
--bg-panel: #F7F8F9
|
|
63
|
+
|
|
64
|
+
[data-color='vibrant']
|
|
65
|
+
--bg-surface: #f2f5f7
|
|
66
|
+
--bg-raised: #e8eef3
|
|
67
|
+
--bg-panel: #E9EEF3
|
|
68
|
+
|
|
69
|
+
@media (prefers-color-scheme: dark)
|
|
70
|
+
:root:not([data-mode='light'])[data-color='clean']
|
|
71
|
+
--bg-surface: #121626
|
|
72
|
+
--bg-raised: #171C2C
|
|
73
|
+
--bg-panel: #10131D
|
|
74
|
+
:root:not([data-mode='light'])[data-color='vibrant']
|
|
75
|
+
--bg-surface: #171E33
|
|
76
|
+
--bg-raised: #26314E
|
|
77
|
+
--bg-panel: #141B2E
|
|
78
|
+
|
|
79
|
+
[data-mode='dark'][data-color='clean']
|
|
80
|
+
--bg-surface: #121626
|
|
81
|
+
--bg-raised: #171C2C
|
|
82
|
+
--bg-panel: #10131D
|
|
83
|
+
|
|
84
|
+
[data-mode='dark'][data-color='vibrant']
|
|
85
|
+
--bg-surface: #171E33
|
|
86
|
+
--bg-raised: #26314E
|
|
87
|
+
--bg-panel: #141B2E
|
|
88
|
+
|
|
89
|
+
// --- Motion — data-motion: springy / heavy / reduced (active is the default) -
|
|
90
|
+
[data-motion='springy']
|
|
91
|
+
--motion-fast: 140ms
|
|
92
|
+
--motion-base: 200ms
|
|
93
|
+
--motion-slow: 300ms
|
|
94
|
+
--ease-out: cubic-bezier(0.34, 1.56, 0.64, 1)
|
|
95
|
+
|
|
96
|
+
[data-motion='heavy']
|
|
97
|
+
--motion-fast: 200ms
|
|
98
|
+
--motion-base: 300ms
|
|
99
|
+
--motion-slow: 450ms
|
|
100
|
+
|
|
101
|
+
[data-motion='reduced']
|
|
102
|
+
--motion-fast: 0ms
|
|
103
|
+
--motion-base: 0ms
|
|
104
|
+
--motion-slow: 0ms
|
|
105
|
+
|
|
106
|
+
// prefers-reduced-motion is honored globally regardless of preset (registry v1).
|
|
107
|
+
@media (prefers-reduced-motion: reduce)
|
|
108
|
+
:root
|
|
109
|
+
--motion-fast: 0ms
|
|
110
|
+
--motion-base: 0ms
|
|
111
|
+
--motion-slow: 0ms
|