@higinio/design-mcp 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.
@@ -0,0 +1,914 @@
1
+ /* ==========================================================================
2
+ CELESTE CLÁSICA — Framework CSS v2.0
3
+ Sistema de diseño de Higinio Sosa · light-first
4
+ Fuente de verdad: DESIGN-celeste-clasica.md
5
+ Uso: enlazar este archivo antes de cualquier estilo propio y aplicar
6
+ la clase .celeste-reset al <body>. Tema: data-theme="light|dark" en <html>.
7
+ ========================================================================== */
8
+
9
+ @import url("https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght@0,9..144,600;0,9..144,700;1,9..144,600&family=Public+Sans:ital,wght@0,400;0,500;0,600;0,700;1,400&family=IBM+Plex+Mono:wght@400;500&display=swap");
10
+
11
+ /* --------------------------------------------------------------------------
12
+ 1. TOKENS (§13)
13
+ -------------------------------------------------------------------------- */
14
+ :root {
15
+ /* == Primitivos: primario == */
16
+ --primary-50: #f2f6fa; --primary-100: #dfe9f2; --primary-200: #c3d5e6;
17
+ --primary-300: #a0c0d4; --primary-400: #87a8c7; --primary-500: #7192ba;
18
+ --primary-600: #5d7ba3; --primary-700: #4d6588; --primary-800: #40536e;
19
+ --primary-900: #31343e;
20
+
21
+ /* == Primitivos: neutrales == */
22
+ --neutral-0: #ffffff; --neutral-50: #f7f8fa; --neutral-100: #eef0f3;
23
+ --neutral-200: #dcdfe5; --neutral-300: #b8bdc7; --neutral-400: #8a8f9c;
24
+ --neutral-500: #666b78; --neutral-600: #4d5160; --neutral-700: #3d414e;
25
+ --neutral-800: #31343e; --neutral-900: #22242b;
26
+
27
+ /* == Primitivos: semánticos (ramp de 3) == */
28
+ --success-500: #3d9970; --success-100: #e2f3ec; --success-text: #2b6e50;
29
+ --warning-500: #c9922e; --warning-100: #faf1de; --warning-text: #8a651c;
30
+ --danger-500: #c04d4d; --danger-100: #f9e7e7; --danger-text: #8f3232;
31
+ --info-500: #7192ba; --info-100: #dfe9f2; --info-text: #4d6588;
32
+
33
+ /* == Aliases semánticos (los componentes consumen SOLO esto) == */
34
+ --bg: var(--neutral-50);
35
+ --surface: var(--neutral-0);
36
+ --surface-alt: var(--neutral-100);
37
+ --border: var(--neutral-200);
38
+ --border-strong: var(--neutral-300);
39
+ --text-primary: var(--neutral-800);
40
+ --text-secondary: var(--neutral-600);
41
+ --text-muted: var(--neutral-500);
42
+ --text-disabled: var(--neutral-400);
43
+ --text-on-primary: #ffffff;
44
+ --text-on-primary-solid: var(--primary-700);
45
+ --accent: var(--primary-500);
46
+ --accent-hover: var(--primary-600);
47
+ --accent-active: var(--primary-700);
48
+ --accent-soft: var(--primary-50);
49
+ --accent-soft-strong: var(--primary-100);
50
+ --link: var(--primary-700);
51
+ --overlay: rgba(49, 52, 62, .5);
52
+ --tooltip-bg: var(--neutral-900);
53
+ --tooltip-text: #ffffff;
54
+
55
+ /* == Tipografía == */
56
+ --font-display: "Fraunces", Georgia, serif;
57
+ --font-body: "Public Sans", system-ui, -apple-system, sans-serif;
58
+ --font-mono: "IBM Plex Mono", ui-monospace, monospace;
59
+ --text-xs: .75rem; --text-sm: .875rem; --text-base: 1rem; --text-lg: 1.125rem;
60
+ --text-xl: 1.25rem; --text-2xl: 1.5625rem; --text-3xl: 1.9375rem;
61
+ --text-4xl: 2.4375rem; --text-5xl: 3.0625rem;
62
+ --leading-xs: 1.5; --leading-sm: 1.5; --leading-base: 1.6; --leading-lg: 1.55;
63
+ --leading-xl: 1.4; --leading-2xl: 1.3; --leading-3xl: 1.25;
64
+ --leading-4xl: 1.15; --leading-5xl: 1.1;
65
+ --tracking-display: -0.02em; --tracking-body: 0; --tracking-label: 0.04em;
66
+ --weight-regular: 400; --weight-medium: 500; --weight-semibold: 600; --weight-bold: 700;
67
+ --measure: 65ch;
68
+
69
+ /* == Espaciado == */
70
+ --space-1: 4px; --space-2: 8px; --space-3: 12px; --space-4: 16px;
71
+ --space-5: 20px; --space-6: 24px; --space-8: 32px; --space-10: 40px;
72
+ --space-12: 48px; --space-16: 64px; --space-20: 80px; --space-24: 96px;
73
+ --card-padding: var(--space-6); --card-padding-mobile: var(--space-4);
74
+ --section-gap: var(--space-16); --form-gap: var(--space-5);
75
+ --button-padding-md: 12px 20px; --button-padding-sm: 8px 14px;
76
+ --control-height-sm: 36px; --control-height-md: 44px; --control-height-lg: 52px;
77
+ --gutter: 24px; --gutter-mobile: 16px;
78
+
79
+ /* == Radios, bordes y sombras == */
80
+ --radius-sm: 6px; --radius-md: 10px; --radius-lg: 14px;
81
+ --radius-xl: 20px; --radius-full: 9999px;
82
+ --border-width: 1px;
83
+ --shadow-xs: 0 1px 2px rgba(49,52,62,.06);
84
+ --shadow-sm: 0 1px 3px rgba(49,52,62,.08), 0 1px 2px rgba(49,52,62,.05);
85
+ --shadow-md: 0 4px 8px rgba(49,52,62,.09), 0 2px 4px rgba(49,52,62,.05);
86
+ --shadow-lg: 0 12px 24px rgba(49,52,62,.12), 0 4px 8px rgba(49,52,62,.06);
87
+ --shadow-xl: 0 24px 48px rgba(49,52,62,.16);
88
+
89
+ /* == Focus == */
90
+ --ring: 0 0 0 3px rgba(113,146,186,.25);
91
+ --ring-color: rgba(113,146,186,.25);
92
+ --ring-danger: 0 0 0 3px rgba(192,77,77,.22);
93
+
94
+ /* == Motion == */
95
+ --duration-instant: 100ms; --duration-fast: 150ms; --duration-base: 200ms;
96
+ --duration-slow: 250ms; --duration-page: 320ms;
97
+ --ease-out: cubic-bezier(0.2, 0, 0, 1);
98
+ --ease-in: cubic-bezier(0.4, 0, 1, 1);
99
+ --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1); /* moverse de A a B en pantalla */
100
+ --ease-spring: cubic-bezier(0.34, 1.4, 0.64, 1);
101
+
102
+ color-scheme: light;
103
+ }
104
+
105
+ /* Modo oscuro (§15.6, extendido con aliases derivados) */
106
+ [data-theme="dark"] {
107
+ --bg: #16181e;
108
+ --surface: #1d2028;
109
+ --surface-alt: #252935;
110
+ --border: #3a3f4d;
111
+ --border-strong: #4a5060;
112
+ --text-primary: #e6e9ee;
113
+ --text-secondary: #b9bfcb;
114
+ --text-muted: #8b91a0;
115
+ --text-disabled: #6f7585;
116
+ --accent: #87a8c7;
117
+ --accent-hover: #a0c0d4;
118
+ --accent-active: #7192ba;
119
+ --accent-soft: rgba(113,146,186,.12);
120
+ --accent-soft-strong: rgba(113,146,186,.18);
121
+ --text-on-primary: #16181e;
122
+ --text-on-primary-solid: #a0c0d4;
123
+ --link: #a0c0d4;
124
+ --overlay: rgba(0, 0, 0, .6);
125
+ --tooltip-bg: #e6e9ee;
126
+ --tooltip-text: #31343e;
127
+ --success-500: #5cbf93; --success-100: #12291f; --success-text: #7fd4ae;
128
+ --warning-500: #e0ad4d; --warning-100: #2b2210; --warning-text: #ecc57e;
129
+ --danger-500: #e07777; --danger-100: #2e1515; --danger-text: #eb9e9e;
130
+ --info-500: #87a8c7; --info-100: #1a2430; --info-text: #a0c0d4;
131
+ --ring: 0 0 0 3px rgba(160,192,212,.3);
132
+ --ring-danger: 0 0 0 3px rgba(224,119,119,.25);
133
+ --shadow-sm: 0 1px 2px rgba(0,0,0,.35);
134
+ --shadow-md: 0 4px 12px rgba(0,0,0,.45);
135
+ --shadow-lg: 0 12px 32px rgba(0,0,0,.55);
136
+ color-scheme: dark;
137
+ }
138
+
139
+ /* --------------------------------------------------------------------------
140
+ 2. BASE (§6, §11.5, §13)
141
+ -------------------------------------------------------------------------- */
142
+ *, *::before, *::after { box-sizing: border-box; }
143
+
144
+ /* Focus ring global de teclado — especificidad cero vía :where() */
145
+ :where(a, button, [role="button"], input, select, textarea, summary, [tabindex]):focus-visible {
146
+ outline: 2px solid var(--primary-500);
147
+ outline-offset: 2px;
148
+ border-radius: 2px;
149
+ }
150
+
151
+ .celeste-reset {
152
+ margin: 0;
153
+ background: var(--bg);
154
+ color: var(--text-primary);
155
+ font-family: var(--font-body);
156
+ font-size: var(--text-base);
157
+ line-height: var(--leading-base);
158
+ letter-spacing: var(--tracking-body);
159
+ -webkit-font-smoothing: antialiased;
160
+ text-rendering: optimizeLegibility;
161
+ }
162
+ .celeste-reset h1, .celeste-reset h2 {
163
+ font-family: var(--font-display);
164
+ font-weight: var(--weight-bold);
165
+ letter-spacing: var(--tracking-display);
166
+ color: var(--text-primary);
167
+ margin: 0 0 .5em;
168
+ }
169
+ .celeste-reset h1 { font-size: var(--text-4xl); line-height: var(--leading-4xl); }
170
+ .celeste-reset h2 { font-size: var(--text-3xl); line-height: var(--leading-3xl); font-weight: var(--weight-semibold); }
171
+ .celeste-reset h3, .celeste-reset h4, .celeste-reset h5, .celeste-reset h6 {
172
+ font-family: var(--font-body);
173
+ font-weight: var(--weight-semibold);
174
+ color: var(--text-primary);
175
+ margin: 0 0 .5em;
176
+ }
177
+ .celeste-reset h3 { font-size: var(--text-2xl); line-height: var(--leading-2xl); }
178
+ .celeste-reset h4 { font-size: var(--text-xl); line-height: var(--leading-xl); }
179
+ .celeste-reset h5 { font-size: var(--text-lg); line-height: var(--leading-lg); }
180
+ .celeste-reset h6 { font-size: var(--text-base); line-height: var(--leading-base); }
181
+ .celeste-reset p { max-width: var(--measure); margin: 0 0 1em; }
182
+ .celeste-reset table { font-variant-numeric: tabular-nums; }
183
+ .celeste-reset ::placeholder { color: var(--text-disabled); }
184
+ .celeste-reset ::selection { background: rgba(113,146,186,.25); }
185
+
186
+ @media (prefers-reduced-motion: reduce) {
187
+ *, *::before, *::after {
188
+ animation-duration: 0.01ms !important;
189
+ animation-iteration-count: 1 !important;
190
+ transition-duration: 0.01ms !important;
191
+ scroll-behavior: auto !important;
192
+ }
193
+ }
194
+
195
+ /* --------------------------------------------------------------------------
196
+ 3. LAYOUT — contenedor, grid 12 col (§14)
197
+ -------------------------------------------------------------------------- */
198
+ .container { width: 100%; margin-inline: auto; padding-inline: var(--gutter-mobile); }
199
+ @media (min-width: 640px) { .container { padding-inline: var(--space-4); } }
200
+ @media (min-width: 768px) { .container { max-width: 720px; } }
201
+ @media (min-width: 1024px) { .container { max-width: 960px; } }
202
+ @media (min-width: 1280px) { .container { max-width: 1200px; } }
203
+
204
+ .grid { display: grid; grid-template-columns: repeat(12, 1fr); gap: var(--gutter-mobile); }
205
+ @media (min-width: 768px) { .grid { gap: var(--gutter); } }
206
+ .col-1{grid-column:span 1}.col-2{grid-column:span 2}.col-3{grid-column:span 3}
207
+ .col-4{grid-column:span 4}.col-5{grid-column:span 5}.col-6{grid-column:span 6}
208
+ .col-7{grid-column:span 7}.col-8{grid-column:span 8}.col-9{grid-column:span 9}
209
+ .col-10{grid-column:span 10}.col-11{grid-column:span 11}.col-12{grid-column:span 12}
210
+ @media (min-width: 768px) {
211
+ .col-md-3{grid-column:span 3}.col-md-4{grid-column:span 4}
212
+ .col-md-6{grid-column:span 6}.col-md-8{grid-column:span 8}.col-md-12{grid-column:span 12}
213
+ }
214
+ @media (min-width: 1024px) {
215
+ .col-lg-3{grid-column:span 3}.col-lg-4{grid-column:span 4}
216
+ .col-lg-6{grid-column:span 6}.col-lg-8{grid-column:span 8}.col-lg-12{grid-column:span 12}
217
+ }
218
+
219
+ /* --------------------------------------------------------------------------
220
+ 4. BOTONES (§10.1) · ICON BUTTON (§10.2) · SPINNER (§10.3)
221
+ -------------------------------------------------------------------------- */
222
+ .btn {
223
+ display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
224
+ height: var(--control-height-md); padding: var(--button-padding-md);
225
+ border: var(--border-width) solid transparent; border-radius: var(--radius-md);
226
+ font-family: var(--font-body); font-size: var(--text-base); font-weight: var(--weight-semibold);
227
+ line-height: 1; color: var(--text-primary); background: transparent;
228
+ cursor: pointer; text-decoration: none; white-space: nowrap; user-select: none;
229
+ transition: background-color var(--duration-fast) var(--ease-out),
230
+ border-color var(--duration-fast) var(--ease-out),
231
+ box-shadow var(--duration-fast) var(--ease-out),
232
+ transform var(--duration-instant) var(--ease-out);
233
+ }
234
+ .btn:active:not(:disabled) { transform: scale(.98); }
235
+ .btn:disabled { cursor: not-allowed; }
236
+ .btn svg { width: 20px; height: 20px; flex: none; }
237
+
238
+ /* Gating de hover (§11.5): los hover que mueven/elevan (transform, box-shadow) van
239
+ dentro de @media (hover: hover) and (pointer: fine) — en touch el tap dispara
240
+ hovers falsos que se quedan pegados. Los hover de solo color/fondo quedan fuera. */
241
+ .btn--primary { background: var(--accent); color: var(--text-on-primary); }
242
+ .btn--primary:hover:not(:disabled) { background: var(--accent-hover); }
243
+ @media (hover: hover) and (pointer: fine) {
244
+ .btn--primary:hover:not(:disabled) { box-shadow: var(--shadow-sm); }
245
+ }
246
+ .btn--primary:active:not(:disabled) { background: var(--accent-active); box-shadow: none; }
247
+ .btn--primary:disabled { background: var(--border); color: var(--text-disabled); box-shadow: none; }
248
+
249
+ .btn--secondary { background: var(--surface); border-color: var(--border-strong); color: var(--text-primary); }
250
+ .btn--secondary:hover:not(:disabled) { background: var(--bg); }
251
+ .btn--secondary:active:not(:disabled) { background: var(--surface-alt); }
252
+ .btn--secondary:disabled { opacity: .5; }
253
+
254
+ .btn--outline { background: transparent; border-color: var(--accent); color: var(--link); }
255
+ .btn--outline:hover:not(:disabled) { background: var(--accent-soft); border-color: var(--accent-hover); }
256
+ .btn--outline:active:not(:disabled) { background: var(--accent-soft-strong); }
257
+ .btn--outline:disabled { opacity: .5; }
258
+
259
+ .btn--ghost { color: var(--link); }
260
+ .btn--ghost:hover:not(:disabled) { background: var(--accent-soft); }
261
+ .btn--ghost:active:not(:disabled) { background: var(--accent-soft-strong); }
262
+ .btn--ghost:disabled { background: var(--border); color: var(--text-disabled); }
263
+
264
+ .btn--danger { background: var(--danger-500); color: #fff; }
265
+ .btn--danger:hover:not(:disabled) { background: color-mix(in srgb, var(--danger-500) 92%, #000); }
266
+ .btn--danger:active:not(:disabled) { background: color-mix(in srgb, var(--danger-500) 86%, #000); }
267
+ .btn--danger:disabled { opacity: .5; }
268
+
269
+ .btn--sm { height: var(--control-height-sm); padding: var(--button-padding-sm); font-size: var(--text-sm); }
270
+ .btn--lg { height: var(--control-height-lg); padding: 14px 24px; font-size: var(--text-lg); }
271
+
272
+ /* IconButton — requiere aria-label */
273
+ .icon-btn {
274
+ display: inline-grid; place-items: center;
275
+ width: 40px; height: 40px; padding: 0;
276
+ border: var(--border-width) solid transparent; border-radius: var(--radius-md);
277
+ background: transparent; color: var(--text-secondary); cursor: pointer;
278
+ transition: background-color var(--duration-fast) var(--ease-out),
279
+ border-color var(--duration-fast) var(--ease-out),
280
+ transform var(--duration-instant) var(--ease-out);
281
+ }
282
+ .icon-btn:active:not(:disabled) { transform: scale(.98); }
283
+ .icon-btn:disabled { opacity: .5; cursor: not-allowed; }
284
+ .icon-btn svg { width: 18px; height: 18px; }
285
+ .icon-btn--sm { width: 32px; height: 32px; } .icon-btn--sm svg { width: 16px; height: 16px; }
286
+ .icon-btn--lg { width: 48px; height: 48px; } .icon-btn--lg svg { width: 20px; height: 20px; }
287
+ .icon-btn--ghost:hover:not(:disabled) { background: var(--surface-alt); color: var(--text-primary); }
288
+ .icon-btn--primary { background: var(--accent); color: var(--text-on-primary); }
289
+ .icon-btn--primary:hover:not(:disabled) { background: var(--accent-hover); }
290
+ .icon-btn--secondary { background: var(--surface); border-color: var(--border-strong); }
291
+ .icon-btn--secondary:hover:not(:disabled) { background: var(--bg); }
292
+
293
+ /* Spinner */
294
+ .spinner { width: 16px; height: 16px; animation: cc-spin .8s linear infinite; color: var(--accent); }
295
+ .spinner circle { opacity: .25; }
296
+ .spinner path { opacity: 1; }
297
+ @keyframes cc-spin { to { transform: rotate(360deg); } }
298
+
299
+ /* --------------------------------------------------------------------------
300
+ 5. FORMULARIOS — field, input, textarea, select (§10.4–10.6)
301
+ -------------------------------------------------------------------------- */
302
+ .field { display: flex; flex-direction: column; gap: 6px; }
303
+ .field__label { font-size: var(--text-sm); font-weight: var(--weight-medium); color: var(--text-secondary); }
304
+ .field__help { font-size: var(--text-sm); color: var(--text-muted); }
305
+ .field__error { font-size: var(--text-sm); color: var(--danger-500); display: inline-flex; align-items: center; gap: 6px; }
306
+ .field__error svg { width: 14px; height: 14px; flex: none; }
307
+
308
+ .input, .textarea, .select {
309
+ width: 100%; font-family: var(--font-body); font-size: var(--text-base);
310
+ color: var(--text-primary); background: var(--surface);
311
+ border: var(--border-width) solid var(--border-strong); border-radius: var(--radius-sm);
312
+ transition: border-color var(--duration-fast) var(--ease-out),
313
+ box-shadow var(--duration-fast) var(--ease-out);
314
+ }
315
+ .input, .select { height: var(--control-height-md); padding: 0 14px; }
316
+ .input:hover:not(:disabled):not(:focus),
317
+ .textarea:hover:not(:disabled):not(:focus),
318
+ .select:hover:not(:disabled):not(:focus) { border-color: var(--text-disabled); }
319
+ .input:focus, .textarea:focus, .select:focus {
320
+ outline: none; border-color: var(--accent); box-shadow: var(--ring);
321
+ }
322
+ .input:disabled, .textarea:disabled, .select:disabled {
323
+ background: var(--surface-alt); color: var(--text-disabled); cursor: not-allowed;
324
+ }
325
+ .input--error, .input--error:focus, .textarea--error { border-color: var(--danger-500); box-shadow: var(--ring-danger); }
326
+ .input--success { border-color: var(--success-500); }
327
+
328
+ .input-icon { position: relative; }
329
+ .input-icon > svg {
330
+ position: absolute; left: 12px; top: 50%; transform: translateY(-50%);
331
+ width: 18px; height: 18px; color: var(--text-disabled); pointer-events: none;
332
+ }
333
+ .input-icon .input { padding-left: 40px; }
334
+
335
+ .textarea { min-height: 96px; padding: 12px 14px; resize: vertical; line-height: var(--leading-base); }
336
+ .textarea-counter { font-size: var(--text-xs); color: var(--text-disabled); text-align: right; }
337
+
338
+ .select-wrap { position: relative; }
339
+ .select { appearance: none; padding-right: 38px; cursor: pointer; }
340
+ .select-wrap::after {
341
+ content: ""; position: absolute; right: 14px; top: 50%;
342
+ width: 16px; height: 16px; transform: translateY(-50%);
343
+ background: currentColor; color: var(--text-muted); pointer-events: none;
344
+ -webkit-mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"/></svg>') center / contain no-repeat;
345
+ mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"/></svg>') center / contain no-repeat;
346
+ transition: transform var(--duration-base) var(--ease-out);
347
+ }
348
+
349
+ /* --------------------------------------------------------------------------
350
+ 6. SEGMENTED CONTROL (§10.7) · SLIDER (§10.8)
351
+ -------------------------------------------------------------------------- */
352
+ .segmented {
353
+ display: inline-flex; align-items: stretch;
354
+ background: var(--surface-alt); border-radius: var(--radius-md); padding: 3px;
355
+ height: 40px;
356
+ }
357
+ .segmented--sm { height: 32px; }
358
+ .segmented input { position: absolute; opacity: 0; pointer-events: none; }
359
+ .segmented label {
360
+ display: inline-flex; align-items: center; padding: 0 16px;
361
+ border-radius: calc(var(--radius-md) - 3px);
362
+ font-size: var(--text-sm); font-weight: var(--weight-medium); color: var(--text-secondary);
363
+ cursor: pointer; user-select: none; white-space: nowrap;
364
+ transition: background-color var(--duration-base) var(--ease-out),
365
+ color var(--duration-fast) var(--ease-out),
366
+ box-shadow var(--duration-base) var(--ease-out);
367
+ }
368
+ .segmented input:checked + label {
369
+ background: var(--surface); color: var(--text-primary);
370
+ font-weight: var(--weight-semibold); box-shadow: var(--shadow-xs);
371
+ }
372
+ .segmented input:focus-visible + label { outline: 2px solid var(--primary-500); outline-offset: 2px; }
373
+
374
+ .slider-row { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 10px; }
375
+ .slider-row .slider-label { font-size: var(--text-sm); color: var(--text-secondary); }
376
+ .slider-row .slider-value { font-family: var(--font-mono); font-size: var(--text-sm); color: var(--text-muted); }
377
+ .slider {
378
+ -webkit-appearance: none; appearance: none;
379
+ width: 100%; height: 6px; border-radius: var(--radius-full);
380
+ background: linear-gradient(to right, var(--accent) var(--slider-fill, 50%), var(--border) var(--slider-fill, 50%));
381
+ cursor: pointer;
382
+ }
383
+ .slider:disabled { opacity: .5; cursor: not-allowed; }
384
+ .slider::-webkit-slider-thumb {
385
+ -webkit-appearance: none; width: 18px; height: 18px; border-radius: 50%;
386
+ background: var(--surface); border: 2px solid var(--accent); box-shadow: var(--shadow-sm);
387
+ transition: transform var(--duration-instant) var(--ease-out);
388
+ }
389
+ .slider:active::-webkit-slider-thumb { transform: scale(1.15); }
390
+ .slider::-moz-range-thumb {
391
+ width: 14px; height: 14px; border-radius: 50%;
392
+ background: var(--surface); border: 2px solid var(--accent); box-shadow: var(--shadow-sm);
393
+ transition: transform var(--duration-instant) var(--ease-out);
394
+ }
395
+ .slider:active::-moz-range-thumb { transform: scale(1.15); }
396
+
397
+ /* --------------------------------------------------------------------------
398
+ 7. SELECCIÓN — checkbox, radio, switch (§10.9–10.10)
399
+ -------------------------------------------------------------------------- */
400
+ .checkbox, .radio {
401
+ display: inline-flex; align-items: center; gap: 10px;
402
+ font-size: var(--text-base); color: var(--text-primary); cursor: pointer; position: relative;
403
+ }
404
+ .checkbox input, .radio input, .switch input {
405
+ position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0;
406
+ }
407
+ .checkbox__box {
408
+ width: 20px; height: 20px; flex: none; display: grid; place-items: center;
409
+ background: var(--surface); border: 2px solid var(--border-strong); border-radius: 4px;
410
+ transition: background-color var(--duration-fast) var(--ease-out),
411
+ border-color var(--duration-fast) var(--ease-out);
412
+ }
413
+ .checkbox__box svg {
414
+ width: 12px; height: 12px; fill: none; stroke: var(--text-on-primary);
415
+ stroke-width: 3; stroke-linecap: round; stroke-linejoin: round;
416
+ stroke-dasharray: 20; stroke-dashoffset: 20;
417
+ transition: stroke-dashoffset var(--duration-base) var(--ease-spring);
418
+ }
419
+ .checkbox:hover .checkbox__box { border-color: var(--primary-400); }
420
+ .checkbox input:checked ~ .checkbox__box { background: var(--accent); border-color: var(--accent); }
421
+ .checkbox input:checked ~ .checkbox__box svg { stroke-dashoffset: 0; }
422
+ .checkbox input:focus-visible ~ .checkbox__box { box-shadow: var(--ring); }
423
+ .checkbox input:disabled ~ * { opacity: .5; cursor: not-allowed; }
424
+
425
+ .radio__dot {
426
+ width: 20px; height: 20px; flex: none; display: grid; place-items: center;
427
+ background: var(--surface); border: 2px solid var(--border-strong); border-radius: var(--radius-full);
428
+ transition: background-color var(--duration-fast) var(--ease-out),
429
+ border-color var(--duration-fast) var(--ease-out);
430
+ }
431
+ .radio__dot::after {
432
+ content: ""; width: 8px; height: 8px; border-radius: 50%;
433
+ background: var(--text-on-primary); transform: scale(0);
434
+ transition: transform var(--duration-base) var(--ease-spring);
435
+ }
436
+ .radio:hover .radio__dot { border-color: var(--primary-400); }
437
+ .radio input:checked ~ .radio__dot { background: var(--accent); border-color: var(--accent); }
438
+ .radio input:checked ~ .radio__dot::after { transform: scale(1); }
439
+ .radio input:focus-visible ~ .radio__dot { box-shadow: var(--ring); }
440
+
441
+ .switch { display: inline-flex; align-items: center; gap: 10px; cursor: pointer; position: relative; font-size: var(--text-base); }
442
+ .switch__track {
443
+ width: 44px; height: 24px; flex: none; border-radius: var(--radius-full);
444
+ background: var(--border-strong); position: relative;
445
+ transition: background-color var(--duration-base) var(--ease-out);
446
+ }
447
+ .switch__track::after {
448
+ content: ""; position: absolute; top: 2px; left: 2px;
449
+ width: 20px; height: 20px; border-radius: 50%;
450
+ background: var(--neutral-0); box-shadow: var(--shadow-xs);
451
+ transition: transform var(--duration-base) var(--ease-spring);
452
+ }
453
+ .switch input:checked ~ .switch__track { background: var(--accent); }
454
+ .switch input:checked ~ .switch__track::after { transform: translateX(20px); }
455
+ .switch input:focus-visible ~ .switch__track { box-shadow: var(--ring); }
456
+ .switch input:disabled ~ * { opacity: .5; cursor: not-allowed; }
457
+
458
+ /* --------------------------------------------------------------------------
459
+ 8. SUPERFICIES — card, badge, tag, avatar, divider, accordion (§10.11–10.14)
460
+ -------------------------------------------------------------------------- */
461
+ .card {
462
+ background: var(--surface); border: var(--border-width) solid var(--border);
463
+ border-radius: var(--radius-lg); padding: var(--card-padding);
464
+ box-shadow: var(--shadow-sm);
465
+ }
466
+ @media (max-width: 639px) { .card { padding: var(--card-padding-mobile); } }
467
+ .card--interactive {
468
+ cursor: pointer;
469
+ transition: transform var(--duration-base) var(--ease-out),
470
+ box-shadow var(--duration-base) var(--ease-out);
471
+ }
472
+ @media (hover: hover) and (pointer: fine) {
473
+ .card--interactive:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
474
+ }
475
+
476
+ .badge {
477
+ display: inline-flex; align-items: center; gap: 4px;
478
+ font-size: var(--text-xs); font-weight: var(--weight-medium);
479
+ padding: 2px 8px; border-radius: var(--radius-full);
480
+ background: var(--surface-alt); color: var(--text-secondary);
481
+ }
482
+ .badge svg { width: 12px; height: 12px; }
483
+ .badge--success { background: var(--success-100); color: var(--success-text); }
484
+ .badge--warning { background: var(--warning-100); color: var(--warning-text); }
485
+ .badge--danger { background: var(--danger-100); color: var(--danger-text); }
486
+ .badge--info { background: var(--info-100); color: var(--info-text); }
487
+
488
+ .tag {
489
+ display: inline-flex; align-items: center; gap: 6px;
490
+ font-size: var(--text-xs); font-weight: var(--weight-medium);
491
+ padding: 3px 6px 3px 10px; border-radius: var(--radius-full);
492
+ background: var(--surface-alt); color: var(--text-secondary);
493
+ border: var(--border-width) solid var(--border);
494
+ }
495
+ .tag__close {
496
+ display: grid; place-items: center; width: 16px; height: 16px;
497
+ border: 0; border-radius: 50%; background: transparent; color: inherit; cursor: pointer;
498
+ transition: background-color var(--duration-fast) var(--ease-out);
499
+ }
500
+ .tag__close:hover { background: var(--border); }
501
+ .tag__close svg { width: 10px; height: 10px; }
502
+
503
+ .avatar {
504
+ position: relative; display: inline-flex; flex: none;
505
+ width: 36px; height: 36px; font-size: 14px;
506
+ }
507
+ .avatar--sm { width: 28px; height: 28px; font-size: 12px; }
508
+ .avatar--lg { width: 48px; height: 48px; font-size: 18px; }
509
+ .avatar--xl { width: 64px; height: 64px; font-size: 24px; }
510
+ .avatar__img, .avatar__initials {
511
+ width: 100%; height: 100%; border-radius: var(--radius-full);
512
+ }
513
+ .avatar__img { object-fit: cover; }
514
+ .avatar__initials {
515
+ display: grid; place-items: center;
516
+ background: var(--accent-soft-strong); color: var(--text-on-primary-solid);
517
+ font-weight: var(--weight-semibold); text-transform: uppercase;
518
+ }
519
+ .avatar__dot {
520
+ position: absolute; right: 0; bottom: 0;
521
+ width: 28%; height: 28%; min-width: 8px; min-height: 8px;
522
+ border-radius: 50%; box-shadow: 0 0 0 2px var(--surface);
523
+ background: var(--neutral-300);
524
+ }
525
+ .avatar__dot--online { background: var(--success-500); }
526
+ .avatar__dot--busy { background: var(--danger-500); }
527
+ .avatar__dot--away { background: var(--warning-500); }
528
+
529
+ .divider { border: 0; border-top: var(--border-width) solid var(--border); margin: var(--space-4) 0; }
530
+ .divider--label {
531
+ display: flex; align-items: center; gap: 12px; border: 0; margin: var(--space-4) 0;
532
+ color: var(--text-muted); font-size: var(--text-xs); font-weight: var(--weight-medium);
533
+ text-transform: uppercase; letter-spacing: var(--tracking-label);
534
+ }
535
+ .divider--label::before, .divider--label::after {
536
+ content: ""; flex: 1; border-top: var(--border-width) solid var(--border);
537
+ }
538
+ .divider--vertical {
539
+ display: inline-block; align-self: stretch; width: var(--border-width);
540
+ background: var(--border); border: 0; margin: 0 var(--space-3);
541
+ }
542
+
543
+ .accordion {
544
+ border: var(--border-width) solid var(--border); border-radius: var(--radius-lg);
545
+ background: var(--surface); overflow: hidden;
546
+ }
547
+ .accordion__item + .accordion__item { border-top: var(--border-width) solid var(--border); }
548
+ .accordion__header {
549
+ display: flex; align-items: center; justify-content: space-between; gap: 12px;
550
+ width: 100%; padding: 16px 20px; border: 0; background: transparent;
551
+ font-family: var(--font-body); font-size: var(--text-base); font-weight: var(--weight-medium);
552
+ color: var(--text-primary); text-align: left; cursor: pointer;
553
+ transition: background-color var(--duration-fast) var(--ease-out);
554
+ }
555
+ .accordion__header:hover { background: var(--bg); }
556
+ .accordion__header svg {
557
+ width: 18px; height: 18px; flex: none; color: var(--text-muted);
558
+ transition: transform var(--duration-base) var(--ease-out);
559
+ }
560
+ .accordion__item.is-open .accordion__header svg { transform: rotate(180deg); }
561
+ .accordion__panel {
562
+ display: grid; grid-template-rows: 0fr;
563
+ transition: grid-template-rows var(--duration-slow) var(--ease-out);
564
+ }
565
+ .accordion__item.is-open .accordion__panel { grid-template-rows: 1fr; }
566
+ .accordion__panel > div { overflow: hidden; }
567
+ .accordion__content {
568
+ padding: 0 20px 16px; font-size: var(--text-sm); color: var(--text-secondary);
569
+ opacity: 0; transition: opacity var(--duration-slow) var(--ease-out);
570
+ }
571
+ .accordion__item.is-open .accordion__content { opacity: 1; }
572
+
573
+ /* --------------------------------------------------------------------------
574
+ 9. FEEDBACK — tooltip, alert, toast, progress, skeleton, empty state
575
+ (§10.15–10.18, §10.25)
576
+ -------------------------------------------------------------------------- */
577
+ [data-tooltip] { position: relative; }
578
+ [data-tooltip]::after {
579
+ content: attr(data-tooltip);
580
+ position: absolute; bottom: calc(100% + 8px); left: 50%;
581
+ transform: translate(-50%, 4px);
582
+ background: var(--tooltip-bg); color: var(--tooltip-text);
583
+ font-size: var(--text-xs); line-height: 1.4; white-space: nowrap;
584
+ padding: 6px 10px; border-radius: var(--radius-sm);
585
+ opacity: 0; pointer-events: none; z-index: 70;
586
+ transition: opacity var(--duration-fast) var(--ease-out) 0s,
587
+ transform var(--duration-fast) var(--ease-out) 0s;
588
+ }
589
+ [data-tooltip]::before {
590
+ content: ""; position: absolute; bottom: calc(100% + 2px); left: 50%;
591
+ transform: translate(-50%, 4px);
592
+ border: 6px solid transparent; border-top-color: var(--tooltip-bg); border-bottom: 0;
593
+ opacity: 0; pointer-events: none; z-index: 70;
594
+ transition: opacity var(--duration-fast) var(--ease-out) 0s,
595
+ transform var(--duration-fast) var(--ease-out) 0s;
596
+ }
597
+ [data-tooltip]:focus-visible::after, [data-tooltip]:focus-visible::before {
598
+ opacity: 1; transform: translate(-50%, 0); transition-delay: 400ms;
599
+ }
600
+ /* Tooltip por hover solo con puntero real — en touch quedaría pegado tras el tap */
601
+ @media (hover: hover) and (pointer: fine) {
602
+ [data-tooltip]:hover::after, [data-tooltip]:hover::before {
603
+ opacity: 1; transform: translate(-50%, 0); transition-delay: 400ms;
604
+ }
605
+ }
606
+
607
+ .alert {
608
+ display: flex; gap: 12px; align-items: flex-start;
609
+ padding: 14px 16px; border-radius: var(--radius-md); font-size: var(--text-sm);
610
+ }
611
+ .alert > svg { width: 20px; height: 20px; flex: none; margin-top: 1px; }
612
+ .alert__title { font-weight: var(--weight-semibold); margin: 0 0 2px; }
613
+ .alert__body { opacity: .92; margin: 0; }
614
+ .alert__close {
615
+ margin-left: auto; flex: none; display: grid; place-items: center;
616
+ width: 24px; height: 24px; border: 0; border-radius: var(--radius-sm);
617
+ background: transparent; color: inherit; cursor: pointer; opacity: .7;
618
+ }
619
+ .alert__close:hover { opacity: 1; }
620
+ .alert__close svg { width: 16px; height: 16px; }
621
+ .alert--info { background: var(--info-100); color: var(--info-text); }
622
+ .alert--info > svg { color: var(--info-500); }
623
+ .alert--success { background: var(--success-100); color: var(--success-text); }
624
+ .alert--success > svg { color: var(--success-500); }
625
+ .alert--warning { background: var(--warning-100); color: var(--warning-text); }
626
+ .alert--warning > svg { color: var(--warning-500); }
627
+ .alert--danger { background: var(--danger-100); color: var(--danger-text); }
628
+ .alert--danger > svg { color: var(--danger-500); }
629
+
630
+ .toast-stack {
631
+ position: fixed; top: 16px; right: 16px; z-index: 90;
632
+ display: flex; flex-direction: column; gap: 12px; align-items: flex-end;
633
+ }
634
+ @media (max-width: 639px) {
635
+ .toast-stack { right: 50%; transform: translateX(50%); align-items: center; }
636
+ }
637
+ .toast {
638
+ display: flex; gap: 12px; align-items: flex-start;
639
+ width: 360px; max-width: calc(100vw - 32px);
640
+ background: var(--surface); color: var(--text-primary);
641
+ border-left: 3px solid var(--info-500); border-radius: var(--radius-md);
642
+ box-shadow: var(--shadow-lg); padding: 14px 16px; font-size: var(--text-sm);
643
+ /* Entrada interrumpible (§11.2): transition + @starting-style, no @keyframes —
644
+ un keyframe no puede invertirse si el toast se apila o se descarta a mitad. */
645
+ opacity: 1; transform: none;
646
+ transition: opacity var(--duration-slow) var(--ease-out),
647
+ transform var(--duration-slow) var(--ease-out);
648
+ }
649
+ @starting-style {
650
+ .toast { opacity: 0; transform: translateX(24px); }
651
+ }
652
+ .toast.is-leaving { animation: cc-toast-out var(--duration-base) var(--ease-in) forwards; }
653
+ .toast > svg { width: 20px; height: 20px; flex: none; }
654
+ .toast--success { border-left-color: var(--success-500); } .toast--success > svg { color: var(--success-500); }
655
+ .toast--warning { border-left-color: var(--warning-500); } .toast--warning > svg { color: var(--warning-500); }
656
+ .toast--danger { border-left-color: var(--danger-500); } .toast--danger > svg { color: var(--danger-500); }
657
+ .toast--info { border-left-color: var(--info-500); } .toast--info > svg { color: var(--info-500); }
658
+ .toast__title { font-weight: var(--weight-semibold); margin: 0; }
659
+ .toast__body { color: var(--text-secondary); margin: 0; }
660
+ @keyframes cc-toast-out { to { opacity: 0; transform: translateX(24px); } }
661
+
662
+ .progress-row { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 8px; }
663
+ .progress-row .progress-label { font-size: var(--text-sm); color: var(--text-secondary); }
664
+ .progress-row .progress-value { font-family: var(--font-mono); font-size: var(--text-sm); color: var(--text-muted); }
665
+ .progress {
666
+ height: 8px; border-radius: var(--radius-full);
667
+ background: var(--surface-alt); overflow: hidden;
668
+ }
669
+ .progress__bar {
670
+ height: 100%; width: 0; border-radius: var(--radius-full);
671
+ background: var(--accent);
672
+ transition: width var(--duration-slow) var(--ease-out);
673
+ }
674
+ .progress__bar--success { background: var(--success-500); }
675
+ .progress__bar--warning { background: var(--warning-500); }
676
+ .progress__bar--danger { background: var(--danger-500); }
677
+
678
+ .progress-ring { display: inline-grid; place-items: center; position: relative; }
679
+ .progress-ring svg { transform: rotate(-90deg); }
680
+ .progress-ring__track { fill: none; stroke: var(--surface-alt); }
681
+ .progress-ring__bar {
682
+ fill: none; stroke: var(--accent); stroke-linecap: round;
683
+ transition: stroke-dashoffset var(--duration-slow) var(--ease-out);
684
+ }
685
+ .progress-ring__value {
686
+ position: absolute; font-family: var(--font-mono); color: var(--text-primary);
687
+ font-weight: var(--weight-medium);
688
+ }
689
+
690
+ .skeleton {
691
+ position: relative; overflow: hidden;
692
+ background: var(--surface-alt); border-radius: var(--radius-sm);
693
+ min-height: 12px;
694
+ }
695
+ .skeleton::after {
696
+ content: ""; position: absolute; inset: 0;
697
+ background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--surface) 80%, transparent), transparent);
698
+ transform: translateX(-100%);
699
+ animation: cc-shimmer 1.4s var(--ease-out) infinite;
700
+ }
701
+ @keyframes cc-shimmer { to { transform: translateX(100%); } }
702
+ .skeleton--circle { border-radius: var(--radius-full); }
703
+
704
+ .empty-state {
705
+ display: flex; flex-direction: column; align-items: center; text-align: center;
706
+ gap: var(--space-3); padding: var(--space-10) var(--space-6);
707
+ }
708
+ .empty-state > svg { width: 40px; height: 40px; color: var(--primary-300); }
709
+ .empty-state__title { font-size: var(--text-lg); font-weight: var(--weight-semibold); color: var(--text-primary); margin: 0; }
710
+ .empty-state__desc { font-size: var(--text-sm); color: var(--text-muted); max-width: 40ch; margin: 0; }
711
+
712
+ /* --------------------------------------------------------------------------
713
+ 10. OVERLAYS — modal, menu (§10.19–10.20)
714
+ -------------------------------------------------------------------------- */
715
+ .modal {
716
+ position: fixed; inset: 0; z-index: 100;
717
+ display: grid; place-items: center; padding: var(--space-4);
718
+ visibility: hidden;
719
+ }
720
+ .modal.is-open { visibility: visible; }
721
+ .modal__overlay {
722
+ position: absolute; inset: 0; background: var(--overlay);
723
+ opacity: 0; transition: opacity var(--duration-base) var(--ease-out);
724
+ }
725
+ .modal.is-open .modal__overlay { opacity: 1; }
726
+ .modal__panel {
727
+ position: relative; width: min(480px, 100%);
728
+ background: var(--surface); border-radius: var(--radius-lg);
729
+ box-shadow: var(--shadow-xl); padding: var(--card-padding);
730
+ opacity: 0; transform: scale(.96);
731
+ transition: opacity var(--duration-slow) var(--ease-out),
732
+ transform var(--duration-slow) var(--ease-out);
733
+ }
734
+ .modal.is-open .modal__panel { opacity: 1; transform: scale(1); }
735
+ .modal__panel--lg { width: min(640px, 100%); }
736
+ .modal__header {
737
+ display: flex; align-items: center; justify-content: space-between;
738
+ gap: var(--space-4); margin-bottom: var(--space-4);
739
+ }
740
+ .modal__title { font-size: var(--text-xl); font-weight: var(--weight-semibold); margin: 0; }
741
+ .modal__footer {
742
+ display: flex; justify-content: flex-end; gap: var(--space-3);
743
+ margin-top: var(--space-6);
744
+ }
745
+
746
+ .menu-wrap { position: relative; display: inline-block; }
747
+ .menu {
748
+ position: absolute; top: calc(100% + 6px); left: 0; z-index: 50;
749
+ min-width: 190px; padding: 6px;
750
+ background: var(--surface); border: var(--border-width) solid var(--border);
751
+ border-radius: var(--radius-md); box-shadow: var(--shadow-lg);
752
+ opacity: 0; transform: translateY(-4px); pointer-events: none;
753
+ transition: opacity 160ms var(--ease-out), transform 160ms var(--ease-out);
754
+ }
755
+ .menu--right { left: auto; right: 0; }
756
+ .menu.is-open { opacity: 1; transform: none; pointer-events: auto; }
757
+ .menu__item {
758
+ display: flex; align-items: center; gap: 10px; width: 100%;
759
+ padding: 9px 12px; border: 0; border-radius: var(--radius-sm);
760
+ background: transparent; font-family: var(--font-body); font-size: var(--text-sm);
761
+ color: var(--text-primary); text-align: left; cursor: pointer;
762
+ transition: background-color var(--duration-fast) var(--ease-out);
763
+ }
764
+ .menu__item:hover { background: var(--bg); }
765
+ .menu__item svg { width: 16px; height: 16px; color: var(--text-muted); flex: none; }
766
+ .menu__item--danger, .menu__item--danger svg { color: var(--danger-500); }
767
+ .menu__item--danger:hover { background: var(--danger-100); }
768
+ .menu__sep { height: var(--border-width); background: var(--border); margin: 6px 4px; }
769
+
770
+ /* --------------------------------------------------------------------------
771
+ 11. DATOS — tabla, stat, pagination (§10.21–10.23)
772
+ -------------------------------------------------------------------------- */
773
+ .table { width: 100%; border-collapse: collapse; font-size: var(--text-sm); font-variant-numeric: tabular-nums; }
774
+ .table thead th {
775
+ height: 40px; padding: 0 16px; text-align: left;
776
+ background: var(--bg); color: var(--text-muted);
777
+ font-size: var(--text-xs); font-weight: var(--weight-medium);
778
+ text-transform: uppercase; letter-spacing: var(--tracking-label);
779
+ border-bottom: var(--border-width) solid var(--border);
780
+ }
781
+ .table tbody td {
782
+ height: 52px; padding: 0 16px; color: var(--text-primary);
783
+ border-bottom: var(--border-width) solid var(--surface-alt);
784
+ }
785
+ .table tbody tr { transition: background-color var(--duration-fast) var(--ease-out); }
786
+ .table tbody tr:hover { background: var(--bg); }
787
+ .table tbody tr.is-selected { background: var(--accent-soft); }
788
+ .table .num, .table td.num, .table th.num { text-align: right; font-family: var(--font-mono); }
789
+
790
+ .stat__label {
791
+ display: inline-flex; align-items: center; gap: 8px; margin-bottom: 8px;
792
+ font-size: var(--text-sm); color: var(--text-muted);
793
+ }
794
+ .stat__label svg { width: 16px; height: 16px; }
795
+ .stat__row { display: flex; align-items: baseline; gap: 10px; }
796
+ .stat__value {
797
+ font-family: var(--font-mono); font-size: var(--text-3xl);
798
+ font-weight: var(--weight-semibold); color: var(--text-primary);
799
+ letter-spacing: -0.01em; line-height: 1;
800
+ }
801
+ .stat__delta {
802
+ display: inline-flex; align-items: center; gap: 4px;
803
+ font-size: var(--text-sm); font-weight: var(--weight-semibold);
804
+ color: var(--text-muted);
805
+ }
806
+ .stat__delta svg { width: 14px; height: 14px; }
807
+ .stat__delta--up { color: var(--success-text); }
808
+ .stat__delta--down { color: var(--danger-text); }
809
+
810
+ .pagination { display: flex; align-items: center; gap: 4px; list-style: none; padding: 0; margin: 0; }
811
+ .pagination__btn {
812
+ display: inline-grid; place-items: center;
813
+ min-width: 36px; height: 36px; padding: 0 8px;
814
+ border: 0; border-radius: var(--radius-sm); background: transparent;
815
+ font-family: var(--font-body); font-size: var(--text-sm); font-weight: var(--weight-medium);
816
+ color: var(--text-secondary); cursor: pointer;
817
+ transition: background-color var(--duration-fast) var(--ease-out);
818
+ }
819
+ .pagination__btn:hover:not(:disabled):not(.is-active) { background: var(--surface-alt); }
820
+ .pagination__btn.is-active {
821
+ background: var(--accent); color: var(--text-on-primary); font-weight: var(--weight-semibold);
822
+ }
823
+ .pagination__btn:disabled { color: var(--text-disabled); cursor: not-allowed; }
824
+ .pagination__btn svg { width: 16px; height: 16px; }
825
+ .pagination__ellipsis { color: var(--text-disabled); padding: 0 4px; user-select: none; }
826
+
827
+ /* --------------------------------------------------------------------------
828
+ 12. NAVEGACIÓN — navbar, sidebar, tabs, breadcrumbs (§10.24)
829
+ -------------------------------------------------------------------------- */
830
+ .navbar {
831
+ display: flex; align-items: center; gap: var(--space-8);
832
+ height: 64px; padding: 0 var(--space-6);
833
+ background: var(--surface); border-bottom: var(--border-width) solid var(--border);
834
+ }
835
+ .navbar__brand { font-family: var(--font-display); font-weight: var(--weight-bold); font-size: var(--text-lg); color: var(--text-primary); text-decoration: none; }
836
+ .navbar__nav { display: flex; align-items: stretch; gap: var(--space-6); height: 100%; }
837
+ .navbar__link {
838
+ position: relative; display: inline-flex; align-items: center;
839
+ font-size: var(--text-sm); font-weight: var(--weight-medium);
840
+ color: var(--text-secondary); text-decoration: none;
841
+ transition: color var(--duration-fast) var(--ease-out);
842
+ }
843
+ .navbar__link:hover { color: var(--text-primary); }
844
+ .navbar__link.is-active { color: var(--accent-active); }
845
+ .navbar__link.is-active::after {
846
+ content: ""; position: absolute; left: 0; right: 0; bottom: 0;
847
+ height: 2px; background: var(--accent);
848
+ }
849
+
850
+ .sidebar {
851
+ width: 260px; padding: var(--space-4);
852
+ background: var(--bg); border-right: var(--border-width) solid var(--border);
853
+ display: flex; flex-direction: column; gap: 2px;
854
+ }
855
+ .sidebar__item {
856
+ display: flex; align-items: center; gap: 10px;
857
+ padding: 10px 12px; border-radius: var(--radius-md);
858
+ font-size: var(--text-sm); font-weight: var(--weight-medium);
859
+ color: var(--text-secondary); text-decoration: none; border: 0; background: transparent;
860
+ cursor: pointer; text-align: left; width: 100%;
861
+ transition: background-color var(--duration-fast) var(--ease-out), color var(--duration-fast) var(--ease-out);
862
+ }
863
+ .sidebar__item svg { width: 18px; height: 18px; flex: none; }
864
+ .sidebar__item:hover { background: var(--surface-alt); color: var(--text-primary); }
865
+ .sidebar__item.is-active { background: var(--accent-soft-strong); color: var(--link); }
866
+ .sidebar__item.is-active svg { color: var(--accent); }
867
+
868
+ .tabs { display: flex; gap: var(--space-6); border-bottom: var(--border-width) solid var(--border); }
869
+ .tabs__tab {
870
+ padding: 12px 4px; margin-bottom: -1px;
871
+ border: 0; border-bottom: 2px solid transparent; background: transparent;
872
+ font-family: var(--font-body); font-size: var(--text-sm); font-weight: var(--weight-medium);
873
+ color: var(--text-secondary); cursor: pointer;
874
+ transition: color var(--duration-fast) var(--ease-out),
875
+ border-color var(--duration-slow) var(--ease-out);
876
+ }
877
+ .tabs__tab:hover { color: var(--text-primary); }
878
+ .tabs__tab.is-active { color: var(--accent-active); border-bottom-color: var(--accent); }
879
+
880
+ .breadcrumbs { display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-sm); color: var(--text-muted); }
881
+ .breadcrumbs a { color: var(--text-muted); text-decoration: none; transition: color var(--duration-fast) var(--ease-out); }
882
+ .breadcrumbs a:hover { color: var(--link); }
883
+ .breadcrumbs__sep { user-select: none; }
884
+ .breadcrumbs__current { color: var(--text-primary); }
885
+
886
+ /* --------------------------------------------------------------------------
887
+ 13. TIPOGRÁFICOS — link, code
888
+ -------------------------------------------------------------------------- */
889
+ .link {
890
+ color: var(--link); text-decoration: none;
891
+ background-image: linear-gradient(currentColor, currentColor);
892
+ background-size: 0% 1px; background-repeat: no-repeat; background-position: 0 100%;
893
+ transition: color var(--duration-fast) var(--ease-out),
894
+ background-size var(--duration-base) var(--ease-out);
895
+ }
896
+ .link:hover { background-size: 100% 1px; }
897
+
898
+ .code {
899
+ font-family: var(--font-mono); font-size: .9em;
900
+ background: var(--surface-alt); color: var(--text-primary);
901
+ border: var(--border-width) solid var(--border);
902
+ border-radius: var(--radius-sm); padding: 1px 6px;
903
+ }
904
+
905
+ /* --------------------------------------------------------------------------
906
+ 14. UTILIDADES MÍNIMAS
907
+ -------------------------------------------------------------------------- */
908
+ .u-visually-hidden {
909
+ position: absolute; width: 1px; height: 1px; margin: -1px;
910
+ clip-path: inset(50%); overflow: hidden; white-space: nowrap;
911
+ }
912
+ .u-mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
913
+ .u-muted { color: var(--text-muted); }
914
+ .u-measure { max-width: var(--measure); }