@dorsk/tsumikit 0.64.1 → 0.66.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 CHANGED
@@ -57,10 +57,17 @@ import { Button, Field, Input, Modal, ThemePicker } from '@dorsk/tsumikit';
57
57
 
58
58
  ## Theming
59
59
 
60
- - 23 themes ship (light, highcontrast, gruvboxlight, solarizedlight,
60
+ - 31 themes ship (light, highcontrast, gruvboxlight, solarizedlight,
61
61
  everforestlight, rosepinedawn, latte, nordlight, tokyoday, kanagawalotus,
62
62
  sepia, dark, **colorblind** — Okabe-Ito —, mocha, dracula, nord, tokyonight,
63
- gruvbox, solarized, rosepine, onedark, everforest, monokai, amoled).
63
+ gruvbox, solarized, rosepine, onedark, everforest, monokai, amoled), plus a
64
+ **dim** tier between the bright and dark extremes: stone, fog, sage (light)
65
+ and slate, moss, espresso, zenburn (dark).
66
+ - Every built-in clears WCAG AA on `bg`, `bg-elev` and `surface`: text 7:1,
67
+ muted 5.5:1, faint and every accent/status hue 4.5:1, `accent-ink` on
68
+ `accent` 4.5:1, and `--c-border-strong` (the outline of every control) 3:1.
69
+ `tests/theme-contrast.mjs` holds the floors; the test suite fails on any
70
+ breach.
64
71
  - `<ThemePicker />` and `<FontScalePicker />` wire the stores to the UI. Theme
65
72
  is persisted to `localStorage` and applied with no flash (head snippet in
66
73
  `app.html`) and updates the mobile `<meta name="theme-color">`.
@@ -276,7 +283,8 @@ and an `attrs` object for `data-*`/test ids on the row; a checkable `pressed` it
276
283
  its icon leading and shows its check trailing, or uses the leading check slot when it has
277
284
  no icon; selecting closes the menu unless `closeOnSelect={false}` or the item sets `keepOpen`;
278
285
  rest props land on the trigger, `count`/`countMax` paint its corner badge and `panelStyle`
279
- sizes the panel),
286
+ sizes the panel; an item with a `control` snippet renders as a non-button row hosting a native
287
+ `<select>` or nested Popover trigger, keeping the icon column, row height and ↑/↓ navigation),
280
288
  Tabs (omit `panel` for a strip-only tablist of document tabs: `closable` + `onclose(id)`
281
289
  close through the ✕, Delete and middle-click, per-tab `leading` snippet, `title`,
282
290
  trailing `actions` snippet; `--tab-max-width` truncates long labels),
@@ -1,7 +1,8 @@
1
1
  <script lang="ts" module>
