@doitrix/tokens 1.0.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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Doitrix Tech Labs
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,78 @@
1
+ # @doitrix/tokens
2
+
3
+ The design decisions of the Doitrix system, in one place. Colour, type, space,
4
+ radius, elevation, motion and layering are decided here once; every other
5
+ package consumes them and none may invent its own.
6
+
7
+ ```bash
8
+ bun add @doitrix/tokens
9
+ ```
10
+
11
+ ## Three tiers
12
+
13
+ | Tier | Example | Who references it |
14
+ |---|---|---|
15
+ | Primitive | `--doitrix-red-600`, `--doitrix-neutral-950` | Only the themes |
16
+ | Semantic | `--doitrix-color-surface`, `--doitrix-color-fg-muted`, `--doitrix-color-accent` | Components, via the component tier |
17
+ | Component | `--journey-primary`, the Tailwind names (`bg-card`, `text-muted-foreground`) | Component source |
18
+
19
+ A theme remaps the semantic tier and nothing else. Rebranding edits a primitive;
20
+ dark mode edits semantics; neither touches a component.
21
+
22
+ ## Use it
23
+
24
+ **Plain CSS** — every token as a custom property:
25
+
26
+ ```css
27
+ @import '@doitrix/tokens/tokens.css';
28
+
29
+ .panel { background: var(--doitrix-color-surface-raised); padding: var(--doitrix-space-4); }
30
+ ```
31
+
32
+ **Tailwind v4** — the same tokens as a theme, plus base styles, motion and a
33
+ `dark:` variant that follows `[data-theme]`:
34
+
35
+ ```css
36
+ @import 'tailwindcss';
37
+ @import '@doitrix/tokens/tailwind.css';
38
+ ```
39
+
40
+ Utilities use the shadcn vocabulary (`bg-primary`, `text-muted-foreground`,
41
+ `border-input`, `ring-ring`) mapped onto the Doitrix roles, so any shadcn-vue
42
+ component you add later is themed with no edits. Type is by role:
43
+ `text-title-md`, `text-body-sm`, `text-label-lg`.
44
+
45
+ **TypeScript** — typed constants, tree-shakable:
46
+
47
+ ```ts
48
+ import { duration, ease, space, themes, contrastRatio } from '@doitrix/tokens'
49
+ ```
50
+
51
+ ## Themes
52
+
53
+ Light is the default; `prefers-color-scheme: dark` switches automatically unless
54
+ `data-theme="light"` is set. Set `data-theme="dark"` on `<html>`, or on any
55
+ subtree, to force it. Every selector is wrapped in `:where()`, so a plain
56
+ `:root { --doitrix-… }` override in your own CSS always wins, whatever the import
57
+ order.
58
+
59
+ ## Decisions
60
+
61
+ - **Palette:** black and brand red (`red-500 #FF0000`, `red-600 #BC0202`,
62
+ `red-800 #830000`) over a neutral ramp, in OKLCH.
63
+ - **Contrast** is tested for every text/surface pairing in both themes (AA:
64
+ 4.5 for text, 3 for focus rings and borders).
65
+ - **`danger` is a fill, `danger-ink` is for text and borders.** On dark surfaces
66
+ no single red passes AA in both roles.
67
+ - **Space** is a 4px scale. **Durations** sit on a 40ms step:
68
+ press 120 · fast 160 · micro 200 · state 280 · morph 360 · enter 440 ·
69
+ overlay 560 · travel 720. Each easing ships with its GSAP equivalent.
70
+ - **Type:** Google Sans for UI and reading, Montserrat (bold) for display and
71
+ headline roles, Geist Mono for figures. Fonts are not bundled — install
72
+ `@fontsource-variable/google-sans`, `@fontsource-variable/montserrat` and
73
+ `@fontsource-variable/geist-mono`, or load them from Google Fonts.
74
+
75
+ ## Editing
76
+
77
+ The source is `src/`. `css/tokens.css` and `css/tailwind.css` are generated —
78
+ run `bun run sync` from the repository root, never edit them by hand.
@@ -0,0 +1,296 @@
1
+ /* Generated by @doitrix/tokens — edit src/, then run `bun run generate`. */
2
+
3
+ @import './tokens.css';
4
+
5
+ @custom-variant dark {
6
+ &:where([data-theme='dark'], [data-theme='dark'] *) {
7
+ @slot;
8
+ }
9
+ @media (prefers-color-scheme: dark) {
10
+ &:where(:root:not([data-theme]) *) {
11
+ @slot;
12
+ }
13
+ }
14
+ }
15
+
16
+ @theme inline {
17
+ --color-background: var(--doitrix-color-surface);
18
+ --color-foreground: var(--doitrix-color-fg);
19
+ --color-card: var(--doitrix-color-surface-raised);
20
+ --color-card-foreground: var(--doitrix-color-fg);
21
+ --color-popover: var(--doitrix-color-surface-raised);
22
+ --color-popover-foreground: var(--doitrix-color-fg);
23
+ --color-primary: var(--doitrix-color-accent);
24
+ --color-primary-foreground: var(--doitrix-color-fg-on-accent);
25
+ --color-primary-hover: var(--doitrix-color-accent-hover);
26
+ --color-primary-active: var(--doitrix-color-accent-active);
27
+ --color-primary-subtle: var(--doitrix-color-accent-subtle);
28
+ --color-primary-ink: var(--doitrix-color-accent-ink);
29
+ --color-secondary: var(--doitrix-color-surface-tonal);
30
+ --color-secondary-foreground: var(--doitrix-color-fg);
31
+ --color-muted: var(--doitrix-color-surface-sunken);
32
+ --color-muted-foreground: var(--doitrix-color-fg-muted);
33
+ --color-subtle-foreground: var(--doitrix-color-fg-subtle);
34
+ --color-accent: var(--doitrix-color-surface-sunken);
35
+ --color-accent-foreground: var(--doitrix-color-fg);
36
+ --color-strong: var(--doitrix-color-surface-strong);
37
+ --color-strong-foreground: var(--doitrix-color-fg-on-strong);
38
+ --color-brand: var(--doitrix-color-surface-brand);
39
+ --color-brand-foreground: var(--doitrix-color-fg-on-brand);
40
+ --color-destructive: var(--doitrix-color-danger);
41
+ --color-destructive-foreground: var(--doitrix-color-fg-on-accent);
42
+ --color-destructive-subtle: var(--doitrix-color-danger-subtle);
43
+ --color-destructive-ink: var(--doitrix-color-danger-ink);
44
+ --color-success: var(--doitrix-color-success-ink);
45
+ --color-success-subtle: var(--doitrix-color-success-subtle);
46
+ --color-warning: var(--doitrix-color-warning-ink);
47
+ --color-warning-subtle: var(--doitrix-color-warning-subtle);
48
+ --color-border: var(--doitrix-color-line);
49
+ --color-border-strong: var(--doitrix-color-line-strong);
50
+ --color-input: var(--doitrix-color-line-strong);
51
+ --color-ring: var(--doitrix-color-focus-ring);
52
+ --color-scrim: var(--doitrix-color-scrim);
53
+ --color-scrim-foreground: var(--doitrix-color-fg-on-brand);
54
+ --font-sans: var(--doitrix-font-sans);
55
+ --font-mono: var(--doitrix-font-mono);
56
+ --font-display: var(--doitrix-font-display);
57
+ --font-weight-medium: var(--doitrix-font-weight-medium);
58
+ --font-weight-semibold: var(--doitrix-font-weight-semibold);
59
+ --font-weight-bold: var(--doitrix-font-weight-bold);
60
+ --font-weight-extrabold: var(--doitrix-font-weight-extrabold);
61
+ --text-display-lg: var(--doitrix-text-display-lg-size);
62
+ --text-display-lg--line-height: var(--doitrix-text-display-lg-line-height);
63
+ --text-display-lg--font-weight: var(--doitrix-text-display-lg-weight);
64
+ --text-display-lg--letter-spacing: var(--doitrix-text-display-lg-tracking);
65
+ --text-display-md: var(--doitrix-text-display-md-size);
66
+ --text-display-md--line-height: var(--doitrix-text-display-md-line-height);
67
+ --text-display-md--font-weight: var(--doitrix-text-display-md-weight);
68
+ --text-display-md--letter-spacing: var(--doitrix-text-display-md-tracking);
69
+ --text-display-sm: var(--doitrix-text-display-sm-size);
70
+ --text-display-sm--line-height: var(--doitrix-text-display-sm-line-height);
71
+ --text-display-sm--font-weight: var(--doitrix-text-display-sm-weight);
72
+ --text-display-sm--letter-spacing: var(--doitrix-text-display-sm-tracking);
73
+ --text-headline-lg: var(--doitrix-text-headline-lg-size);
74
+ --text-headline-lg--line-height: var(--doitrix-text-headline-lg-line-height);
75
+ --text-headline-lg--font-weight: var(--doitrix-text-headline-lg-weight);
76
+ --text-headline-lg--letter-spacing: var(--doitrix-text-headline-lg-tracking);
77
+ --text-headline-md: var(--doitrix-text-headline-md-size);
78
+ --text-headline-md--line-height: var(--doitrix-text-headline-md-line-height);
79
+ --text-headline-md--font-weight: var(--doitrix-text-headline-md-weight);
80
+ --text-headline-md--letter-spacing: var(--doitrix-text-headline-md-tracking);
81
+ --text-headline-sm: var(--doitrix-text-headline-sm-size);
82
+ --text-headline-sm--line-height: var(--doitrix-text-headline-sm-line-height);
83
+ --text-headline-sm--font-weight: var(--doitrix-text-headline-sm-weight);
84
+ --text-headline-sm--letter-spacing: var(--doitrix-text-headline-sm-tracking);
85
+ --text-title-lg: var(--doitrix-text-title-lg-size);
86
+ --text-title-lg--line-height: var(--doitrix-text-title-lg-line-height);
87
+ --text-title-lg--font-weight: var(--doitrix-text-title-lg-weight);
88
+ --text-title-lg--letter-spacing: var(--doitrix-text-title-lg-tracking);
89
+ --text-title-md: var(--doitrix-text-title-md-size);
90
+ --text-title-md--line-height: var(--doitrix-text-title-md-line-height);
91
+ --text-title-md--font-weight: var(--doitrix-text-title-md-weight);
92
+ --text-title-md--letter-spacing: var(--doitrix-text-title-md-tracking);
93
+ --text-title-sm: var(--doitrix-text-title-sm-size);
94
+ --text-title-sm--line-height: var(--doitrix-text-title-sm-line-height);
95
+ --text-title-sm--font-weight: var(--doitrix-text-title-sm-weight);
96
+ --text-title-sm--letter-spacing: var(--doitrix-text-title-sm-tracking);
97
+ --text-body-lg: var(--doitrix-text-body-lg-size);
98
+ --text-body-lg--line-height: var(--doitrix-text-body-lg-line-height);
99
+ --text-body-lg--font-weight: var(--doitrix-text-body-lg-weight);
100
+ --text-body-lg--letter-spacing: var(--doitrix-text-body-lg-tracking);
101
+ --text-body-md: var(--doitrix-text-body-md-size);
102
+ --text-body-md--line-height: var(--doitrix-text-body-md-line-height);
103
+ --text-body-md--font-weight: var(--doitrix-text-body-md-weight);
104
+ --text-body-md--letter-spacing: var(--doitrix-text-body-md-tracking);
105
+ --text-body-sm: var(--doitrix-text-body-sm-size);
106
+ --text-body-sm--line-height: var(--doitrix-text-body-sm-line-height);
107
+ --text-body-sm--font-weight: var(--doitrix-text-body-sm-weight);
108
+ --text-body-sm--letter-spacing: var(--doitrix-text-body-sm-tracking);
109
+ --text-label-lg: var(--doitrix-text-label-lg-size);
110
+ --text-label-lg--line-height: var(--doitrix-text-label-lg-line-height);
111
+ --text-label-lg--font-weight: var(--doitrix-text-label-lg-weight);
112
+ --text-label-lg--letter-spacing: var(--doitrix-text-label-lg-tracking);
113
+ --text-label-md: var(--doitrix-text-label-md-size);
114
+ --text-label-md--line-height: var(--doitrix-text-label-md-line-height);
115
+ --text-label-md--font-weight: var(--doitrix-text-label-md-weight);
116
+ --text-label-md--letter-spacing: var(--doitrix-text-label-md-tracking);
117
+ --text-overline: var(--doitrix-text-overline-size);
118
+ --text-overline--line-height: var(--doitrix-text-overline-line-height);
119
+ --text-overline--font-weight: var(--doitrix-text-overline-weight);
120
+ --text-overline--letter-spacing: var(--doitrix-text-overline-tracking);
121
+ --radius-none: var(--doitrix-radius-none);
122
+ --radius-sm: var(--doitrix-radius-sm);
123
+ --radius-md: var(--doitrix-radius-md);
124
+ --radius-lg: var(--doitrix-radius-lg);
125
+ --radius-xl: var(--doitrix-radius-xl);
126
+ --radius-full: var(--doitrix-radius-full);
127
+ --shadow-sm: var(--doitrix-shadow-sm);
128
+ --shadow-md: var(--doitrix-shadow-md);
129
+ --shadow-lg: var(--doitrix-shadow-lg);
130
+ --shadow-xl: var(--doitrix-shadow-xl);
131
+ --ease-standard: var(--doitrix-ease-standard);
132
+ --ease-out: var(--doitrix-ease-out);
133
+ --ease-in-out: var(--doitrix-ease-in-out);
134
+ --ease-in: var(--doitrix-ease-in);
135
+ --ease-emphasized: var(--doitrix-ease-emphasized);
136
+ --blur-sm: var(--doitrix-blur-sm);
137
+ --blur-md: var(--doitrix-blur-md);
138
+ --blur-lg: var(--doitrix-blur-lg);
139
+ --container-prose: var(--doitrix-container-prose);
140
+ --container-page: var(--doitrix-container-page);
141
+ --animate-fade-in: doitrix-fade-in var(--doitrix-duration-fast) var(--doitrix-ease-out) both;
142
+ --animate-fade-out: doitrix-fade-out var(--doitrix-duration-fast) var(--doitrix-ease-in) both;
143
+ --animate-pop-in: doitrix-pop-in var(--doitrix-duration-fast) var(--doitrix-ease-out) both;
144
+ --animate-pop-out: doitrix-pop-out var(--doitrix-duration-fast) var(--doitrix-ease-in) both;
145
+ --animate-overlay-in: doitrix-overlay-in var(--doitrix-duration-enter) var(--doitrix-ease-out) both;
146
+ --animate-overlay-out: doitrix-overlay-out var(--doitrix-duration-state) var(--doitrix-ease-in) both;
147
+ --animate-dialog-in: doitrix-dialog-in var(--doitrix-duration-enter) var(--doitrix-ease-emphasized) both;
148
+ --animate-dialog-out: doitrix-dialog-out var(--doitrix-duration-micro) var(--doitrix-ease-in) both;
149
+ --animate-float-in: doitrix-float-in var(--doitrix-duration-morph) var(--doitrix-ease-emphasized) both;
150
+ --animate-float-out: doitrix-float-out var(--doitrix-duration-fast) var(--doitrix-ease-in) both;
151
+ --animate-slide-in-top: doitrix-slide-in-top var(--doitrix-duration-enter) var(--doitrix-ease-emphasized) both;
152
+ --animate-slide-out-top: doitrix-slide-out-top var(--doitrix-duration-state) var(--doitrix-ease-in) both;
153
+ --animate-slide-in-bottom: doitrix-slide-in-bottom var(--doitrix-duration-enter) var(--doitrix-ease-emphasized) both;
154
+ --animate-slide-out-bottom: doitrix-slide-out-bottom var(--doitrix-duration-state) var(--doitrix-ease-in) both;
155
+ --animate-slide-in-left: doitrix-slide-in-left var(--doitrix-duration-enter) var(--doitrix-ease-emphasized) both;
156
+ --animate-slide-out-left: doitrix-slide-out-left var(--doitrix-duration-state) var(--doitrix-ease-in) both;
157
+ --animate-slide-in-right: doitrix-slide-in-right var(--doitrix-duration-enter) var(--doitrix-ease-emphasized) both;
158
+ --animate-slide-out-right: doitrix-slide-out-right var(--doitrix-duration-state) var(--doitrix-ease-in) both;
159
+ --animate-collapsible-down: doitrix-collapsible-down var(--doitrix-duration-morph) var(--doitrix-ease-emphasized) both;
160
+ --animate-collapsible-up: doitrix-collapsible-up var(--doitrix-duration-state) var(--doitrix-ease-in) both;
161
+ --animate-indeterminate: doitrix-indeterminate var(--doitrix-duration-overlay) var(--doitrix-ease-in-out) infinite;
162
+ --animate-draw: doitrix-draw var(--doitrix-duration-travel) var(--doitrix-ease-emphasized) both;
163
+ --animate-skeleton: doitrix-skeleton var(--doitrix-duration-travel) var(--doitrix-ease-in-out) infinite;
164
+ --animate-spin: doitrix-spin var(--doitrix-duration-travel) linear infinite;
165
+ --default-transition-duration: var(--doitrix-duration-fast);
166
+ --default-transition-timing-function: var(--doitrix-ease-standard);
167
+ }
168
+
169
+ @keyframes doitrix-fade-in {
170
+ from { opacity: 0; }
171
+ }
172
+
173
+ @keyframes doitrix-fade-out {
174
+ to { opacity: 0; }
175
+ }
176
+
177
+ @keyframes doitrix-pop-in {
178
+ from { opacity: 0; scale: 0.96; }
179
+ }
180
+
181
+ @keyframes doitrix-pop-out {
182
+ to { opacity: 0; scale: 0.96; }
183
+ }
184
+
185
+ @keyframes doitrix-overlay-in {
186
+ from { opacity: 0; }
187
+ }
188
+
189
+ @keyframes doitrix-overlay-out {
190
+ to { opacity: 0; }
191
+ }
192
+
193
+ @keyframes doitrix-dialog-in {
194
+ from { opacity: 0; transform: translateY(var(--doitrix-space-4)) scale(0.96); }
195
+ }
196
+
197
+ @keyframes doitrix-dialog-out {
198
+ to { opacity: 0; transform: translateY(var(--doitrix-space-2)) scale(0.98); }
199
+ }
200
+
201
+ @keyframes doitrix-float-in {
202
+ from { opacity: 0; translate: var(--doitrix-float-x, 0) var(--doitrix-float-y, 0); scale: 0.97; }
203
+ }
204
+
205
+ @keyframes doitrix-float-out {
206
+ to { opacity: 0; scale: 0.98; }
207
+ }
208
+
209
+ @keyframes doitrix-slide-in-top {
210
+ from { translate: 0 -100%; }
211
+ }
212
+
213
+ @keyframes doitrix-slide-out-top {
214
+ to { translate: 0 -100%; }
215
+ }
216
+
217
+ @keyframes doitrix-slide-in-bottom {
218
+ from { translate: 0 100%; }
219
+ }
220
+
221
+ @keyframes doitrix-slide-out-bottom {
222
+ to { translate: 0 100%; }
223
+ }
224
+
225
+ @keyframes doitrix-slide-in-left {
226
+ from { translate: -100% 0; }
227
+ }
228
+
229
+ @keyframes doitrix-slide-out-left {
230
+ to { translate: -100% 0; }
231
+ }
232
+
233
+ @keyframes doitrix-slide-in-right {
234
+ from { translate: 100% 0; }
235
+ }
236
+
237
+ @keyframes doitrix-slide-out-right {
238
+ to { translate: 100% 0; }
239
+ }
240
+
241
+ @keyframes doitrix-collapsible-down {
242
+ from { height: 0; opacity: 0; } to { height: var(--doitrix-collapsible-height); }
243
+ }
244
+
245
+ @keyframes doitrix-collapsible-up {
246
+ from { height: var(--doitrix-collapsible-height); } to { height: 0; opacity: 0; }
247
+ }
248
+
249
+ @keyframes doitrix-indeterminate {
250
+ from { translate: -100% 0; } to { translate: 250% 0; }
251
+ }
252
+
253
+ @keyframes doitrix-draw {
254
+ from { stroke-dashoffset: 1; }
255
+ }
256
+
257
+ @keyframes doitrix-skeleton {
258
+ 50% { opacity: 0.5; }
259
+ }
260
+
261
+ @keyframes doitrix-spin {
262
+ to { rotate: 360deg; }
263
+ }
264
+
265
+ @layer base {
266
+ *, ::before, ::after {
267
+ border-color: var(--doitrix-color-line);
268
+ }
269
+ html {
270
+ background-color: var(--doitrix-color-surface);
271
+ color: var(--doitrix-color-fg);
272
+ font-family: var(--doitrix-font-sans);
273
+ font-weight: var(--doitrix-font-weight-medium);
274
+ -webkit-font-smoothing: antialiased;
275
+ }
276
+ :focus-visible {
277
+ outline: var(--doitrix-focus-ring);
278
+ outline-offset: var(--doitrix-focus-ring-offset);
279
+ }
280
+ :where(.text-display-lg, .text-display-md, .text-display-sm, .text-headline-lg, .text-headline-md, .text-headline-sm) {
281
+ font-family: var(--doitrix-font-display);
282
+ }
283
+ @media (prefers-reduced-motion: reduce) {
284
+ *, ::before, ::after {
285
+ animation-duration: 0.01ms !important;
286
+ animation-iteration-count: 1 !important;
287
+ transition-duration: 0.01ms !important;
288
+ scroll-behavior: auto !important;
289
+ }
290
+ }
291
+ ::selection {
292
+ background-color: var(--doitrix-color-accent-subtle);
293
+ color: var(--doitrix-color-fg);
294
+ }
295
+ }
296
+
package/css/tokens.css ADDED
@@ -0,0 +1,284 @@
1
+ /* Generated by @doitrix/tokens — edit src/, then run `bun run generate`. */
2
+
3
+ :where(:root) {
4
+ --doitrix-black: oklch(0 0 0);
5
+ --doitrix-neutral-0: oklch(1 0 0);
6
+ --doitrix-neutral-50: oklch(0.985 0 0);
7
+ --doitrix-neutral-100: oklch(0.97 0 0);
8
+ --doitrix-neutral-200: oklch(0.922 0 0);
9
+ --doitrix-neutral-300: oklch(0.87 0 0);
10
+ --doitrix-neutral-400: oklch(0.708 0 0);
11
+ --doitrix-neutral-500: oklch(0.556 0 0);
12
+ --doitrix-neutral-600: oklch(0.439 0 0);
13
+ --doitrix-neutral-700: oklch(0.371 0 0);
14
+ --doitrix-neutral-800: oklch(0.269 0 0);
15
+ --doitrix-neutral-900: oklch(0.205 0 0);
16
+ --doitrix-neutral-950: oklch(0.145 0 0);
17
+ --doitrix-red-50: oklch(0.969 0.015 17.4);
18
+ --doitrix-red-100: oklch(0.928 0.037 17.8);
19
+ --doitrix-red-200: oklch(0.869 0.07 18.6);
20
+ --doitrix-red-300: oklch(0.779 0.129 20.4);
21
+ --doitrix-red-400: oklch(0.679 0.209 24.7);
22
+ --doitrix-red-500: oklch(0.628 0.258 29.2);
23
+ --doitrix-red-600: oklch(0.5 0.204 29.1);
24
+ --doitrix-red-700: oklch(0.44 0.18 29.2);
25
+ --doitrix-red-800: oklch(0.383 0.157 29.2);
26
+ --doitrix-red-900: oklch(0.298 0.122 29.2);
27
+ --doitrix-red-950: oklch(0.202 0.083 29.2);
28
+ --doitrix-green-50: oklch(0.982 0.018 155.8);
29
+ --doitrix-green-400: oklch(0.792 0.209 151.7);
30
+ --doitrix-green-700: oklch(0.527 0.154 150.1);
31
+ --doitrix-green-950: oklch(0.266 0.065 152.9);
32
+ --doitrix-amber-50: oklch(0.987 0.022 95.3);
33
+ --doitrix-amber-400: oklch(0.828 0.189 84.4);
34
+ --doitrix-amber-700: oklch(0.555 0.163 49);
35
+ --doitrix-amber-950: oklch(0.279 0.077 45.6);
36
+ --doitrix-space-0: 0;
37
+ --doitrix-space-1: 0.25rem;
38
+ --doitrix-space-2: 0.5rem;
39
+ --doitrix-space-3: 0.75rem;
40
+ --doitrix-space-4: 1rem;
41
+ --doitrix-space-5: 1.25rem;
42
+ --doitrix-space-6: 1.5rem;
43
+ --doitrix-space-8: 2rem;
44
+ --doitrix-space-10: 2.5rem;
45
+ --doitrix-space-12: 3rem;
46
+ --doitrix-space-16: 4rem;
47
+ --doitrix-space-20: 5rem;
48
+ --doitrix-space-24: 6rem;
49
+ --doitrix-radius-none: 0;
50
+ --doitrix-radius-sm: 0.25rem;
51
+ --doitrix-radius-md: 0.5rem;
52
+ --doitrix-radius-lg: 0.75rem;
53
+ --doitrix-radius-xl: 1rem;
54
+ --doitrix-radius-full: 9999px;
55
+ --doitrix-font-sans: 'Google Sans Variable', 'Google Sans', ui-sans-serif, system-ui, sans-serif;
56
+ --doitrix-font-mono: 'Geist Mono Variable', 'Geist Mono', ui-monospace, monospace;
57
+ --doitrix-font-display: 'Montserrat Variable', 'Montserrat', 'Google Sans Variable', ui-sans-serif, system-ui, sans-serif;
58
+ --doitrix-font-weight-medium: 500;
59
+ --doitrix-font-weight-semibold: 600;
60
+ --doitrix-font-weight-bold: 700;
61
+ --doitrix-font-weight-extrabold: 800;
62
+ --doitrix-text-display-lg-size: 3.5625rem;
63
+ --doitrix-text-display-lg-line-height: 4rem;
64
+ --doitrix-text-display-lg-weight: var(--doitrix-font-weight-bold);
65
+ --doitrix-text-display-lg-tracking: -0.015625rem;
66
+ --doitrix-text-display-lg-family: var(--doitrix-font-display);
67
+ --doitrix-text-display-md-size: 2.8125rem;
68
+ --doitrix-text-display-md-line-height: 3.25rem;
69
+ --doitrix-text-display-md-weight: var(--doitrix-font-weight-bold);
70
+ --doitrix-text-display-md-tracking: 0;
71
+ --doitrix-text-display-md-family: var(--doitrix-font-display);
72
+ --doitrix-text-display-sm-size: 2.25rem;
73
+ --doitrix-text-display-sm-line-height: 2.75rem;
74
+ --doitrix-text-display-sm-weight: var(--doitrix-font-weight-bold);
75
+ --doitrix-text-display-sm-tracking: 0;
76
+ --doitrix-text-display-sm-family: var(--doitrix-font-display);
77
+ --doitrix-text-headline-lg-size: 2rem;
78
+ --doitrix-text-headline-lg-line-height: 2.5rem;
79
+ --doitrix-text-headline-lg-weight: var(--doitrix-font-weight-bold);
80
+ --doitrix-text-headline-lg-tracking: 0;
81
+ --doitrix-text-headline-lg-family: var(--doitrix-font-display);
82
+ --doitrix-text-headline-md-size: 1.75rem;
83
+ --doitrix-text-headline-md-line-height: 2.25rem;
84
+ --doitrix-text-headline-md-weight: var(--doitrix-font-weight-bold);
85
+ --doitrix-text-headline-md-tracking: 0;
86
+ --doitrix-text-headline-md-family: var(--doitrix-font-display);
87
+ --doitrix-text-headline-sm-size: 1.5rem;
88
+ --doitrix-text-headline-sm-line-height: 2rem;
89
+ --doitrix-text-headline-sm-weight: var(--doitrix-font-weight-bold);
90
+ --doitrix-text-headline-sm-tracking: 0;
91
+ --doitrix-text-headline-sm-family: var(--doitrix-font-display);
92
+ --doitrix-text-title-lg-size: 1.375rem;
93
+ --doitrix-text-title-lg-line-height: 1.75rem;
94
+ --doitrix-text-title-lg-weight: var(--doitrix-font-weight-semibold);
95
+ --doitrix-text-title-lg-tracking: 0;
96
+ --doitrix-text-title-lg-family: var(--doitrix-font-sans);
97
+ --doitrix-text-title-md-size: 1rem;
98
+ --doitrix-text-title-md-line-height: 1.5rem;
99
+ --doitrix-text-title-md-weight: var(--doitrix-font-weight-semibold);
100
+ --doitrix-text-title-md-tracking: 0.009375rem;
101
+ --doitrix-text-title-md-family: var(--doitrix-font-sans);
102
+ --doitrix-text-title-sm-size: 0.875rem;
103
+ --doitrix-text-title-sm-line-height: 1.25rem;
104
+ --doitrix-text-title-sm-weight: var(--doitrix-font-weight-semibold);
105
+ --doitrix-text-title-sm-tracking: 0.00625rem;
106
+ --doitrix-text-title-sm-family: var(--doitrix-font-sans);
107
+ --doitrix-text-body-lg-size: 1rem;
108
+ --doitrix-text-body-lg-line-height: 1.5rem;
109
+ --doitrix-text-body-lg-weight: var(--doitrix-font-weight-medium);
110
+ --doitrix-text-body-lg-tracking: 0;
111
+ --doitrix-text-body-lg-family: var(--doitrix-font-sans);
112
+ --doitrix-text-body-md-size: 0.875rem;
113
+ --doitrix-text-body-md-line-height: 1.25rem;
114
+ --doitrix-text-body-md-weight: var(--doitrix-font-weight-medium);
115
+ --doitrix-text-body-md-tracking: 0;
116
+ --doitrix-text-body-md-family: var(--doitrix-font-sans);
117
+ --doitrix-text-body-sm-size: 0.75rem;
118
+ --doitrix-text-body-sm-line-height: 1rem;
119
+ --doitrix-text-body-sm-weight: var(--doitrix-font-weight-medium);
120
+ --doitrix-text-body-sm-tracking: 0;
121
+ --doitrix-text-body-sm-family: var(--doitrix-font-sans);
122
+ --doitrix-text-label-lg-size: 0.875rem;
123
+ --doitrix-text-label-lg-line-height: 1.25rem;
124
+ --doitrix-text-label-lg-weight: var(--doitrix-font-weight-medium);
125
+ --doitrix-text-label-lg-tracking: 0.00625rem;
126
+ --doitrix-text-label-lg-family: var(--doitrix-font-sans);
127
+ --doitrix-text-label-md-size: 0.75rem;
128
+ --doitrix-text-label-md-line-height: 1rem;
129
+ --doitrix-text-label-md-weight: var(--doitrix-font-weight-medium);
130
+ --doitrix-text-label-md-tracking: 0.03125rem;
131
+ --doitrix-text-label-md-family: var(--doitrix-font-sans);
132
+ --doitrix-text-overline-size: 0.75rem;
133
+ --doitrix-text-overline-line-height: 1rem;
134
+ --doitrix-text-overline-weight: var(--doitrix-font-weight-semibold);
135
+ --doitrix-text-overline-tracking: 0.16em;
136
+ --doitrix-text-overline-family: var(--doitrix-font-sans);
137
+ --doitrix-duration-press: 120ms;
138
+ --doitrix-duration-fast: 160ms;
139
+ --doitrix-duration-micro: 200ms;
140
+ --doitrix-duration-state: 280ms;
141
+ --doitrix-duration-morph: 360ms;
142
+ --doitrix-duration-enter: 440ms;
143
+ --doitrix-duration-overlay: 560ms;
144
+ --doitrix-duration-travel: 720ms;
145
+ --doitrix-ease-standard: cubic-bezier(0.2, 0, 0, 1);
146
+ --doitrix-ease-out: cubic-bezier(0.33, 1, 0.68, 1);
147
+ --doitrix-ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
148
+ --doitrix-ease-in: cubic-bezier(0.11, 0, 0.5, 0);
149
+ --doitrix-ease-emphasized: cubic-bezier(0.16, 1, 0.3, 1);
150
+ --doitrix-z-base: 0;
151
+ --doitrix-z-dropdown: 1000;
152
+ --doitrix-z-sticky: 1100;
153
+ --doitrix-z-overlay: 1200;
154
+ --doitrix-z-modal: 1300;
155
+ --doitrix-z-popover: 1400;
156
+ --doitrix-z-toast: 1500;
157
+ --doitrix-z-guide: 9999;
158
+ --doitrix-blur-sm: 4px;
159
+ --doitrix-blur-md: 12px;
160
+ --doitrix-blur-lg: 24px;
161
+ --doitrix-container-prose: 42rem;
162
+ --doitrix-container-page: 72rem;
163
+ --doitrix-target-min: 44px;
164
+ --doitrix-focus-ring-width: 2px;
165
+ --doitrix-focus-ring-offset: 2px;
166
+ --doitrix-press-scale: 0.97;
167
+ --doitrix-border-width: 1px;
168
+ --doitrix-float-x: 0;
169
+ --doitrix-float-y: 0;
170
+ --doitrix-collapsible-height: auto;
171
+ --doitrix-collapsible-width: auto;
172
+ }
173
+
174
+ :where(:root, [data-theme='light']) {
175
+ --doitrix-color-surface: var(--doitrix-neutral-0);
176
+ --doitrix-color-surface-raised: var(--doitrix-neutral-0);
177
+ --doitrix-color-surface-sunken: var(--doitrix-neutral-100);
178
+ --doitrix-color-surface-tonal: var(--doitrix-neutral-200);
179
+ --doitrix-color-surface-strong: var(--doitrix-black);
180
+ --doitrix-color-fg: var(--doitrix-neutral-950);
181
+ --doitrix-color-fg-muted: var(--doitrix-neutral-600);
182
+ --doitrix-color-fg-subtle: var(--doitrix-neutral-500);
183
+ --doitrix-color-fg-on-accent: var(--doitrix-neutral-0);
184
+ --doitrix-color-fg-on-strong: var(--doitrix-neutral-0);
185
+ --doitrix-color-line: var(--doitrix-neutral-200);
186
+ --doitrix-color-line-strong: var(--doitrix-neutral-300);
187
+ --doitrix-color-accent: var(--doitrix-red-600);
188
+ --doitrix-color-accent-hover: var(--doitrix-red-700);
189
+ --doitrix-color-accent-active: var(--doitrix-red-800);
190
+ --doitrix-color-accent-subtle: var(--doitrix-red-50);
191
+ --doitrix-color-accent-ink: var(--doitrix-red-700);
192
+ --doitrix-color-success-subtle: var(--doitrix-green-50);
193
+ --doitrix-color-success-ink: var(--doitrix-green-700);
194
+ --doitrix-color-warning-subtle: var(--doitrix-amber-50);
195
+ --doitrix-color-warning-ink: var(--doitrix-amber-700);
196
+ --doitrix-color-danger: var(--doitrix-red-700);
197
+ --doitrix-color-danger-subtle: var(--doitrix-red-50);
198
+ --doitrix-color-danger-ink: var(--doitrix-red-700);
199
+ --doitrix-color-focus-ring: var(--doitrix-red-500);
200
+ --doitrix-color-scrim: var(--doitrix-black);
201
+ --doitrix-color-surface-brand: var(--doitrix-black);
202
+ --doitrix-color-fg-on-brand: var(--doitrix-neutral-50);
203
+ }
204
+
205
+ :where([data-theme='dark']) {
206
+ --doitrix-color-surface: var(--doitrix-neutral-950);
207
+ --doitrix-color-surface-raised: var(--doitrix-neutral-900);
208
+ --doitrix-color-surface-sunken: var(--doitrix-black);
209
+ --doitrix-color-surface-tonal: var(--doitrix-neutral-800);
210
+ --doitrix-color-surface-strong: var(--doitrix-neutral-100);
211
+ --doitrix-color-fg: var(--doitrix-neutral-50);
212
+ --doitrix-color-fg-muted: var(--doitrix-neutral-400);
213
+ --doitrix-color-fg-subtle: var(--doitrix-neutral-400);
214
+ --doitrix-color-fg-on-accent: var(--doitrix-neutral-0);
215
+ --doitrix-color-fg-on-strong: var(--doitrix-neutral-950);
216
+ --doitrix-color-line: var(--doitrix-neutral-800);
217
+ --doitrix-color-line-strong: var(--doitrix-neutral-700);
218
+ --doitrix-color-accent: var(--doitrix-red-600);
219
+ --doitrix-color-accent-hover: var(--doitrix-red-700);
220
+ --doitrix-color-accent-active: var(--doitrix-red-800);
221
+ --doitrix-color-accent-subtle: var(--doitrix-red-950);
222
+ --doitrix-color-accent-ink: var(--doitrix-red-400);
223
+ --doitrix-color-success-subtle: var(--doitrix-green-950);
224
+ --doitrix-color-success-ink: var(--doitrix-green-400);
225
+ --doitrix-color-warning-subtle: var(--doitrix-amber-950);
226
+ --doitrix-color-warning-ink: var(--doitrix-amber-400);
227
+ --doitrix-color-danger: var(--doitrix-red-600);
228
+ --doitrix-color-danger-subtle: var(--doitrix-red-950);
229
+ --doitrix-color-danger-ink: var(--doitrix-red-400);
230
+ --doitrix-color-focus-ring: var(--doitrix-red-500);
231
+ --doitrix-color-scrim: var(--doitrix-black);
232
+ --doitrix-color-surface-brand: var(--doitrix-black);
233
+ --doitrix-color-fg-on-brand: var(--doitrix-neutral-50);
234
+ }
235
+
236
+ @media (prefers-color-scheme: dark) {
237
+ :where(:root:not([data-theme='light'])) {
238
+ --doitrix-color-surface: var(--doitrix-neutral-950);
239
+ --doitrix-color-surface-raised: var(--doitrix-neutral-900);
240
+ --doitrix-color-surface-sunken: var(--doitrix-black);
241
+ --doitrix-color-surface-tonal: var(--doitrix-neutral-800);
242
+ --doitrix-color-surface-strong: var(--doitrix-neutral-100);
243
+ --doitrix-color-fg: var(--doitrix-neutral-50);
244
+ --doitrix-color-fg-muted: var(--doitrix-neutral-400);
245
+ --doitrix-color-fg-subtle: var(--doitrix-neutral-400);
246
+ --doitrix-color-fg-on-accent: var(--doitrix-neutral-0);
247
+ --doitrix-color-fg-on-strong: var(--doitrix-neutral-950);
248
+ --doitrix-color-line: var(--doitrix-neutral-800);
249
+ --doitrix-color-line-strong: var(--doitrix-neutral-700);
250
+ --doitrix-color-accent: var(--doitrix-red-600);
251
+ --doitrix-color-accent-hover: var(--doitrix-red-700);
252
+ --doitrix-color-accent-active: var(--doitrix-red-800);
253
+ --doitrix-color-accent-subtle: var(--doitrix-red-950);
254
+ --doitrix-color-accent-ink: var(--doitrix-red-400);
255
+ --doitrix-color-success-subtle: var(--doitrix-green-950);
256
+ --doitrix-color-success-ink: var(--doitrix-green-400);
257
+ --doitrix-color-warning-subtle: var(--doitrix-amber-950);
258
+ --doitrix-color-warning-ink: var(--doitrix-amber-400);
259
+ --doitrix-color-danger: var(--doitrix-red-600);
260
+ --doitrix-color-danger-subtle: var(--doitrix-red-950);
261
+ --doitrix-color-danger-ink: var(--doitrix-red-400);
262
+ --doitrix-color-focus-ring: var(--doitrix-red-500);
263
+ --doitrix-color-scrim: var(--doitrix-black);
264
+ --doitrix-color-surface-brand: var(--doitrix-black);
265
+ --doitrix-color-fg-on-brand: var(--doitrix-neutral-50);
266
+ }
267
+ }
268
+
269
+ :where(:root, [data-theme]) {
270
+ --doitrix-color-hover: color-mix(in oklch, var(--doitrix-color-fg) 8%, transparent);
271
+ --doitrix-color-pressed: color-mix(in oklch, var(--doitrix-color-fg) 12%, transparent);
272
+ --doitrix-color-disabled: color-mix(in oklch, var(--doitrix-color-fg) 12%, transparent);
273
+ --doitrix-color-fg-disabled: color-mix(in oklch, var(--doitrix-color-fg) 38%, transparent);
274
+ --doitrix-color-overlay: color-mix(in oklch, var(--doitrix-color-scrim) 12%, transparent);
275
+ --doitrix-color-backdrop: color-mix(in oklch, var(--doitrix-color-scrim) 48%, transparent);
276
+ --doitrix-color-shadow-key: color-mix(in oklch, var(--doitrix-color-scrim) 30%, transparent);
277
+ --doitrix-color-shadow-ambient: color-mix(in oklch, var(--doitrix-color-scrim) 15%, transparent);
278
+ --doitrix-shadow-sm: 0 1px 2px 0 var(--doitrix-color-shadow-key), 0 1px 3px 1px var(--doitrix-color-shadow-ambient);
279
+ --doitrix-shadow-md: 0 1px 2px 0 var(--doitrix-color-shadow-key), 0 2px 6px 2px var(--doitrix-color-shadow-ambient);
280
+ --doitrix-shadow-lg: 0 1px 3px 0 var(--doitrix-color-shadow-key), 0 4px 8px 3px var(--doitrix-color-shadow-ambient);
281
+ --doitrix-shadow-xl: 0 4px 4px 0 var(--doitrix-color-shadow-key), 0 8px 12px 6px var(--doitrix-color-shadow-ambient);
282
+ --doitrix-focus-ring: var(--doitrix-focus-ring-width) solid var(--doitrix-color-focus-ring);
283
+ }
284
+
@@ -0,0 +1,4 @@
1
+ /** Relative luminance of an `oklch(L C h)` string, via OKLab → linear sRGB. */
2
+ export declare const luminance: (color: string) => number | null;
3
+ /** WCAG 2 contrast ratio, or null when either colour cannot be parsed. */
4
+ export declare const contrastRatio: (foreground: string, background: string) => number | null;