@spaethtech/svelte-ui 0.17.0 → 0.17.1-dev.80.6b8fb45

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.
@@ -36,6 +36,13 @@ the components use:
36
36
  @source "../node_modules/@spaethtech/svelte-ui/dist"; /* path relative to this file */
37
37
  ```
38
38
 
39
+ > **Missing borders/styles after `npm update`?** Two causes: (1) the `@source` line above is absent or
40
+ > its path is wrong, so Tailwind never emits the components' (arbitrary) classes — fix the glob. (2) A
41
+ > version bumped a class string (e.g. 0.17 rewrote the neutral border classes), and Tailwind's build
42
+ > **cached** the old scan — restart the dev server / clear the Vite+Tailwind cache and rebuild. If a
43
+ > border resolves to the wrong colour (not missing), it's a **theme** issue — see the `themes` skill's
44
+ > "restate `--ui-color-neutral` per scope" note.
45
+
39
46
  ## Import & basic use
40
47
 
41
48
  ```svelte
@@ -219,9 +219,15 @@ Set `--ui-color-*` at `:root` after importing the theme:
219
219
  --ui-color-primary: #ff6600;
220
220
  --ui-color-background: #0d1117;
221
221
  --ui-color-text: #e6edf3;
222
+ --ui-color-neutral: var(--ui-color-text); /* ≥0.17 — restate so neutral borders track your text */
222
223
  }
223
224
  ```
224
225
 
226
+ A bare `:root` override like this works because `--ui-color-neutral` (declared at `:root` in
227
+ `theme.css`) re-resolves on `:root`. But the moment you override the palette in a **more specific
228
+ scope** (`.theme-*`, a branding class, an inverse-surface subtree), you MUST restate
229
+ `--ui-color-neutral` + `--ui-border-color` in that scope too (freeze rule).
230
+
225
231
  ### Scoped override / **inverse surfaces** (a subtree)
226
232
 
227
233
  Because the theme classes are ordinary CSS, apply one to **any container** to re-theme just
@@ -253,10 +259,13 @@ scope picks up the child's `--acc`.
253
259
 
254
260
  Two consequences baked into `theme.css`:
255
261
 
256
- 1. **Tints are repeated in EVERY theme scope** (`:root`, `@media (prefers-color-scheme:dark)
257
- :root`, `.theme-light`, `.theme-dark`) rather than defined once at `:root` — so they
258
- re-resolve against whichever theme (and `--ui-accent`) is in scope. This is why scoped
259
- themes and the switcher-on-`<html>` rule work, and why a switcher on `<body>` breaks them.
262
+ 1. **Tints AND neutral-derived tokens are repeated in EVERY theme scope** (`:root`, `@media
263
+ (prefers-color-scheme:dark) :root`, `.theme-light`, `.theme-dark`) rather than defined once at
264
+ `:root` — so they re-resolve against whichever theme (and `--ui-accent`) is in scope. This
265
+ covers `--ui-color-hover/surface/active` **and** `--ui-color-neutral` + `--ui-border-color`
266
+ (both derive from `--ui-color-text`). This is why scoped themes and the switcher-on-`<html>`
267
+ rule work, why a switcher on `<body>` breaks them, and why **any custom scope that overrides the
268
+ palette must also restate `--ui-color-neutral`/`--ui-border-color`** (see Building a custom theme).
260
269
  2. **Overriding `--ui-accent` requires the `.ui-accent` re-mix class** — the override alone
261
270
  can't re-tint tokens computed higher up.
262
271
 
@@ -292,6 +301,11 @@ custom properties resolve at use-time, the host system's cascade applies automat
292
301
  .theme-myapp {
293
302
  --ui-color-background: var(--color-base-100); /* host token */
294
303
  --ui-color-text: var(--color-base-content);
304
+ /* REQUIRED in ANY scope that overrides the palette: the neutral base + the divider it derives
305
+ * do NOT re-resolve across scopes (freeze rule), so restate them here — otherwise neutral
306
+ * borders/surfaces freeze to `:root`'s colour (wrong hue, or invisible on a dark brand). */
307
+ --ui-color-neutral: var(--ui-color-text);
308
+ --ui-border-color: color-mix(in srgb, var(--ui-color-neutral) var(--ui-tint-divider), transparent);
295
309
  /* only list what differs — the rest inherit; NEVER self-reference (see the trap) */
296
310
  --ui-height-sm: 1.75rem;
297
311
  --ui-height: 2.25rem;
@@ -299,6 +313,12 @@ custom properties resolve at use-time, the host system's cascade applies automat
299
313
  }
300
314
  ```