2
2
  export interface MenuItem {
3
3
  label: string;
4
- onselect: () => void;
4
+ /** Required for button rows; a `control` row's hosted control acts on its own. */
5
+ onselect?: () => void;
5
6
  icon?: import('../atoms/Icon.svelte').IconName;
6
7
  danger?: boolean;
7
8
  disabled?: boolean;
@@ -18,6 +19,13 @@
18
19
  keepOpen?: boolean;
19
20
  /** Custom row content (a rename Input, a slider…) replacing icon/label/tag. */
20
21
  content?: import('svelte').Snippet<[MenuItem]>;
22
+ /**
23
+ * A row that is itself a control (a native `<select>`, a nested Popover trigger):
24
+ * rendered as a non-button row with the menu's icon column and row height, its
25
+ * first focusable element joining ↑/↓ navigation. Replaces label/tag; `onselect`,
26
+ * `pressed` and `keepOpen` do not apply.
27
+ */
28
+ control?: import('svelte').Snippet<[MenuItem, { close: () => void }]>;
21
29
  /**
22
30
  * Extra attributes for the rendered row — `data-*`, `title`, `aria-describedby`…
23
31
  * The row's own semantics (`role`, `aria-checked`, `disabled`, `class`, `onclick`)
@@ -117,18 +125,27 @@
117
125
 
118
126
  let listEl = $state<HTMLDivElement | null>(null);
119
127
 
120
- function buttons(): HTMLButtonElement[] {
121
- return listEl
122
- ? Array.from(listEl.querySelectorAll<HTMLButtonElement>('[role="menuitem"]:not(:disabled), [role="menuitemcheckbox"]:not(:disabled)'))
123
- : [];
128
+ const ROW_TARGET = ':is(select, input, textarea, button):not(:disabled), a[href], [tabindex]:not([tabindex="-1"])';
129
+
130
+ function targets(): HTMLElement[] {
131
+ if (!listEl) return [];
132
+ const rows = listEl.querySelectorAll<HTMLElement>(
133
+ ':scope > [role="menuitem"]:not(:disabled), :scope > [role="menuitemcheckbox"]:not(:disabled), :scope > .menu-row:not([inert])'
134
+ );
135
+ return Array.from(rows).flatMap((row) => {
136
+ if (!row.classList.contains('menu-row')) return [row];
137
+ const control = row.querySelector<HTMLElement>(ROW_TARGET);
138
+ return control ? [control] : [];
139
+ });
124
140
  }
125
141
  function focusAt(i: number) {
126
- const b = buttons();
142
+ const b = targets();
127
143
  if (b.length) b[(i + b.length) % b.length].focus();
128
144
  }
129
145
  function onkeydown(e: KeyboardEvent) {
130
- const b = buttons();
131
- const i = b.indexOf(document.activeElement as HTMLButtonElement);
146
+ if ((e.target as Element).closest('[popover]') !== listEl?.closest('[popover]')) return;
147
+ const b = targets();
148
+ const i = b.indexOf(document.activeElement as HTMLElement);
132
149
  if (e.key === 'ArrowDown') {
133
150
  e.preventDefault();
134
151
  focusAt(i + 1);
@@ -146,7 +163,7 @@
146
163
  function select(item: MenuItem, close: () => void) {
147
164
  if (item.disabled) return;
148
165
  if (menuItemCloses(item, closeOnSelect)) close();
149
- item.onselect();
166
+ item.onselect?.();
150
167
  }
151
168
  </script>
152
169
 
@@ -186,6 +203,12 @@
186
203
  {#snippet children({ close }: { close: () => void })}
187
204
  <div bind:this={listEl} role="none" class="menu" data-tsu="Menu" tabindex="-1" {onkeydown}>
188
205
  {#each items as item (item.label)}
206
+ {#if item.control}
207
+ <div {...item.attrs as HTMLAttributes<HTMLDivElement>} role="none" class="menu-item menu-row" class:danger={item.danger} inert={item.disabled}>
208
+ {#if item.icon}<Icon name={item.icon} />{/if}
209
+ {@render item.control(item, { close })}
210
+ </div>
211
+ {:else}
189
212
  <button
190
213
  type="button"
191
214
  {...item.attrs}
@@ -216,6 +239,7 @@
216
239
  {#if glyphs.trailingCheck}<span class="menu-check menu-check-trailing"><Icon name="check" /></span>{/if}
217
240
  {/if}
218
241
  </button>
242
+ {/if}
219
243
  {/each}
220
244
  </div>
221
245
  {/snippet}
@@ -241,8 +265,12 @@
241
265
  font-size: var(--fs-sm);
242
266
  white-space: nowrap;
243
267
  }
268
+ .menu-row {
269
+ position: relative;
270
+ }
244
271
  .menu-item:hover:not(:disabled),
245
- .menu-item:focus-visible {
272
+ .menu-item:focus-visible,
273
+ .menu-row:focus-within {
246
274
  background: var(--bg-elevated-2);
247
275
  outline: none;
248
276
  }
@@ -273,7 +301,8 @@
273
301
  margin-inline-start: 0;
274
302
  padding-inline-start: 0;
275
303
  }
276
- .menu-item:disabled {
304
+ .menu-item:disabled,
305
+ .menu-row[inert] {
277
306
  opacity: 0.45;
278
307
  cursor: not-allowed;
279
308
  }
@@ -1,6 +1,7 @@
1
1
  export interface MenuItem {
2
2
  label: string;
3
- onselect: () => void;
3
+ /** Required for button rows; a `control` row's hosted control acts on its own. */
4
+ onselect?: () => void;
4
5
  icon?: import('../atoms/Icon.svelte').IconName;
5
6
  danger?: boolean;
6
7
  disabled?: boolean;
@@ -17,6 +18,15 @@ export interface MenuItem {
17
18
  keepOpen?: boolean;
18
19
  /** Custom row content (a rename Input, a slider…) replacing icon/label/tag. */
19
20
  content?: import('svelte').Snippet<[MenuItem]>;
21
+ /**
22
+ * A row that is itself a control (a native `<select>`, a nested Popover trigger):
23
+ * rendered as a non-button row with the menu's icon column and row height, its
24
+ * first focusable element joining ↑/↓ navigation. Replaces label/tag; `onselect`,
25
+ * `pressed` and `keepOpen` do not apply.
26
+ */
27
+ control?: import('svelte').Snippet<[MenuItem, {
28
+ close: () => void;
29
+ }]>;
20
30
  /**
21
31
  * Extra attributes for the rendered row — `data-*`, `title`, `aria-describedby`…
22
32
  * The row's own semantics (`role`, `aria-checked`, `disabled`, `class`, `onclick`)
@@ -65,6 +65,24 @@ export declare const THEMES: readonly [{
65
65
  readonly icon: "✶";
66
66
  readonly themeColor: "#f4ecd8";
67
67
  readonly mode: "light";
68
+ }, {
69
+ readonly id: "stone";
70
+ readonly label: "Stone";
71
+ readonly icon: "◌";
72
+ readonly themeColor: "#d6d1c7";
73
+ readonly mode: "light";
74
+ }, {
75
+ readonly id: "fog";
76
+ readonly label: "Fog";
77
+ readonly icon: "≋";
78
+ readonly themeColor: "#cdd4dc";
79
+ readonly mode: "light";
80
+ }, {
81
+ readonly id: "sage";
82
+ readonly label: "Sage";
83
+ readonly icon: "❧";
84
+ readonly themeColor: "#cfd6c9";
85
+ readonly mode: "light";
68
86
  }, {
69
87
  readonly id: "dark";
70
88
  readonly label: "Dark";
@@ -143,6 +161,30 @@ export declare const THEMES: readonly [{
143
161
  readonly icon: "◼";
144
162
  readonly themeColor: "#000000";
145
163
  readonly mode: "dark";
164
+ }, {
165
+ readonly id: "slate";
166
+ readonly label: "Slate";
167
+ readonly icon: "▤";
168
+ readonly themeColor: "#3a414b";
169
+ readonly mode: "dark";
170
+ }, {
171
+ readonly id: "moss";
172
+ readonly label: "Moss";
173
+ readonly icon: "❦";
174
+ readonly themeColor: "#383f36";
175
+ readonly mode: "dark";
176
+ }, {
177
+ readonly id: "espresso";
178
+ readonly label: "Espresso";
179
+ readonly icon: "◉";
180
+ readonly themeColor: "#463a31";
181
+ readonly mode: "dark";
182
+ }, {
183
+ readonly id: "zenburn";
184
+ readonly label: "Zenburn";
185
+ readonly icon: "Z";
186
+ readonly themeColor: "#3f3f3f";
187
+ readonly mode: "dark";
146
188
  }];
147
189
  export type Mode = (typeof THEMES)[number]['id'];
148
190
  export type ThemeMode = (typeof THEMES)[number]['mode'];
@@ -42,6 +42,10 @@ export const THEMES = [
42
42
  { id: 'tokyoday', label: 'Tokyo Night Day', icon: '✧', themeColor: '#e1e2e7', mode: 'light' },
43
43
  { id: 'kanagawalotus', label: 'Kanagawa Lotus', icon: '❁', themeColor: '#f2ecbc', mode: 'light' },
44
44
  { id: 'sepia', label: 'Sepia', icon: '✶', themeColor: '#f4ecd8', mode: 'light' },
45
+ // ── Dim light ── muted gray bases, well below paper-white
46
+ { id: 'stone', label: 'Stone', icon: '◌', themeColor: '#d6d1c7', mode: 'light' },
47
+ { id: 'fog', label: 'Fog', icon: '≋', themeColor: '#cdd4dc', mode: 'light' },
48
+ { id: 'sage', label: 'Sage', icon: '❧', themeColor: '#cfd6c9', mode: 'light' },
45
49
  // ── Dark ──
46
50
  { id: 'dark', label: 'Dark', icon: '☾', themeColor: '#0f1115', mode: 'dark' },
47
51
  { id: 'colorblind', label: 'Color-blind safe', icon: '◐', themeColor: '#16181d', mode: 'dark' },
@@ -56,6 +60,11 @@ export const THEMES = [
56
60
  { id: 'everforest', label: 'Everforest', icon: '☘', themeColor: '#2d353b', mode: 'dark' },
57
61
  { id: 'monokai', label: 'Monokai', icon: '✸', themeColor: '#272822', mode: 'dark' },
58
62
  { id: 'amoled', label: 'AMOLED (high contrast)', icon: '◼', themeColor: '#000000', mode: 'dark' },
63
+ // ── Dim dark ── lifted gray bases, well above near-black
64
+ { id: 'slate', label: 'Slate', icon: '▤', themeColor: '#3a414b', mode: 'dark' },
65
+ { id: 'moss', label: 'Moss', icon: '❦', themeColor: '#383f36', mode: 'dark' },
66
+ { id: 'espresso', label: 'Espresso', icon: '◉', themeColor: '#463a31', mode: 'dark' },
67
+ { id: 'zenburn', label: 'Zenburn', icon: 'Z', themeColor: '#3f3f3f', mode: 'dark' },
59
68
  ];
60
69
  const FALLBACK_ICON = '◈';
61
70
  class Theme {
@@ -6,6 +6,8 @@
6
6
  * Consumer theme contract: a `[data-theme="x"]` block must set `color-scheme`
7
7
  * (light themes; :root defaults to dark), every --c-* palette token, the three
8
8
  * --shadow-* tokens and the three --mach-*-sl pairs. --md-code-bg is optional.
9
+ *
10
+ * Built-ins must clear the contrast floors in tests/theme-contrast.mjs.
9
11
  */
10
12
 
11
13
  [data-theme="light"] {
@@ -15,20 +17,20 @@
15
17
  --c-bg-elev-2: #eef0f3;
16
18
  --c-surface: #ffffff;
17
19
  --c-border: #d9dde3;
18
- --c-border-strong: #c2c8d1;
20
+ --c-border-strong: #8a9098;
19
21
  --c-text: #1a1d23;
20
22
  --c-text-muted: #5b6472;
21
- --c-text-faint: #8a93a3;
22
- --c-accent: #1f9d6b;
23
+ --c-text-faint: #6a7282;
24
+ --c-accent: #008256;
23
25
  --c-accent-ink: #ffffff;
24
26
  --c-accent-dim: #9bd9c2;
25
- --c-blue: #2f7ddb;
26
- --c-amber: #c98a1d;
27
- --c-red: #d6463f;
28
- --c-green: #1f9d6b;
27
+ --c-blue: #1165c1;
28
+ --c-amber: #9b6700;
29
+ --c-red: #cd3e38;
30
+ --c-green: #008256;
29
31
  --c-violet: #7c3aed;
30
- --c-gold: #c98a1d;
31
- --c-teal: #0d9488;
32
+ --c-gold: #9b6700;
33
+ --c-teal: #008076;
32
34
  --md-code-bg: color-mix(in srgb, var(--c-blue) 12%, var(--c-bg));
33
35
  --shadow-sm: 0 1px 2px rgba(20, 24, 31, 0.08);
34
36
  --shadow-md: 0 6px 20px rgba(20, 24, 31, 0.12);
@@ -48,20 +50,20 @@
48
50
  --c-bg-elev-2: #ece1c6;
49
51
  --c-surface: #faf3e3;
50
52
  --c-border: #ddccab;
51
- --c-border-strong: #c8b48c;
53
+ --c-border-strong: #998660;
52
54
  --c-text: #3b2f1e;
53
- --c-text-muted: #6f5d42;
54
- --c-text-faint: #9a8868;
55
- --c-accent: #5a8250;
55
+ --c-text-muted: #6d5b40;
56
+ --c-text-faint: #7b694a;
57
+ --c-accent: #4e7544;
56
58
  --c-accent-ink: #faf3e3;
57
59
  --c-accent-dim: #aec79f;
58
- --c-blue: #2c6f9b;
59
- --c-amber: #b07a18;
60
+ --c-blue: #1e638f;
61
+ --c-amber: #916200;
60
62
  --c-red: #b5403a;
61
- --c-green: #5a8250;
62
- --c-violet: #8a5fa8;
63
- --c-gold: #a87d1f;
64
- --c-teal: #2a8f86;
63
+ --c-green: #4e7544;
64
+ --c-violet: #8459a2;
65
+ --c-gold: #8b6400;
66
+ --c-teal: #007870;
65
67
  --md-code-bg: color-mix(in srgb, var(--c-blue) 14%, var(--c-bg));
66
68
  --shadow-sm: 0 1px 2px rgba(80, 60, 30, 0.1);
67
69
  --shadow-md: 0 6px 20px rgba(80, 60, 30, 0.14);
@@ -79,10 +81,10 @@
79
81
  --c-bg-elev-2: #313244;
80
82
  --c-surface: #313244;
81
83
  --c-border: #45475a;
82
- --c-border-strong: #585b70;
84
+ --c-border-strong: #777b91;
83
85
  --c-text: #cdd6f4;
84
86
  --c-text-muted: #bac2de;
85
- --c-text-faint: #7f849c;
87
+ --c-text-faint: #959ab2;
86
88
  --c-accent: #cba6f7;
87
89
  --c-accent-ink: #1e1e2e;
88
90
  --c-accent-dim: #6c7086;
@@ -109,16 +111,16 @@
109
111
  --c-bg-elev-2: #44475a;
110
112
  --c-surface: #343746;
111
113
  --c-border: #44475a;
112
- --c-border-strong: #6272a4;
114
+ --c-border-strong: #6f7fb2;
113
115
  --c-text: #f8f8f2;
114
116
  --c-text-muted: #c7c9d1;
115
- --c-text-faint: #6272a4;
117
+ --c-text-faint: #8d9fd4;
116
118
  --c-accent: #bd93f9;
117
119
  --c-accent-ink: #1d1726;
118
120
  --c-accent-dim: #6f558f;
119
121
  --c-blue: #8be9fd;
120
122
  --c-amber: #ffb86c;
121
- --c-red: #ff5555;
123
+ --c-red: #ff7570;
122
124
  --c-green: #50fa7b;
123
125
  --c-violet: #bd93f9;
124
126
  --c-gold: #f1fa8c;
@@ -139,18 +141,18 @@
139
141
  --c-bg-elev-2: #434c5e;
140
142
  --c-surface: #3b4252;
141
143
  --c-border: #4c566a;
142
- --c-border-strong: #5e81ac;
144
+ --c-border-strong: #6b8fbb;
143
145
  --c-text: #eceff4;
144
146
  --c-text-muted: #d8dee9;
145
147
  --c-text-faint: #8fbcbb;
146
148
  --c-accent: #88c0d0;
147
149
  --c-accent-ink: #1f242d;
148
150
  --c-accent-dim: #5e81ac;
149
- --c-blue: #81a1c1;
151
+ --c-blue: #95b6d6;
150
152
  --c-amber: #ebcb8b;
151
- --c-red: #bf616a;
153
+ --c-red: #f59199;
152
154
  --c-green: #a3be8c;
153
- --c-violet: #b48ead;
155
+ --c-violet: #c9a2c1;
154
156
  --c-gold: #ebcb8b;
155
157
  --c-teal: #8fbcbb;
156
158
  --shadow-sm: 0 1px 2px rgba(20, 25, 34, 0.34);
@@ -169,10 +171,10 @@
169
171
  --c-bg-elev-2: #24283b;
170
172
  --c-surface: #1f2233;
171
173
  --c-border: #2f344d;
172
- --c-border-strong: #414868;
174
+ --c-border-strong: #636b8d;
173
175
  --c-text: #c0caf5;
174
176
  --c-text-muted: #9aa5ce;
175
- --c-text-faint: #565f89;
177
+ --c-text-faint: #7e88b5;
176
178
  --c-accent: #7aa2f7;
177
179
  --c-accent-ink: #11121d;
178
180
  --c-accent-dim: #3d59a1;
@@ -198,16 +200,16 @@
198
200
  --c-bg-elev-2: #3c3836;
199
201
  --c-surface: #32302f;
200
202
  --c-border: #504945;
201
- --c-border-strong: #665c54;
203
+ --c-border-strong: #81776f;
202
204
  --c-text: #ebdbb2;
203
205
  --c-text-muted: #d5c4a1;
204
206
  --c-text-faint: #a89984;
205
207
  --c-accent: #fe8019;
206
208
  --c-accent-ink: #1d1a14;
207
209
  --c-accent-dim: #af3a03;
208
- --c-blue: #83a598;
210
+ --c-blue: #87a99c;
209
211
  --c-amber: #fabd2f;
210
- --c-red: #fb4934;
212
+ --c-red: #ff6550;
211
213
  --c-green: #b8bb26;
212
214
  --c-violet: #d3869b;
213
215
  --c-gold: #fabd2f;
@@ -227,20 +229,20 @@
227
229
  --c-bg-elev-2: #0a4350;
228
230
  --c-surface: #073642;
229
231
  --c-border: #0f4d5c;
230
- --c-border-strong: #586e75;
232
+ --c-border-strong: #677e85;
231
233
  --c-text: #eee8d5;
232
- --c-text-muted: #93a1a1;
233
- --c-text-faint: #657b83;
234
- --c-accent: #2aa198;
234
+ --c-text-muted: #9dacac;
235
+ --c-text-faint: #859ca4;
236
+ --c-accent: #35a99f;
235
237
  --c-accent-ink: #002b36;
236
238
  --c-accent-dim: #1a6b66;
237
- --c-blue: #268bd2;
238
- --c-amber: #b58900;
239
- --c-red: #dc322f;
240
- --c-green: #859900;
241
- --c-violet: #6c71c4;
242
- --c-gold: #b58900;
243
- --c-teal: #2aa198;
239
+ --c-blue: #47a7f0;
240
+ --c-amber: #be9218;
241
+ --c-red: #ff665b;
242
+ --c-green: #8da218;
243
+ --c-violet: #8a91e7;
244
+ --c-gold: #be9218;
245
+ --c-teal: #35a99f;
244
246
  --shadow-sm: 0 1px 2px rgba(0, 17, 22, 0.42);
245
247
  --shadow-md: 0 6px 20px rgba(0, 17, 22, 0.5);
246
248
  --shadow-lg: 0 12px 40px rgba(0, 17, 22, 0.58);
@@ -256,10 +258,10 @@
256
258
  --c-bg-elev-2: #26233a;
257
259
  --c-surface: #1f1d2e;
258
260
  --c-border: #2a2839;
259
- --c-border-strong: #403d52;
261
+ --c-border-strong: #6a677e;
260
262
  --c-text: #e0def4;
261
- --c-text-muted: #908caa;
262
- --c-text-faint: #6e6a86;
263
+ --c-text-muted: #9692b0;
264
+ --c-text-faint: #8783a0;
263
265
  --c-accent: #c4a7e7;
264
266
  --c-accent-ink: #14121d;
265
267
  --c-accent-dim: #6c5d8a;
@@ -285,18 +287,18 @@
285
287
  --c-bg-elev-2: #353b45;
286
288
  --c-surface: #2f343f;
287
289
  --c-border: #3e4451;
288
- --c-border-strong: #4b5263;
289
- --c-text: #abb2bf;
290
- --c-text-muted: #9da5b4;
291
- --c-text-faint: #5c6370;
290
+ --c-border-strong: #757d8f;
291
+ --c-text: #bcc3d0;
292
+ --c-text-muted: #a5adbc;
293
+ --c-text-faint: #949caa;
292
294
  --c-accent: #61afef;
293
295
  --c-accent-ink: #11151c;
294
296
  --c-accent-dim: #2c6da3;
295
297
  --c-blue: #61afef;
296
298
  --c-amber: #e5c07b;
297
- --c-red: #e06c75;
299
+ --c-red: #ed7880;
298
300
  --c-green: #98c379;
299
- --c-violet: #c678dd;
301
+ --c-violet: #cc7ee3;
300
302
  --c-gold: #e5c07b;
301
303
  --c-teal: #56b6c2;
302
304
  --shadow-sm: 0 1px 2px rgba(17, 19, 25, 0.4);
@@ -314,16 +316,16 @@
314
316
  --c-bg-elev-2: #3d484d;
315
317
  --c-surface: #343f44;
316
318
  --c-border: #475258;
317
- --c-border-strong: #4f585e;
318
- --c-text: #d3c6aa;
319
- --c-text-muted: #a7b0a3;
320
- --c-text-faint: #859289;
319
+ --c-border-strong: #7f898f;
320
+ --c-text: #dccfb3;
321
+ --c-text-muted: #b3bcaf;
322
+ --c-text-faint: #9daba1;
321
323
  --c-accent: #a7c080;
322
324
  --c-accent-ink: #1c2226;
323
325
  --c-accent-dim: #5c6f49;
324
- --c-blue: #7fbbb3;
326
+ --c-blue: #81beb6;
325
327
  --c-amber: #dbbc7f;
326
- --c-red: #e67e80;
328
+ --c-red: #f38a8b;
327
329
  --c-green: #a7c080;
328
330
  --c-violet: #d699b6;
329
331
  --c-gold: #dbbc7f;
@@ -343,16 +345,16 @@
343
345
  --c-bg-elev-2: #383830;
344
346
  --c-surface: #2f302a;
345
347
  --c-border: #49483e;
346
- --c-border-strong: #5b5a4e;
348
+ --c-border-strong: #7a796c;
347
349
  --c-text: #f8f8f2;
348
350
  --c-text-muted: #cfcfc2;
349
- --c-text-faint: #75715e;
351
+ --c-text-faint: #9b9783;
350
352
  --c-accent: #a6e22e;
351
353
  --c-accent-ink: #14160f;
352
354
  --c-accent-dim: #5f7d18;
353
355
  --c-blue: #66d9ef;
354
356
  --c-amber: #fd971f;
355
- --c-red: #f92672;
357
+ --c-red: #ff5c88;
356
358
  --c-green: #a6e22e;
357
359
  --c-violet: #ae81ff;
358
360
  --c-gold: #e6db74;
@@ -447,7 +449,7 @@
447
449
  --c-bg-elev-2: #262a33;
448
450
  --c-surface: #1d2027;
449
451
  --c-border: #353a44;
450
- --c-border-strong: #4a505c;
452
+ --c-border-strong: #646a77;
451
453
  --c-text: #f2f4f8;
452
454
  --c-text-muted: #b6bdc9;
453
455
  --c-text-faint: #828b99;
@@ -456,7 +458,7 @@
456
458
  --c-accent-dim: #2c6f93;
457
459
  --c-blue: #56b4e9; /* sky blue */
458
460
  --c-amber: #e69f00; /* orange */
459
- --c-red: #d55e00; /* vermillion */
461
+ --c-red: #db630e; /* vermillion */
460
462
  --c-green: #009e73; /* bluish green */
461
463
  --c-violet: #cc79a7; /* reddish purple */
462
464
  --c-gold: #f0e442; /* yellow */
@@ -485,20 +487,20 @@
485
487
  --c-bg-elev-2: #ebdbb2;
486
488
  --c-surface: #f9f5d7;
487
489
  --c-border: #d5c4a1;
488
- --c-border-strong: #bdae93;
490
+ --c-border-strong: #98896f;
489
491
  --c-text: #3c3836;
490
492
  --c-text-muted: #504945;
491
- --c-text-faint: #7c6f64;
493
+ --c-text-faint: #786b60;
492
494
  --c-accent: #af3a03;
493
495
  --c-accent-ink: #fbf1c7;
494
496
  --c-accent-dim: #d65d0e;
495
497
  --c-blue: #076678;
496
- --c-amber: #b57614;
498
+ --c-amber: #996100;
497
499
  --c-red: #9d0006;
498
- --c-green: #79740e;
500
+ --c-green: #767006;
499
501
  --c-violet: #8f3f71;
500
- --c-gold: #b57614;
501
- --c-teal: #427b58;
502
+ --c-gold: #996100;
503
+ --c-teal: #407956;
502
504
  --md-code-bg: color-mix(in srgb, var(--c-blue) 12%, var(--c-bg));
503
505
  --shadow-sm: 0 1px 2px rgba(80, 60, 30, 0.1);
504
506
  --shadow-md: 0 6px 20px rgba(80, 60, 30, 0.14);
@@ -516,20 +518,20 @@
516
518
  --c-bg-elev-2: #eee8d5;
517
519
  --c-surface: #fbf3e0;
518
520
  --c-border: #ddd6c1;
519
- --c-border-strong: #cbc4ad;
521
+ --c-border-strong: #938d77;
520
522
  --c-text: #073642;
521
- --c-text-muted: #586e75;
522
- --c-text-faint: #839496;
523
- --c-accent: #2aa198;
523
+ --c-text-muted: #50656c;
524
+ --c-text-faint: #627274;
525
+ --c-accent: #007d76;
524
526
  --c-accent-ink: #fdf6e3;
525
527
  --c-accent-dim: #2aa198;
526
- --c-blue: #268bd2;
527
- --c-amber: #b58900;
528
- --c-red: #dc322f;
529
- --c-green: #859900;
530
- --c-violet: #6c71c4;
531
- --c-gold: #b58900;
532
- --c-teal: #2aa198;
528
+ --c-blue: #006aa9;
529
+ --c-amber: #8d6a00;
530
+ --c-red: #d52a29;
531
+ --c-green: #677700;
532
+ --c-violet: #6367b9;
533
+ --c-gold: #8d6a00;
534
+ --c-teal: #007d76;
533
535
  --md-code-bg: color-mix(in srgb, var(--c-blue) 12%, var(--c-bg));
534
536
  --shadow-sm: 0 1px 2px rgba(88, 110, 117, 0.12);
535
537
  --shadow-md: 0 6px 20px rgba(88, 110, 117, 0.16);
@@ -547,20 +549,20 @@
547
549
  --c-bg-elev-2: #efebd4;
548
550
  --c-surface: #f4f0d9;
549
551
  --c-border: #e0dcc7;
550
- --c-border-strong: #bdc3af;
551
- --c-text: #5c6a72;
552
- --c-text-muted: #708089;
553
- --c-text-faint: #939f91;
554
- --c-accent: #8da101;
552
+ --c-border-strong: #878c79;
553
+ --c-text: #45525a;
554
+ --c-text-muted: #53626b;
555
+ --c-text-faint: #657063;
556
+ --c-accent: #657400;
555
557
  --c-accent-ink: #fdf6e3;
556
558
  --c-accent-dim: #8da101;
557
- --c-blue: #3a94c5;
558
- --c-amber: #dfa000;
559
- --c-red: #f85552;
560
- --c-green: #8da101;
561
- --c-violet: #df69ba;
562
- --c-gold: #dfa000;
563
- --c-teal: #35a77c;
559
+ --c-blue: #006c9b;
560
+ --c-amber: #8f6500;
561
+ --c-red: #cf2b30;
562
+ --c-green: #657400;
563
+ --c-violet: #b34091;
564
+ --c-gold: #8f6500;
565
+ --c-teal: #007c57;
564
566
  --md-code-bg: color-mix(in srgb, var(--c-blue) 12%, var(--c-bg));
565
567
  --shadow-sm: 0 1px 2px rgba(92, 106, 114, 0.12);
566
568
  --shadow-md: 0 6px 20px rgba(92, 106, 114, 0.16);
@@ -578,20 +580,20 @@
578
580
  --c-bg-elev-2: #f2e9e1;
579
581
  --c-surface: #fffaf3;
580
582
  --c-border: #dfdad9;
581
- --c-border-strong: #cecacd;
582
- --c-text: #575279;
583
- --c-text-muted: #797593;
584
- --c-text-faint: #9893a5;
585
- --c-accent: #907aa9;
583
+ --c-border-strong: #908c8f;
584
+ --c-text: #534e75;
585
+ --c-text-muted: #635f7c;
586
+ --c-text-faint: #736e7f;
587
+ --c-accent: #7d6795;
586
588
  --c-accent-ink: #faf4ed;
587
589
  --c-accent-dim: #907aa9;
588
590
  --c-blue: #286983;
589
- --c-amber: #ea9d34;
590
- --c-red: #b4637a;
591
- --c-green: #56949f;
592
- --c-violet: #907aa9;
593
- --c-gold: #ea9d34;
594
- --c-teal: #56949f;
591
+ --c-amber: #9e6300;
592
+ --c-red: #a7576e;
593
+ --c-green: #3b7984;
594
+ --c-violet: #7d6795;
595
+ --c-gold: #9e6300;
596
+ --c-teal: #3b7984;
595
597
  --md-code-bg: color-mix(in srgb, var(--c-blue) 12%, var(--c-bg));
596
598
  --shadow-sm: 0 1px 2px rgba(87, 82, 121, 0.1);
597
599
  --shadow-md: 0 6px 20px rgba(87, 82, 121, 0.14);
@@ -609,20 +611,20 @@
609
611
  --c-bg-elev-2: #dce0e8;
610
612
  --c-surface: #e6e9ef;
611
613
  --c-border: #ccd0da;
612
- --c-border-strong: #bcc0cc;
613
- --c-text: #4c4f69;
614
- --c-text-muted: #5c5f77;
615
- --c-text-faint: #8c8fa1;
616
- --c-accent: #8839ef;
614
+ --c-border-strong: #828591;
615
+ --c-text: #484b64;
616
+ --c-text-muted: #575a72;
617
+ --c-text-faint: #656879;
618
+ --c-accent: #8738ee;
617
619
  --c-accent-ink: #eff1f5;
618
620
  --c-accent-dim: #8839ef;
619
- --c-blue: #1e66f5;
620
- --c-amber: #df8e1d;
621
- --c-red: #d20f39;
622
- --c-green: #40a02b;
623
- --c-violet: #8839ef;
624
- --c-gold: #df8e1d;
625
- --c-teal: #179299;
621
+ --c-blue: #0f58e7;
622
+ --c-amber: #965c00;
623
+ --c-red: #d10d38;
624
+ --c-green: #1e7900;
625
+ --c-violet: #8738ee;
626
+ --c-gold: #965c00;
627
+ --c-teal: #00757b;
626
628
  --md-code-bg: color-mix(in srgb, var(--c-blue) 10%, var(--c-bg));
627
629
  --shadow-sm: 0 1px 2px rgba(76, 79, 105, 0.1);
628
630
  --shadow-md: 0 6px 20px rgba(76, 79, 105, 0.14);
@@ -641,20 +643,20 @@
641
643
  --c-bg-elev-2: #e5e9f0;
642
644
  --c-surface: #f4f6f9;
643
645
  --c-border: #d8dee9;
644
- --c-border-strong: #c2cad6;
646
+ --c-border-strong: #838a96;
645
647
  --c-text: #2e3440;
646
648
  --c-text-muted: #434c5e;
647
- --c-text-faint: #6b7689;
648
- --c-accent: #5e81ac;
649
+ --c-text-faint: #626d80;
650
+ --c-accent: #4c6f99;
649
651
  --c-accent-ink: #eceff4;
650
652
  --c-accent-dim: #5e81ac;
651
- --c-blue: #5e81ac;
652
- --c-amber: #9a6f12;
653
- --c-red: #bf616a;
653
+ --c-blue: #41648d;
654
+ --c-amber: #8f6500;
655
+ --c-red: #ab4f59;
654
656
  --c-green: #5a7444;
655
- --c-violet: #9a6c93;
656
- --c-gold: #9a6f12;
657
- --c-teal: #3a8a87;
657
+ --c-violet: #8b5e84;
658
+ --c-gold: #8f6500;
659
+ --c-teal: #257875;
658
660
  --md-code-bg: color-mix(in srgb, var(--c-blue) 12%, var(--c-bg));
659
661
  --shadow-sm: 0 1px 2px rgba(46, 52, 64, 0.1);
660
662
  --shadow-md: 0 6px 20px rgba(46, 52, 64, 0.14);
@@ -673,20 +675,20 @@
673
675
  --c-bg-elev-2: #d5d6db;
674
676
  --c-surface: #eaeaee;
675
677
  --c-border: #c4c8da;
676
- --c-border-strong: #a8acc4;
677
- --c-text: #3760bf;
678
- --c-text-muted: #6172b0;
679
- --c-text-faint: #848cb5;
680
- --c-accent: #2e7de9;
678
+ --c-border-strong: #7c8097;
679
+ --c-text: #1c419d;
680
+ --c-text-muted: #455490;
681
+ --c-text-faint: #5c638a;
682
+ --c-accent: #0961cb;
681
683
  --c-accent-ink: #ffffff;
682
684
  --c-accent-dim: #2e7de9;
683
- --c-blue: #2e7de9;
684
- --c-amber: #8c6c3e;
685
- --c-red: #f52a65;
686
- --c-green: #587539;
687
- --c-violet: #9854f1;
688
- --c-gold: #8c6c3e;
689
- --c-teal: #118c74;
685
+ --c-blue: #0055b8;
686
+ --c-amber: #7f5f31;
687
+ --c-red: #c9004c;
688
+ --c-green: #516d32;
689
+ --c-violet: #833bd8;
690
+ --c-gold: #7f5f31;
691
+ --c-teal: #00725e;
690
692
  --md-code-bg: color-mix(in srgb, var(--c-blue) 12%, var(--c-bg));
691
693
  --shadow-sm: 0 1px 2px rgba(55, 96, 191, 0.1);
692
694
  --shadow-md: 0 6px 20px rgba(55, 96, 191, 0.14);
@@ -705,20 +707,20 @@
705
707
  --c-bg-elev-2: #e5ddb0;
706
708
  --c-surface: #ebe3b0;
707
709
  --c-border: #d5cea3;
708
- --c-border-strong: #c9c193;
709
- --c-text: #545464;
710
- --c-text-muted: #766b90;
711
- --c-text-faint: #a09cac;
710
+ --c-border-strong: #898156;
711
+ --c-text: #464656;
712
+ --c-text-muted: #5d5276;
713
+ --c-text-faint: #666371;
712
714
  --c-accent: #624c83;
713
715
  --c-accent-ink: #f2ecbc;
714
716
  --c-accent-dim: #624c83;
715
- --c-blue: #4d699b;
716
- --c-amber: #cc6d00;
717
- --c-red: #c84053;
718
- --c-green: #6f894e;
717
+ --c-blue: #455f91;
718
+ --c-amber: #9b5100;
719
+ --c-red: #b83046;
720
+ --c-green: #536c32;
719
721
  --c-violet: #624c83;
720
- --c-gold: #836f4a;
721
- --c-teal: #597b75;
722
+ --c-gold: #76623e;
723
+ --c-teal: #4a6b65;
722
724
  --md-code-bg: color-mix(in srgb, var(--c-blue) 12%, var(--c-bg));
723
725
  --shadow-sm: 0 1px 2px rgba(84, 84, 100, 0.12);
724
726
  --shadow-md: 0 6px 20px rgba(84, 84, 100, 0.16);
@@ -727,3 +729,215 @@
727
729
  --mach-fg-sl: 35% 34%;
728
730
  --mach-border-sl: 30% 66%;
729
731
  }
732
+
733
+ /* ===================================================================
734
+ Dim tier — between the bright and dark extremes. Dim-dark bases sit
735
+ around OKLCH L 0.37 and dim-light around 0.86: true mid-tones (L 0.5–0.7)
736
+ cap text contrast near 4.5:1 and cannot hold a muted/faint hierarchy.
737
+ =================================================================== */
738
+
739
+ /* ---- Slate — dim gray-blue. */
740
+ [data-theme="slate"] {
741
+ --c-bg: #3a414b;
742
+ --c-bg-elev: #424a55;
743
+ --c-bg-elev-2: #4a535f;
744
+ --c-surface: #444c57;
745
+ --c-border: #535c69;
746
+ --c-border-strong: #8e99a9;
747
+ --c-text: #e6eaf0;
748
+ --c-text-muted: #c7cfd9;
749
+ --c-text-faint: #b3bcc9;
750
+ --c-accent: #8fc1ff;
751
+ --c-accent-ink: #1d232b;
752
+ --c-accent-dim: #4f6680;
753
+ --c-blue: #9bcaff;
754
+ --c-amber: #f2c879;
755
+ --c-red: #ffa3a3;
756
+ --c-green: #9fdcae;
757
+ --c-violet: #c9b3ff;
758
+ --c-gold: #e8cf86;
759
+ --c-teal: #8edcd4;
760
+ --shadow-sm: 0 1px 2px rgba(15, 18, 24, 0.3);
761
+ --shadow-md: 0 6px 20px rgba(15, 18, 24, 0.36);
762
+ --shadow-lg: 0 12px 40px rgba(15, 18, 24, 0.44);
763
+ --mach-bg-sl: 35% 30%;
764
+ --mach-fg-sl: 60% 86%;
765
+ --mach-border-sl: 35% 48%;
766
+ }
767
+
768
+ /* ---- Moss — dim gray-green. */
769
+ [data-theme="moss"] {
770
+ --c-bg: #383f36;
771
+ --c-bg-elev: #40483e;
772
+ --c-bg-elev-2: #485146;
773
+ --c-surface: #424a40;
774
+ --c-border: #525b4f;
775
+ --c-border-strong: #8d9788;
776
+ --c-text: #e4e8dc;
777
+ --c-text-muted: #c5cbbd;
778
+ --c-text-faint: #b1b8a8;
779
+ --c-accent: #b5d68c;
780
+ --c-accent-ink: #1f251c;
781
+ --c-accent-dim: #5d7146;
782
+ --c-blue: #9cc7e6;
783
+ --c-amber: #e9c77e;
784
+ --c-red: #f0a39a;
785
+ --c-green: #b5d68c;
786
+ --c-violet: #cdb4e0;
787
+ --c-gold: #dcc97f;
788
+ --c-teal: #93d3c0;
789
+ --shadow-sm: 0 1px 2px rgba(16, 20, 15, 0.3);
790
+ --shadow-md: 0 6px 20px rgba(16, 20, 15, 0.36);
791
+ --shadow-lg: 0 12px 40px rgba(16, 20, 15, 0.44);
792
+ --mach-bg-sl: 30% 30%;
793
+ --mach-fg-sl: 50% 86%;
794
+ --mach-border-sl: 30% 48%;
795
+ }
796
+
797
+ /* ---- Espresso — dim warm brown. */
798
+ [data-theme="espresso"] {
799
+ --c-bg: #463a31;
800
+ --c-bg-elev: #4e4138;
801
+ --c-bg-elev-2: #57493f;
802
+ --c-surface: #50433a;
803
+ --c-border: #625347;
804
+ --c-border-strong: #a18e7e;
805
+ --c-text: #f0e6da;
806
+ --c-text-muted: #d4c6b6;
807
+ --c-text-faint: #c0b09d;
808
+ --c-accent: #e6b980;
809
+ --c-accent-ink: #2a2019;
810
+ --c-accent-dim: #7a5d3e;
811
+ --c-blue: #a8c8e0;
812
+ --c-amber: #f0c27a;
813
+ --c-red: #f2a08e;
814
+ --c-green: #b9d29a;
815
+ --c-violet: #d7b5d8;
816
+ --c-gold: #e6c977;
817
+ --c-teal: #9ed2c4;
818
+ --shadow-sm: 0 1px 2px rgba(24, 17, 12, 0.32);
819
+ --shadow-md: 0 6px 20px rgba(24, 17, 12, 0.38);
820
+ --shadow-lg: 0 12px 40px rgba(24, 17, 12, 0.46);
821
+ --mach-bg-sl: 30% 30%;
822
+ --mach-fg-sl: 55% 86%;
823
+ --mach-border-sl: 30% 48%;
824
+ }
825
+
826
+ /* ---- Zenburn — the classic low-contrast-on-gray palette. */
827
+ [data-theme="zenburn"] {
828
+ --c-bg: #3f3f3f;
829
+ --c-bg-elev: #474747;
830
+ --c-bg-elev-2: #4f4f4f;
831
+ --c-surface: #494949;
832
+ --c-border: #5b5b5b;
833
+ --c-border-strong: #959595;
834
+ --c-text: #e4e4d4;
835
+ --c-text-muted: #ccccbb;
836
+ --c-text-faint: #b9b9a9;
837
+ --c-accent: #8cd0d3;
838
+ --c-accent-ink: #2b2b2b;
839
+ --c-accent-dim: #5f7f7f;
840
+ --c-blue: #8cd0d3;
841
+ --c-amber: #dfaf8f;
842
+ --c-red: #e3a9a9;
843
+ --c-green: #9fc59f;
844
+ --c-violet: #f09ed6;
845
+ --c-gold: #f0dfaf;
846
+ --c-teal: #93e0e3;
847
+ --shadow-sm: 0 1px 2px rgba(20, 20, 20, 0.3);
848
+ --shadow-md: 0 6px 20px rgba(20, 20, 20, 0.36);
849
+ --shadow-lg: 0 12px 40px rgba(20, 20, 20, 0.44);
850
+ --mach-bg-sl: 25% 30%;
851
+ --mach-fg-sl: 45% 85%;
852
+ --mach-border-sl: 25% 48%;
853
+ }
854
+
855
+ /* ---- Stone — dim warm light gray. */
856
+ [data-theme="stone"] {
857
+ color-scheme: light;
858
+ --c-bg: #d6d1c7;
859
+ --c-bg-elev: #ddd9d0;
860
+ --c-bg-elev-2: #cdc7bc;
861
+ --c-surface: #dfdbd3;
862
+ --c-border: #bdb6a9;
863
+ --c-border-strong: #7c7467;
864
+ --c-text: #2a2620;
865
+ --c-text-muted: #4d473e;
866
+ --c-text-faint: #60594e;
867
+ --c-accent: #376252;
868
+ --c-accent-ink: #f3f0ea;
869
+ --c-accent-dim: #9db3a7;
870
+ --c-blue: #1f507a;
871
+ --c-amber: #775408;
872
+ --c-red: #9a3b30;
873
+ --c-green: #386433;
874
+ --c-violet: #6a4a8a;
875
+ --c-gold: #705705;
876
+ --c-teal: #24645f;
877
+ --shadow-sm: 0 1px 2px rgba(50, 42, 30, 0.1);
878
+ --shadow-md: 0 6px 20px rgba(50, 42, 30, 0.14);
879
+ --shadow-lg: 0 12px 40px rgba(50, 42, 30, 0.2);
880
+ --mach-bg-sl: 30% 80%;
881
+ --mach-fg-sl: 45% 26%;
882
+ --mach-border-sl: 25% 60%;
883
+ }
884
+
885
+ /* ---- Fog — dim cool light gray-blue. */
886
+ [data-theme="fog"] {
887
+ color-scheme: light;
888
+ --c-bg: #cdd4dc;
889
+ --c-bg-elev: #d5dbe2;
890
+ --c-bg-elev-2: #c3cbd4;
891
+ --c-surface: #d8dee5;
892
+ --c-border: #b2bcc8;
893
+ --c-border-strong: #6d7886;
894
+ --c-text: #1f252c;
895
+ --c-text-muted: #3e4753;
896
+ --c-text-faint: #525c69;
897
+ --c-accent: #2a5c99;
898
+ --c-accent-ink: #f2f5f8;
899
+ --c-accent-dim: #9bb2cf;
900
+ --c-blue: #1d4f8b;
901
+ --c-amber: #79540f;
902
+ --c-red: #9b3434;
903
+ --c-green: #2b6741;
904
+ --c-violet: #5f4a99;
905
+ --c-gold: #6e590b;
906
+ --c-teal: #1d646e;
907
+ --shadow-sm: 0 1px 2px rgba(25, 32, 42, 0.1);
908
+ --shadow-md: 0 6px 20px rgba(25, 32, 42, 0.14);
909
+ --shadow-lg: 0 12px 40px rgba(25, 32, 42, 0.2);
910
+ --mach-bg-sl: 35% 80%;
911
+ --mach-fg-sl: 50% 26%;
912
+ --mach-border-sl: 30% 60%;
913
+ }
914
+
915
+ /* ---- Sage — dim light gray-green. */
916
+ [data-theme="sage"] {
917
+ color-scheme: light;
918
+ --c-bg: #cfd6c9;
919
+ --c-bg-elev: #d7ddd2;
920
+ --c-bg-elev-2: #c5cdbe;
921
+ --c-surface: #dae0d5;
922
+ --c-border: #b4bdac;
923
+ --c-border-strong: #6f7a66;
924
+ --c-text: #232a20;
925
+ --c-text-muted: #424b3e;
926
+ --c-text-faint: #545e50;
927
+ --c-accent: #396631;
928
+ --c-accent-ink: #f1f4ee;
929
+ --c-accent-dim: #a5bb9c;
930
+ --c-blue: #245373;
931
+ --c-amber: #7a5512;
932
+ --c-red: #983a33;
933
+ --c-green: #396631;
934
+ --c-violet: #644b85;
935
+ --c-gold: #6b5b0e;
936
+ --c-teal: #24655d;
937
+ --shadow-sm: 0 1px 2px rgba(30, 38, 26, 0.1);
938
+ --shadow-md: 0 6px 20px rgba(30, 38, 26, 0.14);
939
+ --shadow-lg: 0 12px 40px rgba(30, 38, 26, 0.2);
940
+ --mach-bg-sl: 30% 80%;
941
+ --mach-fg-sl: 45% 26%;
942
+ --mach-border-sl: 25% 60%;
943
+ }
@@ -19,10 +19,10 @@
19
19
  --c-bg-elev-2: #1f232c;
20
20
  --c-surface: #21262f;
21
21
  --c-border: #2c323d;
22
- --c-border-strong: #3a414e;
22
+ --c-border-strong: #68707e;
23
23
  --c-text: #e6e9ef;
24
24
  --c-text-muted: #9aa3b2;
25
- --c-text-faint: #6b7384;
25
+ --c-text-faint: #848c9e;
26
26
 
27
27
  --c-accent: #5ad6a0;
28
28
  --c-accent-ink: #04130c;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dorsk/tsumikit",
3
- "version": "0.64.1",
3
+ "version": "0.66.0",
4
4
  "description": "Minimal, dependency-free Svelte 5 + pure-CSS UI kit. Token-driven atoms, molecules & layouts with theming out of the box.",
5
5
  "type": "module",
6
6
  "license": "MIT",