@ajuarezso/sui-design-system 0.24.1 → 0.25.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.
Files changed (120) hide show
  1. package/docs/sui-accordion/README.md +85 -11
  2. package/docs/sui-activity-feed/README.md +65 -11
  3. package/docs/sui-activity-filter/README.md +54 -5
  4. package/docs/sui-alert/README.md +54 -0
  5. package/docs/sui-app-store-badge/README.md +64 -10
  6. package/docs/sui-avatar/README.md +92 -29
  7. package/docs/sui-avatar-group/README.md +75 -9
  8. package/docs/sui-badge/README.md +85 -17
  9. package/docs/sui-banner/README.md +85 -20
  10. package/docs/sui-brand-logo/README.md +95 -31
  11. package/docs/sui-breadcrumb-item/README.md +54 -3
  12. package/docs/sui-breadcrumbs/README.md +54 -6
  13. package/docs/sui-button/README.md +76 -12
  14. package/docs/sui-button-group/README.md +91 -23
  15. package/docs/sui-button-group-item/README.md +81 -14
  16. package/docs/sui-card/README.md +105 -18
  17. package/docs/sui-chart-legend/README.md +63 -10
  18. package/docs/sui-chart-legend-dot/README.md +59 -10
  19. package/docs/sui-checkbox/README.md +109 -29
  20. package/docs/sui-checkbox-card/README.md +70 -14
  21. package/docs/sui-checkbox-label/README.md +92 -26
  22. package/docs/sui-circular-progress-bar/README.md +80 -19
  23. package/docs/sui-color-dot/README.md +72 -12
  24. package/docs/sui-color-picker/README.md +71 -13
  25. package/docs/sui-command-menu-footer/README.md +50 -1
  26. package/docs/sui-command-menu-item/README.md +74 -14
  27. package/docs/sui-command-menu-search/README.md +58 -3
  28. package/docs/sui-compact-avatar-group/README.md +73 -13
  29. package/docs/sui-compact-button/README.md +123 -34
  30. package/docs/sui-compact-select/README.md +61 -7
  31. package/docs/sui-compact-select-for-input/README.md +70 -6
  32. package/docs/sui-content-card/README.md +75 -14
  33. package/docs/sui-content-divider/README.md +67 -16
  34. package/docs/sui-content-label/README.md +99 -20
  35. package/docs/sui-counter-input/README.md +102 -18
  36. package/docs/sui-date-selector/README.md +69 -11
  37. package/docs/sui-datepicker/README.md +85 -18
  38. package/docs/sui-day-cell/README.md +75 -17
  39. package/docs/sui-day-label/README.md +56 -7
  40. package/docs/sui-divider/README.md +64 -9
  41. package/docs/sui-drawer-footer/README.md +63 -2
  42. package/docs/sui-drawer-header/README.md +69 -12
  43. package/docs/sui-dropdown-caption/README.md +58 -6
  44. package/docs/sui-dropdown-item/README.md +75 -9
  45. package/docs/sui-dropdown-menu/README.md +83 -14
  46. package/docs/sui-dropdown-search/README.md +60 -4
  47. package/docs/sui-emoji/README.md +94 -30
  48. package/docs/sui-empty-state/README.md +71 -7
  49. package/docs/sui-fancy-button/README.md +74 -14
  50. package/docs/sui-file-icon/README.md +70 -12
  51. package/docs/sui-file-upload/README.md +77 -17
  52. package/docs/sui-file-upload-card/README.md +64 -12
  53. package/docs/sui-filter/README.md +83 -14
  54. package/docs/sui-flag/README.md +73 -8
  55. package/docs/sui-form-hint/README.md +56 -7
  56. package/docs/sui-form-label/README.md +57 -5
  57. package/docs/sui-href/README.md +47 -0
  58. package/docs/sui-icon/README.md +86 -18
  59. package/docs/sui-image-upload/README.md +90 -22
  60. package/docs/sui-image-upload-profile/README.md +70 -11
  61. package/docs/sui-img-retry/README.md +50 -1
  62. package/docs/sui-inline-input/README.md +67 -9
  63. package/docs/sui-inline-select/README.md +62 -2
  64. package/docs/sui-input/README.md +90 -27
  65. package/docs/sui-integration-switch/README.md +84 -17
  66. package/docs/sui-kbd/README.md +73 -9
  67. package/docs/sui-key-icon/README.md +85 -23
  68. package/docs/sui-link-button/README.md +96 -27
  69. package/docs/sui-logo/README.md +93 -22
  70. package/docs/sui-modal/README.md +72 -13
  71. package/docs/sui-modal-footer/README.md +86 -12
  72. package/docs/sui-modal-header/README.md +57 -1
  73. package/docs/sui-modal-sheet/README.md +74 -12
  74. package/docs/sui-notification/README.md +81 -11
  75. package/docs/sui-notification-footer/README.md +55 -5
  76. package/docs/sui-notification-tab-menu/README.md +61 -5
  77. package/docs/sui-otp-input/README.md +70 -9
  78. package/docs/sui-page-header/README.md +89 -19
  79. package/docs/sui-pagination/README.md +73 -13
  80. package/docs/sui-password-strength/README.md +50 -1
  81. package/docs/sui-payment-icon/README.md +80 -18
  82. package/docs/sui-period-range/README.md +70 -11
  83. package/docs/sui-popover/README.md +81 -15
  84. package/docs/sui-product-card/README.md +89 -21
  85. package/docs/sui-progress-bar/README.md +82 -15
  86. package/docs/sui-progress-bar-label/README.md +79 -18
  87. package/docs/sui-radio/README.md +84 -7
  88. package/docs/sui-radio-card/README.md +70 -16
  89. package/docs/sui-radio-label/README.md +89 -22
  90. package/docs/sui-rating/README.md +101 -31
  91. package/docs/sui-rich-editor/README.md +47 -2
  92. package/docs/sui-segmented-control/README.md +90 -21
  93. package/docs/sui-select/README.md +80 -11
  94. package/docs/sui-sidebar/README.md +71 -16
  95. package/docs/sui-slider/README.md +75 -8
  96. package/docs/sui-social-button/README.md +71 -11
  97. package/docs/sui-status-badge/README.md +75 -14
  98. package/docs/sui-stepper/README.md +75 -18
  99. package/docs/sui-store-card/README.md +85 -22
  100. package/docs/sui-switch/README.md +82 -11
  101. package/docs/sui-switch-card/README.md +80 -16
  102. package/docs/sui-switch-label/README.md +91 -14
  103. package/docs/sui-tab-chips/README.md +93 -21
  104. package/docs/sui-tab-menu-horizontal/README.md +68 -7
  105. package/docs/sui-tab-menu-vertical/README.md +64 -11
  106. package/docs/sui-table/README.md +77 -16
  107. package/docs/sui-tag/README.md +86 -12
  108. package/docs/sui-tag-input/README.md +77 -13
  109. package/docs/sui-textarea/README.md +84 -17
  110. package/docs/sui-time-picker/README.md +96 -33
  111. package/docs/sui-toast/README.md +81 -20
  112. package/docs/sui-tooltip/README.md +80 -22
  113. package/docs/sui-topbar/README.md +64 -10
  114. package/docs/sui-topbar-button/README.md +61 -7
  115. package/docs/sui-topbar-item/README.md +68 -7
  116. package/docs/sui-topbar-user/README.md +61 -5
  117. package/fesm2022/ajuarezso-sui-design-system.mjs +15 -10
  118. package/fesm2022/ajuarezso-sui-design-system.mjs.map +1 -1
  119. package/package.json +1 -1
  120. package/types/ajuarezso-sui-design-system.d.ts +7 -3
