@weasel-js/theme 0.5.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/LICENSE +21 -0
- package/README.md +26 -0
- package/dist/index.d.ts +86 -0
- package/dist/index.js +92 -0
- package/dist/index.js.map +1 -0
- package/dist/tokens.css +206 -0
- package/package.json +45 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 orochi235
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# @weasel-js/theme
|
|
2
|
+
|
|
3
|
+
Design tokens shared by weasel-ui and weasel-hud — CSS variables + a parallel TS export.
|
|
4
|
+
|
|
5
|
+
Part of [weasel](https://github.com/orochi235/weasel), a domain-agnostic 2D
|
|
6
|
+
scene-graph canvas kit for React. See the
|
|
7
|
+
[API reference](https://orochi235.github.io/weasel/api/).
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
npm install @weasel-js/theme
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import { /* … */ } from '@weasel-js/theme';
|
|
19
|
+
import '@weasel-js/theme/tokens.css';
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
The stylesheet is required — component styles ship as one bundled file.
|
|
23
|
+
|
|
24
|
+
## License
|
|
25
|
+
|
|
26
|
+
MIT
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Source of truth for token default values. Mirrors tokens.css exactly,
|
|
3
|
+
* with var(--*) references resolved to their literal target value (TS
|
|
4
|
+
* exports can't reference each other syntactically the way CSS can with
|
|
5
|
+
* var()). The parity test in tokens.test.ts catches drift.
|
|
6
|
+
*
|
|
7
|
+
* color-mix() expressions are resolved to plausible hex approximations
|
|
8
|
+
* — consumers that need exact mixed values should read getComputedStyle
|
|
9
|
+
* from the live DOM rather than relying on these defaults.
|
|
10
|
+
*/
|
|
11
|
+
declare const DEFAULT_TOKENS: {
|
|
12
|
+
readonly '--wzl-gray-50': "#f5f5f6";
|
|
13
|
+
readonly '--wzl-gray-100': "#e6e7e9";
|
|
14
|
+
readonly '--wzl-gray-200': "#c9cbcf";
|
|
15
|
+
readonly '--wzl-gray-300': "#9ea1a8";
|
|
16
|
+
readonly '--wzl-gray-400': "#6f737b";
|
|
17
|
+
readonly '--wzl-gray-500': "#4d5058";
|
|
18
|
+
readonly '--wzl-gray-600': "#383b42";
|
|
19
|
+
readonly '--wzl-gray-700': "#25272c";
|
|
20
|
+
readonly '--wzl-gray-800': "#181a1e";
|
|
21
|
+
readonly '--wzl-gray-900': "#0e0f12";
|
|
22
|
+
readonly '--wzl-accent-soft': "#1d1454";
|
|
23
|
+
readonly '--wzl-accent-base': "#2e1f7a";
|
|
24
|
+
readonly '--wzl-accent-strong': "#5841b8";
|
|
25
|
+
readonly '--wzl-danger-base': "#d94a3f";
|
|
26
|
+
readonly '--wzl-warning-base': "#d99a3f";
|
|
27
|
+
readonly '--wzl-success-base': "#2ec27e";
|
|
28
|
+
readonly '--wzl-radius-sm': "3px";
|
|
29
|
+
readonly '--wzl-radius-md': "5px";
|
|
30
|
+
readonly '--wzl-border-w': "1px";
|
|
31
|
+
readonly '--wzl-line-width': "2px";
|
|
32
|
+
readonly '--wzl-curve-width': "3px";
|
|
33
|
+
readonly '--wzl-motion-fast': "120ms";
|
|
34
|
+
readonly '--wzl-motion-medium': "240ms";
|
|
35
|
+
readonly '--wzl-ease-in-cubic': "cubic-bezier(0.32, 0, 0.67, 0)";
|
|
36
|
+
readonly '--wzl-ease-out-cubic': "cubic-bezier(0.33, 1, 0.68, 1)";
|
|
37
|
+
readonly '--wzl-ease-in-out-cubic': "cubic-bezier(0.65, 0, 0.35, 1)";
|
|
38
|
+
readonly '--wzl-ease-out-back': "cubic-bezier(0.34, 1.56, 0.64, 1)";
|
|
39
|
+
readonly '--wzl-line-subtle': "rgba(230, 231, 233, 0.10)";
|
|
40
|
+
readonly '--wzl-line': "rgba(230, 231, 233, 0.20)";
|
|
41
|
+
readonly '--wzl-line-strong': "rgba(230, 231, 233, 0.40)";
|
|
42
|
+
readonly '--wzl-curve-color': "#5841b8";
|
|
43
|
+
readonly '--wzl-font-ui': "'Oswald', 'Helvetica Neue Condensed', 'Arial Narrow', system-ui, sans-serif";
|
|
44
|
+
readonly '--wzl-font-display': "'Oswald', 'Helvetica Neue Condensed', 'Arial Narrow', system-ui, sans-serif";
|
|
45
|
+
readonly '--wzl-font-body': "'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif";
|
|
46
|
+
readonly '--wzl-font-mono': "ui-monospace, SFMono-Regular, Menlo, Consolas, monospace";
|
|
47
|
+
readonly '--wzl-font-weight-light': "200";
|
|
48
|
+
readonly '--wzl-font-weight-normal': "300";
|
|
49
|
+
readonly '--wzl-font-weight-bold': "400";
|
|
50
|
+
readonly '--wzl-surface': "#181a1e";
|
|
51
|
+
readonly '--wzl-surface-raised': "#25272c";
|
|
52
|
+
readonly '--wzl-surface-sunken': "#0e0f12";
|
|
53
|
+
readonly '--wzl-fg': "#e6e7e9";
|
|
54
|
+
readonly '--wzl-fg-muted': "#9ea1a8";
|
|
55
|
+
readonly '--wzl-fg-subtle': "#6f737b";
|
|
56
|
+
readonly '--wzl-fg-on-accent': "#f5f5f6";
|
|
57
|
+
readonly '--wzl-border': "#25272c";
|
|
58
|
+
readonly '--wzl-border-strong': "#383b42";
|
|
59
|
+
readonly '--wzl-accent': "#2e1f7a";
|
|
60
|
+
readonly '--wzl-accent-fg': "#5841b8";
|
|
61
|
+
readonly '--wzl-accent-hover': "#5841b8";
|
|
62
|
+
readonly '--wzl-danger': "#d94a3f";
|
|
63
|
+
readonly '--wzl-warning': "#d99a3f";
|
|
64
|
+
readonly '--wzl-success': "#2ec27e";
|
|
65
|
+
readonly '--wzl-focus-ring': "#5841b8";
|
|
66
|
+
readonly '--wzl-glass-tint': "#2e1f7a";
|
|
67
|
+
readonly '--wzl-text': "#e6e7e9";
|
|
68
|
+
readonly '--wzl-text-muted': "#9ea1a8";
|
|
69
|
+
readonly '--wzl-bg': "#181a1e";
|
|
70
|
+
readonly '--wzl-muted': "#9ea1a8";
|
|
71
|
+
readonly '--wzl-panel-bg': "#181a1e";
|
|
72
|
+
readonly '--wzl-panel-border': "#25272c";
|
|
73
|
+
readonly '--wzl-input-bg': "#0e0f12";
|
|
74
|
+
readonly '--wzl-track-bg': "#0e0f12";
|
|
75
|
+
readonly '--wzl-track-border': "#25272c";
|
|
76
|
+
readonly '--wzl-thumb-fill': "#9ea1a8";
|
|
77
|
+
readonly '--wzl-thumb-border': "#383b42";
|
|
78
|
+
readonly '--wzl-thumb-text': "#0e0f12";
|
|
79
|
+
readonly '--wzl-button-fill': "#25272c";
|
|
80
|
+
readonly '--wzl-button-fill-hover': "#2f3138";
|
|
81
|
+
readonly '--wzl-button-fill-pressed': "#363941";
|
|
82
|
+
readonly '--wzl-button-text': "#e6e7e9";
|
|
83
|
+
};
|
|
84
|
+
type TokenName = keyof typeof DEFAULT_TOKENS;
|
|
85
|
+
|
|
86
|
+
export { DEFAULT_TOKENS, type TokenName };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
// src/tokens.ts
|
|
2
|
+
var DEFAULT_TOKENS = {
|
|
3
|
+
// Primitive — grays
|
|
4
|
+
"--wzl-gray-50": "#f5f5f6",
|
|
5
|
+
"--wzl-gray-100": "#e6e7e9",
|
|
6
|
+
"--wzl-gray-200": "#c9cbcf",
|
|
7
|
+
"--wzl-gray-300": "#9ea1a8",
|
|
8
|
+
"--wzl-gray-400": "#6f737b",
|
|
9
|
+
"--wzl-gray-500": "#4d5058",
|
|
10
|
+
"--wzl-gray-600": "#383b42",
|
|
11
|
+
"--wzl-gray-700": "#25272c",
|
|
12
|
+
"--wzl-gray-800": "#181a1e",
|
|
13
|
+
"--wzl-gray-900": "#0e0f12",
|
|
14
|
+
// Primitive — accent + status
|
|
15
|
+
"--wzl-accent-soft": "#1d1454",
|
|
16
|
+
"--wzl-accent-base": "#2e1f7a",
|
|
17
|
+
"--wzl-accent-strong": "#5841b8",
|
|
18
|
+
"--wzl-danger-base": "#d94a3f",
|
|
19
|
+
"--wzl-warning-base": "#d99a3f",
|
|
20
|
+
"--wzl-success-base": "#2ec27e",
|
|
21
|
+
// Geometry
|
|
22
|
+
"--wzl-radius-sm": "3px",
|
|
23
|
+
"--wzl-radius-md": "5px",
|
|
24
|
+
"--wzl-border-w": "1px",
|
|
25
|
+
"--wzl-line-width": "2px",
|
|
26
|
+
"--wzl-curve-width": "3px",
|
|
27
|
+
// Motion — durations + CSS equivalents of the JS easing library
|
|
28
|
+
"--wzl-motion-fast": "120ms",
|
|
29
|
+
"--wzl-motion-medium": "240ms",
|
|
30
|
+
"--wzl-ease-in-cubic": "cubic-bezier(0.32, 0, 0.67, 0)",
|
|
31
|
+
"--wzl-ease-out-cubic": "cubic-bezier(0.33, 1, 0.68, 1)",
|
|
32
|
+
"--wzl-ease-in-out-cubic": "cubic-bezier(0.65, 0, 0.35, 1)",
|
|
33
|
+
"--wzl-ease-out-back": "cubic-bezier(0.34, 1.56, 0.64, 1)",
|
|
34
|
+
// Structural lines — three opacity levels of fg. color-mix at runtime;
|
|
35
|
+
// hex approximations here resolve against the dark default fg.
|
|
36
|
+
"--wzl-line-subtle": "rgba(230, 231, 233, 0.10)",
|
|
37
|
+
"--wzl-line": "rgba(230, 231, 233, 0.20)",
|
|
38
|
+
"--wzl-line-strong": "rgba(230, 231, 233, 0.40)",
|
|
39
|
+
// Curve color — semantic alias for the accent.
|
|
40
|
+
"--wzl-curve-color": "#5841b8",
|
|
41
|
+
// Typography
|
|
42
|
+
"--wzl-font-ui": "'Oswald', 'Helvetica Neue Condensed', 'Arial Narrow', system-ui, sans-serif",
|
|
43
|
+
"--wzl-font-display": "'Oswald', 'Helvetica Neue Condensed', 'Arial Narrow', system-ui, sans-serif",
|
|
44
|
+
"--wzl-font-body": "'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif",
|
|
45
|
+
"--wzl-font-mono": "ui-monospace, SFMono-Regular, Menlo, Consolas, monospace",
|
|
46
|
+
"--wzl-font-weight-light": "200",
|
|
47
|
+
"--wzl-font-weight-normal": "300",
|
|
48
|
+
"--wzl-font-weight-bold": "400",
|
|
49
|
+
// Semantic — surfaces
|
|
50
|
+
"--wzl-surface": "#181a1e",
|
|
51
|
+
"--wzl-surface-raised": "#25272c",
|
|
52
|
+
"--wzl-surface-sunken": "#0e0f12",
|
|
53
|
+
// Semantic — text
|
|
54
|
+
"--wzl-fg": "#e6e7e9",
|
|
55
|
+
"--wzl-fg-muted": "#9ea1a8",
|
|
56
|
+
"--wzl-fg-subtle": "#6f737b",
|
|
57
|
+
"--wzl-fg-on-accent": "#f5f5f6",
|
|
58
|
+
// Semantic — borders
|
|
59
|
+
"--wzl-border": "#25272c",
|
|
60
|
+
"--wzl-border-strong": "#383b42",
|
|
61
|
+
// Semantic — interactive
|
|
62
|
+
"--wzl-accent": "#2e1f7a",
|
|
63
|
+
"--wzl-accent-fg": "#5841b8",
|
|
64
|
+
"--wzl-accent-hover": "#5841b8",
|
|
65
|
+
"--wzl-danger": "#d94a3f",
|
|
66
|
+
"--wzl-warning": "#d99a3f",
|
|
67
|
+
"--wzl-success": "#2ec27e",
|
|
68
|
+
"--wzl-focus-ring": "#5841b8",
|
|
69
|
+
// Semantic — glass
|
|
70
|
+
"--wzl-glass-tint": "#2e1f7a",
|
|
71
|
+
// Deprecated aliases (kept for older consumers)
|
|
72
|
+
"--wzl-text": "#e6e7e9",
|
|
73
|
+
"--wzl-text-muted": "#9ea1a8",
|
|
74
|
+
"--wzl-bg": "#181a1e",
|
|
75
|
+
"--wzl-muted": "#9ea1a8",
|
|
76
|
+
"--wzl-panel-bg": "#181a1e",
|
|
77
|
+
"--wzl-panel-border": "#25272c",
|
|
78
|
+
"--wzl-input-bg": "#0e0f12",
|
|
79
|
+
"--wzl-track-bg": "#0e0f12",
|
|
80
|
+
"--wzl-track-border": "#25272c",
|
|
81
|
+
"--wzl-thumb-fill": "#9ea1a8",
|
|
82
|
+
"--wzl-thumb-border": "#383b42",
|
|
83
|
+
"--wzl-thumb-text": "#0e0f12",
|
|
84
|
+
"--wzl-button-fill": "#25272c",
|
|
85
|
+
"--wzl-button-fill-hover": "#2f3138",
|
|
86
|
+
"--wzl-button-fill-pressed": "#363941",
|
|
87
|
+
"--wzl-button-text": "#e6e7e9"
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
export { DEFAULT_TOKENS };
|
|
91
|
+
//# sourceMappingURL=index.js.map
|
|
92
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/tokens.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Source of truth for token default values. Mirrors tokens.css exactly,\n * with var(--*) references resolved to their literal target value (TS\n * exports can't reference each other syntactically the way CSS can with\n * var()). The parity test in tokens.test.ts catches drift.\n *\n * color-mix() expressions are resolved to plausible hex approximations\n * — consumers that need exact mixed values should read getComputedStyle\n * from the live DOM rather than relying on these defaults.\n */\nexport const DEFAULT_TOKENS = {\n // Primitive — grays\n '--wzl-gray-50': '#f5f5f6',\n '--wzl-gray-100': '#e6e7e9',\n '--wzl-gray-200': '#c9cbcf',\n '--wzl-gray-300': '#9ea1a8',\n '--wzl-gray-400': '#6f737b',\n '--wzl-gray-500': '#4d5058',\n '--wzl-gray-600': '#383b42',\n '--wzl-gray-700': '#25272c',\n '--wzl-gray-800': '#181a1e',\n '--wzl-gray-900': '#0e0f12',\n\n // Primitive — accent + status\n '--wzl-accent-soft': '#1d1454',\n '--wzl-accent-base': '#2e1f7a',\n '--wzl-accent-strong': '#5841b8',\n '--wzl-danger-base': '#d94a3f',\n '--wzl-warning-base': '#d99a3f',\n '--wzl-success-base': '#2ec27e',\n\n // Geometry\n '--wzl-radius-sm': '3px',\n '--wzl-radius-md': '5px',\n '--wzl-border-w': '1px',\n '--wzl-line-width': '2px',\n '--wzl-curve-width': '3px',\n\n // Motion — durations + CSS equivalents of the JS easing library\n '--wzl-motion-fast': '120ms',\n '--wzl-motion-medium': '240ms',\n '--wzl-ease-in-cubic': 'cubic-bezier(0.32, 0, 0.67, 0)',\n '--wzl-ease-out-cubic': 'cubic-bezier(0.33, 1, 0.68, 1)',\n '--wzl-ease-in-out-cubic': 'cubic-bezier(0.65, 0, 0.35, 1)',\n '--wzl-ease-out-back': 'cubic-bezier(0.34, 1.56, 0.64, 1)',\n\n // Structural lines — three opacity levels of fg. color-mix at runtime;\n // hex approximations here resolve against the dark default fg.\n '--wzl-line-subtle': 'rgba(230, 231, 233, 0.10)',\n '--wzl-line': 'rgba(230, 231, 233, 0.20)',\n '--wzl-line-strong': 'rgba(230, 231, 233, 0.40)',\n\n // Curve color — semantic alias for the accent.\n '--wzl-curve-color': '#5841b8',\n\n // Typography\n '--wzl-font-ui': \"'Oswald', 'Helvetica Neue Condensed', 'Arial Narrow', system-ui, sans-serif\",\n '--wzl-font-display': \"'Oswald', 'Helvetica Neue Condensed', 'Arial Narrow', system-ui, sans-serif\",\n '--wzl-font-body': \"'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif\",\n '--wzl-font-mono': 'ui-monospace, SFMono-Regular, Menlo, Consolas, monospace',\n '--wzl-font-weight-light': '200',\n '--wzl-font-weight-normal': '300',\n '--wzl-font-weight-bold': '400',\n\n // Semantic — surfaces\n '--wzl-surface': '#181a1e',\n '--wzl-surface-raised': '#25272c',\n '--wzl-surface-sunken': '#0e0f12',\n\n // Semantic — text\n '--wzl-fg': '#e6e7e9',\n '--wzl-fg-muted': '#9ea1a8',\n '--wzl-fg-subtle': '#6f737b',\n '--wzl-fg-on-accent': '#f5f5f6',\n\n // Semantic — borders\n '--wzl-border': '#25272c',\n '--wzl-border-strong': '#383b42',\n\n // Semantic — interactive\n '--wzl-accent': '#2e1f7a',\n '--wzl-accent-fg': '#5841b8',\n '--wzl-accent-hover': '#5841b8',\n '--wzl-danger': '#d94a3f',\n '--wzl-warning': '#d99a3f',\n '--wzl-success': '#2ec27e',\n '--wzl-focus-ring': '#5841b8',\n\n // Semantic — glass\n '--wzl-glass-tint': '#2e1f7a',\n\n // Deprecated aliases (kept for older consumers)\n '--wzl-text': '#e6e7e9',\n '--wzl-text-muted': '#9ea1a8',\n '--wzl-bg': '#181a1e',\n '--wzl-muted': '#9ea1a8',\n '--wzl-panel-bg': '#181a1e',\n '--wzl-panel-border': '#25272c',\n '--wzl-input-bg': '#0e0f12',\n '--wzl-track-bg': '#0e0f12',\n '--wzl-track-border': '#25272c',\n '--wzl-thumb-fill': '#9ea1a8',\n '--wzl-thumb-border': '#383b42',\n '--wzl-thumb-text': '#0e0f12',\n '--wzl-button-fill': '#25272c',\n '--wzl-button-fill-hover': '#2f3138',\n '--wzl-button-fill-pressed': '#363941',\n '--wzl-button-text': '#e6e7e9',\n} as const;\n\nexport type TokenName = keyof typeof DEFAULT_TOKENS;\n"]}
|
package/dist/tokens.css
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/* Design tokens for the weasel design system. Shared by weasel-ui (DOM)
|
|
2
|
+
* and weasel-hud (WebGL). Apps with their own design system should skip
|
|
3
|
+
* this file and define the variables themselves at the desired scope.
|
|
4
|
+
*
|
|
5
|
+
* Structure:
|
|
6
|
+
* 1. Primitive scale — raw values, not for direct consumption
|
|
7
|
+
* 2. Semantic tokens — what components reference
|
|
8
|
+
* 3. Deprecated aliases — kept so older components keep rendering
|
|
9
|
+
*/
|
|
10
|
+
@import url('https://fonts.googleapis.com/css2?family=Oswald:wght@200;300;400&display=swap');
|
|
11
|
+
|
|
12
|
+
:root {
|
|
13
|
+
/* ---------- 1. Primitive scale ---------- */
|
|
14
|
+
|
|
15
|
+
/* Neutrals — perceptually-spaced gray ramp. */
|
|
16
|
+
--wzl-gray-50: #f5f5f6;
|
|
17
|
+
--wzl-gray-100: #e6e7e9;
|
|
18
|
+
--wzl-gray-200: #c9cbcf;
|
|
19
|
+
--wzl-gray-300: #9ea1a8;
|
|
20
|
+
--wzl-gray-400: #6f737b;
|
|
21
|
+
--wzl-gray-500: #4d5058;
|
|
22
|
+
--wzl-gray-600: #383b42;
|
|
23
|
+
--wzl-gray-700: #25272c;
|
|
24
|
+
--wzl-gray-800: #181a1e;
|
|
25
|
+
--wzl-gray-900: #0e0f12;
|
|
26
|
+
|
|
27
|
+
/* Accent — midnight blue-violet. Deep and saturated; carries enough
|
|
28
|
+
* weight to anchor primary actions in both light and dark surfaces.
|
|
29
|
+
* Apps override at their own scope. */
|
|
30
|
+
--wzl-accent-soft: #1d1454;
|
|
31
|
+
--wzl-accent-base: #2e1f7a;
|
|
32
|
+
--wzl-accent-strong: #5841b8;
|
|
33
|
+
|
|
34
|
+
--wzl-danger-base: #d94a3f;
|
|
35
|
+
--wzl-warning-base: #d99a3f;
|
|
36
|
+
--wzl-success-base: #2ec27e;
|
|
37
|
+
|
|
38
|
+
/* Geometry */
|
|
39
|
+
--wzl-radius-sm: 3px;
|
|
40
|
+
--wzl-radius-md: 5px;
|
|
41
|
+
--wzl-border-w: 1px;
|
|
42
|
+
|
|
43
|
+
/* Motion. Easing names mirror the kit's JS easing library
|
|
44
|
+
* (src/animation/easings.ts) so DOM chrome and canvas animation share
|
|
45
|
+
* one vocabulary — each cubic-bezier is the standard CSS approximation
|
|
46
|
+
* of the Penner curve of the same name.
|
|
47
|
+
* fast : micro-interactions — hover, focus, pressed states.
|
|
48
|
+
* medium : entrances/exits — toasts, popovers, panels. */
|
|
49
|
+
--wzl-motion-fast: 120ms;
|
|
50
|
+
--wzl-motion-medium: 240ms;
|
|
51
|
+
--wzl-ease-in-cubic: cubic-bezier(0.32, 0, 0.67, 0);
|
|
52
|
+
--wzl-ease-out-cubic: cubic-bezier(0.33, 1, 0.68, 1);
|
|
53
|
+
--wzl-ease-in-out-cubic: cubic-bezier(0.65, 0, 0.35, 1);
|
|
54
|
+
--wzl-ease-out-back: cubic-bezier(0.34, 1.56, 0.64, 1);
|
|
55
|
+
|
|
56
|
+
/* Typography. UI/body defaults to Inter; display is Oswald and is loaded
|
|
57
|
+
* via the @import above (consumers either bring their own Inter or accept
|
|
58
|
+
* the system-ui fallback). */
|
|
59
|
+
/* UI / display face — Oswald condensed. Used for chrome labels, buttons,
|
|
60
|
+
* menus, and headings. Loaded weights are 200/300/400 only; the heavier
|
|
61
|
+
* cuts get too blocky for this face at any size. */
|
|
62
|
+
--wzl-font-ui: 'Oswald', 'Helvetica Neue Condensed', 'Arial Narrow', system-ui, sans-serif;
|
|
63
|
+
--wzl-font-display: 'Oswald', 'Helvetica Neue Condensed', 'Arial Narrow', system-ui, sans-serif;
|
|
64
|
+
/* Body face — Inter for paragraphs and long-form prose. Consumers must
|
|
65
|
+
* load the Inter webfont themselves (or accept the system-ui fallback). */
|
|
66
|
+
--wzl-font-body: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
|
|
67
|
+
--wzl-font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
|
68
|
+
/* Weight tokens are tuned to the UI face (Oswald 200/300/400). Body /
|
|
69
|
+
* prose text using Inter will typically hardcode its own weights (e.g.
|
|
70
|
+
* 400/700) rather than route through these. */
|
|
71
|
+
--wzl-font-weight-light: 200;
|
|
72
|
+
--wzl-font-weight-normal: 300;
|
|
73
|
+
--wzl-font-weight-bold: 400;
|
|
74
|
+
|
|
75
|
+
/* ---------- 2. Semantic tokens ---------- */
|
|
76
|
+
|
|
77
|
+
/* Surfaces — three depths. */
|
|
78
|
+
--wzl-surface: var(--wzl-gray-800);
|
|
79
|
+
--wzl-surface-raised: var(--wzl-gray-700);
|
|
80
|
+
--wzl-surface-sunken: var(--wzl-gray-900);
|
|
81
|
+
|
|
82
|
+
/* Text */
|
|
83
|
+
--wzl-fg: var(--wzl-gray-100);
|
|
84
|
+
--wzl-fg-muted: var(--wzl-gray-300);
|
|
85
|
+
--wzl-fg-subtle: var(--wzl-gray-400);
|
|
86
|
+
--wzl-fg-on-accent: var(--wzl-gray-50);
|
|
87
|
+
|
|
88
|
+
/* Borders */
|
|
89
|
+
--wzl-border: var(--wzl-gray-700);
|
|
90
|
+
--wzl-border-strong: var(--wzl-gray-600);
|
|
91
|
+
|
|
92
|
+
/* Lines — for structural strokes (gridlines, dividers, plot axes).
|
|
93
|
+
* Distinct from borders, which enclose UI elements; lines partition
|
|
94
|
+
* content. Three alpha steps over `--wzl-fg` so the line auto-tints
|
|
95
|
+
* for whichever surface it's drawn on without needing per-mode values.
|
|
96
|
+
* Perceptual jobs: `subtle` = barely-there separators (table rows),
|
|
97
|
+
* default = primary gridlines on sunken surfaces, `strong` = axes /
|
|
98
|
+
* emphasized dividers. */
|
|
99
|
+
--wzl-line-subtle: color-mix(in srgb, var(--wzl-fg) 10%, transparent);
|
|
100
|
+
--wzl-line: color-mix(in srgb, var(--wzl-fg) 20%, transparent);
|
|
101
|
+
--wzl-line-strong: color-mix(in srgb, var(--wzl-fg) 40%, transparent);
|
|
102
|
+
/* Stroke widths.
|
|
103
|
+
* --wzl-line-width : structural lines (gridlines, dividers, axes).
|
|
104
|
+
* --wzl-curve-width : drawn data curves / signal traces. Heavier than
|
|
105
|
+
* structural lines so the data reads as primary
|
|
106
|
+
* content. Independently tunable. */
|
|
107
|
+
--wzl-line-width: 2px;
|
|
108
|
+
--wzl-curve-width: 3px;
|
|
109
|
+
/* Curve color — used by plot components (CurveEditor today; future
|
|
110
|
+
* waveform / chart widgets). Routes through the bright accent variant
|
|
111
|
+
* because --wzl-accent (midnight purple) is too dim on sunken
|
|
112
|
+
* surfaces. */
|
|
113
|
+
--wzl-curve-color: var(--wzl-accent-strong);
|
|
114
|
+
|
|
115
|
+
/* Interactive */
|
|
116
|
+
--wzl-accent: var(--wzl-accent-base);
|
|
117
|
+
/* Accent for *foreground* use — text, icons, selected-state labels drawn
|
|
118
|
+
* directly on a surface. --wzl-accent is a fill; the midnight base is too
|
|
119
|
+
* dim to read as text against dark surfaces (same reason --wzl-curve-color
|
|
120
|
+
* routes through the strong variant). Flips to the deep base in light
|
|
121
|
+
* mode, where it's the legible one. */
|
|
122
|
+
--wzl-accent-fg: var(--wzl-accent-strong);
|
|
123
|
+
--wzl-accent-hover: var(--wzl-accent-strong);
|
|
124
|
+
--wzl-danger: var(--wzl-danger-base);
|
|
125
|
+
--wzl-warning: var(--wzl-warning-base);
|
|
126
|
+
--wzl-success: var(--wzl-success-base);
|
|
127
|
+
--wzl-focus-ring: var(--wzl-accent-strong);
|
|
128
|
+
|
|
129
|
+
/* Frosted glass — the kit's signature treatment. Components compose:
|
|
130
|
+
* background: color-mix(in srgb, var(--wzl-glass-tint) 78%, transparent);
|
|
131
|
+
* backdrop-filter: blur(3px);
|
|
132
|
+
* Override `--wzl-glass-tint` at the component scope to tint glass
|
|
133
|
+
* with something other than the accent (e.g. danger). */
|
|
134
|
+
--wzl-glass-tint: var(--wzl-accent);
|
|
135
|
+
|
|
136
|
+
/* ---------- 3. Deprecated aliases ---------- *
|
|
137
|
+
* Older components still reference these names. New code should use
|
|
138
|
+
* the semantic tokens above. These will be removed once every
|
|
139
|
+
* component has been migrated.
|
|
140
|
+
*/
|
|
141
|
+
--wzl-text: var(--wzl-fg);
|
|
142
|
+
--wzl-text-muted: var(--wzl-fg-muted);
|
|
143
|
+
--wzl-bg: var(--wzl-surface);
|
|
144
|
+
--wzl-muted: var(--wzl-fg-muted);
|
|
145
|
+
--wzl-panel-bg: var(--wzl-surface);
|
|
146
|
+
--wzl-panel-border: var(--wzl-border);
|
|
147
|
+
--wzl-input-bg: var(--wzl-surface-sunken);
|
|
148
|
+
--wzl-track-bg: var(--wzl-surface-sunken);
|
|
149
|
+
--wzl-track-border: var(--wzl-border);
|
|
150
|
+
--wzl-thumb-fill: var(--wzl-fg-muted);
|
|
151
|
+
--wzl-thumb-border: var(--wzl-border-strong);
|
|
152
|
+
--wzl-thumb-text: var(--wzl-gray-900);
|
|
153
|
+
--wzl-button-fill: var(--wzl-surface-raised);
|
|
154
|
+
--wzl-button-fill-hover: color-mix(in srgb, var(--wzl-fg) 10%, transparent);
|
|
155
|
+
--wzl-button-fill-pressed: color-mix(in srgb, var(--wzl-fg) 18%, transparent);
|
|
156
|
+
--wzl-button-text: var(--wzl-fg);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/* Default the document's UI font to the token. Apps that want a
|
|
160
|
+
* different face override at their own scope. */
|
|
161
|
+
:root {
|
|
162
|
+
font-family: var(--wzl-font-ui);
|
|
163
|
+
font-weight: var(--wzl-font-weight-normal);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/* Explicit dark-mode rules so descendants with `data-theme="dark"` reassert
|
|
167
|
+
* the dark palette even when the document root is in light mode. Mirrors the
|
|
168
|
+
* dark values in `:root` for every semantic token that has a light override. */
|
|
169
|
+
[data-theme='dark'] {
|
|
170
|
+
color-scheme: dark;
|
|
171
|
+
--wzl-surface: var(--wzl-gray-800);
|
|
172
|
+
--wzl-surface-raised: var(--wzl-gray-700);
|
|
173
|
+
--wzl-surface-sunken: var(--wzl-gray-900);
|
|
174
|
+
|
|
175
|
+
--wzl-fg: var(--wzl-gray-100);
|
|
176
|
+
--wzl-fg-muted: var(--wzl-gray-300);
|
|
177
|
+
--wzl-fg-subtle: var(--wzl-gray-400);
|
|
178
|
+
|
|
179
|
+
--wzl-border: var(--wzl-gray-700);
|
|
180
|
+
--wzl-border-strong: var(--wzl-gray-600);
|
|
181
|
+
|
|
182
|
+
--wzl-accent-fg: var(--wzl-accent-strong);
|
|
183
|
+
|
|
184
|
+
--wzl-thumb-text: var(--wzl-gray-900);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/* Light-mode overrides. Only the semantic surface/text/border tokens flip;
|
|
188
|
+
* the primitive scale and accent ramp stay constant. Toggle by setting
|
|
189
|
+
* `data-theme="light"` on `<html>` (or any ancestor — these cascade). */
|
|
190
|
+
[data-theme='light'] {
|
|
191
|
+
color-scheme: light;
|
|
192
|
+
--wzl-surface: var(--wzl-gray-50);
|
|
193
|
+
--wzl-surface-raised: var(--wzl-gray-100);
|
|
194
|
+
--wzl-surface-sunken: var(--wzl-gray-200);
|
|
195
|
+
|
|
196
|
+
--wzl-fg: var(--wzl-gray-900);
|
|
197
|
+
--wzl-fg-muted: var(--wzl-gray-600);
|
|
198
|
+
--wzl-fg-subtle: var(--wzl-gray-500);
|
|
199
|
+
|
|
200
|
+
--wzl-border: var(--wzl-gray-200);
|
|
201
|
+
--wzl-border-strong: var(--wzl-gray-300);
|
|
202
|
+
|
|
203
|
+
--wzl-accent-fg: var(--wzl-accent-base);
|
|
204
|
+
|
|
205
|
+
--wzl-thumb-text: var(--wzl-gray-50);
|
|
206
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@weasel-js/theme",
|
|
3
|
+
"version": "0.5.0",
|
|
4
|
+
"description": "Design tokens shared by weasel-ui and weasel-hud — CSS variables + a parallel TS export.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"sideEffects": [
|
|
8
|
+
"*.css"
|
|
9
|
+
],
|
|
10
|
+
"main": "./dist/index.js",
|
|
11
|
+
"module": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"import": "./dist/index.js",
|
|
16
|
+
"types": "./dist/index.d.ts"
|
|
17
|
+
},
|
|
18
|
+
"./tokens.css": "./dist/tokens.css",
|
|
19
|
+
"./package.json": "./package.json"
|
|
20
|
+
},
|
|
21
|
+
"author": "orochi235",
|
|
22
|
+
"homepage": "https://orochi235.github.io/weasel/",
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "git+https://github.com/orochi235/weasel.git",
|
|
26
|
+
"directory": "packages/theme"
|
|
27
|
+
},
|
|
28
|
+
"bugs": {
|
|
29
|
+
"url": "https://github.com/orochi235/weasel/issues"
|
|
30
|
+
},
|
|
31
|
+
"engines": {
|
|
32
|
+
"node": ">=20"
|
|
33
|
+
},
|
|
34
|
+
"files": [
|
|
35
|
+
"dist",
|
|
36
|
+
"README.md",
|
|
37
|
+
"LICENSE"
|
|
38
|
+
],
|
|
39
|
+
"publishConfig": {
|
|
40
|
+
"access": "public"
|
|
41
|
+
},
|
|
42
|
+
"scripts": {
|
|
43
|
+
"build": "tsup && cp src/tokens.css dist/tokens.css"
|
|
44
|
+
}
|
|
45
|
+
}
|