@khipu/design-system 0.2.0-alpha.4 → 0.2.0-alpha.40

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.
@@ -11,7 +11,7 @@
11
11
  *
12
12
  * AUTO-GENERATED FILE - DO NOT EDIT MANUALLY
13
13
  * Source: design-system/src/tokens/tokens.json
14
- * Generated: 2026-05-14T19:34:35.577Z
14
+ * Generated: 2026-06-10T17:26:00.201Z
15
15
  *
16
16
  * To regenerate:
17
17
  * cd design-system && npm run tokens:generate
@@ -48,15 +48,21 @@
48
48
  --kds-color-success-main: #2E7D32;
49
49
  --kds-color-success-light: #4CAF50;
50
50
  --kds-color-success-dark: #1B5E20;
51
+ --kds-color-success-contrast: #FFFFFF;
51
52
  --kds-color-warning-main: #EF6C00;
52
53
  --kds-color-warning-light: #FF9800;
53
54
  --kds-color-warning-dark: #E65100;
55
+ --kds-color-warning-contrast: #FFFFFF;
56
+ --kds-color-warning-warm: #8A6D1A;
54
57
  --kds-color-error-main: #D32F2F;
55
58
  --kds-color-error-light: #EF5350;
56
59
  --kds-color-error-dark: #C62828;
60
+ --kds-color-error-contrast: #FFFFFF;
57
61
  --kds-color-info-main: #0288D1;
58
62
  --kds-color-info-light: #03A9F4;
59
63
  --kds-color-info-dark: #01579B;
64
+ --kds-color-info-contrast: #FFFFFF;
65
+ --kds-color-info-blue: #5A5FE0;
60
66
 
61
67
  /* Text colors */
62
68
  --kds-color-text-primary: #333333;
@@ -134,6 +140,8 @@
134
140
  --kds-font-weight-bold: 700;
135
141
 
136
142
  /* Font sizes (base scale xs–4xl: see responsive section below) */
143
+ --kds-font-size-decimal-sup: 0.5em;
144
+
137
145
  /* Line heights */
138
146
  --kds-line-height-tight: 1.2;
139
147
  --kds-line-height-snug: 1.375;