@@ -47,57 +47,60 @@ atención de un local (L M M J V S D), filtros que se suman en una barra.
47
47
  | multi | cuándo | ejemplo de copy | fuente |
48
48
  |---|---|---|---|
49
49
  | `true` | Elegir días u opciones que se combinan. | L M M J V S D (días de atención) | canon (aprobado por el dueño, 03-10-2026) |
50
- | `false` (default) | No: elegir una sola o cambiar de vista va con `sui-segmented-control`. | — | cambiar de vista: canon (aprobado por el dueño, 03-10-2026) · elegir una sola en general: propuesta |
50
+ | `false` (default) | No: elegir una sola o cambiar de vista va con `sui-segmented-control`. | — | cambiar de vista: canon (aprobado por el dueño, 03-10-2026) · elegir una sola: canon (decisión del dueño 04-10-2026: 2–4 opciones excluyentes → `sui-segmented-control`; más opciones → `sui-tab-chips`) |
51
51
 
52
52
  ### `size`
53
53
 
54
54
  | size | alto | cuándo | fuente |
55
55
  |---|---|---|---|
56
56
  | `large` | 48 | Mobile: los días del horario y las opciones de un formulario, para tocar con el dedo. Label/Medium (16/24), ícono 20, radius 12. | canon (aprobado por el dueño, 03-10-2026) · extensión SUI |
57
- | `medium` | 40 | Mobile cuando la fila es larga (los 7 días) y `large` no entra en 360 px. Label/Small (14/20), ícono 20, radius 10. | alto y tipografía: canon (aprobado por el dueño, 03-10-2026), extensión SUI · cuándo: propuesta |
58
- | `small` (default) | 36 | Web: los días del horario, formularios. | escala según la guía del DS · cuándo: propuesta |
59
- | `xsmall` | 32 | Barras de filtros en desktop. | escala según la guía del DS · cuándo: propuesta |
60
- | `2xsmall` | 24 | Solo desktop, dentro de una tabla o una card densa. Muy chico para el dedo. | escala según la guía del DS · cuándo: propuesta |
57
+ | `medium` | 40 | Web: lo normal (días del horario, formularios, filtros, tablas). Mobile: cuando la fila es larga (los 7 días) y `large` no entra en 360 px. Label/Small (14/20), ícono 20, radius 10. | alto y tipografía: canon (aprobado por el dueño, 03-10-2026), extensión SUI · web: canon (dueño, 05-10-2026, D16) · mobile con la fila larga: propuesta |
58
+ | `small` (default) | 36 | No usar: es chico. En web va `medium`. | escala según la guía del DS · no usarlo: canon (dueño, 05-10-2026, D16), reemplaza el «cuándo» del bloque B1 |
59
+ | `xsmall` | 32 | No usar: es chico. Las barras de filtros van en `medium`. | escala según la guía del DS · no usarlo: canon (dueño, 05-10-2026, D16) |
60
+ | `2xsmall` | 24 | No usar: es chico. En una tabla o una card densa va `medium`. | escala según la guía del DS · no usarlo: canon (dueño, 05-10-2026, D16), reemplaza el «cuándo» del bloque B1 |
61
61
 
62
62
  ### `items` (lo que lleva cada opción)
63
63
 
64
64
  | contenido | cuándo | fuente |
65
65
  |---|---|---|
66
- | solo `label` | Lo normal: textos de una a tres letras o una palabra («L», «Delivery»). | propuesta |
67
- | `leftIcon` + `label` | Cuando el ícono ayuda a distinguir opciones parecidas (moto / bici / auto). | propuesta |
68
- | solo ícono (`leftIcon`, sin `label`) | Desktop, opciones universales; **`ariaLabel` obligatorio** en cada una. | propuesta |
69
- | `disabled: true` en una opción | La opción existe pero hoy no se puede elegir (un día que el local no atiende por regla). | propuesta |
66
+ | solo `label` | Lo normal: textos de una a tres letras o una palabra («L», «Delivery»). | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
67
+ | `leftIcon` + `label` | Cuando el ícono ayuda a distinguir opciones parecidas (moto / bici / auto). | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
68
+ | solo ícono (`leftIcon`, sin `label`) | Desktop, opciones universales; **`ariaLabel` obligatorio** en cada una. | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
69
+ | `disabled: true` en una opción | La opción existe pero hoy no se puede elegir (un día que el local no atiende por regla). | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
70
70
  | cuántas | De 2 a 7. Con más, no entra en el ancho del teléfono: lista de `sui-checkbox`. | propuesta (el Figma dibuja de 2 a 6; los días son 7) |
71
71
 
72
72
  ### `value`, `ariaLabel`, `change`
73
73
 
74
74
  | prop | cuándo | fuente |
75
75
  |---|---|---|
76
- | `[(value)]` | Con `multi`, un `string[]` con los `value` prendidos. | propuesta |
77
- | `ariaLabel` | Siempre: dice qué se elige («Días de atención»). El host es `role="group"`. | propuesta |
78
- | `(change)` | Cuando hay que reaccionar al cambio (guardar, filtrar); si alcanza con el `model`, no hace falta. | propuesta |
76
+ | `[(value)]` | Con `multi`, un `string[]` con los `value` prendidos. | según el código |
77
+ | `ariaLabel` | Siempre: dice qué se elige («Días de atención»). El host es `role="group"`. | según el código |
78
+ | `(change)` | Cuando hay que reaccionar al cambio (guardar, filtrar); si alcanza con el `model`, no hace falta. | según el código |
79
79
 
