@invana/styling 0.0.30 → 0.0.32

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 CHANGED
@@ -95,10 +95,16 @@ All colors follow the CSS variable pattern and can be used with TailwindCSS util
95
95
 
96
96
  ### Border Radius
97
97
 
98
- - `--radius`: Base radius (0.5rem)
99
- - `--radius-lg`: Large radius
100
- - `--radius-md`: Medium radius
101
- - `--radius-sm`: Small radius
98
+ Three dials set every corner; no component takes a radius prop. See the rationale at the top
99
+ of `src/index.css` and try them live in Storybook (`Others/CornerRadius`).
100
+
101
+ | Dial | Class | Draws | Default |
102
+ | --- | --- | --- | --- |
103
+ | `--radius` | `rounded`, `rounded-sm` … `rounded-4xl` (every step reads `--radius`) | tables, rows, boxes inside a card | `0px` |
104
+ | `--radius-surface` | `rounded-surface` | cards, panels, dialogs, popovers, menus, tooltips | `var(--radius)` |
105
+ | `--radius-control` | `rounded-control` | buttons, badges, chips, inputs, selects, tabs, toggles | `4px` |
106
+
107
+ Round objects (avatars, dots, switch thumbs) keep `rounded-full` and follow no dial.
102
108
 
103
109
  ### Animations
104
110
 
@@ -120,7 +126,11 @@ You can override any variable by defining it after importing:
120
126
 
121
127
  @theme {
122
128
  --color-primary: hsl(270 100% 50%); /* Override primary color */
123
- --radius: 1rem; /* Increase border radius */
129
+ }
130
+
131
+ :root {
132
+ --radius-surface: 6px; /* Round cards, panels and floating surfaces */
133
+ --radius-control: 2px; /* Soften buttons, badges and inputs less */
124
134
  }
