twico-ui 0.1.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 +182 -0
- package/dist/index.cjs +7675 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1501 -0
- package/dist/index.d.ts +1501 -0
- package/dist/index.mjs +7617 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +71 -0
- package/styles/fonts/JetBrainsMono-Variable.ttf +0 -0
- package/styles/fonts/OFL-PlusJakartaSans.txt +93 -0
- package/styles/fonts/PlusJakartaSans-Italic-Variable.ttf +0 -0
- package/styles/fonts/PlusJakartaSans-Variable.ttf +0 -0
- package/styles/twico-ui.css +546 -0
|
@@ -0,0 +1,546 @@
|
|
|
1
|
+
/* ============================================================
|
|
2
|
+
twico-ui — bundled stylesheet (design tokens + base reset + webfonts)
|
|
3
|
+
Import ONCE at your app root: import "twico-ui/styles.css";
|
|
4
|
+
Dark mode: add class="dark" (or data-theme="dark") to <html>.
|
|
5
|
+
Fonts ship beside this file in ./fonts/ (self-hosted, OFL).
|
|
6
|
+
============================================================ */
|
|
7
|
+
|
|
8
|
+
/* ===== tokens/fonts.css ===== */
|
|
9
|
+
/* ============================================================
|
|
10
|
+
Twico UI — Webfonts (self-hosted, OFL licensed)
|
|
11
|
+
Plus Jakarta Sans (UI) + JetBrains Mono (code).
|
|
12
|
+
Variable fonts: one file covers weights 200–800.
|
|
13
|
+
============================================================ */
|
|
14
|
+
|
|
15
|
+
@font-face {
|
|
16
|
+
font-family: "Plus Jakarta Sans";
|
|
17
|
+
src: url("./fonts/PlusJakartaSans-Variable.ttf") format("truetype-variations");
|
|
18
|
+
font-weight: 200 800;
|
|
19
|
+
font-style: normal;
|
|
20
|
+
font-display: swap;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
@font-face {
|
|
24
|
+
font-family: "Plus Jakarta Sans";
|
|
25
|
+
src: url("./fonts/PlusJakartaSans-Italic-Variable.ttf") format("truetype-variations");
|
|
26
|
+
font-weight: 200 800;
|
|
27
|
+
font-style: italic;
|
|
28
|
+
font-display: swap;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@font-face {
|
|
32
|
+
font-family: "JetBrains Mono";
|
|
33
|
+
src: url("./fonts/JetBrainsMono-Variable.ttf") format("truetype-variations");
|
|
34
|
+
font-weight: 100 800;
|
|
35
|
+
font-style: normal;
|
|
36
|
+
font-display: swap;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/* ===== tokens/colors.css ===== */
|
|
40
|
+
/* ============================================================
|
|
41
|
+
Twico UI — Color tokens
|
|
42
|
+
Primitive palettes (raw scales) + semantic aliases.
|
|
43
|
+
Semantic aliases flip under .dark / [data-theme="dark"].
|
|
44
|
+
Re-theme by overriding the --brand-* scale or the --color-* aliases.
|
|
45
|
+
============================================================ */
|
|
46
|
+
|
|
47
|
+
:root {
|
|
48
|
+
/* ---- Primitive: Indigo (brand) ---- */
|
|
49
|
+
--indigo-50: #eef2ff;
|
|
50
|
+
--indigo-100: #e0e7ff;
|
|
51
|
+
--indigo-200: #c7d2fe;
|
|
52
|
+
--indigo-300: #a5b4fc;
|
|
53
|
+
--indigo-400: #818cf8;
|
|
54
|
+
--indigo-500: #6366f1;
|
|
55
|
+
--indigo-600: #4f46e5;
|
|
56
|
+
--indigo-700: #4338ca;
|
|
57
|
+
--indigo-800: #3730a3;
|
|
58
|
+
--indigo-900: #312e81;
|
|
59
|
+
--indigo-950: #1e1b4b;
|
|
60
|
+
|
|
61
|
+
/* Brand alias — remap these to re-skin the whole library */
|
|
62
|
+
--brand-50: var(--indigo-50);
|
|
63
|
+
--brand-100: var(--indigo-100);
|
|
64
|
+
--brand-200: var(--indigo-200);
|
|
65
|
+
--brand-300: var(--indigo-300);
|
|
66
|
+
--brand-400: var(--indigo-400);
|
|
67
|
+
--brand-500: var(--indigo-500);
|
|
68
|
+
--brand-600: var(--indigo-600);
|
|
69
|
+
--brand-700: var(--indigo-700);
|
|
70
|
+
--brand-800: var(--indigo-800);
|
|
71
|
+
--brand-900: var(--indigo-900);
|
|
72
|
+
--brand-950: var(--indigo-950);
|
|
73
|
+
|
|
74
|
+
/* ---- Primitive: Slate (neutral) ---- */
|
|
75
|
+
--slate-50: #f8fafc;
|
|
76
|
+
--slate-100: #f1f5f9;
|
|
77
|
+
--slate-200: #e2e8f0;
|
|
78
|
+
--slate-300: #cbd5e1;
|
|
79
|
+
--slate-400: #94a3b8;
|
|
80
|
+
--slate-500: #64748b;
|
|
81
|
+
--slate-600: #475569;
|
|
82
|
+
--slate-700: #334155;
|
|
83
|
+
--slate-800: #1e293b;
|
|
84
|
+
--slate-900: #0f172a;
|
|
85
|
+
--slate-950: #020617;
|
|
86
|
+
|
|
87
|
+
/* ---- Primitive: Semantic hues ---- */
|
|
88
|
+
--emerald-400: #34d399;
|
|
89
|
+
--emerald-500: #10b981;
|
|
90
|
+
--emerald-600: #059669;
|
|
91
|
+
--emerald-50: #ecfdf5;
|
|
92
|
+
|
|
93
|
+
--amber-400: #fbbf24;
|
|
94
|
+
--amber-500: #f59e0b;
|
|
95
|
+
--amber-600: #d97706;
|
|
96
|
+
--amber-50: #fffbeb;
|
|
97
|
+
|
|
98
|
+
--rose-400: #fb7185;
|
|
99
|
+
--rose-500: #f43f5e;
|
|
100
|
+
--rose-600: #e11d48;
|
|
101
|
+
--rose-50: #fff1f2;
|
|
102
|
+
|
|
103
|
+
--sky-400: #38bdf8;
|
|
104
|
+
--sky-500: #0ea5e9;
|
|
105
|
+
--sky-600: #0284c7;
|
|
106
|
+
--sky-50: #f0f9ff;
|
|
107
|
+
|
|
108
|
+
/* ============================================================
|
|
109
|
+
SEMANTIC ALIASES — LIGHT (default)
|
|
110
|
+
============================================================ */
|
|
111
|
+
|
|
112
|
+
/* Surfaces & backgrounds */
|
|
113
|
+
--color-bg: var(--slate-50); /* app/page background */
|
|
114
|
+
--color-surface: #ffffff; /* cards, panels, sheets */
|
|
115
|
+
--color-surface-raised: #ffffff; /* menus, popovers (with shadow) */
|
|
116
|
+
--color-surface-sunken: var(--slate-100); /* wells, inset areas */
|
|
117
|
+
--color-overlay: rgb(15 23 42 / 0.45); /* modal scrim */
|
|
118
|
+
|
|
119
|
+
/* Borders & dividers */
|
|
120
|
+
--color-border: var(--slate-200);
|
|
121
|
+
--color-border-strong: var(--slate-300);
|
|
122
|
+
--color-divider: var(--slate-200);
|
|
123
|
+
|
|
124
|
+
/* Text */
|
|
125
|
+
--color-text: var(--slate-900);
|
|
126
|
+
--color-text-muted: var(--slate-600);
|
|
127
|
+
--color-text-subtle: var(--slate-400);
|
|
128
|
+
--color-text-inverted: #ffffff;
|
|
129
|
+
|
|
130
|
+
/* Primary / brand */
|
|
131
|
+
--color-primary: var(--brand-500);
|
|
132
|
+
--color-primary-hover: var(--brand-600);
|
|
133
|
+
--color-primary-active: var(--brand-700);
|
|
134
|
+
--color-primary-fg: #ffffff;
|
|
135
|
+
--color-primary-subtle: var(--brand-50);
|
|
136
|
+
--color-primary-subtle-fg: var(--brand-700);
|
|
137
|
+
--color-primary-border: var(--brand-200);
|
|
138
|
+
|
|
139
|
+
/* Focus ring */
|
|
140
|
+
--color-ring: rgb(99 102 241 / 0.45);
|
|
141
|
+
|
|
142
|
+
/* Success */
|
|
143
|
+
--color-success: var(--emerald-600);
|
|
144
|
+
--color-success-fg: #ffffff;
|
|
145
|
+
--color-success-subtle: var(--emerald-50);
|
|
146
|
+
--color-success-subtle-fg: var(--emerald-600);
|
|
147
|
+
|
|
148
|
+
/* Warning */
|
|
149
|
+
--color-warning: var(--amber-500);
|
|
150
|
+
--color-warning-fg: #ffffff;
|
|
151
|
+
--color-warning-subtle: var(--amber-50);
|
|
152
|
+
--color-warning-subtle-fg: var(--amber-600);
|
|
153
|
+
|
|
154
|
+
/* Danger */
|
|
155
|
+
--color-danger: var(--rose-500);
|
|
156
|
+
--color-danger-hover: var(--rose-600);
|
|
157
|
+
--color-danger-fg: #ffffff;
|
|
158
|
+
--color-danger-subtle: var(--rose-50);
|
|
159
|
+
--color-danger-subtle-fg: var(--rose-600);
|
|
160
|
+
|
|
161
|
+
/* Info */
|
|
162
|
+
--color-info: var(--sky-500);
|
|
163
|
+
--color-info-fg: #ffffff;
|
|
164
|
+
--color-info-subtle: var(--sky-50);
|
|
165
|
+
--color-info-subtle-fg: var(--sky-600);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/* ============================================================
|
|
169
|
+
SEMANTIC ALIASES — DARK
|
|
170
|
+
Toggle by adding class="dark" or data-theme="dark" to <html>.
|
|
171
|
+
============================================================ */
|
|
172
|
+
|
|
173
|
+
.dark,
|
|
174
|
+
[data-theme="dark"] {
|
|
175
|
+
--color-bg: var(--slate-950);
|
|
176
|
+
--color-surface: var(--slate-900);
|
|
177
|
+
--color-surface-raised: var(--slate-800);
|
|
178
|
+
--color-surface-sunken: #0b1222;
|
|
179
|
+
--color-overlay: rgb(2 6 23 / 0.65);
|
|
180
|
+
|
|
181
|
+
--color-border: #25324a;
|
|
182
|
+
--color-border-strong: var(--slate-700);
|
|
183
|
+
--color-divider: #1c2840;
|
|
184
|
+
|
|
185
|
+
--color-text: var(--slate-50);
|
|
186
|
+
--color-text-muted: var(--slate-300);
|
|
187
|
+
--color-text-subtle: var(--slate-500);
|
|
188
|
+
--color-text-inverted: var(--slate-900);
|
|
189
|
+
|
|
190
|
+
--color-primary: var(--brand-500);
|
|
191
|
+
--color-primary-hover: var(--brand-400);
|
|
192
|
+
--color-primary-active: var(--brand-300);
|
|
193
|
+
--color-primary-fg: #ffffff;
|
|
194
|
+
--color-primary-subtle: rgb(99 102 241 / 0.16);
|
|
195
|
+
--color-primary-subtle-fg: var(--brand-300);
|
|
196
|
+
--color-primary-border: rgb(99 102 241 / 0.35);
|
|
197
|
+
|
|
198
|
+
--color-ring: rgb(129 140 248 / 0.55);
|
|
199
|
+
|
|
200
|
+
--color-success: var(--emerald-500);
|
|
201
|
+
--color-success-fg: #052e1d;
|
|
202
|
+
--color-success-subtle: rgb(16 185 129 / 0.15);
|
|
203
|
+
--color-success-subtle-fg: var(--emerald-400);
|
|
204
|
+
|
|
205
|
+
--color-warning: var(--amber-500);
|
|
206
|
+
--color-warning-fg: #2c1701;
|
|
207
|
+
--color-warning-subtle: rgb(245 158 11 / 0.15);
|
|
208
|
+
--color-warning-subtle-fg: var(--amber-400);
|
|
209
|
+
|
|
210
|
+
--color-danger: var(--rose-500);
|
|
211
|
+
--color-danger-hover: var(--rose-400);
|
|
212
|
+
--color-danger-fg: #2c0610;
|
|
213
|
+
--color-danger-subtle: rgb(244 63 94 / 0.15);
|
|
214
|
+
--color-danger-subtle-fg: var(--rose-400);
|
|
215
|
+
|
|
216
|
+
--color-info: var(--sky-500);
|
|
217
|
+
--color-info-fg: #04212f;
|
|
218
|
+
--color-info-subtle: rgb(14 165 233 / 0.15);
|
|
219
|
+
--color-info-subtle-fg: var(--sky-400);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/* ===== tokens/typography.css ===== */
|
|
223
|
+
/* ============================================================
|
|
224
|
+
Twico UI — Typography tokens
|
|
225
|
+
Family: Plus Jakarta Sans (UI) · JetBrains Mono (code)
|
|
226
|
+
============================================================ */
|
|
227
|
+
|
|
228
|
+
:root {
|
|
229
|
+
/* Families */
|
|
230
|
+
--font-sans: "Plus Jakarta Sans", ui-sans-serif, system-ui, -apple-system,
|
|
231
|
+
"Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
|
232
|
+
--font-mono: "JetBrains Mono", ui-monospace, "SF Mono", "Cascadia Code",
|
|
233
|
+
Menlo, Consolas, monospace;
|
|
234
|
+
|
|
235
|
+
/* Type scale (rem, 16px root) */
|
|
236
|
+
--text-xs: 0.75rem; /* 12 */
|
|
237
|
+
--text-sm: 0.875rem; /* 14 */
|
|
238
|
+
--text-base: 1rem; /* 16 */
|
|
239
|
+
--text-lg: 1.125rem; /* 18 */
|
|
240
|
+
--text-xl: 1.25rem; /* 20 */
|
|
241
|
+
--text-2xl: 1.5rem; /* 24 */
|
|
242
|
+
--text-3xl: 1.875rem; /* 30 */
|
|
243
|
+
--text-4xl: 2.25rem; /* 36 */
|
|
244
|
+
--text-5xl: 3rem; /* 48 */
|
|
245
|
+
--text-6xl: 3.75rem; /* 60 */
|
|
246
|
+
--text-7xl: 4.5rem; /* 72 */
|
|
247
|
+
|
|
248
|
+
/* Weights */
|
|
249
|
+
--font-normal: 400;
|
|
250
|
+
--font-medium: 500;
|
|
251
|
+
--font-semibold: 600;
|
|
252
|
+
--font-bold: 700;
|
|
253
|
+
--font-extrabold: 800;
|
|
254
|
+
|
|
255
|
+
/* Line heights */
|
|
256
|
+
--leading-none: 1;
|
|
257
|
+
--leading-tight: 1.2;
|
|
258
|
+
--leading-snug: 1.35;
|
|
259
|
+
--leading-normal: 1.5;
|
|
260
|
+
--leading-relaxed: 1.65;
|
|
261
|
+
|
|
262
|
+
/* Letter spacing */
|
|
263
|
+
--tracking-tighter: -0.03em; /* display headings */
|
|
264
|
+
--tracking-tight: -0.015em; /* headings */
|
|
265
|
+
--tracking-normal: 0em;
|
|
266
|
+
--tracking-wide: 0.02em;
|
|
267
|
+
--tracking-wider: 0.06em; /* eyebrows / labels (uppercase) */
|
|
268
|
+
|
|
269
|
+
/* Semantic role tokens */
|
|
270
|
+
--text-display: var(--text-6xl);
|
|
271
|
+
--text-h1: var(--text-4xl);
|
|
272
|
+
--text-h2: var(--text-3xl);
|
|
273
|
+
--text-h3: var(--text-2xl);
|
|
274
|
+
--text-h4: var(--text-xl);
|
|
275
|
+
--text-body: var(--text-base);
|
|
276
|
+
--text-body-sm: var(--text-sm);
|
|
277
|
+
--text-caption: var(--text-xs);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/* ===== tokens/spacing.css ===== */
|
|
281
|
+
/* ============================================================
|
|
282
|
+
Twico UI — Spacing & sizing tokens
|
|
283
|
+
4px base grid.
|
|
284
|
+
============================================================ */
|
|
285
|
+
|
|
286
|
+
:root {
|
|
287
|
+
--space-0: 0;
|
|
288
|
+
--space-px: 1px;
|
|
289
|
+
--space-0-5: 0.125rem; /* 2 */
|
|
290
|
+
--space-1: 0.25rem; /* 4 */
|
|
291
|
+
--space-1-5: 0.375rem; /* 6 */
|
|
292
|
+
--space-2: 0.5rem; /* 8 */
|
|
293
|
+
--space-2-5: 0.625rem; /* 10 */
|
|
294
|
+
--space-3: 0.75rem; /* 12 */
|
|
295
|
+
--space-4: 1rem; /* 16 */
|
|
296
|
+
--space-5: 1.25rem; /* 20 */
|
|
297
|
+
--space-6: 1.5rem; /* 24 */
|
|
298
|
+
--space-7: 1.75rem; /* 28 */
|
|
299
|
+
--space-8: 2rem; /* 32 */
|
|
300
|
+
--space-10: 2.5rem; /* 40 */
|
|
301
|
+
--space-12: 3rem; /* 48 */
|
|
302
|
+
--space-16: 4rem; /* 64 */
|
|
303
|
+
--space-20: 5rem; /* 80 */
|
|
304
|
+
--space-24: 6rem; /* 96 */
|
|
305
|
+
--space-32: 8rem; /* 128 */
|
|
306
|
+
|
|
307
|
+
/* Control heights (consistent across buttons / inputs / selects) */
|
|
308
|
+
--control-h-sm: 2rem; /* 32 */
|
|
309
|
+
--control-h-md: 2.5rem; /* 40 */
|
|
310
|
+
--control-h-lg: 3rem; /* 48 */
|
|
311
|
+
|
|
312
|
+
/* Layout */
|
|
313
|
+
--container-sm: 640px;
|
|
314
|
+
--container-md: 768px;
|
|
315
|
+
--container-lg: 1024px;
|
|
316
|
+
--container-xl: 1280px;
|
|
317
|
+
--container-2xl: 1440px;
|
|
318
|
+
|
|
319
|
+
/* Z-index scale */
|
|
320
|
+
--z-base: 0; /* @kind other */
|
|
321
|
+
--z-dropdown: 1000; /* @kind other */
|
|
322
|
+
--z-sticky: 1100; /* @kind other */
|
|
323
|
+
--z-overlay: 1200; /* @kind other */
|
|
324
|
+
--z-modal: 1300; /* @kind other */
|
|
325
|
+
--z-popover: 1400; /* @kind other */
|
|
326
|
+
--z-toast: 1500; /* @kind other */
|
|
327
|
+
--z-tooltip: 1600; /* @kind other */
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/* ===== tokens/radius.css ===== */
|
|
331
|
+
/* ============================================================
|
|
332
|
+
Twico UI — Radius, borders & elevation
|
|
333
|
+
No pointy corners — everything rounds.
|
|
334
|
+
============================================================ */
|
|
335
|
+
|
|
336
|
+
:root {
|
|
337
|
+
/* Corner radii — base control radius is --radius-md (10px) */
|
|
338
|
+
--radius-xs: 4px;
|
|
339
|
+
--radius-sm: 6px;
|
|
340
|
+
--radius-md: 10px; /* buttons, inputs, selects, badges */
|
|
341
|
+
--radius-lg: 14px; /* cards, popovers, menus */
|
|
342
|
+
--radius-xl: 18px; /* large cards, sheets */
|
|
343
|
+
--radius-2xl: 24px; /* hero panels, modals */
|
|
344
|
+
--radius-full: 9999px; /* pills, avatars, switches */
|
|
345
|
+
|
|
346
|
+
/* Border widths */
|
|
347
|
+
--border-thin: 1px;
|
|
348
|
+
--border-medium: 1.5px;
|
|
349
|
+
--border-thick: 2px;
|
|
350
|
+
|
|
351
|
+
/* Elevation — soft, slate-tinted, crisp (light) */
|
|
352
|
+
--shadow-xs: 0 1px 2px 0 rgb(15 23 42 / 0.05);
|
|
353
|
+
--shadow-sm: 0 1px 3px 0 rgb(15 23 42 / 0.08), 0 1px 2px -1px rgb(15 23 42 / 0.06);
|
|
354
|
+
--shadow-md: 0 4px 12px -2px rgb(15 23 42 / 0.10), 0 2px 6px -2px rgb(15 23 42 / 0.06);
|
|
355
|
+
--shadow-lg: 0 12px 28px -6px rgb(15 23 42 / 0.14), 0 4px 10px -4px rgb(15 23 42 / 0.08);
|
|
356
|
+
--shadow-xl: 0 24px 48px -12px rgb(15 23 42 / 0.20), 0 8px 16px -8px rgb(15 23 42 / 0.10);
|
|
357
|
+
|
|
358
|
+
/* Brand-tinted glow (primary buttons on hover, focus accents) */
|
|
359
|
+
--shadow-brand: 0 8px 24px -6px rgb(99 102 241 / 0.45);
|
|
360
|
+
|
|
361
|
+
/* Focus ring (composable as box-shadow) */
|
|
362
|
+
--ring-width: 3px;
|
|
363
|
+
--ring: 0 0 0 var(--ring-width) var(--color-ring);
|
|
364
|
+
--ring-offset: 0 0 0 2px var(--color-surface), 0 0 0 5px var(--color-ring);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/* Deeper, darker elevation in dark mode */
|
|
368
|
+
.dark,
|
|
369
|
+
[data-theme="dark"] {
|
|
370
|
+
--shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.30);
|
|
371
|
+
--shadow-sm: 0 1px 3px 0 rgb(0 0 0 / 0.40), 0 1px 2px -1px rgb(0 0 0 / 0.30);
|
|
372
|
+
--shadow-md: 0 4px 12px -2px rgb(0 0 0 / 0.50), 0 2px 6px -2px rgb(0 0 0 / 0.40);
|
|
373
|
+
--shadow-lg: 0 12px 28px -6px rgb(0 0 0 / 0.60), 0 4px 10px -4px rgb(0 0 0 / 0.45);
|
|
374
|
+
--shadow-xl: 0 24px 48px -12px rgb(0 0 0 / 0.70), 0 8px 16px -8px rgb(0 0 0 / 0.50);
|
|
375
|
+
--shadow-brand: 0 8px 28px -6px rgb(99 102 241 / 0.60);
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
/* ===== tokens/motion.css ===== */
|
|
379
|
+
/* ============================================================
|
|
380
|
+
Twico UI — Motion tokens & keyframes
|
|
381
|
+
Lively: spring entrances, gentle press-scale, ripples.
|
|
382
|
+
============================================================ */
|
|
383
|
+
|
|
384
|
+
:root {
|
|
385
|
+
/* Durations */
|
|
386
|
+
--duration-instant: 80ms; /* @kind other */
|
|
387
|
+
--duration-fast: 140ms; /* @kind other */
|
|
388
|
+
--duration-base: 220ms; /* @kind other */
|
|
389
|
+
--duration-slow: 320ms; /* @kind other */
|
|
390
|
+
--duration-slower: 480ms; /* @kind other */
|
|
391
|
+
|
|
392
|
+
/* Easing curves */
|
|
393
|
+
--ease-standard: cubic-bezier(0.4, 0, 0.2, 1); /* @kind other */
|
|
394
|
+
--ease-out: cubic-bezier(0.16, 1, 0.3, 1); /* @kind other */
|
|
395
|
+
--ease-in: cubic-bezier(0.4, 0, 1, 1); /* @kind other */
|
|
396
|
+
--ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1); /* @kind other */
|
|
397
|
+
--ease-emphasis: cubic-bezier(0.2, 0.8, 0.2, 1); /* @kind other */
|
|
398
|
+
|
|
399
|
+
/* Press feedback */
|
|
400
|
+
--press-scale: 0.96; /* @kind other */
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
/* ---- Keyframes ---- */
|
|
404
|
+
@keyframes twico-fade-in {
|
|
405
|
+
from { opacity: 0; }
|
|
406
|
+
to { opacity: 1; }
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
@keyframes twico-scale-in {
|
|
410
|
+
from { opacity: 0; transform: scale(0.94); }
|
|
411
|
+
to { opacity: 1; transform: scale(1); }
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
@keyframes twico-pop-in {
|
|
415
|
+
0% { opacity: 0; transform: scale(0.85); }
|
|
416
|
+
60% { opacity: 1; transform: scale(1.03); }
|
|
417
|
+
100% { opacity: 1; transform: scale(1); }
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
@keyframes twico-slide-up {
|
|
421
|
+
from { opacity: 0; transform: translateY(10px); }
|
|
422
|
+
to { opacity: 1; transform: translateY(0); }
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
@keyframes twico-slide-down {
|
|
426
|
+
from { opacity: 0; transform: translateY(-10px); }
|
|
427
|
+
to { opacity: 1; transform: translateY(0); }
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
@keyframes twico-slide-in-right {
|
|
431
|
+
from { opacity: 0; transform: translateX(24px); }
|
|
432
|
+
to { opacity: 1; transform: translateX(0); }
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
@keyframes twico-spin {
|
|
436
|
+
to { transform: rotate(360deg); }
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
@keyframes twico-ripple {
|
|
440
|
+
to { transform: scale(2.6); opacity: 0; }
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
@keyframes twico-shimmer {
|
|
444
|
+
100% { transform: translateX(100%); }
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
@keyframes twico-pulse {
|
|
448
|
+
0%, 100% { opacity: 1; }
|
|
449
|
+
50% { opacity: 0.5; }
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
@keyframes twico-progress-indeterminate {
|
|
453
|
+
0% { left: -40%; right: 100%; }
|
|
454
|
+
60% { left: 100%; right: -90%; }
|
|
455
|
+
100% { left: 100%; right: -90%; }
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
/* ===== base.css ===== */
|
|
459
|
+
/* ============================================================
|
|
460
|
+
Twico UI — Base layer
|
|
461
|
+
Minimal, non-destructive resets + sensible element defaults.
|
|
462
|
+
Applies the brand font + semantic colors to the document.
|
|
463
|
+
============================================================ */
|
|
464
|
+
|
|
465
|
+
*,
|
|
466
|
+
*::before,
|
|
467
|
+
*::after {
|
|
468
|
+
box-sizing: border-box;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
html {
|
|
472
|
+
-webkit-text-size-adjust: 100%;
|
|
473
|
+
text-size-adjust: 100%;
|
|
474
|
+
font-feature-settings: "cv05" 1; /* single-storey a for Plus Jakarta */
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
body {
|
|
478
|
+
margin: 0;
|
|
479
|
+
font-family: var(--font-sans);
|
|
480
|
+
font-size: var(--text-base);
|
|
481
|
+
line-height: var(--leading-normal);
|
|
482
|
+
font-weight: var(--font-normal);
|
|
483
|
+
color: var(--color-text);
|
|
484
|
+
background-color: var(--color-bg);
|
|
485
|
+
-webkit-font-smoothing: antialiased;
|
|
486
|
+
-moz-osx-font-smoothing: grayscale;
|
|
487
|
+
text-rendering: optimizeLegibility;
|
|
488
|
+
transition: background-color var(--duration-base) var(--ease-standard),
|
|
489
|
+
color var(--duration-base) var(--ease-standard);
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
h1, h2, h3, h4, h5, h6 {
|
|
493
|
+
margin: 0;
|
|
494
|
+
font-weight: var(--font-bold);
|
|
495
|
+
line-height: var(--leading-tight);
|
|
496
|
+
letter-spacing: var(--tracking-tight);
|
|
497
|
+
color: var(--color-text);
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
p { margin: 0; }
|
|
501
|
+
|
|
502
|
+
a {
|
|
503
|
+
color: var(--color-primary);
|
|
504
|
+
text-decoration: none;
|
|
505
|
+
transition: color var(--duration-fast) var(--ease-standard);
|
|
506
|
+
}
|
|
507
|
+
a:hover { color: var(--color-primary-hover); }
|
|
508
|
+
|
|
509
|
+
code, pre, kbd, samp {
|
|
510
|
+
font-family: var(--font-mono);
|
|
511
|
+
font-size: 0.9em;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
/* Keyboard focus ring for standalone interactive elements.
|
|
515
|
+
NOTE: text inputs / textarea / select are deliberately excluded — in Twico UI
|
|
516
|
+
every text field lives inside a bordered wrapper that shows focus via
|
|
517
|
+
:focus-within, so the bare control must NOT paint its own box ring (that was
|
|
518
|
+
the recurring "boxy purple outline" on search/command inputs). A field that is
|
|
519
|
+
genuinely standalone opts back in with its own higher-specificity :focus rule
|
|
520
|
+
(e.g. .twc-pagination__jump input, .twc-cp__hex). */
|
|
521
|
+
:focus-visible {
|
|
522
|
+
outline: none;
|
|
523
|
+
box-shadow: var(--ring);
|
|
524
|
+
}
|
|
525
|
+
input:focus-visible,
|
|
526
|
+
textarea:focus-visible,
|
|
527
|
+
select:focus-visible {
|
|
528
|
+
box-shadow: none;
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
::selection {
|
|
532
|
+
background: var(--color-primary-subtle);
|
|
533
|
+
color: var(--color-primary-subtle-fg);
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
/* Honor reduced-motion globally */
|
|
537
|
+
@media (prefers-reduced-motion: reduce) {
|
|
538
|
+
*,
|
|
539
|
+
*::before,
|
|
540
|
+
*::after {
|
|
541
|
+
animation-duration: 0.01ms !important;
|
|
542
|
+
animation-iteration-count: 1 !important;
|
|
543
|
+
transition-duration: 0.01ms !important;
|
|
544
|
+
scroll-behavior: auto !important;
|
|
545
|
+
}
|
|
546
|
+
}
|