@sfperusacdev/sf-ui 0.3.0 → 0.3.2

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.
Files changed (106) hide show
  1. package/dist/sf-ui.css +1 -1
  2. package/dist/sf-ui.js +4759 -2720
  3. package/dist/sf-ui.js.map +1 -1
  4. package/dist/sf-ui.umd.cjs +9 -8
  5. package/dist/sf-ui.umd.cjs.map +1 -1
  6. package/dist/theme/densidad.css +290 -0
  7. package/dist/theme/neon.css +185 -0
  8. package/dist/theme/temas.css +345 -0
  9. package/dist/types/src/components/cards/Badge.d.ts +7 -1
  10. package/dist/types/src/components/cards/MetricBar.caracterizacion.test.d.ts +1 -0
  11. package/dist/types/src/components/cards/MetricBar.d.ts +5 -3
  12. package/dist/types/src/components/cards/MetricBar.disposiciones.test.d.ts +1 -0
  13. package/dist/types/src/components/cards/ProfileCard.d.ts +27 -0
  14. package/dist/types/src/components/cards/ProfileCard.test.d.ts +1 -0
  15. package/dist/types/src/components/cards/QuoteCard.d.ts +11 -0
  16. package/dist/types/src/components/cards/QuoteCard.test.d.ts +1 -0
  17. package/dist/types/src/components/cards/index.d.ts +6 -2
  18. package/dist/types/src/components/cards/types.d.ts +19 -0
  19. package/dist/types/src/components/charts/Chart.colores.test.d.ts +1 -0
  20. package/dist/types/src/components/charts/Chart.d.ts +1 -1
  21. package/dist/types/src/components/charts/ChartLegend.caracterizacion.test.d.ts +1 -0
  22. package/dist/types/src/components/charts/ChartLegend.d.ts +22 -1
  23. package/dist/types/src/components/charts/index.d.ts +1 -1
  24. package/dist/types/src/components/charts/types.d.ts +5 -0
  25. package/dist/types/src/components/dashboard/DonutGauge.caracterizacion.test.d.ts +1 -0
  26. package/dist/types/src/components/dashboard/DonutGauge.d.ts +5 -1
  27. package/dist/types/src/components/dashboard/DonutGauge.degradado.test.d.ts +1 -0
  28. package/dist/types/src/components/dashboard/MetricTile.d.ts +24 -0
  29. package/dist/types/src/components/dashboard/MetricTile.sinDesborde.test.d.ts +1 -0
  30. package/dist/types/src/components/dashboard/MetricTile.test.d.ts +1 -0
  31. package/dist/types/src/components/dashboard/Seleccion.test.d.ts +1 -0
  32. package/dist/types/src/components/dashboard/StageFlow.caracterizacion.test.d.ts +1 -0
  33. package/dist/types/src/components/dashboard/StageFlow.d.ts +43 -0
  34. package/dist/types/src/components/dashboard/StageFlow.test.d.ts +1 -0
  35. package/dist/types/src/components/dashboard/StateChain.d.ts +28 -0
  36. package/dist/types/src/components/dashboard/StateChain.test.d.ts +1 -0
  37. package/dist/types/src/components/dashboard/StateChain.vertical.test.d.ts +1 -0
  38. package/dist/types/src/components/dashboard/Stepper.caracterizacion.test.d.ts +1 -0
  39. package/dist/types/src/components/dashboard/Stepper.d.ts +3 -1
  40. package/dist/types/src/components/dashboard/Stepper.icono.test.d.ts +1 -0
  41. package/dist/types/src/components/dashboard/index.d.ts +6 -0
  42. package/dist/types/src/components/dashboard/types.d.ts +4 -0
  43. package/dist/types/src/components/display/AuditTimeline.cadena.test.d.ts +1 -0
  44. package/dist/types/src/components/display/AuditTimeline.caracterizacion.test.d.ts +1 -0
  45. package/dist/types/src/components/display/AuditTimeline.d.ts +7 -1
  46. package/dist/types/src/components/display/CheckList.d.ts +19 -0
  47. package/dist/types/src/components/display/CheckList.srOnly.test.d.ts +1 -0
  48. package/dist/types/src/components/display/CheckList.test.d.ts +1 -0
  49. package/dist/types/src/components/display/MediaGallery.d.ts +41 -0
  50. package/dist/types/src/components/display/MediaGallery.test.d.ts +1 -0
  51. package/dist/types/src/components/display/MediaPanel.d.ts +4 -1
  52. package/dist/types/src/components/display/RecordList.caracterizacion.test.d.ts +1 -0
  53. package/dist/types/src/components/display/RecordList.compacta.test.d.ts +1 -0
  54. package/dist/types/src/components/display/RecordList.d.ts +15 -2
  55. package/dist/types/src/components/display/Timeline.caracterizacion.test.d.ts +1 -0
  56. package/dist/types/src/components/display/Timeline.columnas.test.d.ts +1 -0
  57. package/dist/types/src/components/display/Timeline.d.ts +22 -1
  58. package/dist/types/src/components/display/Timeline.horizontal.test.d.ts +1 -0
  59. package/dist/types/src/components/display/index.d.ts +8 -4
  60. package/dist/types/src/components/display/mediaGalleryFoco.d.ts +1 -0
  61. package/dist/types/src/components/display/mediaGalleryFoco.test.d.ts +1 -0
  62. package/dist/types/src/components/layout/AppShell.caracterizacion.test.d.ts +1 -0
  63. package/dist/types/src/components/layout/AppShell.d.ts +8 -2
  64. package/dist/types/src/components/layout/Tabs.caracterizacion.test.d.ts +1 -0
  65. package/dist/types/src/components/layout/Tabs.d.ts +5 -2
  66. package/dist/types/src/components/layout/Tabs.test.d.ts +1 -0
  67. package/dist/types/src/components/layout/ThemePicker.d.ts +23 -0
  68. package/dist/types/src/components/layout/ThemePicker.test.d.ts +1 -0
  69. package/dist/types/src/components/layout/WorkspaceHeader.d.ts +31 -0
  70. package/dist/types/src/components/layout/WorkspaceHeader.test.d.ts +1 -0
  71. package/dist/types/src/components/layout/index.d.ts +5 -1
  72. package/dist/types/src/components/overlays/Drawer.d.ts +5 -2
  73. package/dist/types/src/components/overlays/Foco.test.d.ts +1 -0
  74. package/dist/types/src/components/overlays/Modal.d.ts +4 -1
  75. package/dist/types/src/components/overlays/colorTexto.test.d.ts +1 -0
  76. package/dist/types/src/components/overlays/useFocoDeCapa.d.ts +8 -0
  77. package/dist/types/src/components/overlays/useOverlayStack.consulta.test.d.ts +1 -0
  78. package/dist/types/src/components/overlays/useOverlayStack.d.ts +10 -0
  79. package/dist/types/src/components/table/CustomTable.d.ts +14 -1
  80. package/dist/types/src/components/table/CustomTable.densidad.caracterizacion.test.d.ts +1 -0
  81. package/dist/types/src/components/table/CustomTable.densidad.test.d.ts +1 -0
  82. package/dist/types/src/components/table/index.d.ts +1 -1
  83. package/dist/types/src/components/visualization/IntegrationFlow.caracterizacion.test.d.ts +1 -0
  84. package/dist/types/src/components/visualization/IntegrationFlow.d.ts +61 -0
  85. package/dist/types/src/components/visualization/IntegrationFlow.paneles.test.d.ts +1 -0
  86. package/dist/types/src/components/visualization/IntegrationFlow.sinRecorte.test.d.ts +1 -0
  87. package/dist/types/src/components/visualization/IntegrationFlow.test.d.ts +1 -0
  88. package/dist/types/src/components/visualization/RelationGraph.caracterizacion.test.d.ts +1 -0
  89. package/dist/types/src/components/visualization/RelationGraph.d.ts +65 -0
  90. package/dist/types/src/components/visualization/RelationGraph.orbita.test.d.ts +1 -0
  91. package/dist/types/src/components/visualization/RelationGraph.test.d.ts +1 -0
  92. package/dist/types/src/components/visualization/SeleccionNodos.test.d.ts +1 -0
  93. package/dist/types/src/components/visualization/disponerOrbita.d.ts +29 -0
  94. package/dist/types/src/components/visualization/disponerRadial.d.ts +19 -0
  95. package/dist/types/src/components/visualization/index.d.ts +4 -0
  96. package/dist/types/src/theme/temas.test.d.ts +1 -0
  97. package/dist/types/src/utils/devWarning.d.ts +2 -0
  98. package/dist/types/src/utils/devWarning.test.d.ts +1 -0
  99. package/dist/types/src/utils/exportTableXlsx.d.ts +7 -1
  100. package/dist/types/src/utils/exportTableXlsx.notas.test.d.ts +1 -0
  101. package/dist/types/src/utils/foco.d.ts +9 -0
  102. package/dist/types/src/utils/identidadColeccion.d.ts +11 -0
  103. package/dist/types/src/utils/identidadColeccion.test.d.ts +1 -0
  104. package/dist/types/src/utils/useAnchoContenedor.d.ts +22 -0
  105. package/dist/types/src/utils/useAnchoContenedor.test.d.ts +1 -0
  106. package/package.json +5 -2
