orbital-ds 0.2.0 → 0.4.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/AGENTS.md +60 -0
- package/README.md +28 -14
- package/components.manifest.json +1255 -0
- package/contract.json +162 -38
- package/dist/styles.css +486 -427
- package/dist/themes/qratia.css +14 -14
- package/dist/themes/qratia.fonts.css +2 -0
- package/dist/themes/qratia.scoped.css +247 -0
- package/dist/themes/twitter.css +290 -0
- package/dist/themes/twitter.fonts.css +6 -0
- package/dist/themes/twitter.scoped.css +290 -0
- package/dist/themes/zyro.css +252 -60
- package/dist/themes/zyro.fonts.css +2 -0
- package/dist/themes/zyro.scoped.css +381 -0
- package/dist/ui/attachment.d.ts +1 -1
- package/dist/ui/badge.d.ts +1 -1
- package/dist/ui/bubble.d.ts +1 -1
- package/dist/ui/button.d.ts +2 -2
- package/dist/ui/input-group.d.ts +1 -1
- package/dist/ui/item.d.ts +2 -2
- package/dist/ui/sidebar.js +4 -4
- package/dist/ui/tabs.d.ts +1 -1
- package/docs/CONTRACT.md +44 -5
- package/package.json +15 -8
- package/scripts/doctor.mjs +110 -28
- package/scripts/init.mjs +55 -0
- package/scripts/manifest.mjs +79 -0
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* TEMA zyro — «liquid glass» (traducido de faro-orbital-zyro-ui).
|
|
3
|
+
*
|
|
4
|
+
* Personalidad: lavanda claro / azul muy oscuro, acento azul profundo (claro) y
|
|
5
|
+
* cian (oscuro). El cristal vive en la capa de NAVEGACIÓN y CONTROLES (sidebar,
|
|
6
|
+
* campos, menús); el CONTENIDO (tarjetas) se mantiene casi opaco, como indican
|
|
7
|
+
* las guías de cristal. Sidebar a ras de borde, sin silueta flotante. Acción
|
|
8
|
+
* primaria = píldora con degradado de marca y brillo.
|
|
9
|
+
*
|
|
10
|
+
* Estructura del fichero:
|
|
11
|
+
* 1. Variables claras (:root) y oscuras (.dark) — el CONTRATO del tema.
|
|
12
|
+
* 2. Capa de PERSONALIDAD — reglas sobre los ganchos del DOM (`data-slot`,
|
|
13
|
+
* `data-variant`…) escritas solo con variables. Va SIN capa para ganar a las
|
|
14
|
+
* utilidades de los componentes, así que define también los estados
|
|
15
|
+
* (hover, active). Es lo que da forma propia a los elementos.
|
|
16
|
+
*
|
|
17
|
+
* Variables `--zy-*`: privadas de este tema (no son contrato).
|
|
18
|
+
* Importar DESPUÉS de la estructura. Fuentes: `zyro.fonts.css`, lo primero del CSS.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/* ── 1. VARIABLES · PIEL CLARA ───────────────────────────────────────────── */
|
|
22
|
+
:root[data-theme='zyro'] {
|
|
23
|
+
--radius: 18px;
|
|
24
|
+
|
|
25
|
+
/* Tipografía: Montserrat (titulares) + Roboto (cuerpo) */
|
|
26
|
+
--ds-font-sans: 'Roboto', system-ui, -apple-system, sans-serif;
|
|
27
|
+
--ds-font-display: 'Montserrat', system-ui, -apple-system, sans-serif;
|
|
28
|
+
--ds-font-mono: ui-monospace, 'SF Mono', Menlo, monospace;
|
|
29
|
+
--ds-heading-tracking: -0.01em;
|
|
30
|
+
|
|
31
|
+
/* Color */
|
|
32
|
+
--background: #eaeefb;
|
|
33
|
+
--foreground: rgba(14, 22, 48, 0.92);
|
|
34
|
+
|
|
35
|
+
--card: rgba(255, 255, 255, 0.98);
|
|
36
|
+
--card-foreground: rgba(14, 22, 48, 0.92);
|
|
37
|
+
--popover: #ffffff;
|
|
38
|
+
--popover-foreground: rgba(14, 22, 48, 0.92);
|
|
39
|
+
|
|
40
|
+
--primary: #0349fe;
|
|
41
|
+
--primary-foreground: #ffffff;
|
|
42
|
+
--secondary: rgba(243, 246, 253, 0.9);
|
|
43
|
+
--secondary-foreground: rgba(14, 22, 48, 0.92);
|
|
44
|
+
--muted: rgba(243, 246, 253, 0.9);
|
|
45
|
+
--muted-foreground: rgba(14, 22, 48, 0.66);
|
|
46
|
+
--accent: rgba(3, 73, 254, 0.09);
|
|
47
|
+
--accent-foreground: #0349fe;
|
|
48
|
+
--destructive: #eb1919;
|
|
49
|
+
--destructive-foreground: #ffffff;
|
|
50
|
+
|
|
51
|
+
--border: rgba(168, 190, 235, 0.3);
|
|
52
|
+
--input: rgba(168, 190, 235, 0.55);
|
|
53
|
+
--ring: #0349fe;
|
|
54
|
+
|
|
55
|
+
--chart-1: #0349fe;
|
|
56
|
+
--chart-2: #14bd44;
|
|
57
|
+
--chart-3: #ffb300;
|
|
58
|
+
--chart-4: #eb1919;
|
|
59
|
+
--chart-5: #9747ff;
|
|
60
|
+
|
|
61
|
+
--sidebar: rgba(255, 255, 255, 0.58);
|
|
62
|
+
--sidebar-foreground: rgba(14, 22, 48, 0.78);
|
|
63
|
+
--sidebar-primary: #0349fe;
|
|
64
|
+
--sidebar-primary-foreground: #ffffff;
|
|
65
|
+
--sidebar-accent: rgba(3, 73, 254, 0.09);
|
|
66
|
+
--sidebar-accent-foreground: #0349fe;
|
|
67
|
+
--sidebar-border: rgba(168, 190, 235, 0.35);
|
|
68
|
+
--sidebar-ring: #0349fe;
|
|
69
|
+
|
|
70
|
+
--danger: #c21414;
|
|
71
|
+
--danger-soft: rgba(235, 25, 25, 0.1);
|
|
72
|
+
--warning: #9a6e00;
|
|
73
|
+
--warning-soft: rgba(255, 179, 0, 0.16);
|
|
74
|
+
--success: #0e8f34;
|
|
75
|
+
--success-soft: rgba(20, 189, 68, 0.12);
|
|
76
|
+
--info: #136ba8;
|
|
77
|
+
--info-soft: rgba(42, 147, 213, 0.12);
|
|
78
|
+
--neutral: rgba(14, 22, 48, 0.6);
|
|
79
|
+
--neutral-soft: rgba(14, 22, 48, 0.06);
|
|
80
|
+
|
|
81
|
+
--link: #0349fe;
|
|
82
|
+
--link-hover: #0236c0;
|
|
83
|
+
--inset: rgba(243, 246, 253, 0.9);
|
|
84
|
+
--inset-foreground: rgba(14, 22, 48, 0.92);
|
|
85
|
+
--brand: #0349fe;
|
|
86
|
+
--brand-bright: #36b3ed;
|
|
87
|
+
|
|
88
|
+
/* Formas: la esquina crece con el tamaño del contenedor (7·10·14·18·22) */
|
|
89
|
+
--ds-radius-sm: 7px;
|
|
90
|
+
--ds-radius-md: 10px;
|
|
91
|
+
--ds-radius-lg: 14px;
|
|
92
|
+
--ds-radius-xl: 18px;
|
|
93
|
+
--ds-radius-2xl: 22px;
|
|
94
|
+
--ds-radius-control: 10px;
|
|
95
|
+
--ds-radius-overlay: 22px;
|
|
96
|
+
|
|
97
|
+
/* Sombras de cristal: capa tenue + brillo interior en el borde superior */
|
|
98
|
+
--ds-shadow-card: 0 2px 14px rgba(28, 48, 100, 0.07);
|
|
99
|
+
--ds-shadow-card-hover: 0 6px 26px rgba(28, 48, 100, 0.1);
|
|
100
|
+
--ds-shadow-raised: 0 4px 30px rgba(28, 48, 100, 0.08), inset 0 1px 0 rgba(255, 255, 255, 0.85);
|
|
101
|
+
--ds-shadow-overlay: 0 14px 52px rgba(28, 48, 100, 0.12), inset 0 1px 0 rgba(255, 255, 255, 0.95);
|
|
102
|
+
--ds-shadow-popover: 0 14px 52px rgba(28, 48, 100, 0.12), inset 0 1px 0 rgba(255, 255, 255, 0.95);
|
|
103
|
+
|
|
104
|
+
/* Medidas: controles algo más altos y holgados */
|
|
105
|
+
--ds-control-h-sm: 2.25rem;
|
|
106
|
+
--ds-control-h-md: 2.5rem;
|
|
107
|
+
--ds-control-h-lg: 2.75rem;
|
|
108
|
+
--ds-button-px-sm: 1rem;
|
|
109
|
+
--ds-button-px-md: 1.25rem;
|
|
110
|
+
--ds-button-px-lg: 1.5rem;
|
|
111
|
+
--ds-field-px: 1rem;
|
|
112
|
+
|
|
113
|
+
/* Materiales: cristal en navegación y controles; tarjetas sin desenfoque */
|
|
114
|
+
--ds-sidebar-backdrop: blur(28px) saturate(180%);
|
|
115
|
+
--ds-overlay-backdrop: blur(28px) saturate(180%);
|
|
116
|
+
--ds-field-backdrop: blur(12px) saturate(160%);
|
|
117
|
+
--ds-card-backdrop: none;
|
|
118
|
+
--ds-page-backdrop:
|
|
119
|
+
radial-gradient(55% 45% at 78% 6%, rgba(54, 179, 237, 0.3), transparent 70%),
|
|
120
|
+
radial-gradient(50% 45% at 96% 58%, rgba(3, 73, 254, 0.16), transparent 70%),
|
|
121
|
+
radial-gradient(55% 50% at 40% 106%, rgba(151, 71, 255, 0.14), transparent 70%);
|
|
122
|
+
|
|
123
|
+
/* Sidebar a ras de borde: sin separación, sin silueta; filo de 1px */
|
|
124
|
+
--ds-sidebar-pad: 0px;
|
|
125
|
+
--ds-sidebar-radius: 0px;
|
|
126
|
+
--ds-sidebar-shadow: 0 0 #0000;
|
|
127
|
+
--ds-sidebar-ring: 0px;
|
|
128
|
+
--ds-sidebar-edge: 1px solid var(--zy-glass-bs);
|
|
129
|
+
--ds-sidebar-item-radius: var(--ds-radius-lg);
|
|
130
|
+
|
|
131
|
+
/* Privadas de zyro */
|
|
132
|
+
--zy-accent-g: linear-gradient(135deg, #0349fe, #36b3ed);
|
|
133
|
+
--zy-accent-glow: rgba(3, 73, 254, 0.24);
|
|
134
|
+
--zy-glass-bt: rgba(255, 255, 255, 0.95);
|
|
135
|
+
--zy-glass-bs: rgba(168, 190, 235, 0.4);
|
|
136
|
+
--zy-card-bt: rgba(255, 255, 255, 1);
|
|
137
|
+
--zy-card-bs: rgba(168, 190, 235, 0.46);
|
|
138
|
+
--zy-field-bg: rgba(255, 255, 255, 0.72);
|
|
139
|
+
--zy-field-b: rgba(168, 190, 235, 0.55);
|
|
140
|
+
--zy-field-bt: rgba(255, 255, 255, 1);
|
|
141
|
+
--zy-pill: rgba(255, 255, 255, 0.55);
|
|
142
|
+
--zy-pill-on: rgba(255, 255, 255, 0.98);
|
|
143
|
+
--zy-conv-h: rgba(20, 40, 90, 0.04);
|
|
144
|
+
--zy-conv-a: rgba(3, 73, 254, 0.07);
|
|
145
|
+
--zy-conv-ab: rgba(3, 73, 254, 0.24);
|
|
146
|
+
--zy-ease: cubic-bezier(0.2, 0.7, 0.2, 1);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/* ── 1b. VARIABLES · PIEL OSCURA ─────────────────────────────────────────── */
|
|
150
|
+
:root[data-theme='zyro'].dark {
|
|
151
|
+
--background: #0e3148;
|
|
152
|
+
--foreground: rgba(255, 255, 255, 0.94);
|
|
153
|
+
|
|
154
|
+
--card: rgba(16, 24, 54, 0.94);
|
|
155
|
+
--card-foreground: rgba(255, 255, 255, 0.94);
|
|
156
|
+
--popover: rgba(22, 32, 68, 0.97);
|
|
157
|
+
--popover-foreground: rgba(255, 255, 255, 0.94);
|
|
158
|
+
|
|
159
|
+
--primary: #36b3ed;
|
|
160
|
+
--primary-foreground: #04121c;
|
|
161
|
+
--secondary: rgba(255, 255, 255, 0.05);
|
|
162
|
+
--secondary-foreground: rgba(255, 255, 255, 0.94);
|
|
163
|
+
--muted: rgba(255, 255, 255, 0.05);
|
|
164
|
+
--muted-foreground: rgba(255, 255, 255, 0.68);
|
|
165
|
+
--accent: rgba(54, 179, 237, 0.16);
|
|
166
|
+
--accent-foreground: #36b3ed;
|
|
167
|
+
--destructive: #eb1919;
|
|
168
|
+
--destructive-foreground: #ffffff;
|
|
169
|
+
|
|
170
|
+
--border: rgba(255, 255, 255, 0.07);
|
|
171
|
+
--input: rgba(255, 255, 255, 0.12);
|
|
172
|
+
--ring: #36b3ed;
|
|
173
|
+
|
|
174
|
+
--chart-1: #36b3ed;
|
|
175
|
+
--chart-2: #14bd44;
|
|
176
|
+
--chart-3: #ffb300;
|
|
177
|
+
--chart-4: #eb1919;
|
|
178
|
+
--chart-5: #9747ff;
|
|
179
|
+
|
|
180
|
+
--sidebar: rgba(255, 255, 255, 0.04);
|
|
181
|
+
--sidebar-foreground: rgba(255, 255, 255, 0.72);
|
|
182
|
+
--sidebar-primary: #36b3ed;
|
|
183
|
+
--sidebar-primary-foreground: #04121c;
|
|
184
|
+
--sidebar-accent: rgba(54, 179, 237, 0.16);
|
|
185
|
+
--sidebar-accent-foreground: #36b3ed;
|
|
186
|
+
--sidebar-border: rgba(255, 255, 255, 0.07);
|
|
187
|
+
--sidebar-ring: #36b3ed;
|
|
188
|
+
|
|
189
|
+
--danger: #ff6b6b;
|
|
190
|
+
--danger-soft: rgba(235, 25, 25, 0.2);
|
|
191
|
+
--warning: #ffb300;
|
|
192
|
+
--warning-soft: rgba(255, 179, 0, 0.18);
|
|
193
|
+
--success: #14bd44;
|
|
194
|
+
--success-soft: rgba(20, 189, 68, 0.18);
|
|
195
|
+
--info: #2a93d5;
|
|
196
|
+
--info-soft: rgba(42, 147, 213, 0.2);
|
|
197
|
+
--neutral: rgba(255, 255, 255, 0.6);
|
|
198
|
+
--neutral-soft: rgba(255, 255, 255, 0.08);
|
|
199
|
+
|
|
200
|
+
--link: #36b3ed;
|
|
201
|
+
--link-hover: #7fd0f5;
|
|
202
|
+
--inset: rgba(255, 255, 255, 0.05);
|
|
203
|
+
--inset-foreground: rgba(255, 255, 255, 0.94);
|
|
204
|
+
--brand: #36b3ed;
|
|
205
|
+
--brand-bright: #7fd0f5;
|
|
206
|
+
|
|
207
|
+
--ds-shadow-card: 0 2px 14px rgba(0, 0, 0, 0.3);
|
|
208
|
+
--ds-shadow-card-hover: 0 6px 26px rgba(0, 0, 0, 0.38);
|
|
209
|
+
--ds-shadow-raised: 0 8px 40px rgba(0, 0, 0, 0.28), inset 0 1px 0 rgba(255, 255, 255, 0.1);
|
|
210
|
+
--ds-shadow-overlay: 0 22px 64px rgba(0, 0, 0, 0.36), inset 0 1px 0 rgba(255, 255, 255, 0.13);
|
|
211
|
+
--ds-shadow-popover: 0 22px 64px rgba(0, 0, 0, 0.36), inset 0 1px 0 rgba(255, 255, 255, 0.13);
|
|
212
|
+
|
|
213
|
+
--ds-sidebar-backdrop: blur(24px) saturate(180%);
|
|
214
|
+
--ds-overlay-backdrop: blur(24px) saturate(180%);
|
|
215
|
+
--ds-page-backdrop:
|
|
216
|
+
radial-gradient(55% 45% at 78% 6%, rgba(54, 179, 237, 0.26), transparent 70%),
|
|
217
|
+
radial-gradient(50% 45% at 96% 58%, rgba(3, 73, 254, 0.24), transparent 70%),
|
|
218
|
+
radial-gradient(55% 50% at 40% 106%, rgba(151, 71, 255, 0.2), transparent 70%);
|
|
219
|
+
|
|
220
|
+
--zy-accent-g: linear-gradient(135deg, #36b3ed, #0349fe);
|
|
221
|
+
--zy-accent-glow: rgba(54, 179, 237, 0.42);
|
|
222
|
+
--zy-glass-bt: rgba(255, 255, 255, 0.3);
|
|
223
|
+
--zy-glass-bs: rgba(255, 255, 255, 0.07);
|
|
224
|
+
--zy-card-bt: rgba(255, 255, 255, 0.11);
|
|
225
|
+
--zy-card-bs: rgba(255, 255, 255, 0.06);
|
|
226
|
+
--zy-field-bg: rgba(255, 255, 255, 0.06);
|
|
227
|
+
--zy-field-b: rgba(255, 255, 255, 0.12);
|
|
228
|
+
--zy-field-bt: rgba(255, 255, 255, 0.26);
|
|
229
|
+
--zy-pill: rgba(255, 255, 255, 0.05);
|
|
230
|
+
--zy-pill-on: rgba(255, 255, 255, 0.12);
|
|
231
|
+
--zy-conv-h: rgba(255, 255, 255, 0.05);
|
|
232
|
+
--zy-conv-a: rgba(54, 179, 237, 0.14);
|
|
233
|
+
--zy-conv-ab: rgba(54, 179, 237, 0.4);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/* ── 2. PERSONALIDAD ─────────────────────────────────────────────────────────
|
|
237
|
+
* Sin capa: gana a las utilidades de los componentes. Solo variables.
|
|
238
|
+
*/
|
|
239
|
+
:root[data-theme='zyro'] {
|
|
240
|
+
/* Botones: píldora. Acción primaria con degradado de marca y brillo. */
|
|
241
|
+
[data-slot='button'] {
|
|
242
|
+
border-radius: 9999px;
|
|
243
|
+
transition: all var(--ds-motion-base) var(--zy-ease);
|
|
244
|
+
}
|
|
245
|
+
[data-slot='button'][data-size^='icon'] {
|
|
246
|
+
border-radius: var(--ds-radius-xl);
|
|
247
|
+
}
|
|
248
|
+
[data-slot='button']:active:not(:disabled) {
|
|
249
|
+
transform: scale(0.98);
|
|
250
|
+
}
|
|
251
|
+
[data-slot='button'][data-variant='default'] {
|
|
252
|
+
background-color: transparent;
|
|
253
|
+
background-image: var(--zy-accent-g);
|
|
254
|
+
color: #ffffff;
|
|
255
|
+
border-color: transparent;
|
|
256
|
+
box-shadow: 0 4px 16px var(--zy-accent-glow);
|
|
257
|
+
}
|
|
258
|
+
[data-slot='button'][data-variant='default']:hover:not(:disabled) {
|
|
259
|
+
filter: brightness(1.1);
|
|
260
|
+
box-shadow: 0 6px 22px var(--zy-accent-glow);
|
|
261
|
+
}
|
|
262
|
+
[data-slot='button'][data-variant='destructive'] {
|
|
263
|
+
box-shadow: 0 4px 16px rgba(235, 25, 25, 0.3);
|
|
264
|
+
}
|
|
265
|
+
[data-slot='button'][data-variant='outline'],
|
|
266
|
+
[data-slot='button'][data-variant='secondary'] {
|
|
267
|
+
border: 1px solid var(--zy-field-b);
|
|
268
|
+
background: color-mix(in oklch, var(--foreground) 5%, var(--background));
|
|
269
|
+
color: var(--muted-foreground);
|
|
270
|
+
}
|
|
271
|
+
[data-slot='button'][data-variant='outline']:hover:not(:disabled),
|
|
272
|
+
[data-slot='button'][data-variant='secondary']:hover:not(:disabled) {
|
|
273
|
+
background: color-mix(in oklch, var(--foreground) 11%, var(--background));
|
|
274
|
+
color: var(--foreground);
|
|
275
|
+
}
|
|
276
|
+
[data-slot='button'][data-variant='ghost']:hover:not(:disabled) {
|
|
277
|
+
background: var(--zy-conv-h);
|
|
278
|
+
color: var(--foreground);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/* Tarjetas: contenido casi opaco con filo superior luminoso */
|
|
282
|
+
[data-slot='card'] {
|
|
283
|
+
border: 1px solid var(--zy-card-bs);
|
|
284
|
+
border-top-color: var(--zy-card-bt);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/* Campos: cristal claro con filo superior */
|
|
288
|
+
[data-slot='input'],
|
|
289
|
+
[data-slot='textarea'],
|
|
290
|
+
[data-slot='select-trigger'] {
|
|
291
|
+
background-color: var(--zy-field-bg);
|
|
292
|
+
border-color: var(--zy-field-b);
|
|
293
|
+
border-top-color: var(--zy-field-bt);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/* Capas flotantes: filo de cristal */
|
|
297
|
+
[data-slot='dialog-content'],
|
|
298
|
+
[data-slot='popover-content'],
|
|
299
|
+
[data-slot='dropdown-menu-content'],
|
|
300
|
+
[data-slot='select-content'] {
|
|
301
|
+
border: 1px solid var(--zy-glass-bs);
|
|
302
|
+
border-top-color: var(--zy-glass-bt);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/* Etiquetas en píldora */
|
|
306
|
+
[data-slot='badge'] {
|
|
307
|
+
border-radius: 9999px;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/* Pestañas: píldora de cristal con la activa elevada */
|
|
311
|
+
[data-slot='tabs-list'] {
|
|
312
|
+
background: var(--zy-pill);
|
|
313
|
+
border: 1px solid var(--zy-card-bs);
|
|
314
|
+
border-radius: 9999px;
|
|
315
|
+
}
|
|
316
|
+
[data-slot='tabs-trigger'] {
|
|
317
|
+
border-radius: 9999px;
|
|
318
|
+
}
|
|
319
|
+
[data-slot='tabs-trigger'][data-active] {
|
|
320
|
+
background: var(--zy-pill-on);
|
|
321
|
+
box-shadow: 0 1px 6px rgba(28, 48, 100, 0.12);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/* Interruptor y progreso: degradado de marca */
|
|
325
|
+
[data-slot='switch'][data-checked] {
|
|
326
|
+
background-image: var(--zy-accent-g);
|
|
327
|
+
background-color: transparent;
|
|
328
|
+
}
|
|
329
|
+
[data-slot='progress-indicator'] {
|
|
330
|
+
background-image: var(--zy-accent-g);
|
|
331
|
+
background-color: transparent;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/* Sidebar: destino activo con tinte y filo, como la conversación activa de zyro */
|
|
335
|
+
[data-sidebar='menu-button'][data-active='true'] {
|
|
336
|
+
background: var(--zy-conv-a);
|
|
337
|
+
box-shadow: inset 0 0 0 1px var(--zy-conv-ab);
|
|
338
|
+
color: var(--sidebar-accent-foreground);
|
|
339
|
+
}
|
|
340
|
+
[data-sidebar='menu-button']:hover:not([data-active='true']) {
|
|
341
|
+
background: var(--zy-conv-h);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/* Ajustes de personalidad (vistos en el banco de pruebas) */
|
|
346
|
+
:root[data-theme='zyro'] {
|
|
347
|
+
/* Grupos de botones: píldora solo en los extremos, el interior recto */
|
|
348
|
+
[data-slot='button-group'] [data-slot='button'] {
|
|
349
|
+
border-radius: 0;
|
|
350
|
+
}
|
|
351
|
+
[data-slot='button-group'] [data-slot='button']:first-child {
|
|
352
|
+
border-start-start-radius: 9999px;
|
|
353
|
+
border-end-start-radius: 9999px;
|
|
354
|
+
}
|
|
355
|
+
[data-slot='button-group'] [data-slot='button']:last-child {
|
|
356
|
+
border-start-end-radius: 9999px;
|
|
357
|
+
border-end-end-radius: 9999px;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
/* Esqueletos: visibles sobre la tarjeta casi blanca */
|
|
361
|
+
[data-slot='skeleton'] {
|
|
362
|
+
background: color-mix(in oklch, var(--foreground) 9%, transparent);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/* Fondo vivo: los degradados derivan despacio (aproximación ligera, sin WebGL de la
|
|
367
|
+
malla original). `prefers-reduced-motion` ya detiene la animación en la estructura. */
|
|
368
|
+
:root[data-theme='zyro'] {
|
|
369
|
+
body {
|
|
370
|
+
background-size: 160% 160%;
|
|
371
|
+
animation: zy-drift 40s ease-in-out infinite alternate;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
@keyframes zy-drift {
|
|
375
|
+
from {
|
|
376
|
+
background-position: 0% 0%;
|
|
377
|
+
}
|
|
378
|
+
to {
|
|
379
|
+
background-position: 100% 100%;
|
|
380
|
+
}
|
|
381
|
+
}
|
package/dist/ui/attachment.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { VariantProps } from 'class-variance-authority';
|
|
|
5
5
|
import { Button } from './button.js';
|
|
6
6
|
|
|
7
7
|
declare const attachmentVariants: (props?: ({
|
|
8
|
-
size?: "default" | "
|
|
8
|
+
size?: "default" | "sm" | "xs" | null | undefined;
|
|
9
9
|
orientation?: "horizontal" | "vertical" | null | undefined;
|
|
10
10
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
11
11
|
declare function Attachment({ className, state, size, orientation, ...props }: React.ComponentProps<"div"> & VariantProps<typeof attachmentVariants> & {
|
package/dist/ui/badge.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { useRender } from '@base-ui/react/use-render';
|
|
|
4
4
|
import { VariantProps } from 'class-variance-authority';
|
|
5
5
|
|
|
6
6
|
declare const badgeVariants: (props?: ({
|
|
7
|
-
variant?: "
|
|
7
|
+
variant?: "link" | "default" | "outline" | "secondary" | "ghost" | "destructive" | null | undefined;
|
|
8
8
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
9
9
|
declare function Badge({ className, variant, render, ...props }: useRender.ComponentProps<"span"> & VariantProps<typeof badgeVariants>): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>;
|
|
10
10
|
|
package/dist/ui/bubble.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { VariantProps } from 'class-variance-authority';
|
|
|
5
5
|
|
|
6
6
|
declare function BubbleGroup({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
|
|
7
7
|
declare const bubbleVariants: (props?: ({
|
|
8
|
-
variant?: "default" | "
|
|
8
|
+
variant?: "default" | "outline" | "secondary" | "ghost" | "destructive" | "muted" | "tinted" | null | undefined;
|
|
9
9
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
10
10
|
declare function Bubble({ variant, align, className, ...props }: React.ComponentProps<"div"> & VariantProps<typeof bubbleVariants> & {
|
|
11
11
|
align?: "start" | "end";
|
package/dist/ui/button.d.ts
CHANGED
|
@@ -4,8 +4,8 @@ import { useRender } from '@base-ui/react/use-render';
|
|
|
4
4
|
import { VariantProps } from 'class-variance-authority';
|
|
5
5
|
|
|
6
6
|
declare const buttonVariants: (props?: ({
|
|
7
|
-
variant?: "
|
|
8
|
-
size?: "default" | "
|
|
7
|
+
variant?: "link" | "default" | "outline" | "secondary" | "ghost" | "destructive" | null | undefined;
|
|
8
|
+
size?: "default" | "sm" | "xs" | "lg" | "icon" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
|
|
9
9
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
10
10
|
declare function Button({ className, variant, size, render, nativeButton: _nativeButton, ...props }: useRender.ComponentProps<"button"> & VariantProps<typeof buttonVariants> & {
|
|
11
11
|
nativeButton?: boolean;
|
package/dist/ui/input-group.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ declare const inputGroupAddonVariants: (props?: ({
|
|
|
10
10
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
11
11
|
declare function InputGroupAddon({ className, align, ...props }: React.ComponentProps<"div"> & VariantProps<typeof inputGroupAddonVariants>): React.JSX.Element;
|
|
12
12
|
declare const inputGroupButtonVariants: (props?: ({
|
|
13
|
-
size?: "
|
|
13
|
+
size?: "sm" | "xs" | "icon-xs" | "icon-sm" | null | undefined;
|
|
14
14
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
15
15
|
declare function InputGroupButton({ className, type, variant, size, ...props }: Omit<React.ComponentProps<typeof Button>, "size" | "type"> & VariantProps<typeof inputGroupButtonVariants> & {
|
|
16
16
|
type?: "button" | "submit" | "reset";
|
package/dist/ui/item.d.ts
CHANGED
|
@@ -9,11 +9,11 @@ declare function ItemGroup({ className, ...props }: React.ComponentProps<"div">)
|
|
|
9
9
|
declare function ItemSeparator({ className, ...props }: React.ComponentProps<typeof Separator>): React.JSX.Element;
|
|
10
10
|
declare const itemVariants: (props?: ({
|
|
11
11
|
variant?: "default" | "outline" | "muted" | null | undefined;
|
|
12
|
-
size?: "default" | "
|
|
12
|
+
size?: "default" | "sm" | "xs" | null | undefined;
|
|
13
13
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
14
14
|
declare function Item({ className, variant, size, render, ...props }: useRender.ComponentProps<"div"> & VariantProps<typeof itemVariants>): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>;
|
|
15
15
|
declare const itemMediaVariants: (props?: ({
|
|
16
|
-
variant?: "
|
|
16
|
+
variant?: "image" | "default" | "icon" | null | undefined;
|
|
17
17
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
18
18
|
declare function ItemMedia({ className, variant, ...props }: React.ComponentProps<"div"> & VariantProps<typeof itemMediaVariants>): React.JSX.Element;
|
|
19
19
|
declare function ItemContent({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
|
package/dist/ui/sidebar.js
CHANGED
|
@@ -170,7 +170,7 @@ function Sidebar({
|
|
|
170
170
|
"relative w-(--sidebar-width) bg-transparent transition-[width] duration-(--ds-motion-base) ease-linear",
|
|
171
171
|
"group-data-[collapsible=offcanvas]:w-0",
|
|
172
172
|
"group-data-[side=right]:rotate-180",
|
|
173
|
-
variant === "floating" || variant === "inset" ? "group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--
|
|
173
|
+
variant === "floating" || variant === "inset" ? "group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(var(--ds-sidebar-pad)*2))]" : "group-data-[collapsible=icon]:w-(--sidebar-width-icon)"
|
|
174
174
|
)
|
|
175
175
|
}
|
|
176
176
|
),
|
|
@@ -182,7 +182,7 @@ function Sidebar({
|
|
|
182
182
|
className: cn(
|
|
183
183
|
"fixed inset-y-0 z-(--ds-z-raised) hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-(--ds-motion-base) ease-linear data-[side=left]:left-0 data-[side=left]:group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)] data-[side=right]:right-0 data-[side=right]:group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)] md:flex",
|
|
184
184
|
// Adjust the padding for floating and inset variants.
|
|
185
|
-
variant === "floating" || variant === "inset" ? "p-
|
|
185
|
+
variant === "floating" || variant === "inset" ? "p-(--ds-sidebar-pad) group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(var(--ds-sidebar-pad)*2)+2px)]" : "group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l",
|
|
186
186
|
className
|
|
187
187
|
),
|
|
188
188
|
...props,
|
|
@@ -191,7 +191,7 @@ function Sidebar({
|
|
|
191
191
|
{
|
|
192
192
|
"data-sidebar": "sidebar",
|
|
193
193
|
"data-slot": "sidebar-inner",
|
|
194
|
-
className: "flex size-full flex-col bg-sidebar group-data-[variant=floating]:rounded-
|
|
194
|
+
className: "flex size-full flex-col bg-sidebar group-data-[variant=floating]:rounded-(--ds-sidebar-radius) group-data-[variant=floating]:shadow-(--ds-sidebar-shadow) group-data-[variant=floating]:ring-(length:--ds-sidebar-ring) group-data-[variant=floating]:ring-sidebar-border",
|
|
195
195
|
children
|
|
196
196
|
}
|
|
197
197
|
)
|
|
@@ -421,7 +421,7 @@ function SidebarMenuItem({ className, ...props }) {
|
|
|
421
421
|
);
|
|
422
422
|
}
|
|
423
423
|
const sidebarMenuButtonVariants = cva(
|
|
424
|
-
"peer/menu-button group/menu-button flex w-full items-center gap-2 overflow-hidden rounded-
|
|
424
|
+
"peer/menu-button group/menu-button flex w-full items-center gap-2 overflow-hidden rounded-(--ds-sidebar-item-radius) px-3 py-2 text-left text-sm ring-sidebar-ring outline-hidden transition-[width,height,padding] group-has-data-[sidebar=menu-action]/menu-item:pr-8 group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-open:hover:bg-sidebar-accent data-open:hover:text-sidebar-accent-foreground data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground [&_svg]:size-4 [&_svg]:shrink-0 [&>span:last-child]:truncate",
|
|
425
425
|
{
|
|
426
426
|
variants: {
|
|
427
427
|
variant: {
|
package/dist/ui/tabs.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { VariantProps } from 'class-variance-authority';
|
|
|
5
5
|
|
|
6
6
|
declare function Tabs({ className, orientation, ...props }: Tabs$1.Root.Props): React.JSX.Element;
|
|
7
7
|
declare const tabsListVariants: (props?: ({
|
|
8
|
-
variant?: "
|
|
8
|
+
variant?: "line" | "default" | null | undefined;
|
|
9
9
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
10
10
|
declare function TabsList({ className, variant, ...props }: Tabs$1.List.Props & VariantProps<typeof tabsListVariants>): React.JSX.Element;
|
|
11
11
|
declare function TabsTrigger({ className, ...props }: Tabs$1.Tab.Props): React.JSX.Element;
|
package/docs/CONTRACT.md
CHANGED
|
@@ -6,13 +6,15 @@ colores, medidas, sombras, capas ni duraciones escritos a mano. Por eso cambiar
|
|
|
6
6
|
tema cambia todo el aspecto sin tocar un componente.
|
|
7
7
|
|
|
8
8
|
El contrato vive en [`contract.json`](../contract.json) y lo comprueba
|
|
9
|
-
`pnpm
|
|
9
|
+
`pnpm check:ds` (que forma parte de `pnpm verify`): si a un tema le falta un token
|
|
10
10
|
obligatorio, el build falla.
|
|
11
11
|
|
|
12
12
|
## Cómo se usa
|
|
13
13
|
|
|
14
14
|
```css
|
|
15
|
+
@import 'orbital-ds/themes/qratia.fonts.css'; /* 0. las FUENTES del tema: lo PRIMERO del fichero */
|
|
15
16
|
@import 'tailwindcss';
|
|
17
|
+
@plugin '@tailwindcss/typography';
|
|
16
18
|
@import 'tw-animate-css';
|
|
17
19
|
|
|
18
20
|
@import 'orbital-ds/styles.css'; /* 1. la ESTRUCTURA común */
|
|
@@ -24,6 +26,14 @@ obligatorio, el build falla.
|
|
|
24
26
|
El tema se importa **después** de la estructura: así puede sobrescribir también la
|
|
25
27
|
escala de radios y las sombras, que viven en `@theme`.
|
|
26
28
|
|
|
29
|
+
Las **fuentes** van en un fichero aparte por tema (`themes/<tema>.fonts.css`, solo un
|
|
30
|
+
`@import url(...)` de Google Fonts) porque un `@import` remoto solo vale al principio
|
|
31
|
+
de la hoja. Importado el primero, el empaquetador lo sube al inicio y se cargan. Dentro
|
|
32
|
+
del propio `<tema>.css` no se pueden poner.
|
|
33
|
+
|
|
34
|
+
Los títulos usan `--font-display` (por defecto, la misma fuente que el cuerpo; un tema
|
|
35
|
+
con fuente de titulares, como zyro, la sobrescribe).
|
|
36
|
+
|
|
27
37
|
Para ajustar un valor sin crear un tema, se sobrescribe la variable al final:
|
|
28
38
|
|
|
29
39
|
```css
|
|
@@ -46,9 +56,9 @@ Para ajustar un valor sin crear un tema, se sobrescribe la variable al final:
|
|
|
46
56
|
| Texto acentuado | `--link`, `--link-hover` |
|
|
47
57
|
| Superficie hundida | `--inset`, `--inset-foreground` |
|
|
48
58
|
| Marca | `--brand`, `--brand-bright` |
|
|
49
|
-
| Tipografía | `--font-sans` (en `:root` o en `@theme`) |
|
|
59
|
+
| Tipografía | `--font-sans` (en `:root` o en `@theme`); opcional `--font-display` para titulares |
|
|
50
60
|
|
|
51
|
-
En `.dark` se redefine lo que cambie; `
|
|
61
|
+
En `.dark` se redefine lo que cambie; `check:ds` avisa (no falla) de los tokens
|
|
52
62
|
principales que se hereden de la piel clara.
|
|
53
63
|
|
|
54
64
|
`--destructive` es el rojo de **acciones** (botón de borrar); `--danger` es el rojo
|
|
@@ -74,6 +84,35 @@ Los **materiales** son lo que hace posible un tema de cristal como `zyro`: con v
|
|
|
74
84
|
neutros no hay efecto ni coste; con `blur(28px) saturate(180%)` las superficies se
|
|
75
85
|
vuelven translúcidas.
|
|
76
86
|
|
|
87
|
+
## Capa de marca (`brand.css`): lo que cambia una app, y nunca se pisa
|
|
88
|
+
|
|
89
|
+
Tres capas, de menos a más personal:
|
|
90
|
+
|
|
91
|
+
1. **Estructura y componentes** (paquete): se actualizan.
|
|
92
|
+
2. **Tema y personalidad** (paquete: `qratia`, `zyro`…): formas, sombras, materiales,
|
|
93
|
+
anatomía del sidebar. Se actualizan con versión y changelog.
|
|
94
|
+
3. **Marca** (`src/brand.css`, **en la app**): el grupo estable de variables que una marca
|
|
95
|
+
suele cambiar (`brand.tokens` en `contract.json`: color principal, foco, enlace,
|
|
96
|
+
acento, radio, fuentes). Se importa **después** del tema, así gana, y **ninguna
|
|
97
|
+
actualización lo toca**. Sin fichero, o vacío, se aplica el estándar del tema.
|
|
98
|
+
|
|
99
|
+
```css
|
|
100
|
+
@import 'orbital-ds/themes/qratia.css';
|
|
101
|
+
@import './brand.css'; /* tuyo: gana al tema */
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
`pnpm exec orbital-ds-init` lo crea la primera vez (con las variables comentadas) y **nunca
|
|
105
|
+
sobrescribe** uno existente.
|
|
106
|
+
|
|
107
|
+
**Por qué una actualización no lo rompe:** los nombres de ese grupo son estables; quitar o
|
|
108
|
+
renombrar uno es versión **mayor**, con aviso antes. Además,
|
|
109
|
+
`orbital-ds-doctor --css src/brand.css` falla si el fichero usa una `--ds-*` que el paquete
|
|
110
|
+
ya no define, para que una renombrada no se ignore en silencio.
|
|
111
|
+
|
|
112
|
+
**Cambiar el color principal:** mueve juntas `primary`, `ring`, `link`, `brand`,
|
|
113
|
+
`sidebar-primary` y `chart-1`, y comprueba el contraste del texto sobre ellas. Nunca edites
|
|
114
|
+
el tema dentro de `node_modules` para personalizar una app.
|
|
115
|
+
|
|
77
116
|
## Reglas de nombres
|
|
78
117
|
|
|
79
118
|
- Todo en **inglés**: tokens, props y valores de variantes.
|
|
@@ -83,7 +122,7 @@ vuelven translúcidas.
|
|
|
83
122
|
- Un componente que necesite un hueco nuevo **añade el token** con un valor que deje
|
|
84
123
|
el aspecto como estaba; nunca escribe el valor en el componente.
|
|
85
124
|
|
|
86
|
-
## Qué comprueba `pnpm
|
|
125
|
+
## Qué comprueba `pnpm check:ds`
|
|
87
126
|
|
|
88
127
|
1. **Contrato**: cada tema define todos los tokens obligatorios.
|
|
89
128
|
2. **Repetidos**: ninguna variable se define dos veces en el mismo bloque.
|
|
@@ -99,7 +138,7 @@ También se puede pasar el CSS de una app: `orbital-ds-doctor --css src/styles.c
|
|
|
99
138
|
|
|
100
139
|
1. Copia `themes/qratia.css` (o `zyro.css`) a `themes/<nombre>.css`.
|
|
101
140
|
2. Cambia los valores; no quites ninguno.
|
|
102
|
-
3. `pnpm
|
|
141
|
+
3. `pnpm check:ds`: te dice qué falta.
|
|
103
142
|
4. Opcional: usa los materiales para dar cristal, relieve o un fondo propio.
|
|
104
143
|
|
|
105
144
|
Se puede partir de un tema de shadcn (por ejemplo exportado desde tweakcn): usa los
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "orbital-ds",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Sistema de diseño genérico: estructura común + temas
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"description": "Sistema de diseño genérico: estructura común + temas con personalidad (qratia, zyro) + ~60 componentes sobre Base UI y Tailwind v4, con contrato verificable y legible por agentes.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"design-system",
|
|
7
7
|
"design-tokens",
|
|
@@ -20,9 +20,13 @@
|
|
|
20
20
|
"dist",
|
|
21
21
|
"scripts/doctor.mjs",
|
|
22
22
|
"contract.json",
|
|
23
|
+
"components.manifest.json",
|
|
23
24
|
"docs",
|
|
25
|
+
"AGENTS.md",
|
|
24
26
|
"README.md",
|
|
25
|
-
"LICENSE"
|
|
27
|
+
"LICENSE",
|
|
28
|
+
"scripts/init.mjs",
|
|
29
|
+
"scripts/manifest.mjs"
|
|
26
30
|
],
|
|
27
31
|
"exports": {
|
|
28
32
|
"./styles.css": "./dist/styles.css",
|
|
@@ -40,14 +44,16 @@
|
|
|
40
44
|
"import": "./dist/hooks/*.js"
|
|
41
45
|
},
|
|
42
46
|
"./package.json": "./package.json",
|
|
43
|
-
"./contract.json": "./contract.json"
|
|
47
|
+
"./contract.json": "./contract.json",
|
|
48
|
+
"./components.manifest.json": "./components.manifest.json"
|
|
44
49
|
},
|
|
45
50
|
"scripts": {
|
|
46
|
-
"build": "tsup && node scripts/
|
|
51
|
+
"build": "tsup && node scripts/build-css.mjs",
|
|
47
52
|
"dev": "tsup --watch --onSuccess \"node scripts/copy-css.mjs\"",
|
|
48
53
|
"typecheck": "tsc --noEmit",
|
|
49
|
-
"verify": "pnpm
|
|
50
|
-
"
|
|
54
|
+
"verify": "pnpm check:ds && pnpm typecheck && pnpm build",
|
|
55
|
+
"manifest": "node scripts/manifest.mjs",
|
|
56
|
+
"check:ds": "node scripts/doctor.mjs"
|
|
51
57
|
},
|
|
52
58
|
"peerDependencies": {
|
|
53
59
|
"@base-ui/react": ">=1.9",
|
|
@@ -128,6 +134,7 @@
|
|
|
128
134
|
"react-resizable-panels": "^4.14.4"
|
|
129
135
|
},
|
|
130
136
|
"bin": {
|
|
131
|
-
"orbital-ds-doctor": "./scripts/doctor.mjs"
|
|
137
|
+
"orbital-ds-doctor": "./scripts/doctor.mjs",
|
|
138
|
+
"orbital-ds-init": "./scripts/init.mjs"
|
|
132
139
|
}
|
|
133
140
|
}
|