80
80
  ## Tamaño en mobile y en web
81
81
 
82
- En mobile se toca con el dedo: el área táctil tiene que medir **44 px o más**. En web, con mouse,
83
- va un tamaño más chico. La app ya lo resuelve con `BreakpointsService`
84
- (`src/app/services/breakpoints.service.ts`, mobile = hasta 767 px):
85
- `[size]="bp.isMobile() ? 'large' : 'small'"`. Medido el 04-10-2026 en `master-pedidos`: 166 `[size]`
86
- con `bp` (142 `large`/`medium`, 22 `large`/`small`, 2 `medium`/`xsmall`). Regla del dueño, 03-10-2026.
82
+ En mobile se toca con el dedo: el área táctil tiene que medir **44 px o más**. En la tablet
83
+ (`pointer: coarse`) va igual que en el celular, porque también se toca; en la computadora
84
+ (`pointer: fine`), `medium`; en el celular chico (< 380 px), `medium` a la vista sin bajar el área de 44.
85
+ Nada en `small` ni `xsmall` (canon, dueño, 05-10-2026, D16; reemplaza al «tamaño por plataforma» del
86
+ 03-10-2026, que bajaba la web a `small`). La app lo resuelve con `BreakpointsService`
87
+ (`src/app/services/breakpoints.service.ts`): la señal `bp.tactil()` (celular por ancho o pantalla
88
+ táctil) ya incluye la tablet; ver «Por dispositivo (D16)» abajo. Medido el 04-10-2026 en `master-pedidos`: 166 `[size]`
89
+ con `bp` (142 `large`/`medium`, 22 `large`/`small`, 2 `medium`/`xsmall`); los 24 que bajan de `medium` se migran.
87
90
 
88
91
  Desde el 03-10-2026 el grupo tiene `large` (48) y `medium` (40), la misma escala de `sui-button`,
89
92
  así que el par es el de toda la app.
90
93
 
91
94
  | uso | mobile | web | fuente |
92
95
  |---|---|---|---|
93
- | días del horario, opciones en un formulario | `large` (48) | `small` (36) | canon (aprobado por el dueño, 03-10-2026) |
94
- | fila larga que no entra a 48 en 360 px (los 7 días con texto) | `medium` (40) | `small` (36) | propuesta, falta aprobación |
95
- | barra de filtros | `large` | `xsmall` (32) | propuesta, falta aprobación |
96
- | dentro de una tabla o una card densa | no va en mobile | `2xsmall` (24) | propuesta |
96
+ | días del horario, opciones en un formulario | `large` (48) | `medium` (40) | mobile: canon (aprobado por el dueño, 03-10-2026) · web: canon (dueño, 05-10-2026, D16), antes `small` |
97
+ | fila larga que no entra a 48 en 360 px (los 7 días con texto) | `medium` (40) | `medium` (40) | mobile: propuesta, falta aprobación (espera P18) · web: canon (dueño, 05-10-2026, D16) |
98
+ | barra de filtros | `large` | `medium` (40) | web: canon (dueño, 05-10-2026, D16) · mobile: propuesta, falta aprobación |
99
+ | dentro de una tabla o una card densa | no va en mobile | `medium` (40) | no va en mobile: canon (aprobado por el dueño, 05-10-2026, bloque B7) · web: canon (dueño, 05-10-2026, D16), antes `2xsmall` |
97
100
 
98
101
  ```html
99
102
  <sui-button-group [items]="dias" [multi]="true" [(value)]="diasAbiertos" ariaLabel="Días de atención"
100
- [size]="bp.isMobile() ? 'large' : 'small'" />
103
+ [size]="bp.tactil() ? 'large' : 'medium'" />
101
104
  ```
102
105
 
103
106
  En mobile, cada opción va ancha (los 7 días repartidos en todo el ancho, no apretados a la
@@ -105,6 +108,24 @@ izquierda) — propuesta, falta aprobación. **El componente no lo hace solo**:
105
108
  `inline-flex` y no hay un input de ancho completo, así que hoy lo tendría que resolver quien lo usa
106
109
  con CSS. Si las opciones no entran ni en `medium`, va una lista de `sui-checkbox`.
107
110
 
111
+ ### Por dispositivo (D16)
112
+
113
+ Fila `button-group` (+ `-item`) de la tabla D16 (dueño, 05-10-2026). Se toca, así que va por tipo de
114
+ puntero además del ancho.
115
+
116
+ | dispositivo | size | nota |
117
+ |---|---|---|
118
+ | celular chico (< 380 px) | `large` (48) | D16 pide `medium` con área tocable de 44; mientras el DS no estire el área de los `medium`, va `large` (interino) |
119
+ | celular (380–767 px) | `large` (48) | `medium` (40) si los 7 días no entran: **pendiente (P18)**, falta decidir entre `[stretch]`, lista de `checkbox-label` o bajar el tope |
120
+ | tablet táctil (`pointer: coarse`) | `large` (48) | también se toca con el dedo: Apple pide 44 pt en el iPad |
121
+ | computadora (`pointer: fine`) | `medium` (40) | también en tablas y cards densas |
122
+
123
+ Ultrawide (≥ 1920 px): igual que la computadora, `medium`; el espacio extra va a ancho y columnas,
124
+ no a controles más grandes.
125
+
126
+ En master-pedidos: `[size]="bp.tactil() ? 'large' : 'medium'"` (no hay helper propio; da el mismo
127
+ par que `bp.sizeControl()`). `bp.isMobile()` solo no sirve: deja la tablet en `medium`.
128
+
108
129
  ## «No usar»: por qué no hoy y cuándo sí
109
130
 
110
131
  Nada se borra del DS. Lo marcado «no usar» no tiene caso en la app de hoy; si un flujo nuevo cae