@@ -756,7 +764,7 @@ footer {
756
764
  ======================================== */
757
765
  :root {
758
766
  /* Scroll-linked collapse range (mobile sticky invoice) */
759
- --kds-scroll-collapse-end: 150px;
767
+ --kds-scroll-collapse-end: 60px;
760
768
 
761
769
  /* Merchant tile: normal and collapsed sizes (from source prototype) */
762
770
  --kds-merchant-size: 64px;
@@ -778,6 +786,10 @@ footer {
778
786
  * Source: design.khipu.com and Material Design 3 specifications
779
787
  */
780
788
 
789
+ * {
790
+ border-radius: 0;
791
+ }
792
+
781
793
 
782
794
  :has(>main) {
783
795
  background-color: transparent !important;
@@ -842,7 +854,10 @@ a.kds-btn {
842
854
 
843
855
  /* Interaction */
844
856
  cursor: pointer;
845
- transition: background .15s, box-shadow .15s, transform .05s;
857
+ transition: background-color var(--kds-transition-shorter) var(--kds-easing-standard),
858
+ color var(--kds-transition-shorter) var(--kds-easing-standard),
859
+ box-shadow var(--kds-transition-shorter) var(--kds-easing-standard),
860
+ transform var(--kds-transition-shortest) var(--kds-easing-standard);
846
861
  box-sizing: border-box;
847
862
  vertical-align: middle;
848
863
  }
@@ -974,7 +989,7 @@ a.kds-btn-text {
974
989
 
975
990
  button.kds-btn-text:hover:not(:disabled),
976
991
  a.kds-btn-text:hover:not(:disabled) {
977
- background: var(--kds-color-primary-hover); /* rgba(131, 71, 173, 0.04) */
992
+ color: var(--kds-color-primary-dark);
978
993
  }
979
994
 
980
995
  button.kds-btn-text:disabled,
@@ -984,6 +999,30 @@ a.kds-btn-text:disabled {
984
999
  box-shadow: none;
985
1000
  }
986
1001
 
1002
+ /* Error text (destructive, ghost) — red text, no fill/border. Para acciones
1003
+ destructivas secundarias que no deben competir con el CTA primario. */
1004
+ button.kds-btn-error-text,
1005
+ a.kds-btn-error-text {
1006
+ background: transparent;
1007
+ color: var(--kds-color-error-main);
1008
+ border: none;
1009
+ padding: 6px var(--kds-spacing-2);
1010
+ min-height: 32px;
1011
+ box-shadow: none;
1012
+ }
1013
+
1014
+ button.kds-btn-error-text:hover:not(:disabled),
1015
+ a.kds-btn-error-text:hover:not(:disabled) {
1016
+ color: var(--kds-color-error-dark);
1017
+ }
1018
+
1019
+ button.kds-btn-error-text:disabled,
1020
+ a.kds-btn-error-text:disabled {
1021
+ background: transparent;
1022
+ color: var(--kds-color-action-disabled);
1023
+ box-shadow: none;
1024
+ }
1025
+
987
1026
  /* Icon wrapper - control size via span container */
988
1027
  button.kds-btn > .kds-icon,
989
1028
  a.kds-btn > .kds-icon {
@@ -1046,6 +1085,7 @@ a.kds-btn.kds-btn-md {
1046
1085
  padding: var(--kds-spacing-2);
1047
1086
  box-shadow: var(--kds-shadow-card);
1048
1087
  transition: box-shadow 0.3s ease;
1088
+ margin-block-start: 0 !important;
1049
1089
  }
1050
1090
 
1051
1091
  .kds-card-elevated:hover,
@@ -1068,63 +1108,90 @@ a.kds-btn.kds-btn-md {
1068
1108
  }
1069
1109
  }
1070
1110
 
1071
- /* Selection card */
1111
+ /* Selection card.
1112
+ IMPORTANTE: este componente se renderiza como `<button>`. BeerCSS aplica al
1113
+ `button` base: `display: inline-flex; align-items: center; justify-content: center;
1114
+ block-size: 2.5rem; padding: 0 1rem; background: var(--primary); color: on-primary`.
1115
+ Todas esas reglas hay que sobreescribirlas para que el card-selector funcione como
1116
+ un contenedor flex column de altura variable y alineado a la izquierda.
1117
+
1118
+ Convención del DS: spacing entre hijos via `gap` del flex padre + padding.
1119
+ Los elementos internos (.kds-card-selector-icon/-title/-description) NO usan margin. */
1072
1120
  .kds-card-selector {
1121
+ /* Reset BeerCSS button */
1122
+ display: flex;
1123
+ flex-direction: column;
1124
+ align-items: stretch;
1125
+ justify-content: flex-start;
1126
+ block-size: auto;
1127
+ inline-size: 100%;
1128
+ text-align: left;
1129
+ line-height: 1.5;
1130
+ color: var(--kds-color-text-primary);
1131
+ /* Estilos propios del card-selector */
1073
1132
  padding: var(--kds-spacing-3);
1133
+ gap: var(--kds-spacing-1-5);
1074
1134
  border-radius: var(--kds-radius-md);
1075
- border: 2px solid var(--kds-border-light);
1135
+ border: var(--kds-border-width-md) solid var(--kds-border-light);
1076
1136
  background: var(--kds-color-background-paper);
1077
1137
  transition: all 0.3s ease;
1078
- text-align: left;
1079
1138
  cursor: pointer;
1080
- display: flex;
1081
- flex-direction: column;
1082
1139
  }
1083
1140
 
1084
- .kds-card-selector:hover {
1085
- border-color: #D1D5DB; /* gray-300 */
1141
+ .kds-card-selector:hover:not(.selected) {
1142
+ border-color: var(--kds-color-primary-light);
1143
+ background: var(--kds-color-primary-hover);
1144
+ }
1145
+
1146
+ /* Override del ripple/overlay default de BeerCSS:
1147
+ `:is(.wave,.chip,.button,button,nav.tabbed>a,...):not([class*=ripple])::after`
1148
+ tiene specificity (0,2,4) según DevTools (Chrome cuenta cada selector dentro
1149
+ de :is() individualmente para algunos motores). Usamos !important — consistente
1150
+ con cómo se overridean otros estilos de BeerCSS en este archivo (67 usos previos).
1151
+ Antes pintaba negro porque `currentColor` resolvía a text-primary del card. */
1152
+ .kds-card-selector::after {
1153
+ background-image: radial-gradient(circle, var(--kds-color-primary-main) 1%, transparent 1%) !important;
1086
1154
  }
1087
1155
 
1088
1156
  .kds-card-selector.selected {
1089
- border-color: #3B82F6; /* blue-600 */
1090
- background: #EFF6FF; /* blue-50 */
1157
+ border-color: var(--kds-color-primary-main);
1158
+ background: var(--kds-color-primary-faint);
1091
1159
  box-shadow: var(--kds-shadow-md);
1092
1160
  }
1093
1161
 
1094
- /* Icon container */
1162
+ /* Icon container — spacing manejado por gap del padre, no margin */
1095
1163
  .kds-card-selector-icon {
1096
- width: 48px;
1097
- height: 48px;
1098
- background: #DBEAFE; /* blue-100 */
1099
- border-radius: 8px;
1164
+ width: var(--kds-spacing-6);
1165
+ height: var(--kds-spacing-6);
1166
+ background: var(--kds-color-primary-focus);
1167
+ border-radius: var(--kds-radius-sm);
1100
1168
  display: flex;
1101
1169
  align-items: center;
1102
1170
  justify-content: center;
1103
- margin-bottom: 16px;
1104
1171
  }
1105
1172
 
1106
1173
  .kds-card-selector-icon i,
1107
1174
  .kds-card-selector-icon svg {
1108
- width: 24px;
1109
- height: 24px;
1110
- min-width: 24px;
1111
- min-height: 24px;
1112
- color: #3B82F6; /* blue-600 */
1175
+ width: var(--kds-spacing-3);
1176
+ height: var(--kds-spacing-3);
1177
+ min-width: var(--kds-spacing-3);
1178
+ min-height: var(--kds-spacing-3);
1179
+ font-size: var(--kds-spacing-3);
1180
+ color: var(--kds-color-primary-main);
1113
1181
  }
1114
1182
 
1115
- /* Title */
1183
+ /* Title — spacing manejado por gap del padre, no margin */
1116
1184
  .kds-card-selector-title {
1117
- font-weight: 600;
1185
+ font-weight: var(--kds-font-weight-semibold);
1118
1186
  color: var(--kds-color-text-primary);
1119
- margin-bottom: 8px;
1120
- font-size: 16px;
1187
+ font-size: var(--kds-font-size-lg);
1121
1188
  }
1122
1189
 
1123
1190
  /* Description */
1124
1191
  .kds-card-selector-description {
1125
- font-size: 14px;
1126
- color: #4B5563; /* gray-600 */
1127
- line-height: 1.5;
1192
+ font-size: var(--kds-font-size-sm);
1193
+ color: var(--kds-color-text-secondary);
1194
+ line-height: var(--kds-line-height-normal);
1128
1195
  }
1129
1196
 
1130
1197
  /* Selected state - visual feedback via border only */
@@ -1136,14 +1203,22 @@ a.kds-btn.kds-btn-md {
1136
1203
  display: flex;
1137
1204
  flex-direction: column;
1138
1205
  gap: var(--kds-spacing-2);
1139
- padding: var(--kds-spacing-4);
1206
+ padding: var(--kds-spacing-2);
1140
1207
  border-radius: var(--kds-radius-lg);
1141
1208
  border: 2px solid var(--kds-border-medium);
1142
- max-width: 400px; /* Increased from 365px for better text spacing */
1209
+ /* Ancho mínimo aplicado a TODOS los planes así un plan sin badge en una
1210
+ grilla con un plan recomendado mantiene la misma anchura, y el badge nunca
1211
+ se superpone al título por estrechez del card. */
1212
+ min-width: 260px;
1213
+ max-width: 400px;
1143
1214
  background: var(--kds-surface-base);
1144
1215
  transition: all 0.3s ease;
1145
1216
  cursor: pointer;
1146
- height: 100%; /* Ensure cards fill grid height */
1217
+ /* Alto fijo: el card se estira al alto de su row del grid (align-items stretch
1218
+ es el default) — todas las cards de la misma fila quedan a la misma altura
1219
+ sin importar el contenido. `align-self: stretch` lo hace explícito. */
1220
+ height: 100%;
1221
+ align-self: stretch;
1147
1222
  }
1148
1223
 
1149
1224
  .kds-card-plan:hover {
@@ -1163,18 +1238,19 @@ a.kds-btn.kds-btn-md {
1163
1238
  box-shadow: var(--kds-shadow-elevation-4);
1164
1239
  }
1165
1240
 
1166
- /* Recommended Badge */
1241
+ /* Recommended Badge — inline dentro del card (no flotante).
1242
+ Es el primer hijo del .kds-card-plan, así que aparece arriba de todo
1243
+ el contenido, alineado a la izquierda. */
1167
1244
  .kds-card-plan-badge {
1168
- position: absolute;
1169
- top: -12px;
1170
- right: var(--kds-spacing-6);
1171
- padding: var(--kds-spacing-1) var(--kds-spacing-4);
1245
+ align-self: flex-start;
1246
+ padding: var(--kds-spacing-0-5) var(--kds-spacing-1-5);
1172
1247
  background: var(--primary);
1173
1248
  color: white;
1174
- font-size: var(--kds-font-size-sm);
1249
+ font-size: var(--kds-font-size-xs);
1175
1250
  font-weight: var(--kds-font-weight-semibold);
1251
+ line-height: 1;
1176
1252
  border-radius: var(--kds-radius-full);
1177
- box-shadow: var(--kds-shadow-elevation-1);
1253
+ white-space: nowrap;
1178
1254
  }
1179
1255
 
1180
1256
  /* Plan Header */
@@ -1202,13 +1278,11 @@ a.kds-btn.kds-btn-md {
1202
1278
  display: flex;
1203
1279
  align-items: baseline;
1204
1280
  gap: var(--kds-spacing-2);
1205
- padding: var(--kds-spacing-4) 0;
1206
1281
  border-bottom: 1px solid var(--kds-border-light);
1207
- min-height: 88px; /* Standardize price area height */
1208
1282
  }
1209
1283
 
1210
1284
  .kds-price {
1211
- font-size: 42px;
1285
+ font-size: var(--kds-font-size-4xl);
1212
1286
  font-weight: var(--kds-font-weight-bold);
1213
1287
  color: var(--primary);
1214
1288
  line-height: 1.1;
@@ -1722,53 +1796,108 @@ a.kds-btn.kds-btn-md {
1722
1796
  }
1723
1797
 
1724
1798
  /* ========================================
1725
- Snackbar Positioning
1799
+ Snackbar Positioning & Styling
1726
1800
  ======================================== */
1727
1801
 
1728
1802
  .snackbar {
1729
1803
  position: fixed;
1730
- bottom: var(--kds-spacing-3);
1731
- left: 50%;
1732
- transform: translateX(-50%);
1733
1804
  z-index: var(--kds-z-index-snackbar);
1734
1805
  min-width: 344px;
1735
1806
  max-width: var(--kds-snackbar-max-width);
1736
1807
  box-shadow: var(--kds-shadow-8);
1808
+ border-radius: var(--kds-radius-md);
1809
+ padding: var(--kds-spacing-1-5) var(--kds-spacing-2);
1810
+ gap: var(--kds-spacing-1);
1811
+ font-family: var(--kds-font-family-primary);
1812
+ font-size: var(--kds-font-size-body2);
1813
+ font-weight: var(--kds-font-weight-medium);
1814
+ line-height: var(--kds-line-height-normal);
1815
+ letter-spacing: var(--kds-letter-spacing-normal);
1816
+ overflow: hidden;
1737
1817
  }
1738
1818
 
1739
1819
  /* Snackbar active state - ensure visibility when toggled via JS */
1740
1820
  .snackbar.active {
1741
1821
  visibility: visible !important;
1742
1822
  opacity: 1 !important;
1743
- transform: translateX(-50%) !important;
1744
1823
  }
1745
1824
 
1746
- /* Snackbar semantic variants - background + text/icon color */
1825
+ /* Snackbar semantic variants
1826
+ All use white text (--kds-color-primary-contrast) on solid semantic backgrounds */
1747
1827
  .snackbar.error {
1748
1828
  background-color: var(--kds-color-error-main) !important;
1749
- color: var(--on-error, var(--kds-color-primary-contrast)) !important;
1829
+ color: var(--kds-color-primary-contrast) !important;
1750
1830
  }
1751
1831
 
1752
1832
  .snackbar.error i {
1753
- color: var(--on-error, var(--kds-color-primary-contrast)) !important;
1833
+ color: var(--kds-color-primary-contrast) !important;
1754
1834
  }
1755
1835
 
1756
1836
  .snackbar.info {
1757
1837
  background-color: var(--kds-color-info-main) !important;
1758
- color: var(--on-info, var(--kds-color-primary-contrast)) !important;
1838
+ color: var(--kds-color-primary-contrast) !important;
1759
1839
  }
1760
1840
 
1761
1841
  .snackbar.info i {
1762
- color: var(--on-info, var(--kds-color-primary-contrast)) !important;
1842
+ color: var(--kds-color-primary-contrast) !important;
1763
1843
  }
1764
1844
 
1765
1845
  .snackbar.success {
1766
1846
  background-color: var(--kds-color-success-main) !important;
1767
- color: var(--on-success, var(--kds-color-primary-contrast)) !important;
1847
+ color: var(--kds-color-primary-contrast) !important;
1768
1848
  }
1769
1849
 
1770
1850
  .snackbar.success i {
1771
- color: var(--on-success, var(--kds-color-primary-contrast)) !important;
1851
+ color: var(--kds-color-primary-contrast) !important;
1852
+ }
1853
+
1854
+ /* Snackbar progress bar — animated timer for auto-dismiss */
1855
+ .snackbar[data-auto-dismiss]::after {
1856
+ content: '';
1857
+ position: absolute;
1858
+ bottom: 0;
1859
+ left: 0;
1860
+ height: 3px;
1861
+ width: 100%;
1862
+ background: rgba(255, 255, 255, 0.35);
1863
+ border-radius: 0 0 var(--kds-radius-md) var(--kds-radius-md);
1864
+ animation: kds-snackbar-timer var(--kds-snackbar-duration, 5s) linear forwards;
1865
+ }
1866
+
1867
+ @keyframes kds-snackbar-timer {
1868
+ from { width: 100%; }
1869
+ to { width: 0; }
1870
+ }
1871
+
1872
+ /* Snackbar close button */
1873
+ .kds-snackbar-close {
1874
+ background: none !important;
1875
+ border: none !important;
1876
+ color: var(--kds-color-primary-contrast) !important;
1877
+ cursor: pointer;
1878
+ padding: var(--kds-spacing-0-5) !important;
1879
+ margin: calc(-1 * var(--kds-spacing-0-5)) !important;
1880
+ margin-left: 0 !important;
1881
+ border-radius: var(--kds-radius-full) !important;
1882
+ display: flex;
1883
+ align-items: center;
1884
+ justify-content: center;
1885
+ flex-shrink: 0;
1886
+ opacity: 0.7;
1887
+ transition: opacity 150ms;
1888
+ min-width: auto !important;
1889
+ width: auto !important;
1890
+ height: auto !important;
1891
+ }
1892
+
1893
+ .kds-snackbar-close:hover {
1894
+ opacity: 1;
1895
+ background: rgba(255, 255, 255, 0.15) !important;
1896
+ }
1897
+
1898
+ .kds-snackbar-close i {
1899
+ font-size: 18px !important;
1900
+ color: var(--kds-color-primary-contrast) !important;
1772
1901
  }
1773
1902
 
1774
1903
  /* ========================================
@@ -1969,6 +2098,28 @@ a.kds-btn-google:disabled {
1969
2098
  height: var(--kds-spacing-button-icon-size);
1970
2099
  }
1971
2100
 
2101
+ /* ========================================
2102
+ KDS LINEAR PROGRESS
2103
+ Native <progress> (KdsLinearProgress). Additive over BeerCSS `progress`,
2104
+ scoped to .kds-progress so other consumers are unaffected.
2105
+ ======================================== */
2106
+
2107
+ /* `progress` is inline-block by default → leaves a baseline (descender) gap
2108
+ below the bar. Block removes that gap so it sits flush with siblings. */
2109
+ .kds-progress {
2110
+ display: block;
2111
+ }
2112
+
2113
+ /* Animate the filled value when it changes (e.g. advancing a step). BeerCSS
2114
+ sets the value background but no transition, so the width jumps abruptly. */
2115
+ .kds-progress::-webkit-progress-value {
2116
+ transition: width var(--kds-transition-standard) var(--kds-easing-standard);
2117
+ }
2118
+
2119
+ .kds-progress::-moz-progress-bar {
2120
+ transition: width var(--kds-transition-standard) var(--kds-easing-standard);
2121
+ }
2122
+
1972
2123
  /* ========================================
1973
2124
  Link Styles
1974
2125
  ======================================== */
@@ -2101,6 +2252,17 @@ body.dark {
2101
2252
  transition: border-color 0.2s, box-shadow 0.2s, outline-color 0.2s;
2102
2253
  }
2103
2254
 
2255
+ /* === TEXTAREA FIX === */
2256
+ /* BeerCSS base sets minimal block padding; add breathing room for textarea */
2257
+ .field > textarea {
2258
+ padding-block: 0.75rem;
2259
+ resize: vertical;
2260
+ }
2261
+
2262
+ .field.label > textarea {
2263
+ padding-block-start: 1.5rem;
2264
+ }
2265
+
2104
2266
  /* ==========================================
2105
2267
  NOTCH VISIBILITY (opacity)
2106
2268
  ========================================== */
@@ -2188,12 +2350,16 @@ body.dark {
2188
2350
  Asegurar que el dropdown arrow sea visible
2189
2351
  ========================================== */
2190
2352
 
2191
- /* Select: mantener appearance nativa para mostrar el dropdown arrow */
2353
+ /* Select: reset nativo + arrow custom via SVG (iOS Safari ignora estilos con appearance:auto) */
2192
2354
  .field select {
2193
- /* BeerCSS puede estar ocultando el arrow, aseguramos que sea visible */
2194
- appearance: auto;
2195
- -webkit-appearance: auto;
2196
- -moz-appearance: auto;
2355
+ -webkit-appearance: none;
2356
+ -moz-appearance: none;
2357
+ appearance: none;
2358
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpath fill='%23333' d='M7 10l5 5 5-5z'/%3E%3C/svg%3E");
2359
+ background-repeat: no-repeat;
2360
+ background-position: right var(--kds-spacing-1) center;
2361
+ background-size: 20px;
2362
+ padding-right: var(--kds-spacing-4) !important;
2197
2363
  }
2198
2364
 
2199
2365
  /* ==========================================
@@ -2325,6 +2491,71 @@ body.dark {
2325
2491
  display: inline-flex;
2326
2492
  }
2327
2493
 
2494
+ /* ========================================
2495
+ Radix Tooltip (.kds-tooltip)
2496
+ Espejo de `.tooltip` pero para popovers de Radix:
2497
+ bg oscuro, texto blanco, sombra + animación fade/slide direccional.
2498
+ ======================================== */
2499
+
2500
+ .kds-tooltip {
2501
+ background-color: var(--kds-color-text-primary);
2502
+ color: var(--kds-color-background-paper);
2503
+ font-family: var(--kds-font-family-primary);
2504
+ font-size: var(--kds-font-size-xs);
2505
+ font-weight: var(--kds-font-weight-medium);
2506
+ line-height: var(--kds-line-height-normal);
2507
+ border-radius: var(--kds-radius-sm);
2508
+ padding: var(--kds-spacing-0-75) var(--kds-spacing-1-5);
2509
+ box-shadow: var(--kds-shadow-4);
2510
+ max-width: 280px;
2511
+ z-index: var(--kds-z-index-tooltip, 1500);
2512
+ user-select: none;
2513
+ /* Animación direccional según Radix data-side — coordinada con copy-row
2514
+ (cubic-bezier 0.2, 0.8, 0.2, 1) para un feel consistente del DS. */
2515
+ animation-duration: 240ms;
2516
+ animation-timing-function: cubic-bezier(0.2, 0.8, 0.2, 1);
2517
+ will-change: transform, opacity;
2518
+ }
2519
+
2520
+ .kds-tooltip[data-state='closed'] {
2521
+ animation-duration: 140ms;
2522
+ animation-timing-function: cubic-bezier(0.4, 0, 0.6, 1);
2523
+ }
2524
+
2525
+ /* Direccional según data-side (Radix añade el attr en runtime).
2526
+ Cada lado entra desde su dirección con ~8px de offset (más visible que 4px). */
2527
+ .kds-tooltip[data-side='top'][data-state='delayed-open'],
2528
+ .kds-tooltip[data-side='top'][data-state='instant-open'] { animation-name: kds-tooltip-in-top; }
2529
+ .kds-tooltip[data-side='bottom'][data-state='delayed-open'],
2530
+ .kds-tooltip[data-side='bottom'][data-state='instant-open'] { animation-name: kds-tooltip-in-bottom; }
2531
+ .kds-tooltip[data-side='left'][data-state='delayed-open'],
2532
+ .kds-tooltip[data-side='left'][data-state='instant-open'] { animation-name: kds-tooltip-in-left; }
2533
+ .kds-tooltip[data-side='right'][data-state='delayed-open'],
2534
+ .kds-tooltip[data-side='right'][data-state='instant-open'] { animation-name: kds-tooltip-in-right; }
2535
+
2536
+ /* Fallback cuando no hay data-side resuelto aún */
2537
+ .kds-tooltip[data-state='delayed-open']:not([data-side]),
2538
+ .kds-tooltip[data-state='instant-open']:not([data-side]) {
2539
+ animation-name: kds-tooltip-in-top;
2540
+ }
2541
+
2542
+ .kds-tooltip[data-state='closed'] { animation-name: kds-tooltip-out; }
2543
+
2544
+ @keyframes kds-tooltip-in-top { from { opacity: 0; transform: translateY(8px) scale(0.96); } to { opacity: 1; transform: none; } }
2545
+ @keyframes kds-tooltip-in-bottom { from { opacity: 0; transform: translateY(-8px) scale(0.96); } to { opacity: 1; transform: none; } }
2546
+ @keyframes kds-tooltip-in-left { from { opacity: 0; transform: translateX(8px) scale(0.96); } to { opacity: 1; transform: none; } }
2547
+ @keyframes kds-tooltip-in-right { from { opacity: 0; transform: translateX(-8px) scale(0.96); } to { opacity: 1; transform: none; } }
2548
+
2549
+ @keyframes kds-tooltip-out {
2550
+ from { opacity: 1; transform: none; }
2551
+ to { opacity: 0; transform: scale(0.96); }
2552
+ }
2553
+
2554
+ /* Arrow (SVG path generado por Radix) */
2555
+ .kds-tooltip-arrow {
2556
+ fill: var(--kds-color-text-primary);
2557
+ }
2558
+
2328
2559
  /* ========================================
2329
2560
  Material Symbols Icon Sizing
2330
2561
  ======================================== */
@@ -2741,7 +2972,8 @@ dialog.modal .field.border:focus-within {
2741
2972
  padding: var(--kds-spacing-2);
2742
2973
  }
2743
2974
 
2744
- .snackbar {
2975
+ .snackbar,
2976
+ .snackbar.active {
2745
2977
  min-width: calc(100% - 32px);
2746
2978
  left: 16px;
2747
2979
  right: 16px;
@@ -3040,6 +3272,32 @@ footer > .kds-container-center {
3040
3272
  color: var(--kds-color-error-dark);
3041
3273
  }
3042
3274
 
3275
+ /* Close button — icon-only, discreto, no usa kds-btn para no romper el flex layout del alert */
3276
+ .kds-alert-close {
3277
+ flex-shrink: 0;
3278
+ display: inline-flex;
3279
+ align-items: center;
3280
+ justify-content: center;
3281
+ width: 28px;
3282
+ height: 28px;
3283
+ padding: 0;
3284
+ background: transparent;
3285
+ border: 0;
3286
+ border-radius: 50%;
3287
+ color: inherit;
3288
+ cursor: pointer;
3289
+ transition: background-color 0.15s ease;
3290
+ }
3291
+
3292
+ .kds-alert-close:hover {
3293
+ background: rgba(0, 0, 0, 0.06);
3294
+ }
3295
+
3296
+ .kds-alert-close i {
3297
+ font-size: 18px;
3298
+ line-height: 1;
3299
+ }
3300
+
3043
3301
  /* Lists inside alerts */
3044
3302
  .kds-alert ul {
3045
3303
  padding-left: var(--kds-spacing-2);
@@ -4036,6 +4294,14 @@ dialog#surveyModal button.circle {
4036
4294
  text-align: center;
4037
4295
  }
4038
4296
 
4297
+ .kds-text-left {
4298
+ text-align: left;
4299
+ }
4300
+
4301
+ .kds-text-right {
4302
+ text-align: right;
4303
+ }
4304
+
4039
4305
  .kds-text-underline {
4040
4306
  text-decoration: underline;
4041
4307
  }
@@ -4052,6 +4318,54 @@ dialog#surveyModal button.circle {
4052
4318
  font-size: var(--kds-font-size-sm);
4053
4319
  }
4054
4320
 
4321
+ /* ── Font-size scale utilities (additive — opt-in companions to .kds-text-sm) ── */
4322
+ .kds-text-base {
4323
+ font-size: var(--kds-font-size-base);
4324
+ }
4325
+
4326
+ .kds-text-lg {
4327
+ font-size: var(--kds-font-size-lg);
4328
+ }
4329
+
4330
+ .kds-text-xl {
4331
+ font-size: var(--kds-font-size-xl);
4332
+ }
4333
+
4334
+ .kds-text-2xl {
4335
+ font-size: var(--kds-font-size-2xl);
4336
+ }
4337
+
4338
+ /* ── Font-weight utilities ── */
4339
+ .kds-fw-regular {
4340
+ font-weight: var(--kds-font-weight-regular);
4341
+ }
4342
+
4343
+ .kds-fw-medium {
4344
+ font-weight: var(--kds-font-weight-medium);
4345
+ }
4346
+
4347
+ .kds-fw-semibold {
4348
+ font-weight: var(--kds-font-weight-semibold);
4349
+ }
4350
+
4351
+ .kds-fw-bold {
4352
+ font-weight: var(--kds-font-weight-bold);
4353
+ }
4354
+
4355
+ /* ── Text-transform utilities ── */
4356
+ .kds-text-transform-none {
4357
+ text-transform: none;
4358
+ }
4359
+
4360
+ /* ── Soft background utilities (semantic muted backgrounds for callouts) ── */
4361
+ .kds-bg-warning-soft {
4362
+ background-color: var(--kds-color-warning-soft);
4363
+ }
4364
+
4365
+ .kds-bg-info-soft {
4366
+ background-color: var(--kds-color-info-soft);
4367
+ }
4368
+
4055
4369
  /* ── Typography variants ── */
4056
4370
  .kds-text-display1 {
4057
4371
  font-family: var(--kds-font-family-primary, 'Public Sans', sans-serif);
@@ -4262,7 +4576,9 @@ dialog#surveyModal button.circle {
4262
4576
  ======================================== */
4263
4577
 
4264
4578
  .kds-badge {
4265
- display: inline-block;
4579
+ display: inline-flex;
4580
+ align-items: center;
4581
+ gap: 4px;
4266
4582
  padding: 2px 8px;
4267
4583
  border-radius: var(--kds-radius-sm);
4268
4584
  font-size: var(--kds-font-size-xs);
@@ -4270,6 +4586,40 @@ dialog#surveyModal button.circle {
4270
4586
  line-height: 1.5;
4271
4587
  }
4272
4588
 
4589
+ /* Icon prefix inside chip — small inline icon */
4590
+ .kds-badge > i.material-symbols-outlined {
4591
+ font-size: 14px;
4592
+ line-height: 1;
4593
+ }
4594
+
4595
+ /* Deletable chip close button — discreto, sin kds-btn (eso lo agrandaba ridículo) */
4596
+ .kds-badge-close {
4597
+ display: inline-flex;
4598
+ align-items: center;
4599
+ justify-content: center;
4600
+ width: 16px;
4601
+ height: 16px;
4602
+ margin-right: -2px;
4603
+ padding: 0;
4604
+ background: transparent;
4605
+ border: 0;
4606
+ border-radius: 50%;
4607
+ color: inherit;
4608
+ cursor: pointer;
4609
+ opacity: 0.7;
4610
+ transition: opacity 0.15s, background-color 0.15s;
4611
+ }
4612
+
4613
+ .kds-badge-close:hover {
4614
+ opacity: 1;
4615
+ background: rgba(0, 0, 0, 0.1);
4616
+ }
4617
+
4618
+ .kds-badge-close i {
4619
+ font-size: 14px;
4620
+ line-height: 1;
4621
+ }
4622
+
4273
4623
  .kds-badge.success {
4274
4624
  background-color: var(--kds-color-success-container);
4275
4625
  color: var(--kds-color-success-dark);
@@ -4548,6 +4898,11 @@ dialog#surveyModal button.circle {
4548
4898
  color: var(--kds-color-text-primary);
4549
4899
  }
4550
4900
 
4901
+ /* Opt-in color modifier — switches the value to the LigoPay/khipu-blue tone */
4902
+ .kds-amount-value--info {
4903
+ color: var(--kds-color-info-blue); /* #5A5FE0 */
4904
+ }
4905
+
4551
4906
  .kds-amount-value small {
4552
4907
  font-size: 18px;
4553
4908
  font-weight: 500;
@@ -4905,7 +5260,7 @@ dialog#surveyModal button.circle {
4905
5260
  display: flex;
4906
5261
  align-items: center;
4907
5262
  justify-content: center;
4908
- gap: var(--kds-spacing-1);
5263
+ gap: var(--kds-spacing-0-5);
4909
5264
  color: var(--kds-color-gray-400);
4910
5265
  font-size: var(--kds-font-size-xs);
4911
5266
  letter-spacing: var(--kds-letter-spacing-wide);
@@ -4917,6 +5272,10 @@ dialog#surveyModal button.circle {
4917
5272
  display: none;
4918
5273
  }
4919
5274
 
5275
+ .kds-screen > form {
5276
+ margin-block-start: 0 !important;
5277
+ }
5278
+
4920
5279
  @media (max-width: 767px) {
4921
5280
  .kds-card-elevated > .kds-secure-footer {
4922
5281
  display: flex;
@@ -4966,14 +5325,20 @@ dialog#surveyModal button.circle {
4966
5325
  cursor: pointer;
4967
5326
  display: inline-flex;
4968
5327
  align-items: center;
4969
- gap: var(--kds-spacing-0-75);
5328
+ gap: 0;
4970
5329
  }
4971
5330
 
4972
- .kds-expand-toggle:hover {
5331
+ .kds-expand-toggle:hover,
5332
+ .kds-expand-toggle:focus,
5333
+ .kds-expand-toggle:active {
4973
5334
  background: transparent;
5335
+ outline: none;
5336
+ box-shadow: none;
4974
5337
  }
4975
5338
 
4976
- .kds-expand-toggle:hover span {
5339
+ .kds-expand-toggle:hover span,
5340
+ .kds-expand-toggle:focus span,
5341
+ .kds-expand-toggle:active span {
4977
5342
  text-decoration: underline;
4978
5343
  }
4979
5344
 
@@ -5153,11 +5518,11 @@ dialog#surveyModal button.circle {
5153
5518
  color: var(--kds-color-success-main);
5154
5519
  }
5155
5520
 
5156
- /* Variant: pending (animated spinner) */
5521
+ /* Variant: pending (animated blue spinner, sin icono interno) */
5157
5522
  .kds-status-block[data-status="pending"] .kds-status-block-icon {
5158
5523
  background: transparent;
5159
5524
  border: 3px solid var(--kds-color-divider);
5160
- border-top-color: var(--kds-color-primary-main);
5525
+ border-top-color: var(--kds-color-info-main);
5161
5526
  animation: kds-spin 1s linear infinite;
5162
5527
  }
5163
5528
 
@@ -5175,12 +5540,21 @@ dialog#surveyModal button.circle {
5175
5540
  color: var(--kds-color-error-main);
5176
5541
  }
5177
5542
 
5543
+ /* Variant: info — usar SIEMPRE con icon "info_i" (i minúscula sin glyph circular)
5544
+ para que solo se vea nuestro círculo decorativo. Iconos como "info" tienen
5545
+ su propio círculo built-in → causarían doble círculo. */
5546
+ .kds-status-block[data-status="info"] .kds-status-block-icon {
5547
+ background: var(--kds-color-info-soft);
5548
+ border: var(--kds-border-width-md) solid var(--kds-color-info-main);
5549
+ color: var(--kds-color-info-main);
5550
+ }
5551
+
5178
5552
  /* Inline variant: icon left + text right */
5179
5553
  .kds-status-block.inline {
5180
5554
  text-align: left;
5181
5555
  display: flex;
5182
5556
  align-items: center;
5183
- gap: var(--kds-spacing-3);
5557
+ gap: var(--kds-spacing-2);
5184
5558
  padding: var(--kds-spacing-1) 0;
5185
5559
  }
5186
5560
 
@@ -5242,6 +5616,40 @@ dialog#surveyModal button.circle {
5242
5616
  background: var(--kds-color-divider);
5243
5617
  }
5244
5618
 
5619
+ /* Close button — top-right discreto, NO usa kds-btn (rompía el flex layout) */
5620
+ .kds-bottom-sheet-close {
5621
+ position: absolute;
5622
+ top: var(--kds-spacing-1);
5623
+ right: var(--kds-spacing-1);
5624
+ width: 32px;
5625
+ height: 32px;
5626
+ display: inline-flex;
5627
+ align-items: center;
5628
+ justify-content: center;
5629
+ padding: 0;
5630
+ background: transparent;
5631
+ border: 0;
5632
+ border-radius: 50%;
5633
+ color: var(--kds-color-text-secondary);
5634
+ cursor: pointer;
5635
+ transition: background-color 0.15s ease;
5636
+ }
5637
+
5638
+ .kds-bottom-sheet-close:hover {
5639
+ background: rgba(0, 0, 0, 0.06);
5640
+ }
5641
+
5642
+ .kds-bottom-sheet-close i {
5643
+ font-size: 20px;
5644
+ line-height: 1;
5645
+ }
5646
+
5647
+ /* Body container — separa el content del title/actions */
5648
+ .kds-bottom-sheet-body {
5649
+ text-align: left;
5650
+ margin-top: var(--kds-spacing-1);
5651
+ }
5652
+
5245
5653
  .kds-bottom-sheet-icon {
5246
5654
  font-size: var(--kds-font-size-4xl);
5247
5655
  }
@@ -5571,6 +5979,13 @@ div.kds-invoice-header,
5571
5979
  align-content: initial;
5572
5980
  }
5573
5981
 
5982
+ /* Mobile collapsed state: center-align so merchant tile aligns with the smaller amount */
5983
+ @media (max-width: 767px) {
5984
+ .kds-invoice-sticky.is-collapsed .kds-invoice-header {
5985
+ align-items: center;
5986
+ }
5987
+ }
5988
+
5574
5989
  /* Reset BeerCSS sibling margin on <p> inside invoice header — specificity (0,4,1) ties BeerCSS, wins by source order */
5575
5990
  .kds-card-elevated.kds-invoice-sticky .kds-invoice-header p.kds-invoice-amount,
5576
5991
  .kds-card-elevated.kds-invoice-sticky .kds-invoice-header p.kds-invoice-code {
@@ -5578,7 +5993,7 @@ div.kds-invoice-header,
5578
5993
  }
5579
5994
 
5580
5995
  .kds-invoice-amount {
5581
- font-weight: var(--kds-font-weight-bold);
5996
+ font-weight: var(--kds-font-weight-semibold);
5582
5997
  font-size: var(--kds-font-size-3xl);
5583
5998
  line-height: var(--kds-line-height-tight);
5584
5999
  letter-spacing: var(--kds-letter-spacing-wide);
@@ -5599,10 +6014,16 @@ div.kds-invoice-header,
5599
6014
  color: var(--kds-color-gray-400);
5600
6015
  text-transform: uppercase;
5601
6016
  margin: 0;
5602
- margin-top: var(--kds-spacing-1);
6017
+ margin-block: unset;
6018
+ display: flex;
6019
+ gap: var(--kds-spacing-1-5);
5603
6020
  }
5604
6021
 
5605
6022
  .kds-invoice-code-value {
6023
+ color: var(--kds-color-gray-400);
6024
+ }
6025
+
6026
+ .kds-invoice-code-value--lowercase {
5606
6027
  text-transform: lowercase;
5607
6028
  }
5608
6029
 
@@ -5615,6 +6036,9 @@ div.kds-invoice-header,
5615
6036
  place-items: center;
5616
6037
  color: #fff;
5617
6038
  flex-shrink: 0;
6039
+ /* Clip the slightly-oversized logo (see `.kds-invoice-merchant img`) to the
6040
+ rounded square so it can fully cover the deep-purple background. */
6041
+ overflow: hidden;
5618
6042
  }
5619
6043
 
5620
6044
  .kds-invoice-merchant i {
@@ -5634,15 +6058,18 @@ div.kds-invoice-header,
5634
6058
  }
5635
6059
 
5636
6060
  .kds-invoice-merchant img {
5637
- width: 100%;
5638
- height: 100%;
6061
+ /* Slightly larger than the container (+2px, centered by the grid) so the
6062
+ logo overflows under the parent's rounded clip and the deep-purple
6063
+ background never peeks through at the corners when the logo shrinks. */
6064
+ width: calc(100% + 2px);
6065
+ height: calc(100% + 2px);
5639
6066
  object-fit: cover;
5640
6067
  border-radius: var(--kds-radius-md);
5641
6068
  }
5642
6069
 
5643
6070
  /* -- Card Title -- */
5644
6071
  .kds-card-title {
5645
- font-weight: 700;
6072
+ font-weight: var(--kds-font-weight-semibold);
5646
6073
  font-size: var(--kds-font-size-base);
5647
6074
  line-height: 1.5;
5648
6075
  letter-spacing: -0.31px;
@@ -5650,12 +6077,22 @@ div.kds-invoice-header,
5650
6077
  margin-bottom: var(--kds-spacing-2) !important;
5651
6078
  }
5652
6079
 
6080
+ /* Opt-in size modifiers (additive — do NOT change default 16/600) */
6081
+ .kds-card-title--lg {
6082
+ font-size: var(--kds-font-size-xl); /* 20px */
6083
+ font-weight: var(--kds-font-weight-semibold);
6084
+ }
6085
+
6086
+ .kds-card-title--xl {
6087
+ font-size: var(--kds-font-size-2xl); /* 24px */
6088
+ font-weight: var(--kds-font-weight-semibold);
6089
+ }
6090
+
5653
6091
  /* -- Key-Value Grid -- */
5654
6092
  .kds-kv {
5655
6093
  display: grid;
5656
6094
  grid-template-columns: auto 1fr;
5657
- row-gap: var(--kds-spacing-1);
5658
- column-gap: var(--kds-spacing-1-5);
6095
+ column-gap: var(--kds-spacing-1);
5659
6096
  align-items: baseline;
5660
6097
  }
5661
6098
 
@@ -5672,7 +6109,7 @@ div.kds-invoice-header,
5672
6109
  margin: 0;
5673
6110
  font-size: var(--kds-font-size-sm);
5674
6111
  line-height: var(--kds-line-height-relaxed);
5675
- font-weight: var(--kds-font-weight-bold);
6112
+ font-weight: var(--kds-font-weight-semibold);
5676
6113
  letter-spacing: normal;
5677
6114
  color: var(--kds-color-gray-800);
5678
6115
  min-width: 0;
@@ -5702,7 +6139,13 @@ div.kds-invoice-header,
5702
6139
  flex-direction: column;
5703
6140
  gap: var(--kds-spacing-1-5);
5704
6141
  margin: 0;
5705
- padding: 0 0 var(--kds-spacing-1);
6142
+ padding: 0;
6143
+ }
6144
+
6145
+ @media (max-width: 767px) {
6146
+ .kds-detail-list {
6147
+ padding-bottom: var(--kds-spacing-2);
6148
+ }
5706
6149
  }
5707
6150
 
5708
6151
  .kds-detail-group {
@@ -5718,7 +6161,6 @@ div.kds-invoice-header,
5718
6161
  letter-spacing: var(--kds-letter-spacing-wide);
5719
6162
  color: var(--kds-color-text-hint);
5720
6163
  text-transform: uppercase;
5721
- margin: 0 0 var(--kds-spacing-0-5);
5722
6164
  }
5723
6165
 
5724
6166
  .kds-detail-group dd {
@@ -5787,16 +6229,16 @@ div.kds-invoice-header,
5787
6229
  font-size: var(--kds-font-size-sm);
5788
6230
  }
5789
6231
 
5790
- .kds-recap-list .k {
6232
+ .kds-recap-list .kds-key {
5791
6233
  color: var(--kds-color-text-secondary);
5792
6234
  }
5793
6235
 
5794
- .kds-recap-list .v {
6236
+ .kds-recap-list .kds-value {
5795
6237
  color: var(--kds-color-text-primary);
5796
6238
  font-weight: 500;
5797
6239
  }
5798
6240
 
5799
- .kds-recap-list .v.placeholder {
6241
+ .kds-recap-list .kds-value.placeholder {
5800
6242
  color: var(--kds-color-text-hint);
5801
6243
  }
5802
6244
 
@@ -5823,6 +6265,72 @@ a.kds-btn-success:disabled {
5823
6265
  box-shadow: none;
5824
6266
  }
5825
6267
 
6268
+ /* -- Button Warning (amber CTA) -- */
6269
+ button.kds-btn-warning,
6270
+ a.kds-btn-warning {
6271
+ background: var(--kds-color-warning-main);
6272
+ color: var(--kds-color-warning-contrast);
6273
+ border: none;
6274
+ }
6275
+
6276
+ button.kds-btn-warning:hover:not(:disabled),
6277
+ a.kds-btn-warning:hover:not(:disabled) {
6278
+ background: var(--kds-color-warning-dark);
6279
+ }
6280
+
6281
+ button.kds-btn-warning:active:not(:disabled),
6282
+ button.kds-btn-warning:focus-visible:not(:disabled),
6283
+ a.kds-btn-warning:active:not(:disabled),
6284
+ a.kds-btn-warning:focus-visible:not(:disabled) {
6285
+ background: var(--kds-color-warning-dark);
6286
+ outline: 2px solid var(--kds-color-warning-main);
6287
+ outline-offset: 2px;
6288
+ }
6289
+
6290
+ button.kds-btn-warning:disabled,
6291
+ a.kds-btn-warning:disabled {
6292
+ background-color: var(--kds-color-action-disabled-bg);
6293
+ color: var(--kds-color-action-disabled);
6294
+ box-shadow: none;
6295
+ }
6296
+
6297
+ button.kds-btn-warning::after {
6298
+ display: none;
6299
+ }
6300
+
6301
+ /* -- Button Error (red / destructive CTA) -- */
6302
+ button.kds-btn-error,
6303
+ a.kds-btn-error {
6304
+ background: var(--kds-color-error-main);
6305
+ color: var(--kds-color-error-contrast);
6306
+ border: none;
6307
+ }
6308
+
6309
+ button.kds-btn-error:hover:not(:disabled),
6310
+ a.kds-btn-error:hover:not(:disabled) {
6311
+ background: var(--kds-color-error-dark);
6312
+ }
6313
+
6314
+ button.kds-btn-error:active:not(:disabled),
6315
+ button.kds-btn-error:focus-visible:not(:disabled),
6316
+ a.kds-btn-error:active:not(:disabled),
6317
+ a.kds-btn-error:focus-visible:not(:disabled) {
6318
+ background: var(--kds-color-error-dark);
6319
+ outline: 2px solid var(--kds-color-error-main);
6320
+ outline-offset: 2px;
6321
+ }
6322
+
6323
+ button.kds-btn-error:disabled,
6324
+ a.kds-btn-error:disabled {
6325
+ background-color: var(--kds-color-action-disabled-bg);
6326
+ color: var(--kds-color-action-disabled);
6327
+ box-shadow: none;
6328
+ }
6329
+
6330
+ button.kds-btn-error::after {
6331
+ display: none;
6332
+ }
6333
+
5826
6334
  /* -- Field Helper Text -- */
5827
6335
  .kds-field-helper {
5828
6336
  font-size: var(--kds-font-size-xs);
@@ -5865,6 +6373,8 @@ button.kds-btn-success::after {
5865
6373
  /* -- Alert inline (borderless, used inside cards) -- */
5866
6374
  .kds-alert-inline {
5867
6375
  border: none;
6376
+ padding: var(--kds-spacing-1) var(--kds-spacing-1-5);
6377
+ margin-bottom: var(--kds-spacing-1-5);
5868
6378
  }
5869
6379
 
5870
6380
  /* -- Card dimmed (behind overlays) -- */
@@ -5966,17 +6476,42 @@ button.kds-btn-success::after {
5966
6476
  }
5967
6477
 
5968
6478
  .kds-bill-description-picture {
5969
- width: 120px;
5970
- height: 120px;
6479
+ max-width: 100px;
5971
6480
  object-fit: contain;
5972
6481
  background: var(--kds-color-background-paper);
5973
- padding: var(--kds-spacing-1-25);
5974
- border-radius: var(--kds-radius-md);
5975
- margin-top: var(--kds-spacing-1);
6482
+ margin-top: var(--kds-spacing-1-25);
5976
6483
  display: block;
5977
6484
  box-sizing: content-box;
5978
6485
  }
5979
6486
 
6487
+ /* -- Bill Attachments -- */
6488
+ .kds-bill-attachments {
6489
+ display: flex;
6490
+ flex-direction: column;
6491
+ gap: var(--kds-spacing-0-75);
6492
+ }
6493
+
6494
+ .kds-bill-attachment {
6495
+ display: inline-flex;
6496
+ align-items: center;
6497
+ justify-content: flex-start;
6498
+ width: fit-content;
6499
+ color: var(--kds-color-info-main);
6500
+ font-size: var(--kds-font-size-sm);
6501
+ font-weight: var(--kds-font-weight-medium);
6502
+ text-decoration: none;
6503
+ }
6504
+
6505
+ .kds-bill-attachment:hover span {
6506
+ text-decoration: underline;
6507
+ }
6508
+
6509
+ .kds-bill-attachment i {
6510
+ font-size: var(--kds-font-size-lg);
6511
+ min-width: unset;
6512
+ justify-content: flex-start;
6513
+ }
6514
+
5980
6515
  /* -- Share Card (mustContinue) -- */
5981
6516
  .kds-share-card {
5982
6517
  margin-top: var(--kds-spacing-2);
@@ -6089,6 +6624,14 @@ button.kds-btn-success::after {
6089
6624
  padding-top: 0;
6090
6625
  padding-bottom: 0;
6091
6626
  }
6627
+
6628
+ /* Reset BeerCSS sibling margin on form/section inside payment cards.
6629
+ BeerCSS sets `:not(.grid,nav,.row) > … + form/section { margin-block-start:1rem }`
6630
+ which adds unwanted spacing inside cards that contain forms. */
6631
+ .kds-payment-flow .kds-card-elevated > form,
6632
+ .kds-payment-flow .kds-card-elevated > section {
6633
+ margin-block-start: 0;
6634
+ }
6092
6635
  .kds-payment-flow .kds-card-elevated.kds-invoice-sticky {
6093
6636
  padding-top: var(--kds-spacing-1);
6094
6637
  padding-bottom: 0;
@@ -6138,10 +6681,17 @@ button.kds-btn-success::after {
6138
6681
  padding-bottom: var(--kds-spacing-2);
6139
6682
  }
6140
6683
 
6141
- /* Invoice sticky card: progressive padding-top (expanded 20px → collapsed 8px).
6142
- Overrides base rule at same specificity; source order wins here. */
6684
+ /* Invoice sticky card padding (mobile).
6685
+ Top: estático 12px. Bottom: progresivo 20px (expandido) 8px (colapsado).
6686
+ El padding-bottom animado da breathing room natural cuando expandido y se
6687
+ reduce convencionalmente al colapsar — sin depender de que el clip-path
6688
+ corte el padding abruptamente. */
6143
6689
  .kds-payment-flow .kds-card-elevated.kds-invoice-sticky {
6144
6690
  padding-top: var(--kds-spacing-1-5);
6691
+ padding-bottom: calc(
6692
+ var(--kds-spacing-2-5)
6693
+ - var(--kds-spacing-1-5) * var(--collapse-progress, 0)
6694
+ );
6145
6695
  }
6146
6696
 
6147
6697
 
@@ -6180,7 +6730,8 @@ button.kds-btn-success::after {
6180
6730
  }
6181
6731
  .kds-brand-inner svg,
6182
6732
  .kds-brand-inner img {
6183
- height: 22px;
6733
+ width: calc(50px - 16px * var(--collapse-progress, 0));
6734
+ height: auto;
6184
6735
  display: block;
6185
6736
  }
6186
6737
 
@@ -6399,7 +6950,7 @@ button.kds-btn-success::after {
6399
6950
  inset: 0;
6400
6951
  background: var(--kds-modal-backdrop);
6401
6952
  display: none;
6402
- align-items: center;
6953
+ align-items: flex-start;
6403
6954
  justify-content: center;
6404
6955
  z-index: var(--kds-z-index-modal, 50);
6405
6956
  animation: kds-fade 0.2s ease both;
@@ -6427,7 +6978,7 @@ button.kds-btn-success::after {
6427
6978
  display: flex;
6428
6979
  align-items: center;
6429
6980
  justify-content: space-between;
6430
- padding: var(--kds-spacing-2) var(--kds-spacing-2) var(--kds-spacing-1);
6981
+ padding: var(--kds-spacing-1) var(--kds-spacing-2) var(--kds-spacing-1);
6431
6982
  }
6432
6983
 
6433
6984
  .kds-bank-modal-header h3 {
@@ -6574,7 +7125,7 @@ button.kds-btn-success::after {
6574
7125
  min-width: 0;
6575
7126
  }
6576
7127
 
6577
- .kds-qr-text .title {
7128
+ .kds-qr-text .kds-qr-title {
6578
7129
  font-family: var(--kds-font-family-primary);
6579
7130
  font-weight: 600;
6580
7131
  font-size: var(--kds-font-size-sm);
@@ -6582,10 +7133,15 @@ button.kds-btn-success::after {
6582
7133
  color: var(--kds-color-text-primary);
6583
7134
  }
6584
7135
 
6585
- .kds-qr-text .sub {
7136
+ .kds-qr-text .kds-qr-subtitle {
6586
7137
  font-family: var(--kds-font-family-primary);
6587
7138
  font-size: var(--kds-font-size-caption);
6588
7139
  color: var(--kds-color-text-secondary);
7140
+ /* Trunca con ellipsis en lugar de wrap a 2 líneas — evita apretar el row
7141
+ cuando el contenedor es angosto (mobile o decorator constrained). */
7142
+ overflow: hidden;
7143
+ text-overflow: ellipsis;
7144
+ white-space: nowrap;
6589
7145
  }
6590
7146
 
6591
7147
  /* QR Badge - "Rápido" indicator */
@@ -6608,46 +7164,26 @@ button.kds-btn-success::after {
6608
7164
  font-size: 20px;
6609
7165
  }
6610
7166
 
6611
- /* Mobile responsive: Ajustes para pantallas pequeñas */
7167
+ /* Mobile responsive (≤480px): respira más mantenemos padding/gap/avatar igual
7168
+ que desktop y solo agregamos truncation al subtitle y `flex-shrink: 0` en los
7169
+ ítems que deben mantener su tamaño (avatar, badge, chevron). */
6612
7170
  @media (max-width: 480px) {
6613
- .kds-qr-row {
6614
- gap: var(--kds-spacing-1-5);
6615
- padding: var(--kds-spacing-1-5);
6616
- }
6617
-
6618
7171
  .kds-qr-avatar {
6619
- width: var(--kds-spacing-4-5);
6620
- height: var(--kds-spacing-4-5);
6621
7172
  flex-shrink: 0;
6622
7173
  }
6623
7174
 
6624
- .kds-qr-avatar .material-symbols-outlined,
6625
- .kds-qr-avatar .material-icons-round {
6626
- font-size: var(--kds-font-size-lg);
6627
- }
6628
-
6629
- .kds-qr-text .title {
6630
- font-size: var(--kds-font-size-xs);
6631
- line-height: var(--kds-line-height-tight);
6632
- }
6633
-
6634
7175
  .kds-qr-text .sub {
6635
- font-size: var(--kds-font-size-caption);
6636
- line-height: var(--kds-line-height-tight);
6637
7176
  overflow: hidden;
6638
7177
  text-overflow: ellipsis;
6639
7178
  white-space: nowrap;
6640
7179
  }
6641
7180
 
6642
7181
  .kds-qr-badge {
6643
- font-size: var(--kds-font-size-caption);
6644
- padding: var(--kds-spacing-0-25) var(--kds-spacing-0-75);
6645
7182
  flex-shrink: 0;
6646
7183
  }
6647
7184
 
6648
7185
  .kds-qr-row .material-symbols-outlined:last-child,
6649
7186
  .kds-qr-row .material-icons-round:last-child {
6650
- font-size: var(--kds-font-size-base);
6651
7187
  flex-shrink: 0;
6652
7188
  }
6653
7189
  }
@@ -6676,7 +7212,11 @@ button.kds-btn-success::after {
6676
7212
  border-radius: var(--kds-spacing-0-75);
6677
7213
  font-size: var(--kds-font-size-sm);
6678
7214
  cursor: pointer;
6679
- transition: background 0.12s ease;
7215
+ /* Transición más amplia y suave: bg + color + border ease-out */
7216
+ transition:
7217
+ background-color 280ms cubic-bezier(0.2, 0.8, 0.2, 1),
7218
+ color 280ms cubic-bezier(0.2, 0.8, 0.2, 1),
7219
+ border-top-color 280ms ease-out;
6680
7220
  position: relative;
6681
7221
  user-select: none;
6682
7222
  }
@@ -6685,19 +7225,21 @@ button.kds-btn-success::after {
6685
7225
  border-top: 0;
6686
7226
  }
6687
7227
 
6688
- .kds-copyable-table-row:hover {
7228
+ /* Hover NO aplica mientras la row esté en `.copied` o `.settling`
7229
+ (evita el flicker del hover state al desaparecer el verde de "copiado") */
7230
+ .kds-copyable-table-row:not(.copied):not(.settling):hover {
6689
7231
  background: var(--kds-color-primary-faint);
6690
7232
  }
6691
7233
 
6692
- .kds-copyable-table-row:hover + .kds-copyable-table-row {
7234
+ .kds-copyable-table-row:not(.copied):not(.settling):hover + .kds-copyable-table-row {
6693
7235
  border-top-color: transparent;
6694
7236
  }
6695
7237
 
6696
- .kds-copyable-table-row:active {
7238
+ .kds-copyable-table-row:not(.copied):not(.settling):active {
6697
7239
  background: var(--kds-color-primary-selected);
6698
7240
  }
6699
7241
 
6700
- .kds-copyable-table-row .k {
7242
+ .kds-copyable-table-row .kds-key {
6701
7243
  color: var(--kds-color-text-secondary);
6702
7244
  font-size: var(--kds-font-size-caption);
6703
7245
  letter-spacing: 0.3px;
@@ -6706,7 +7248,7 @@ button.kds-btn-success::after {
6706
7248
  flex: 0 0 auto;
6707
7249
  }
6708
7250
 
6709
- .kds-copyable-table-row .v {
7251
+ .kds-copyable-table-row .kds-value {
6710
7252
  color: var(--kds-color-text-primary);
6711
7253
  font-family: 'JetBrains Mono', 'SF Mono', ui-monospace, Menlo, Consolas, monospace;
6712
7254
  font-weight: var(--kds-font-weight-medium);
@@ -6722,17 +7264,18 @@ button.kds-btn-success::after {
6722
7264
  flex: 1 1 auto;
6723
7265
  }
6724
7266
 
6725
- .kds-copyable-table-row .v::after {
7267
+ .kds-copyable-table-row .kds-value::after {
6726
7268
  content: 'content_copy';
6727
7269
  font-family: 'Material Symbols Outlined';
6728
7270
  font-size: var(--kds-font-size-sm);
6729
7271
  color: var(--kds-color-primary-main);
6730
7272
  opacity: 0;
6731
- transition: opacity 0.12s ease;
7273
+ /* Transición coordinada con la row */
7274
+ transition: opacity 280ms cubic-bezier(0.2, 0.8, 0.2, 1);
6732
7275
  flex: 0 0 auto;
6733
7276
  }
6734
7277
 
6735
- .kds-copyable-table-row:hover .v::after {
7278
+ .kds-copyable-table-row:not(.copied):not(.settling):hover .kds-value::after {
6736
7279
  opacity: 0.7;
6737
7280
  }
6738
7281
 
@@ -6740,17 +7283,25 @@ button.kds-btn-success::after {
6740
7283
  background: var(--kds-color-success-soft);
6741
7284
  }
6742
7285
 
6743
- .kds-copyable-table-row.copied .v {
7286
+ .kds-copyable-table-row.copied .kds-value {
6744
7287
  color: var(--kds-color-success-dark);
6745
7288
  }
6746
7289
 
6747
- .kds-copyable-table-row.copied .v::after {
7290
+ .kds-copyable-table-row.copied .kds-value::after {
6748
7291
  content: 'check';
6749
7292
  font-family: 'Material Symbols Outlined';
6750
7293
  color: var(--kds-color-success-dark);
6751
7294
  opacity: 1;
6752
7295
  }
6753
7296
 
7297
+ /* `.settling`: estado de "recién copiado" — la row vuelve al normal sin
7298
+ activar hover. Dura lo mismo que la transición (~300ms) y se aplica
7299
+ desde React tras quitar `.copied`. */
7300
+ .kds-copyable-table-row.settling .kds-value::after {
7301
+ /* Mantén el check con opacity 0 mientras settling, fade out suave */
7302
+ opacity: 0;
7303
+ }
7304
+
6754
7305
  /* Disable BeerCSS ripple on copyable table rows */
6755
7306
  .kds-copyable-table-row::after {
6756
7307
  display: none;
@@ -6813,6 +7364,14 @@ a.kds-copy-all-btn.copied:hover {
6813
7364
  min-height: unset;
6814
7365
  }
6815
7366
 
7367
+ /* Severity variants — default stays warning (backward-compatible) */
7368
+ .kds-section-note.kds-info { color: var(--kds-color-info-dark); }
7369
+ .kds-section-note.kds-info > i { color: var(--kds-color-info-dark); }
7370
+ .kds-section-note.kds-success { color: var(--kds-color-success-dark); }
7371
+ .kds-section-note.kds-success > i { color: var(--kds-color-success-dark); }
7372
+ .kds-section-note.kds-error { color: var(--kds-color-error-dark); }
7373
+ .kds-section-note.kds-error > i { color: var(--kds-color-error-dark); }
7374
+
6816
7375
  /* ========================================
6817
7376
  INFO TOOLTIP (.kds-info-tip)
6818
7377
  Inline info button with hover/click tooltip bubble.
@@ -6908,7 +7467,7 @@ a.kds-copy-all-btn.copied:hover {
6908
7467
  .kds-monto-row {
6909
7468
  display: flex;
6910
7469
  justify-content: space-between;
6911
- align-items: flex-end;
7470
+ align-items: flex-start;
6912
7471
  padding: var(--kds-spacing-1-75) 0 var(--kds-spacing-1);
6913
7472
  border-top: 1px dashed var(--kds-color-divider);
6914
7473
  margin-top: var(--kds-spacing-1-75);
@@ -6932,3 +7491,191 @@ a.kds-copy-all-btn.copied:hover {
6932
7491
  color: var(--kds-color-text-primary);
6933
7492
  }
6934
7493
 
7494
+ /* ========================================
7495
+ PAYMENT TOTAL (.kds-payment-total)
7496
+ Bloque "monto a pagar" para QR view y email templates.
7497
+ Portado desde paylink-ligopay → <kh:paymentTotal> + materialize-config.css.
7498
+ Variantes:
7499
+ - default: amount grande (3rem) en color primario Khipu.
7500
+ - email: amount compacto (1.5rem) en color texto primario.
7501
+ Responsive (default): mobile (≤ 1024px) centra y oculta titleMobile.
7502
+ ======================================== */
7503
+
7504
+ .kds-payment-total {
7505
+ /* Component-scoped tokens — overrideables sin tocar el CSS global. */
7506
+ --kds-payment-total-title-size: var(--kds-font-size-2xl); /* 24px */
7507
+ --kds-payment-total-label-size: var(--kds-font-size-xl); /* 20px */
7508
+ --kds-payment-amount-size: 3rem; /* 48px — destacado */
7509
+ --kds-payment-amount-line-height: var(--kds-line-height-snug);
7510
+ --kds-payment-amount-color: var(--kds-color-primary-main);
7511
+ --kds-payment-amount-weight: var(--kds-font-weight-medium);
7512
+
7513
+ text-align: left;
7514
+ }
7515
+
7516
+ .kds-payment-total-title,
7517
+ .kds-payment-total-title-mobile {
7518
+ font-size: var(--kds-payment-total-title-size);
7519
+ font-weight: var(--kds-font-weight-semibold);
7520
+ color: var(--kds-color-text-primary);
7521
+ margin-bottom: var(--kds-spacing-4);
7522
+ }
7523
+
7524
+ .kds-payment-total-title-mobile {
7525
+ display: none;
7526
+ }
7527
+
7528
+ .kds-payment-total .kds-payment-label {
7529
+ font-size: var(--kds-payment-total-label-size);
7530
+ font-weight: var(--kds-font-weight-semibold);
7531
+ color: var(--kds-color-text-primary);
7532
+ margin-bottom: var(--kds-spacing-1);
7533
+ padding-top: 0;
7534
+ }
7535
+
7536
+ .kds-payment-total .kds-payment-amount {
7537
+ font-size: var(--kds-payment-amount-size);
7538
+ font-weight: var(--kds-payment-amount-weight);
7539
+ line-height: var(--kds-payment-amount-line-height);
7540
+ color: var(--kds-payment-amount-color);
7541
+ margin-bottom: var(--kds-spacing-4);
7542
+ }
7543
+
7544
+ .kds-payment-total .kds-payment-amount .kds-payment-total-decimal-sup,
7545
+ .kds-invoice-amount .kds-payment-total-decimal-sup {
7546
+ font-size: var(--kds-font-size-decimal-sup);
7547
+ font-weight: var(--kds-font-weight-semibold);
7548
+ position: relative;
7549
+ top: 0;
7550
+ }
7551
+
7552
+ /* Variante email: amount compacto en color texto primario, alineación izquierda fija */
7553
+ .kds-payment-total--email {
7554
+ --kds-payment-amount-size: var(--kds-font-size-2xl); /* 24px */
7555
+ --kds-payment-amount-line-height: var(--kds-line-height-snug);
7556
+ --kds-payment-amount-color: var(--kds-color-text-primary);
7557
+ --kds-payment-amount-weight: var(--kds-font-weight-semibold);
7558
+ }
7559
+
7560
+ /* Tone modifier: swaps the amount color to the khipu-blue / LigoPay info blue.
7561
+ Combinable with --email or with the default variant. */
7562
+ .kds-payment-total--tone-info {
7563
+ --kds-payment-amount-color: var(--kds-color-info-blue); /* #5A5FE0 */
7564
+ }
7565
+
7566
+ /* Centered modifier: removes the asymmetric desktop padding (which exists for
7567
+ LigoPay QR view) and centers all internal text. Composable with --email and
7568
+ --tone-info. */
7569
+ .kds-payment-total--centered {
7570
+ padding-left: 0;
7571
+ padding-top: 0;
7572
+ text-align: center;
7573
+ }
7574
+ .kds-payment-total--centered .kds-payment-total-title,
7575
+ .kds-payment-total--centered .kds-payment-total-title-mobile,
7576
+ .kds-payment-total--centered .kds-payment-label,
7577
+ .kds-payment-total--centered .kds-payment-amount {
7578
+ text-align: center;
7579
+ }
7580
+
7581
+ /* Responsive: mobile ≤ 1024px — centra y conmuta los títulos (sólo variante default) */
7582
+ @media (max-width: 1024px) {
7583
+ .kds-payment-total {
7584
+ text-align: center;
7585
+ }
7586
+
7587
+ .kds-payment-total .kds-payment-total-title {
7588
+ display: none;
7589
+ }
7590
+
7591
+ .kds-payment-total .kds-payment-total-title-mobile {
7592
+ display: block;
7593
+ text-align: center;
7594
+ }
7595
+
7596
+ .kds-payment-total .kds-payment-label,
7597
+ .kds-payment-total .kds-payment-amount {
7598
+ text-align: center;
7599
+ }
7600
+
7601
+ /* Email mantiene alineación izquierda incluso en mobile (matchea email clients) */
7602
+ .kds-payment-total--email,
7603
+ .kds-payment-total--email .kds-payment-label,
7604
+ .kds-payment-total--email .kds-payment-amount {
7605
+ text-align: left;
7606
+ }
7607
+ }
7608
+
7609
+ /* ==========================================================================
7610
+ GRID UTILITIES — semantic aliases for BeerCSS .grid / .s* / .m* / .l*
7611
+
7612
+ Estas utilidades son ALIAS de las clases cortas de BeerCSS para que
7613
+ consumers (payment, LigoPay, Grails legacy) puedan escribir markup con
7614
+ nombres descriptivos sin renunciar al grid de 12 columnas de BeerCSS.
7615
+
7616
+ Convención (estilo Bootstrap responsive):
7617
+ - kds-grid → .grid (12-col CSS grid + 1rem gap)
7618
+ - kds-col-sm-{1..12} → .s{1..12} (mobile, siempre aplica)
7619
+ - kds-col-md-{1..12} → .m{1..12} (>=601px)
7620
+ - kds-col-lg-{1..12} → .l{1..12} (>=993px)
7621
+
7622
+ Las definiciones originales de BeerCSS NO se tocan; estas son aditivas.
7623
+ ========================================================================== */
7624
+
7625
+ .kds-grid {
7626
+ --_gap: 1rem;
7627
+ display: grid;
7628
+ grid-template-columns: repeat(12, 1fr);
7629
+ gap: var(--_gap);
7630
+ block-size: auto;
7631
+ }
7632
+
7633
+ .kds-grid.kds-grid-no-space { --_gap: 0rem; }
7634
+ .kds-grid.kds-grid-medium-space { --_gap: 1.5rem; }
7635
+ .kds-grid.kds-grid-large-space { --_gap: 2rem; }
7636
+
7637
+ .kds-grid > * { margin: 0; }
7638
+
7639
+ .kds-col-sm-1 { grid-area: auto/span 1; }
7640
+ .kds-col-sm-2 { grid-area: auto/span 2; }
7641
+ .kds-col-sm-3 { grid-area: auto/span 3; }
7642
+ .kds-col-sm-4 { grid-area: auto/span 4; }
7643
+ .kds-col-sm-5 { grid-area: auto/span 5; }
7644
+ .kds-col-sm-6 { grid-area: auto/span 6; }
7645
+ .kds-col-sm-7 { grid-area: auto/span 7; }
7646
+ .kds-col-sm-8 { grid-area: auto/span 8; }
7647
+ .kds-col-sm-9 { grid-area: auto/span 9; }
7648
+ .kds-col-sm-10 { grid-area: auto/span 10; }
7649
+ .kds-col-sm-11 { grid-area: auto/span 11; }
7650
+ .kds-col-sm-12 { grid-area: auto/span 12; }
7651
+
7652
+ @media only screen and (min-width: 601px) {
7653
+ .kds-col-md-1 { grid-area: auto/span 1; }
7654
+ .kds-col-md-2 { grid-area: auto/span 2; }
7655
+ .kds-col-md-3 { grid-area: auto/span 3; }
7656
+ .kds-col-md-4 { grid-area: auto/span 4; }
7657
+ .kds-col-md-5 { grid-area: auto/span 5; }
7658
+ .kds-col-md-6 { grid-area: auto/span 6; }
7659
+ .kds-col-md-7 { grid-area: auto/span 7; }
7660
+ .kds-col-md-8 { grid-area: auto/span 8; }
7661
+ .kds-col-md-9 { grid-area: auto/span 9; }
7662
+ .kds-col-md-10 { grid-area: auto/span 10; }
7663
+ .kds-col-md-11 { grid-area: auto/span 11; }
7664
+ .kds-col-md-12 { grid-area: auto/span 12; }
7665
+ }
7666
+
7667
+ @media only screen and (min-width: 993px) {
7668
+ .kds-col-lg-1 { grid-area: auto/span 1; }
7669
+ .kds-col-lg-2 { grid-area: auto/span 2; }
7670
+ .kds-col-lg-3 { grid-area: auto/span 3; }
7671
+ .kds-col-lg-4 { grid-area: auto/span 4; }
7672
+ .kds-col-lg-5 { grid-area: auto/span 5; }
7673
+ .kds-col-lg-6 { grid-area: auto/span 6; }
7674
+ .kds-col-lg-7 { grid-area: auto/span 7; }
7675
+ .kds-col-lg-8 { grid-area: auto/span 8; }
7676
+ .kds-col-lg-9 { grid-area: auto/span 9; }
7677
+ .kds-col-lg-10 { grid-area: auto/span 10; }
7678
+ .kds-col-lg-11 { grid-area: auto/span 11; }
7679
+ .kds-col-lg-12 { grid-area: auto/span 12; }
7680
+ }
7681
+