301
315
 
316
+ > **Upgrading an existing theme to ≥ 0.17:** `--ui-color-neutral` is new (it's what all *neutral*
317
+ > borders/surfaces derive from). A pre-0.17 custom theme scope defines the palette but not this token,
318
+ > so after upgrading, neutral borders (Card/Input frames, Menu, DataTable/SideBarMenu edges…) render
319
+ > with the wrong colour or vanish. **Add `--ui-color-neutral` (and re-derive `--ui-border-color`) to
320
+ > every scope where you override `--ui-color-*`.**
321
+
302
322
  Apply globally at `:root` (svelte-ui _is_ the design system) or scoped on a wrapper subtree
303
323
  (svelte-ui opted into per route/component while the rest of the app uses the host system).
304
324
 
@@ -316,7 +336,10 @@ Verify light + dark before/after.
316
336
  SC consumes these `--ui-*` tokens **directly** — there is no `--color-*`/`--border-*` alias
317
337
  layer (it was removed). Per-tenant branding overrides `--ui-color-primary`/`--ui-color-secondary`
318
338
  at `html.theme-light,html.theme-dark` (see SC `$lib/branding.ts`); neutrals and semantic colours
319
- stay theme-controlled.
339
+ stay theme-controlled. **≥ 0.17:** those branding scopes must also set
340
+ `--ui-color-neutral: var(--ui-color-text);` (and re-derive `--ui-border-color`) — the freeze rule
341
+ means the scope's `--ui-color-text` override won't otherwise reach the neutral borders, so they'd
342
+ freeze to `:root` (wrong hue / invisible on a dark tenant).
320
343
 
321
344
  ## Authoring checklist
322
345
 
package/docs/themes.md CHANGED
@@ -173,3 +173,18 @@ This page documents the token _surface_. For the authoring side — swapping pal
173
173
  by variant (`--ui-accent` + `.ui-accent`), scoping/inverse surfaces, the custom-property freeze
174
174
  rule, the self-reference trap, and bridging to another design system (DaisyUI, shadcn, …) — see the
175
175
  themes skill: [`.claude/skills/themes/SKILL.md`](../.claude/skills/themes/SKILL.md).
176
+
177
+ > **Any scope that overrides `--ui-color-*` must also restate `--ui-color-neutral`** (and re-derive
178
+ > `--ui-border-color`). Neutral borders/surfaces derive from `--ui-color-neutral`, which — by the
179
+ > freeze rule — does not re-resolve against a scope's `--ui-color-text` override on its own:
180
+ >
181
+ > ```css
182
+ > .your-scope {
183
+ > --ui-color-text: /* … */;
184
+ > --ui-color-neutral: var(--ui-color-text); /* or a brand grey */
185
+ > --ui-border-color: color-mix(in srgb, var(--ui-color-neutral) var(--ui-tint-divider), transparent);
186
+ > }
187
+ > ```
188
+ >
189
+ > Omit it and neutral borders freeze to `:root` (wrong hue, or invisible on a dark brand). This became
190
+ > required in **0.17** when `--ui-color-neutral` was introduced.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spaethtech/svelte-ui",
3
- "version": "0.17.0",
3
+ "version": "0.17.1-dev.80.6b8fb45",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/spaethtech/svelte-ui.git"