@plures/design-dojo 0.5.3 → 0.7.1
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/dist/app/CanvasBreadcrumb.svelte +146 -0
- package/dist/app/CanvasBreadcrumb.svelte.d.ts +19 -0
- package/dist/app/CanvasBreadcrumb.types.js +1 -0
- package/dist/app/ChatInput.svelte +296 -0
- package/dist/app/ChatInput.svelte.d.ts +15 -0
- package/dist/app/ChatView.svelte +542 -0
- package/dist/app/ChatView.svelte.d.ts +19 -0
- package/dist/app/ChatView.types.js +1 -0
- package/dist/app/ConversationGraph.svelte +471 -0
- package/dist/app/ConversationGraph.svelte.d.ts +20 -0
- package/dist/app/FirstRunWizard.svelte +542 -0
- package/dist/app/FirstRunWizard.svelte.d.ts +10 -0
- package/dist/app/FirstRunWizard.types.js +1 -0
- package/dist/app/MemorySidebar.svelte +258 -0
- package/dist/app/MemorySidebar.svelte.d.ts +9 -0
- package/dist/app/MemorySidebar.types.js +1 -0
- package/dist/app/PeerStatusPanel.svelte +464 -0
- package/dist/app/PeerStatusPanel.svelte.d.ts +16 -0
- package/dist/app/ProcedureCanvas.svelte +994 -0
- package/dist/app/ProcedureCanvas.svelte.d.ts +12 -0
- package/dist/app/ProcedureCanvas.types.js +1 -0
- package/dist/app/ProcedureEditor.svelte +494 -0
- package/dist/app/ProcedureEditor.svelte.d.ts +11 -0
- package/dist/app/ProcedureEditor.types.js +1 -0
- package/dist/app/ProcedureInspector.svelte +520 -0
- package/dist/app/ProcedureInspector.svelte.d.ts +15 -0
- package/dist/app/ProcedureNode.svelte +283 -0
- package/dist/app/ProcedureNode.svelte.d.ts +26 -0
- package/dist/app/Realm.types.js +1 -0
- package/dist/app/RealmIndicator.svelte +81 -0
- package/dist/app/RealmIndicator.svelte.d.ts +10 -0
- package/dist/app/RealmSwitcher.svelte +354 -0
- package/dist/app/RealmSwitcher.svelte.d.ts +16 -0
- package/dist/app/SemanticConversation.types.js +1 -0
- package/dist/app/SemanticSearchInput.svelte +630 -0
- package/dist/app/SemanticSearchInput.svelte.d.ts +20 -0
- package/dist/app/SemanticSearchInput.types.js +1 -0
- package/dist/app/SemanticTimeline.svelte +426 -0
- package/dist/app/SemanticTimeline.svelte.d.ts +13 -0
- package/dist/app/SettingsPanel.svelte +330 -0
- package/dist/app/SettingsPanel.svelte.d.ts +12 -0
- package/dist/app/SettingsPanel.types.js +1 -0
- package/dist/app/SubCanvas.svelte +457 -0
- package/dist/app/SubCanvas.svelte.d.ts +48 -0
- package/dist/app/SubCanvas.types.js +1 -0
- package/dist/app/Sync.types.js +1 -0
- package/dist/app/SyncIndicator.svelte +219 -0
- package/dist/app/SyncIndicator.svelte.d.ts +15 -0
- package/dist/app/SyncTimeline.svelte +299 -0
- package/dist/app/SyncTimeline.svelte.d.ts +12 -0
- package/dist/app/TagCloud.svelte +287 -0
- package/dist/app/TagCloud.svelte.d.ts +12 -0
- package/dist/app/WorkModeToggle.svelte +188 -0
- package/dist/app/WorkModeToggle.svelte.d.ts +17 -0
- package/dist/data/List.svelte +104 -0
- package/dist/data/List.svelte.d.ts +18 -0
- package/dist/data/ListItem.svelte +130 -0
- package/dist/data/ListItem.svelte.d.ts +12 -0
- package/dist/data/Table.svelte +241 -0
- package/dist/data/Table.svelte.d.ts +17 -0
- package/dist/data/index.d.ts +3 -0
- package/dist/data/index.js +3 -0
- package/dist/disclosure/Accordion.svelte +48 -0
- package/dist/disclosure/Accordion.svelte.d.ts +15 -0
- package/dist/feedback/Badge.svelte +60 -0
- package/dist/feedback/Badge.svelte.d.ts +14 -0
- package/dist/feedback/Callout.svelte +52 -0
- package/dist/feedback/Callout.svelte.d.ts +12 -0
- package/dist/feedback/EmptyState.svelte +47 -0
- package/dist/feedback/EmptyState.svelte.d.ts +12 -0
- package/dist/feedback/ProgressBar.svelte +95 -0
- package/dist/feedback/ProgressBar.svelte.d.ts +16 -0
- package/dist/forms/FileUpload.svelte +99 -0
- package/dist/forms/FileUpload.svelte.d.ts +18 -0
- package/dist/forms/RadioGroup.svelte +84 -0
- package/dist/forms/RadioGroup.svelte.d.ts +19 -0
- package/dist/icons/NerdFont.svelte +44 -0
- package/dist/icons/NerdFont.svelte.d.ts +13 -0
- package/dist/icons/index.d.ts +1 -0
- package/dist/icons/index.js +1 -0
- package/dist/index.d.ts +76 -0
- package/dist/index.js +70 -6212
- package/dist/layout/Box.svelte +207 -0
- package/dist/layout/Box.svelte.d.ts +22 -0
- package/dist/layout/Sidebar.svelte +210 -0
- package/dist/layout/Sidebar.svelte.d.ts +22 -0
- package/dist/layout/SplitPane.svelte +64 -0
- package/dist/layout/SplitPane.svelte.d.ts +12 -0
- package/dist/layout/StatusBar.svelte +83 -0
- package/dist/layout/StatusBar.svelte.d.ts +12 -0
- package/dist/layout/StatusBarItem.svelte +146 -0
- package/dist/layout/StatusBarItem.svelte.d.ts +15 -0
- package/dist/layout/StatusBarSpacer.svelte +38 -0
- package/dist/layout/StatusBarSpacer.svelte.d.ts +3 -0
- package/dist/layout/Tabs.svelte +254 -0
- package/dist/layout/Tabs.svelte.d.ts +21 -0
- package/dist/layout/Tabs.types.js +1 -0
- package/dist/layout/TitleBar.svelte +422 -0
- package/dist/layout/TitleBar.svelte.d.ts +22 -0
- package/dist/layout/index.d.ts +9 -0
- package/dist/layout/index.js +8 -0
- package/dist/motion/index.d.ts +1 -0
- package/dist/motion/index.js +1 -0
- package/dist/motion/spring.js +116 -0
- package/dist/overlays/ContextMenu.svelte +268 -0
- package/dist/overlays/ContextMenu.svelte.d.ts +17 -0
- package/dist/overlays/Dialog.svelte +264 -0
- package/dist/overlays/Dialog.svelte.d.ts +20 -0
- package/dist/overlays/Menu.svelte +274 -0
- package/dist/overlays/Menu.svelte.d.ts +26 -0
- package/dist/overlays/Menu.types.js +1 -0
- package/dist/overlays/Popover.svelte +158 -0
- package/dist/overlays/Popover.svelte.d.ts +21 -0
- package/dist/overlays/Toast.svelte +179 -0
- package/dist/overlays/Toast.svelte.d.ts +19 -0
- package/dist/overlays/Tooltip.svelte +114 -0
- package/dist/overlays/Tooltip.svelte.d.ts +17 -0
- package/dist/overlays/index.d.ts +7 -0
- package/dist/overlays/index.js +6 -0
- package/dist/primitives/Button.svelte +217 -0
- package/dist/primitives/Button.svelte.d.ts +13 -0
- package/dist/primitives/ContextMenu.svelte +242 -0
- package/dist/primitives/ContextMenu.svelte.d.ts +18 -0
- package/dist/primitives/ContextMenu.types.js +1 -0
- package/dist/primitives/Input.svelte +468 -0
- package/dist/primitives/Input.svelte.d.ts +21 -0
- package/dist/primitives/MarkdownEditor.svelte +781 -0
- package/dist/primitives/MarkdownEditor.svelte.d.ts +21 -0
- package/dist/primitives/MarkdownEditor.types.js +1 -0
- package/dist/primitives/SearchInput.svelte +623 -0
- package/dist/primitives/SearchInput.svelte.d.ts +24 -0
- package/dist/primitives/Select.svelte +336 -0
- package/dist/primitives/Select.svelte.d.ts +18 -0
- package/dist/primitives/Text.svelte +177 -0
- package/dist/primitives/Text.svelte.d.ts +26 -0
- package/dist/primitives/Toggle.svelte +138 -0
- package/dist/primitives/Toggle.svelte.d.ts +9 -0
- package/dist/primitives/index.d.ts +9 -0
- package/dist/primitives/index.js +7 -0
- package/dist/primitives/search-input-types.js +1 -0
- package/dist/surfaces/ChatPane.svelte +520 -0
- package/dist/surfaces/ChatPane.svelte.d.ts +15 -0
- package/dist/surfaces/ChatPane.types.js +1 -0
- package/dist/surfaces/GlassPanel.svelte +118 -0
- package/dist/surfaces/GlassPanel.svelte.d.ts +19 -0
- package/dist/surfaces/Pane.svelte +172 -0
- package/dist/surfaces/Pane.svelte.d.ts +25 -0
- package/dist/surfaces/index.d.ts +4 -0
- package/dist/surfaces/index.js +3 -0
- package/dist/telemetry/correlation.js +26 -0
- package/dist/telemetry/index.d.ts +4 -4
- package/dist/telemetry/index.js +20 -101
- package/dist/telemetry/sampling.js +58 -0
- package/dist/telemetry/tracer.d.ts +16 -1
- package/dist/telemetry/tracer.js +112 -0
- package/dist/tokens.css +123 -0
- package/dist/tui-tokens.css +36 -0
- package/dist/useTui.js +31 -0
- package/package.json +32 -22
- package/dist/design-dojo.css +0 -1
- package/dist/enforce/index.d.ts +0 -75
- package/dist/enforce/known-components.d.ts +0 -7
- package/dist/enforce/rules/no-local-components.d.ts +0 -29
- package/dist/enforce/rules/prefer-design-dojo-imports.d.ts +0 -27
- package/dist/enforce.js +0 -132
- package/dist/lib/app/CanvasBreadcrumb.svelte.d.ts +0 -1
- package/dist/lib/app/ChatInput.svelte.d.ts +0 -1
- package/dist/lib/app/ChatView.svelte.d.ts +0 -1
- package/dist/lib/app/ConversationGraph.svelte.d.ts +0 -1
- package/dist/lib/app/FirstRunWizard.svelte.d.ts +0 -1
- package/dist/lib/app/MemorySidebar.svelte.d.ts +0 -1
- package/dist/lib/app/PeerStatusPanel.svelte.d.ts +0 -1
- package/dist/lib/app/ProcedureCanvas.svelte.d.ts +0 -1
- package/dist/lib/app/ProcedureEditor.svelte.d.ts +0 -1
- package/dist/lib/app/ProcedureInspector.svelte.d.ts +0 -1
- package/dist/lib/app/ProcedureNode.svelte.d.ts +0 -1
- package/dist/lib/app/RealmIndicator.svelte.d.ts +0 -1
- package/dist/lib/app/RealmSwitcher.svelte.d.ts +0 -1
- package/dist/lib/app/SemanticSearchInput.svelte.d.ts +0 -1
- package/dist/lib/app/SemanticTimeline.svelte.d.ts +0 -1
- package/dist/lib/app/SettingsPanel.svelte.d.ts +0 -1
- package/dist/lib/app/SubCanvas.svelte.d.ts +0 -1
- package/dist/lib/app/SyncIndicator.svelte.d.ts +0 -1
- package/dist/lib/app/SyncTimeline.svelte.d.ts +0 -1
- package/dist/lib/app/TagCloud.svelte.d.ts +0 -1
- package/dist/lib/app/WorkModeToggle.svelte.d.ts +0 -1
- package/dist/lib/data/List.svelte.d.ts +0 -1
- package/dist/lib/data/ListItem.svelte.d.ts +0 -1
- package/dist/lib/data/Table.svelte.d.ts +0 -1
- package/dist/lib/data/index.d.ts +0 -3
- package/dist/lib/disclosure/Accordion.svelte.d.ts +0 -1
- package/dist/lib/feedback/Badge.svelte.d.ts +0 -1
- package/dist/lib/feedback/Callout.svelte.d.ts +0 -1
- package/dist/lib/feedback/EmptyState.svelte.d.ts +0 -1
- package/dist/lib/feedback/ProgressBar.svelte.d.ts +0 -1
- package/dist/lib/forms/FileUpload.svelte.d.ts +0 -1
- package/dist/lib/forms/RadioGroup.svelte.d.ts +0 -1
- package/dist/lib/icons/NerdFont.svelte.d.ts +0 -1
- package/dist/lib/icons/index.d.ts +0 -1
- package/dist/lib/index.d.ts +0 -76
- package/dist/lib/layout/Box.svelte.d.ts +0 -1
- package/dist/lib/layout/Sidebar.svelte.d.ts +0 -1
- package/dist/lib/layout/SplitPane.svelte.d.ts +0 -1
- package/dist/lib/layout/StatusBar.svelte.d.ts +0 -1
- package/dist/lib/layout/StatusBarItem.svelte.d.ts +0 -1
- package/dist/lib/layout/StatusBarSpacer.svelte.d.ts +0 -1
- package/dist/lib/layout/Tabs.svelte.d.ts +0 -1
- package/dist/lib/layout/TitleBar.svelte.d.ts +0 -1
- package/dist/lib/layout/index.d.ts +0 -9
- package/dist/lib/motion/index.d.ts +0 -1
- package/dist/lib/overlays/ContextMenu.svelte.d.ts +0 -1
- package/dist/lib/overlays/Dialog.svelte.d.ts +0 -1
- package/dist/lib/overlays/Menu.svelte.d.ts +0 -1
- package/dist/lib/overlays/Popover.svelte.d.ts +0 -1
- package/dist/lib/overlays/Toast.svelte.d.ts +0 -1
- package/dist/lib/overlays/Tooltip.svelte.d.ts +0 -1
- package/dist/lib/overlays/index.d.ts +0 -7
- package/dist/lib/primitives/Button.svelte.d.ts +0 -1
- package/dist/lib/primitives/ContextMenu.svelte.d.ts +0 -1
- package/dist/lib/primitives/Input.svelte.d.ts +0 -1
- package/dist/lib/primitives/MarkdownEditor.svelte.d.ts +0 -1
- package/dist/lib/primitives/SearchInput.svelte.d.ts +0 -1
- package/dist/lib/primitives/Select.svelte.d.ts +0 -1
- package/dist/lib/primitives/Text.svelte.d.ts +0 -1
- package/dist/lib/primitives/Toggle.svelte.d.ts +0 -1
- package/dist/lib/primitives/index.d.ts +0 -9
- package/dist/lib/surfaces/ChatPane.svelte.d.ts +0 -1
- package/dist/lib/surfaces/GlassPanel.svelte.d.ts +0 -1
- package/dist/lib/surfaces/Pane.svelte.d.ts +0 -1
- package/dist/lib/surfaces/index.d.ts +0 -4
- /package/dist/{lib/app → app}/CanvasBreadcrumb.types.d.ts +0 -0
- /package/dist/{lib/app → app}/ChatView.types.d.ts +0 -0
- /package/dist/{lib/app → app}/FirstRunWizard.types.d.ts +0 -0
- /package/dist/{lib/app → app}/MemorySidebar.types.d.ts +0 -0
- /package/dist/{lib/app → app}/ProcedureCanvas.types.d.ts +0 -0
- /package/dist/{lib/app → app}/ProcedureEditor.types.d.ts +0 -0
- /package/dist/{lib/app → app}/Realm.types.d.ts +0 -0
- /package/dist/{lib/app → app}/SemanticConversation.types.d.ts +0 -0
- /package/dist/{lib/app → app}/SemanticSearchInput.types.d.ts +0 -0
- /package/dist/{lib/app → app}/SettingsPanel.types.d.ts +0 -0
- /package/dist/{lib/app → app}/SubCanvas.types.d.ts +0 -0
- /package/dist/{lib/app → app}/Sync.types.d.ts +0 -0
- /package/dist/{lib/layout → layout}/Tabs.types.d.ts +0 -0
- /package/dist/{lib/motion → motion}/spring.d.ts +0 -0
- /package/dist/{lib/overlays → overlays}/Menu.types.d.ts +0 -0
- /package/dist/{lib/primitives → primitives}/ContextMenu.types.d.ts +0 -0
- /package/dist/{lib/primitives → primitives}/MarkdownEditor.types.d.ts +0 -0
- /package/dist/{lib/primitives → primitives}/search-input-types.d.ts +0 -0
- /package/dist/{lib/surfaces → surfaces}/ChatPane.types.d.ts +0 -0
- /package/dist/{lib/useTui.d.ts → useTui.d.ts} +0 -0
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Pane — A named, scrollable content region. The atomic layout unit.
|
|
3
|
+
|
|
4
|
+
GUI mode: Flexbox container with optional scroll and title.
|
|
5
|
+
TUI mode: Box-drawing–style border with bold title, scrollable area.
|
|
6
|
+
Maps to ratatui Block::default().borders(Borders::ALL).title(…)
|
|
7
|
+
-->
|
|
8
|
+
<script lang="ts">
|
|
9
|
+
import { provideTui, useTui } from "../useTui.js";
|
|
10
|
+
import type { Snippet } from "svelte";
|
|
11
|
+
|
|
12
|
+
interface Props {
|
|
13
|
+
/** Enable TUI mode: box-drawing border, terminal-safe colors, no decorative CSS. */
|
|
14
|
+
tui?: boolean;
|
|
15
|
+
/** Title shown in the top border (TUI) or as a label above content (GUI). */
|
|
16
|
+
title?: string;
|
|
17
|
+
/** Allow content to scroll vertically. */
|
|
18
|
+
scrollable?: boolean;
|
|
19
|
+
/** Flex-grow weight for proportional sizing inside SplitPane. */
|
|
20
|
+
flex?: number;
|
|
21
|
+
/** Override width. Numbers are treated as pixels. */
|
|
22
|
+
width?: string | number;
|
|
23
|
+
/** Override height. Numbers are treated as pixels. */
|
|
24
|
+
height?: string | number;
|
|
25
|
+
/**
|
|
26
|
+
* Show a border around the pane.
|
|
27
|
+
* Default: true in TUI mode, false in GUI mode.
|
|
28
|
+
*/
|
|
29
|
+
border?: boolean;
|
|
30
|
+
class?: string;
|
|
31
|
+
children: Snippet;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
let {
|
|
35
|
+
tui = false,
|
|
36
|
+
title = "",
|
|
37
|
+
scrollable = false,
|
|
38
|
+
flex,
|
|
39
|
+
width,
|
|
40
|
+
height,
|
|
41
|
+
border,
|
|
42
|
+
class: className = "",
|
|
43
|
+
children,
|
|
44
|
+
}: Props = $props();
|
|
45
|
+
|
|
46
|
+
const getTuiCtx = useTui();
|
|
47
|
+
const isTui = $derived(tui || getTuiCtx());
|
|
48
|
+
|
|
49
|
+
// Propagate TUI mode to nested children
|
|
50
|
+
provideTui(() => isTui);
|
|
51
|
+
|
|
52
|
+
const showBorder = $derived(border !== undefined ? border : isTui);
|
|
53
|
+
|
|
54
|
+
const widthStyle = $derived(
|
|
55
|
+
width !== undefined ? (typeof width === "number" ? `${width}px` : width) : undefined,
|
|
56
|
+
);
|
|
57
|
+
const heightStyle = $derived(
|
|
58
|
+
height !== undefined ? (typeof height === "number" ? `${height}px` : height) : undefined,
|
|
59
|
+
);
|
|
60
|
+
const flexStyle = $derived(flex !== undefined ? String(flex) : undefined);
|
|
61
|
+
</script>
|
|
62
|
+
|
|
63
|
+
{#if isTui}
|
|
64
|
+
<div
|
|
65
|
+
class="pane-tui {className}"
|
|
66
|
+
class:pane-tui--border={showBorder}
|
|
67
|
+
style:flex-grow={flexStyle}
|
|
68
|
+
style:width={widthStyle}
|
|
69
|
+
style:height={heightStyle}
|
|
70
|
+
>
|
|
71
|
+
{#if title && showBorder}
|
|
72
|
+
<span class="pane-tui__title">{title}</span>
|
|
73
|
+
{/if}
|
|
74
|
+
<div class="pane-tui__content" class:pane-tui__content--scroll={scrollable}>
|
|
75
|
+
{@render children()}
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
78
|
+
{:else}
|
|
79
|
+
<div
|
|
80
|
+
class="pane-gui {className}"
|
|
81
|
+
class:pane-gui--border={showBorder}
|
|
82
|
+
style:flex-grow={flexStyle}
|
|
83
|
+
style:width={widthStyle}
|
|
84
|
+
style:height={heightStyle}
|
|
85
|
+
>
|
|
86
|
+
{#if title}
|
|
87
|
+
<div class="pane-gui__title">{title}</div>
|
|
88
|
+
{/if}
|
|
89
|
+
<div class="pane-gui__content" class:pane-gui__content--scroll={scrollable}>
|
|
90
|
+
{@render children()}
|
|
91
|
+
</div>
|
|
92
|
+
</div>
|
|
93
|
+
{/if}
|
|
94
|
+
|
|
95
|
+
<style>
|
|
96
|
+
/* ===== GUI mode ===== */
|
|
97
|
+
.pane-gui {
|
|
98
|
+
display: flex;
|
|
99
|
+
flex-direction: column;
|
|
100
|
+
min-width: 0;
|
|
101
|
+
min-height: 0;
|
|
102
|
+
overflow: hidden;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.pane-gui--border {
|
|
106
|
+
border: 1px solid var(--color-border, #2a2a2a);
|
|
107
|
+
border-radius: var(--radius-md, 10px);
|
|
108
|
+
padding: var(--space-4, 16px);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.pane-gui__title {
|
|
112
|
+
font-size: var(--text-sm, 14px);
|
|
113
|
+
font-weight: 600;
|
|
114
|
+
color: var(--color-text-muted, #888888);
|
|
115
|
+
margin-bottom: var(--space-2, 8px);
|
|
116
|
+
text-transform: uppercase;
|
|
117
|
+
letter-spacing: 0.05em;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.pane-gui__content {
|
|
121
|
+
flex: 1;
|
|
122
|
+
min-height: 0;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.pane-gui__content--scroll {
|
|
126
|
+
overflow-y: auto;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/* ===== TUI mode ===== */
|
|
130
|
+
.pane-tui {
|
|
131
|
+
display: flex;
|
|
132
|
+
flex-direction: column;
|
|
133
|
+
min-width: 0;
|
|
134
|
+
min-height: 0;
|
|
135
|
+
font-family: var(--font-mono, monospace);
|
|
136
|
+
color: var(--tui-text, #e0e0e0);
|
|
137
|
+
background: var(--tui-surface, #16213e);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.pane-tui--border {
|
|
141
|
+
position: relative;
|
|
142
|
+
border: 1px solid var(--tui-border, #0f3460);
|
|
143
|
+
padding: var(--space-4, 16px);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.pane-tui--border:has(.pane-tui__title) {
|
|
147
|
+
padding-top: calc(var(--space-4, 16px) + 0.9em);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.pane-tui__title {
|
|
151
|
+
position: absolute;
|
|
152
|
+
top: -0.65em;
|
|
153
|
+
left: 1ch;
|
|
154
|
+
background: var(--tui-surface, #16213e);
|
|
155
|
+
padding: 0 1ch;
|
|
156
|
+
color: var(--tui-accent, #00d4ff);
|
|
157
|
+
font-weight: bold;
|
|
158
|
+
font-size: var(--text-sm, 14px);
|
|
159
|
+
font-family: var(--font-mono, monospace);
|
|
160
|
+
white-space: nowrap;
|
|
161
|
+
user-select: none;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.pane-tui__content {
|
|
165
|
+
flex: 1;
|
|
166
|
+
min-height: 0;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
.pane-tui__content--scroll {
|
|
170
|
+
overflow-y: auto;
|
|
171
|
+
}
|
|
172
|
+
</style>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Snippet } from "svelte";
|
|
2
|
+
interface Props {
|
|
3
|
+
/** Enable TUI mode: box-drawing border, terminal-safe colors, no decorative CSS. */
|
|
4
|
+
tui?: boolean;
|
|
5
|
+
/** Title shown in the top border (TUI) or as a label above content (GUI). */
|
|
6
|
+
title?: string;
|
|
7
|
+
/** Allow content to scroll vertically. */
|
|
8
|
+
scrollable?: boolean;
|
|
9
|
+
/** Flex-grow weight for proportional sizing inside SplitPane. */
|
|
10
|
+
flex?: number;
|
|
11
|
+
/** Override width. Numbers are treated as pixels. */
|
|
12
|
+
width?: string | number;
|
|
13
|
+
/** Override height. Numbers are treated as pixels. */
|
|
14
|
+
height?: string | number;
|
|
15
|
+
/**
|
|
16
|
+
* Show a border around the pane.
|
|
17
|
+
* Default: true in TUI mode, false in GUI mode.
|
|
18
|
+
*/
|
|
19
|
+
border?: boolean;
|
|
20
|
+
class?: string;
|
|
21
|
+
children: Snippet;
|
|
22
|
+
}
|
|
23
|
+
declare const Pane: import("svelte").Component<Props, {}, "">;
|
|
24
|
+
type Pane = ReturnType<typeof Pane>;
|
|
25
|
+
export default Pane;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* correlation — Lightweight correlation ID utilities for design-dojo telemetry.
|
|
3
|
+
*
|
|
4
|
+
* Correlation IDs link related spans across component boundaries and async
|
|
5
|
+
* operations without including any personally-identifiable information.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Generate a UUID v4 correlation ID suitable for use in URLs and logs.
|
|
9
|
+
* Uses crypto.randomUUID when available, falls back to crypto.getRandomValues.
|
|
10
|
+
*/
|
|
11
|
+
export function generateCorrelationId() {
|
|
12
|
+
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
13
|
+
return crypto.randomUUID();
|
|
14
|
+
}
|
|
15
|
+
if (typeof crypto !== "undefined" && typeof crypto.getRandomValues === "function") {
|
|
16
|
+
const bytes = new Uint8Array(16);
|
|
17
|
+
crypto.getRandomValues(bytes);
|
|
18
|
+
// Format as UUID v4
|
|
19
|
+
bytes[6] = (bytes[6] & 0x0f) | 0x40;
|
|
20
|
+
bytes[8] = (bytes[8] & 0x3f) | 0x80;
|
|
21
|
+
const hex = Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
22
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
23
|
+
}
|
|
24
|
+
// SSR/non-crypto fallback (non-unique, good enough for local dev)
|
|
25
|
+
return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
|
|
26
|
+
}
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* tracer.recordInteraction("click", "success");
|
|
16
16
|
* ```
|
|
17
17
|
*/
|
|
18
|
-
export { createComponentTracer, SpanAttributes } from
|
|
19
|
-
export type { ComponentTracer, ComponentAttributes, EventOutcome } from
|
|
20
|
-
export { shouldSample, TELEMETRY_ENABLED, SAMPLE_RATE } from
|
|
21
|
-
export { generateCorrelationId } from
|
|
18
|
+
export { createComponentTracer, SpanAttributes } from "./tracer.js";
|
|
19
|
+
export type { ComponentTracer, ComponentAttributes, EventOutcome } from "./tracer.js";
|
|
20
|
+
export { shouldSample, TELEMETRY_ENABLED, SAMPLE_RATE } from "./sampling.js";
|
|
21
|
+
export { generateCorrelationId } from "./correlation.js";
|
package/dist/telemetry/index.js
CHANGED
|
@@ -1,101 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
return d ? u >= 1 ? !0 : u <= 0 ? !1 : Math.random() < u : !1;
|
|
22
|
-
}
|
|
23
|
-
function S() {
|
|
24
|
-
if (typeof crypto < "u" && typeof crypto.randomUUID == "function")
|
|
25
|
-
return crypto.randomUUID();
|
|
26
|
-
if (typeof crypto < "u" && typeof crypto.getRandomValues == "function") {
|
|
27
|
-
const t = new Uint8Array(16);
|
|
28
|
-
crypto.getRandomValues(t), t[6] = t[6] & 15 | 64, t[8] = t[8] & 63 | 128;
|
|
29
|
-
const e = Array.from(t).map((a) => a.toString(16).padStart(2, "0")).join("");
|
|
30
|
-
return `${e.slice(0, 8)}-${e.slice(8, 12)}-${e.slice(12, 16)}-${e.slice(16, 20)}-${e.slice(20)}`;
|
|
31
|
-
}
|
|
32
|
-
return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
|
|
33
|
-
}
|
|
34
|
-
const A = "@plures/design-dojo", s = {
|
|
35
|
-
COMPONENT_NAME: "ui.component.name",
|
|
36
|
-
COMPONENT_VARIANT: "ui.component.variant",
|
|
37
|
-
COMPONENT_STATE: "ui.component.state",
|
|
38
|
-
EVENT_NAME: "ui.event.name",
|
|
39
|
-
EVENT_OUTCOME: "ui.event.outcome",
|
|
40
|
-
CORRELATION_ID: "ui.correlation_id"
|
|
41
|
-
};
|
|
42
|
-
function R(t, e = {}) {
|
|
43
|
-
const a = f.getTracer(A), T = S();
|
|
44
|
-
function E(r = {}) {
|
|
45
|
-
const n = {};
|
|
46
|
-
e.extra && Object.assign(n, e.extra), r.extra && Object.assign(n, r.extra), n[s.COMPONENT_NAME] = t, n[s.CORRELATION_ID] = T;
|
|
47
|
-
const o = r.variant ?? e.variant, i = r.state ?? e.state;
|
|
48
|
-
return o !== void 0 && (n[s.COMPONENT_VARIANT] = o), i !== void 0 && (n[s.COMPONENT_STATE] = i), n;
|
|
49
|
-
}
|
|
50
|
-
return {
|
|
51
|
-
otel: a,
|
|
52
|
-
correlationId: T,
|
|
53
|
-
recordInteraction(r, n, o = {}) {
|
|
54
|
-
if (!p()) return;
|
|
55
|
-
const i = a.startSpan(`${t}.${r}`, {
|
|
56
|
-
attributes: {
|
|
57
|
-
...E(o),
|
|
58
|
-
[s.EVENT_NAME]: r,
|
|
59
|
-
[s.EVENT_OUTCOME]: n
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
n === "error" && i.setStatus({ code: N.ERROR }), i.end();
|
|
63
|
-
},
|
|
64
|
-
startInteractionSpan(r, n = {}) {
|
|
65
|
-
if (!p())
|
|
66
|
-
return { span: f.wrapSpanContext(O), finish: () => {
|
|
67
|
-
} };
|
|
68
|
-
const o = a.startSpan(`${t}.${r}`, {
|
|
69
|
-
attributes: {
|
|
70
|
-
...E(n),
|
|
71
|
-
[s.EVENT_NAME]: r
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
return {
|
|
75
|
-
span: o,
|
|
76
|
-
finish(i, c) {
|
|
77
|
-
o.setAttribute(s.EVENT_OUTCOME, i), i === "error" && (o.setStatus({
|
|
78
|
-
code: N.ERROR,
|
|
79
|
-
message: c == null ? void 0 : c.message
|
|
80
|
-
}), c && o.recordException(c)), o.end();
|
|
81
|
-
}
|
|
82
|
-
};
|
|
83
|
-
},
|
|
84
|
-
startRenderSpan(r = {}) {
|
|
85
|
-
if (!p()) return () => {
|
|
86
|
-
};
|
|
87
|
-
const n = a.startSpan(`${t}.render`, {
|
|
88
|
-
attributes: E(r)
|
|
89
|
-
});
|
|
90
|
-
return () => n.end();
|
|
91
|
-
}
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
export {
|
|
95
|
-
u as SAMPLE_RATE,
|
|
96
|
-
s as SpanAttributes,
|
|
97
|
-
d as TELEMETRY_ENABLED,
|
|
98
|
-
R as createComponentTracer,
|
|
99
|
-
S as generateCorrelationId,
|
|
100
|
-
p as shouldSample
|
|
101
|
-
};
|
|
1
|
+
/**
|
|
2
|
+
* @plures/design-dojo — telemetry module
|
|
3
|
+
*
|
|
4
|
+
* Provides OpenTelemetry instrumentation utilities for design-dojo components.
|
|
5
|
+
*
|
|
6
|
+
* The module uses `@opentelemetry/api` which is a no-op by default — spans are
|
|
7
|
+
* only recorded once a consumer app registers an OTel SDK provider. See
|
|
8
|
+
* docs/telemetry.md for setup instructions.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { createComponentTracer } from "@plures/design-dojo/telemetry";
|
|
13
|
+
*
|
|
14
|
+
* const tracer = createComponentTracer("MyButton", { variant: "solid" });
|
|
15
|
+
* tracer.recordInteraction("click", "success");
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export { createComponentTracer, SpanAttributes } from "./tracer.js";
|
|
19
|
+
export { shouldSample, TELEMETRY_ENABLED, SAMPLE_RATE } from "./sampling.js";
|
|
20
|
+
export { generateCorrelationId } from "./correlation.js";
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* sampling — Sampling controls for design-dojo telemetry.
|
|
3
|
+
*
|
|
4
|
+
* Consumers configure sampling via Vite environment variables, which are
|
|
5
|
+
* resolved at build time and inlined via `import.meta.env`:
|
|
6
|
+
*
|
|
7
|
+
* VITE_OTEL_SAMPLE_RATE=0.1 (10% of spans recorded, default 1.0)
|
|
8
|
+
* VITE_OTEL_ENABLED=false (disable telemetry entirely)
|
|
9
|
+
*
|
|
10
|
+
* These values are read once at module initialisation so they impose no
|
|
11
|
+
* per-span overhead in production.
|
|
12
|
+
*/
|
|
13
|
+
/** Whether telemetry is enabled at all. Defaults to `true`. */
|
|
14
|
+
export const TELEMETRY_ENABLED = (() => {
|
|
15
|
+
try {
|
|
16
|
+
// Vite replaces import.meta.env.* at build time; cast via unknown to satisfy
|
|
17
|
+
// strict TS outside of a vite/client type context.
|
|
18
|
+
const env = import.meta.env;
|
|
19
|
+
if (env?.VITE_OTEL_ENABLED === "false")
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
// Not a Vite environment — treat as enabled.
|
|
24
|
+
}
|
|
25
|
+
return true;
|
|
26
|
+
})();
|
|
27
|
+
/**
|
|
28
|
+
* Fractional sample rate in `[0, 1]`. `1.0` records every span; `0` records
|
|
29
|
+
* none. Controlled by `VITE_OTEL_SAMPLE_RATE` (build-time env var).
|
|
30
|
+
*/
|
|
31
|
+
export const SAMPLE_RATE = (() => {
|
|
32
|
+
try {
|
|
33
|
+
const env = import.meta.env;
|
|
34
|
+
const raw = env?.VITE_OTEL_SAMPLE_RATE;
|
|
35
|
+
if (raw !== undefined) {
|
|
36
|
+
const parsed = parseFloat(raw);
|
|
37
|
+
if (!isNaN(parsed) && parsed >= 0 && parsed <= 1)
|
|
38
|
+
return parsed;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
// Not a Vite environment — use default.
|
|
43
|
+
}
|
|
44
|
+
return 1.0;
|
|
45
|
+
})();
|
|
46
|
+
/**
|
|
47
|
+
* Returns `true` when this particular call-site should be recorded.
|
|
48
|
+
* Used by all span helpers to honour the configured sample rate.
|
|
49
|
+
*/
|
|
50
|
+
export function shouldSample() {
|
|
51
|
+
if (!TELEMETRY_ENABLED)
|
|
52
|
+
return false;
|
|
53
|
+
if (SAMPLE_RATE >= 1.0)
|
|
54
|
+
return true;
|
|
55
|
+
if (SAMPLE_RATE <= 0)
|
|
56
|
+
return false;
|
|
57
|
+
return Math.random() < SAMPLE_RATE;
|
|
58
|
+
}
|
|
@@ -1,4 +1,19 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* tracer — Component tracer factory for design-dojo telemetry.
|
|
3
|
+
*
|
|
4
|
+
* Uses `@opentelemetry/api` which is a zero-overhead no-op when no SDK is
|
|
5
|
+
* registered. Consumer apps wire up their preferred SDK in
|
|
6
|
+
* `hooks.client.ts` / `hooks.server.ts` (see docs/telemetry.md).
|
|
7
|
+
*
|
|
8
|
+
* Span attribute conventions (no PII):
|
|
9
|
+
* ui.component.name — e.g. "Button"
|
|
10
|
+
* ui.component.variant — e.g. "solid" | "ghost"
|
|
11
|
+
* ui.component.state — e.g. "disabled" | "focused"
|
|
12
|
+
* ui.event.name — e.g. "click" | "change"
|
|
13
|
+
* ui.event.outcome — "success" | "error" | "cancelled"
|
|
14
|
+
* ui.correlation_id — UUID v4 string linking related spans
|
|
15
|
+
*/
|
|
16
|
+
import { type Tracer, type Span, type Attributes } from "@opentelemetry/api";
|
|
2
17
|
/** Well-known attribute keys (keeps typos out of call sites). */
|
|
3
18
|
export declare const SpanAttributes: {
|
|
4
19
|
readonly COMPONENT_NAME: "ui.component.name";
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* tracer — Component tracer factory for design-dojo telemetry.
|
|
3
|
+
*
|
|
4
|
+
* Uses `@opentelemetry/api` which is a zero-overhead no-op when no SDK is
|
|
5
|
+
* registered. Consumer apps wire up their preferred SDK in
|
|
6
|
+
* `hooks.client.ts` / `hooks.server.ts` (see docs/telemetry.md).
|
|
7
|
+
*
|
|
8
|
+
* Span attribute conventions (no PII):
|
|
9
|
+
* ui.component.name — e.g. "Button"
|
|
10
|
+
* ui.component.variant — e.g. "solid" | "ghost"
|
|
11
|
+
* ui.component.state — e.g. "disabled" | "focused"
|
|
12
|
+
* ui.event.name — e.g. "click" | "change"
|
|
13
|
+
* ui.event.outcome — "success" | "error" | "cancelled"
|
|
14
|
+
* ui.correlation_id — UUID v4 string linking related spans
|
|
15
|
+
*/
|
|
16
|
+
import { trace, SpanStatusCode, INVALID_SPAN_CONTEXT, } from "@opentelemetry/api";
|
|
17
|
+
import { shouldSample } from "./sampling.js";
|
|
18
|
+
import { generateCorrelationId } from "./correlation.js";
|
|
19
|
+
/** Instrumentation scope name for all design-dojo spans. */
|
|
20
|
+
const INSTRUMENTATION_NAME = "@plures/design-dojo";
|
|
21
|
+
/** Well-known attribute keys (keeps typos out of call sites). */
|
|
22
|
+
export const SpanAttributes = {
|
|
23
|
+
COMPONENT_NAME: "ui.component.name",
|
|
24
|
+
COMPONENT_VARIANT: "ui.component.variant",
|
|
25
|
+
COMPONENT_STATE: "ui.component.state",
|
|
26
|
+
EVENT_NAME: "ui.event.name",
|
|
27
|
+
EVENT_OUTCOME: "ui.event.outcome",
|
|
28
|
+
CORRELATION_ID: "ui.correlation_id",
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Create a `ComponentTracer` bound to `componentName`.
|
|
32
|
+
*
|
|
33
|
+
* @param componentName PascalCase component name, e.g. "Button"
|
|
34
|
+
* @param defaultAttrs Attributes applied to every span from this tracer
|
|
35
|
+
*/
|
|
36
|
+
export function createComponentTracer(componentName, defaultAttrs = {}) {
|
|
37
|
+
const otel = trace.getTracer(INSTRUMENTATION_NAME);
|
|
38
|
+
const correlationId = generateCorrelationId();
|
|
39
|
+
function baseAttributes(attrs = {}) {
|
|
40
|
+
const merged = {};
|
|
41
|
+
// Merge default extras first, then caller-provided extras so they can override; reserved keys below always win.
|
|
42
|
+
if (defaultAttrs.extra)
|
|
43
|
+
Object.assign(merged, defaultAttrs.extra);
|
|
44
|
+
if (attrs.extra)
|
|
45
|
+
Object.assign(merged, attrs.extra);
|
|
46
|
+
// Enforce required convention attributes last.
|
|
47
|
+
merged[SpanAttributes.COMPONENT_NAME] = componentName;
|
|
48
|
+
merged[SpanAttributes.CORRELATION_ID] = correlationId;
|
|
49
|
+
const variant = attrs.variant ?? defaultAttrs.variant;
|
|
50
|
+
const state = attrs.state ?? defaultAttrs.state;
|
|
51
|
+
if (variant !== undefined)
|
|
52
|
+
merged[SpanAttributes.COMPONENT_VARIANT] = variant;
|
|
53
|
+
if (state !== undefined)
|
|
54
|
+
merged[SpanAttributes.COMPONENT_STATE] = state;
|
|
55
|
+
return merged;
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
otel,
|
|
59
|
+
correlationId,
|
|
60
|
+
recordInteraction(eventName, outcome, attrs = {}) {
|
|
61
|
+
if (!shouldSample())
|
|
62
|
+
return;
|
|
63
|
+
const span = otel.startSpan(`${componentName}.${eventName}`, {
|
|
64
|
+
attributes: {
|
|
65
|
+
...baseAttributes(attrs),
|
|
66
|
+
[SpanAttributes.EVENT_NAME]: eventName,
|
|
67
|
+
[SpanAttributes.EVENT_OUTCOME]: outcome,
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
if (outcome === "error") {
|
|
71
|
+
span.setStatus({ code: SpanStatusCode.ERROR });
|
|
72
|
+
}
|
|
73
|
+
span.end();
|
|
74
|
+
},
|
|
75
|
+
startInteractionSpan(eventName, attrs = {}) {
|
|
76
|
+
if (!shouldSample()) {
|
|
77
|
+
// Return a non-recording span so no span is emitted regardless of SDK.
|
|
78
|
+
const noopSpan = trace.wrapSpanContext(INVALID_SPAN_CONTEXT);
|
|
79
|
+
return { span: noopSpan, finish: () => { } };
|
|
80
|
+
}
|
|
81
|
+
const span = otel.startSpan(`${componentName}.${eventName}`, {
|
|
82
|
+
attributes: {
|
|
83
|
+
...baseAttributes(attrs),
|
|
84
|
+
[SpanAttributes.EVENT_NAME]: eventName,
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
return {
|
|
88
|
+
span,
|
|
89
|
+
finish(outcome, error) {
|
|
90
|
+
span.setAttribute(SpanAttributes.EVENT_OUTCOME, outcome);
|
|
91
|
+
if (outcome === "error") {
|
|
92
|
+
span.setStatus({
|
|
93
|
+
code: SpanStatusCode.ERROR,
|
|
94
|
+
message: error?.message,
|
|
95
|
+
});
|
|
96
|
+
if (error)
|
|
97
|
+
span.recordException(error);
|
|
98
|
+
}
|
|
99
|
+
span.end();
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
},
|
|
103
|
+
startRenderSpan(attrs = {}) {
|
|
104
|
+
if (!shouldSample())
|
|
105
|
+
return () => { };
|
|
106
|
+
const span = otel.startSpan(`${componentName}.render`, {
|
|
107
|
+
attributes: baseAttributes(attrs),
|
|
108
|
+
});
|
|
109
|
+
return () => span.end();
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
}
|
package/dist/tokens.css
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Pares Design Tokens
|
|
3
|
+
*
|
|
4
|
+
* The single source of truth for all visual values.
|
|
5
|
+
* No component should use raw values — only tokens.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
:root {
|
|
9
|
+
/* ===== Spacing (4px grid) ===== */
|
|
10
|
+
--space-0: 0px;
|
|
11
|
+
--space-1: 4px;
|
|
12
|
+
--space-2: 8px;
|
|
13
|
+
--space-3: 12px;
|
|
14
|
+
--space-4: 16px;
|
|
15
|
+
--space-6: 24px;
|
|
16
|
+
--space-8: 32px;
|
|
17
|
+
--space-12: 48px;
|
|
18
|
+
--space-16: 64px;
|
|
19
|
+
|
|
20
|
+
/* ===== Typography (Major Third 1.25×) ===== */
|
|
21
|
+
--text-xs: 12px;
|
|
22
|
+
--text-sm: 14px;
|
|
23
|
+
--text-base: 16px;
|
|
24
|
+
--text-lg: 20px;
|
|
25
|
+
--text-xl: 24px;
|
|
26
|
+
--text-2xl: 30px;
|
|
27
|
+
--text-3xl: 36px;
|
|
28
|
+
--text-4xl: 48px;
|
|
29
|
+
|
|
30
|
+
--leading-tight: 1.25;
|
|
31
|
+
--leading-normal: 1.5;
|
|
32
|
+
--leading-relaxed: 1.625;
|
|
33
|
+
|
|
34
|
+
--font-sans: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", system-ui, sans-serif;
|
|
35
|
+
--font-mono: "JetBrains Mono", "SF Mono", "Cascadia Code", "Fira Code", monospace;
|
|
36
|
+
|
|
37
|
+
/* ===== Border Radius ===== */
|
|
38
|
+
--radius-sm: 6px;
|
|
39
|
+
--radius-md: 10px;
|
|
40
|
+
--radius-lg: 16px;
|
|
41
|
+
--radius-xl: 24px;
|
|
42
|
+
--radius-full: 9999px;
|
|
43
|
+
|
|
44
|
+
/* ===== Shadows / Elevation ===== */
|
|
45
|
+
--shadow-sm: 0 1px 2px rgba(0,0,0,0.05), 0 1px 3px rgba(0,0,0,0.1);
|
|
46
|
+
--shadow-md: 0 4px 6px rgba(0,0,0,0.05), 0 10px 15px rgba(0,0,0,0.1);
|
|
47
|
+
--shadow-lg: 0 10px 25px rgba(0,0,0,0.1), 0 20px 48px rgba(0,0,0,0.15);
|
|
48
|
+
|
|
49
|
+
/* Elevation: 0 = flush, 1 = card, 2 = popover, 3 = modal */
|
|
50
|
+
--elevation-0: none;
|
|
51
|
+
--elevation-1: var(--shadow-sm);
|
|
52
|
+
--elevation-2: var(--shadow-md);
|
|
53
|
+
--elevation-3: var(--shadow-lg);
|
|
54
|
+
|
|
55
|
+
/* ===== Focus ring ===== */
|
|
56
|
+
--focus-ring-width: 3px;
|
|
57
|
+
--focus-ring-offset: 2px;
|
|
58
|
+
|
|
59
|
+
/* ===== Selection ===== */
|
|
60
|
+
--color-selection-bg: rgba(99,102,241,0.35);
|
|
61
|
+
--color-selection-text: inherit;
|
|
62
|
+
|
|
63
|
+
/* ===== Alpha layers ===== */
|
|
64
|
+
--alpha-5: rgba(255,255,255, 0.05);
|
|
65
|
+
--alpha-10: rgba(255,255,255, 0.10);
|
|
66
|
+
--alpha-20: rgba(255,255,255, 0.20);
|
|
67
|
+
--alpha-40: rgba(255,255,255, 0.40);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/* ===== Dark Theme (default) ===== */
|
|
71
|
+
:root, [data-theme="dark"] {
|
|
72
|
+
--surface-0: #0a0a0a;
|
|
73
|
+
--surface-1: #141414;
|
|
74
|
+
--surface-2: #1e1e1e;
|
|
75
|
+
--surface-3: rgba(0,0,0,0.6);
|
|
76
|
+
|
|
77
|
+
--color-text: #e8e8e8;
|
|
78
|
+
--color-text-muted: #888888;
|
|
79
|
+
--color-text-subtle: #555555;
|
|
80
|
+
--color-accent: #6366f1;
|
|
81
|
+
--color-accent-hover:#818cf8;
|
|
82
|
+
--color-success: #22c55e;
|
|
83
|
+
--color-warning: #f59e0b;
|
|
84
|
+
--color-danger: #ef4444;
|
|
85
|
+
--color-info: #3b82f6;
|
|
86
|
+
--color-border: #2a2a2a;
|
|
87
|
+
--color-focus-ring: #818cf8;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/* ===== Light Theme ===== */
|
|
91
|
+
[data-theme="light"] {
|
|
92
|
+
--surface-0: #ffffff;
|
|
93
|
+
--surface-1: #f5f5f5;
|
|
94
|
+
--surface-2: #eeeeee;
|
|
95
|
+
--surface-3: rgba(0,0,0,0.3);
|
|
96
|
+
|
|
97
|
+
--color-text: #1a1a1a;
|
|
98
|
+
--color-text-muted: #666666;
|
|
99
|
+
--color-text-subtle: #999999;
|
|
100
|
+
--color-accent: #4f46e5;
|
|
101
|
+
--color-accent-hover:#6366f1;
|
|
102
|
+
--color-success: #16a34a;
|
|
103
|
+
--color-warning: #d97706;
|
|
104
|
+
--color-danger: #dc2626;
|
|
105
|
+
--color-info: #2563eb;
|
|
106
|
+
--color-border: #e0e0e0;
|
|
107
|
+
--color-focus-ring: #4f46e5;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/* ===== Reduced Motion ===== */
|
|
111
|
+
@media (prefers-reduced-motion: reduce) {
|
|
112
|
+
*, *::before, *::after {
|
|
113
|
+
animation-duration: 0.01ms !important;
|
|
114
|
+
animation-iteration-count: 1 !important;
|
|
115
|
+
transition-duration: 0.01ms !important;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/* ===== Selection ===== */
|
|
120
|
+
::selection {
|
|
121
|
+
background: var(--color-selection-bg, rgba(99,102,241,0.35));
|
|
122
|
+
color: var(--color-selection-text, inherit);
|
|
123
|
+
}
|