@dorsk/tsumikit 0.79.0 → 0.80.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.
Files changed (48) hide show
  1. package/dist/components/atoms/Badge.svelte +1 -4
  2. package/dist/components/atoms/Button.svelte +303 -9
  3. package/dist/components/atoms/Button.svelte.d.ts +4 -1
  4. package/dist/components/atoms/Card.svelte +142 -0
  5. package/dist/components/atoms/Checkbox.svelte +177 -1
  6. package/dist/components/atoms/Input.svelte +35 -0
  7. package/dist/components/atoms/Link.svelte +61 -0
  8. package/dist/components/atoms/Progress.svelte +74 -1
  9. package/dist/components/atoms/Progress.svelte.d.ts +1 -0
  10. package/dist/components/atoms/Select.svelte +30 -0
  11. package/dist/components/atoms/Skeleton.svelte +54 -3
  12. package/dist/components/atoms/Skeleton.svelte.d.ts +1 -0
  13. package/dist/components/atoms/Spinner.svelte +152 -3
  14. package/dist/components/atoms/Spinner.svelte.d.ts +1 -1
  15. package/dist/components/atoms/Switch.svelte +135 -0
  16. package/dist/components/atoms/Textarea.svelte +36 -0
  17. package/dist/components/atoms/Thinking.svelte +130 -0
  18. package/dist/components/atoms/Thinking.svelte.d.ts +15 -0
  19. package/dist/components/molecules/CopyButton.svelte +146 -5
  20. package/dist/components/molecules/Field.svelte +55 -1
  21. package/dist/components/molecules/FileButton.svelte +4 -2
  22. package/dist/components/molecules/InputGroup.svelte +1 -1
  23. package/dist/components/molecules/LookPicker.svelte +87 -0
  24. package/dist/components/molecules/LookPicker.svelte.d.ts +17 -0
  25. package/dist/components/molecules/MotionSettings.svelte +166 -0
  26. package/dist/components/molecules/MotionSettings.svelte.d.ts +18 -0
  27. package/dist/components/molecules/RadioGroup.svelte +61 -0
  28. package/dist/components/molecules/Tabs.svelte +157 -4
  29. package/dist/fx.d.ts +149 -0
  30. package/dist/fx.js +111 -0
  31. package/dist/fx.md +58 -0
  32. package/dist/index.d.ts +8 -2
  33. package/dist/index.js +8 -2
  34. package/dist/looks/README.md +101 -0
  35. package/dist/looks/depth.css +939 -0
  36. package/dist/looks/editorial.css +545 -0
  37. package/dist/looks/tactile.css +871 -0
  38. package/dist/pointer.d.ts +3 -0
  39. package/dist/pointer.js +40 -0
  40. package/dist/stores/fx.svelte.d.ts +17 -0
  41. package/dist/stores/fx.svelte.js +64 -0
  42. package/dist/stores/theme.svelte.d.ts +8 -2
  43. package/dist/stores/theme.svelte.js +33 -7
  44. package/dist/styles/themes.css +249 -249
  45. package/dist/styles/tokens.css +4 -3
  46. package/dist/theme-mode.d.ts +31 -0
  47. package/dist/theme-mode.js +19 -0
  48. package/package.json +3 -2
