@eduardoalvarez/arrecife 0.5.1 → 0.7.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/CHANGELOG.md +114 -0
- package/README.md +868 -467
- package/dist/brand/index.cjs +112 -95
- package/dist/brand/index.d.cts +40 -39
- package/dist/brand/index.d.ts +40 -39
- package/dist/brand/index.js +5 -4
- package/dist/catalog-D13txprv.d.cts +78 -0
- package/dist/catalog-D13txprv.d.ts +78 -0
- package/dist/chart/index.cjs +100 -83
- package/dist/chart/index.d.cts +66 -66
- package/dist/chart/index.d.ts +66 -66
- package/dist/chart/index.js +14 -12
- package/dist/chunk-2WPWEIMD.js +27 -0
- package/dist/chunk-45HVCTB7.js +70 -0
- package/dist/{chunk-ZEOQKRQ7.js → chunk-727HCBD4.js} +1 -1
- package/dist/chunk-CKRSQPTX.js +36 -0
- package/dist/chunk-E6KFUSKB.js +144 -0
- package/dist/chunk-GCRII2KQ.js +86 -0
- package/dist/{chunk-YZ2SDOVZ.js → chunk-JN3IS5OS.js} +30 -30
- package/dist/chunk-ODBFN44D.js +45 -0
- package/dist/chunk-OMKSESQB.js +300 -0
- package/dist/{chunk-VPT32GPG.js → chunk-TA7TLWW4.js} +2 -2
- package/dist/chunk-WGNIRIN7.js +42 -0
- package/dist/doctor.mjs +166 -0
- package/dist/form/index.cjs +109 -92
- package/dist/form/index.d.cts +43 -42
- package/dist/form/index.d.ts +43 -42
- package/dist/form/index.js +25 -23
- package/dist/icons/index.cjs +149 -0
- package/dist/icons/index.d.cts +94 -0
- package/dist/icons/index.d.ts +94 -0
- package/dist/icons/index.js +28 -0
- package/dist/index-DlAO2JZs.d.cts +47 -0
- package/dist/index-DlAO2JZs.d.ts +47 -0
- package/dist/index.cjs +1292 -983
- package/dist/index.d.cts +927 -806
- package/dist/index.d.ts +927 -806
- package/dist/index.js +809 -778
- package/dist/{label-DuTvJGxD.d.ts → label-MgHFKnFy.d.cts} +3 -3
- package/dist/{label-DuTvJGxD.d.cts → label-MgHFKnFy.d.ts} +3 -3
- package/dist/og/index.cjs +133 -132
- package/dist/og/index.d.cts +93 -89
- package/dist/og/index.d.ts +93 -89
- package/dist/og/index.js +106 -106
- package/dist/shiki/index.cjs +28 -30
- package/dist/shiki/index.d.cts +4 -4
- package/dist/shiki/index.d.ts +4 -4
- package/dist/shiki/index.js +12 -12
- package/dist/social/index.cjs +67 -0
- package/dist/social/index.d.cts +2 -0
- package/dist/social/index.d.ts +2 -0
- package/dist/social/index.js +2 -0
- package/dist/theme/index.cjs +97 -0
- package/dist/theme/index.d.cts +144 -0
- package/dist/theme/index.d.ts +144 -0
- package/dist/theme/index.js +2 -0
- package/dist/tokens/index.cjs +159 -88
- package/dist/tokens/index.d.cts +277 -165
- package/dist/tokens/index.d.ts +277 -165
- package/dist/tokens/index.js +2 -2
- package/dist/tokens/theme.css +165 -100
- package/dist/variants/index.cjs +195 -0
- package/dist/variants/index.d.cts +195 -0
- package/dist/variants/index.d.ts +195 -0
- package/dist/variants/index.js +3 -0
- package/llms.txt +1145 -746
- package/package.json +42 -11
- package/dist/catalogo-Du5ID-Hi.d.cts +0 -77
- package/dist/catalogo-Du5ID-Hi.d.ts +0 -77
- package/dist/chunk-E3OMP2DL.js +0 -36
- package/dist/chunk-KPZNNMV5.js +0 -83
- package/dist/chunk-NHS7ETKJ.js +0 -27
- package/dist/chunk-TSPJOM6K.js +0 -229
- package/dist/chunk-UOWIDFCB.js +0 -81
- package/dist/tema/index.cjs +0 -94
- package/dist/tema/index.d.cts +0 -110
- package/dist/tema/index.d.ts +0 -110
- package/dist/tema/index.js +0 -2
package/dist/tokens/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { tokens } from '../chunk-
|
|
2
|
-
export { brand, colors, control, dark, fonts, gradient, light, limits, motion, naming, radius, series, shadow,
|
|
1
|
+
export { tokens } from '../chunk-TA7TLWW4.js';
|
|
2
|
+
export { brand, colors, control, dark, fonts, gradient, light, limits, motion, naming, radius, series, shadow, size, spacing, syntax, tagline, typeScale } from '../chunk-OMKSESQB.js';
|
|
3
3
|
import '../chunk-MLKGABMK.js';
|
package/dist/tokens/theme.css
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
/*
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* GENERATED by scripts/build-tokens.mjs from src/tokens/tokens.ts.
|
|
3
|
+
* Do not edit by hand: it is regenerated on every build.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
5
|
+
* Usage in a Tailwind v4 project:
|
|
6
6
|
* @import "tailwindcss";
|
|
7
7
|
* @import "@eduardoalvarez/arrecife/tokens/theme.css";
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
9
|
+
* Dark is the primary mode and the default. A project in light mode
|
|
10
|
+
* declares data-theme="light" on <html>.
|
|
11
11
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
12
|
+
* Font families are declared by name: the project loads Bricolage
|
|
13
|
+
* Grotesque, Geist and JetBrains Mono however it prefers.
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
-
/*
|
|
17
|
-
|
|
16
|
+
/* The mode is chosen with data-theme. Dark is primary, so it is the default:
|
|
17
|
+
a light project declares data-theme="light" on <html>. */
|
|
18
18
|
@custom-variant dark (&:where([data-theme="dark"], [data-theme="dark"] *));
|
|
19
19
|
@custom-variant light (&:where([data-theme="light"], [data-theme="light"] *));
|
|
20
20
|
|
|
21
21
|
@theme {
|
|
22
|
-
/* --- color ·
|
|
22
|
+
/* --- color · dark mode (default) ------------------------------------- */
|
|
23
23
|
--color-background: #091319;
|
|
24
24
|
--color-surface: #10202B;
|
|
25
25
|
--color-surface-raised: #17303E;
|
|
@@ -38,19 +38,22 @@
|
|
|
38
38
|
--color-success: #4FB477;
|
|
39
39
|
--color-warning: #E8A33D;
|
|
40
40
|
--color-error: #E15757;
|
|
41
|
+
--color-danger: #F4736B;
|
|
42
|
+
--color-danger-hover: #F78D86;
|
|
43
|
+
--color-danger-on: #2B0A08;
|
|
41
44
|
|
|
42
|
-
/* ---
|
|
45
|
+
/* --- brand · identical in both modes ----------------------------------- */
|
|
43
46
|
--color-brand-body: #3E7CB1;
|
|
44
47
|
--color-brand-spots: #C2D7E7;
|
|
45
48
|
--color-brand-hull: #0B1524;
|
|
46
49
|
|
|
47
|
-
/* --- series
|
|
48
|
-
--color-
|
|
49
|
-
--color-
|
|
50
|
-
--color-
|
|
51
|
-
--color-
|
|
50
|
+
/* --- chart series · dark mode (default) -------------------------------- */
|
|
51
|
+
--color-series-1: #35D6C0;
|
|
52
|
+
--color-series-2: #F2A65A;
|
|
53
|
+
--color-series-3: #3E7CB1;
|
|
54
|
+
--color-series-4: #71919C;
|
|
52
55
|
|
|
53
|
-
/* ---
|
|
56
|
+
/* --- typography --------------------------------------------------------- */
|
|
54
57
|
--font-display: "Bricolage Grotesque", ui-sans-serif, system-ui, sans-serif;
|
|
55
58
|
--font-sans: "Geist", ui-sans-serif, system-ui, sans-serif;
|
|
56
59
|
--font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
@@ -99,7 +102,7 @@
|
|
|
99
102
|
--text-eyebrow: 12px;
|
|
100
103
|
--text-eyebrow--letter-spacing: 0.12em;
|
|
101
104
|
|
|
102
|
-
/* ---
|
|
105
|
+
/* --- shape and rhythm --------------------------------------------------- */
|
|
103
106
|
--radius-chip: 6px;
|
|
104
107
|
--radius-control: 10px;
|
|
105
108
|
--radius-card: 14px;
|
|
@@ -117,8 +120,12 @@
|
|
|
117
120
|
--spacing-control-md: 22px;
|
|
118
121
|
--spacing-control-lg: 30px;
|
|
119
122
|
--spacing-control-icon: 42px;
|
|
123
|
+
--spacing-control-icon-sm: 32px;
|
|
120
124
|
|
|
121
125
|
--spacing-nav: 64px;
|
|
126
|
+
--spacing-nav-compact: 56px;
|
|
127
|
+
--spacing-sidebar: 256px;
|
|
128
|
+
--spacing-sidebar-rail: 56px;
|
|
122
129
|
--container-content: 760px;
|
|
123
130
|
--container-wide: 1180px;
|
|
124
131
|
--container-measure: 68ch;
|
|
@@ -128,17 +135,17 @@
|
|
|
128
135
|
--duration-standard: 150ms;
|
|
129
136
|
--ease-standard: ease-out;
|
|
130
137
|
|
|
131
|
-
/* ---
|
|
138
|
+
/* --- gradients · dark mode (default) ----------------------------------- */
|
|
132
139
|
--gradient-hero: linear-gradient(160deg, #091319 60%, #0D2129 100%);
|
|
133
|
-
--gradient-
|
|
140
|
+
--gradient-section: linear-gradient(150deg, #10202B 0%, #0D2129 100%);
|
|
134
141
|
--gradient-og: linear-gradient(145deg, #091319 55%, #0D2129 100%);
|
|
135
142
|
}
|
|
136
143
|
|
|
137
|
-
/* --- color
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
144
|
+
/* --- color per mode, nestable ----------------------------------------------
|
|
145
|
+
Both modes are emitted as their own blocks, not just light. That way a subtree
|
|
146
|
+
can declare the opposite mode to the page and everything inside honours it:
|
|
147
|
+
which is what a code block needs, since it sits on hull in both themes and
|
|
148
|
+
therefore always carries light ink on top. */
|
|
142
149
|
[data-theme='dark'] {
|
|
143
150
|
--color-background: #091319;
|
|
144
151
|
--color-surface: #10202B;
|
|
@@ -158,14 +165,17 @@
|
|
|
158
165
|
--color-success: #4FB477;
|
|
159
166
|
--color-warning: #E8A33D;
|
|
160
167
|
--color-error: #E15757;
|
|
168
|
+
--color-danger: #F4736B;
|
|
169
|
+
--color-danger-hover: #F78D86;
|
|
170
|
+
--color-danger-on: #2B0A08;
|
|
161
171
|
|
|
162
|
-
--color-
|
|
163
|
-
--color-
|
|
164
|
-
--color-
|
|
165
|
-
--color-
|
|
172
|
+
--color-series-1: #35D6C0;
|
|
173
|
+
--color-series-2: #F2A65A;
|
|
174
|
+
--color-series-3: #3E7CB1;
|
|
175
|
+
--color-series-4: #71919C;
|
|
166
176
|
|
|
167
177
|
--gradient-hero: linear-gradient(160deg, #091319 60%, #0D2129 100%);
|
|
168
|
-
--gradient-
|
|
178
|
+
--gradient-section: linear-gradient(150deg, #10202B 0%, #0D2129 100%);
|
|
169
179
|
--gradient-og: linear-gradient(145deg, #091319 55%, #0D2129 100%);
|
|
170
180
|
}
|
|
171
181
|
|
|
@@ -188,34 +198,39 @@
|
|
|
188
198
|
--color-success: #0F6B52;
|
|
189
199
|
--color-warning: #8D6111;
|
|
190
200
|
--color-error: #C0392B;
|
|
201
|
+
--color-danger: #C0392B;
|
|
202
|
+
--color-danger-hover: #A32F22;
|
|
203
|
+
--color-danger-on: #FFF6F4;
|
|
191
204
|
|
|
192
|
-
--color-
|
|
193
|
-
--color-
|
|
194
|
-
--color-
|
|
195
|
-
--color-
|
|
205
|
+
--color-series-1: #0D7C6F;
|
|
206
|
+
--color-series-2: #A65B27;
|
|
207
|
+
--color-series-3: #3E7CB1;
|
|
208
|
+
--color-series-4: #626A75;
|
|
196
209
|
|
|
197
|
-
--gradient-hero: linear-gradient(160deg, #F6F2EA 60%, #
|
|
198
|
-
--gradient-
|
|
199
|
-
--gradient-og: linear-gradient(145deg, #F6F2EA 55%, #
|
|
210
|
+
--gradient-hero: linear-gradient(160deg, #F6F2EA 60%, #FFFFFF 100%);
|
|
211
|
+
--gradient-section: linear-gradient(150deg, #FFFFFF 0%, #F6F2EA 100%);
|
|
212
|
+
--gradient-og: linear-gradient(145deg, #F6F2EA 55%, #FFFFFF 100%);
|
|
200
213
|
}
|
|
201
214
|
|
|
202
|
-
/* ---
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
215
|
+
/* --- the system's two gradients, as utilities -------------------------------
|
|
216
|
+
They are the only two blocks with a gradient: the hero and the section panel.
|
|
217
|
+
Making them utilities rather than arbitrary classes is what stops each project
|
|
218
|
+
from writing its own angle. They follow the mode because they read the custom
|
|
219
|
+
property. */
|
|
220
|
+
@utility gradient-hero {
|
|
207
221
|
background-image: var(--gradient-hero);
|
|
208
222
|
}
|
|
209
|
-
@utility
|
|
210
|
-
background-image: var(--gradient-
|
|
223
|
+
@utility gradient-section {
|
|
224
|
+
background-image: var(--gradient-section);
|
|
211
225
|
}
|
|
212
226
|
|
|
213
|
-
/* ---
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
227
|
+
/* --- the third motion exception: the skeleton shimmer -----------------------
|
|
228
|
+
The system does not animate, and this is the third exception, alongside the
|
|
229
|
+
button spinner and the side panel. All of them are feedback about PROGRESS,
|
|
230
|
+
not about state: a block that is still and a block that will never load look
|
|
231
|
+
identical.
|
|
217
232
|
|
|
218
|
-
1.4s
|
|
233
|
+
1.4s linear, from the document. It sits behind motion-safe in the component. */
|
|
219
234
|
@keyframes arrecife-shimmer {
|
|
220
235
|
from { background-position: 200% 0; }
|
|
221
236
|
to { background-position: -200% 0; }
|
|
@@ -232,76 +247,126 @@
|
|
|
232
247
|
animation: arrecife-shimmer 1.4s linear infinite;
|
|
233
248
|
}
|
|
234
249
|
|
|
235
|
-
/* ---
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
250
|
+
/* --- the fifth exception: the caret of the CLI signature --------------------
|
|
251
|
+
A terminal prompt with a caret that does not blink is a terminal that has
|
|
252
|
+
hung. The caret is the one piece of the footer that says the signature is a
|
|
253
|
+
prompt and not a decorative string, and a still block reads as a typo.
|
|
254
|
+
|
|
255
|
+
step-end and not a fade: a real caret is on or off, and easing it turns a
|
|
256
|
+
terminal into a pulsing dot. 1.06s is the cadence of a VT100 and of the site
|
|
257
|
+
this comes from.
|
|
258
|
+
|
|
259
|
+
It is the only exception that is not feedback about progress, and it earns its
|
|
260
|
+
place on the other half of the criterion the other four share: it is not
|
|
261
|
+
decoration, it is what makes the piece legible as what it is. Behind
|
|
262
|
+
motion-safe, where the caret stays solid — which is a caret at rest, not a
|
|
263
|
+
missing one. See docs/decisions.md § 23. */
|
|
264
|
+
@keyframes arrecife-caret {
|
|
265
|
+
0%, 50% { opacity: 1; }
|
|
266
|
+
50.01%, 100% { opacity: 0; }
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
@utility caret {
|
|
270
|
+
animation: arrecife-caret 1.06s step-end infinite;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/* --- the accordion exception -----------------------------------------------
|
|
274
|
+
The fourth one and, like the other three, it is not «it looks better»: a
|
|
275
|
+
disclosure that reveals content with no transition makes everything below it
|
|
276
|
+
JUMP, and whoever just clicked loses their place on the page. It is the same
|
|
277
|
+
category as the side panel — a panel entering from an edge slides by
|
|
278
|
+
definition — and not an entrance animation, which is what the system rejects:
|
|
279
|
+
nothing new appears on screen here, a gap opens.
|
|
280
|
+
|
|
281
|
+
Radix publishes the height as --radix-accordion-content-height. It lasts as
|
|
282
|
+
long as everything else and uses the same curve, so it introduces no new
|
|
283
|
+
timing. In the component it sits behind motion-safe. */
|
|
284
|
+
@keyframes arrecife-expand {
|
|
247
285
|
from { height: 0; }
|
|
248
286
|
to { height: var(--radix-accordion-content-height); }
|
|
249
287
|
}
|
|
250
|
-
@keyframes arrecife-
|
|
288
|
+
@keyframes arrecife-collapse {
|
|
251
289
|
from { height: var(--radix-accordion-content-height); }
|
|
252
290
|
to { height: 0; }
|
|
253
291
|
}
|
|
254
292
|
|
|
255
|
-
@utility
|
|
256
|
-
animation: arrecife-
|
|
293
|
+
@utility expand {
|
|
294
|
+
animation: arrecife-expand var(--duration-standard) var(--ease-standard);
|
|
257
295
|
}
|
|
258
|
-
@utility
|
|
259
|
-
animation: arrecife-
|
|
296
|
+
@utility collapse {
|
|
297
|
+
animation: arrecife-collapse var(--duration-standard) var(--ease-standard);
|
|
260
298
|
}
|
|
261
299
|
|
|
262
|
-
/* ---
|
|
263
|
-
|
|
264
|
-
modal
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
@keyframes arrecife-
|
|
270
|
-
@keyframes arrecife-
|
|
271
|
-
@keyframes arrecife-
|
|
272
|
-
@keyframes arrecife-
|
|
273
|
-
@keyframes arrecife-
|
|
274
|
-
@keyframes arrecife-
|
|
275
|
-
@keyframes arrecife-
|
|
276
|
-
@keyframes arrecife-
|
|
277
|
-
|
|
278
|
-
@utility
|
|
279
|
-
animation: arrecife-
|
|
300
|
+
/* --- the side panel exception ----------------------------------------------
|
|
301
|
+
A panel entering from an edge slides by definition: held still it would be an
|
|
302
|
+
off-centre modal. It is the second exception to "no displacement", and it was
|
|
303
|
+
approved knowingly.
|
|
304
|
+
|
|
305
|
+
It lasts as long as everything else and uses the same curve, so it introduces
|
|
306
|
+
no new timing. In the component it sits behind motion-safe. */
|
|
307
|
+
@keyframes arrecife-slide-in-right { from { translate: 100% 0; } }
|
|
308
|
+
@keyframes arrecife-slide-out-right { to { translate: 100% 0; } }
|
|
309
|
+
@keyframes arrecife-slide-in-left { from { translate: -100% 0; } }
|
|
310
|
+
@keyframes arrecife-slide-out-left { to { translate: -100% 0; } }
|
|
311
|
+
@keyframes arrecife-slide-in-top { from { translate: 0 -100%; } }
|
|
312
|
+
@keyframes arrecife-slide-out-top { to { translate: 0 -100%; } }
|
|
313
|
+
@keyframes arrecife-slide-in-bottom { from { translate: 0 100%; } }
|
|
314
|
+
@keyframes arrecife-slide-out-bottom { to { translate: 0 100%; } }
|
|
315
|
+
|
|
316
|
+
@utility slide-in-right {
|
|
317
|
+
animation: arrecife-slide-in-right var(--duration-standard) var(--ease-standard);
|
|
318
|
+
}
|
|
319
|
+
@utility slide-out-right {
|
|
320
|
+
animation: arrecife-slide-out-right var(--duration-standard) var(--ease-standard);
|
|
321
|
+
}
|
|
322
|
+
@utility slide-in-left {
|
|
323
|
+
animation: arrecife-slide-in-left var(--duration-standard) var(--ease-standard);
|
|
280
324
|
}
|
|
281
|
-
@utility
|
|
282
|
-
animation: arrecife-
|
|
325
|
+
@utility slide-out-left {
|
|
326
|
+
animation: arrecife-slide-out-left var(--duration-standard) var(--ease-standard);
|
|
283
327
|
}
|
|
284
|
-
@utility
|
|
285
|
-
animation: arrecife-
|
|
328
|
+
@utility slide-in-top {
|
|
329
|
+
animation: arrecife-slide-in-top var(--duration-standard) var(--ease-standard);
|
|
286
330
|
}
|
|
287
|
-
@utility
|
|
288
|
-
animation: arrecife-
|
|
331
|
+
@utility slide-out-top {
|
|
332
|
+
animation: arrecife-slide-out-top var(--duration-standard) var(--ease-standard);
|
|
289
333
|
}
|
|
290
|
-
@utility
|
|
291
|
-
animation: arrecife-
|
|
334
|
+
@utility slide-in-bottom {
|
|
335
|
+
animation: arrecife-slide-in-bottom var(--duration-standard) var(--ease-standard);
|
|
292
336
|
}
|
|
293
|
-
@utility
|
|
294
|
-
animation: arrecife-
|
|
337
|
+
@utility slide-out-bottom {
|
|
338
|
+
animation: arrecife-slide-out-bottom var(--duration-standard) var(--ease-standard);
|
|
295
339
|
}
|
|
296
|
-
|
|
297
|
-
|
|
340
|
+
|
|
341
|
+
/* --- the focus ring ---------------------------------------------------------
|
|
342
|
+
The document gives it once, on the primary button: «focus ring 2px #35D6C0 +
|
|
343
|
+
offset 3px». The code had it as three classes copied to twenty-nine call
|
|
344
|
+
sites in twenty-four files, all of them at offset 2, and three audits in a row
|
|
345
|
+
said so — the value was never argued down to 2, it was copied from the first
|
|
346
|
+
component and inherited by the next twenty-eight.
|
|
347
|
+
|
|
348
|
+
It is one utility for the reason § 15 gives: a list kept in sync by hand with
|
|
349
|
+
another list ends up out of sync. Twenty-nine copies is twenty-nine chances to
|
|
350
|
+
write the next one at offset 2 again, and nothing was checking.
|
|
351
|
+
|
|
352
|
+
focus-ring-warm exists for the ONE control the ring cannot be biolume on:
|
|
353
|
+
the conversion button is the system's only sand fill, and a biolume ring
|
|
354
|
+
around it puts both of the brand's accents in the same three pixels. It sets
|
|
355
|
+
only the color, so the width and the offset stay in one place. */
|
|
356
|
+
@utility focus-ring {
|
|
357
|
+
&:focus-visible {
|
|
358
|
+
outline: 2px solid var(--color-accent);
|
|
359
|
+
outline-offset: 3px;
|
|
360
|
+
}
|
|
298
361
|
}
|
|
299
|
-
@utility
|
|
300
|
-
|
|
362
|
+
@utility focus-ring-warm {
|
|
363
|
+
&:focus-visible {
|
|
364
|
+
outline-color: var(--color-warm);
|
|
365
|
+
}
|
|
301
366
|
}
|
|
302
367
|
|
|
303
|
-
/*
|
|
304
|
-
|
|
368
|
+
/* The system's only transition, as a utility. States are communicated with
|
|
369
|
+
border and color, not with movement: this class cannot animate anything else. */
|
|
305
370
|
@utility transition-standard {
|
|
306
371
|
transition-property: color, background-color, border-color, fill, stroke;
|
|
307
372
|
transition-duration: var(--duration-standard);
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var classVarianceAuthority = require('class-variance-authority');
|
|
4
|
+
|
|
5
|
+
// src/variants/button.ts
|
|
6
|
+
var button = classVarianceAuthority.cva(
|
|
7
|
+
[
|
|
8
|
+
"inline-flex cursor-pointer items-center justify-center gap-step-xs whitespace-nowrap select-none",
|
|
9
|
+
"rounded-control font-sans font-medium",
|
|
10
|
+
"transition-standard",
|
|
11
|
+
"focus-ring",
|
|
12
|
+
"disabled:pointer-events-none disabled:opacity-50",
|
|
13
|
+
"[&_svg]:shrink-0"
|
|
14
|
+
],
|
|
15
|
+
{
|
|
16
|
+
variants: {
|
|
17
|
+
variant: {
|
|
18
|
+
primary: [
|
|
19
|
+
"bg-accent text-accent-on hover:bg-accent-hover",
|
|
20
|
+
"light:bg-brand-hull light:text-accent-on light:hover:bg-text-secondary"
|
|
21
|
+
],
|
|
22
|
+
// The one control whose focus ring is not biolume. It is the system's
|
|
23
|
+
// only sand fill, and a biolume ring three pixels off a sand button puts
|
|
24
|
+
// both of the brand's accents in the same glance. See `decisions.md` § 37.
|
|
25
|
+
conversion: "bg-warm text-warm-on hover:bg-warm-hover focus-ring-warm",
|
|
26
|
+
secondary: [
|
|
27
|
+
"border-hairline-hover border bg-transparent text-text-primary",
|
|
28
|
+
"hover:border-accent hover:text-accent"
|
|
29
|
+
],
|
|
30
|
+
tertiary: [
|
|
31
|
+
"bg-transparent font-mono font-normal text-text-secondary",
|
|
32
|
+
"hover:text-accent hover:underline hover:underline-offset-4"
|
|
33
|
+
],
|
|
34
|
+
/** Irreversible only. Never for «cancel» on a form. */
|
|
35
|
+
destructive: "bg-danger text-danger-on hover:bg-danger-hover",
|
|
36
|
+
destructiveOutline: [
|
|
37
|
+
"border-danger text-danger border bg-transparent",
|
|
38
|
+
"hover:bg-danger hover:text-danger-on"
|
|
39
|
+
]
|
|
40
|
+
},
|
|
41
|
+
size: {
|
|
42
|
+
sm: "h-8 px-control-sm text-label",
|
|
43
|
+
md: "h-10 px-control-md text-ui",
|
|
44
|
+
lg: "h-12 px-control-lg text-lead",
|
|
45
|
+
/** A 42×42 square, no text. `aria-label` is mandatory on it. */
|
|
46
|
+
icon: "size-control-icon p-0",
|
|
47
|
+
/** 32×32, for a table row. Same height as `sm`, and same mandatory `aria-label`. */
|
|
48
|
+
"icon-sm": "size-control-icon-sm p-0"
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
compoundVariants: [
|
|
52
|
+
/**
|
|
53
|
+
* The tertiary has no box: neither horizontal padding nor control height.
|
|
54
|
+
* It goes here rather than as `px-0` on the variant so it beats the size's
|
|
55
|
+
* `px-*` without depending on the order cva concatenates classes in.
|
|
56
|
+
*/
|
|
57
|
+
{ variant: "tertiary", size: ["sm", "md", "lg"], class: "h-auto px-0" }
|
|
58
|
+
],
|
|
59
|
+
defaultVariants: { variant: "primary", size: "md" }
|
|
60
|
+
}
|
|
61
|
+
);
|
|
62
|
+
var badge = classVarianceAuthority.cva(
|
|
63
|
+
["inline-flex items-center gap-step-xs", "rounded-chip px-step-xs py-0.5", "font-sans text-tag", "transition-standard"],
|
|
64
|
+
{
|
|
65
|
+
variants: {
|
|
66
|
+
variant: {
|
|
67
|
+
neutral: "bg-surface-raised text-text-secondary",
|
|
68
|
+
accent: "bg-accent/8 text-text-primary",
|
|
69
|
+
warm: "bg-warm/8 text-text-primary",
|
|
70
|
+
success: "bg-success/8 text-text-primary",
|
|
71
|
+
warning: "bg-warning/8 text-text-primary",
|
|
72
|
+
error: "bg-error/8 text-text-primary"
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
defaultVariants: { variant: "neutral" }
|
|
76
|
+
}
|
|
77
|
+
);
|
|
78
|
+
var category = classVarianceAuthority.cva(
|
|
79
|
+
[
|
|
80
|
+
"inline-flex items-center gap-step-xs",
|
|
81
|
+
"rounded-pill px-step-sm py-0.5",
|
|
82
|
+
"font-mono text-chip",
|
|
83
|
+
"border transition-standard"
|
|
84
|
+
],
|
|
85
|
+
{
|
|
86
|
+
variants: {
|
|
87
|
+
active: {
|
|
88
|
+
false: "border-warm/28 bg-transparent text-warm",
|
|
89
|
+
true: "border-warm bg-warm text-warm-on"
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
defaultVariants: { active: false }
|
|
93
|
+
}
|
|
94
|
+
);
|
|
95
|
+
var metric = ["inline-flex items-center gap-step-xs", "rounded-pill", "font-mono text-chip text-text-muted"];
|
|
96
|
+
var text = classVarianceAuthority.cva("", {
|
|
97
|
+
variants: {
|
|
98
|
+
variant: {
|
|
99
|
+
display: "text-display font-display",
|
|
100
|
+
// Large metrics: 46px of display. It is the only scale designed for a
|
|
101
|
+
// number, which is why its line height is 1.
|
|
102
|
+
stat: "text-stat font-display",
|
|
103
|
+
h1: "text-h1 font-display",
|
|
104
|
+
h2: "text-h2 font-display",
|
|
105
|
+
h3: "text-h3 font-display",
|
|
106
|
+
body: "text-body font-sans",
|
|
107
|
+
// 17px: the deck on interior pages and the large button.
|
|
108
|
+
lead: "text-lead font-sans",
|
|
109
|
+
ui: "text-ui font-sans",
|
|
110
|
+
label: "text-label font-sans",
|
|
111
|
+
// The two badge scales. `tag` is status (sans 12.5/500) and `chip` is
|
|
112
|
+
// category and metric (mono 11.5). Neither transforms the text.
|
|
113
|
+
tag: "text-tag font-sans",
|
|
114
|
+
chip: "text-chip font-mono",
|
|
115
|
+
// Mono with NO transform: dates, paths, versions, file names and the
|
|
116
|
+
// footer signature. It is the step that was missing, and the reason every
|
|
117
|
+
// call site ended up writing `variant="eyebrow" className="normal-case"`.
|
|
118
|
+
meta: "text-meta font-mono",
|
|
119
|
+
// `uppercase` does not fit in a size token: text-transform is not a
|
|
120
|
+
// modifier of --text-*. Which is why the variant sets it, not theme.css.
|
|
121
|
+
eyebrow: "text-eyebrow font-mono uppercase"
|
|
122
|
+
},
|
|
123
|
+
tone: {
|
|
124
|
+
primary: "text-text-primary",
|
|
125
|
+
secondary: "text-text-secondary",
|
|
126
|
+
muted: "text-text-muted",
|
|
127
|
+
accent: "text-accent",
|
|
128
|
+
warm: "text-warm",
|
|
129
|
+
success: "text-success",
|
|
130
|
+
warning: "text-warning",
|
|
131
|
+
error: "text-error"
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
defaultVariants: { variant: "body", tone: "primary" }
|
|
135
|
+
});
|
|
136
|
+
var alert = classVarianceAuthority.cva("w-full rounded-card border p-step-md font-sans text-ui", {
|
|
137
|
+
variants: {
|
|
138
|
+
variant: {
|
|
139
|
+
accent: "text-text-secondary",
|
|
140
|
+
success: "text-text-secondary",
|
|
141
|
+
warning: "text-text-secondary",
|
|
142
|
+
error: "text-text-secondary"
|
|
143
|
+
},
|
|
144
|
+
emphasis: {
|
|
145
|
+
subtle: "",
|
|
146
|
+
strong: ""
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
compoundVariants: [
|
|
150
|
+
{ variant: "accent", emphasis: "subtle", class: "border-accent/22 bg-accent/8" },
|
|
151
|
+
{ variant: "success", emphasis: "subtle", class: "border-success/22 bg-success/8" },
|
|
152
|
+
{ variant: "warning", emphasis: "subtle", class: "border-warning/22 bg-warning/8" },
|
|
153
|
+
{ variant: "error", emphasis: "subtle", class: "border-error/22 bg-error/8" },
|
|
154
|
+
{ variant: "accent", emphasis: "strong", class: "border-accent bg-accent/10" },
|
|
155
|
+
{ variant: "success", emphasis: "strong", class: "border-success bg-success/10" },
|
|
156
|
+
{ variant: "warning", emphasis: "strong", class: "border-warning bg-warning/10" },
|
|
157
|
+
{ variant: "error", emphasis: "strong", class: "border-error bg-error/10" }
|
|
158
|
+
],
|
|
159
|
+
defaultVariants: { variant: "accent", emphasis: "subtle" }
|
|
160
|
+
});
|
|
161
|
+
var avatar = classVarianceAuthority.cva(
|
|
162
|
+
"relative flex shrink-0 overflow-hidden rounded-pill bg-surface-raised border border-hairline",
|
|
163
|
+
{
|
|
164
|
+
variants: {
|
|
165
|
+
size: {
|
|
166
|
+
sm: "size-8",
|
|
167
|
+
md: "size-10",
|
|
168
|
+
lg: "size-14",
|
|
169
|
+
xl: "size-24"
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
defaultVariants: { size: "md" }
|
|
173
|
+
}
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
// src/variants/card.ts
|
|
177
|
+
var CARD_SURFACE = "rounded-card border-hairline bg-surface border";
|
|
178
|
+
var CARD_HOVER = "transition-standard hover:border-hairline-hover";
|
|
179
|
+
var CARD = [
|
|
180
|
+
"group block cursor-pointer",
|
|
181
|
+
CARD_SURFACE,
|
|
182
|
+
CARD_HOVER,
|
|
183
|
+
"focus-ring"
|
|
184
|
+
];
|
|
185
|
+
|
|
186
|
+
exports.CARD = CARD;
|
|
187
|
+
exports.CARD_HOVER = CARD_HOVER;
|
|
188
|
+
exports.CARD_SURFACE = CARD_SURFACE;
|
|
189
|
+
exports.alertVariants = alert;
|
|
190
|
+
exports.avatarVariants = avatar;
|
|
191
|
+
exports.badgeVariants = badge;
|
|
192
|
+
exports.buttonVariants = button;
|
|
193
|
+
exports.categoryBadgeVariants = category;
|
|
194
|
+
exports.metricBadgeVariants = metric;
|
|
195
|
+
exports.textVariants = text;
|