@higinio/design-mcp 0.2.0 → 0.2.1

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.
@@ -1,30 +1,27 @@
1
- /* ==========================================================================
2
- CELESTE CLÁSICA — Framework CSS v2.0
1
+ /* ============================================================
2
+ Celeste Clásica — Design Tokens v2.0
3
3
  Sistema de diseño de Higinio Sosa · light-first
4
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
- ========================================================================== */
5
+ Uso: importar ANTES de cualquier estilo propio.
6
+ Los componentes consumen SOLO aliases semánticos, nunca hex.
7
+ ============================================================ */
8
8
 
9
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
10
 
11
- /* --------------------------------------------------------------------------
12
- 1. TOKENS (§13)
13
- -------------------------------------------------------------------------- */
14
11
  :root {
15
- /* == Primitivos: primario == */
12
+ /* == Primitivos: primario (Azul Acero) == */
16
13
  --primary-50: #f2f6fa; --primary-100: #dfe9f2; --primary-200: #c3d5e6;
17
14
  --primary-300: #a0c0d4; --primary-400: #87a8c7; --primary-500: #7192ba;
18
15
  --primary-600: #5d7ba3; --primary-700: #4d6588; --primary-800: #40536e;
19
16
  --primary-900: #31343e;
20
17
 
21
- /* == Primitivos: neutrales == */
18
+ /* == Primitivos: neutrales (Gris Azulado) == */
22
19
  --neutral-0: #ffffff; --neutral-50: #f7f8fa; --neutral-100: #eef0f3;
23
20
  --neutral-200: #dcdfe5; --neutral-300: #b8bdc7; --neutral-400: #8a8f9c;
24
21
  --neutral-500: #666b78; --neutral-600: #4d5160; --neutral-700: #3d414e;
25
22
  --neutral-800: #31343e; --neutral-900: #22242b;
26
23
 
27
- /* == Primitivos: semánticos (ramp de 3) == */
24
+ /* == Primitivos: semánticos (ramp de 3: sólido / fondo / texto AA) == */
28
25
  --success-500: #3d9970; --success-100: #e2f3ec; --success-text: #2b6e50;
29
26
  --warning-500: #c9922e; --warning-100: #faf1de; --warning-text: #8a651c;
30
27
  --danger-500: #c04d4d; --danger-100: #f9e7e7; --danger-text: #8f3232;
@@ -47,10 +44,7 @@
47
44
  --accent-active: var(--primary-700);
48
45
  --accent-soft: var(--primary-50);
49
46
  --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;
47
+ --link: var(--primary-700); /* AA ~6:1 — texto de links y ghost; primary-500 solo para UI */
54
48
 
55
49
  /* == Tipografía == */
56
50
  --font-display: "Fraunces", Georgia, serif;
@@ -66,7 +60,7 @@
66
60
  --weight-regular: 400; --weight-medium: 500; --weight-semibold: 600; --weight-bold: 700;
67
61
  --measure: 65ch;
68
62
 
69
- /* == Espaciado == */
63
+ /* == Espaciado (escala base 4px) == */
70
64
  --space-1: 4px; --space-2: 8px; --space-3: 12px; --space-4: 16px;
71
65
  --space-5: 20px; --space-6: 24px; --space-8: 32px; --space-10: 40px;
72
66
  --space-12: 48px; --space-16: 64px; --space-20: 80px; --space-24: 96px;
@@ -76,7 +70,7 @@
76
70
  --control-height-sm: 36px; --control-height-md: 44px; --control-height-lg: 52px;
77
71
  --gutter: 24px; --gutter-mobile: 16px;
78
72
 
79
- /* == Radios, bordes y sombras == */
73
+ /* == Radios, bordes y sombras (teñidas de tinta, nunca negro puro) == */
80
74
  --radius-sm: 6px; --radius-md: 10px; --radius-lg: 14px;
81
75
  --radius-xl: 20px; --radius-full: 9999px;
82
76
  --border-width: 1px;
@@ -89,7 +83,6 @@
89
83
  /* == Focus == */
90
84
  --ring: 0 0 0 3px rgba(113,146,186,.25);
91
85
  --ring-color: rgba(113,146,186,.25);
92
- --ring-danger: 0 0 0 3px rgba(192,77,77,.22);
93
86
 
94
87
  /* == Motion == */
95
88
  --duration-instant: 100ms; --duration-fast: 150ms; --duration-base: 200ms;
@@ -98,11 +91,49 @@
98
91
  --ease-in: cubic-bezier(0.4, 0, 1, 1);
99
92
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1); /* moverse de A a B en pantalla */
100
93
  --ease-spring: cubic-bezier(0.34, 1.4, 0.64, 1);
94
+ --stagger-step: 30ms;
101
95
 
102
96
  color-scheme: light;
