@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.
Files changed (57) hide show
  1. package/README.md +140 -0
  2. package/dist/components/.gitkeep +0 -0
  3. package/dist/components/Button.svelte +118 -0
  4. package/dist/components/Button.svelte.d.ts +12 -0
  5. package/dist/components/CommandPalette.svelte +167 -0
  6. package/dist/components/CommandPalette.svelte.d.ts +16 -0
  7. package/dist/components/Input.svelte +70 -0
  8. package/dist/components/Input.svelte.d.ts +9 -0
  9. package/dist/components/Modal.svelte +83 -0
  10. package/dist/components/Modal.svelte.d.ts +12 -0
  11. package/dist/components/Tooltip.svelte +92 -0
  12. package/dist/components/Tooltip.svelte.d.ts +12 -0
  13. package/dist/components/index.d.ts +8 -0
  14. package/dist/components/index.js +5 -0
  15. package/dist/index.d.ts +3 -0
  16. package/dist/index.js +3 -0
  17. package/dist/layout/.gitkeep +0 -0
  18. package/dist/layout/AIPanel.svelte +34 -0
  19. package/dist/layout/AIPanel.svelte.d.ts +11 -0
  20. package/dist/layout/AppShell.svelte +78 -0
  21. package/dist/layout/AppShell.svelte.d.ts +11 -0
  22. package/dist/layout/Canvas.svelte +22 -0
  23. package/dist/layout/Canvas.svelte.d.ts +7 -0
  24. package/dist/layout/CommandBar.svelte +25 -0
  25. package/dist/layout/CommandBar.svelte.d.ts +7 -0
  26. package/dist/layout/Panel.svelte +157 -0
  27. package/dist/layout/Panel.svelte.d.ts +13 -0
  28. package/dist/layout/Sidebar.svelte +34 -0
  29. package/dist/layout/Sidebar.svelte.d.ts +11 -0
  30. package/dist/layout/StatusBar.svelte +26 -0
  31. package/dist/layout/StatusBar.svelte.d.ts +7 -0
  32. package/dist/layout/__tests__/helpers.js +53 -0
  33. package/dist/layout/index.d.ts +8 -0
  34. package/dist/layout/index.js +7 -0
  35. package/dist/themes/ThemeProvider.svelte +44 -0
  36. package/dist/themes/ThemeProvider.svelte.d.ts +10 -0
  37. package/dist/themes/dark.css +49 -0
  38. package/dist/themes/index.d.ts +2 -0
  39. package/dist/themes/index.js +1 -0
  40. package/dist/themes/light.css +79 -0
  41. package/dist/tokens/.gitkeep +0 -0
  42. package/dist/tokens/__tests__/helpers.js +117 -0
  43. package/dist/tokens/color.css +112 -0
  44. package/dist/tokens/components/appshell.css +22 -0
  45. package/dist/tokens/components/button.css +16 -0
  46. package/dist/tokens/components/command-palette.css +15 -0
  47. package/dist/tokens/components/input.css +16 -0
  48. package/dist/tokens/components/modal.css +9 -0
  49. package/dist/tokens/components/panel.css +16 -0
  50. package/dist/tokens/components/tooltip.css +10 -0
  51. package/dist/tokens/index.css +13 -0
  52. package/dist/tokens/radii.css +10 -0
  53. package/dist/tokens/semantic.css +79 -0
  54. package/dist/tokens/shadows.css +11 -0
  55. package/dist/tokens/spacing.css +32 -0
  56. package/dist/tokens/typography.css +39 -0
  57. 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,2 @@
1
+ export { default as ThemeProvider } from "./ThemeProvider.svelte";
2
+ export type { Theme } from "./ThemeProvider.svelte";
@@ -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
+ }