@dorsk/tsumikit 0.22.0 → 0.24.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 +151 -8
- package/dist/components/atoms/Button.svelte +121 -12
- package/dist/components/atoms/Button.svelte.d.ts +4 -0
- package/dist/components/atoms/Scrim.svelte +81 -0
- package/dist/components/atoms/Scrim.svelte.d.ts +14 -0
- package/dist/components/layouts/Cluster.svelte +33 -0
- package/dist/components/layouts/Cluster.svelte.d.ts +1 -0
- package/dist/components/layouts/ResizablePanel.svelte +238 -120
- package/dist/components/layouts/ResizablePanel.svelte.d.ts +24 -8
- package/dist/components/layouts/resizable-panel-frame.d.ts +70 -0
- package/dist/components/layouts/resizable-panel-frame.js +161 -0
- package/dist/components/molecules/CopyButton.svelte +11 -2
- package/dist/components/molecules/CopyButton.svelte.d.ts +4 -0
- package/dist/components/molecules/FileButton.svelte +32 -3
- package/dist/components/molecules/FileButton.svelte.d.ts +4 -0
- package/dist/components/molecules/IconButton.svelte +34 -6
- package/dist/components/molecules/IconButton.svelte.d.ts +3 -0
- package/dist/components/molecules/Popover.svelte +32 -2
- package/dist/components/molecules/Popover.svelte.d.ts +5 -0
- package/dist/components/molecules/SelectButton.svelte +6 -1
- package/dist/components/molecules/SelectButton.svelte.d.ts +2 -0
- package/dist/components/molecules/ThemePicker.svelte +11 -13
- package/dist/components/organisms/DataTable.svelte +210 -10
- package/dist/components/organisms/DataTable.svelte.d.ts +27 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +3 -1
- package/dist/stores/theme.svelte.d.ts +21 -5
- package/dist/stores/theme.svelte.js +48 -22
- package/dist/styles/app.css +7 -297
- package/dist/styles/reset.css +97 -0
- package/dist/styles/syntax.css +94 -0
- package/dist/styles/themes.css +729 -0
- package/dist/styles/tokens.css +207 -0
- package/dist/styles/utilities.css +111 -0
- package/dist/styles/variables.css +5 -915
- package/package.json +7 -2
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* TOKENS — the theme-less contract. `:root` defines every token the kit reads:
|
|
3
|
+
* raw palette (--c-*), semantic aliases (--bg, --text, --accent, …), type scale,
|
|
4
|
+
* spacing, radii, shadows, z-index, safe-area insets and fonts.
|
|
5
|
+
*
|
|
6
|
+
* Import this alone when you ship your own palette and do not want the built-in
|
|
7
|
+
* theme blocks (those live in themes.css; variables.css = both).
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
:root {
|
|
11
|
+
/* Tell the UA our default surface is dark so native widgets (form controls,
|
|
12
|
+
scrollbars, the caret, spellcheck underlines) render their dark variant.
|
|
13
|
+
Light themes flip this in their own block. */
|
|
14
|
+
color-scheme: dark;
|
|
15
|
+
|
|
16
|
+
/* ---- Palette (raw) ---- */
|
|
17
|
+
--c-bg: #0f1115;
|
|
18
|
+
--c-bg-elev: #171a21;
|
|
19
|
+
--c-bg-elev-2: #1f232c;
|
|
20
|
+
--c-surface: #21262f;
|
|
21
|
+
--c-border: #2c323d;
|
|
22
|
+
--c-border-strong: #3a414e;
|
|
23
|
+
--c-text: #e6e9ef;
|
|
24
|
+
--c-text-muted: #9aa3b2;
|
|
25
|
+
--c-text-faint: #6b7384;
|
|
26
|
+
|
|
27
|
+
--c-accent: #5ad6a0;
|
|
28
|
+
--c-accent-ink: #04130c;
|
|
29
|
+
--c-accent-dim: #2a6e54;
|
|
30
|
+
|
|
31
|
+
--c-blue: #5aa9ff;
|
|
32
|
+
--c-amber: #f0b454;
|
|
33
|
+
--c-red: #f0716b;
|
|
34
|
+
--c-green: #5ad6a0;
|
|
35
|
+
--c-violet: #b48ef0;
|
|
36
|
+
--c-gold: #f0b454;
|
|
37
|
+
--c-teal: #4fd6cf;
|
|
38
|
+
|
|
39
|
+
/* ---- Role colors (CCT-161) — uniform message theming, all derived from
|
|
40
|
+
palette tokens so each theme adapts. Used for role badges + bubble tints. */
|
|
41
|
+
--role-user: var(--c-green);
|
|
42
|
+
--role-assistant: var(--c-blue);
|
|
43
|
+
--role-system: var(--c-violet);
|
|
44
|
+
--role-tool: var(--c-gold);
|
|
45
|
+
--role-mcp: var(--c-teal);
|
|
46
|
+
/* compact/clear boundary — neutral "paper white" so it reads as structure */
|
|
47
|
+
--role-boundary: var(--c-text-muted);
|
|
48
|
+
|
|
49
|
+
/* ---- Markdown / syntax-highlight tokens (CCT-161) — themeable ---- */
|
|
50
|
+
--md-text: var(--c-text-muted); /* base prose: grayish */
|
|
51
|
+
--md-strong: var(--c-text); /* bold: bright white-ish */
|
|
52
|
+
--md-code: var(--c-blue); /* inline code: bold blue */
|
|
53
|
+
--md-code-bg: color-mix(in srgb, var(--c-blue) 14%, var(--c-bg));
|
|
54
|
+
--md-heading: var(--c-text);
|
|
55
|
+
--syn-keyword: var(--c-violet);
|
|
56
|
+
--syn-string: var(--c-green);
|
|
57
|
+
--syn-number: var(--c-amber);
|
|
58
|
+
--syn-comment: var(--c-text-faint);
|
|
59
|
+
--syn-function: var(--c-blue);
|
|
60
|
+
--syn-punct: var(--c-text-muted);
|
|
61
|
+
|
|
62
|
+
/* ---- Semantic ---- */
|
|
63
|
+
--bg: var(--c-bg);
|
|
64
|
+
--bg-elevated: var(--c-bg-elev);
|
|
65
|
+
--bg-elevated-2: var(--c-bg-elev-2);
|
|
66
|
+
--surface: var(--c-surface);
|
|
67
|
+
--border: var(--c-border);
|
|
68
|
+
--border-strong: var(--c-border-strong);
|
|
69
|
+
|
|
70
|
+
--text: var(--c-text);
|
|
71
|
+
--text-muted: var(--c-text-muted);
|
|
72
|
+
--text-faint: var(--c-text-faint);
|
|
73
|
+
--text-on-accent: var(--c-accent-ink);
|
|
74
|
+
/* Adaptive ink for filled positive actions: dark canvas ink on bright greens,
|
|
75
|
+
light canvas ink on the darker greens used by light themes. */
|
|
76
|
+
--text-on-success: var(--bg);
|
|
77
|
+
|
|
78
|
+
--accent: var(--c-accent);
|
|
79
|
+
--accent-dim: var(--c-accent-dim);
|
|
80
|
+
--link: var(--c-blue);
|
|
81
|
+
|
|
82
|
+
--ok: var(--c-green);
|
|
83
|
+
--warn: var(--c-amber);
|
|
84
|
+
--danger: var(--c-red);
|
|
85
|
+
--info: var(--c-blue);
|
|
86
|
+
|
|
87
|
+
/* status dots */
|
|
88
|
+
--dot-active: var(--c-green);
|
|
89
|
+
--dot-stale: var(--c-amber);
|
|
90
|
+
--dot-dead: var(--c-text-faint);
|
|
91
|
+
--dot-hibernated: var(--c-red);
|
|
92
|
+
|
|
93
|
+
/* attention highlight (needs-input row) */
|
|
94
|
+
--attention-bg: color-mix(in srgb, var(--c-amber) 12%, transparent);
|
|
95
|
+
--attention-bar: var(--c-amber);
|
|
96
|
+
|
|
97
|
+
/* machine-badge tinting (CCT-271, fixed CCT-272) — the hue is per-machine
|
|
98
|
+
(name hash or operator override, --mh, set on the badge element), but the
|
|
99
|
+
saturation/lightness come from the theme as `<sat%> <light%>` PAIRS. The
|
|
100
|
+
badge composes `hsl(var(--mh) var(--mach-*-sl))` itself, so both vars
|
|
101
|
+
resolve on the element where --mh lives. (Composing the full hsl() here at
|
|
102
|
+
:root would break: --mh is undefined at :root, so the token is invalid and
|
|
103
|
+
inherits down invalid → white badges.) Dark themes default here; light
|
|
104
|
+
themes flip to dark-text-on-pale-tint in their [data-theme] block. */
|
|
105
|
+
--mach-bg-sl: 45% 22%;
|
|
106
|
+
--mach-fg-sl: 70% 80%;
|
|
107
|
+
--mach-border-sl: 45% 35%;
|
|
108
|
+
|
|
109
|
+
/* ---- Typography ---- */
|
|
110
|
+
--font-sans:
|
|
111
|
+
ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
|
|
112
|
+
"Helvetica Neue", Arial, sans-serif;
|
|
113
|
+
--font-mono:
|
|
114
|
+
ui-monospace, "SF Mono", "JetBrains Mono", "Fira Code", Menlo, Consolas,
|
|
115
|
+
monospace;
|
|
116
|
+
|
|
117
|
+
/* Text-scale factor (CCT-305). The UI font control multiplies ONLY the
|
|
118
|
+
font-size tokens by this — not the root font-size — so bumping the size up
|
|
119
|
+
enlarges text (chat, session text, badges, labels) meaningfully while the
|
|
120
|
+
chrome (button heights, padding, spacing, the px-pinned header) stays put.
|
|
121
|
+
Previously the control scaled the document root font-size, which grew every
|
|
122
|
+
rem-based chrome dimension in lockstep so text "barely grew" relative to the
|
|
123
|
+
ballooning UI. Default 1 = no scaling. */
|
|
124
|
+
--fs-scale: 1;
|
|
125
|
+
|
|
126
|
+
--fs-xs: calc(0.75rem * var(--fs-scale)); /* 12 */
|
|
127
|
+
--fs-sm: calc(0.8125rem * var(--fs-scale)); /* 13 */
|
|
128
|
+
--fs-base: calc(0.9375rem * var(--fs-scale)); /* 15 */
|
|
129
|
+
--fs-md: calc(1rem * var(--fs-scale)); /* 16 */
|
|
130
|
+
--fs-lg: calc(1.125rem * var(--fs-scale)); /* 18 */
|
|
131
|
+
--fs-xl: calc(1.375rem * var(--fs-scale)); /* 22 */
|
|
132
|
+
--fs-2xl: calc(1.75rem * var(--fs-scale)); /* 28 */
|
|
133
|
+
|
|
134
|
+
--fw-normal: 400;
|
|
135
|
+
--fw-medium: 500;
|
|
136
|
+
--fw-semibold: 600;
|
|
137
|
+
--fw-bold: 700;
|
|
138
|
+
|
|
139
|
+
--lh-tight: 1.25;
|
|
140
|
+
--lh-normal: 1.5;
|
|
141
|
+
|
|
142
|
+
/* ---- Spacing (4px base) ---- */
|
|
143
|
+
--sp-0: 0;
|
|
144
|
+
--sp-1: 0.25rem;
|
|
145
|
+
--sp-2: 0.5rem;
|
|
146
|
+
--sp-3: 0.75rem;
|
|
147
|
+
--sp-4: 1rem;
|
|
148
|
+
--sp-5: 1.25rem;
|
|
149
|
+
--sp-6: 1.5rem;
|
|
150
|
+
--sp-8: 2rem;
|
|
151
|
+
--sp-10: 2.5rem;
|
|
152
|
+
--sp-12: 3rem;
|
|
153
|
+
|
|
154
|
+
/* ---- Radii ---- */
|
|
155
|
+
--r-sm: 6px;
|
|
156
|
+
--r-md: 10px;
|
|
157
|
+
--r-lg: 14px;
|
|
158
|
+
--r-pill: 999px;
|
|
159
|
+
|
|
160
|
+
/* ---- Elevation ---- */
|
|
161
|
+
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
|
|
162
|
+
--shadow-md: 0 6px 20px rgba(0, 0, 0, 0.45);
|
|
163
|
+
--shadow-lg: 0 12px 40px rgba(0, 0, 0, 0.55);
|
|
164
|
+
|
|
165
|
+
/* ---- Controls ----
|
|
166
|
+
`size="sm"` is the compact toolbar contract shared by Button, Popover and
|
|
167
|
+
SegmentedControl. `control` is the roomier uniform-height contract used by
|
|
168
|
+
Button and other composer controls. Both remain rem-based for zoom. */
|
|
169
|
+
--control-height-compact: 2rem;
|
|
170
|
+
--control-height-default: 2.5rem;
|
|
171
|
+
--control-height-large: 3rem;
|
|
172
|
+
--control-height: 2.75rem;
|
|
173
|
+
/* Square box scale for icon-only controls (IconButton, Button `box`/`square`,
|
|
174
|
+
SelectButton, Popover trigger, CopyButton, FileButton). md is the classic
|
|
175
|
+
2.25rem icon button; sm/lg reuse the control heights so a boxed control
|
|
176
|
+
lines up with text controls in the same row. */
|
|
177
|
+
--box-xs: 1.5rem;
|
|
178
|
+
--box-sm: var(--control-height-compact);
|
|
179
|
+
--box-md: 2.25rem;
|
|
180
|
+
--box-lg: var(--control-height-default);
|
|
181
|
+
/* Minimum hit area on coarse pointers (WCAG 2.5.8); px so it never shrinks
|
|
182
|
+
under a small root font-size. */
|
|
183
|
+
--touch-target: 44px;
|
|
184
|
+
|
|
185
|
+
/* ---- Layout ---- */
|
|
186
|
+
/* Fixed (px, not rem): the header is chrome that must NOT scale with the
|
|
187
|
+
UI font slider it hosts (CCT-264) — a rem header-h would grow under the
|
|
188
|
+
slider and reflow it mid-drag. Pinning here keeps the bar height, the
|
|
189
|
+
content clearance, and the sticky offsets that key off it all consistent
|
|
190
|
+
with the fixed toolbar. */
|
|
191
|
+
--header-h: 52px;
|
|
192
|
+
--nav-h: 3.5rem;
|
|
193
|
+
--content-max: 56rem;
|
|
194
|
+
--z-header: 50;
|
|
195
|
+
--z-nav: 50;
|
|
196
|
+
--z-drawer: 100;
|
|
197
|
+
--z-modal: 200;
|
|
198
|
+
--z-toast: 300;
|
|
199
|
+
|
|
200
|
+
/* safe-area insets (phones with notch / gesture bar / bottom address bar) */
|
|
201
|
+
--safe-top: env(safe-area-inset-top, 0px);
|
|
202
|
+
--safe-bottom: env(safe-area-inset-bottom, 0px);
|
|
203
|
+
--safe-left: env(safe-area-inset-left, 0px);
|
|
204
|
+
--safe-right: env(safe-area-inset-right, 0px);
|
|
205
|
+
|
|
206
|
+
--ease: cubic-bezier(0.2, 0.8, 0.2, 1);
|
|
207
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Generic utilities + icon sizing + misc helpers. Component styling lives in
|
|
3
|
+
* each component's own scoped <style>, never here.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/* ---------- generic utilities ----------
|
|
7
|
+
* Small, content-agnostic helpers (NOT component styling — components own that in
|
|
8
|
+
* their own scope). Layout components (Container/Stack/Cluster/AutoGrid) are the
|
|
9
|
+
* recommended API; these stay for ad-hoc markup and as documented escape hatches. */
|
|
10
|
+
.container {
|
|
11
|
+
width: 100%;
|
|
12
|
+
max-width: var(--content-max);
|
|
13
|
+
margin-inline: auto;
|
|
14
|
+
padding-inline: max(var(--sp-4), var(--safe-left)) max(var(--sp-4), var(--safe-right));
|
|
15
|
+
}
|
|
16
|
+
.stack {
|
|
17
|
+
display: flex;
|
|
18
|
+
flex-direction: column;
|
|
19
|
+
gap: var(--sp-3);
|
|
20
|
+
}
|
|
21
|
+
.row {
|
|
22
|
+
display: flex;
|
|
23
|
+
align-items: center;
|
|
24
|
+
gap: var(--sp-2);
|
|
25
|
+
}
|
|
26
|
+
.row-wrap {
|
|
27
|
+
flex-wrap: wrap;
|
|
28
|
+
}
|
|
29
|
+
.spacer {
|
|
30
|
+
flex: 1;
|
|
31
|
+
}
|
|
32
|
+
.faint {
|
|
33
|
+
/* `--faint-color` lets a parent retint slotted `.faint` text via inheritance
|
|
34
|
+
(custom props cross the slot boundary, so no :global needed). */
|
|
35
|
+
color: var(--faint-color, var(--text-faint));
|
|
36
|
+
}
|
|
37
|
+
.mono {
|
|
38
|
+
font-family: var(--font-mono);
|
|
39
|
+
}
|
|
40
|
+
.truncate {
|
|
41
|
+
overflow: hidden;
|
|
42
|
+
text-overflow: ellipsis;
|
|
43
|
+
white-space: nowrap;
|
|
44
|
+
min-width: 0;
|
|
45
|
+
}
|
|
46
|
+
.nowrap {
|
|
47
|
+
white-space: nowrap;
|
|
48
|
+
}
|
|
49
|
+
/* Opt a wrapper into container queries so descendants can respond to THIS box's
|
|
50
|
+
width (not the viewport). Pair with `@container (…)` in a component's scope,
|
|
51
|
+
or with the .cq-* utilities below. */
|
|
52
|
+
.cq {
|
|
53
|
+
container-type: inline-size;
|
|
54
|
+
}
|
|
55
|
+
/* Container-responsive utilities — they react to the nearest ancestor query
|
|
56
|
+
container (any `.cq`, or an AppShell region), NOT the viewport. Put them on
|
|
57
|
+
children of a container so a component degrades when ITS box is tight,
|
|
58
|
+
wherever it lives. The breakpoints are container widths. */
|
|
59
|
+
@container (max-width: 30rem) {
|
|
60
|
+
.cq-hide {
|
|
61
|
+
display: none !important;
|
|
62
|
+
} /* e.g. wrap a button's label to drop it → icon-only */
|
|
63
|
+
.cq-stack {
|
|
64
|
+
flex-direction: column !important;
|
|
65
|
+
align-items: stretch !important;
|
|
66
|
+
}
|
|
67
|
+
.cq-truncate {
|
|
68
|
+
overflow: hidden;
|
|
69
|
+
text-overflow: ellipsis;
|
|
70
|
+
white-space: nowrap;
|
|
71
|
+
min-width: 0;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
@container (max-width: 18rem) {
|
|
75
|
+
.cq-hide-xs {
|
|
76
|
+
display: none !important;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/* ---------- icon sizing ----------
|
|
81
|
+
* Components own their own button/control styling in scope (Button, IconButton,
|
|
82
|
+
* Modal, Toaster, Dot, …). This single rule stays global because it also sizes
|
|
83
|
+
* raw decorative SVGs that callers drop in outside any component. */
|
|
84
|
+
.icon,
|
|
85
|
+
svg[aria-hidden='true'] {
|
|
86
|
+
flex: none;
|
|
87
|
+
width: 1em;
|
|
88
|
+
height: 1em;
|
|
89
|
+
min-width: 1em;
|
|
90
|
+
min-height: 1em;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/* ---------- misc ---------- */
|
|
94
|
+
.divider {
|
|
95
|
+
height: 1px;
|
|
96
|
+
background: var(--border);
|
|
97
|
+
border: 0;
|
|
98
|
+
margin: var(--sp-2) 0;
|
|
99
|
+
}
|
|
100
|
+
.sr-only {
|
|
101
|
+
position: absolute;
|
|
102
|
+
width: 1px;
|
|
103
|
+
height: 1px;
|
|
104
|
+
padding: 0;
|
|
105
|
+
margin: -1px;
|
|
106
|
+
overflow: hidden;
|
|
107
|
+
clip: rect(0, 0, 0, 0);
|
|
108
|
+
white-space: nowrap;
|
|
109
|
+
border: 0;
|
|
110
|
+
}
|
|
111
|
+
|