@r2digisolutions/components 0.6.9 → 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 +47 -0
- package/dist/components/atoms/Input/Input.svelte +61 -44
- package/dist/components/molecules/InfiniteScroll/InfiniteScroll.svelte +16 -25
- package/dist/components/molecules/InfiniteScroll/InfiniteScroll.svelte.d.ts +1 -1
- package/dist/components/molecules/Select/Select.svelte +3 -4
- package/dist/components/molecules/TreePanel/TreePanel.stories.d.ts +26 -0
- package/dist/components/molecules/TreePanel/TreePanel.stories.js +18 -0
- package/dist/components/molecules/TreePanel/TreePanel.svelte +278 -0
- package/dist/components/molecules/TreePanel/TreePanel.svelte.d.ts +37 -0
- package/dist/components/molecules/TreePanel/TreePanelStory.svelte +54 -0
- package/dist/components/molecules/TreePanel/TreePanelStory.svelte.d.ts +7 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +1 -0
- package/dist/styles.css +247 -202
- package/dist/utils/theme.svelte.d.ts +16 -2
- package/dist/utils/theme.svelte.js +44 -7
- package/package.json +1 -1
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
export interface TreePanelNode {
|
|
3
|
+
id: string;
|
|
4
|
+
label: string;
|
|
5
|
+
/** Emoji or short glyph shown instead of the default folder / branch icon. */
|
|
6
|
+
icon?: string | null;
|
|
7
|
+
/** Extra column value (sort order, count, …). */
|
|
8
|
+
meta?: string | number | null;
|
|
9
|
+
children?: TreePanelNode[];
|
|
10
|
+
}
|
|
11
|
+
interface TreePanelProps {
|
|
12
|
+
items?: TreePanelNode[];
|
|
13
|
+
collapsedIds?: string[];
|
|
14
|
+
emptyMessage?: string;
|
|
15
|
+
hierarchyLabel?: string;
|
|
16
|
+
metaLabel?: string;
|
|
17
|
+
actionsLabel?: string;
|
|
18
|
+
showMeta?: boolean;
|
|
19
|
+
addChildLabel?: string;
|
|
20
|
+
editLabel?: string;
|
|
21
|
+
deleteLabel?: string;
|
|
22
|
+
expandLabel?: string;
|
|
23
|
+
collapseLabel?: string;
|
|
24
|
+
onAddChild?: (node: TreePanelNode) => void;
|
|
25
|
+
onEdit?: (node: TreePanelNode) => void;
|
|
26
|
+
onDelete?: (node: TreePanelNode) => void;
|
|
27
|
+
/** Extra content after the label (badges, counts). */
|
|
28
|
+
meta?: Snippet<[TreePanelNode, number]>;
|
|
29
|
+
/** Replaces the default add / edit / delete buttons. */
|
|
30
|
+
trailing?: Snippet<[TreePanelNode, number]>;
|
|
31
|
+
leading?: Snippet<[TreePanelNode, number]>;
|
|
32
|
+
empty?: Snippet;
|
|
33
|
+
class?: string;
|
|
34
|
+
}
|
|
35
|
+
declare const TreePanel: import("svelte").Component<TreePanelProps, {}, "collapsedIds">;
|
|
36
|
+
type TreePanel = ReturnType<typeof TreePanel>;
|
|
37
|
+
export default TreePanel;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import TreePanel, { type TreePanelNode } from './TreePanel.svelte';
|
|
3
|
+
|
|
4
|
+
let {
|
|
5
|
+
showMeta = false,
|
|
6
|
+
empty = false
|
|
7
|
+
}: {
|
|
8
|
+
showMeta?: boolean;
|
|
9
|
+
empty?: boolean;
|
|
10
|
+
} = $props();
|
|
11
|
+
|
|
12
|
+
const catalog: TreePanelNode[] = [
|
|
13
|
+
{
|
|
14
|
+
id: 'products',
|
|
15
|
+
label: 'Productos',
|
|
16
|
+
children: [
|
|
17
|
+
{ id: 'lighting', label: 'Iluminación', meta: 1 },
|
|
18
|
+
{ id: 'furniture', label: 'Mobiliario', meta: 2 }
|
|
19
|
+
]
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
id: 'services',
|
|
23
|
+
label: 'Servicios',
|
|
24
|
+
children: [
|
|
25
|
+
{ id: 'consulting', label: 'Consultoría', meta: 1 },
|
|
26
|
+
{ id: 'renovation', label: 'Reforma', meta: 2 }
|
|
27
|
+
]
|
|
28
|
+
}
|
|
29
|
+
];
|
|
30
|
+
|
|
31
|
+
let collapsedIds = $state<string[]>([]);
|
|
32
|
+
let lastAction = $state('—');
|
|
33
|
+
</script>
|
|
34
|
+
|
|
35
|
+
<div class="max-w-2xl">
|
|
36
|
+
<TreePanel
|
|
37
|
+
items={empty ? [] : catalog}
|
|
38
|
+
bind:collapsedIds
|
|
39
|
+
{showMeta}
|
|
40
|
+
emptyMessage="No hay categorías todavía."
|
|
41
|
+
hierarchyLabel="Jerarquía"
|
|
42
|
+
metaLabel="Orden"
|
|
43
|
+
actionsLabel="Acciones"
|
|
44
|
+
addChildLabel="Añadir subcategoría"
|
|
45
|
+
editLabel="Editar"
|
|
46
|
+
deleteLabel="Eliminar"
|
|
47
|
+
onAddChild={(node) => (lastAction = `Añadir hijo de ${node.label}`)}
|
|
48
|
+
onEdit={(node) => (lastAction = `Editar ${node.label}`)}
|
|
49
|
+
onDelete={(node) => (lastAction = `Eliminar ${node.label}`)}
|
|
50
|
+
/>
|
|
51
|
+
<p class="mt-3 text-xs text-secondary">
|
|
52
|
+
Última acción: <span class="font-medium text-primary">{lastAction}</span>
|
|
53
|
+
</p>
|
|
54
|
+
</div>
|
package/dist/index.d.ts
CHANGED
|
@@ -227,6 +227,8 @@ export { default as Carousel } from './components/molecules/Carousel/Carousel.sv
|
|
|
227
227
|
export type { CarouselItem } from './components/molecules/Carousel/Carousel.svelte';
|
|
228
228
|
export { default as TreeView } from './components/molecules/TreeView/TreeView.svelte';
|
|
229
229
|
export type { TreeNode } from './components/molecules/TreeView/TreeView.svelte';
|
|
230
|
+
export { default as TreePanel } from './components/molecules/TreePanel/TreePanel.svelte';
|
|
231
|
+
export type { TreePanelNode } from './components/molecules/TreePanel/TreePanel.svelte';
|
|
230
232
|
export { default as TreeSelect } from './components/molecules/TreeSelect/TreeSelect.svelte';
|
|
231
233
|
export { default as Cascader } from './components/molecules/Cascader/Cascader.svelte';
|
|
232
234
|
export type { CascaderOption } from './components/molecules/Cascader/Cascader.svelte';
|
|
@@ -818,7 +820,7 @@ export { default as CanvasEditorTemplate } from './components/templates/CanvasEd
|
|
|
818
820
|
export { default as VideoEditorTemplate } from './components/templates/VideoEditorTemplate/VideoEditorTemplate.svelte';
|
|
819
821
|
export { default as AudioEditorTemplate } from './components/templates/AudioEditorTemplate/AudioEditorTemplate.svelte';
|
|
820
822
|
export { themeStore } from './utils/theme.svelte.js';
|
|
821
|
-
export type { Theme } from './utils/theme.svelte.js';
|
|
823
|
+
export type { Theme, ThemePalette } from './utils/theme.svelte.js';
|
|
822
824
|
export { createId } from './utils/id.js';
|
|
823
825
|
export { resolveAccessor, accessorPatchKey, resolveRowKey } from './utils/columnAccessor.js';
|
|
824
826
|
export type { ColumnAccessor, RowKey } from './utils/columnAccessor.js';
|
package/dist/index.js
CHANGED
|
@@ -176,6 +176,7 @@ export { default as ConfirmDialog } from './components/molecules/ConfirmDialog/C
|
|
|
176
176
|
export { default as ContextMenu } from './components/molecules/ContextMenu/ContextMenu.svelte';
|
|
177
177
|
export { default as Carousel } from './components/molecules/Carousel/Carousel.svelte';
|
|
178
178
|
export { default as TreeView } from './components/molecules/TreeView/TreeView.svelte';
|
|
179
|
+
export { default as TreePanel } from './components/molecules/TreePanel/TreePanel.svelte';
|
|
179
180
|
export { default as TreeSelect } from './components/molecules/TreeSelect/TreeSelect.svelte';
|
|
180
181
|
export { default as Cascader } from './components/molecules/Cascader/Cascader.svelte';
|
|
181
182
|
export { default as MaskedInput } from './components/molecules/MaskedInput/MaskedInput.svelte';
|
package/dist/styles.css
CHANGED
|
@@ -10,51 +10,72 @@
|
|
|
10
10
|
─────────────────────────────────────────────────────────────────────────── */
|
|
11
11
|
|
|
12
12
|
@theme {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
13
|
+
/* Brand colors */
|
|
14
|
+
--color-brand-50: oklch(97% 0.02 265);
|
|
15
|
+
--color-brand-100: oklch(93% 0.05 265);
|
|
16
|
+
--color-brand-200: oklch(86% 0.1 265);
|
|
17
|
+
--color-brand-300: oklch(76% 0.15 265);
|
|
18
|
+
--color-brand-400: oklch(65% 0.2 265);
|
|
19
|
+
--color-brand-500: oklch(55% 0.25 265);
|
|
20
|
+
--color-brand-600: oklch(47% 0.26 265);
|
|
21
|
+
--color-brand-700: oklch(39% 0.24 265);
|
|
22
|
+
--color-brand-800: oklch(31% 0.2 265);
|
|
23
|
+
--color-brand-900: oklch(22% 0.14 265);
|
|
24
|
+
--color-brand-950: oklch(15% 0.08 265);
|
|
25
|
+
|
|
26
|
+
/* Semantic surface tokens */
|
|
27
|
+
--color-surface: var(--surface);
|
|
28
|
+
--color-surface-elevated: var(--surface-elevated);
|
|
29
|
+
--color-surface-overlay: var(--surface-overlay);
|
|
30
|
+
--color-border: var(--border);
|
|
31
|
+
--color-border-strong: var(--border-strong);
|
|
32
|
+
--color-text-primary: var(--text-primary);
|
|
33
|
+
--color-text-secondary: var(--text-secondary);
|
|
34
|
+
--color-text-muted: var(--text-muted);
|
|
35
|
+
--color-text-inverse: var(--text-inverse);
|
|
36
|
+
|
|
37
|
+
/* Typography */
|
|
38
|
+
--font-sans: 'Inter', ui-sans-serif, system-ui, sans-serif;
|
|
39
|
+
--font-mono: 'JetBrains Mono', ui-monospace, monospace;
|
|
40
|
+
|
|
41
|
+
/* Radii */
|
|
42
|
+
--radius-sm: 0.375rem;
|
|
43
|
+
--radius-md: 0.5rem;
|
|
44
|
+
--radius-lg: 0.75rem;
|
|
45
|
+
--radius-xl: 1rem;
|
|
46
|
+
--radius-2xl: 1.5rem;
|
|
47
|
+
--radius-full: 9999px;
|
|
48
|
+
|
|
49
|
+
/* Shadows */
|
|
50
|
+
--shadow-sm: 0 1px 3px 0 oklch(0% 0 0 / 0.08), 0 1px 2px -1px oklch(0% 0 0 / 0.06);
|
|
51
|
+
--shadow-md: 0 4px 6px -1px oklch(0% 0 0 / 0.1), 0 2px 4px -2px oklch(0% 0 0 / 0.08);
|
|
52
|
+
--shadow-lg: 0 10px 15px -3px oklch(0% 0 0 / 0.12), 0 4px 6px -4px oklch(0% 0 0 / 0.08);
|
|
53
|
+
--shadow-xl: 0 20px 25px -5px oklch(0% 0 0 / 0.14), 0 8px 10px -6px oklch(0% 0 0 / 0.08);
|
|
54
|
+
|
|
55
|
+
/* Transitions */
|
|
56
|
+
--ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
|
|
57
|
+
--ease-smooth: cubic-bezier(0.4, 0, 0.2, 1);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/* ─────────────────────────────────────────────────────────────────────────────
|
|
61
|
+
Gray palette — <html data-theme="slate" | "neutral">
|
|
62
|
+
slate (default): cool indigo cast (hue 265)
|
|
63
|
+
neutral: chroma 0, same family as Tailwind `neutral`
|
|
64
|
+
─────────────────────────────────────────────────────────────────────────── */
|
|
65
|
+
|
|
66
|
+
:root {
|
|
67
|
+
--r2-gray-h: 265;
|
|
68
|
+
--r2-gray-c: 0.02;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
:root[data-theme='slate'] {
|
|
72
|
+
--r2-gray-h: 265;
|
|
73
|
+
--r2-gray-c: 0.02;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
:root[data-theme='neutral'] {
|
|
77
|
+
--r2-gray-h: 0;
|
|
78
|
+
--r2-gray-c: 0;
|
|
58
79
|
}
|
|
59
80
|
|
|
60
81
|
/* ─────────────────────────────────────────────────────────────────────────────
|
|
@@ -62,46 +83,46 @@
|
|
|
62
83
|
─────────────────────────────────────────────────────────────────────────── */
|
|
63
84
|
|
|
64
85
|
:root {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
86
|
+
color-scheme: light;
|
|
87
|
+
|
|
88
|
+
--surface: oklch(99% calc(var(--r2-gray-c) * 0.25) var(--r2-gray-h));
|
|
89
|
+
--surface-elevated: oklch(100% 0 0);
|
|
90
|
+
--surface-overlay: oklch(97% calc(var(--r2-gray-c) * 0.5) var(--r2-gray-h));
|
|
91
|
+
--border: oklch(88% var(--r2-gray-c) var(--r2-gray-h));
|
|
92
|
+
--border-strong: oklch(75% calc(var(--r2-gray-c) * 2) var(--r2-gray-h));
|
|
93
|
+
--text-primary: oklch(15% var(--r2-gray-c) var(--r2-gray-h));
|
|
94
|
+
--text-secondary: oklch(35% calc(var(--r2-gray-c) * 1.5) var(--r2-gray-h));
|
|
95
|
+
--text-muted: oklch(45% var(--r2-gray-c) var(--r2-gray-h));
|
|
96
|
+
--text-inverse: oklch(99% 0 0);
|
|
97
|
+
|
|
98
|
+
/* Alert tones */
|
|
99
|
+
--alert-info-bg: oklch(96% 0.03 240);
|
|
100
|
+
--alert-info-border: oklch(82% 0.06 240);
|
|
101
|
+
--alert-info-fg: oklch(28% 0.08 240);
|
|
102
|
+
--alert-info-muted: oklch(40% 0.06 240);
|
|
103
|
+
--alert-info-icon: oklch(52% 0.14 240);
|
|
104
|
+
--alert-info-accent: oklch(55% 0.16 240);
|
|
105
|
+
|
|
106
|
+
--alert-success-bg: oklch(96% 0.04 150);
|
|
107
|
+
--alert-success-border: oklch(82% 0.07 150);
|
|
108
|
+
--alert-success-fg: oklch(28% 0.08 150);
|
|
109
|
+
--alert-success-muted: oklch(38% 0.06 150);
|
|
110
|
+
--alert-success-icon: oklch(50% 0.14 150);
|
|
111
|
+
--alert-success-accent: oklch(55% 0.16 150);
|
|
112
|
+
|
|
113
|
+
--alert-warning-bg: oklch(96% 0.05 85);
|
|
114
|
+
--alert-warning-border: oklch(84% 0.1 85);
|
|
115
|
+
--alert-warning-fg: oklch(30% 0.08 75);
|
|
116
|
+
--alert-warning-muted: oklch(42% 0.07 75);
|
|
117
|
+
--alert-warning-icon: oklch(58% 0.15 75);
|
|
118
|
+
--alert-warning-accent: oklch(68% 0.16 75);
|
|
119
|
+
|
|
120
|
+
--alert-error-bg: oklch(96% 0.03 25);
|
|
121
|
+
--alert-error-border: oklch(84% 0.08 25);
|
|
122
|
+
--alert-error-fg: oklch(30% 0.1 25);
|
|
123
|
+
--alert-error-muted: oklch(42% 0.08 25);
|
|
124
|
+
--alert-error-icon: oklch(55% 0.18 25);
|
|
125
|
+
--alert-error-accent: oklch(58% 0.2 25);
|
|
105
126
|
}
|
|
106
127
|
|
|
107
128
|
/* ─────────────────────────────────────────────────────────────────────────────
|
|
@@ -109,46 +130,46 @@
|
|
|
109
130
|
─────────────────────────────────────────────────────────────────────────── */
|
|
110
131
|
|
|
111
132
|
:root.dark {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
133
|
+
color-scheme: dark;
|
|
134
|
+
|
|
135
|
+
--surface: oklch(14% var(--r2-gray-c) var(--r2-gray-h));
|
|
136
|
+
--surface-elevated: oklch(18% calc(var(--r2-gray-c) * 1.25) var(--r2-gray-h));
|
|
137
|
+
--surface-overlay: oklch(20% calc(var(--r2-gray-c) * 1.5) var(--r2-gray-h));
|
|
138
|
+
--border: oklch(28% calc(var(--r2-gray-c) * 1.5) var(--r2-gray-h));
|
|
139
|
+
--border-strong: oklch(40% calc(var(--r2-gray-c) * 2) var(--r2-gray-h));
|
|
140
|
+
--text-primary: oklch(96% calc(var(--r2-gray-c) * 0.5) var(--r2-gray-h));
|
|
141
|
+
--text-secondary: oklch(75% calc(var(--r2-gray-c) * 1.5) var(--r2-gray-h));
|
|
142
|
+
--text-muted: oklch(55% calc(var(--r2-gray-c) * 1.5) var(--r2-gray-h));
|
|
143
|
+
--text-inverse: oklch(15% var(--r2-gray-c) var(--r2-gray-h));
|
|
144
|
+
|
|
145
|
+
/* Alert tones */
|
|
146
|
+
--alert-info-bg: oklch(24% 0.04 240);
|
|
147
|
+
--alert-info-border: oklch(38% 0.06 240);
|
|
148
|
+
--alert-info-fg: oklch(92% 0.03 240);
|
|
149
|
+
--alert-info-muted: oklch(78% 0.04 240);
|
|
150
|
+
--alert-info-icon: oklch(72% 0.12 240);
|
|
151
|
+
--alert-info-accent: oklch(65% 0.14 240);
|
|
152
|
+
|
|
153
|
+
--alert-success-bg: oklch(24% 0.04 150);
|
|
154
|
+
--alert-success-border: oklch(38% 0.06 150);
|
|
155
|
+
--alert-success-fg: oklch(92% 0.03 150);
|
|
156
|
+
--alert-success-muted: oklch(78% 0.04 150);
|
|
157
|
+
--alert-success-icon: oklch(72% 0.12 150);
|
|
158
|
+
--alert-success-accent: oklch(65% 0.14 150);
|
|
159
|
+
|
|
160
|
+
--alert-warning-bg: oklch(25% 0.04 85);
|
|
161
|
+
--alert-warning-border: oklch(40% 0.07 85);
|
|
162
|
+
--alert-warning-fg: oklch(93% 0.03 85);
|
|
163
|
+
--alert-warning-muted: oklch(80% 0.04 85);
|
|
164
|
+
--alert-warning-icon: oklch(78% 0.12 85);
|
|
165
|
+
--alert-warning-accent: oklch(72% 0.14 85);
|
|
166
|
+
|
|
167
|
+
--alert-error-bg: oklch(24% 0.05 25);
|
|
168
|
+
--alert-error-border: oklch(40% 0.08 25);
|
|
169
|
+
--alert-error-fg: oklch(93% 0.03 25);
|
|
170
|
+
--alert-error-muted: oklch(80% 0.04 25);
|
|
171
|
+
--alert-error-icon: oklch(72% 0.14 25);
|
|
172
|
+
--alert-error-accent: oklch(65% 0.18 25);
|
|
152
173
|
}
|
|
153
174
|
|
|
154
175
|
/* ─────────────────────────────────────────────────────────────────────────────
|
|
@@ -156,41 +177,41 @@
|
|
|
156
177
|
─────────────────────────────────────────────────────────────────────────── */
|
|
157
178
|
|
|
158
179
|
@layer base {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
180
|
+
*,
|
|
181
|
+
*::before,
|
|
182
|
+
*::after {
|
|
183
|
+
box-sizing: border-box;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
html {
|
|
187
|
+
-webkit-text-size-adjust: 100%;
|
|
188
|
+
-webkit-font-smoothing: antialiased;
|
|
189
|
+
-moz-osx-font-smoothing: grayscale;
|
|
190
|
+
scroll-behavior: smooth;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
body {
|
|
194
|
+
margin: 0;
|
|
195
|
+
background-color: var(--surface);
|
|
196
|
+
color: var(--text-primary);
|
|
197
|
+
font-family: var(--font-sans);
|
|
198
|
+
line-height: 1.6;
|
|
199
|
+
transition:
|
|
200
|
+
background-color 0.2s var(--ease-smooth),
|
|
201
|
+
color 0.2s var(--ease-smooth);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/* Focus visible styles */
|
|
205
|
+
:focus-visible {
|
|
206
|
+
outline: 2px solid oklch(55% 0.25 265);
|
|
207
|
+
outline-offset: 2px;
|
|
208
|
+
border-radius: var(--radius-sm);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/* Selection */
|
|
212
|
+
::selection {
|
|
213
|
+
background-color: oklch(55% 0.25 265 / 0.25);
|
|
214
|
+
}
|
|
194
215
|
}
|
|
195
216
|
|
|
196
217
|
/* ─────────────────────────────────────────────────────────────────────────────
|
|
@@ -198,46 +219,70 @@
|
|
|
198
219
|
─────────────────────────────────────────────────────────────────────────── */
|
|
199
220
|
|
|
200
221
|
@layer utilities {
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
222
|
+
/* Touch-friendly minimum tap target */
|
|
223
|
+
.touch-target {
|
|
224
|
+
min-height: 44px;
|
|
225
|
+
min-width: 44px;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/* Smooth transitions */
|
|
229
|
+
.transition-smooth {
|
|
230
|
+
transition: all 0.2s var(--ease-smooth);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
.transition-spring {
|
|
234
|
+
transition: all 0.3s var(--ease-spring);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/* Glass morphism */
|
|
238
|
+
.glass {
|
|
239
|
+
backdrop-filter: blur(12px) saturate(180%);
|
|
240
|
+
background-color: oklch(100% 0 0 / 0.08);
|
|
241
|
+
border: 1px solid oklch(100% 0 0 / 0.12);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
.dark .glass {
|
|
245
|
+
background-color: oklch(0% 0 0 / 0.2);
|
|
246
|
+
border-color: oklch(100% 0 0 / 0.08);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/* Surface utilities */
|
|
250
|
+
.bg-surface {
|
|
251
|
+
background-color: var(--surface);
|
|
252
|
+
}
|
|
253
|
+
.bg-surface-elevated {
|
|
254
|
+
background-color: var(--surface-elevated);
|
|
255
|
+
}
|
|
256
|
+
.bg-surface-overlay {
|
|
257
|
+
background-color: var(--surface-overlay);
|
|
258
|
+
}
|
|
259
|
+
.border-border {
|
|
260
|
+
border-color: var(--border);
|
|
261
|
+
}
|
|
262
|
+
.border-border-strong {
|
|
263
|
+
border-color: var(--border-strong);
|
|
264
|
+
}
|
|
265
|
+
.text-primary {
|
|
266
|
+
color: var(--text-primary);
|
|
267
|
+
}
|
|
268
|
+
.text-secondary {
|
|
269
|
+
color: var(--text-secondary);
|
|
270
|
+
}
|
|
271
|
+
.text-muted {
|
|
272
|
+
color: var(--text-muted);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/* SVG chart labels — Tailwind fill-* needs these (text-* alone does not paint <text>) */
|
|
276
|
+
.fill-primary {
|
|
277
|
+
fill: var(--text-primary);
|
|
278
|
+
}
|
|
279
|
+
.fill-secondary {
|
|
280
|
+
fill: var(--text-secondary);
|
|
281
|
+
}
|
|
282
|
+
.fill-muted {
|
|
283
|
+
fill: var(--text-muted);
|
|
284
|
+
}
|
|
285
|
+
.stroke-border {
|
|
286
|
+
stroke: var(--border);
|
|
287
|
+
}
|
|
243
288
|
}
|
|
@@ -1,19 +1,33 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Theme store —
|
|
2
|
+
* Theme store — light/dark + gray palette for R2DigiSolutions components.
|
|
3
|
+
*
|
|
4
|
+
* Mode: `class="dark"` on `<html>`
|
|
5
|
+
* Palette: `data-theme="slate" | "neutral"` on `<html>`
|
|
3
6
|
*
|
|
4
7
|
* - Persists preference to localStorage
|
|
5
8
|
* - Detects system preference via prefers-color-scheme
|
|
6
|
-
* - Applies 'dark' class to <html> element
|
|
7
9
|
* - Reactive via Svelte 5 runes ($state)
|
|
8
10
|
*/
|
|
9
11
|
export type Theme = 'light' | 'dark' | 'system';
|
|
12
|
+
export type ThemePalette = 'slate' | 'neutral';
|
|
10
13
|
declare class ThemeStore {
|
|
11
14
|
#private;
|
|
12
15
|
constructor();
|
|
13
16
|
get theme(): Theme;
|
|
17
|
+
get palette(): ThemePalette;
|
|
14
18
|
get resolved(): 'light' | 'dark';
|
|
15
19
|
get isDark(): boolean;
|
|
16
20
|
set(theme: Theme): void;
|
|
21
|
+
/**
|
|
22
|
+
* Gray family for surfaces, borders and body text.
|
|
23
|
+
* `slate` = cool (hue 265). `neutral` = chroma 0, no blue cast.
|
|
24
|
+
*
|
|
25
|
+
* Pass `{ persist: false }` for a page-level override that does not
|
|
26
|
+
* stick in localStorage.
|
|
27
|
+
*/
|
|
28
|
+
setPalette(palette: ThemePalette, opts?: {
|
|
29
|
+
persist?: boolean;
|
|
30
|
+
}): void;
|
|
17
31
|
toggle(): void;
|
|
18
32
|
}
|
|
19
33
|
export declare const themeStore: ThemeStore;
|