@@ -0,0 +1,101 @@
1
+ # Looks
2
+
3
+ A look is the kit's structural style: surfaces, edges, elevation, control fills and
4
+ interactions. It is its own axis, independent of the theme (the colors) and of the
5
+ light/dark mode. Any look works with any of the 30 built-in themes and with your own.
6
+
7
+ | id | status | character |
8
+ | ----------- | ------------ | ------------------------------------------------------ |
9
+ | `default` | stable | polished: the kit as shipped, no stylesheet needed |
10
+ | `depth` | stable | layered elevation, inner highlights, accent glow |
11
+ | `tactile` | stable | soft raised and pressed surfaces |
12
+ | `editorial` | experimental | bold type scale, rules, solid tones; may change |
13
+
14
+ ## Use
15
+
16
+ Import the looks you offer, next to the kit's stylesheet. A look costs nothing until it is
17
+ active: every rule is scoped to `:root[data-look="<id>"]`.
18
+
19
+ ```ts
20
+ import '@dorsk/tsumikit/styles/app.css';
21
+ import '@dorsk/tsumikit/looks/depth.css';
22
+ import '@dorsk/tsumikit/looks/tactile.css';
23
+ ```
24
+
25
+ The theme store owns the look and persists it with the theme preference
26
+ (`localStorage['tsumikit-theme']`, a `look` key that is absent for the default look):
27
+
28
+ ```svelte
29
+ <script lang="ts">
30
+ import { LookPicker, ThemePicker, theme } from '@dorsk/tsumikit';
31
+ </script>
32
+
33
+ <LookPicker />
34
+ <ThemePicker auto />
35
+ <p>{theme.look}</p>
36
+ <button onclick={() => theme.setLook('depth')}>Depth</button>
37
+ ```
38
+
39
+ `LOOKS` lists `{ id, label, status }`. `<LookPicker experimental={false} />` hides
40
+ experimental looks; `looks={['default', 'depth']}` restricts and orders them.
41
+
42
+ The store paints `data-theme`, `data-mode="light|dark"` and `data-look` (absent for the
43
+ default look) on `<html>`. Inline `THEME_PREPAINT` in `<head>` to paint all three before
44
+ first paint:
45
+
46
+ ```svelte
47
+ <script lang="ts">
48
+ import { THEME_PREPAINT } from '@dorsk/tsumikit';
49
+ </script>
50
+
51
+ <svelte:head>
52
+ {@html `<script>${THEME_PREPAINT}</` + `script>`}
53
+ </svelte:head>
54
+ ```
55
+
56
+ If you register your own themes, build the script with
57
+ `themePrepaint('tsumikit-theme', [...THEMES, ...yours])` so legacy single-id values resolve.
58
+
59
+ Apps that persist settings server-side get `look` inside the preference passed to
60
+ `theme.onchange`, and can replay it with `theme.hydrate(pref)`. A preference without
61
+ `look` keeps the current look.
62
+
63
+ ### Pointer effects
64
+
65
+ Some looks light the surface under the mouse. Call `trackPointer()` once, client side; it
66
+ sets `--pointer-x` / `--pointer-y` on the hovered `[data-tsu]` element and its `[data-tsu]`
67
+ ancestors and returns a disposer. Looks degrade gracefully without it.
68
+
69
+ ```ts
70
+ $effect(() => trackPointer());
71
+ ```
72
+
73
+ ## Writing a look
74
+
75
+ `src/lib/looks/<id>.css`, plus an entry in `LOOKS` (`src/lib/theme-mode.ts`).
76
+ `tests/looks-lint.test.js` enforces the first three rules.
77
+
78
+ 1. **Scope everything** under `:root[data-look="<id>"]`. Light-only tweaks go under
79
+ `:root[data-look="<id>"][data-mode="light"]`; prefer recipes that work in both modes.
80
+ `@keyframes` are global: namespace their names.
81
+ 2. **No literal colors.** No hex, no `rgb()`/`hsl()`/`oklch()`/`lab()` with channel
82
+ numbers, no named colors (`black` and `white` included) except `transparent` and
83
+ `currentColor`. Derive every color from the active theme:
84
+ `var(--accent)`, `color-mix(in oklab, var(--accent) 30%, transparent)`,
85
+ `oklch(from var(--accent) l c h / 0.4)`; shadows from
86
+ `oklch(from var(--bg) calc(l * 0.4) c h / 0.6)` or
87
+ `color-mix(in oklab, var(--text) 18%, transparent)`.
88
+ 3. **No `transition: all`.** Durations come from `--dur-*`.
89
+ 4. **Tokens first.** Override the structural tokens in `styles/tokens.css` ("Structural
90
+ look": surface, raised, overlay, control, track, thumb and button fills, edges and
91
+ shadows, `--edge-width`, `--hover-lift`, `--focus-glow`). Add per-component rules
92
+ (`:root[data-look="<id>"] [data-tsu="Card"]`) only where a token cannot express it.
93
+ 5. **Motion:** hover-only effects inside `@media (hover: hover) and (pointer: fine)`;
94
+ respect `prefers-reduced-motion`.
95
+ 6. **Contrast**, for every theme in both modes: text ≥ 4.5:1, UI boundaries and focus
96
+ rings ≥ 3:1. A look must not lower text contrast; it should rarely touch text colors.
97
+
98
+ Palette tokens available to a look: `--bg`, `--bg-elevated`, `--bg-elevated-2`,
99
+ `--surface`, `--border`, `--border-strong`, `--text`, `--text-muted`, `--text-faint`,
100
+ `--accent`, `--text-on-accent`, `--ok`, `--warn`, `--danger`, `--info` and the `--c-*`
101
+ palette.