103
- }
104
97
 
105
- /* Modo oscuro (§15.6, extendido con aliases derivados) */
98
+ --overlay: rgba(49, 52, 62, .5);
99
+ --tooltip-bg: var(--neutral-900);
100
+ --tooltip-text: #ffffff;
101
+ --ring-danger: 0 0 0 3px rgba(192,77,77,.22);
102
+
103
+ --action-bg: var(--primary-700);
104
+ --action-hover: var(--primary-800);
105
+ --action-active: var(--primary-900);
106
+ --text-on-action: var(--text-on-primary);
107
+ --control-border: var(--neutral-400);
108
+ --placeholder: var(--text-muted);
109
+ --selection-bg: var(--action-bg);
110
+ --selection-text: var(--text-on-action);
111
+ --font-ui-heading: var(--font-body);
112
+ --text-ui-title: 2rem;
113
+ --touch-target: 44px;
114
+ --focus-color: var(--accent);
115
+ --text-display-fluid: clamp(2.75rem, 1.7rem + 3vw, 4.75rem);
116
+ --border-hover: var(--neutral-500);
117
+ --text-on-danger: #ffffff;
118
+
119
+ /* Series categóricas: orden estable; acompañar con etiqueta o forma. */
120
+ --chart-1: #4a8cc1;
121
+ --chart-2: #853f63;
122
+ --chart-3: #129a92;
123
+ --chart-4: #8e4031;
124
+ --chart-5: #5b975e;
125
+ --chart-6: #8a600a;
126
+ --chart-7: #857bc1;
127
+ /* Ritmo de contenido y formularios. */
128
+ --field-gap: 6px;
129
+ --heading-gap: var(--space-2);
130
+ --content-gap: var(--space-4);
131
+ --card-content-gap: var(--space-4);
132
+ --card-group-gap: var(--space-6);
133
+
134
+ }
135
+
136
+ /* == Modo oscuro (variante) — alternar data-theme en <html> == */
106
137
  [data-theme="dark"] {
107
138
  --bg: #16181e;
108
139
  --surface: #1d2028;
@@ -119,31 +150,58 @@
119
150
  --accent-soft: rgba(113,146,186,.12);
120
151
  --accent-soft-strong: rgba(113,146,186,.18);
121
152
  --text-on-primary: #16181e;
122
- --text-on-primary-solid: #a0c0d4;
123
153
  --link: #a0c0d4;
124
- --overlay: rgba(0, 0, 0, .6);
125
- --tooltip-bg: #e6e9ee;
126
- --tooltip-text: #31343e;
127
154
  --success-500: #5cbf93; --success-100: #12291f; --success-text: #7fd4ae;
128
155
  --warning-500: #e0ad4d; --warning-100: #2b2210; --warning-text: #ecc57e;
129
156
  --danger-500: #e07777; --danger-100: #2e1515; --danger-text: #eb9e9e;
130
157
  --info-500: #87a8c7; --info-100: #1a2430; --info-text: #a0c0d4;
131
158
  --ring: 0 0 0 3px rgba(160,192,212,.3);
132
- --ring-danger: 0 0 0 3px rgba(224,119,119,.25);
159
+ --ring-color: rgba(160,192,212,.3);
133
160
  --shadow-sm: 0 1px 2px rgba(0,0,0,.35);
134
161
  --shadow-md: 0 4px 12px rgba(0,0,0,.45);
135
162
  --shadow-lg: 0 12px 32px rgba(0,0,0,.55);
136
163
  color-scheme: dark;
164
+
165
+ --text-on-primary-solid: #a0c0d4;
166
+ --overlay: rgba(0, 0, 0, .6);
167
+ --tooltip-bg: #e6e9ee;
168
+ --tooltip-text: #31343e;
169
+ --ring-danger: 0 0 0 3px rgba(224,119,119,.25);
170
+
171
+ --selection-bg: var(--action-bg);
172
+ --selection-text: var(--text-on-action);
173
+ --action-bg: var(--accent);
174
+ --action-hover: var(--accent-hover);
175
+ --action-active: var(--accent-active);
176
+ --control-border: var(--text-muted);
177
+ --border-hover: var(--text-secondary);
178
+ --text-on-danger: #16181e;
179
+ --focus-color: var(--accent);
180
+
181
+ /* Series categóricas: orden estable; acompañar con etiqueta o forma. */
182
+ --chart-1: #5798ce;
183
+ --chart-2: #a0587c;
184
+ --chart-3: #2aa79e;
185
+ --chart-4: #aa5849;
186
+ --chart-5: #67a369;
187
+ --chart-6: #946a1c;
188
+ --chart-7: #877cc3;
189
+ }
190
+
191
+ /* == Accesibilidad del movimiento == */
192
+
193
+ @media (prefers-reduced-motion: reduce) {
194
+ :root {
195
+ --duration-instant: 0ms; --duration-fast: 0ms; --duration-base: 0ms;
196
+ --duration-slow: 0ms; --duration-page: 0ms; --stagger-step: 0ms;
197
+ }
137
198
  }
