@momoi-labs/kiso 0.1.0 → 0.2.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/kiso/AGENTS.md +6 -1
- package/kiso/README.md +5 -3
- package/kiso/docs/accessibility.md +18 -2
- package/kiso/docs/brand.md +3 -1
- package/kiso/docs/components/README.md +1 -0
- package/kiso/docs/components/alert.md +4 -1
- package/kiso/docs/components/button.md +25 -15
- package/kiso/docs/components/card.md +42 -6
- package/kiso/docs/components/command-palette.md +6 -3
- package/kiso/docs/components/drawer.md +3 -1
- package/kiso/docs/components/dropdown-menu.md +4 -2
- package/kiso/docs/components/empty-state.md +3 -1
- package/kiso/docs/components/modal-dialog.md +4 -1
- package/kiso/docs/components/popover.md +3 -1
- package/kiso/docs/components/skeleton.md +1 -1
- package/kiso/docs/components/table.md +6 -2
- package/kiso/docs/components/theme-selector.md +114 -0
- package/kiso/docs/components/toast.md +2 -1
- package/kiso/docs/data-interfaces.md +2 -1
- package/kiso/docs/patterns/command-palette.md +2 -1
- package/kiso/docs/patterns/onboarding.md +1 -1
- package/kiso/docs/patterns/settings.md +25 -2
- package/kiso/docs/tokens.md +208 -8
- package/package.json +2 -1
- package/tokens/build/tokens.css +100 -40
- package/tokens/build/tokens.d.ts +149 -13
- package/tokens/build/tokens.json +86 -18
- package/tokens/build/tokens.scss +87 -19
package/kiso/docs/tokens.md
CHANGED
|
@@ -14,10 +14,23 @@ npm run build
|
|
|
14
14
|
```
|
|
15
15
|
|
|
16
16
|
The build emits `tokens/build/tokens.css`, `tokens.json`, `tokens.d.ts`, and
|
|
17
|
-
`tokens.scss`.
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
`tokens.scss`.
|
|
18
|
+
|
|
19
|
+
Each custom property is declared **once**, in `:root`. A role whose two themes
|
|
20
|
+
differ is emitted as CSS `light-dark()`, and the theme is chosen by
|
|
21
|
+
`color-scheme`:
|
|
22
|
+
|
|
23
|
+
```css
|
|
24
|
+
:root { color-scheme: light dark; }
|
|
25
|
+
[data-theme="light"] { color-scheme: light; }
|
|
26
|
+
[data-theme="dark"] { color-scheme: dark; }
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
So the default — no `data-theme` attribute on `<html>` — follows the operating
|
|
30
|
+
system, with no media query and no JavaScript. An explicit choice flips one
|
|
31
|
+
property. See [Theme](patterns/settings.md#theme) for the full contract.
|
|
32
|
+
|
|
33
|
+
Import `tokens.css`; application CSS should need no raw color values.
|
|
21
34
|
|
|
22
35
|
```css
|
|
23
36
|
@import "../../tokens/build/tokens.css";
|
|
@@ -49,6 +62,74 @@ color values.
|
|
|
49
62
|
| `focus` | Keyboard focus ring; never text. | `accent.300` | `accent.base` |
|
|
50
63
|
| `disabled` | Disabled text and controls only. | `neutral.600` | `neutral.400` |
|
|
51
64
|
|
|
65
|
+
### Fills and their foregrounds
|
|
66
|
+
|
|
67
|
+
A filled control needs a text colour of its own. Without one it inherits the
|
|
68
|
+
page foreground, the fill loses its contrast, and the control degrades into an
|
|
69
|
+
outline — which is how a violet design system ends up rendering grey.
|
|
70
|
+
|
|
71
|
+
| Role | Meaning and use | Dark primitive | Light primitive |
|
|
72
|
+
| --- | --- | --- | --- |
|
|
73
|
+
| `primary-foreground` | Text and icons on a `primary` fill. | `neutral.900` | `white` |
|
|
74
|
+
| `primary-hover` | `primary` fill on hover. | `accent.300` | `accent.800` |
|
|
75
|
+
| `danger-foreground` | Text and icons on a `danger` fill. | `neutral.900` | `white` |
|
|
76
|
+
| `secondary` | Neutral button fill, range track, count badge; never text. | `neutral.700` | `neutral.300` |
|
|
77
|
+
| `secondary-foreground` | Text on a `secondary` fill. | `foreground` | `foreground` |
|
|
78
|
+
| `secondary-hover` | `secondary` fill on hover; never text. | `neutral.600` | `neutral.400` |
|
|
79
|
+
| `selected` | Selected row, active nav item, highlighted result; never text. | `accent.900` | `accent.200` |
|
|
80
|
+
| `selected-foreground` | Text on a `selected` fill. | `foreground` | `foreground` |
|
|
81
|
+
|
|
82
|
+
`primary-foreground` and `danger-foreground` invert with their fill: near-black
|
|
83
|
+
on the light lilac of dark theme, white on the deep violet of light theme. Both
|
|
84
|
+
are gated at 4.5:1 **against their own fill**, not against a surface.
|
|
85
|
+
|
|
86
|
+
### Component surfaces
|
|
87
|
+
|
|
88
|
+
| Role | Meaning and use | Dark primitive | Light primitive |
|
|
89
|
+
| --- | --- | --- | --- |
|
|
90
|
+
| `card` | Panel and card fill. Alias of `surface`. | `neutral.800` | `neutral.100` |
|
|
91
|
+
| `card-foreground` | Text on `card`. Alias of `foreground`. | `foreground` | `foreground` |
|
|
92
|
+
| `popover` | Menus, dialogs, palette. Alias of `elevated-surface`. | `neutral.700` | `white` |
|
|
93
|
+
| `popover-foreground` | Text on `popover`. Alias of `foreground`. | `foreground` | `foreground` |
|
|
94
|
+
| `muted` | Recessed fill one step off `card`: table headers, card footers, segmented tracks. | `neutral.700` | `neutral.200` |
|
|
95
|
+
| `sidebar` | Application shell navigation column. | `neutral.950` | `neutral.100` |
|
|
96
|
+
| `sidebar-border` | Divider between sidebar and content. Alias of `border`. | `border` | `border` |
|
|
97
|
+
| `disabled-surface` | Fill of a disabled control. | `neutral.800` | `neutral.200` |
|
|
98
|
+
| `skeleton` | Loading placeholder fill. | `neutral.700` | `neutral.300` |
|
|
99
|
+
| `overlay` | Scrim behind a modal layer. | `black` at 60% | `black` at 40% |
|
|
100
|
+
|
|
101
|
+
### Lines, tints, and state
|
|
102
|
+
|
|
103
|
+
| Role | Meaning and use | Dark primitive | Light primitive |
|
|
104
|
+
| --- | --- | --- | --- |
|
|
105
|
+
| `border-strong` | Hover outlines, switch tracks, gridlines, corner marks; never text. | `neutral.500` | `neutral.500` |
|
|
106
|
+
| `input` | Form control outline at rest. Alias of `border`. | `border` | `border` |
|
|
107
|
+
| `corner-mark` | Corner registration marks. Alias of `border-strong`. | `border-strong` | `border-strong` |
|
|
108
|
+
| `hatch` | Hatch stripe over a region that is not data. | `neutral.700` | `neutral.300` |
|
|
109
|
+
| `accent-surface` | Faintest accent tint: row hover, ghost hover; never text. | `accent.950` | `accent.50` |
|
|
110
|
+
| `accent-surface-hover` | Accent tint one step stronger; never text. | `accent.900` | `accent.200` |
|
|
111
|
+
| `ring` | Focus ring, active drag handle. Alias of `focus`. | `focus` | `focus` |
|
|
112
|
+
| `link` | Inline and standalone links. Alias of `primary`. | `primary` | `primary` |
|
|
113
|
+
| `shadow-hairline` | Shadow colour for a resting control's contact line. | `black` at 30% | `black` at 5% |
|
|
114
|
+
| `shadow-contact` | Shadow colour for separated and floating layers. | `black` at 40% | `black` at 8% |
|
|
115
|
+
|
|
116
|
+
`border-strong` and `corner-mark` are non-text roles but are gated at 3:1
|
|
117
|
+
against every surface: a registration mark that cannot be seen is not a mark.
|
|
118
|
+
|
|
119
|
+
### Status fills
|
|
120
|
+
|
|
121
|
+
Each status role gains a tinted fill and an outline, both the status hue at low
|
|
122
|
+
alpha. No status introduces a second hue.
|
|
123
|
+
|
|
124
|
+
| Role | Dark | Light |
|
|
125
|
+
| --- | --- | --- |
|
|
126
|
+
| `success-surface`, `warning-surface`, `danger-surface`, `info-surface` | status hue at 12% | status hue at 10% |
|
|
127
|
+
| `success-border`, `warning-border`, `danger-border`, `info-border` | status hue at 35% | status hue at 30% |
|
|
128
|
+
|
|
129
|
+
`warning-on-dark`, `danger-on-dark`, and `info-on-dark` are theme-invariant on
|
|
130
|
+
purpose. They are for surfaces that stay dark in both themes — log views and
|
|
131
|
+
terminals — which cannot follow `color-scheme`, so their text cannot either.
|
|
132
|
+
|
|
52
133
|
Use `foreground` for default reading, `muted-foreground` when content is
|
|
53
134
|
secondary but still needs normal-text contrast, and `subtle-foreground` only
|
|
54
135
|
for large or non-essential supporting copy. Use `primary` for the action that
|
|
@@ -70,16 +151,135 @@ themes it resolves the semantic aliases and checks:
|
|
|
70
151
|
and `elevated-surface`;
|
|
71
152
|
- `subtle-foreground` at **3:1** or better against those surfaces, restricting
|
|
72
153
|
it to large text and non-essential metadata;
|
|
73
|
-
- `
|
|
154
|
+
- `border-strong` and `corner-mark` at **3:1** or better against those
|
|
155
|
+
surfaces, per WCAG 1.4.11 for non-text boundaries;
|
|
156
|
+
- `focus` at **3:1** or better against `background` for visible focus rings;
|
|
157
|
+
- each foreground-on-fill pair — `primary-foreground` on `primary`,
|
|
158
|
+
`danger-foreground` on `danger`, `secondary-foreground` on `secondary`,
|
|
159
|
+
`selected-foreground` on `selected`, `card-foreground` on `card`, and
|
|
160
|
+
`popover-foreground` on `popover` — at **4.5:1** or better. This pair is what
|
|
161
|
+
a system without `*-foreground` slots gets wrong, so it is gated rather than
|
|
162
|
+
asserted.
|
|
74
163
|
|
|
75
|
-
`disabled`
|
|
76
|
-
exempt from WCAG 1.4.3. `background`, `surface`,
|
|
77
|
-
|
|
164
|
+
`disabled` and `disabled-surface` are intentionally outside the gate because
|
|
165
|
+
inactive controls are exempt from WCAG 1.4.3. `background`, `surface`,
|
|
166
|
+
`elevated-surface`, `border`, and the tinted `*-surface` roles are not text
|
|
167
|
+
roles. Run the gate with:
|
|
78
168
|
|
|
79
169
|
```sh
|
|
80
170
|
node scripts/check-contrast.mjs tokens/tokens.json
|
|
81
171
|
```
|
|
82
172
|
|
|
173
|
+
## Control size is not touch target
|
|
174
|
+
|
|
175
|
+
`size.control.*` is the height of a single-line control. `size.touch.min` is
|
|
176
|
+
the WCAG 2.2 target-size minimum. They are separate tokens because they answer
|
|
177
|
+
different questions, and collapsing them is what makes a dense console look
|
|
178
|
+
like a toy.
|
|
179
|
+
|
|
180
|
+
| Token | Value | Use |
|
|
181
|
+
| --- | --- | --- |
|
|
182
|
+
| `--size-control-xs` | 24px | Inline table-row actions, dense toolbars. |
|
|
183
|
+
| `--size-control-sm` | 32px | Toolbars, segmented controls, compact forms. |
|
|
184
|
+
| `--size-control-md` | 36px | **The default.** Buttons, inputs, selects. |
|
|
185
|
+
| `--size-control-lg` | 40px | Primary calls to action, table row height. |
|
|
186
|
+
| `--size-touch-min` | 44px | Accessibility minimum — see below. |
|
|
187
|
+
|
|
188
|
+
`--size-touch-min` is applied **only** inside `@media (pointer: coarse)`, as a
|
|
189
|
+
`min-height` on top of a control size. Never as the control size itself.
|
|
190
|
+
|
|
191
|
+
```css
|
|
192
|
+
.btn { height: var(--size-control-md); }
|
|
193
|
+
|
|
194
|
+
@media (pointer: coarse) {
|
|
195
|
+
.btn { min-height: var(--size-touch-min); }
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Layout sizes: `--size-sidebar` (248px) is the shell navigation column;
|
|
200
|
+
`--size-content-max` (1280px) is the maximum content measure. Icon boxes are
|
|
201
|
+
`--size-icon-sm` (14px), `--size-icon-md` (16px, the default), and
|
|
202
|
+
`--size-icon-lg` (20px).
|
|
203
|
+
|
|
204
|
+
## Corners: marks, not radius
|
|
205
|
+
|
|
206
|
+
Panels are square. `--radius-surface` is `0px`, and a panel's corner treatment
|
|
207
|
+
is a **corner mark** instead: two 1px ticks per corner, each lying along the
|
|
208
|
+
frame line it extends and stopping `--corner-mark-gap` short of it, so the mark
|
|
209
|
+
points at the corner without touching it.
|
|
210
|
+
|
|
211
|
+
| Token | Value | Meaning |
|
|
212
|
+
| --- | --- | --- |
|
|
213
|
+
| `--corner-mark` | `1` | Opacity: marks on (`1`) or off (`0`). |
|
|
214
|
+
| `--corner-mark-tick` | 4px | Length of one tick. |
|
|
215
|
+
| `--corner-mark-gap` | 2px | Distance from tick end to the frame. |
|
|
216
|
+
|
|
217
|
+
Two ticks per corner, not four. A full cross puts its other two arms directly
|
|
218
|
+
on top of the 1px panel border, where they are invisible; dropping them halves
|
|
219
|
+
the paint and makes the hollow centre explicit rather than accidental.
|
|
220
|
+
|
|
221
|
+
The gap **is** the mark. Close it and this is just a thicker border.
|
|
222
|
+
|
|
223
|
+
Marks appear on every panel, without exception. There is no rounded mode and no
|
|
224
|
+
`data-corners` attribute — the choice was made once, here.
|
|
225
|
+
|
|
226
|
+
The remaining radii only take the bite off controls:
|
|
227
|
+
|
|
228
|
+
| Token | Value | Use |
|
|
229
|
+
| --- | --- | --- |
|
|
230
|
+
| `--radius-xs` | 2px | Checkboxes, chart bars, the smallest controls. |
|
|
231
|
+
| `--radius-sm` | 3px | Extra-small buttons, focus-ring rounding. |
|
|
232
|
+
| `--radius-md` | 4px | **Buttons, inputs, menu items** — the control default. |
|
|
233
|
+
| `--radius-lg` | 5px | Segmented tracks and other control groups. |
|
|
234
|
+
| `--radius-full` | 9999px | Pills, dots, switches, avatars. |
|
|
235
|
+
| `--radius-surface` | 0px | **Panels, cards, tables, dialogs** — always. |
|
|
236
|
+
|
|
237
|
+
## Hatch
|
|
238
|
+
|
|
239
|
+
A diagonal hatch marks a region that is **not data**. It is the companion to
|
|
240
|
+
the corner marks, and it has exactly three sanctioned uses:
|
|
241
|
+
|
|
242
|
+
- an empty state — nothing here yet;
|
|
243
|
+
- a chrome band — this strip is title and controls, not content;
|
|
244
|
+
- an unavailable pane — the data does not exist right now.
|
|
245
|
+
|
|
246
|
+
```css
|
|
247
|
+
.hatch {
|
|
248
|
+
background-image: repeating-linear-gradient(
|
|
249
|
+
var(--hatch-angle),
|
|
250
|
+
var(--color-hatch) 0,
|
|
251
|
+
var(--color-hatch) var(--hatch-line),
|
|
252
|
+
transparent var(--hatch-line),
|
|
253
|
+
transparent var(--hatch-period)
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
`--hatch-line` is 5px, `--hatch-period` 10px, `--hatch-angle` 45deg. The stripe
|
|
259
|
+
colour is one step off the surface it sits on. Do not raise the contrast to
|
|
260
|
+
make it "read better": if it is loud enough to notice while reading, it is in
|
|
261
|
+
the wrong place.
|
|
262
|
+
|
|
263
|
+
## Shadow is a colour
|
|
264
|
+
|
|
265
|
+
`--shadow-xs`, `-sm`, `-md`, and `-lg` carry the geometry. The colour is a
|
|
266
|
+
token — `--color-shadow-hairline` or `--color-shadow-contact` — so a shadow
|
|
267
|
+
deepens with the theme instead of staying a fixed black at a fixed alpha.
|
|
268
|
+
|
|
269
|
+
| Token | Use |
|
|
270
|
+
| --- | --- |
|
|
271
|
+
| `--shadow-xs` | Resting controls: buttons, inputs, selected segments. A contact line, not a shadow. |
|
|
272
|
+
| `--shadow-sm` | Cards and panels on the canvas. |
|
|
273
|
+
| `--shadow-md` | Popovers and dropdowns. |
|
|
274
|
+
| `--shadow-lg` | Dialogs, drawers, and the command palette — the only layers that float free. |
|
|
275
|
+
|
|
276
|
+
## Type scale
|
|
277
|
+
|
|
278
|
+
11, 12, 14, 16, 18, 22, 30 — `metadata`, `label`, `body`, `h3`, `h2`, `h1`,
|
|
279
|
+
`display`. Tighter than a modular ramp on purpose: these are the steps a
|
|
280
|
+
console actually uses, each distinguishable from its neighbour at a 14px body.
|
|
281
|
+
Body is 14px, not 16px, because a console is read at desk distance, in density.
|
|
282
|
+
|
|
83
283
|
## Generated files
|
|
84
284
|
|
|
85
285
|
All four files in `tokens/build/` are committed. This makes the published
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@momoi-labs/kiso",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Kiso design-system contracts and generated design tokens",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"type": "module",
|
|
11
11
|
"files": [
|
|
12
12
|
"kiso/",
|
|
13
|
+
"!kiso/blocks/",
|
|
13
14
|
"tokens/build/"
|
|
14
15
|
],
|
|
15
16
|
"exports": {
|
package/tokens/build/tokens.css
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
/* Kiso design tokens — generated from tokens/tokens.json. Do not edit. */
|
|
2
2
|
|
|
3
3
|
:root {
|
|
4
|
+
color-scheme: light dark;
|
|
4
5
|
--color-white: #ffffff;
|
|
5
6
|
--color-black: #000000;
|
|
7
|
+
--color-neutral-50: #fffefc;
|
|
6
8
|
--color-neutral-100: #faf9f7;
|
|
7
9
|
--color-neutral-200: #f4f2ee;
|
|
8
10
|
--color-neutral-300: #e0dcd6;
|
|
@@ -12,43 +14,86 @@
|
|
|
12
14
|
--color-neutral-700: #312f37;
|
|
13
15
|
--color-neutral-800: #26252b;
|
|
14
16
|
--color-neutral-900: #1b1a1e;
|
|
17
|
+
--color-neutral-950: #131217;
|
|
18
|
+
--color-accent-50: #f7f4ff;
|
|
15
19
|
--color-accent-200: #ede8fd;
|
|
16
20
|
--color-accent-300: #ded5fb;
|
|
17
21
|
--color-accent-400: #c4b4f5;
|
|
22
|
+
--color-accent-500: #a690ea;
|
|
18
23
|
--color-accent-600: #7d68d1;
|
|
19
24
|
--color-accent-700: #6552b8;
|
|
20
25
|
--color-accent-800: #46309e;
|
|
21
26
|
--color-accent-900: #2e2170;
|
|
22
|
-
--color-accent-
|
|
23
|
-
--color-
|
|
24
|
-
--color-status-
|
|
25
|
-
--color-status-
|
|
26
|
-
--color-status-
|
|
27
|
-
--color-
|
|
28
|
-
--color-
|
|
29
|
-
--color-
|
|
30
|
-
--color-
|
|
31
|
-
--color-
|
|
27
|
+
--color-accent-950: #211741;
|
|
28
|
+
--color-accent-base: light-dark(#5b3fc4, #cbbdf7);
|
|
29
|
+
--color-status-success: light-dark(#0c6b43, #4ed69a);
|
|
30
|
+
--color-status-warning: light-dark(#7a5000, #e8c05a);
|
|
31
|
+
--color-status-danger: light-dark(#ad2f29, #f4867f);
|
|
32
|
+
--color-status-info: light-dark(#15559e, #8fc9f5);
|
|
33
|
+
--color-background: light-dark(var(--color-neutral-200), var(--color-neutral-900));
|
|
34
|
+
--color-surface: light-dark(var(--color-neutral-100), var(--color-neutral-800));
|
|
35
|
+
--color-elevated-surface: light-dark(var(--color-white), var(--color-neutral-700));
|
|
36
|
+
--color-foreground: light-dark(var(--color-neutral-900), var(--color-neutral-100));
|
|
37
|
+
--color-muted-foreground: light-dark(var(--color-neutral-600), var(--color-neutral-400));
|
|
32
38
|
--color-subtle-foreground: var(--color-neutral-500);
|
|
33
|
-
--color-border: var(--color-neutral-600);
|
|
39
|
+
--color-border: light-dark(var(--color-neutral-300), var(--color-neutral-600));
|
|
34
40
|
--color-primary: var(--color-accent-base);
|
|
35
|
-
--color-accent: var(--color-accent-300);
|
|
41
|
+
--color-accent: light-dark(var(--color-accent-800), var(--color-accent-300));
|
|
36
42
|
--color-success: var(--color-status-success);
|
|
37
43
|
--color-warning: var(--color-status-warning);
|
|
38
44
|
--color-danger: var(--color-status-danger);
|
|
39
45
|
--color-info: var(--color-status-info);
|
|
40
|
-
--color-focus: var(--color-accent-300);
|
|
41
|
-
--color-disabled: var(--color-neutral-600);
|
|
46
|
+
--color-focus: light-dark(var(--color-accent-base), var(--color-accent-300));
|
|
47
|
+
--color-disabled: light-dark(var(--color-neutral-400), var(--color-neutral-600));
|
|
48
|
+
--color-card: light-dark(var(--color-neutral-100), var(--color-neutral-800));
|
|
49
|
+
--color-card-foreground: var(--color-foreground);
|
|
50
|
+
--color-popover: light-dark(var(--color-white), var(--color-neutral-700));
|
|
51
|
+
--color-popover-foreground: var(--color-foreground);
|
|
52
|
+
--color-muted: light-dark(var(--color-neutral-200), var(--color-neutral-700));
|
|
53
|
+
--color-sidebar: light-dark(var(--color-neutral-100), var(--color-neutral-950));
|
|
54
|
+
--color-sidebar-border: var(--color-border);
|
|
55
|
+
--color-border-strong: var(--color-neutral-500);
|
|
56
|
+
--color-input: var(--color-border);
|
|
57
|
+
--color-primary-foreground: light-dark(var(--color-white), var(--color-neutral-900));
|
|
58
|
+
--color-primary-hover: light-dark(var(--color-accent-800), var(--color-accent-300));
|
|
59
|
+
--color-link: var(--color-primary);
|
|
60
|
+
--color-accent-surface: light-dark(var(--color-accent-50), var(--color-accent-950));
|
|
61
|
+
--color-accent-surface-hover: light-dark(var(--color-accent-200), var(--color-accent-900));
|
|
62
|
+
--color-selected: light-dark(var(--color-accent-200), var(--color-accent-900));
|
|
63
|
+
--color-selected-foreground: var(--color-foreground);
|
|
64
|
+
--color-secondary: light-dark(var(--color-neutral-300), var(--color-neutral-700));
|
|
65
|
+
--color-secondary-foreground: var(--color-foreground);
|
|
66
|
+
--color-secondary-hover: light-dark(var(--color-neutral-400), var(--color-neutral-600));
|
|
67
|
+
--color-ring: var(--color-focus);
|
|
68
|
+
--color-disabled-surface: light-dark(var(--color-neutral-200), var(--color-neutral-800));
|
|
69
|
+
--color-skeleton: light-dark(var(--color-neutral-300), var(--color-neutral-700));
|
|
70
|
+
--color-overlay: light-dark(rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.6));
|
|
71
|
+
--color-hatch: light-dark(var(--color-neutral-300), var(--color-neutral-700));
|
|
72
|
+
--color-corner-mark: var(--color-border-strong);
|
|
73
|
+
--color-shadow-hairline: light-dark(rgba(0, 0, 0, 0.05), rgba(0, 0, 0, 0.3));
|
|
74
|
+
--color-shadow-contact: light-dark(rgba(0, 0, 0, 0.08), rgba(0, 0, 0, 0.4));
|
|
75
|
+
--color-success-surface: light-dark(rgba(12, 107, 67, 0.1), rgba(78, 214, 154, 0.12));
|
|
76
|
+
--color-success-border: light-dark(rgba(12, 107, 67, 0.3), rgba(78, 214, 154, 0.35));
|
|
77
|
+
--color-warning-surface: light-dark(rgba(122, 80, 0, 0.1), rgba(232, 192, 90, 0.12));
|
|
78
|
+
--color-warning-border: light-dark(rgba(122, 80, 0, 0.3), rgba(232, 192, 90, 0.35));
|
|
79
|
+
--color-danger-surface: light-dark(rgba(173, 47, 41, 0.1), rgba(244, 134, 127, 0.12));
|
|
80
|
+
--color-danger-border: light-dark(rgba(173, 47, 41, 0.3), rgba(244, 134, 127, 0.35));
|
|
81
|
+
--color-info-surface: light-dark(rgba(21, 85, 158, 0.1), rgba(143, 201, 245, 0.12));
|
|
82
|
+
--color-info-border: light-dark(rgba(21, 85, 158, 0.3), rgba(143, 201, 245, 0.35));
|
|
83
|
+
--color-danger-foreground: light-dark(var(--color-white), var(--color-neutral-900));
|
|
84
|
+
--color-warning-on-dark: #e8c05a;
|
|
85
|
+
--color-danger-on-dark: #f4867f;
|
|
86
|
+
--color-info-on-dark: #8fc9f5;
|
|
42
87
|
--font-heading: Inter, system-ui, sans-serif;
|
|
43
88
|
--font-body: Inter, system-ui, sans-serif;
|
|
44
89
|
--font-mono: JetBrains Mono, ui-monospace, monospace;
|
|
45
90
|
--type-size-metadata: 11px;
|
|
46
|
-
--type-size-label:
|
|
47
|
-
--type-size-body:
|
|
48
|
-
--type-size-h3:
|
|
49
|
-
--type-size-h2:
|
|
50
|
-
--type-size-h1:
|
|
51
|
-
--type-size-display:
|
|
91
|
+
--type-size-label: 12px;
|
|
92
|
+
--type-size-body: 14px;
|
|
93
|
+
--type-size-h3: 16px;
|
|
94
|
+
--type-size-h2: 18px;
|
|
95
|
+
--type-size-h1: 22px;
|
|
96
|
+
--type-size-display: 30px;
|
|
52
97
|
--type-weight-regular: 400;
|
|
53
98
|
--type-weight-medium: 500;
|
|
54
99
|
--type-weight-semibold: 600;
|
|
@@ -56,13 +101,16 @@
|
|
|
56
101
|
--type-line-height-tight: 1.2;
|
|
57
102
|
--type-line-height-normal: 1.5;
|
|
58
103
|
--type-line-height-relaxed: 1.6;
|
|
104
|
+
--type-line-height-snug: 1.35;
|
|
59
105
|
--type-letter-spacing-heading: -0.01rem;
|
|
60
106
|
--type-letter-spacing-normal: 0rem;
|
|
61
107
|
--type-letter-spacing-label: 0.02rem;
|
|
108
|
+
--type-letter-spacing-display: -0.02rem;
|
|
109
|
+
--type-letter-spacing-caps: 0.06rem;
|
|
62
110
|
--type-role-display-font-family: var(--font-heading);
|
|
63
111
|
--type-role-display-font-size: var(--type-size-display);
|
|
64
112
|
--type-role-display-font-weight: var(--type-weight-medium);
|
|
65
|
-
--type-role-display-letter-spacing: var(--type-letter-spacing-
|
|
113
|
+
--type-role-display-letter-spacing: var(--type-letter-spacing-display);
|
|
66
114
|
--type-role-display-line-height: var(--type-line-height-tight);
|
|
67
115
|
--type-role-heading-font-family: var(--font-heading);
|
|
68
116
|
--type-role-heading-font-size: var(--type-size-h1);
|
|
@@ -94,6 +142,7 @@
|
|
|
94
142
|
--type-role-numeric-font-weight: var(--type-weight-regular);
|
|
95
143
|
--type-role-numeric-letter-spacing: var(--type-letter-spacing-normal);
|
|
96
144
|
--type-role-numeric-line-height: var(--type-line-height-normal);
|
|
145
|
+
--spacing-2xs: 2px;
|
|
97
146
|
--spacing-xs: 4px;
|
|
98
147
|
--spacing-sm: 8px;
|
|
99
148
|
--spacing-md: 12px;
|
|
@@ -102,12 +151,16 @@
|
|
|
102
151
|
--spacing-2xl: 32px;
|
|
103
152
|
--spacing-3xl: 48px;
|
|
104
153
|
--spacing-4xl: 64px;
|
|
105
|
-
--radius-
|
|
106
|
-
--radius-
|
|
107
|
-
--radius-
|
|
154
|
+
--radius-xs: 2px;
|
|
155
|
+
--radius-sm: 3px;
|
|
156
|
+
--radius-md: 4px;
|
|
157
|
+
--radius-lg: 5px;
|
|
108
158
|
--radius-full: 9999px;
|
|
109
|
-
--
|
|
110
|
-
--shadow-
|
|
159
|
+
--radius-surface: 0px;
|
|
160
|
+
--shadow-xs: 0px 1px 1px 0px var(--color-shadow-hairline);
|
|
161
|
+
--shadow-sm: 0px 1px 2px 0px var(--color-shadow-contact);
|
|
162
|
+
--shadow-md: 0px 2px 8px 0px var(--color-shadow-contact);
|
|
163
|
+
--shadow-lg: 0px 8px 24px 0px var(--color-shadow-contact);
|
|
111
164
|
--motion-duration-fast: 120ms;
|
|
112
165
|
--motion-duration-normal: 200ms;
|
|
113
166
|
--motion-easing-standard: cubic-bezier(0.2, 0, 0, 1);
|
|
@@ -115,24 +168,31 @@
|
|
|
115
168
|
--breakpoint-md: 768px;
|
|
116
169
|
--breakpoint-lg: 1024px;
|
|
117
170
|
--breakpoint-xl: 1280px;
|
|
171
|
+
--size-control-xs: 24px;
|
|
172
|
+
--size-control-sm: 32px;
|
|
173
|
+
--size-control-md: 36px;
|
|
174
|
+
--size-control-lg: 40px;
|
|
175
|
+
--size-touch-min: 44px;
|
|
176
|
+
--size-icon-sm: 14px;
|
|
177
|
+
--size-icon-md: 16px;
|
|
178
|
+
--size-icon-lg: 20px;
|
|
179
|
+
--size-sidebar: 248px;
|
|
180
|
+
--size-content-max: 1280px;
|
|
181
|
+
--corner-mark: 1;
|
|
182
|
+
--corner-mark-tick: 4px;
|
|
183
|
+
--corner-mark-gap: 2px;
|
|
184
|
+
--hatch-line: 5px;
|
|
185
|
+
--hatch-period: 10px;
|
|
186
|
+
--hatch-angle: 45deg;
|
|
118
187
|
--font-variant-numeric: tabular-nums;
|
|
119
188
|
}
|
|
120
189
|
|
|
121
190
|
[data-theme="light"] {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
--color-background: var(--color-neutral-200);
|
|
128
|
-
--color-surface: var(--color-neutral-100);
|
|
129
|
-
--color-elevated-surface: var(--color-white);
|
|
130
|
-
--color-foreground: var(--color-neutral-900);
|
|
131
|
-
--color-muted-foreground: var(--color-neutral-600);
|
|
132
|
-
--color-border: var(--color-neutral-300);
|
|
133
|
-
--color-accent: var(--color-accent-800);
|
|
134
|
-
--color-focus: var(--color-accent-base);
|
|
135
|
-
--color-disabled: var(--color-neutral-400);
|
|
191
|
+
color-scheme: light;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
[data-theme="dark"] {
|
|
195
|
+
color-scheme: dark;
|
|
136
196
|
}
|
|
137
197
|
|
|
138
198
|
@media (prefers-reduced-motion: reduce) {
|