@@ -162,11 +183,58 @@ interface SuiButtonGroupEntry {
162
183
  acompáñalo con un texto que diga cuántas hay elegidas.
163
184
  - Ya trae el arreglo de iOS para el `:active` pegado: no lo agregues.
164
185
 
186
+ ## Bien y mal
187
+
188
+ Hoy no hay usos en la app: los pares salen de «Cuándo no» y de «Trampas».
189
+
190
+ **Cambiar de vista**
191
+
192
+ ```html
193
+ <!-- ❌ mal: elegir una sola vista no es un button-group; con multi en false ni se puede apagar la prendida -->
194
+ <sui-button-group [items]="vistas" [(value)]="vista" ariaLabel="Vista" size="medium" />
195
+ ```
196
+
197
+ ```html
198
+ <!-- ✅ bien -->
199
+ <sui-segmented-control [tabs]="vistas" [(active)]="vista" ariaLabel="Vista"
200
+ [size]="bp.tactil() ? '2xlarge' : 'medium'" />
201
+ ```
202
+
203
+ **Opciones proyectadas en vez de `items`**
204
+
205
+ ```html
206
+ <!-- ❌ mal: el grupo no tiene ng-content (los ítems no se pintan) e items es obligatorio -->
207
+ <sui-button-group ariaLabel="Días de atención">
208
+ <sui-button-group-item label="L" />
209
+ <sui-button-group-item label="M" />
210
+ </sui-button-group>
211
+ ```
212
+
213
+ ```html
214
+ <!-- ✅ bien: las opciones van en items, con ariaLabel en los dos «M» -->
215
+ <sui-button-group [items]="dias" [multi]="true" [(value)]="diasAbiertos" ariaLabel="Días de atención"
216
+ [size]="bp.tactil() ? 'large' : 'medium'" />
217
+ ```
218
+
219
+ **Sin `size`**
220
+
221
+ ```html
222
+ <!-- ❌ mal: sin size queda en small (36): chico en la computadora y sin los 44 del dedo en el teléfono -->
223
+ <sui-button-group [items]="dias" [multi]="true" [(value)]="diasAbiertos" ariaLabel="Días de atención" />
224
+ ```
225
+
226
+ ```html
227
+ <!-- ✅ bien -->
228
+ <sui-button-group [items]="dias" [multi]="true" [(value)]="diasAbiertos" ariaLabel="Días de atención"
229
+ [size]="bp.tactil() ? 'large' : 'medium'" />
230
+ ```
231
+
165
232
  ## Ejemplo
166
233
 
167
234
  ```html
168
235
  <!-- Días de atención del local -->
169
- <sui-button-group [items]="dias" [multi]="true" [(value)]="diasAbiertos" ariaLabel="Días de atención" />
236
+ <sui-button-group [items]="dias" [multi]="true" [(value)]="diasAbiertos" ariaLabel="Días de atención"
237
+ [size]="bp.tactil() ? 'large' : 'medium'" />
170
238
  ```
171
239
 
172
240
  ```ts
@@ -27,26 +27,47 @@ apagar algo suelto está `sui-switch`; para una acción, `sui-button`.
27
27
  | prop | valor | cuándo | fuente |
28
28
  |---|---|---|---|
29
29
  | `size` | `large` · `medium` · `small` · `xsmall` · `2xsmall` | El mismo del grupo; lo pone el grupo. Altos 48 · 40 · 36 · 32 · 24. | `small` a `2xsmall`: escala según la guía del DS · `large` y `medium`: canon (aprobado por el dueño, 03-10-2026), extensión SUI |
30
- | `active` | `true` | La opción está elegida; lo calcula el grupo desde `value`. | propuesta |
31
- | `disabled` | `true` | La opción existe pero hoy no se puede elegir; viene de `disabled` en la entrada de `items`. | propuesta |
32
- | `label` | texto | Una a tres letras o una palabra. | propuesta |
33
- | `leftIcon` / `rightIcon` | RemixIcon | Ícono a la izquierda si ayuda a distinguir; a la derecha, sin caso. Sin `label` queda cuadrado. | propuesta |
34
- | `ariaLabel` | texto | Obligatorio si no hay `label`, o si dos opciones tienen el mismo texto. | propuesta |
30
+ | `active` | `true` | La opción está elegida; lo calcula el grupo desde `value`. | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
31
+ | `disabled` | `true` | La opción existe pero hoy no se puede elegir; viene de `disabled` en la entrada de `items`. | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
32
+ | `label` | texto | Una a tres letras o una palabra. | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
33
+ | `leftIcon` / `rightIcon` | RemixIcon | Ícono a la izquierda si ayuda a distinguir; a la derecha, sin caso. Sin `label` queda cuadrado. | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
34
+ | `ariaLabel` | texto | Obligatorio si no hay `label`, o si dos opciones tienen el mismo texto. | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
35
35
 
36
36
  ## Tamaño en mobile y en web
37
37
 
38
- En mobile se toca con el dedo: el área táctil tiene que medir **44 px o más**. En web, con mouse,
39
- va un tamaño más chico. La app ya lo resuelve con `BreakpointsService`
40
- (`src/app/services/breakpoints.service.ts`, mobile = hasta 767 px):
41
- `[size]="bp.isMobile() ? 'large' : 'small'"`. Medido el 04-10-2026 en `master-pedidos`: 166 `[size]`
42
- con `bp` (142 `large`/`medium`, 22 `large`/`small`, 2 `medium`/`xsmall`). Regla del dueño, 03-10-2026.
38
+ En mobile se toca con el dedo: el área táctil tiene que medir **44 px o más**. En la tablet
39
+ (`pointer: coarse`) va igual que en el celular, porque también se toca; en la computadora
40
+ (`pointer: fine`), `medium`; en el celular chico (< 380 px), `medium` a la vista sin bajar el área de 44.
41
+ Nada en `small` ni `xsmall` (canon, dueño, 05-10-2026, D16; reemplaza al «tamaño por plataforma» del
42
+ 03-10-2026, que bajaba la web a `small`). La app lo resuelve con `BreakpointsService`
43
+ (`src/app/services/breakpoints.service.ts`): la señal `bp.tactil()` (celular por ancho o pantalla
44
+ táctil) ya incluye la tablet; ver «Por dispositivo (D16)» abajo. Medido el 04-10-2026 en `master-pedidos`: 166 `[size]`
45
+ con `bp` (142 `large`/`medium`, 22 `large`/`small`, 2 `medium`/`xsmall`); los 24 que bajan de `medium` se migran.
43
46
 
44
47
  El tamaño lo pone el grupo: es el mismo `size` de `sui-button-group` (ver su README).
45
48
 
46
49
  | uso | mobile | web | fuente |
47
50
  |---|---|---|---|
48
- | dentro de un grupo | `large` (48) · `medium` (40) si la fila no entra | `small` (36) | canon (aprobado por el dueño, 03-10-2026) |
49
- | suelto (barra de herramientas) | no va en mobile | `xsmall` o `2xsmall` | propuesta |
51
+ | dentro de un grupo | `large` (48) · `medium` (40) si la fila no entra | `medium` (40) | mobile: canon (aprobado por el dueño, 03-10-2026) · web: canon (dueño, 05-10-2026, D16), antes `small` |
52
+ | suelto (barra de herramientas) | no va en mobile | `medium` (40) | no va en mobile: canon (aprobado por el dueño, 05-10-2026, bloque B7) · web: canon (dueño, 05-10-2026, D16), antes `xsmall` o `2xsmall` |
53
+
54
+ ### Por dispositivo (D16)
55
+
56
+ Dentro del grupo el ítem no elige: recibe el `size` de `sui-button-group` (fila `button-group` de
57
+ la tabla D16, dueño 05-10-2026).
58
+
59
+ | dispositivo | size | nota |
60
+ |---|---|---|
61
+ | celular chico (< 380 px) | `large` (48) | D16 pide `medium` con área tocable de 44; mientras el DS no estire el área de los `medium`, va `large` (interino) |
62
+ | celular (380–767 px) | `large` (48) | `medium` (40) si los 7 días no entran: **pendiente (P18)**, falta decidir entre `[stretch]`, lista de `checkbox-label` o bajar el tope |
63
+ | tablet táctil (`pointer: coarse`) | `large` (48) | también se toca con el dedo: Apple pide 44 pt en el iPad |
64
+ | computadora (`pointer: fine`) | `medium` (40) | también suelto en una barra de herramientas |
65
+
66
+ Ultrawide (≥ 1920 px): igual que la computadora, `medium`; el espacio extra va a ancho y columnas,
67
+ no a controles más grandes.
68
+
69
+ En master-pedidos: `[size]="bp.tactil() ? 'large' : 'medium'"` en el grupo (no hay helper propio;
70
+ da el mismo par que `bp.sizeControl()`). Suelto: `size="medium"`.
50
71
 
51
72
  ## «No usar»: por qué no hoy y cuándo sí
52
73
 
@@ -90,13 +111,59 @@ en la columna de la derecha, se usa (aprobado por el dueño, 03-10-2026).
90
111
  - Es un `<button type="button">` con `aria-pressed`: el lector de pantalla lo anuncia como botón de
91
112
  alternar.
92
113
 
114
+ ## Bien y mal
115
+
116
+ Hoy no hay usos en la app (ni del ítem ni del grupo): los pares salen de «Trampas» y de «Cuándo no».
117
+
118
+ **Opciones armadas a mano en vez de `items`**
119
+
120
+ ```html
121
+ <!-- ❌ mal: sueltos no reciben las puntas redondeadas ni los bordes juntos; eso lo pone el grupo -->
122
+ <div class="horario__dias">
123
+ <sui-button-group-item label="L" size="medium" [active]="lunes()" (clicked)="lunes.set(!lunes())" />
124
+ <sui-button-group-item label="M" size="medium" [active]="martes()" (clicked)="martes.set(!martes())" />
125
+ </div>
126
+ ```
127
+
128
+ ```html
129
+ <!-- ✅ bien -->
130
+ <sui-button-group [items]="dias" [multi]="true" [(value)]="diasAbiertos" ariaLabel="Días de atención"
131
+ [size]="bp.tactil() ? 'large' : 'medium'" />
132
+ ```
133
+
134
+ **Botón de alternar suelto en una barra de desktop**
135
+
136
+ ```html
137
+ <!-- ❌ mal: 2xsmall (24) es chico (D16) y, sin label ni ariaLabel, el lector de pantalla no dice qué es -->
138
+ <sui-button-group-item leftIcon="bold" size="2xsmall" [active]="negrita()" (clicked)="negrita.set(!negrita())" />
139
+ ```
140
+
141
+ ```html
142
+ <!-- ✅ bien -->
143
+ <sui-button-group-item leftIcon="bold" ariaLabel="Negrita" size="medium"
144
+ [active]="negrita()" (clicked)="negrita.set(!negrita())" />
145
+ ```
146
+
147
+ **Esperar que se prenda solo al tocarlo**
148
+
149
+ ```html
150
+ <!-- ❌ mal: active no cambia solo; el ítem avisa con (clicked) y se queda apagado -->
151
+ <sui-button-group-item label="Negrita" size="medium" (clicked)="guardarFormato()" />
152
+ ```
153
+
154
+ ```html
155
+ <!-- ✅ bien: quien lo usa cambia active -->
156
+ <sui-button-group-item label="Negrita" size="medium" [active]="negrita()" (clicked)="negrita.set(!negrita())" />
157
+ ```
158
+
93
159
  ## Ejemplo
94
160
 
95
161
  ```html
96
162
  <!-- Lo normal: no se escribe a mano, lo arma el grupo -->
97
- <sui-button-group [items]="dias" [multi]="true" [(value)]="diasAbiertos" ariaLabel="Días de atención" />
163
+ <sui-button-group [items]="dias" [multi]="true" [(value)]="diasAbiertos" ariaLabel="Días de atención"
164
+ [size]="bp.tactil() ? 'large' : 'medium'" />
98
165
 
99
166
  <!-- Suelto, solo en el caso de «cuándo sí» -->
100
- <sui-button-group-item leftIcon="bold" ariaLabel="Negrita" size="xsmall"
167
+ <sui-button-group-item leftIcon="bold" ariaLabel="Negrita" size="medium"
101
168
  [active]="negrita()" (clicked)="negrita.set(!negrita())" />
102
169
  ```
@@ -45,8 +45,8 @@ selección.**
45
45
 
46
46
  | variant | cuándo | fuente |
47
47
  |---|---|---|
48
- | `default` | Lo normal: la card sobre el fondo de la app (borde + sombra x-small). 251 de 253. | propuesta (práctica de la app) |
49
- | `elevated` | La card flota sobre un mapa, una foto o un fondo de color, donde el borde se pierde y hace falta la sombra media. Precedente: el seguimiento público del pedido (`pages/public/pedido-en-vivo/pedido-en-vivo.html:19`, `:69`). | propuesta |
48
+ | `default` | Lo normal: la card sobre el fondo de la app (borde + sombra x-small). 251 de 253. | canon (aprobado por el dueño, 05-10-2026, bloque B2) (práctica de la app) |
49
+ | `elevated` | La card flota sobre un mapa, una foto o un fondo de color, donde el borde se pierde y hace falta la sombra media. Precedente: el seguimiento público del pedido (`pages/public/pedido-en-vivo/pedido-en-vivo.html:19`, `:69`). | canon (aprobado por el dueño, 05-10-2026, bloque B2) |
50
50
  | `flat` | Ver «No usar». | propuesta |
51
51
 
52
52
  ### `size` (padding × gap entre slots)
@@ -54,16 +54,16 @@ selección.**
54
54
  | size | medidas | cuándo | fuente |
55
55
  |---|---|---|---|
56
56
  | `small` | 16 / 12 | Filas de una lista de cards, KPIs chicos, cards tocables. **Toda card en mobile.** | propuesta |
57
- | `medium` (default) | 20 / 16 | Secciones en web. | propuesta |
58
- | `large` | 24 / 20 | La sección principal de una pantalla de web (los 14 de hoy son gráficos de reportes y los pasos del onboarding). | propuesta |
59
- | `xlarge` | 28 / 24 | Ver «No usar». Extensión SUI (no está en Figma). | propuesta |
57
+ | `medium` (default) | 20 / 16 | Secciones en web. | canon (aprobado por el dueño, 05-10-2026, bloque B1) |
58
+ | `large` | 24 / 20 | La sección principal de una pantalla de web (los 14 de hoy son gráficos de reportes y los pasos del onboarding). | canon (aprobado por el dueño, 05-10-2026, bloque B1) |
59
+ | `xlarge` | 28 / 24 | Ver «No usar». Extensión SUI (no está en Figma). | canon (aprobado por el dueño, 05-10-2026, bloque B6) |
60
60
 
61
61
  ### `interactive`
62
62
 
63
63
  | valor | cuándo | fuente |
64
64
  |---|---|---|
65
- | `true` | La card entera es **una** acción: abre un detalle o lleva a otra pantalla («Mis direcciones», una factura). Da cursor, hover, foco y el arreglo de iOS. | propuesta |
66
- | `false` (default) | La card tiene 2 acciones o más adentro, o ninguna. Las acciones van como botones dentro. | propuesta |
65
+ | `true` | La card entera es **una** acción: abre un detalle o lleva a otra pantalla («Mis direcciones», una factura). Da cursor, hover, foco y el arreglo de iOS. | canon (aprobado por el dueño, 05-10-2026, bloque B8) |
66
+ | `false` (default) | La card tiene 2 acciones o más adentro, o ninguna. Las acciones van como botones dentro. | canon (aprobado por el dueño, 05-10-2026, bloque B8) |
67
67
 
68
68
  ### Slots
69
69
 
@@ -71,19 +71,30 @@ selección.**
71
71
  |---|---|---|
72
72
  | `[sui-card-header]` | Título de la card a la izquierda y, si hace falta, una acción chica a la derecha (`sui-link-button` «Ver todo»). | propuesta |
73
73
  | cuerpo (sin atributo) | El contenido. **Con 2 bloques o más, envuélvelos en un div propio con `display:flex; flex-direction:column; gap`** (ver Trampas). | canon (memoria del proyecto, 10-05-2026) |
74
- | `[sui-card-media]` | Gráfico, mapa o foto de borde a borde, al final. Si después va un footer, la media deja de comerse el borde inferior. | propuesta |
74
+ | `[sui-card-media]` | Gráfico, mapa o foto de borde a borde, al final. Si después va un footer, la media deja de comerse el borde inferior. | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
75
75
  | `[sui-card-footer]` | La acción de la card o un resumen. Si son dos botones, siguen el orden de `sui-modal-footer` (secundario a la izquierda, primario a la derecha). | canon (orden de botones, CLAUDE.md) |
76
76
 
77
- **Usos de hoy que rompen las reglas** (revisado el 04-10-2026):
78
-
79
- - **Los 18 `gap` puestos en la clase del `sui-card`** (central-inicio, master-semanas,
80
- central-ingresos, invoices, driver-history, driver-wallet) ya van con un wrapper `…-body` propio
81
- desde el 03-10-2026 (commit `103f76fa` de la app). Quedan 0.
82
- - **3 cards tocables con `[interactive]` y además `(keydown.enter)`**: la card ya dispara el click
83
- con Enter, así que el handler corre **dos veces** (ver Trampas).
84
- `pages/super-admin/master-users/master-users.html:156`,
85
- `pages/super-admin/master-settings/master-settings.html:611` (con `routerLink`) y
86
- `pages/driver/driver-dashboard/driver-dashboard.html:990`. Se borra el `(keydown.enter)`.
77
+ **Usos de hoy que rompen las reglas** (revisado el 06-10-2026):
78
+
79
+ - **`gap` puesto en la clase del `sui-card` para separar lo del cuerpo.** Los 18 que se contaron el
80
+ 03-10-2026 (central-inicio, master-semanas, central-ingresos, invoices, driver-history,
81
+ driver-wallet) ya van con un wrapper `…-body` propio (commit `103f76fa` de la app). Ese conteo
82
+ dejó fuera 6 cards en 3 archivos, que siguen igual: su `gap` no separa nada porque todo va en el
83
+ cuerpo.
84
+ - `pages/super-admin/master-users/master-users.html:158` · `.mu__card { gap: 6px !important }`
85
+ (`master-users.scss:57`). Es el «mal» de «Separar las filas del cuerpo», abajo.
86
+ - `pages/super-admin/master-overview/master-overview.html:444`, `:450`, `:456`, `:462` ·
87
+ `.mo__quick-link { gap: 8px }` (`master-overview.scss:273`).
88
+ - `pages/central/central-gastos/central-gastos.html:35` · `.cg__kpi { gap: 4px }`
89
+ (`central-gastos.scss:37`).
90
+
91
+ No cuentan los `gap: 0 !important` (master-settings, master-users `.mu__table-wrap`,
92
+ master-earnings, master-approvals, master-overview `.mo__recent-list`): apagan el gap entre slots
93
+ a propósito, no intentan separar hijos.
94
+ - **Cards con `[interactive]` y además `(keydown.enter)`**: quedan 0. Las 3 que había
95
+ (master-users, master-settings y driver-dashboard) se corrigieron con el commit `00c3f17c` de la
96
+ app; hoy ningún `sui-card` lleva `(keydown.enter)`. El `(keydown.enter)` que sigue en
97
+ `master-users.html:117` es de una fila `<tr>` de la tabla, no de una card.
87
98
 
88
99
  ## Tamaño en mobile y en web
89
100
 
@@ -103,6 +114,13 @@ mobile es no perder ancho.
103
114
  `bp` es el `BreakpointsService` de la app. Va al ritmo de los gaps de página (12 / 16 / 20 por
104
115
  breakpoint). Si la card es tocable, el alto de la fila (≥ 44) lo da su contenido, no el `size`.
105
116
 
117
+ ### Por dispositivo (D16)
118
+
119
+ D16 no mueve la card: su `size` es padding y gap, no algo que se toca ni que se lee más grande, y
120
+ no está en la tabla por componente de D16. Lo que va adentro sigue su propio README (los botones,
121
+ `bp.sizeControl()`). El `small` en mobile de la tabla de arriba sigue **pendiente (P12)**: falta
122
+ decidir si va solo en pantallas nuevas, si se migran las de hoy o si queda `medium` en las dos.
123
+
106
124
  ## «No usar»: por qué no hoy y cuándo sí
107
125
 
108
126
  | qué | por qué no hoy | cuándo sí, en un flujo nuevo |
@@ -144,6 +162,75 @@ Slots: `[sui-card-header]`, cuerpo (`<ng-content>`), `[sui-card-media]`, `[sui-c
144
162
  cambias el padding a la card desde afuera, la media queda corrida.
145
163
  - En modo oscuro `elevated` usa `--sui-card-elevated-border` para el borde (la sombra no se ve).
146
164
 
165
+ ## Bien y mal
166
+
167
+ **Separar las filas del cuerpo**
168
+
169
+ ```html
170
+ <!-- ❌ mal: el gap en la clase del card separa slots, no lo que proyectas (master-users.html:158, .mu__card { gap: 6px } en master-users.scss:57) -->
171
+ <sui-card size="small" class="mu__card">
172
+ <span class="mu__card-name">{{ u.name }}</span>
173
+ <span class="mu__card-email">{{ u.email }}</span>
174
+ </sui-card>
175
+ ```
176
+
177
+ ```html
178
+ <!-- ✅ bien: wrapper propio con display:flex; flex-direction:column; gap:6px -->
179
+ <sui-card size="small">
180
+ <div class="mu__card-body">
181
+ <span class="mu__card-name">{{ u.name }}</span>
182
+ <span class="mu__card-email">{{ u.email }}</span>
183
+ </div>
184
+ </sui-card>
185
+ ```
186
+
187
+ **Card tocable con botones adentro**
188
+
189
+ ```html
190
+ <!-- ❌ mal: interactive es para UNA acción; esta abre la ficha y además tiene dos botones
191
+ (pages/super-admin/master-users/master-users.html:158, resumido) -->
192
+ <sui-card size="small" [interactive]="true" (click)="abrirFicha(u)">
193
+ …nombre, correo, aparatos, fecha…
194
+ <div class="mu__card-actions" (click)="$event.stopPropagation()">
195
+ <sui-button variant="stroke" color="neutral" [size]="bp.sizeControl()" (click)="openBanModal(u)">{{ u.baneado ? 'Desbloquear cuenta' : 'Bloquear cuenta' }}</sui-button>
196
+ <sui-button variant="stroke" color="error" [size]="bp.sizeControl()" (click)="openDeleteUserModal(u)">Eliminar usuario</sui-button>
197
+ </div>
198
+ </sui-card>
199
+ ```
200
+
201
+ Son **tres** acciones: abrir la ficha, bloquear y eliminar. Sin `interactive`, abrir la ficha
202
+ pasa a ser una acción explícita, y no entra como tercer botón: el canon de `sui-modal-footer`
203
+ admite dos botones como máximo, y la tercera acción va como `sui-link-button` a la izquierda.
204
+ Ninguna se pierde.
205
+
206
+ ```html
207
+ <!-- ✅ bien: sin interactive; «Ver ficha» es el link de la izquierda y los dos botones quedan a la derecha
208
+ (.mu__card-actions: display:flex; align-items:center; gap:12px · .mu__card-ver: margin-right:auto) -->
209
+ <sui-card size="small"> <!-- nombre y correo en el cuerpo, con su wrapper como arriba -->
210
+ <div sui-card-footer class="mu__card-actions">
211
+ <sui-link-button class="mu__card-ver" variant="primary" [size]="bp.isMobile() ? 'large' : 'medium'" (click)="abrirFicha(u)">Ver ficha</sui-link-button>
212
+ <sui-button variant="stroke" color="neutral" [size]="bp.sizeControl()" (click)="openBanModal(u)">{{ u.baneado ? 'Desbloquear cuenta' : 'Bloquear cuenta' }}</sui-button>
213
+ <sui-button variant="stroke" color="error" [size]="bp.sizeControl()" (click)="openDeleteUserModal(u)">Eliminar usuario</sui-button>
214
+ </div>
215
+ </sui-card>
216
+ ```
217
+
218
+ El tamaño del link sigue su README (`large` en el teléfono está pendiente de P8); los botones van
219
+ con `bp.sizeControl()` (D16). Los dos son `stroke` como en la app: en una lista de cards un
220
+ `filled` rojo por fila pesa más que el dato.
221
+
222
+ **Enter además de `interactive`**
223
+
224
+ ```html
225
+ <!-- ❌ mal: la card ya hace click con Enter; el handler corre dos veces (pasaba en master-users.html, master-settings.html y driver-dashboard.html; corregido en el commit 00c3f17c de la app) -->
226
+ <sui-card size="small" [interactive]="true" (click)="abrirDirecciones()" (keydown.enter)="abrirDirecciones()">…</sui-card>
227
+ ```
228
+
229
+ ```html
230
+ <!-- ✅ bien -->
231
+ <sui-card size="small" [interactive]="true" (click)="abrirDirecciones()">…</sui-card>
232
+ ```
233
+
147
234
  ## Ejemplo
148
235
 
149
236
  ```html
@@ -26,7 +26,7 @@ igual en el celular, sin tocar nada.
26
26
  ## Qué variante usar
27
27
 
28
28
  > La guía del DS no tiene página para este componente: sale del Figma del DS (set «Chart Legends»).
29
- > Todo lo de abajo es **propuesta**, salvo lo marcado «según el componente» o «canon».
29
+ > Las reglas de abajo son **canon** (cada fila dice de qué aprobación sale), salvo lo marcado «según el componente».
30
30
  >
31
31
  > Uso medido el 03-10-2026 en `master-pedidos/src/app` (sin prototipos ni vitrinas): **1 uso**, más
32
32
  > **5 leyendas hechas a mano** y **9 gráficos con la leyenda de ECharts**.
@@ -35,12 +35,12 @@ igual en el celular, sin tocar nada.
35
35
 
36
36
  | campo | valor | cuándo | fuente |
37
37
  |---|---|---|---|
38
- | `label` | nombre corto | El nombre de la serie, tal como se dice en la app: «Entregados», «Yape». | propuesta |
39
- | `color` | sin pasar | **Lo normal** en categorías sin bien ni mal (canales, métodos de pago, distritos): el componente reparte azul, naranja, rojo, verde… en orden. | según el componente (orden) · cuándo: propuesta |
38
+ | `label` | nombre corto | El nombre de la serie, tal como se dice en la app: «Entregados», «Yape». | canon (aprobado por el dueño, 05-10-2026, bloque B4) |
39
+ | `color` | sin pasar | **Lo normal** en categorías sin bien ni mal (canales, métodos de pago, distritos): el componente reparte azul, naranja, rojo, verde… en orden. | según el componente (orden) · cuándo: canon (aprobado por el dueño, 05-10-2026, bloque B3) |
40
40
  | `color` | el del estado | Cuando la serie **es un estado**: entregados `green`, cancelados `red`, pendientes `orange`. Mismo significado que en `sui-badge`. | canon (colores con significado del badge) |
41
- | `customColor` | el color que ya usa el gráfico | Solo cuando el gráfico tiene su propia paleta y el punto tiene que coincidir. Va el mismo valor en los dos lados. | propuesta |
42
- | `value` | número o texto | Cuando el número importa para leer el gráfico: «42», «S/ 1,200.00», «38 %». | propuesta |
43
- | `disabled` | `true` | Una serie sin datos en el período: se ve, apagada, para que no parezca que falta. | propuesta |
41
+ | `customColor` | el color que ya usa el gráfico | Solo cuando el gráfico tiene su propia paleta y el punto tiene que coincidir. Va el mismo valor en los dos lados. | canon (aprobado por el dueño, 05-10-2026, bloque B3) |
42
+ | `value` | número o texto | Cuando el número importa para leer el gráfico: «42», «S/ 1,200.00», «38 %». | canon (aprobado por el dueño, 05-10-2026, bloque B3) |
43
+ | `disabled` | `true` | Una serie sin datos en el período: se ve, apagada, para que no parezca que falta. | canon (aprobado por el dueño, 05-10-2026, bloque B3) |
44
44
 
45
45
  Los 12 valores de `color`, uno por uno y con su regla, están en el README de `sui-chart-legend-dot`.
46
46
 
@@ -51,8 +51,8 @@ Para que el gráfico y la leyenda pinten **el mismo color**, ECharts recibe la p
51
51
 
52
52
  | orientation | cuándo | fuente |
53
53
  |---|---|---|
54
- | `horizontal` (default) | Debajo de un gráfico de barras o de líneas. Si no entra, baja a la línea siguiente. | propuesta |
55
- | `vertical` | Al lado de una dona o un pie, con el `value` de cada serie. En mobile, debajo de la dona. | propuesta |
54
+ | `horizontal` (default) | Debajo de un gráfico de barras o de líneas. Si no entra, baja a la línea siguiente. | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
55
+ | `vertical` | Al lado de una dona o un pie, con el `value` de cada serie. En mobile, debajo de la dona. | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
56
56
 
57
57
  ### Usos de hoy que romperían la regla
58
58
 
@@ -75,8 +75,8 @@ para el dedo; lo que cambia por plataforma es la orientación.
75
75
 
76
76
  | uso | mobile | web | fuente |
77
77
  |---|---|---|---|
78
- | bajo barras o líneas | `horizontal` (envuelve) | `horizontal` | propuesta |
79
- | junto a una dona | `vertical`, **debajo** de la dona | `vertical`, a la derecha | propuesta |
78
+ | bajo barras o líneas | `horizontal` (envuelve) | `horizontal` | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
79
+ | junto a una dona | `vertical`, **debajo** de la dona | `vertical`, a la derecha | canon (aprobado por el dueño, 05-10-2026, bloque B9) |
80
80
 
81
81
  ```html
82
82
  <!-- Junto a una dona: vertical en las dos; el layout la pone debajo en mobile y a la derecha en web -->
@@ -85,6 +85,15 @@ para el dedo; lo que cambia por plataforma es la orientación.
85
85
 
86
86
  El texto de 12 px queda chico en mobile y el componente no tiene un tamaño mayor: no se cambia aquí.
87
87
 
88
+ ### Por dispositivo (D16)
89
+
90
+ No aplica: **no tiene `size`** (punto de 16 y texto de 12 en todos los dispositivos, del celular
91
+ chico al ultrawide). Es lo que no se toca, pero no hay un tamaño más grande al que subir en el
92
+ celular; lo único que cambia por dispositivo es dónde se pone (`orientation` y el layout, tabla de
93
+ arriba).
94
+
95
+ En master-pedidos: no hay helper ni `[size]`; solo `orientation` según el gráfico.
96
+
88
97
  ## «No usar»: por qué no hoy y cuándo sí
89
98
 
90
99
  | qué | por qué no hoy | cuándo sí, en un flujo nuevo |
@@ -125,6 +134,50 @@ interface SuiChartLegendItem {
125
134
  - Host con `role="list"` y cada item `role="listitem"`; el punto es decorativo.
126
135
  - `items` es obligatorio.
127
136
 
137
+ ## Bien y mal
138
+
139
+ Leyenda bajo una dona
140
+
141
+ ```html
142
+ <!-- ❌ mal: leyenda hecha a mano con el punto en [style.background] (components/marketing-channels/marketing-channels.html:13) -->
143
+ <div class="payment-methods__legend-item">
144
+ <span class="payment-methods__legend-dot" [style.background]="item.color"></span>
145
+ <span class="payment-methods__legend-label">{{ item.name }}</span>
146
+ </div>
147
+ ```
148
+
149
+ ```html
150
+ <!-- ✅ bien: leyendaPagos() = { label: item.name, customColor: item.color, value: item.value } -->
151
+ <sui-chart-legend orientation="vertical" [items]="leyendaPagos()" />
152
+ ```
153
+
154
+ Color de cada método de pago
155
+
156
+ ```html
157
+ <!-- ❌ mal: hex suelto en un ternario, distinto de la paleta del gráfico (pages/reports/reports.html:86) -->
158
+ <span class="reports__legend-dot"
159
+ [style.background-color]="pm.method === 'yape' ? '#7e22ce' : '#6366f1'"></span>
160
+ ```
161
+
162
+ ```html
163
+ <!-- ✅ bien: el mismo customColor que recibe ECharts en series[].color -->
164
+ <sui-chart-legend orientation="vertical" [items]="[
165
+ { label: 'Yape', customColor: colorYape, value: 42 },
166
+ ]" />
167
+ ```
168
+
169
+ Series sin color con un gráfico de paleta propia
170
+
171
+ ```html
172
+ <!-- ❌ mal: sin color salen azul, naranja… y el gráfico pinta otros -->
173
+ <sui-chart-legend [items]="[{ label: 'Entregados' }, { label: 'Cancelados' }]" />
174
+ ```
175
+
176
+ ```html
177
+ <!-- ✅ bien: la serie es un estado, va su color -->
178
+ <sui-chart-legend [items]="[{ label: 'Entregados', color: 'green' }, { label: 'Cancelados', color: 'red' }]" />
179
+ ```
180
+
128
181
  ## Ejemplo
129
182
 
130
183
  ```html