125
135
  ```
126
136
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@invana/styling",
3
- "version": "0.0.30",
3
+ "version": "0.0.32",
4
4
  "description": "Invana TailwindCSS 4 Design System - Reusable styling configuration",
5
5
  "homepage": "https://github.com/invana/design-kit#readme",
6
6
  "type": "module",
@@ -32,6 +32,7 @@
32
32
  },
33
33
  "./themes": "./src/themes/index.ts",
34
34
  "./themes.config": "./src/themes.config.ts",
35
+ "./color": "./src/color.ts",
35
36
  "./themes/default": {
36
37
  "style": "./src/themes/default.css",
37
38
  "default": "./src/themes/default.css"
package/src/base.css CHANGED
@@ -1,6 +1,24 @@
1
1
  /* Base styles */
2
- * {
3
- border-color: var(--color-border);
2
+ /*
3
+ * In the base layer, so a border-colour utility (`border-primary`,
4
+ * `border-l-warning`) wins. Unlayered, this rule beat every utility and each
5
+ * coloured border in the kit drew as the plain border.
6
+ */
7
+ @layer base {
8
+ * {
9
+ border-color: var(--color-border);
10
+ }
11
+
12
+ /*
13
+ * A ring's offset gap is the page, not Tailwind's default white — so a
14
+ * `ring-offset-2` reads as a gap on a dark theme too. A
15
+ * `ring-offset-<colour>` utility still wins.
16
+ */
17
+ *,
18
+ ::before,
19
+ ::after {
20
+ --tw-ring-offset-color: var(--color-background);
21
+ }
4
22
  }
5
23
 
6
24
  body {
package/src/color.ts ADDED
@@ -0,0 +1,80 @@
1
+ /**
2
+ * A colour for any string — a node type, a relationship type, a model's name.
3
+ *
4
+ * Every categorical thing that needs a default colour gets one slot of the data
5
+ * palette (`themes/data-palette.css`), chosen by hashing its name. Same string,
6
+ * same slot, always: a type keeps its colour across canvases, lists and reloads,
7
+ * and it does not shift when a sibling is added or the list is re-sorted —
8
+ * colour follows the entity, never its rank.
9
+ *
10
+ * A set can hold more names than the palette has slots; past the eighth, slots
11
+ * repeat. That is admissible only because every use names the thing beside its
12
+ * swatch — colour is never the only carrier of identity.
13
+ *
14
+ * Three rungs, pick the one the surface can take:
15
+ *
16
+ * | Function | Returns | For |
17
+ * |---|---|---|
18
+ * | `colorSlotByString` | `1`…`8` | storing or binding the slot itself |
19
+ * | `colorVarByString` | `var(--color-data-N)` | anything that takes CSS |
20
+ * | `colorByString` | `rgb(…)`, resolved live | a canvas that needs a concrete value |
21
+ */
22
+
23
+ /** How many slots the data palette defines. */
24
+ export const DATA_PALETTE_SLOTS = 8;
25
+
26
+ /** Neutral stand-in when a slot will not resolve (older styling, no theme yet). */
27
+ const FALLBACK_VAR = '--color-muted-foreground';
28
+
29
+ /** The palette slot (1-based) a string lands in. Empty → slot 1. */
30
+ export function colorSlotByString(value: string | null | undefined): number {
31
+ if (!value) return 1;
32
+ let h = 0;
33
+ for (let i = 0; i < value.length; i++) h = (h * 31 + value.charCodeAt(i)) >>> 0;
34
+ return (h % DATA_PALETTE_SLOTS) + 1;
35
+ }
36
+
37
+ /** The slot's token as a CSS value, with a neutral fallback baked in. */
38
+ export function colorVarByString(value: string | null | undefined): string {
39
+ return `var(--color-data-${colorSlotByString(value)}, var(${FALLBACK_VAR}))`;
40
+ }
41
+
42
+ /*
43
+ * Resolved colours, keyed by the root's theme stamp. A canvas asks once per
44
+ * item on every restyle and each probe forces a style recalc, so reads are
45
+ * cached; the theme lives on the root's class and inline style, so a theme or
46
+ * mode switch changes the stamp and the next read re-resolves.
47
+ */
48
+ let cacheStamp = '';
49
+ const cache = new Map<string, string | undefined>();
50
+
51
+ /** Resolve any CSS colour value to the concrete `rgb(…)` the browser computes. */
52
+ export function resolveCssColor(css: string): string | undefined {
53
+ if (typeof document === 'undefined') return undefined;
54
+ const root = document.documentElement;
55
+ const stamp = `${root.className}|${root.getAttribute('style') ?? ''}`;
56
+ if (stamp !== cacheStamp) {
57
+ cacheStamp = stamp;
58
+ cache.clear();
59
+ }
60
+ if (cache.has(css)) return cache.get(css);
61
+ const probe = document.createElement('span');
62
+ probe.style.color = css;
63
+ probe.style.display = 'none';
64
+ root.appendChild(probe);
65
+ const rgb = getComputedStyle(probe).color || undefined;
66
+ probe.remove();
67
+ cache.set(css, rgb);
68
+ return rgb;
69
+ }
70
+
71
+ /**
72
+ * The live colour for a string: `explicit` if given, else its palette slot
73
+ * resolved against the active theme. Falls back to the token string when there
74
+ * is no DOM to resolve against.
75
+ */
76
+ export function colorByString(value: string | null | undefined, explicit?: string): string {
77
+ if (explicit) return explicit;
78
+ const css = colorVarByString(value);
79
+ return resolveCssColor(css) ?? css;
80
+ }
package/src/index.css CHANGED
@@ -141,6 +141,25 @@
141
141
  --color-card: hsl(0 0% 100%);
142
142
  --color-card-foreground: hsl(210 10% 20%);
143
143
 
144
+ /* What frames the work — app header and footer, side panels, a panel's
145
+ header strip, a table's header — as distinct from the work itself
146
+ (`card`). A theme that sets no chrome of its own gets the point halfway
147
+ from its card to its background, so the layer exists, and recedes, in
148
+ every theme. */
149
+ --color-chrome: color-mix(in srgb, var(--color-card), var(--color-background));
150
+
151
+ /* shadcn's Sidebar names, mapped onto the kit's own: a sidebar is chrome,
152
+ its hover is accent, so it follows every theme rather than carrying a
153
+ palette of its own. */
154
+ --color-sidebar: var(--color-chrome);
155
+ --color-sidebar-foreground: var(--color-card-foreground);
156
+ --color-sidebar-primary: var(--color-primary);
157
+ --color-sidebar-primary-foreground: var(--color-primary-foreground);
158
+ --color-sidebar-accent: var(--color-accent);
159
+ --color-sidebar-accent-foreground: var(--color-accent-foreground);
160
+ --color-sidebar-border: var(--color-border);
161
+ --color-sidebar-ring: var(--color-ring);
162
+
144
163
  /* The line between two things on a canvas — a graph edge, a dependency
145
164
  arrow, a connector. Deliberately NOT --color-border: a border separates
146
165
  surfaces and may go invisible against them, while an edge is content and
@@ -148,59 +167,97 @@
148
167
  --color-edge: hsl(210 6% 78%);
149
168
 
150
169
  /* ------------------------------------------------------------------------
151
- * Border radius — the design language, decided 01-09-2026.
170
+ * Border radius — three dials, revised 03-10-2026.
152
171
  *
153
- * STRUCTURE is cut. 0 anything that CONTAINS
154
- * CONTROLS are pressed. 2px anything you PRESS or TYPE INTO
155
- * SHAPE is not radius. 999px only where round IS the object
172
+ * STRUCTURE --radius 0 anything that CONTAINS
173
+ * SURFACES --radius-surface --radius cards, panels, anything floating
174
+ * CONTROLS --radius-control 4px anything you PRESS, TYPE INTO
175
+ * or that labels at control height
176
+ * SHAPE rounded-full 999px only where round IS the object
156
177
  *
157
- * Structure: cards, panels, dialogs, popovers, menus, tables, ledger rows,
158
- * chips, badges, tab panels, canvas surfaces, diagram nodes.
159
- * Controls: buttons, inputs, selects, textareas, menu items, tab triggers,
160
- * toggles — `rounded-control`, generated from `--radius-control` below.
178
+ * Structure: tables, ledger rows, boxes inside a card, tab panels, canvas
179
+ * surfaces, diagram nodes — `rounded`, `rounded-sm` …
180
+ * `rounded-4xl`, every step of which reads `--radius`.
181
+ * Surfaces: the frames a block or a screen section sits in — Card (and so
182
+ * PanelContent), PanelBox — and everything that floats over
183
+ * the page: Dialog, AlertDialog, Popover, HoverCard, Tooltip, dropdown and
184
+ * menubar menus, Select's list, Command, the NavigationMenu viewport —
185
+ * `rounded-surface`, which reads `--radius-surface`. It defaults to
186
+ * `--radius`; set it to round the frames while what is inside them stays
187
+ * cut.
188
+ * Controls: buttons, badges, chips, inputs, selects, textareas, menu items,
189
+ * tab triggers, toggles — `rounded-control`, which reads `--radius-control`.
161
190
  * Shape: avatars, status dots, spinners, slider thumbs, switch capsules,
162
- * scrollbar thumbs. These keep `rounded-full` because they are round
163
- * objects, not rectangles with soft ends. A rectangle wearing round ends is
164
- * a pill, and there are no pills.
191
+ * scrollbar thumbs keep `rounded-full` because they are round objects, not
192
+ * rectangles with soft ends. There are no pills.
165
193
  *
166
194
  * WHY 0 FOR STRUCTURE. The hairline grid is the house component: cells sit
167
195
  * on a `bg-border` backdrop separated by `gap-px`, so the "border" is the
168
196
  * backdrop showing through a one-pixel gap. Any radius on a cell lets that
169
197
  * backdrop through at every corner as a grey notch — radii and hairline
170
- * grids cannot both win. It also holds at application density: a radius
171
- * that is invisible on a 44px button is loud on a 24px row, and nesting a
172
- * chip in a row in a panel in a card stacks four of them into mush. Sharp
173
- * nests at any size.
198
+ * grids cannot both win. Nesting a chip in a row in a panel in a card would
199
+ * also stack radii into mush. Sharp nests at any size.
174
200
  *
175
- * WHY 2px FOR CONTROLS, not 0. At touch size a fully cut button reads as
176
- * cut metal. 2px is invisible as decoration and legible as affordance: the
177
- * difference between a surface and a thing you press is information, and in
178
- * a dense application that does real work.
201
+ * WHY A RADIUS FOR CONTROLS. The difference between a surface and a thing
202
+ * you press is information. A badge sits with the controls, not the
203
+ * structure, so a Badge beside a Button of the same height draws the same
204
+ * corner.
179
205
  *
180
- * The scale is deliberately flat. `rounded-sm` / `-md` / `-lg` / `-xl` /
181
- * `-2xl` all resolve to 0, so the ~79 components already written against
182
- * them need no edit, and a `rounded-lg` typed out of habit tomorrow cannot
183
- * quietly reintroduce a radius.
206
+ * ALL THREE ARE DIALS. Tune any on `:root` or per theme
207
+ * (`[data-theme="…"] { --radius-control: 2px }`) and everything on that side
208
+ * follows. The structure scale is flat on purpose: every step draws the same
209
+ * corner, so a `rounded-lg` typed out of habit cannot drift from the rest.
210
+ * A component with no `rounded-*` class follows neither dial — give it one.
184
211
  * ---------------------------------------------------------------------- */
185
212
  --radius: 0px;
186
- --radius-sm: 0px;
187
- --radius-md: 0px;
188
- --radius-lg: 0px;
189
- --radius-xl: 0px;
190
- --radius-2xl: 0px;
191
- --radius-3xl: 0px;
213
+ --radius-xs: var(--radius);
214
+ --radius-sm: var(--radius);
215
+ --radius-md: var(--radius);
216
+ --radius-lg: var(--radius);
217
+ --radius-xl: var(--radius);
218
+ --radius-2xl: var(--radius);
219
+ --radius-3xl: var(--radius);
220
+ --radius-4xl: var(--radius);
221
+
222
+ /* Cards, panels and floating surfaces (dialogs, popovers, menus) point at
223
+ `rounded-surface`. Follows --radius until set on its own. */
224
+ --radius-surface: var(--radius);
225
+
226
+ /* Every control points at `rounded-control`. */
227
+ --radius-control: 4px;
192
228
 
193
- /* The only non-zero rectangle radius in the system. Generates
194
- `rounded-control`, which every control component points at. */
195
- --radius-control: 2px;
229
+ /* Retained alias of --radius-control. Prefer `rounded-control`. */
230
+ --radius-2px: var(--radius-control);
196
231
 
197
- /* Retained: predates the decision, and is now the same value as
198
- --radius-control. Prefer `rounded-control` — it says what it is for. */
199
- --radius-2px: 2px;
232
+ /* ------------------------------------------------------------------------
233
+ * Control heights — one scale, and a size name means one height.
234
+ *
235
+ * xs 22px a badge or an icon button inside a row
236
+ * sm 26px the application control: search, input, select, filter
237
+ * chip, segmented control, tab, toolbar button
238
+ * md 32px a standalone form, a dialog's buttons — `default` sizes
239
+ * lg 40px a page form, a page's primary action
240
+ *
241
+ * Before this, every component picked its own number for each name — a
242
+ * `sm` badge was 22px, a `sm` button 32px, a `sm` input 26px — so two
243
+ * controls of the same size never lined up in a toolbar. Every component
244
+ * with a `size` now maps the name onto these, and nothing else.
245
+ *
246
+ * Spacing tokens, so they generate `h-control-sm`, `min-h-control-sm`,
247
+ * `size-control-sm` and `w-control-sm`. Ratios of the root like the type:
248
+ * the px above are at the 13px application root, and a 16px site gets
249
+ * proportionally taller controls. `cn` registers the names with
250
+ * tailwind-merge, which does not otherwise know them.
251
+ * ---------------------------------------------------------------------- */
252
+ --spacing-control-xs: calc(22rem / 13);
253
+ --spacing-control-sm: calc(26rem / 13);
254
+ --spacing-control-md: calc(32rem / 13);
255
+ --spacing-control-lg: calc(40rem / 13);
200
256
 
201
257
  /* Animations */
202
258
  --animate-accordion-down: accordion-down 0.2s ease-out;
203
259
  --animate-accordion-up: accordion-up 0.2s ease-out;
260
+ --animate-row-in: row-in 1s ease-out;
204
261
  }
205
262
 
206
263
  /*
@@ -279,12 +336,13 @@
279
336
  opacity: 0;
280
337
  transform: scale(0.9);
281
338
  transition: opacity 150ms ease-out, transform 150ms ease-out;
339
+ --hint-color: color-mix(in srgb, var(--color-foreground) 70%, transparent);
282
340
  background-repeat: no-repeat;
283
341
  background-image:
284
- linear-gradient(hsl(var(--foreground) / 0.7), hsl(var(--foreground) / 0.7)),
285
- linear-gradient(hsl(var(--foreground) / 0.7), hsl(var(--foreground) / 0.7)),
286
- linear-gradient(hsl(var(--foreground) / 0.7), hsl(var(--foreground) / 0.7)),
287
- linear-gradient(hsl(var(--foreground) / 0.7), hsl(var(--foreground) / 0.7));
342
+ linear-gradient(var(--hint-color), var(--hint-color)),
343
+ linear-gradient(var(--hint-color), var(--hint-color)),
344
+ linear-gradient(var(--hint-color), var(--hint-color)),
345
+ linear-gradient(var(--hint-color), var(--hint-color));
288
346
  }
289
347
 
290
348
  &::before {
@@ -300,9 +358,7 @@
300
358
  &:hover::before,
301
359
  &:hover::after,
302
360
  &:focus-visible::before,
303
- &:focus-visible::after,
304
- &:focus-within::before,
305
- &:focus-within::after {
361
+ &:focus-visible::after {
306
362
  opacity: 1;
307
363
  transform: scale(1);
308
364
  }
@@ -326,6 +382,13 @@
326
382
  }
327
383
  }
328
384
 
385
+ /* A row that just streamed in: arrives tinted, fades to its own ground. */
386
+ @keyframes row-in {
387
+ from {
388
+ background-color: color-mix(in srgb, var(--color-primary) 12%, transparent);
389
+ }
390
+ }
391
+
329
392
  /* Base styles */
330
393
  html,
331
394
  body {
@@ -334,8 +397,26 @@ body {
334
397
  -webkit-font-smoothing: antialiased;
335
398
  }
336
399
 
337
- * {
338
- border-color: var(--color-border);
400
+ /*
401
+ * In the base layer, so a border-colour utility (`border-primary`,
402
+ * `border-l-warning`) wins. Unlayered, this rule beat every utility and each
403
+ * coloured border in the kit drew as the plain border.
404
+ */
405
+ @layer base {
406
+ * {
407
+ border-color: var(--color-border);
408
+ }
409
+
410
+ /*
411
+ * A ring's offset gap is the page, not Tailwind's default white — so a
412
+ * `ring-offset-2` reads as a gap on a dark theme too. A
413
+ * `ring-offset-<colour>` utility still wins.
414
+ */
415
+ *,
416
+ ::before,
417
+ ::after {
418
+ --tw-ring-offset-color: var(--color-background);
419
+ }
339
420
  }
340
421
 
341
422
  body {
package/src/theme.css CHANGED
@@ -34,21 +34,27 @@
34
34
  --color-card-foreground: hsl(222.2 84% 4.9%);
35
35
 
36
36
  /* Border Radius — see the full rationale in `index.css`.
37
- Structure 0 · controls 2px (`rounded-control`) · round only where round
38
- IS the object. The scale is flat on purpose so components already written
39
- against rounded-sm/md/lg need no edit and cannot drift back. */
37
+ Three dials: structure `--radius` (0, every step below reads it),
38
+ surfaces `--radius-surface` (card-like frames, `rounded-surface`, follows
39
+ --radius) and controls `--radius-control` (4px, `rounded-control`) ·
40
+ round only where
41
+ round IS the object. */
40
42
  --radius: 0px;
41
- --radius-sm: 0px;
42
- --radius-md: 0px;
43
- --radius-lg: 0px;
44
- --radius-xl: 0px;
45
- --radius-2xl: 0px;
46
- --radius-3xl: 0px;
47
- --radius-control: 2px;
43
+ --radius-xs: var(--radius);
44
+ --radius-sm: var(--radius);
45
+ --radius-md: var(--radius);
46
+ --radius-lg: var(--radius);
47
+ --radius-xl: var(--radius);
48
+ --radius-2xl: var(--radius);
49
+ --radius-3xl: var(--radius);
50
+ --radius-4xl: var(--radius);
51
+ --radius-surface: var(--radius);
52
+ --radius-control: 4px;
48
53
 
49
54
  /* Animations */
50
55
  --animate-accordion-down: accordion-down 0.2s ease-out;
51
56
  --animate-accordion-up: accordion-up 0.2s ease-out;
57
+ --animate-row-in: row-in 1s ease-out;
52
58
  }
53
59
 
54
60
  @keyframes accordion-down {
@@ -61,6 +67,10 @@
61
67
  to { height: 0; }
62
68
  }
63
69
 
70
+ @keyframes row-in {
71
+ from { background-color: color-mix(in srgb, var(--color-primary) 12%, transparent); }
72
+ }
73
+
64
74
  /* Dark mode */
65
75
  @media (prefers-color-scheme: dark) {
66
76
  @theme {
@@ -1,63 +1,76 @@
1
1
  /**
2
2
  * Default Theme (Invana Brand Colors)
3
- * Light and dark variants with green accent
3
+ * Light and dark variants with green accent, on a cool slate neutral.
4
+ *
5
+ * Surfaces are three layers, so a shell reads as structure rather than one
6
+ * colour with lines on it:
7
+ * background the canvas behind everything (gutters, resize handles)
8
+ * chrome what frames the work: app header and footer, side panels,
9
+ * a panel's header strip — it recedes
10
+ * card the work itself: the editor, a panel's body — it comes forward
11
+ * popover what floats over all of them: menus, tooltips, popovers —
12
+ * solid, one step past card, with a border and a shadow
13
+ * Dark runs background < chrome < card; light runs background < chrome < card
14
+ * the same way, ending on white. Primary passes 4.5:1 against card in both.
4
15
  */
5
16
 
6
17
  /* Light mode - Default theme */
7
18
  [data-theme="default-light"],
8
19
  .theme-default-light {
9
20
  /* Raw HSL values for opacity modifiers */
10
- --background: 0 0% 97%;
11
- --foreground: 210 10% 20%;
12
- --muted: 210 6% 90%;
13
- --muted-foreground: 210 8% 45%;
14
- --accent: 210 6% 92%;
15
- --accent-foreground: 210 10% 20%;
16
- --popover: 0 0% 98%;
17
- --popover-foreground: 210 10% 20%;
18
- --border: 210 6% 85%;
19
- --input: 210 6% 92%;
21
+ --background: 220 14% 92%;
22
+ --foreground: 220 15% 15%;
23
+ --chrome: 220 16% 96.5%;
24
+ --muted: 220 12% 93%;
25
+ --muted-foreground: 220 9% 42%;
26
+ --accent: 220 12% 91%;
27
+ --accent-foreground: 220 15% 15%;
28
+ --popover: 0 0% 100%;
29
+ --popover-foreground: 220 15% 15%;
30
+ --border: 220 12% 86%;
31
+ --input: 220 12% 86%;
20
32
  --card: 0 0% 100%;
21
- --card-foreground: 210 10% 20%;
22
- --primary: 142 70% 43%;
33
+ --card-foreground: 220 15% 15%;
34
+ --primary: 152 68% 30%;
23
35
  --primary-foreground: 0 0% 100%;
24
- --secondary: 142 30% 95%;
25
- --secondary-foreground: 142 25% 40%;
26
- --destructive: 0 70% 60%;
36
+ --secondary: 152 30% 94%;
37
+ --secondary-foreground: 152 40% 26%;
38
+ --destructive: 0 68% 48%;
27
39
  --destructive-foreground: 0 0% 100%;
28
- --ring: 142 70% 43%;
29
- --success: 142 70% 38%;
40
+ --ring: 152 68% 30%;
41
+ --success: 152 68% 30%;
30
42
  --success-foreground: 0 0% 100%;
31
- --warning: 38 92% 42%;
43
+ --warning: 38 92% 38%;
32
44
  --warning-foreground: 0 0% 100%;
33
- --info: 210 90% 45%;
45
+ --info: 212 85% 45%;
34
46
  --info-foreground: 0 0% 100%;
35
47
 
36
48
  /* Full HSL colors for direct use */
37
- --color-background: hsl(0 0% 97%);
38
- --color-foreground: hsl(210 10% 20%);
49
+ --color-background: hsl(220 14% 92%);
50
+ --color-foreground: hsl(220 15% 15%);
51
+ --color-chrome: hsl(220 16% 96.5%);
52
+ --color-muted: hsl(220 12% 93%);
53
+ --color-muted-foreground: hsl(220 9% 42%);
54
+ --color-accent: hsl(220 12% 91%);
55
+ --color-accent-foreground: hsl(220 15% 15%);
56
+ --color-popover: hsl(0 0% 100%);
57
+ --color-popover-foreground: hsl(220 15% 15%);
58
+ --color-border: hsl(220 12% 86%);
59
+ --color-input: hsl(220 12% 86%);
39
60
  --color-card: hsl(0 0% 100%);
40
- --color-card-foreground: hsl(210 10% 20%);
41
- --color-popover: hsl(0 0% 98%);
42
- --color-popover-foreground: hsl(210 10% 20%);
43
- --color-primary: hsl(142 70% 43%);
61
+ --color-card-foreground: hsl(220 15% 15%);
62
+ --color-primary: hsl(152 68% 30%);
44
63
  --color-primary-foreground: hsl(0 0% 100%);
45
- --color-secondary: hsl(142 30% 95%);
46
- --color-secondary-foreground: hsl(142 25% 40%);
47
- --color-muted: hsl(210 6% 90%);
48
- --color-muted-foreground: hsl(210 8% 45%);
49
- --color-accent: hsl(210 6% 92%);
50
- --color-accent-foreground: hsl(210 10% 20%);
51
- --color-destructive: hsl(0 70% 60%);
64
+ --color-secondary: hsl(152 30% 94%);
65
+ --color-secondary-foreground: hsl(152 40% 26%);
66
+ --color-destructive: hsl(0 68% 48%);
52
67
  --color-destructive-foreground: hsl(0 0% 100%);
53
- --color-border: hsl(210 6% 85%);
54
- --color-input: hsl(210 6% 92%);
55
- --color-ring: hsl(142 70% 43%);
56
- --color-success: hsl(142 70% 38%);
68
+ --color-ring: hsl(152 68% 30%);
69
+ --color-success: hsl(152 68% 30%);
57
70
  --color-success-foreground: hsl(0 0% 100%);
58
- --color-warning: hsl(38 92% 42%);
71
+ --color-warning: hsl(38 92% 38%);
59
72
  --color-warning-foreground: hsl(0 0% 100%);
60
- --color-info: hsl(210 90% 45%);
73
+ --color-info: hsl(212 85% 45%);
61
74
  --color-info-foreground: hsl(0 0% 100%);
62
75
  }
63
76
 
@@ -65,56 +78,58 @@
65
78
  [data-theme="default-dark"],
66
79
  .theme-default-dark {
67
80
  /* Raw HSL values for opacity modifiers */
68
- --background: 210 4% 10%;
69
- --foreground: 0 0% 85%;
70
- --muted: 210 6% 18%;
71
- --muted-foreground: 210 8% 60%;
72
- --accent: 210 6% 22%;
73
- --accent-foreground: 0 0% 85%;
74
- --popover: 210 4% 11%;
75
- --popover-foreground: 0 0% 85%;
76
- --border: 210 6% 22%;
77
- --input: 210 6% 22%;
78
- --card: 210 4% 14%;
79
- --card-foreground: 0 0% 85%;
80
- --primary: 142 70% 60%;
81
- --primary-foreground: 210 4% 13%;
82
- --secondary: 210 8% 28%;
83
- --secondary-foreground: 0 0% 85%;
84
- --destructive: 0 60% 45%;
85
- --destructive-foreground: 0 0% 95%;
86
- --ring: 142 70% 60%;
87
- --success: 142 65% 55%;
88
- --success-foreground: 210 4% 13%;
89
- --warning: 45 90% 60%;
90
- --warning-foreground: 210 4% 13%;
91
- --info: 210 90% 65%;
92
- --info-foreground: 210 4% 13%;
81
+ --background: 220 10% 6%;
82
+ --foreground: 220 10% 92%;
83
+ --chrome: 220 9% 9.5%;
84
+ --muted: 220 8% 17%;
85
+ --muted-foreground: 220 8% 64%;
86
+ --accent: 220 8% 20%;
87
+ --accent-foreground: 220 10% 92%;
88
+ --popover: 220 8% 16%;
89
+ --popover-foreground: 220 10% 92%;
90
+ --border: 220 8% 18%;
91
+ --input: 220 8% 21%;
92
+ --card: 220 8% 11%;
93
+ --card-foreground: 220 10% 92%;
94
+ --primary: 152 52% 52%;
95
+ --primary-foreground: 220 10% 6%;
96
+ --secondary: 220 8% 21%;
97
+ --secondary-foreground: 220 10% 92%;
98
+ --destructive: 0 62% 52%;
99
+ --destructive-foreground: 0 0% 98%;
100
+ --ring: 152 52% 52%;
101
+ --success: 152 52% 52%;
102
+ --success-foreground: 220 10% 6%;
103
+ --warning: 42 88% 58%;
104
+ --warning-foreground: 220 10% 6%;
105
+ --info: 212 85% 64%;
106
+ --info-foreground: 220 10% 6%;
93
107
 
94
108
  /* Full HSL colors for direct use */
95
- --color-background: hsl(210 4% 10%);
96
- --color-foreground: hsl(0 0% 85%);
97
- --color-card: hsl(210 4% 14%);
98
- --color-card-foreground: hsl(0 0% 85%);
99
- --color-popover: hsl(210 4% 11%);
100
- --color-popover-foreground: hsl(0 0% 85%);
101
- --color-primary: hsl(142 70% 60%);
102
- --color-primary-foreground: hsl(210 4% 13%);
103
- --color-secondary: hsl(210 8% 28%);
104
- --color-secondary-foreground: hsl(0 0% 85%);
105
- --color-muted: hsl(210 6% 18%);
106
- --color-muted-foreground: hsl(210 8% 60%);
107
- --color-accent: hsl(210 6% 22%);
108
- --color-accent-foreground: hsl(0 0% 85%);
109
- --color-destructive: hsl(0 60% 45%);
110
- --color-destructive-foreground: hsl(0 0% 95%);
111
- --color-border: hsl(210 6% 22%);
112
- --color-input: hsl(210 6% 22%);
113
- --color-ring: hsl(142 70% 60%);
114
- --color-success: hsl(142 65% 55%);
115
- --color-success-foreground: hsl(210 4% 13%);
116
- --color-warning: hsl(45 90% 60%);
117
- --color-warning-foreground: hsl(210 4% 13%);
118
- --color-info: hsl(210 90% 65%);
119
- --color-info-foreground: hsl(210 4% 13%);
109
+ --color-background: hsl(220 10% 6%);
110
+ --color-foreground: hsl(220 10% 92%);
111
+ --color-chrome: hsl(220 9% 9.5%);
112
+ --color-muted: hsl(220 8% 17%);
113
+ --color-muted-foreground: hsl(220 8% 64%);
114
+ --color-accent: hsl(220 8% 20%);
115
+ --color-accent-foreground: hsl(220 10% 92%);
116
+ --color-popover: hsl(220 8% 16%);
117
+ --color-popover-foreground: hsl(220 10% 92%);
118
+ --color-border: hsl(220 8% 18%);
119
+ --color-input: hsl(220 8% 21%);
120
+ --color-card: hsl(220 8% 11%);
121
+ --color-card-foreground: hsl(220 10% 92%);
122
+ --color-primary: hsl(152 52% 52%);
123
+ --color-primary-foreground: hsl(220 10% 6%);
124
+ --color-secondary: hsl(220 8% 21%);
125
+ --color-secondary-foreground: hsl(220 10% 92%);
126
+ --color-destructive: hsl(0 62% 52%);
127
+ --color-destructive-foreground: hsl(0 0% 98%);
128
+ --color-ring: hsl(152 52% 52%);
129
+ --color-success: hsl(152 52% 52%);
130
+ --color-success-foreground: hsl(220 10% 6%);
131
+ --color-warning: hsl(42 88% 58%);
132
+ --color-warning-foreground: hsl(220 10% 6%);
133
+ --color-info: hsl(212 85% 64%);
134
+ --color-info-foreground: hsl(220 10% 6%);
120
135
  }
@@ -92,6 +92,6 @@
92
92
  color: var(--color-primary);
93
93
  background: var(--kbd-bg);
94
94
  border: 1px solid var(--color-border-medium);
95
- border-radius: 0.25rem;
95
+ border-radius: var(--radius-control);
96
96
  box-shadow: 0 1px 0 var(--scrollbar-thumb);
97
97
  }
@@ -27,12 +27,12 @@ html[data-theme^="minimal-"] {
27
27
  --background: 0 0% 4%;
28
28
  --color-foreground: #eee1d3;
29
29
  --foreground: 31 44% 88%;
30
- --color-card: #1a1a1a;
31
- --card: 0 0% 10%;
30
+ --color-card: #171717;
31
+ --card: 0 0% 9%;
32
32
  --color-card-foreground: #eee1d3;
33
33
  --card-foreground: 31 44% 88%;
34
- --color-popover: #141414;
35
- --popover: 0 0% 8%;
34
+ --color-popover: #1f1f1f;
35
+ --popover: 0 0% 12%;
36
36
  --color-popover-foreground: #eee1d3;
37
37
  --popover-foreground: 31 44% 88%;
38
38
  --color-muted: #111111;
@@ -165,12 +165,12 @@ html[data-theme^="minimal-"] {
165
165
  --background: 216 33% 6%;
166
166
  --color-foreground: #ccdeeb;
167
167
  --foreground: 205 44% 86%;
168
- --color-card: #1a222c;
169
- --card: 213 26% 14%;
168
+ --color-card: #151b23;
169
+ --card: 213 26% 11%;
170
170
  --color-card-foreground: #ccdeeb;
171
171
  --card-foreground: 205 44% 86%;
172
- --color-popover: #141c24;
173
- --popover: 210 29% 11%;
172
+ --color-popover: #19242e;
173
+ --popover: 210 29% 14%;
174
174
  --color-popover-foreground: #ccdeeb;
175
175
  --popover-foreground: 205 44% 86%;
176
176
  --color-muted: #111820;
@@ -303,12 +303,12 @@ html[data-theme^="minimal-"] {
303
303
  --background: 120 23% 5%;
304
304
  --color-foreground: #cfe1d4;
305
305
  --foreground: 137 23% 85%;
306
- --color-card: #1a241a;
307
- --card: 120 16% 12%;
306
+ --color-card: #151e15;
307
+ --card: 120 16% 10%;
308
308
  --color-card-foreground: #cfe1d4;
309
309
  --card-foreground: 137 23% 85%;
310
- --color-popover: #141c14;
311
- --popover: 120 17% 9%;
310
+ --color-popover: #1c271c;
311
+ --popover: 120 17% 13%;
312
312
  --color-popover-foreground: #cfe1d4;
313
313
  --popover-foreground: 137 23% 85%;
314
314
  --color-muted: #111811;
@@ -441,12 +441,12 @@ html[data-theme^="minimal-"] {
441
441
  --background: 0 23% 5%;
442
442
  --color-foreground: #ebd2d7;
443
443
  --foreground: 348 38% 87%;
444
- --color-card: #221a1a;
445
- --card: 0 13% 12%;
444
+ --color-card: #1d1616;
445
+ --card: 0 13% 10%;
446
446
  --color-card-foreground: #ebd2d7;
447
447
  --card-foreground: 348 38% 87%;
448
- --color-popover: #1c1414;
449
- --popover: 0 17% 9%;
448
+ --color-popover: #271c1c;
449
+ --popover: 0 17% 13%;
450
450
  --color-popover-foreground: #ebd2d7;
451
451
  --popover-foreground: 348 38% 87%;
452
452
  --color-muted: #181111;
@@ -579,12 +579,12 @@ html[data-theme^="minimal-"] {
579
579
  --background: 220 17% 6%;
580
580
  --color-foreground: #d7dce4;
581
581
  --foreground: 218 18% 87%;
582
- --color-card: #1a1d23;
583
- --card: 222 13% 12%;
582
+ --color-card: #181b20;
583
+ --card: 222 13% 11%;
584
584
  --color-card-foreground: #d7dce4;
585
585
  --card-foreground: 218 18% 87%;
586
- --color-popover: #15171c;
587
- --popover: 222 15% 10%;
586
+ --color-popover: #1e2229;
587
+ --popover: 222 15% 14%;
588
588
  --color-popover-foreground: #d7dce4;
589
589
  --popover-foreground: 218 18% 87%;
590
590
  --color-muted: #16181d;