@fudge-me/design-system 0.1.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 +140 -0
- package/dist/components/.gitkeep +0 -0
- package/dist/components/Button.svelte +118 -0
- package/dist/components/Button.svelte.d.ts +12 -0
- package/dist/components/CommandPalette.svelte +167 -0
- package/dist/components/CommandPalette.svelte.d.ts +16 -0
- package/dist/components/Input.svelte +70 -0
- package/dist/components/Input.svelte.d.ts +9 -0
- package/dist/components/Modal.svelte +83 -0
- package/dist/components/Modal.svelte.d.ts +12 -0
- package/dist/components/Tooltip.svelte +92 -0
- package/dist/components/Tooltip.svelte.d.ts +12 -0
- package/dist/components/index.d.ts +8 -0
- package/dist/components/index.js +5 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/layout/.gitkeep +0 -0
- package/dist/layout/AIPanel.svelte +34 -0
- package/dist/layout/AIPanel.svelte.d.ts +11 -0
- package/dist/layout/AppShell.svelte +78 -0
- package/dist/layout/AppShell.svelte.d.ts +11 -0
- package/dist/layout/Canvas.svelte +22 -0
- package/dist/layout/Canvas.svelte.d.ts +7 -0
- package/dist/layout/CommandBar.svelte +25 -0
- package/dist/layout/CommandBar.svelte.d.ts +7 -0
- package/dist/layout/Panel.svelte +157 -0
- package/dist/layout/Panel.svelte.d.ts +13 -0
- package/dist/layout/Sidebar.svelte +34 -0
- package/dist/layout/Sidebar.svelte.d.ts +11 -0
- package/dist/layout/StatusBar.svelte +26 -0
- package/dist/layout/StatusBar.svelte.d.ts +7 -0
- package/dist/layout/__tests__/helpers.js +53 -0
- package/dist/layout/index.d.ts +8 -0
- package/dist/layout/index.js +7 -0
- package/dist/themes/ThemeProvider.svelte +44 -0
- package/dist/themes/ThemeProvider.svelte.d.ts +10 -0
- package/dist/themes/dark.css +49 -0
- package/dist/themes/index.d.ts +2 -0
- package/dist/themes/index.js +1 -0
- package/dist/themes/light.css +79 -0
- package/dist/tokens/.gitkeep +0 -0
- package/dist/tokens/__tests__/helpers.js +117 -0
- package/dist/tokens/color.css +112 -0
- package/dist/tokens/components/appshell.css +22 -0
- package/dist/tokens/components/button.css +16 -0
- package/dist/tokens/components/command-palette.css +15 -0
- package/dist/tokens/components/input.css +16 -0
- package/dist/tokens/components/modal.css +9 -0
- package/dist/tokens/components/panel.css +16 -0
- package/dist/tokens/components/tooltip.css +10 -0
- package/dist/tokens/index.css +13 -0
- package/dist/tokens/radii.css +10 -0
- package/dist/tokens/semantic.css +79 -0
- package/dist/tokens/shadows.css +11 -0
- package/dist/tokens/spacing.css +32 -0
- package/dist/tokens/typography.css +39 -0
- package/package.json +70 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
export type Theme = 'light' | 'dark' | 'system';
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<script lang="ts">
|
|
6
|
+
import type { Snippet } from 'svelte';
|
|
7
|
+
|
|
8
|
+
interface Props {
|
|
9
|
+
theme?: Theme;
|
|
10
|
+
target?: HTMLElement;
|
|
11
|
+
children?: Snippet;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
let { theme = 'system', target, children }: Props = $props();
|
|
15
|
+
|
|
16
|
+
let resolved = $state<'light' | 'dark'>('light');
|
|
17
|
+
|
|
18
|
+
$effect(() => {
|
|
19
|
+
if (theme !== 'system') {
|
|
20
|
+
resolved = theme;
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const mql = window.matchMedia('(prefers-color-scheme: dark)');
|
|
25
|
+
resolved = mql.matches ? 'dark' : 'light';
|
|
26
|
+
|
|
27
|
+
const onChange = (e: MediaQueryListEvent) => {
|
|
28
|
+
resolved = e.matches ? 'dark' : 'light';
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
mql.addEventListener('change', onChange);
|
|
32
|
+
return () => mql.removeEventListener('change', onChange);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
$effect(() => {
|
|
36
|
+
const el = target ?? document.documentElement;
|
|
37
|
+
el.setAttribute('data-theme', resolved);
|
|
38
|
+
return () => el.removeAttribute('data-theme');
|
|
39
|
+
});
|
|
40
|
+
</script>
|
|
41
|
+
|
|
42
|
+
{#if children}
|
|
43
|
+
{@render children()}
|
|
44
|
+
{/if}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type Theme = 'light' | 'dark' | 'system';
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
interface Props {
|
|
4
|
+
theme?: Theme;
|
|
5
|
+
target?: HTMLElement;
|
|
6
|
+
children?: Snippet;
|
|
7
|
+
}
|
|
8
|
+
declare const ThemeProvider: import("svelte").Component<Props, {}, "">;
|
|
9
|
+
type ThemeProvider = ReturnType<typeof ThemeProvider>;
|
|
10
|
+
export default ThemeProvider;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/* Dark theme — fudge-design-system
|
|
2
|
+
* Rebinds color semantic tokens only.
|
|
3
|
+
* Non-color tokens (spacing, typography, radii, shadow) inherit from :root.
|
|
4
|
+
*/
|
|
5
|
+
[data-theme="dark"] {
|
|
6
|
+
/* Color — Backgrounds / Surfaces */
|
|
7
|
+
--fds-color-bg: var(--fds-color-gray-950);
|
|
8
|
+
--fds-color-surface: var(--fds-color-gray-900);
|
|
9
|
+
--fds-color-surface-raised: var(--fds-color-gray-800);
|
|
10
|
+
--fds-color-surface-sunken: var(--fds-color-gray-950);
|
|
11
|
+
--fds-color-surface-overlay: var(--fds-color-gray-800);
|
|
12
|
+
--fds-color-primary: var(--fds-color-primary-500);
|
|
13
|
+
--fds-color-primary-hover: var(--fds-color-primary-400);
|
|
14
|
+
--fds-color-primary-active: var(--fds-color-primary-300);
|
|
15
|
+
--fds-color-secondary: var(--fds-color-secondary-400);
|
|
16
|
+
--fds-color-accent: var(--fds-color-accent-400);
|
|
17
|
+
|
|
18
|
+
/* Color — Text */
|
|
19
|
+
--fds-color-text: var(--fds-color-gray-50);
|
|
20
|
+
--fds-color-text-secondary: var(--fds-color-gray-400);
|
|
21
|
+
--fds-color-text-tertiary: var(--fds-color-gray-500);
|
|
22
|
+
--fds-color-text-inverse: var(--fds-color-gray-900);
|
|
23
|
+
--fds-color-text-link: var(--fds-color-primary-400);
|
|
24
|
+
--fds-color-text-on-primary: var(--fds-color-white);
|
|
25
|
+
|
|
26
|
+
/* Color — Borders */
|
|
27
|
+
--fds-color-border: var(--fds-color-gray-700);
|
|
28
|
+
--fds-color-border-strong: var(--fds-color-gray-600);
|
|
29
|
+
--fds-color-border-focus: var(--fds-color-primary-500);
|
|
30
|
+
--fds-color-border-error: var(--fds-color-error-400);
|
|
31
|
+
|
|
32
|
+
/* Color — State / Feedback */
|
|
33
|
+
--fds-color-success: var(--fds-color-success-400);
|
|
34
|
+
--fds-color-success-subtle: var(--fds-color-success-950);
|
|
35
|
+
--fds-color-warning: var(--fds-color-warning-400);
|
|
36
|
+
--fds-color-warning-subtle: var(--fds-color-warning-950);
|
|
37
|
+
--fds-color-error: var(--fds-color-error-400);
|
|
38
|
+
--fds-color-error-subtle: var(--fds-color-error-950);
|
|
39
|
+
--fds-color-info: var(--fds-color-info-400);
|
|
40
|
+
--fds-color-info-subtle: var(--fds-color-info-950);
|
|
41
|
+
|
|
42
|
+
/* Color — Interactive */
|
|
43
|
+
--fds-color-interactive-hover: var(--fds-color-gray-800);
|
|
44
|
+
--fds-color-interactive-active: var(--fds-color-gray-700);
|
|
45
|
+
--fds-color-disabled: var(--fds-color-gray-600);
|
|
46
|
+
|
|
47
|
+
/* Color — Overlay */
|
|
48
|
+
--fds-color-backdrop: var(--fds-color-black);
|
|
49
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as ThemeProvider } from "./ThemeProvider.svelte";
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/* Light theme — fudge-design-system
|
|
2
|
+
* Explicit light theme. Identical mappings to :root semantic defaults.
|
|
3
|
+
* Self-documenting: works even if semantic.css isn't loaded.
|
|
4
|
+
*/
|
|
5
|
+
[data-theme="light"] {
|
|
6
|
+
/* Color — Backgrounds / Surfaces */
|
|
7
|
+
--fds-color-bg: var(--fds-color-white);
|
|
8
|
+
--fds-color-surface: var(--fds-color-white);
|
|
9
|
+
--fds-color-surface-raised: var(--fds-color-gray-50);
|
|
10
|
+
--fds-color-surface-sunken: var(--fds-color-gray-100);
|
|
11
|
+
--fds-color-surface-overlay: var(--fds-color-white);
|
|
12
|
+
--fds-color-primary: var(--fds-color-primary-600);
|
|
13
|
+
--fds-color-primary-hover: var(--fds-color-primary-700);
|
|
14
|
+
--fds-color-primary-active: var(--fds-color-primary-800);
|
|
15
|
+
--fds-color-secondary: var(--fds-color-secondary-600);
|
|
16
|
+
--fds-color-accent: var(--fds-color-accent-500);
|
|
17
|
+
|
|
18
|
+
/* Color — Text */
|
|
19
|
+
--fds-color-text: var(--fds-color-gray-900);
|
|
20
|
+
--fds-color-text-secondary: var(--fds-color-gray-600);
|
|
21
|
+
--fds-color-text-tertiary: var(--fds-color-gray-400);
|
|
22
|
+
--fds-color-text-inverse: var(--fds-color-white);
|
|
23
|
+
--fds-color-text-link: var(--fds-color-primary-600);
|
|
24
|
+
--fds-color-text-on-primary: var(--fds-color-white);
|
|
25
|
+
|
|
26
|
+
/* Color — Borders */
|
|
27
|
+
--fds-color-border: var(--fds-color-gray-200);
|
|
28
|
+
--fds-color-border-strong: var(--fds-color-gray-300);
|
|
29
|
+
--fds-color-border-focus: var(--fds-color-primary-500);
|
|
30
|
+
--fds-color-border-error: var(--fds-color-error-500);
|
|
31
|
+
|
|
32
|
+
/* Color — State / Feedback */
|
|
33
|
+
--fds-color-success: var(--fds-color-success-600);
|
|
34
|
+
--fds-color-success-subtle: var(--fds-color-success-50);
|
|
35
|
+
--fds-color-warning: var(--fds-color-warning-500);
|
|
36
|
+
--fds-color-warning-subtle: var(--fds-color-warning-50);
|
|
37
|
+
--fds-color-error: var(--fds-color-error-600);
|
|
38
|
+
--fds-color-error-subtle: var(--fds-color-error-50);
|
|
39
|
+
--fds-color-info: var(--fds-color-info-600);
|
|
40
|
+
--fds-color-info-subtle: var(--fds-color-info-50);
|
|
41
|
+
|
|
42
|
+
/* Color — Interactive */
|
|
43
|
+
--fds-color-interactive-hover: var(--fds-color-gray-100);
|
|
44
|
+
--fds-color-interactive-active: var(--fds-color-gray-200);
|
|
45
|
+
--fds-color-disabled: var(--fds-color-gray-300);
|
|
46
|
+
|
|
47
|
+
/* Color — Overlay */
|
|
48
|
+
--fds-color-backdrop: var(--fds-color-black);
|
|
49
|
+
|
|
50
|
+
/* Spacing */
|
|
51
|
+
--fds-spacing-element-xs: var(--fds-spacing-1);
|
|
52
|
+
--fds-spacing-element-sm: var(--fds-spacing-2);
|
|
53
|
+
--fds-spacing-element: var(--fds-spacing-3);
|
|
54
|
+
--fds-spacing-element-lg: var(--fds-spacing-4);
|
|
55
|
+
--fds-spacing-section: var(--fds-spacing-6);
|
|
56
|
+
--fds-spacing-section-lg: var(--fds-spacing-10);
|
|
57
|
+
|
|
58
|
+
/* Typography */
|
|
59
|
+
--fds-font-body-family: var(--fds-font-family-sans);
|
|
60
|
+
--fds-font-body-size: var(--fds-font-size-sm);
|
|
61
|
+
--fds-font-body-weight: var(--fds-font-weight-regular);
|
|
62
|
+
--fds-font-body-line-height: var(--fds-line-height-normal);
|
|
63
|
+
--fds-font-heading-family: var(--fds-font-family-sans);
|
|
64
|
+
--fds-font-heading-weight: var(--fds-font-weight-semibold);
|
|
65
|
+
--fds-font-heading-line-height: var(--fds-line-height-tight);
|
|
66
|
+
--fds-font-code-family: var(--fds-font-family-mono);
|
|
67
|
+
--fds-font-label-size: var(--fds-font-size-xs);
|
|
68
|
+
--fds-font-label-weight: var(--fds-font-weight-medium);
|
|
69
|
+
|
|
70
|
+
/* Border Radius */
|
|
71
|
+
--fds-radius-element: var(--fds-radius-md);
|
|
72
|
+
--fds-radius-surface: var(--fds-radius-lg);
|
|
73
|
+
--fds-radius-overlay: var(--fds-radius-xl);
|
|
74
|
+
|
|
75
|
+
/* Shadow */
|
|
76
|
+
--fds-shadow-element: var(--fds-shadow-sm);
|
|
77
|
+
--fds-shadow-surface: var(--fds-shadow-md);
|
|
78
|
+
--fds-shadow-overlay: var(--fds-shadow-xl);
|
|
79
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import postcss from "postcss";
|
|
4
|
+
// ── Path constants ──────────────────────────────────────────────────────────
|
|
5
|
+
const LIB_DIR = path.resolve(import.meta.dirname, "../..");
|
|
6
|
+
const TOKENS_DIR = path.resolve(LIB_DIR, "tokens");
|
|
7
|
+
const THEMES_DIR = path.resolve(LIB_DIR, "themes");
|
|
8
|
+
const COMPONENT_DIR = path.resolve(TOKENS_DIR, "components");
|
|
9
|
+
const RAW_FILES = [
|
|
10
|
+
"color.css",
|
|
11
|
+
"spacing.css",
|
|
12
|
+
"radii.css",
|
|
13
|
+
"typography.css",
|
|
14
|
+
"shadows.css",
|
|
15
|
+
];
|
|
16
|
+
export { TOKENS_DIR, THEMES_DIR, COMPONENT_DIR, RAW_FILES };
|
|
17
|
+
// ── PostCSS parsing ─────────────────────────────────────────────────────────
|
|
18
|
+
export function parseCSSFile(absolutePath) {
|
|
19
|
+
const css = fs.readFileSync(absolutePath, "utf-8");
|
|
20
|
+
return postcss.parse(css, { from: absolutePath });
|
|
21
|
+
}
|
|
22
|
+
export function parseTokenFile(relativePath) {
|
|
23
|
+
return parseCSSFile(path.resolve(TOKENS_DIR, relativePath));
|
|
24
|
+
}
|
|
25
|
+
export function parseThemeFile(fileName) {
|
|
26
|
+
return parseCSSFile(path.resolve(THEMES_DIR, fileName));
|
|
27
|
+
}
|
|
28
|
+
export function getDeclarations(root) {
|
|
29
|
+
const result = [];
|
|
30
|
+
root.walkDecls((decl) => {
|
|
31
|
+
if (!decl.prop.startsWith("--"))
|
|
32
|
+
return;
|
|
33
|
+
const selector = decl.parent && "selector" in decl.parent
|
|
34
|
+
? decl.parent.selector
|
|
35
|
+
: "";
|
|
36
|
+
result.push({ prop: decl.prop, value: decl.value, selector });
|
|
37
|
+
});
|
|
38
|
+
return result;
|
|
39
|
+
}
|
|
40
|
+
// ── Value classifiers ───────────────────────────────────────────────────────
|
|
41
|
+
const VAR_PATTERN = /var\(\s*(--[a-zA-Z0-9-]+)\s*(?:,\s*[^)]+)?\)/;
|
|
42
|
+
export function extractVarRefs(value) {
|
|
43
|
+
return [...value.matchAll(new RegExp(VAR_PATTERN, "g"))].map((m) => m[1]);
|
|
44
|
+
}
|
|
45
|
+
export function isVarRef(value) {
|
|
46
|
+
return VAR_PATTERN.test(value);
|
|
47
|
+
}
|
|
48
|
+
export function isLiteral(value) {
|
|
49
|
+
return !isVarRef(value);
|
|
50
|
+
}
|
|
51
|
+
const PURE_VAR_RE = /^var\(\s*--[a-zA-Z0-9-]+\s*(?:,\s*[^)]+)?\)$/;
|
|
52
|
+
/** True when value is exactly one var() call with nothing else. */
|
|
53
|
+
export function isPureVarRef(value) {
|
|
54
|
+
return PURE_VAR_RE.test(value.trim());
|
|
55
|
+
}
|
|
56
|
+
// ── Selector extraction ─────────────────────────────────────────────────────
|
|
57
|
+
export function getSelectors(root) {
|
|
58
|
+
const selectors = new Set();
|
|
59
|
+
root.walkRules((rule) => {
|
|
60
|
+
for (const s of rule.selectors) {
|
|
61
|
+
selectors.add(s.trim());
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
return [...selectors];
|
|
65
|
+
}
|
|
66
|
+
// ── Token set builders ──────────────────────────────────────────────────────
|
|
67
|
+
export function getRawTokenNames() {
|
|
68
|
+
const names = new Set();
|
|
69
|
+
for (const file of RAW_FILES) {
|
|
70
|
+
const root = parseTokenFile(file);
|
|
71
|
+
for (const decl of getDeclarations(root)) {
|
|
72
|
+
names.add(decl.prop);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return names;
|
|
76
|
+
}
|
|
77
|
+
export function getSemanticTokenNames() {
|
|
78
|
+
const names = new Set();
|
|
79
|
+
const root = parseTokenFile("semantic.css");
|
|
80
|
+
for (const decl of getDeclarations(root)) {
|
|
81
|
+
names.add(decl.prop);
|
|
82
|
+
}
|
|
83
|
+
return names;
|
|
84
|
+
}
|
|
85
|
+
export function getComponentFiles() {
|
|
86
|
+
if (!fs.existsSync(COMPONENT_DIR))
|
|
87
|
+
return [];
|
|
88
|
+
return fs
|
|
89
|
+
.readdirSync(COMPONENT_DIR)
|
|
90
|
+
.filter((f) => f.endsWith(".css"))
|
|
91
|
+
.map((f) => path.resolve(COMPONENT_DIR, f));
|
|
92
|
+
}
|
|
93
|
+
export function getComponentTokenNames() {
|
|
94
|
+
const names = new Set();
|
|
95
|
+
for (const file of getComponentFiles()) {
|
|
96
|
+
const root = parseCSSFile(file);
|
|
97
|
+
for (const decl of getDeclarations(root)) {
|
|
98
|
+
names.add(decl.prop);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return names;
|
|
102
|
+
}
|
|
103
|
+
// ── Allowlists (D014 + css-variable-scoping.md §4-§5) ──────────────────────
|
|
104
|
+
/** Structural literals permitted in component tokens */
|
|
105
|
+
export const COMPONENT_LITERAL_ALLOWLIST = {
|
|
106
|
+
"--fds-panel-handle-width": "4px",
|
|
107
|
+
"--fds-panel-handle-color": "transparent",
|
|
108
|
+
};
|
|
109
|
+
/** Raw token refs permitted in component tokens (D014) */
|
|
110
|
+
export const COMPONENT_RAW_REF_ALLOWLIST = {
|
|
111
|
+
"--fds-appshell-commandbar-height": "--fds-spacing-12",
|
|
112
|
+
"--fds-appshell-statusbar-height": "--fds-spacing-8",
|
|
113
|
+
};
|
|
114
|
+
/** Mixed literal+var values permitted in component tokens */
|
|
115
|
+
export const COMPONENT_MIXED_VALUE_ALLOWLIST = {
|
|
116
|
+
"--fds-statusbar-padding": "0 var(--fds-spacing-element)",
|
|
117
|
+
};
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/* Raw color tokens — fudge-design-system
|
|
2
|
+
* Literal hex values. No semantic aliases.
|
|
3
|
+
* Palette derived from OKLCH-informed ramps (Tailwind basis).
|
|
4
|
+
*/
|
|
5
|
+
:root {
|
|
6
|
+
--fds-color-white: #ffffff;
|
|
7
|
+
--fds-color-black: #000000;
|
|
8
|
+
|
|
9
|
+
/* Gray (cool neutral, ~220 hue) */
|
|
10
|
+
--fds-color-gray-50: #f8fafc;
|
|
11
|
+
--fds-color-gray-100: #f1f5f9;
|
|
12
|
+
--fds-color-gray-200: #e2e8f0;
|
|
13
|
+
--fds-color-gray-300: #cbd5e1;
|
|
14
|
+
--fds-color-gray-400: #94a3b8;
|
|
15
|
+
--fds-color-gray-500: #64748b;
|
|
16
|
+
--fds-color-gray-600: #475569;
|
|
17
|
+
--fds-color-gray-700: #334155;
|
|
18
|
+
--fds-color-gray-800: #1e293b;
|
|
19
|
+
--fds-color-gray-900: #0f172a;
|
|
20
|
+
--fds-color-gray-950: #020617;
|
|
21
|
+
|
|
22
|
+
/* Primary (blue, ~220 hue) */
|
|
23
|
+
--fds-color-primary-50: #eff6ff;
|
|
24
|
+
--fds-color-primary-100: #dbeafe;
|
|
25
|
+
--fds-color-primary-200: #bfdbfe;
|
|
26
|
+
--fds-color-primary-300: #93c5fd;
|
|
27
|
+
--fds-color-primary-400: #60a5fa;
|
|
28
|
+
--fds-color-primary-500: #3b82f6;
|
|
29
|
+
--fds-color-primary-600: #2563eb;
|
|
30
|
+
--fds-color-primary-700: #1d4ed8;
|
|
31
|
+
--fds-color-primary-800: #1e40af;
|
|
32
|
+
--fds-color-primary-900: #1e3a8a;
|
|
33
|
+
--fds-color-primary-950: #172554;
|
|
34
|
+
|
|
35
|
+
/* Secondary (violet, ~270 hue) */
|
|
36
|
+
--fds-color-secondary-50: #f5f3ff;
|
|
37
|
+
--fds-color-secondary-100: #ede9fe;
|
|
38
|
+
--fds-color-secondary-200: #ddd6fe;
|
|
39
|
+
--fds-color-secondary-300: #c4b5fd;
|
|
40
|
+
--fds-color-secondary-400: #a78bfa;
|
|
41
|
+
--fds-color-secondary-500: #8b5cf6;
|
|
42
|
+
--fds-color-secondary-600: #7c3aed;
|
|
43
|
+
--fds-color-secondary-700: #6d28d9;
|
|
44
|
+
--fds-color-secondary-800: #5b21b6;
|
|
45
|
+
--fds-color-secondary-900: #4c1d95;
|
|
46
|
+
--fds-color-secondary-950: #2e1065;
|
|
47
|
+
|
|
48
|
+
/* Accent (amber, ~40 hue) */
|
|
49
|
+
--fds-color-accent-50: #fffbeb;
|
|
50
|
+
--fds-color-accent-100: #fef3c7;
|
|
51
|
+
--fds-color-accent-200: #fde68a;
|
|
52
|
+
--fds-color-accent-300: #fcd34d;
|
|
53
|
+
--fds-color-accent-400: #fbbf24;
|
|
54
|
+
--fds-color-accent-500: #f59e0b;
|
|
55
|
+
--fds-color-accent-600: #d97706;
|
|
56
|
+
--fds-color-accent-700: #b45309;
|
|
57
|
+
--fds-color-accent-800: #92400e;
|
|
58
|
+
--fds-color-accent-900: #78350f;
|
|
59
|
+
--fds-color-accent-950: #451a03;
|
|
60
|
+
|
|
61
|
+
/* Success (green, ~145 hue) */
|
|
62
|
+
--fds-color-success-50: #f0fdf4;
|
|
63
|
+
--fds-color-success-100: #dcfce7;
|
|
64
|
+
--fds-color-success-200: #bbf7d0;
|
|
65
|
+
--fds-color-success-300: #86efac;
|
|
66
|
+
--fds-color-success-400: #4ade80;
|
|
67
|
+
--fds-color-success-500: #22c55e;
|
|
68
|
+
--fds-color-success-600: #16a34a;
|
|
69
|
+
--fds-color-success-700: #15803d;
|
|
70
|
+
--fds-color-success-800: #166534;
|
|
71
|
+
--fds-color-success-900: #14532d;
|
|
72
|
+
--fds-color-success-950: #052e16;
|
|
73
|
+
|
|
74
|
+
/* Warning (yellow, ~50 hue) */
|
|
75
|
+
--fds-color-warning-50: #fefce8;
|
|
76
|
+
--fds-color-warning-100: #fef9c3;
|
|
77
|
+
--fds-color-warning-200: #fef08a;
|
|
78
|
+
--fds-color-warning-300: #fde047;
|
|
79
|
+
--fds-color-warning-400: #facc15;
|
|
80
|
+
--fds-color-warning-500: #eab308;
|
|
81
|
+
--fds-color-warning-600: #ca8a04;
|
|
82
|
+
--fds-color-warning-700: #a16207;
|
|
83
|
+
--fds-color-warning-800: #854d0e;
|
|
84
|
+
--fds-color-warning-900: #713f12;
|
|
85
|
+
--fds-color-warning-950: #422006;
|
|
86
|
+
|
|
87
|
+
/* Error (red, ~0 hue) */
|
|
88
|
+
--fds-color-error-50: #fef2f2;
|
|
89
|
+
--fds-color-error-100: #fee2e2;
|
|
90
|
+
--fds-color-error-200: #fecaca;
|
|
91
|
+
--fds-color-error-300: #fca5a5;
|
|
92
|
+
--fds-color-error-400: #f87171;
|
|
93
|
+
--fds-color-error-500: #ef4444;
|
|
94
|
+
--fds-color-error-600: #dc2626;
|
|
95
|
+
--fds-color-error-700: #b91c1c;
|
|
96
|
+
--fds-color-error-800: #991b1b;
|
|
97
|
+
--fds-color-error-900: #7f1d1d;
|
|
98
|
+
--fds-color-error-950: #450a0a;
|
|
99
|
+
|
|
100
|
+
/* Info (cyan, ~190 hue) */
|
|
101
|
+
--fds-color-info-50: #ecfeff;
|
|
102
|
+
--fds-color-info-100: #cffafe;
|
|
103
|
+
--fds-color-info-200: #a5f3fc;
|
|
104
|
+
--fds-color-info-300: #67e8f9;
|
|
105
|
+
--fds-color-info-400: #22d3ee;
|
|
106
|
+
--fds-color-info-500: #06b6d4;
|
|
107
|
+
--fds-color-info-600: #0891b2;
|
|
108
|
+
--fds-color-info-700: #0e7490;
|
|
109
|
+
--fds-color-info-800: #155e75;
|
|
110
|
+
--fds-color-info-900: #164e63;
|
|
111
|
+
--fds-color-info-950: #083344;
|
|
112
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/* Component tokens — AppShell + structural zones */
|
|
2
|
+
.fds-appshell {
|
|
3
|
+
--fds-appshell-commandbar-height: var(--fds-spacing-12);
|
|
4
|
+
--fds-appshell-statusbar-height: var(--fds-spacing-8);
|
|
5
|
+
--fds-appshell-bg: var(--fds-color-bg);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.fds-commandbar {
|
|
9
|
+
--fds-commandbar-bg: var(--fds-color-surface);
|
|
10
|
+
--fds-commandbar-border-color: var(--fds-color-border);
|
|
11
|
+
--fds-commandbar-padding: var(--fds-spacing-element-sm) var(--fds-spacing-element);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.fds-canvas {
|
|
15
|
+
--fds-canvas-bg: var(--fds-color-bg);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.fds-statusbar {
|
|
19
|
+
--fds-statusbar-bg: var(--fds-color-surface);
|
|
20
|
+
--fds-statusbar-border-color: var(--fds-color-border);
|
|
21
|
+
--fds-statusbar-padding: 0 var(--fds-spacing-element);
|
|
22
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
.fds-button {
|
|
2
|
+
--fds-button-bg: var(--fds-color-primary);
|
|
3
|
+
--fds-button-bg-hover: var(--fds-color-primary-hover);
|
|
4
|
+
--fds-button-bg-active: var(--fds-color-primary-active);
|
|
5
|
+
--fds-button-text: var(--fds-color-text-on-primary);
|
|
6
|
+
--fds-button-border-color: var(--fds-color-primary);
|
|
7
|
+
--fds-button-border-color-focus: var(--fds-color-border-focus);
|
|
8
|
+
--fds-button-font-family: var(--fds-font-body-family);
|
|
9
|
+
--fds-button-font-size: var(--fds-font-body-size);
|
|
10
|
+
--fds-button-font-weight: var(--fds-font-label-weight);
|
|
11
|
+
--fds-button-padding-x: var(--fds-spacing-element-lg);
|
|
12
|
+
--fds-button-padding-y: var(--fds-spacing-element-sm);
|
|
13
|
+
--fds-button-radius: var(--fds-radius-element);
|
|
14
|
+
--fds-button-bg-disabled: var(--fds-color-disabled);
|
|
15
|
+
--fds-button-text-disabled: var(--fds-color-text-secondary);
|
|
16
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
.fds-command-palette {
|
|
2
|
+
--fds-command-palette-bg: var(--fds-color-surface-overlay);
|
|
3
|
+
--fds-command-palette-border-color: var(--fds-color-border);
|
|
4
|
+
--fds-command-palette-radius: var(--fds-radius-overlay);
|
|
5
|
+
--fds-command-palette-shadow: var(--fds-shadow-overlay);
|
|
6
|
+
--fds-command-palette-padding: var(--fds-spacing-element-sm);
|
|
7
|
+
--fds-command-palette-item-bg-active: var(--fds-color-interactive-hover);
|
|
8
|
+
--fds-command-palette-item-text: var(--fds-color-text);
|
|
9
|
+
--fds-command-palette-item-text-secondary: var(--fds-color-text-tertiary);
|
|
10
|
+
--fds-command-palette-item-font-size-secondary: var(--fds-font-label-size);
|
|
11
|
+
--fds-command-palette-item-padding-x: var(--fds-spacing-element);
|
|
12
|
+
--fds-command-palette-item-padding-y: var(--fds-spacing-element-sm);
|
|
13
|
+
--fds-command-palette-item-radius: var(--fds-radius-element);
|
|
14
|
+
--fds-command-palette-empty-text: var(--fds-color-text-tertiary);
|
|
15
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
.fds-input {
|
|
2
|
+
--fds-input-bg: var(--fds-color-surface);
|
|
3
|
+
--fds-input-text: var(--fds-color-text);
|
|
4
|
+
--fds-input-placeholder: var(--fds-color-text-tertiary);
|
|
5
|
+
--fds-input-border-color: var(--fds-color-border);
|
|
6
|
+
--fds-input-border-color-hover: var(--fds-color-border-strong);
|
|
7
|
+
--fds-input-border-color-focus: var(--fds-color-border-focus);
|
|
8
|
+
--fds-input-border-color-error: var(--fds-color-border-error);
|
|
9
|
+
--fds-input-font-family: var(--fds-font-body-family);
|
|
10
|
+
--fds-input-font-size: var(--fds-font-body-size);
|
|
11
|
+
--fds-input-padding-x: var(--fds-spacing-element);
|
|
12
|
+
--fds-input-padding-y: var(--fds-spacing-element-sm);
|
|
13
|
+
--fds-input-radius: var(--fds-radius-element);
|
|
14
|
+
--fds-input-bg-disabled: var(--fds-color-disabled);
|
|
15
|
+
--fds-input-text-disabled: var(--fds-color-text-secondary);
|
|
16
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
.fds-modal {
|
|
2
|
+
--fds-modal-bg: var(--fds-color-surface-overlay);
|
|
3
|
+
--fds-modal-text: var(--fds-color-text);
|
|
4
|
+
--fds-modal-border-color: var(--fds-color-border);
|
|
5
|
+
--fds-modal-radius: var(--fds-radius-overlay);
|
|
6
|
+
--fds-modal-shadow: var(--fds-shadow-overlay);
|
|
7
|
+
--fds-modal-padding: var(--fds-spacing-section);
|
|
8
|
+
--fds-modal-backdrop: var(--fds-color-backdrop);
|
|
9
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/* Component tokens — Panel
|
|
2
|
+
*
|
|
3
|
+
* Width defaults/min/max are intentionally NOT tokenized here.
|
|
4
|
+
* Panel width is controlled programmatically via Svelte props (width, minWidth,
|
|
5
|
+
* maxWidth) and applied as inline styles. CSS custom properties cannot serve as
|
|
6
|
+
* JS prop defaults, so declaring them here would create a misleading dual
|
|
7
|
+
* source of truth. The component props are authoritative for sizing.
|
|
8
|
+
*/
|
|
9
|
+
.fds-panel {
|
|
10
|
+
--fds-panel-bg: var(--fds-color-surface);
|
|
11
|
+
--fds-panel-border-color: var(--fds-color-border);
|
|
12
|
+
--fds-panel-handle-width: 4px;
|
|
13
|
+
--fds-panel-handle-color: transparent;
|
|
14
|
+
--fds-panel-handle-color-hover: var(--fds-color-border-strong);
|
|
15
|
+
--fds-panel-handle-color-active: var(--fds-color-primary);
|
|
16
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
.fds-tooltip {
|
|
2
|
+
--fds-tooltip-bg: var(--fds-color-surface-overlay);
|
|
3
|
+
--fds-tooltip-text: var(--fds-color-text);
|
|
4
|
+
--fds-tooltip-font-family: var(--fds-font-body-family);
|
|
5
|
+
--fds-tooltip-font-size: var(--fds-font-label-size);
|
|
6
|
+
--fds-tooltip-padding-x: var(--fds-spacing-element-sm);
|
|
7
|
+
--fds-tooltip-padding-y: var(--fds-spacing-element-xs);
|
|
8
|
+
--fds-tooltip-radius: var(--fds-radius-element);
|
|
9
|
+
--fds-tooltip-shadow: var(--fds-shadow-overlay);
|
|
10
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
@import './color.css';
|
|
2
|
+
@import './spacing.css';
|
|
3
|
+
@import './radii.css';
|
|
4
|
+
@import './typography.css';
|
|
5
|
+
@import './shadows.css';
|
|
6
|
+
@import './semantic.css';
|
|
7
|
+
@import './components/appshell.css';
|
|
8
|
+
@import './components/button.css';
|
|
9
|
+
@import './components/command-palette.css';
|
|
10
|
+
@import './components/input.css';
|
|
11
|
+
@import './components/modal.css';
|
|
12
|
+
@import './components/panel.css';
|
|
13
|
+
@import './components/tooltip.css';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/* Raw border-radius tokens — fudge-design-system */
|
|
2
|
+
:root {
|
|
3
|
+
--fds-radius-none: 0;
|
|
4
|
+
--fds-radius-sm: 0.125rem; /* 2px */
|
|
5
|
+
--fds-radius-md: 0.375rem; /* 6px */
|
|
6
|
+
--fds-radius-lg: 0.5rem; /* 8px */
|
|
7
|
+
--fds-radius-xl: 0.75rem; /* 12px */
|
|
8
|
+
--fds-radius-2xl: 1rem; /* 16px */
|
|
9
|
+
--fds-radius-full: 9999px;
|
|
10
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/* Semantic tokens — fudge-design-system
|
|
2
|
+
* Intent-driven aliases resolving to raw tokens via var().
|
|
3
|
+
* Zero literal values. Theming works by rebinding these mappings.
|
|
4
|
+
*/
|
|
5
|
+
:root {
|
|
6
|
+
/* Color — Backgrounds / Surfaces */
|
|
7
|
+
--fds-color-bg: var(--fds-color-white);
|
|
8
|
+
--fds-color-surface: var(--fds-color-white);
|
|
9
|
+
--fds-color-surface-raised: var(--fds-color-gray-50);
|
|
10
|
+
--fds-color-surface-sunken: var(--fds-color-gray-100);
|
|
11
|
+
--fds-color-surface-overlay: var(--fds-color-white);
|
|
12
|
+
--fds-color-primary: var(--fds-color-primary-600);
|
|
13
|
+
--fds-color-primary-hover: var(--fds-color-primary-700);
|
|
14
|
+
--fds-color-primary-active: var(--fds-color-primary-800);
|
|
15
|
+
--fds-color-secondary: var(--fds-color-secondary-600);
|
|
16
|
+
--fds-color-accent: var(--fds-color-accent-500);
|
|
17
|
+
|
|
18
|
+
/* Color — Text */
|
|
19
|
+
--fds-color-text: var(--fds-color-gray-900);
|
|
20
|
+
--fds-color-text-secondary: var(--fds-color-gray-600);
|
|
21
|
+
--fds-color-text-tertiary: var(--fds-color-gray-400);
|
|
22
|
+
--fds-color-text-inverse: var(--fds-color-white);
|
|
23
|
+
--fds-color-text-link: var(--fds-color-primary-600);
|
|
24
|
+
--fds-color-text-on-primary: var(--fds-color-white);
|
|
25
|
+
|
|
26
|
+
/* Color — Borders */
|
|
27
|
+
--fds-color-border: var(--fds-color-gray-200);
|
|
28
|
+
--fds-color-border-strong: var(--fds-color-gray-300);
|
|
29
|
+
--fds-color-border-focus: var(--fds-color-primary-500);
|
|
30
|
+
--fds-color-border-error: var(--fds-color-error-500);
|
|
31
|
+
|
|
32
|
+
/* Color — State / Feedback */
|
|
33
|
+
--fds-color-success: var(--fds-color-success-600);
|
|
34
|
+
--fds-color-success-subtle: var(--fds-color-success-50);
|
|
35
|
+
--fds-color-warning: var(--fds-color-warning-500);
|
|
36
|
+
--fds-color-warning-subtle: var(--fds-color-warning-50);
|
|
37
|
+
--fds-color-error: var(--fds-color-error-600);
|
|
38
|
+
--fds-color-error-subtle: var(--fds-color-error-50);
|
|
39
|
+
--fds-color-info: var(--fds-color-info-600);
|
|
40
|
+
--fds-color-info-subtle: var(--fds-color-info-50);
|
|
41
|
+
|
|
42
|
+
/* Color — Interactive */
|
|
43
|
+
--fds-color-interactive-hover: var(--fds-color-gray-100);
|
|
44
|
+
--fds-color-interactive-active: var(--fds-color-gray-200);
|
|
45
|
+
--fds-color-disabled: var(--fds-color-gray-300);
|
|
46
|
+
|
|
47
|
+
/* Color — Overlay */
|
|
48
|
+
--fds-color-backdrop: var(--fds-color-black);
|
|
49
|
+
|
|
50
|
+
/* Spacing */
|
|
51
|
+
--fds-spacing-element-xs: var(--fds-spacing-1);
|
|
52
|
+
--fds-spacing-element-sm: var(--fds-spacing-2);
|
|
53
|
+
--fds-spacing-element: var(--fds-spacing-3);
|
|
54
|
+
--fds-spacing-element-lg: var(--fds-spacing-4);
|
|
55
|
+
--fds-spacing-section: var(--fds-spacing-6);
|
|
56
|
+
--fds-spacing-section-lg: var(--fds-spacing-10);
|
|
57
|
+
|
|
58
|
+
/* Typography */
|
|
59
|
+
--fds-font-body-family: var(--fds-font-family-sans);
|
|
60
|
+
--fds-font-body-size: var(--fds-font-size-sm);
|
|
61
|
+
--fds-font-body-weight: var(--fds-font-weight-regular);
|
|
62
|
+
--fds-font-body-line-height: var(--fds-line-height-normal);
|
|
63
|
+
--fds-font-heading-family: var(--fds-font-family-sans);
|
|
64
|
+
--fds-font-heading-weight: var(--fds-font-weight-semibold);
|
|
65
|
+
--fds-font-heading-line-height: var(--fds-line-height-tight);
|
|
66
|
+
--fds-font-code-family: var(--fds-font-family-mono);
|
|
67
|
+
--fds-font-label-size: var(--fds-font-size-xs);
|
|
68
|
+
--fds-font-label-weight: var(--fds-font-weight-medium);
|
|
69
|
+
|
|
70
|
+
/* Border Radius */
|
|
71
|
+
--fds-radius-element: var(--fds-radius-md);
|
|
72
|
+
--fds-radius-surface: var(--fds-radius-lg);
|
|
73
|
+
--fds-radius-overlay: var(--fds-radius-xl);
|
|
74
|
+
|
|
75
|
+
/* Shadow */
|
|
76
|
+
--fds-shadow-element: var(--fds-shadow-sm);
|
|
77
|
+
--fds-shadow-surface: var(--fds-shadow-md);
|
|
78
|
+
--fds-shadow-overlay: var(--fds-shadow-xl);
|
|
79
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/* Raw shadow tokens — fudge-design-system
|
|
2
|
+
* Multi-layer box-shadows. CSS Color Level 4 syntax.
|
|
3
|
+
*/
|
|
4
|
+
:root {
|
|
5
|
+
--fds-shadow-none: none;
|
|
6
|
+
--fds-shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
|
|
7
|
+
--fds-shadow-md: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
|
|
8
|
+
--fds-shadow-lg: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
|
|
9
|
+
--fds-shadow-xl: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
|
|
10
|
+
--fds-shadow-2xl: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
|
|
11
|
+
}
|