138
199
 
139
- /* --------------------------------------------------------------------------
140
- 2. BASE (§6, §11.5, §13)
141
- -------------------------------------------------------------------------- */
142
200
  *, *::before, *::after { box-sizing: border-box; }
143
201
 
144
202
  /* Focus ring global de teclado — especificidad cero vía :where() */
145
203
  :where(a, button, [role="button"], input, select, textarea, summary, [tabindex]):focus-visible {
146
- outline: 2px solid var(--primary-500);
204
+ outline: 2px solid var(--focus-color);
147
205
  outline-offset: 2px;
148
206
  border-radius: 2px;
149
207
  }
@@ -180,17 +238,10 @@
180
238
  .celeste-reset h6 { font-size: var(--text-base); line-height: var(--leading-base); }
181
239
  .celeste-reset p { max-width: var(--measure); margin: 0 0 1em; }
182
240
  .celeste-reset table { font-variant-numeric: tabular-nums; }
183
- .celeste-reset ::placeholder { color: var(--text-disabled); }
241
+ .celeste-reset ::placeholder { color: var(--placeholder); }
184
242
  .celeste-reset ::selection { background: rgba(113,146,186,.25); }
185
243
 
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
- }
244
+
194
245
 
195
246
  /* --------------------------------------------------------------------------
196
247
  3. LAYOUT — contenedor, grid 12 col (§14)
@@ -238,12 +289,12 @@
238
289
  /* Gating de hover (§11.5): los hover que mueven/elevan (transform, box-shadow) van
239
290
  dentro de @media (hover: hover) and (pointer: fine) — en touch el tap dispara
240
291
  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); }
292
+ .btn--primary { background: var(--action-bg); color: var(--text-on-action); }
293
+ .btn--primary:hover:not(:disabled) { background: var(--action-hover); }
243
294
  @media (hover: hover) and (pointer: fine) {
244
295
  .btn--primary:hover:not(:disabled) { box-shadow: var(--shadow-sm); }
245
296
  }
246
- .btn--primary:active:not(:disabled) { background: var(--accent-active); box-shadow: none; }
297
+ .btn--primary:active:not(:disabled) { background: var(--action-active); box-shadow: none; }
247
298
  .btn--primary:disabled { background: var(--border); color: var(--text-disabled); box-shadow: none; }
248
299
 
249
300
  .btn--secondary { background: var(--surface); border-color: var(--border-strong); color: var(--text-primary); }
@@ -261,7 +312,7 @@
261
312
  .btn--ghost:active:not(:disabled) { background: var(--accent-soft-strong); }
262
313
  .btn--ghost:disabled { background: var(--border); color: var(--text-disabled); }
263
314
 
264
- .btn--danger { background: var(--danger-500); color: #fff; }
315
+ .btn--danger { background: var(--danger-500); color: var(--text-on-danger); }
265
316
  .btn--danger:hover:not(:disabled) { background: color-mix(in srgb, var(--danger-500) 92%, #000); }
266
317
  .btn--danger:active:not(:disabled) { background: color-mix(in srgb, var(--danger-500) 86%, #000); }
267
318
  .btn--danger:disabled { opacity: .5; }
@@ -302,7 +353,7 @@
302
353
  .field { display: flex; flex-direction: column; gap: 6px; }
303
354
  .field__label { font-size: var(--text-sm); font-weight: var(--weight-medium); color: var(--text-secondary); }
304
355
  .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; }
356
+ .field__error { font-size: var(--text-sm); color: var(--danger-text); display: inline-flex; align-items: center; gap: 6px; }
306
357
  .field__error svg { width: 14px; height: 14px; flex: none; }
307
358
  /* Campo obligatorio (§10.4): asterisco decorativo; el input lleva required/aria-required */
308
359
  .field--required .field__label::after { content: " *"; color: var(--danger-500); }
@@ -310,14 +361,14 @@
310
361
  .input, .textarea, .select {
311
362
  width: 100%; font-family: var(--font-body); font-size: var(--text-base);
312
363
  color: var(--text-primary); background: var(--surface);
313
- border: var(--border-width) solid var(--border-strong); border-radius: var(--radius-sm);
364
+ border: var(--border-width) solid var(--control-border); border-radius: var(--radius-sm);
314
365
  transition: border-color var(--duration-fast) var(--ease-out),
315
366
  box-shadow var(--duration-fast) var(--ease-out);
316
367
  }
317
368
  .input, .select { height: var(--control-height-md); padding: 0 14px; }