@@ -0,0 +1,345 @@
1
+ /**
2
+ * Temas intercambiables en tiempo de ejecución según el <html>: data-skin="sark|erp|neon" y data-theme="dark".
3
+ * Carga junto a sark.css, dark.css y neon.css. Sin data-skin nada de este archivo aplica.
4
+ * El bloque ERP claro repite las variables de erp.css: la prueba temas.test.ts falla si se separan.
5
+ */
6
+
7
+ /* —— ERP Systel claro (naranja + navy) —— */
8
+ :root[data-skin='erp']:not([data-theme='dark']) {
9
+ --sf-primary: rgb(12, 33, 49);
10
+ --sf-primary-muted: #46555c;
11
+ --sf-accent: #ec7211;
12
+ --sf-accent-hover: #d96510;
13
+ --sf-accent-10: rgb(236 114 17 / 0.1);
14
+
15
+ --sf-navy: rgb(12, 33, 49);
16
+ --sf-navy-muted: #64748b;
17
+ --sf-green: #ec7211;
18
+ --sf-green-mid: #d96510;
19
+
20
+ --sf-surface: #f1f3f4;
21
+ --sf-surface-alt: #f8fafc;
22
+ --sf-page-bg: #f0f4fa;
23
+
24
+ --sf-border: #d1d5db;
25
+ --sf-border-strong: #c7d5ce;
26
+ --sf-text: #374151;
27
+ --sf-text-muted: #6b7280;
28
+ --sf-label: #374151;
29
+
30
+ --sf-input-bg: #f8fafc;
31
+ --sf-input-bg-readonly: #f1f5f9;
32
+ --sf-input-border: #d1d5db;
33
+ --sf-input-border-focus: #ec7211;
34
+ --sf-input-text: #374151;
35
+ --sf-input-placeholder: #9ca3af;
36
+ --sf-input-font-size: 13px;
37
+
38
+ --sf-ring: rgb(236 114 17 / 0.18);
39
+ --sf-ring-focus: rgb(236 114 17 / 0.18);
40
+ --sf-ring-width: 3px;
41
+ --sf-ring-error: rgb(244 63 94 / 0.15);
42
+ --sf-input-border-error: #fb7185;
43
+
44
+ --sf-danger: #f05a25;
45
+ --sf-danger-bg: rgb(240 90 37 / 0.1);
46
+ --sf-row-hover: #f0f7ff;
47
+ --sf-row-selected: rgb(236 114 17 / 0.06);
48
+
49
+ --sf-btn-primary-bg: var(--sf-accent);
50
+ --sf-btn-primary-hover: var(--sf-accent-hover);
51
+ --sf-btn-primary-shadow: 0 4px 14px rgb(236 114 17 / 0.3);
52
+ --sf-btn-primary-shadow-hover: 0 6px 20px rgb(236 114 17 / 0.4);
53
+ --sf-btn-outline-border: rgb(236 114 17 / 0.4);
54
+ --sf-btn-outline-text: #ec7211;
55
+ --sf-btn-outline-hover-bg: rgb(236 114 17 / 0.08);
56
+
57
+ --sf-shadow-2: 0 1px 3px rgb(12 33 49 / 0.08), 0 1px 2px rgb(12 33 49 / 0.05);
58
+ --sf-shadow-4: 0 4px 16px rgb(12 33 49 / 0.08), 0 2px 6px rgb(12 33 49 / 0.04);
59
+ --sf-shadow-8: 0 10px 32px rgb(12 33 49 / 0.1), 0 4px 10px rgb(12 33 49 / 0.06);
60
+
61
+ --sf-modal-overlay: rgb(12 33 49 / 0.45);
62
+ --sf-card-border: var(--sf-border);
63
+ --sf-badge-primary-bg: var(--sf-accent);
64
+ --sf-badge-primary-dot: var(--sf-accent-hover);
65
+
66
+ --sf-table-header-bg: var(--sf-primary);
67
+ --sf-table-header-text: var(--sf-white);
68
+ --sf-table-header-border: color-mix(in srgb, var(--sf-primary) 82%, var(--sf-white));
69
+ --sf-modal-header-bg: var(--sf-primary);
70
+ --sf-modal-header-text: var(--sf-white);
71
+ --sf-modal-header-subtitle: var(--sf-app-shell-topbar-muted);
72
+ --sf-modal-header-icon-bg: var(--sf-app-shell-accent);
73
+ --sf-modal-footer-bg: var(--sf-surface-alt);
74
+ --sf-record-item-bg: var(--sf-white);
75
+ --sf-master-detail-panel-bg: var(--sf-white);
76
+ --sf-filter-bar-bg: var(--sf-white);
77
+ --sf-expandable-row-bg: var(--sf-white);
78
+ --sf-itinerary-map-bg: color-mix(in srgb, var(--sf-accent-10) 55%, var(--sf-white));
79
+ --sf-avatar-accent-bg: var(--sf-accent);
80
+ --sf-app-shell-nav-badge-bg: var(--sf-accent);
81
+ --sf-app-shell-nav-badge-text: var(--sf-white);
82
+ --sf-maestro-toolbar-bg: var(--sf-white);
83
+ --sf-live-status-bg: var(--sf-white);
84
+ --sf-passenger-onboard-bg: color-mix(in srgb, var(--sf-success) 10%, var(--sf-white));
85
+ }
86
+
87
+ /* —— Modo oscuro de cada tema: dark.css con el acento propio —— */
88
+ :root[data-theme='dark'][data-skin='erp'] {
89
+ --sf-accent: #f59a4a;
90
+ --sf-accent-hover: #ec7211;
91
+ --sf-accent-10: rgb(245 154 74 / 0.14);
92
+ --sf-input-border-focus: #f59a4a;
93
+ --sf-ring: rgb(245 154 74 / 0.28);
94
+ --sf-ring-focus: rgb(245 154 74 / 0.28);
95
+ --sf-btn-primary-bg: #f59a4a;
96
+ --sf-btn-primary-hover: #ec7211;
97
+ --sf-btn-primary-text: #1b1206;
98
+ --sf-btn-primary-shadow: 0 4px 14px rgb(245 154 74 / 0.25);
99
+ --sf-btn-outline-border: rgb(245 154 74 / 0.45);
100
+ --sf-btn-outline-text: #f59a4a;
101
+ --sf-btn-outline-hover-bg: rgb(245 154 74 / 0.12);
102
+ --sf-app-shell-accent: #f59a4a;
103
+ --sf-avatar-accent-bg: #f59a4a;
104
+ --sf-app-shell-nav-badge-bg: #f59a4a;
105
+ --sf-spinner-fill: #f59a4a;
106
+ }
107
+
108
+ :root[data-theme='dark'][data-skin='sark'] {
109
+ --sf-accent: #3dba6e;
110
+ --sf-accent-hover: #2e9e5b;
111
+ --sf-accent-10: rgb(61 186 110 / 0.14);
112
+ --sf-input-border-focus: #3dba6e;
113
+ --sf-ring: rgb(61 186 110 / 0.28);
114
+ --sf-ring-focus: rgb(61 186 110 / 0.28);
115
+ --sf-btn-primary-bg: #3dba6e;
116
+ --sf-btn-primary-hover: #2e9e5b;
117
+ --sf-btn-primary-text: #06150c;
118
+ --sf-btn-primary-shadow: 0 4px 14px rgb(61 186 110 / 0.25);
119
+ --sf-btn-outline-border: rgb(61 186 110 / 0.45);
120
+ --sf-btn-outline-text: #3dba6e;
121
+ --sf-btn-outline-hover-bg: rgb(61 186 110 / 0.12);
122
+ --sf-app-shell-accent: #3dba6e;
123
+ --sf-spinner-fill: #3dba6e;
124
+ }
125
+
126
+ /* —— Modo claro con cualquier tema: el texto pintado con un color de categoría se oscurece para leerse sobre
127
+ blanco (los colores de categoría están pensados para rellenos y para fondo oscuro). —— */
128
+ :root[data-skin]:not([data-theme='dark']) .sf-metric-tile__value {
129
+ color: color-mix(in srgb, var(--sf-metric-tile-value-color) 62%, #0b1f29);
130
+ }
131
+
132
+ :root[data-skin]:not([data-theme='dark']) .sf-metric-tile--centered .sf-metric-tile__icon,
133
+ :root[data-skin]:not([data-theme='dark']) .sf-metric-row__prefix {
134
+ filter: none;
135
+ }
136
+
137
+ :root[data-skin]:not([data-theme='dark']) .sf-metric-row__prefix {
138
+ color: color-mix(in srgb, var(--sf-metric-color, var(--sf-accent)) 62%, #0b1f29);
139
+ }
140
+
141
+ :root[data-skin]:not([data-theme='dark']) .sf-stage-flow--ring .sf-stage-flow__eyebrow {
142
+ color: color-mix(in srgb, var(--sf-stage-color) 45%, #0b1f29);
143
+ }
144
+
145
+ :root[data-skin]:not([data-theme='dark']) .sf-state-chain--dot .sf-state-chain__item--current .sf-state-chain__label {
146
+ color: color-mix(in srgb, var(--sf-state-color) 45%, #0b1f29);
147
+ }
148
+
149
+ /* Texto de acento y de categoría sobre blanco: verbo del grafo, etiqueta de la dona, numeración de baldosas, fechas. */
150
+ :root[data-skin]:not([data-theme='dark']) .sf-relation-graph--orbit .sf-relation-graph__relation {
151
+ color: color-mix(in srgb, var(--sf-relation-color) 40%, #0b1f29);
152
+ }
153
+
154
+ :root[data-skin]:not([data-theme='dark']) .sf-donut-gauge__label[style*="--sf-donut-label-color"] {
155
+ color: color-mix(in srgb, var(--sf-donut-label-color) 48%, #0b1f29);
156
+ }
157
+
158
+ /* Íconos de baldosa (procesados, en espera, validadas…): el centrado se oscurece como el texto; en el «leading», el
159
+ círculo de color lleva el ícono en blanco, así que es el círculo el que se oscurece. */
160
+ :root[data-skin]:not([data-theme='dark']) .sf-metric-tile--centered .sf-metric-tile__icon {
161
+ color: color-mix(in srgb, var(--sf-metric-tile-color) 50%, #0b1f29);
162
+ }
163
+
164
+ :root[data-skin]:not([data-theme='dark']) .sf-metric-tile--leading .sf-metric-tile__icon {
165
+ background: color-mix(in srgb, var(--sf-metric-tile-color) 55%, #0b1f29);
166
+ color: #ffffff;
167
+ }
168
+
169
+ :root[data-skin]:not([data-theme='dark']) .sf-metric-row__tile-icon {
170
+ border-color: color-mix(in srgb, var(--sf-metric-color, var(--sf-accent)) 60%, #0b1f29);
171
+ color: color-mix(in srgb, var(--sf-metric-color, var(--sf-accent)) 48%, #0b1f29);
172
+ }
173
+
174
+ /* Partes gráficas que deben distinguirse (3:1) sobre blanco: muestras de leyenda, rellenos de barra, puntos y
175
+ círculos de estado. Sus colores llegan en línea desde quien usa el componente, por eso se oscurecen con filtro. */
176
+ :root[data-skin]:not([data-theme='dark']) .sf-chart-legend__swatch {
177
+ filter: brightness(0.65) saturate(1.2);
178
+ }
179
+
180
+ :root[data-skin]:not([data-theme='dark']) .sf-metric-row__fill,
181
+ :root[data-skin]:not([data-theme='dark']) .sf-timeline__dot--custom {
182
+ filter: brightness(0.6) saturate(1.2);
183
+ }
184
+
185
+ :root[data-skin]:not([data-theme='dark']) .sf-state-chain--ring .sf-state-chain__circle {
186
+ border-color: color-mix(in srgb, var(--sf-state-color) 62%, #0b1f29);
187
+ }
188
+
189
+ :root[data-skin]:not([data-theme='dark']) .sf-state-chain--dot .sf-state-chain__circle {
190
+ background: color-mix(in srgb, var(--sf-state-color) 58%, #0b1f29);
191
+ }
192
+
193
+ /* ERP claro: el naranja publicado da 3:1 con texto blanco; en botones y texto de acento va un tono más profundo. */
194
+ :root[data-skin='erp']:not([data-theme='dark']) {
195
+ --sf-btn-primary-bg: #b35400;
196
+ --sf-btn-primary-hover: #9a4800;
197
+ --sf-btn-outline-text: #a94f00;
198
+ --sf-accent-text: #a94f00;
199
+ --sf-text-muted: #5f6876;
200
+ }
201
+
202
+ :root[data-skin='erp']:not([data-theme='dark']) .sf-timeline__time {
203
+ color: var(--sf-accent-text);
204
+ }
205
+
206
+ /* Página activa del paginador en claro: en classic, soft y neon el número va en blanco sobre el acento, y el de ERP
207
+ (#ec7211) o Neón (#0d9488) no llega a 4,5:1. premium y matrix tienen sus propios colores y no se tocan. */
208
+ :root[data-skin='erp']:not([data-theme='dark']) .sf-pagination--classic .sf-pagination__page--active,
209
+ :root[data-skin='erp']:not([data-theme='dark']) .sf-pagination--classic .sf-pagination__page--active:hover,
210
+ :root[data-skin='erp']:not([data-theme='dark']) .sf-pagination--soft .sf-pagination__page--active,
211
+ :root[data-skin='erp']:not([data-theme='dark']) .sf-pagination--soft .sf-pagination__page--active:hover,
212
+ :root[data-skin='erp']:not([data-theme='dark']) .sf-pagination--neon .sf-pagination__page--active,
213
+ :root[data-skin='erp']:not([data-theme='dark']) .sf-pagination--neon .sf-pagination__page--active:hover {
214
+ background: #b35400;
215
+ border-color: #b35400;
216
+ }
217
+
218
+ :root[data-skin='neon']:not([data-theme='dark']) .sf-pagination--classic .sf-pagination__page--active,
219
+ :root[data-skin='neon']:not([data-theme='dark']) .sf-pagination--classic .sf-pagination__page--active:hover,
220
+ :root[data-skin='neon']:not([data-theme='dark']) .sf-pagination--soft .sf-pagination__page--active,
221
+ :root[data-skin='neon']:not([data-theme='dark']) .sf-pagination--soft .sf-pagination__page--active:hover,
222
+ :root[data-skin='neon']:not([data-theme='dark']) .sf-pagination--neon .sf-pagination__page--active,
223
+ :root[data-skin='neon']:not([data-theme='dark']) .sf-pagination--neon .sf-pagination__page--active:hover {
224
+ background: #0f766e;
225
+ border-color: #0f766e;
226
+ }
227
+
228
+ /* —— Detalles y capas (medido en el prototipo ADN con capas-temas, 6 temas) ——
229
+ Botones de estado: el texto no sale de --sf-btn-primary-text, que en los oscuros es casi negro. */
230
+ :root[data-skin] .sf-btn--success {
231
+ background: #15803d;
232
+ color: #ffffff;
233
+ }
234
+
235
+ :root[data-skin] .sf-btn--success:hover:not(:disabled) {
236
+ background: #166534;
237
+ }
238
+
239
+ :root[data-skin] .sf-btn--danger-solid {
240
+ background: #b91c1c;
241
+ color: #ffffff;
242
+ }
243
+
244
+ :root[data-skin] .sf-btn--danger-solid:hover:not(:disabled) {
245
+ background: #991b1b;
246
+ }
247
+
248
+ /* Claro: rojo, acentos de aviso, asterisco y cierre de los avisos a 4,5:1 sobre blanco o su tinte. */
249
+ :root[data-skin]:not([data-theme='dark']) {
250
+ --sf-alert-info-accent: #1d4ed8;
251
+ --sf-alert-success-accent: #15803d;
252
+ --sf-alert-warning-accent: #b45309;
253
+ --sf-alert-danger-accent: #b91c1c;
254
+ }
255
+
256
+ :root[data-skin]:not([data-theme='dark']) .sf-btn--danger {
257
+ background: #ffffff;
258
+ color: #b91c1c;
259
+ }
260
+
261
+ :root[data-skin]:not([data-theme='dark']) .sf-field-required {
262
+ color: #b91c1c;
263
+ }
264
+
265
+ :root[data-skin]:not([data-theme='dark']) .sf-table thead th:not([class*='sf-table__th--']) {
266
+ color: #475569;
267
+ }
268
+
269
+ :root[data-skin]:not([data-theme='dark']) .sf-toast__close {
270
+ color: #475569;
271
+ }
272
+
273
+ :root[data-skin]:not([data-theme='dark']) .sf-toast--warning .sf-toast__icon {
274
+ color: #b45309;
275
+ }
276
+
277
+ /* El encabezado sin variante no tiene fondo propio: el subtítulo va sobre el blanco del modal, no sobre el marino. */
278
+ :root[data-skin]:not([data-theme='dark']) .sf-modal-header:not(.sf-modal-header--dark):not(.sf-modal-header--brand) .sf-modal-header__subtitle {
279
+ color: var(--sf-text-muted);
280
+ }
281
+
282
+ /* Oscuro: los mismos elementos con los tonos claros de su color, sobre el fondo pizarra o negro. */
283
+ :root[data-skin][data-theme='dark'] {
284
+ --sf-alert-info-accent: #60a5fa;
285
+ --sf-alert-success-accent: #4ade80;
286
+ --sf-alert-warning-accent: #fbbf24;
287
+ --sf-alert-danger-accent: #f87171;
288
+ }
289
+
290
+ :root[data-skin][data-theme='dark'] .sf-btn--danger {
291
+ background: transparent;
292
+ color: #f87171;
293
+ }
294
+
295
+ :root[data-skin][data-theme='dark'] .sf-field-required {
296
+ color: #f87171;
297
+ }
298
+
299
+ :root[data-skin][data-theme='dark'] .sf-table thead th:not([class*='sf-table__th--']) {
300
+ color: var(--sf-text-muted);
301
+ }
302
+
303
+ :root[data-skin][data-theme='dark'] .sf-badge--info:not(.sf-badge--solid) {
304
+ color: #93c5fd;
305
+ }
306
+
307
+ :root[data-skin][data-theme='dark'] .sf-toast__close {
308
+ color: var(--sf-text-muted);
309
+ }
310
+
311
+ /* Modo oscuro con cualquier tema: el texto pintado con un color de categoría se aclara para leerse sobre el fondo
312
+ pizarra o negro; el amarillo de advertencia suave y los rellenos de barra también suben de luz. */
313
+ :root[data-skin][data-theme='dark'] .sf-relation-graph--orbit .sf-relation-graph__relation {
314
+ color: color-mix(in srgb, var(--sf-relation-color) 65%, #ffffff);
315
+ }
316
+
317
+ :root[data-skin][data-theme='dark'] .sf-stage-flow--ring .sf-stage-flow__eyebrow {
318
+ color: color-mix(in srgb, var(--sf-stage-color) 70%, #ffffff);
319
+ }
320
+
321
+ :root[data-skin][data-theme='dark'] .sf-metric-row__prefix {
322
+ color: color-mix(in srgb, var(--sf-metric-color, var(--sf-accent)) 70%, #ffffff);
323
+ }
324
+
325
+ :root[data-skin][data-theme='dark'] .sf-badge--warning:not(.sf-badge--solid) {
326
+ color: #fbbf24;
327
+ }
328
+
329
+ :root[data-skin][data-theme='dark'] .sf-metric-row__fill {
330
+ filter: brightness(1.15);
331
+ }
332
+
333
+ /* Modo claro con cualquier tema: advertencia suave, contador de la campana y avatar sin foto a 4,5:1. */
334
+ :root[data-skin]:not([data-theme='dark']) {
335
+ --sf-avatar-text: var(--sf-text);
336
+ }
337
+
338
+ :root[data-skin]:not([data-theme='dark']) .sf-badge--warning:not(.sf-badge--solid) {
339
+ color: #92400e;
340
+ }
341
+
342
+ :root[data-skin]:not([data-theme='dark']) .sf-notification-bell__badge {
343
+ background: #15803d;
344
+ color: #ffffff;
345
+ }
@@ -10,5 +10,11 @@ export type BadgeProps = {
10
10
  /** Icono antes del label (`.sf-badge__icon`). Compatible con `dot`: si vienen ambos, primero el punto y
11
11
  * luego el icono. Solo aplica a `shape="pill"` (el círculo es de un solo carácter). */
12
12
  icon?: ReactNode;
13
+ /** "solid": relleno del color con texto claro y esquinas de 6px (estados en tablas densas). Por defecto
14
+ * "soft", el acabado publicado. */
15
+ appearance?: BadgeAppearance;
16
+ /** Color propio para estados sin variante (ej. un estado de un flujo propio). Gana sobre `variant`. */
17
+ color?: string;
13
18
  };
14
- export declare const Badge: ({ label, variant, dot, size, shape, className, icon, }: BadgeProps) => import('react').JSX.Element;
19
+ export type BadgeAppearance = "soft" | "solid";
20
+ export declare const Badge: ({ label, variant, dot, size, shape, className, icon, appearance, color, }: BadgeProps) => import('react').JSX.Element;
@@ -1,17 +1,19 @@
1
- import { MetricBarFootnote, MetricBarItem } from './types';
1
+ import { MetricBarFootnote, MetricBarItem, MetricBarLayout } from './types';
2
2
  type MetricBarRowProps = {
3
3
  item: MetricBarItem;
4
4
  small?: boolean;
5
+ layout?: MetricBarLayout;
5
6
  };
6
- export declare const MetricBarRow: ({ item, small }: MetricBarRowProps) => import('react').JSX.Element;
7
+ export declare const MetricBarRow: ({ item, small, layout }: MetricBarRowProps) => import('react').JSX.Element;
7
8
  type MetricBarListProps = {
8
9
  metrics: MetricBarItem[];
9
10
  small?: boolean;
11
+ layout?: MetricBarLayout;
10
12
  className?: string;
11
13
  /** Nota destacada debajo de las barras (ej. "56% con menos de 3 meses"), en una caja tintada.
12
14
  * Por defecto no se muestra nada (acabado actual). No es una conclusión calculada — el texto es
13
15
  * responsabilidad de quien arma los datos. */
14
16
  footnote?: MetricBarFootnote;
15
17
  };
16
- export declare const MetricBarList: ({ metrics, small, className, footnote }: MetricBarListProps) => import('react').JSX.Element;
18
+ export declare const MetricBarList: ({ metrics, small, layout, className, footnote }: MetricBarListProps) => import('react').JSX.Element;
17
19
  export {};
@@ -0,0 +1,27 @@
1
+ import { ReactNode } from 'react';
2
+ import { BadgeVariant } from './types';
3
+ export type ProfileCardFact = {
4
+ key: string;
5
+ icon?: ReactNode;
6
+ label: ReactNode;
7
+ };
8
+ export type ProfileCardProps = {
9
+ name: string;
10
+ role?: string;
11
+ /** Código visible de la persona (ej. su número de empleado). */
12
+ code?: string;
13
+ photoSrc?: string;
14
+ photoAlt?: string;
15
+ /** Estado superpuesto sobre la foto, abajo a la izquierda. */
16
+ status?: {
17
+ label: string;
18
+ variant?: BadgeVariant;
19
+ };
20
+ /** Con `onEdit` aparece el botón de lápiz sobre la foto. */
21
+ onEdit?: () => void;
22
+ editLabel?: string;
23
+ facts?: ProfileCardFact[];
24
+ quote?: ReactNode;
25
+ className?: string;
26
+ };
27
+ export declare const ProfileCard: ({ name, role, code, photoSrc, photoAlt, status, onEdit, editLabel, facts, quote, className, }: ProfileCardProps) => import('react').JSX.Element;
@@ -0,0 +1,11 @@
1
+ import { ReactNode } from 'react';
2
+ export type QuoteCardProps = {
3
+ quote: ReactNode;
4
+ author?: ReactNode;
5
+ /** Adorno decorativo abajo a la derecha (ej. una hoja). */
6
+ icon?: ReactNode;
7
+ /** Foto de fondo, oscurecida para que el texto se lea. */
8
+ backgroundSrc?: string;
9
+ className?: string;
10
+ };
11
+ export declare const QuoteCard: ({ quote, author, icon, backgroundSrc, className }: QuoteCardProps) => import('react').JSX.Element;
@@ -1,5 +1,5 @@
1
1
  export { Badge } from './Badge';
2
- export type { BadgeProps } from './Badge';
2
+ export type { BadgeAppearance, BadgeProps } from './Badge';
3
3
  export { badgeClassName, badgeDotClassName } from './badgeClassName';
4
4
  export { KPICard, KPIGrid } from './KPICard';
5
5
  export type { KPICardAccentTone, KPICardProgress, KPICardLayout, KPICardVariant, KPICardIconStyle, KPICardSize, KPICardDensity, KPICardTrendDirection, KPICardValueFormat, KPICardFormatOptions, KPICardSparkline, KPICardProps, } from './KPICard';
@@ -10,8 +10,12 @@ export type { QuickActionTileProps, QuickActionGridProps } from './QuickActionTi
10
10
  export { MetricBarRow, MetricBarList } from './MetricBar';
11
11
  export { EntityCard, EntityCardGrid } from './EntityCard';
12
12
  export type { EntityCardProps } from './EntityCard';
13
+ export { ProfileCard } from './ProfileCard';
14
+ export type { ProfileCardFact, ProfileCardProps } from './ProfileCard';
15
+ export { QuoteCard } from './QuoteCard';
16
+ export type { QuoteCardProps } from './QuoteCard';
13
17
  export { RecommendationCard } from './RecommendationCard';
14
18
  export type { RecommendationCardProps } from './RecommendationCard';
15
19
  export { ModuleCard, ModuleCardGrid } from './ModuleCard';
16
20
  export type { ModuleCardProps } from './ModuleCard';
17
- export type { BadgeVariant, BadgeSize, BadgeShape, MetricBarTone, MetricBarThresholds, MetricBarItem, MetricBarFootnote, SplitBarTone, SplitBarSegment, EntityCardStatus, EntityCardVariant, RecommendationPriority, RecommendationImpact, ModuleCardVariant, ModuleCardDensity, } from './types';
21
+ export type { BadgeVariant, BadgeSize, BadgeShape, MetricBarTone, MetricBarThresholds, MetricBarItem, MetricBarLayout, MetricBarFootnote, SplitBarTone, SplitBarSegment, EntityCardStatus, EntityCardVariant, RecommendationPriority, RecommendationImpact, ModuleCardVariant, ModuleCardDensity, } from './types';
@@ -1,3 +1,4 @@
1
+ import { ReactNode } from 'react';
1
2
  export type BadgeVariant = "neutral" | "primary" | "success" | "warning" | "danger" | "info";
2
3
  export type BadgeSize = "sm" | "md";
3
4
  export type BadgeShape = "pill" | "circle";
@@ -37,7 +38,25 @@ export type MetricBarItem = {
37
38
  /** Texto a mostrar a la derecha en vez del autogenerado (ej. un conteo real: "442"). NUNCA es lo que
38
39
  * dimensiona la barra — eso siempre es `value` (crudo si hay `max`, 0-100 si no lo hay). */
39
40
  valueLabel?: string;
41
+ /** Color CSS de categoría (ej. `categoryColor(i)`) para el relleno de la barra y el ícono. Gana sobre `tone` y
42
+ * `thresholds` solo en esas partes gráficas: etiqueta, descripción y valor siguen con los colores de texto del tema. */
43
+ color?: string;
44
+ /** Ícono decorativo antes de la etiqueta. */
45
+ icon?: ReactNode;
46
+ /** Texto debajo de la etiqueta (ej. "Quién es"). Parte línea; no se trunca. */
47
+ description?: ReactNode;
48
+ /** Texto corto antes de la etiqueta, en el color de la barra (ej. «01.»). Solo en las disposiciones `tile` e
49
+ * `inline`. */
50
+ prefix?: string;
51
+ /** Contenido tras el valor (ej. un ícono de estado). Solo en las disposiciones `tile` e `inline`. */
52
+ trailing?: ReactNode;
53
+ /** Solo en `tile` e `inline`: la fila es un botón. */
54
+ onClick?: () => void;
55
+ selected?: boolean;
40
56
  };
57
+ /** `default`: etiqueta y valor arriba, barra debajo (publicado). `tile`: baldosa con ícono en círculo, etiqueta,
58
+ * descripción y barra con el valor a su derecha. `inline`: etiqueta, barra gruesa y valor en una sola fila. */
59
+ export type MetricBarLayout = "default" | "tile" | "inline";
41
60
  export type MetricBarFootnote = {
42
61
  text: string;
43
62
  tone?: MetricBarTone;
@@ -1,3 +1,3 @@
1
1
  import { ChartProps } from './types';
2
2
  export type { ChartProps } from './types';
3
- export declare const Chart: ({ type, data, xKey, series, height, ariaLabel, emptyMessage, className, showGrid, showTooltip, showLegend, orientation, stacking, unit, yDomain, xAxisFormat, yAxisFormat, tooltipFormat, valueLabelFormat, showValueLabels, referenceLines, onDataPointClick, }: ChartProps) => import('react').JSX.Element;
3
+ export declare const Chart: ({ type, data, xKey, series, height, ariaLabel, emptyMessage, className, showGrid, showTooltip, showLegend, orientation, stacking, unit, yDomain, xAxisFormat, yAxisFormat, tooltipFormat, valueLabelFormat, showValueLabels, referenceLines, onDataPointClick, stackRadius, }: ChartProps) => import('react').JSX.Element;
@@ -1,14 +1,35 @@
1
+ import { ReactNode } from 'react';
1
2
  export type ChartLegendItem = {
3
+ /** Identidad del ítem, única en `items`. Por defecto, `label`. */
4
+ key?: string;
2
5
  label: string;
3
6
  /** Color CSS (token o hex), el mismo de la serie del gráfico. */
4
7
  color: string;
8
+ /** Cifra que acompaña al nombre (ej. "420.530" o "88%"). Sin ella, el ítem es solo muestra y nombre. */
9
+ value?: ReactNode;
10
+ /** Ícono decorativo en lugar de la muestra de color (ej. una verificación en los indicadores de calidad). */
11
+ icon?: ReactNode;
5
12
  };
13
+ export type ChartLegendOrientation = "inline" | "vertical";
6
14
  export type ChartLegendProps = {
7
15
  items: ChartLegendItem[];
16
+ /** "inline" (por defecto): una línea que parte entre ítems. "vertical": una fila por ítem con la cifra alineada a la
17
+ * derecha, para leyendas con valores (ej. 10 dimensiones junto a una dona). */
18
+ orientation?: ChartLegendOrientation;
19
+ /** Solo en vertical: 2 reparte los ítems en dos columnas (de arriba abajo, luego la derecha) que pasan a una cuando
20
+ * el ancho no alcanza. Por defecto 1. */
21
+ columns?: 1 | 2;
22
+ /** Con `columns={2}`: ancho mínimo de cada columna antes de pasar a una sola (longitud CSS). Por defecto 13rem. */
23
+ columnMinWidth?: string;
24
+ /** Forma de la muestra de color. Por defecto "square". */
25
+ swatchShape?: "square" | "circle";
26
+ /** Con `onSelect` cada ítem es un botón (aria-pressed según `selectedKey`); recibe `key ?? label`. */
27
+ onSelect?: (key: string) => void;
28
+ selectedKey?: string;
8
29
  className?: string;
9
30
  };
10
31
  /**
11
32
  * Leyenda compacta en una línea, para la cabecera de una tarjeta (`DashboardCard.headerAction`) cuando el gráfico va
12
33
  * con `showLegend={false}`: deja el alto del gráfico para los datos.
13
34
  */
14
- export declare const ChartLegend: ({ items, className }: ChartLegendProps) => import('react').JSX.Element;
35
+ export declare const ChartLegend: ({ items, orientation, columns, columnMinWidth, swatchShape, onSelect, selectedKey, className, }: ChartLegendProps) => import('react').JSX.Element;
@@ -1,7 +1,7 @@
1
1
  export { Chart } from './Chart';
2
2
  export type { ChartProps } from './Chart';
3
3
  export { ChartLegend } from './ChartLegend';
4
- export type { ChartLegendItem, ChartLegendProps } from './ChartLegend';
4
+ export type { ChartLegendItem, ChartLegendOrientation, ChartLegendProps } from './ChartLegend';
5
5
  export { Sparkline } from './Sparkline';
6
6
  export { DiagnosticRadar } from './DiagnosticRadar';
7
7
  export { DeviationBand } from './DeviationBand';
@@ -16,6 +16,9 @@ export type ChartSeries = {
16
16
  /** Id de grupo de apilado explícito, para mezclar series apiladas y sueltas en un mismo chart.
17
17
  * Si se omite y `stacking` es "stacked"/"stacked-100", todas las series comparten un solo stack. */
18
18
  stackId?: string;
19
+ /** Solo en `line`: un color por punto, en el orden de `data`. Los puntos toman su color y la línea pasa por ellos
20
+ * en degradado. */
21
+ pointColors?: string[];
19
22
  };
20
23
  export type ChartDataPoint = Record<string, string | number | null | undefined>;
21
24
  /** Formatea un valor numérico de un chart (eje, tooltip o label de barra). `key` es la key de la
@@ -67,6 +70,8 @@ export type BaseChartProps = {
67
70
  * (comportamiento de Recharts: no es un hit-test exacto de la barra/punto individual, es el punto
68
71
  * activo del eje de categorías en esa posición). `series` es la primera serie definida, como referencia. */
69
72
  onDataPointClick?: (point: ChartDataPoint, series: ChartSeries) => void;
73
+ /** Barras apiladas: "all" (por defecto) redondea cada tramo; "top" solo el extremo de la pila. */
74
+ stackRadius?: "all" | "top";
70
75
  };
71
76
  export type ChartProps = BaseChartProps & {
72
77
  type: ChartType;
@@ -14,9 +14,13 @@ export type DonutGaugeProps = {
14
14
  showValue?: boolean;
15
15
  /** Grosor del anillo. Se acota a un quinto del diámetro para que el centro siempre tenga hueco. */
16
16
  strokeWidth?: number;
17
+ /** Trazo en degradado del primer color al segundo (gana sobre `color` y los umbrales). */
18
+ gradient?: [string, string];
19
+ /** Color de la etiqueta bajo la dona (ej. una calificación en verde). */
20
+ labelColor?: string;
17
21
  className?: string;
18
22
  };
19
- export declare const DonutGauge: ({ value, label, sublabel, size, color, thresholds, inverse, showValue, strokeWidth, className, }: DonutGaugeProps) => import('react').JSX.Element;
23
+ export declare const DonutGauge: ({ value, label, sublabel, size, color, thresholds, inverse, showValue, strokeWidth, gradient, labelColor, className, }: DonutGaugeProps) => import('react').JSX.Element;
20
24
  export type DonutGaugeRowItem = Omit<DonutGaugeProps, "className">;
21
25
  type DonutGaugeRowProps = {
22
26
  gauges: DonutGaugeRowItem[];
@@ -0,0 +1,24 @@
1
+ import { ReactNode } from 'react';
2
+ export type MetricTileLayout = "leading" | "centered";
3
+ export type MetricTileProps = {
4
+ label: ReactNode;
5
+ value: ReactNode;
6
+ sublabel?: ReactNode;
7
+ /** Rótulo pequeño encima de todo (ej. «Estado actual»). */
8
+ eyebrow?: ReactNode;
9
+ icon?: ReactNode;
10
+ /** Color de categoría o de tono: tiñe el fondo, el borde y el ícono. Por defecto `--sf-accent`. */
11
+ color?: string;
12
+ /** Color de la cifra. Por defecto, en `leading` el mismo `color`; en `centered`, `--sf-success`. */
13
+ valueColor?: string;
14
+ /** `leading`: ícono a la izquierda, cifra arriba y etiqueta debajo. `centered`: ícono arriba, etiqueta y cifra
15
+ * centradas. */
16
+ layout?: MetricTileLayout;
17
+ /** Solo en `centered`: "value-first" pone la cifra antes de la etiqueta (ej. tipos de archivo). */
18
+ order?: "label-first" | "value-first";
19
+ /** Con `onClick` la baldosa es un botón (aria-pressed según `selected`). */
20
+ onClick?: () => void;
21
+ selected?: boolean;
22
+ className?: string;
23
+ };
24
+ export declare const MetricTile: ({ label, value, sublabel, eyebrow, icon, color, valueColor, layout, order, onClick, selected, className, }: MetricTileProps) => import('react').JSX.Element;