318
369
  .input:hover:not(:disabled):not(:focus),
319
370
  .textarea:hover:not(:disabled):not(:focus),
320
- .select:hover:not(:disabled):not(:focus) { border-color: var(--text-disabled); }
371
+ .select:hover:not(:disabled):not(:focus) { border-color: var(--border-hover); }
321
372
  .input:focus, .textarea:focus, .select:focus {
322
373
  outline: none; border-color: var(--accent); box-shadow: var(--ring);
323
374
  }
@@ -371,7 +422,7 @@
371
422
  background: var(--surface); color: var(--text-primary);
372
423
  font-weight: var(--weight-semibold); box-shadow: var(--shadow-xs);
373
424
  }
374
- .segmented input:focus-visible + label { outline: 2px solid var(--primary-500); outline-offset: 2px; }
425
+ .segmented input:focus-visible + label { outline: 2px solid var(--focus-color); outline-offset: 2px; }
375
426
 
376
427
  .slider-row { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 10px; }
377
428
  .slider-row .slider-label { font-size: var(--text-sm); color: var(--text-secondary); }
@@ -408,7 +459,7 @@
408
459
  }
409
460
  .checkbox__box {
410
461
  width: 20px; height: 20px; flex: none; display: grid; place-items: center;
411
- background: var(--surface); border: 2px solid var(--border-strong); border-radius: 4px;
462
+ background: var(--surface); border: 2px solid var(--control-border); border-radius: 4px;
412
463
  transition: background-color var(--duration-fast) var(--ease-out),
413
464
  border-color var(--duration-fast) var(--ease-out);
414
465
  }
@@ -418,7 +469,7 @@
418
469
  stroke-dasharray: 20; stroke-dashoffset: 20;
419
470
  transition: stroke-dashoffset var(--duration-base) var(--ease-spring);
420
471
  }
421
- .checkbox:hover .checkbox__box { border-color: var(--primary-400); }
472
+ .checkbox:hover .checkbox__box { border-color: var(--focus-color); }
422
473
  .checkbox input:checked ~ .checkbox__box { background: var(--accent); border-color: var(--accent); }
423
474
  .checkbox input:checked ~ .checkbox__box svg { stroke-dashoffset: 0; }
424
475
  .checkbox input:focus-visible ~ .checkbox__box { box-shadow: var(--ring); }
@@ -435,7 +486,7 @@
435
486
 
436
487
  .radio__dot {
437
488
  width: 20px; height: 20px; flex: none; display: grid; place-items: center;
438
- background: var(--surface); border: 2px solid var(--border-strong); border-radius: var(--radius-full);
489
+ background: var(--surface); border: 2px solid var(--control-border); border-radius: var(--radius-full);
439
490
  transition: background-color var(--duration-fast) var(--ease-out),
440
491
  border-color var(--duration-fast) var(--ease-out);
441
492
  }
@@ -444,7 +495,7 @@
444
495
  background: var(--text-on-primary); transform: scale(0);
445
496
  transition: transform var(--duration-base) var(--ease-spring);
446
497
  }
447
- .radio:hover .radio__dot { border-color: var(--primary-400); }
498
+ .radio:hover .radio__dot { border-color: var(--focus-color); }
448
499
  .radio input:checked ~ .radio__dot { background: var(--accent); border-color: var(--accent); }
449
500
  .radio input:checked ~ .radio__dot::after { transform: scale(1); }
450
501
  .radio input:focus-visible ~ .radio__dot { box-shadow: var(--ring); }
@@ -774,10 +825,14 @@
774
825
  background: var(--surface); border: var(--border-width) solid var(--border);
775
826
  border-radius: var(--radius-md); box-shadow: var(--shadow-lg);
776
827
  opacity: 0; transform: translateY(-4px); pointer-events: none;
777
- transition: opacity 160ms var(--ease-out), transform 160ms var(--ease-out);
828
+ transition: opacity var(--duration-fast) var(--ease-out), transform var(--duration-fast) var(--ease-out);
829
+
830
+ visibility: hidden;
831
+
832
+ display: none;
778
833
  }
779
834
  .menu--right { left: auto; right: 0; }
780
- .menu.is-open { opacity: 1; transform: none; pointer-events: auto; }
835
+ .menu.is-open { opacity: 1; transform: none; pointer-events: auto; visibility: visible; display: block; }
781
836
  .menu__item {
782
837
  display: flex; align-items: center; gap: 10px; width: 100%;
783
838
  padding: 9px 12px; border: 0; border-radius: var(--radius-sm);
@@ -787,7 +842,7 @@
787
842
  }
788
843
  .menu__item:hover { background: var(--bg); }
789
844
  .menu__item svg { width: 16px; height: 16px; color: var(--text-muted); flex: none; }
790
- .menu__item--danger, .menu__item--danger svg { color: var(--danger-500); }
845
+ .menu__item--danger, .menu__item--danger svg { color: var(--danger-text); }
791
846
  .menu__item--danger:hover { background: var(--danger-100); }
792
847
  .menu__sep { height: var(--border-width); background: var(--border); margin: 6px 4px; }
793
848
 
@@ -879,7 +934,7 @@ button.metric-chip {
879
934
  }
880
935
  button.metric-chip:hover { background: var(--accent-soft); border-color: var(--accent); }
881
936
  button.metric-chip:active { background: var(--accent-soft-strong); transform: scale(.98); }
882
- button.metric-chip:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
937
+ button.metric-chip:focus-visible { outline: 2px solid var(--focus-color); outline-offset: 2px; }
883
938
 
884
939
  .pagination { display: flex; align-items: center; gap: 4px; list-style: none; padding: 0; margin: 0; }
885
940
  .pagination__btn {
@@ -1048,11 +1103,11 @@ button.metric-chip:focus-visible { outline: 2px solid var(--accent); outline-off
1048
1103
  width: 100%; height: var(--control-height-md); padding: 0 14px;
1049
1104
  font-family: var(--font-body); font-size: var(--text-base);
1050
1105
  color: var(--text-primary); background: var(--surface);
1051
- border: var(--border-width) solid var(--border-strong); border-radius: var(--radius-sm);
1106
+ border: var(--border-width) solid var(--control-border); border-radius: var(--radius-sm);
1052
1107
  transition: border-color var(--duration-fast) var(--ease-out),
1053
1108
  box-shadow var(--duration-fast) var(--ease-out);
1054
1109
  }
1055
- .combobox__input:hover:not(:disabled):not(:focus) { border-color: var(--text-disabled); }
1110
+ .combobox__input:hover:not(:disabled):not(:focus) { border-color: var(--border-hover); }
1056
1111
  .combobox__input:focus { outline: none; border-color: var(--accent); box-shadow: var(--ring); }
1057
1112
  .combobox__input:disabled { background: var(--surface-alt); color: var(--text-disabled); cursor: not-allowed; }
1058
1113
  .combobox__list {
@@ -1090,12 +1145,12 @@ button.metric-chip:focus-visible { outline: 2px solid var(--accent); outline-off
1090
1145
  width: 100%; height: var(--control-height-md); padding: 0 40px;
1091
1146
  font-family: var(--font-body); font-size: var(--text-base);
1092
1147
  color: var(--text-primary); background: var(--surface);
1093
- border: var(--border-width) solid var(--border-strong); border-radius: var(--radius-sm);
1148
+ border: var(--border-width) solid var(--control-border); border-radius: var(--radius-sm);
1094
1149
  transition: border-color var(--duration-fast) var(--ease-out),
1095
1150
  box-shadow var(--duration-fast) var(--ease-out);
1096
1151
  }
1097
1152
  .search__input::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }
1098
- .search__input:hover:not(:focus) { border-color: var(--text-disabled); }
1153
+ .search__input:hover:not(:focus) { border-color: var(--border-hover); }
1099
1154
  .search__input:focus { outline: none; border-color: var(--accent); box-shadow: var(--ring); }
1100
1155
  .search__clear {
1101
1156
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
@@ -1158,8 +1213,12 @@ button.metric-chip:focus-visible { outline: 2px solid var(--accent); outline-off
1158
1213
  transform-origin: top left; opacity: 0; transform: scale(.96); pointer-events: none;
1159
1214
  transition: opacity var(--duration-base) var(--ease-out),
1160
1215
  transform var(--duration-base) var(--ease-out);
1216
+
1217
+ visibility: hidden;
1218
+
1219
+ display: none;
1161
1220
  }
1162
- .popover.is-open .popover__panel { opacity: 1; transform: none; pointer-events: auto; }
1221
+ .popover.is-open .popover__panel { opacity: 1; transform: none; pointer-events: auto; visibility: visible; display: block; }
1163
1222
  .popover--right .popover__panel { left: auto; right: 0; transform-origin: top right; }
1164
1223
 
1165
1224
  /* ButtonGroup (§10.31) */
@@ -1184,11 +1243,11 @@ button.metric-chip:focus-visible { outline: 2px solid var(--accent); outline-off
1184
1243
  width: 100%; height: var(--control-height-md); padding: 0 40px 0 14px;
1185
1244
  font-family: var(--font-body); font-size: var(--text-base);
1186
1245
  color: var(--text-primary); background: var(--surface);
1187
- border: var(--border-width) solid var(--border-strong); border-radius: var(--radius-sm);
1246
+ border: var(--border-width) solid var(--control-border); border-radius: var(--radius-sm);
1188
1247
  transition: border-color var(--duration-fast) var(--ease-out),
1189
1248
  box-shadow var(--duration-fast) var(--ease-out);
1190
1249
  }
1191
- .datepicker__input:hover:not(:disabled):not(:focus) { border-color: var(--text-disabled); }
1250
+ .datepicker__input:hover:not(:disabled):not(:focus) { border-color: var(--border-hover); }
1192
1251
  .datepicker__input:focus { outline: none; border-color: var(--accent); box-shadow: var(--ring); }
1193
1252
  .datepicker__input:disabled { background: var(--surface-alt); color: var(--text-disabled); cursor: not-allowed; }
1194
1253
  .datepicker__icon {
@@ -1203,8 +1262,12 @@ button.metric-chip:focus-visible { outline: 2px solid var(--accent); outline-off
1203
1262
  transform-origin: top left; opacity: 0; transform: scale(.96); pointer-events: none;
1204
1263
  transition: opacity var(--duration-base) var(--ease-out),
1205
1264
  transform var(--duration-base) var(--ease-out);
1265
+
1266
+ visibility: hidden;
1267
+
1268
+ display: none;
1206
1269
  }
1207
- .datepicker.is-open .datepicker__calendar { opacity: 1; transform: none; pointer-events: auto; }
1270
+ .datepicker.is-open .datepicker__calendar { opacity: 1; transform: none; pointer-events: auto; visibility: visible; display: block; }
1208
1271
  .datepicker--right .datepicker__calendar { left: auto; right: 0; transform-origin: top right; }
1209
1272
 
1210
1273
  .calendar { width: 15.75rem; }
@@ -1349,3 +1412,168 @@ button.metric-chip:focus-visible { outline: 2px solid var(--accent); outline-off
1349
1412
  .u-mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
1350
1413
  .u-muted { color: var(--text-muted); }
1351
1414
  .u-measure { max-width: var(--measure); }
1415
+
1416
+ /* CONTRATOS COMPARTIDOS GENERADOS */
1417
+ /* Contratos comunes de interacción; la identidad y los valores viven en tokens.css. */
1418
+ .grid { grid-template-columns: repeat(12, minmax(0, 1fr)); }
1419
+ .grid > *, .field, .card { min-inline-size: 0; }
1420
+ .stack, .card__content, .form-stack, .text-group { display: flex; flex-direction: column; align-items: stretch; }
1421
+ .stack, .card__content { gap: var(--content-gap); }
1422
+ .stack--tight, .text-group { gap: var(--heading-gap); }
1423
+ .stack--cards { gap: var(--card-group-gap); }
1424
+ .form-stack { gap: var(--form-gap); }
1425
+ .cluster { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); }
1426
+ .card { display: flex; flex-direction: column; gap: var(--card-content-gap); }
1427
+ .field { gap: var(--field-gap); }
1428
+ .field__label, .field__help, .field__error, .field > :is(label, p, span, div) { margin-block: 0; }
1429
+ :where(.field + .field, .field + .btn, .field + .cluster) { margin-block-start: var(--form-gap); }
1430
+ :where(.card + .card) { margin-block-start: var(--card-group-gap); }
1431
+ .stack > *, .card__content > *, .form-stack > *, .text-group > *, .grid > .card,
1432
+ .card > :is(h1, h2, h3, h4, h5, h6, p), .text-group > :is(h1, h2, h3, h4, h5, h6, p),
1433
+ .stack > :is(h1, h2, h3, h4, h5, h6, p) { margin-block: 0; }
1434
+ .form-stack > .field { margin-block: 0; }
1435
+ .btn {
1436
+ block-size: auto;
1437
+ min-block-size: var(--control-height-md);
1438
+ max-inline-size: 100%;
1439
+ white-space: normal;
1440
+ line-height: 1.35;
1441
+ text-align: center;
1442
+ }
1443
+ .btn--sm { min-block-size: var(--control-height-sm, 36px); }
1444
+ .btn--lg { min-block-size: var(--control-height-lg, 52px); }
1445
+ .btn--primary, .icon-btn--primary, .calendar__day--selected, .pagination__btn.is-active {
1446
+ background: var(--action-bg);
1447
+ color: var(--text-on-action);
1448
+ }
1449
+ .btn--primary:hover:not(:disabled), .icon-btn--primary:hover:not(:disabled) { background: var(--action-hover); color: var(--text-on-action); }
1450
+ .btn--primary:active:not(:disabled), .icon-btn--primary:active:not(:disabled) { background: var(--action-active); color: var(--text-on-action); }
1451
+ .input, .textarea, .select, .combobox__input, .search__input, .datepicker__input {
1452
+ max-inline-size: 100%;
1453
+ caret-color: var(--focus-color);
1454
+ }
1455
+ .input, .select, .combobox__input, .search__input, .datepicker__input {
1456
+ block-size: auto; min-block-size: var(--control-height-md);
1457
+ padding-block: var(--space-2); line-height: 1.5;
1458
+ }
1459
+ :is(.input, .textarea, .select, .combobox__input, .search__input, .datepicker__input):not(.input--error, .input--success, .textarea--error, [aria-invalid="true"]) { border-color: var(--control-border); }
1460
+ .input:hover:not(:disabled):not(:focus):not(.input--error, .input--success, [aria-invalid="true"]), .textarea:hover:not(:disabled):not(:focus):not(.textarea--error, [aria-invalid="true"]),
1461
+ .select:hover:not(:disabled):not(:focus), .combobox__input:hover:not(:disabled):not(:focus),
1462
+ .search__input:hover:not(:focus), .datepicker__input:hover:not(:disabled):not(:focus) { border-color: var(--border-hover); }
1463
+ .input:focus-visible, .textarea:focus-visible, .select:focus-visible,
1464
+ .combobox__input:focus-visible, .search__input:focus-visible, .datepicker__input:focus-visible {
1465
+ outline: 2px solid var(--focus-color);
1466
+ outline-offset: 2px;
1467
+ }
1468
+ .input[aria-invalid="true"], .textarea[aria-invalid="true"] { border-color: var(--danger-text, var(--danger)); }
1469
+ .input.input--error, .textarea.textarea--error,
1470
+ .input.input--error:hover:not(:disabled):not(:focus), .textarea.textarea--error:hover:not(:disabled):not(:focus),
1471
+ :is(.input, .textarea, .select, .combobox__input, .search__input, .datepicker__input)[aria-invalid="true"]:hover:not(:disabled):not(:focus) {
1472
+ border-color: var(--danger-text, var(--danger));
1473
+ }
1474
+ .input.input--success, .input.input--success:hover:not(:disabled):not(:focus) { border-color: var(--success-text, var(--success)); }
1475
+ .pagination { max-inline-size: 100%; flex-wrap: wrap; row-gap: var(--space-2); }
1476
+ .pagination__ellipsis { color: var(--text-muted); }
1477
+ .step--current .step__marker { color: var(--link); border-color: var(--focus-color); }
1478
+ .checkbox input:focus-visible ~ .checkbox__box,
1479
+ .radio input:focus-visible ~ .radio__dot,
1480
+ .switch input:focus-visible ~ .switch__track {
1481
+ outline: 2px solid var(--focus-color);
1482
+ outline-offset: 2px;
1483
+ }
1484
+ input.checkbox, input.radio { border-color: var(--control-border); }
1485
+ input.checkbox:hover, input.radio:hover { border-color: var(--focus-color); }
1486
+ input.checkbox:checked, input.checkbox:indeterminate, input.radio:checked { border-color: var(--focus-color); }
1487
+ .switch__track { background: var(--control-border); }
1488
+ .tabs { max-inline-size: 100%; overflow-x: auto; }
1489
+ .tabs__tab { flex-shrink: 0; }
1490
+ .segmented { max-inline-size: 100%; block-size: auto; min-block-size: var(--control-height-md); overflow-x: auto; }
1491
+ .segmented label { padding-block: var(--space-2); }
1492
+ .stat__row, .breadcrumbs, .check-row { flex-wrap: wrap; row-gap: var(--space-2); }
1493
+ .progress-row, .slider-row { flex-wrap: wrap; gap: var(--space-2); }
1494
+ .stat__value { max-inline-size: 100%; white-space: normal; overflow-wrap: anywhere; }
1495
+ .file-upload, .file-upload__label { min-inline-size: 0; max-inline-size: 100%; }
1496
+ .file-upload__button { max-inline-size: 100%; white-space: normal; text-align: center; }
1497
+ .file-upload__hint { overflow-wrap: anywhere; }
1498
+ .table-scroll { max-inline-size: 100%; overflow-x: auto; overscroll-behavior-inline: contain; }
1499
+ .popover__panel, .datepicker__calendar, .combobox__list {
1500
+ max-inline-size: calc(100vw - 2rem);
1501
+ max-block-size: min(32rem, 70dvh);
1502
+ overflow: auto;
1503
+ }
1504
+ .file-upload__input:focus-visible + .file-upload__label { outline: 2px solid var(--focus-color); outline-offset: 2px; }
1505
+ .calendar { max-inline-size: calc(100vw - 2rem); }
1506
+ .ui-title, :is(h1, h2, h3, h4, h5, h6).ui-title, [data-mode="operate"] :is(h1, h2, h3) {
1507
+ font-family: var(--font-ui-heading);
1508
+ letter-spacing: 0;
1509
+ line-height: 1.3;
1510
+ font-weight: var(--weight-semibold);
1511
+ }
1512
+ .ui-title, :is(h1, h2, h3, h4, h5, h6).ui-title, [data-mode="operate"] h1 { font-size: var(--text-ui-title); }
1513
+ [data-mode="operate"] h2 { font-size: var(--text-xl); }
1514
+ [data-mode="operate"] h3 { font-size: var(--text-lg); }
1515
+ .display, .reading-title, :is(h1, h2, h3, h4, h5, h6):is(.display, .reading-title) {
1516
+ font-family: var(--font-display);
1517
+ font-size: var(--text-display-fluid);
1518
+ line-height: 1.08;
1519
+ letter-spacing: var(--tracking-display);
1520
+ text-wrap: balance;
1521
+ }
1522
+ :where(.celeste-reset, .salvia-reset, .bruma-reset, .nocturna-reset, body[data-system]) {
1523
+ scrollbar-color: var(--control-border) var(--bg);
1524
+ }
1525
+ ::selection,
1526
+ .celeste-reset ::selection, .salvia-reset ::selection, .bruma-reset ::selection {
1527
+ background: var(--selection-bg); color: var(--selection-text);
1528
+ }
1529
+ ::placeholder { color: var(--placeholder); opacity: 1; }
1530
+ :where(a) { text-underline-offset: .2em; text-decoration-thickness: .08em; }
1531
+ .skip-link {
1532
+ position: fixed; inset-block-start: var(--space-2); inset-inline-start: var(--space-2);
1533
+ z-index: 1000; padding: var(--space-3) var(--space-4);
1534
+ background: var(--action-bg); color: var(--text-on-action);
1535
+ border-radius: var(--radius-sm); transform: translateY(-180%);
1536
+ }
1537
+ .skip-link:focus { transform: none; outline: 2px solid var(--focus-color); outline-offset: 2px; }
1538
+ [data-tooltip]::before, [data-tooltip]::after { display: none; }
1539
+ [data-tooltip]:focus-visible::before, [data-tooltip]:focus-visible::after { display: block; }
1540
+ .has-tooltip .tooltip { display: none; }
1541
+ .has-tooltip:has(:focus-visible) .tooltip { display: block; opacity: 1; transform: translate(-50%, 0); }
1542
+ @media (hover: hover) and (pointer: fine) {
1543
+ [data-tooltip]:hover::before, [data-tooltip]:hover::after { display: block; }
1544
+ .has-tooltip:hover .tooltip { display: block; }
1545
+ }
1546
+ @media (pointer: coarse) {
1547
+ .btn, .icon-btn, .segmented label, .pagination button,
1548
+ .tag__close, .search__clear, .toast__close, .check-row,
1549
+ .checkbox:not(input), .radio:not(input), .switch:not(input) {
1550
+ min-block-size: var(--touch-target);
1551
+ min-inline-size: var(--touch-target);
1552
+ }
1553
+ }
1554
+ @media (max-width: 479px) {
1555
+ .btn-group { flex-wrap: wrap; }
1556
+ .modal { max-inline-size: calc(100vw - 2rem); }
1557
+ .stepper { flex-direction: column; align-items: stretch; gap: var(--space-4); }
1558
+ .step { flex-direction: row; align-items: center; gap: var(--space-3); text-align: start; min-inline-size: 0; }
1559
+ .step__label { overflow-wrap: anywhere; }
1560
+ .step__connector { display: none; }
1561
+ }
1562
+ @media (prefers-reduced-motion: reduce) {
1563
+ html, html:focus-within { scroll-behavior: auto; }
1564
+ .spinner, .skeleton, .skeleton::after,
1565
+ .progress--indeterminate .progress__bar, .alert.is-leaving, .toast.is-leaving { animation: none; }
1566
+ .progress--indeterminate .progress__bar { transform: none; }
1567
+ .btn, .icon-btn, .card--interactive, .slider::-webkit-slider-thumb { transform: none; }
1568
+ .btn:active:not(:disabled), .icon-btn:active:not(:disabled), .card--interactive:hover { transform: none; }
1569
+ .btn, .icon-btn { transition: background-color 80ms linear, color 80ms linear; }
1570
+ .menu, .popover__panel, .datepicker__calendar, .link::after { transition: none; }
1571
+ .progress__bar, .progress-ring__value, .accordion__content, .accordion__body { transition: none; }
1572
+ }
1573
+ @media (forced-colors: active) {
1574
+ input.switch, .switch__track { border: 1px solid CanvasText; background: Canvas; }
1575
+ input.switch::after, .switch__track::after { background: CanvasText; }
1576
+ input.switch:checked, .switch input:checked ~ .switch__track { border-color: Highlight; }
1577
+ input.switch:checked::after, .switch input:checked ~ .switch__track::after { background: Highlight; }
1578
+ .checkbox__box, .radio__dot { border-color: CanvasText; }
1579
+ }