@khipu/design-system 0.2.0-alpha.3 → 0.2.0-alpha.30

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-13T19:14:37.483Z
14
+ * Generated: 2026-06-01T18:22:23.831Z
15
15
  *
16
16
  * To regenerate:
17
17
  * cd design-system && npm run tokens:generate
@@ -51,12 +51,14 @@
51
51
  --kds-color-warning-main: #EF6C00;
52
52
  --kds-color-warning-light: #FF9800;
53
53
  --kds-color-warning-dark: #E65100;
54
+ --kds-color-warning-warm: #8A6D1A;
54
55
  --kds-color-error-main: #D32F2F;
55
56
  --kds-color-error-light: #EF5350;
56
57
  --kds-color-error-dark: #C62828;
57
58
  --kds-color-info-main: #0288D1;
58
59
  --kds-color-info-light: #03A9F4;
59
60
  --kds-color-info-dark: #01579B;
61
+ --kds-color-info-blue: #5A5FE0;
60
62
 
61
63
  /* Text colors */
62
64
  --kds-color-text-primary: #333333;
@@ -134,6 +136,8 @@
134
136
  --kds-font-weight-bold: 700;
135
137
 
136
138
  /* Font sizes (base scale xs–4xl: see responsive section below) */
139
+ --kds-font-size-decimal-sup: 0.5em;
140
+
137
141
  /* Line heights */
138
142
  --kds-line-height-tight: 1.2;
139
143
  --kds-line-height-snug: 1.375;
@@ -147,9 +151,9 @@
147
151
  --kds-letter-spacing-widest: 1px;
148
152
 
149
153
  /* Button typography */
150
- --kds-typography-button-font-size: 0.9375rem;
154
+ --kds-typography-button-font-size: 0.875rem;
151
155
  --kds-typography-button-font-weight: 500;
152
- --kds-typography-button-line-height: 26px;
156
+ --kds-typography-button-line-height: 1.5;
153
157
  --kds-typography-button-letter-spacing: 0.46px;
154
158
 
155
159
  /* Typography margins */
@@ -199,10 +203,10 @@
199
203
  --kds-spacing-input-padding-y: 16px;
200
204
  --kds-spacing-input-padding-x: 12px;
201
205
  --kds-spacing-input-padding: 16px 12px;
202
- --kds-spacing-button-padding-y: 8px;
203
- --kds-spacing-button-padding-x: 22px;
204
- --kds-spacing-button-padding: 8px 22px;
205
- --kds-spacing-button-min-height: 50px;
206
+ --kds-spacing-button-padding-y: 0;
207
+ --kds-spacing-button-padding-x: 16px;
208
+ --kds-spacing-button-padding: 0 16px;
209
+ --kds-spacing-button-min-height: 44px;
206
210
  --kds-spacing-button-icon-size: 20px;
207
211
  --kds-spacing-sidebar-width: 280px;
208
212
  --kds-spacing-sidebar-width-collapsed: 72px;
@@ -241,7 +245,7 @@
241
245
  --kds-radius-full: 9999px;
242
246
 
243
247
  /* Component-specific radii */
244
- --kds-radius-button: 4px;
248
+ --kds-radius-button: 10px;
245
249
  --kds-radius-input: 4px;
246
250
  --kds-radius-card: 14px;
247
251
  --kds-radius-modal: 20px;
@@ -643,6 +647,7 @@ body.dark {
643
647
  /* Scroll Container Utilities */
644
648
  --kds-scroll-sm-height: 280px;
645
649
  --kds-scroll-md-height: 420px;
650
+
646
651
  --kds-scroll-lg-height: 600px;
647
652
 
648
653
  /* Stage Layout */
@@ -755,7 +760,7 @@ footer {
755
760
  ======================================== */
756
761
  :root {
757
762
  /* Scroll-linked collapse range (mobile sticky invoice) */
758
- --kds-scroll-collapse-end: 150px;
763
+ --kds-scroll-collapse-end: 60px;
759
764
 
760
765
  /* Merchant tile: normal and collapsed sizes (from source prototype) */
761
766
  --kds-merchant-size: 64px;
@@ -777,6 +782,10 @@ footer {
777
782
  * Source: design.khipu.com and Material Design 3 specifications
778
783
  */
779
784
 
785
+ * {
786
+ border-radius: 0;
787
+ }
788
+
780
789
 
781
790
  :has(>main) {
782
791
  background-color: transparent !important;
@@ -821,34 +830,37 @@ a.kds-btn {
821
830
  justify-content: center;
822
831
  gap: 8px;
823
832
  text-align: center;
833
+ width: 100%;
824
834
 
825
835
  /* Typography - Using design tokens */
826
836
  font-family: var(--kds-font-family-secondary);
827
- font-weight: var(--kds-font-weight-medium); /* 500, no 600 */
828
- font-size: var(--kds-typography-button-font-size); /* 0.9375rem = 15px */
829
- line-height: var(--kds-typography-button-line-height); /* 26px, no 1 */
837
+ font-weight: var(--kds-font-weight-medium); /* 500 */
838
+ font-size: var(--kds-typography-button-font-size); /* 0.875rem = 14px */
839
+ line-height: var(--kds-typography-button-line-height); /* 1.5 */
830
840
  letter-spacing: var(--kds-typography-button-letter-spacing); /* 0.46px */
831
841
  text-transform: uppercase;
832
842
 
833
843
  /* Spacing - Using design tokens */
834
- padding: var(--kds-spacing-button-padding); /* 8px 22px */
835
- min-height: var(--kds-spacing-button-min-height); /* 50px */
836
- height: auto; /* Remove fixed height, let content + padding define it */
844
+ padding: var(--kds-spacing-button-padding); /* 0 16px */
845
+ height: var(--kds-spacing-button-min-height); /* 44px */
837
846
 
838
847
  /* Border - Using design token */
839
- border-radius: var(--kds-radius-button); /* 4px */
848
+ border-radius: var(--kds-radius-button); /* 10px */
840
849
  border: none;
841
850
 
842
851
  /* Interaction */
843
852
  cursor: pointer;
844
- transition: background-color 250ms cubic-bezier(0.4, 0, 0.2, 1),
845
- box-shadow 250ms cubic-bezier(0.4, 0, 0.2, 1),
846
- border-color 250ms cubic-bezier(0.4, 0, 0.2, 1),
847
- color 250ms cubic-bezier(0.4, 0, 0.2, 1);
853
+ transition: background .15s, box-shadow .15s, transform .05s;
848
854
  box-sizing: border-box;
849
855
  vertical-align: middle;
850
856
  }
851
857
 
858
+ /* Active state - add subtle press effect */
859
+ button.kds-btn:active:not(:disabled),
860
+ a.kds-btn:active:not(:disabled) {
861
+ transform: translateY(1px);
862
+ }
863
+
852
864
  /* Disabled state - colores específicos en lugar de opacity */
853
865
  button.kds-btn:disabled,
854
866
  a.kds-btn:disabled {
@@ -866,18 +878,13 @@ a.kds-btn-primary {
866
878
  background: var(--kds-color-primary-main); /* #8347AD */
867
879
  color: white;
868
880
  border: none;
869
- box-shadow: 0px 3px 1px -2px rgba(0, 0, 0, 0.2),
870
- 0px 2px 2px 0px rgba(0, 0, 0, 0.14),
871
- 0px 1px 5px 0px rgba(0, 0, 0, 0.12); /* elevation/2 */
881
+ box-shadow: 0 1px 2px rgba(131, 71, 173, .25);
872
882
  }
873
883
 
874
- /* Hover State - background más oscuro + elevation/4 */
884
+ /* Hover State - background más oscuro */
875
885
  button.kds-btn-primary:hover:not(:disabled),
876
886
  a.kds-btn-primary:hover:not(:disabled) {
877
- background: var(--kds-color-primary-dark); /* #6A3A8C */
878
- box-shadow: 0px 2px 4px -1px rgba(0, 0, 0, 0.2),
879
- 0px 4px 5px 0px rgba(0, 0, 0, 0.14),
880
- 0px 1px 10px 0px rgba(0, 0, 0, 0.12); /* elevation/4 */
887
+ background: var(--kds-color-primary-dark); /* #5B3179 */
881
888
  }
882
889
 
883
890
  /* Active/Focus State */
@@ -1047,6 +1054,7 @@ a.kds-btn.kds-btn-md {
1047
1054
  padding: var(--kds-spacing-2);
1048
1055
  box-shadow: var(--kds-shadow-card);
1049
1056
  transition: box-shadow 0.3s ease;
1057
+ margin-block-start: 0 !important;
1050
1058
  }
1051
1059
 
1052
1060
  .kds-card-elevated:hover,
@@ -1069,63 +1077,90 @@ a.kds-btn.kds-btn-md {
1069
1077
  }
1070
1078
  }
1071
1079
 
1072
- /* Selection card */
1080
+ /* Selection card.
1081
+ IMPORTANTE: este componente se renderiza como `<button>`. BeerCSS aplica al
1082
+ `button` base: `display: inline-flex; align-items: center; justify-content: center;
1083
+ block-size: 2.5rem; padding: 0 1rem; background: var(--primary); color: on-primary`.
1084
+ Todas esas reglas hay que sobreescribirlas para que el card-selector funcione como
1085
+ un contenedor flex column de altura variable y alineado a la izquierda.
1086
+
1087
+ Convención del DS: spacing entre hijos via `gap` del flex padre + padding.
1088
+ Los elementos internos (.kds-card-selector-icon/-title/-description) NO usan margin. */
1073
1089
  .kds-card-selector {
1090
+ /* Reset BeerCSS button */
1091
+ display: flex;
1092
+ flex-direction: column;
1093
+ align-items: stretch;
1094
+ justify-content: flex-start;
1095
+ block-size: auto;
1096
+ inline-size: 100%;
1097
+ text-align: left;
1098
+ line-height: 1.5;
1099
+ color: var(--kds-color-text-primary);
1100
+ /* Estilos propios del card-selector */
1074
1101
  padding: var(--kds-spacing-3);
1102
+ gap: var(--kds-spacing-1-5);
1075
1103
  border-radius: var(--kds-radius-md);
1076
- border: 2px solid var(--kds-border-light);
1104
+ border: var(--kds-border-width-md) solid var(--kds-border-light);
1077
1105
  background: var(--kds-color-background-paper);
1078
1106
  transition: all 0.3s ease;
1079
- text-align: left;
1080
1107
  cursor: pointer;
1081
- display: flex;
1082
- flex-direction: column;
1083
1108
  }
1084
1109
 
1085
- .kds-card-selector:hover {
1086
- border-color: #D1D5DB; /* gray-300 */
1110
+ .kds-card-selector:hover:not(.selected) {
1111
+ border-color: var(--kds-color-primary-light);
1112
+ background: var(--kds-color-primary-hover);
1113
+ }
1114
+
1115
+ /* Override del ripple/overlay default de BeerCSS:
1116
+ `:is(.wave,.chip,.button,button,nav.tabbed>a,...):not([class*=ripple])::after`
1117
+ tiene specificity (0,2,4) según DevTools (Chrome cuenta cada selector dentro
1118
+ de :is() individualmente para algunos motores). Usamos !important — consistente
1119
+ con cómo se overridean otros estilos de BeerCSS en este archivo (67 usos previos).
1120
+ Antes pintaba negro porque `currentColor` resolvía a text-primary del card. */
1121
+ .kds-card-selector::after {
1122
+ background-image: radial-gradient(circle, var(--kds-color-primary-main) 1%, transparent 1%) !important;
1087
1123
  }
1088
1124
 
1089
1125
  .kds-card-selector.selected {
1090
- border-color: #3B82F6; /* blue-600 */
1091
- background: #EFF6FF; /* blue-50 */
1126
+ border-color: var(--kds-color-primary-main);
1127
+ background: var(--kds-color-primary-faint);
1092
1128
  box-shadow: var(--kds-shadow-md);
1093
1129
  }
1094
1130
 
1095
- /* Icon container */
1131
+ /* Icon container — spacing manejado por gap del padre, no margin */
1096
1132
  .kds-card-selector-icon {
1097
- width: 48px;
1098
- height: 48px;
1099
- background: #DBEAFE; /* blue-100 */
1100
- border-radius: 8px;
1133
+ width: var(--kds-spacing-6);
1134
+ height: var(--kds-spacing-6);
1135
+ background: var(--kds-color-primary-focus);
1136
+ border-radius: var(--kds-radius-sm);
1101
1137
  display: flex;
1102
1138
  align-items: center;
1103
1139
  justify-content: center;
1104
- margin-bottom: 16px;
1105
1140
  }
1106
1141
 
1107
1142
  .kds-card-selector-icon i,
1108
1143
  .kds-card-selector-icon svg {
1109
- width: 24px;
1110
- height: 24px;
1111
- min-width: 24px;
1112
- min-height: 24px;
1113
- color: #3B82F6; /* blue-600 */
1144
+ width: var(--kds-spacing-3);
1145
+ height: var(--kds-spacing-3);
1146
+ min-width: var(--kds-spacing-3);
1147
+ min-height: var(--kds-spacing-3);
1148
+ font-size: var(--kds-spacing-3);
1149
+ color: var(--kds-color-primary-main);
1114
1150
  }
1115
1151
 
1116
- /* Title */
1152
+ /* Title — spacing manejado por gap del padre, no margin */
1117
1153
  .kds-card-selector-title {
1118
- font-weight: 600;
1154
+ font-weight: var(--kds-font-weight-semibold);
1119
1155
  color: var(--kds-color-text-primary);
1120
- margin-bottom: 8px;
1121
- font-size: 16px;
1156
+ font-size: var(--kds-font-size-lg);
1122
1157
  }
1123
1158
 
1124
1159
  /* Description */
1125
1160
  .kds-card-selector-description {
1126
- font-size: 14px;
1127
- color: #4B5563; /* gray-600 */
1128
- line-height: 1.5;
1161
+ font-size: var(--kds-font-size-sm);
1162
+ color: var(--kds-color-text-secondary);
1163
+ line-height: var(--kds-line-height-normal);
1129
1164
  }
1130
1165
 
1131
1166
  /* Selected state - visual feedback via border only */
@@ -1137,14 +1172,22 @@ a.kds-btn.kds-btn-md {
1137
1172
  display: flex;
1138
1173
  flex-direction: column;
1139
1174
  gap: var(--kds-spacing-2);
1140
- padding: var(--kds-spacing-4);
1175
+ padding: var(--kds-spacing-2);
1141
1176
  border-radius: var(--kds-radius-lg);
1142
1177
  border: 2px solid var(--kds-border-medium);
1143
- max-width: 400px; /* Increased from 365px for better text spacing */
1178
+ /* Ancho mínimo aplicado a TODOS los planes así un plan sin badge en una
1179
+ grilla con un plan recomendado mantiene la misma anchura, y el badge nunca
1180
+ se superpone al título por estrechez del card. */
1181
+ min-width: 260px;
1182
+ max-width: 400px;
1144
1183
  background: var(--kds-surface-base);
1145
1184
  transition: all 0.3s ease;
1146
1185
  cursor: pointer;
1147
- height: 100%; /* Ensure cards fill grid height */
1186
+ /* Alto fijo: el card se estira al alto de su row del grid (align-items stretch
1187
+ es el default) — todas las cards de la misma fila quedan a la misma altura
1188
+ sin importar el contenido. `align-self: stretch` lo hace explícito. */
1189
+ height: 100%;
1190
+ align-self: stretch;
1148
1191
  }
1149
1192
 
1150
1193
  .kds-card-plan:hover {
@@ -1164,18 +1207,19 @@ a.kds-btn.kds-btn-md {
1164
1207
  box-shadow: var(--kds-shadow-elevation-4);
1165
1208
  }
1166
1209
 
1167
- /* Recommended Badge */
1210
+ /* Recommended Badge — inline dentro del card (no flotante).
1211
+ Es el primer hijo del .kds-card-plan, así que aparece arriba de todo
1212
+ el contenido, alineado a la izquierda. */
1168
1213
  .kds-card-plan-badge {
1169
- position: absolute;
1170
- top: -12px;
1171
- right: var(--kds-spacing-6);
1172
- padding: var(--kds-spacing-1) var(--kds-spacing-4);
1214
+ align-self: flex-start;
1215
+ padding: var(--kds-spacing-0-5) var(--kds-spacing-1-5);
1173
1216
  background: var(--primary);
1174
1217
  color: white;
1175
- font-size: var(--kds-font-size-sm);
1218
+ font-size: var(--kds-font-size-xs);
1176
1219
  font-weight: var(--kds-font-weight-semibold);
1220
+ line-height: 1;
1177
1221
  border-radius: var(--kds-radius-full);
1178
- box-shadow: var(--kds-shadow-elevation-1);
1222
+ white-space: nowrap;
1179
1223
  }
1180
1224
 
1181
1225
  /* Plan Header */
@@ -1203,13 +1247,11 @@ a.kds-btn.kds-btn-md {
1203
1247
  display: flex;
1204
1248
  align-items: baseline;
1205
1249
  gap: var(--kds-spacing-2);
1206
- padding: var(--kds-spacing-4) 0;
1207
1250
  border-bottom: 1px solid var(--kds-border-light);
1208
- min-height: 88px; /* Standardize price area height */
1209
1251
  }
1210
1252
 
1211
1253
  .kds-price {
1212
- font-size: 42px;
1254
+ font-size: var(--kds-font-size-4xl);
1213
1255
  font-weight: var(--kds-font-weight-bold);
1214
1256
  color: var(--primary);
1215
1257
  line-height: 1.1;
@@ -1723,53 +1765,108 @@ a.kds-btn.kds-btn-md {
1723
1765
  }
1724
1766
 
1725
1767
  /* ========================================
1726
- Snackbar Positioning
1768
+ Snackbar Positioning & Styling
1727
1769
  ======================================== */
1728
1770
 
1729
1771
  .snackbar {
1730
1772
  position: fixed;
1731
- bottom: var(--kds-spacing-3);
1732
- left: 50%;
1733
- transform: translateX(-50%);
1734
1773
  z-index: var(--kds-z-index-snackbar);
1735
1774
  min-width: 344px;
1736
1775
  max-width: var(--kds-snackbar-max-width);
1737
1776
  box-shadow: var(--kds-shadow-8);
1777
+ border-radius: var(--kds-radius-md);
1778
+ padding: var(--kds-spacing-1-5) var(--kds-spacing-2);
1779
+ gap: var(--kds-spacing-1);
1780
+ font-family: var(--kds-font-family-primary);
1781
+ font-size: var(--kds-font-size-body2);
1782
+ font-weight: var(--kds-font-weight-medium);
1783
+ line-height: var(--kds-line-height-normal);
1784
+ letter-spacing: var(--kds-letter-spacing-normal);
1785
+ overflow: hidden;
1738
1786
  }
1739
1787
 
1740
1788
  /* Snackbar active state - ensure visibility when toggled via JS */
1741
1789
  .snackbar.active {
1742
1790
  visibility: visible !important;
1743
1791
  opacity: 1 !important;
1744
- transform: translateX(-50%) !important;
1745
1792
  }
1746
1793
 
1747
- /* Snackbar semantic variants - background + text/icon color */
1794
+ /* Snackbar semantic variants
1795
+ All use white text (--kds-color-primary-contrast) on solid semantic backgrounds */
1748
1796
  .snackbar.error {
1749
1797
  background-color: var(--kds-color-error-main) !important;
1750
- color: var(--on-error, var(--kds-color-primary-contrast)) !important;
1798
+ color: var(--kds-color-primary-contrast) !important;
1751
1799
  }
1752
1800
 
1753
1801
  .snackbar.error i {
1754
- color: var(--on-error, var(--kds-color-primary-contrast)) !important;
1802
+ color: var(--kds-color-primary-contrast) !important;
1755
1803
  }
1756
1804
 
1757
1805
  .snackbar.info {
1758
1806
  background-color: var(--kds-color-info-main) !important;
1759
- color: var(--on-info, var(--kds-color-primary-contrast)) !important;
1807
+ color: var(--kds-color-primary-contrast) !important;
1760
1808
  }
1761
1809
 
1762
1810
  .snackbar.info i {
1763
- color: var(--on-info, var(--kds-color-primary-contrast)) !important;
1811
+ color: var(--kds-color-primary-contrast) !important;
1764
1812
  }
1765
1813
 
1766
1814
  .snackbar.success {
1767
1815
  background-color: var(--kds-color-success-main) !important;
1768
- color: var(--on-success, var(--kds-color-primary-contrast)) !important;
1816
+ color: var(--kds-color-primary-contrast) !important;
1769
1817
  }
1770
1818
 
1771
1819
  .snackbar.success i {
1772
- color: var(--on-success, var(--kds-color-primary-contrast)) !important;
1820
+ color: var(--kds-color-primary-contrast) !important;
1821
+ }
1822
+
1823
+ /* Snackbar progress bar — animated timer for auto-dismiss */
1824
+ .snackbar[data-auto-dismiss]::after {
1825
+ content: '';
1826
+ position: absolute;
1827
+ bottom: 0;
1828
+ left: 0;
1829
+ height: 3px;
1830
+ width: 100%;
1831
+ background: rgba(255, 255, 255, 0.35);
1832
+ border-radius: 0 0 var(--kds-radius-md) var(--kds-radius-md);
1833
+ animation: kds-snackbar-timer var(--kds-snackbar-duration, 5s) linear forwards;
1834
+ }
1835
+
1836
+ @keyframes kds-snackbar-timer {
1837
+ from { width: 100%; }
1838
+ to { width: 0; }
1839
+ }
1840
+
1841
+ /* Snackbar close button */
1842
+ .kds-snackbar-close {
1843
+ background: none !important;
1844
+ border: none !important;
1845
+ color: var(--kds-color-primary-contrast) !important;
1846
+ cursor: pointer;
1847
+ padding: var(--kds-spacing-0-5) !important;
1848
+ margin: calc(-1 * var(--kds-spacing-0-5)) !important;
1849
+ margin-left: 0 !important;
1850
+ border-radius: var(--kds-radius-full) !important;
1851
+ display: flex;
1852
+ align-items: center;
1853
+ justify-content: center;
1854
+ flex-shrink: 0;
1855
+ opacity: 0.7;
1856
+ transition: opacity 150ms;
1857
+ min-width: auto !important;
1858
+ width: auto !important;
1859
+ height: auto !important;
1860
+ }
1861
+
1862
+ .kds-snackbar-close:hover {
1863
+ opacity: 1;
1864
+ background: rgba(255, 255, 255, 0.15) !important;
1865
+ }
1866
+
1867
+ .kds-snackbar-close i {
1868
+ font-size: 18px !important;
1869
+ color: var(--kds-color-primary-contrast) !important;
1773
1870
  }
1774
1871
 
1775
1872
  /* ========================================
@@ -2102,6 +2199,17 @@ body.dark {
2102
2199
  transition: border-color 0.2s, box-shadow 0.2s, outline-color 0.2s;
2103
2200
  }
2104
2201
 
2202
+ /* === TEXTAREA FIX === */
2203
+ /* BeerCSS base sets minimal block padding; add breathing room for textarea */
2204
+ .field > textarea {
2205
+ padding-block: 0.75rem;
2206
+ resize: vertical;
2207
+ }
2208
+
2209
+ .field.label > textarea {
2210
+ padding-block-start: 1.5rem;
2211
+ }
2212
+
2105
2213
  /* ==========================================
2106
2214
  NOTCH VISIBILITY (opacity)
2107
2215
  ========================================== */
@@ -2189,12 +2297,16 @@ body.dark {
2189
2297
  Asegurar que el dropdown arrow sea visible
2190
2298
  ========================================== */
2191
2299
 
2192
- /* Select: mantener appearance nativa para mostrar el dropdown arrow */
2300
+ /* Select: reset nativo + arrow custom via SVG (iOS Safari ignora estilos con appearance:auto) */
2193
2301
  .field select {
2194
- /* BeerCSS puede estar ocultando el arrow, aseguramos que sea visible */
2195
- appearance: auto;
2196
- -webkit-appearance: auto;
2197
- -moz-appearance: auto;
2302
+ -webkit-appearance: none;
2303
+ -moz-appearance: none;
2304
+ appearance: none;
2305
+ 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");
2306
+ background-repeat: no-repeat;
2307
+ background-position: right var(--kds-spacing-1) center;
2308
+ background-size: 20px;
2309
+ padding-right: var(--kds-spacing-4) !important;
2198
2310
  }
2199
2311
 
2200
2312
  /* ==========================================
@@ -2326,6 +2438,71 @@ body.dark {
2326
2438
  display: inline-flex;
2327
2439
  }
2328
2440
 
2441
+ /* ========================================
2442
+ Radix Tooltip (.kds-tooltip)
2443
+ Espejo de `.tooltip` pero para popovers de Radix:
2444
+ bg oscuro, texto blanco, sombra + animación fade/slide direccional.
2445
+ ======================================== */
2446
+
2447
+ .kds-tooltip {
2448
+ background-color: var(--kds-color-text-primary);
2449
+ color: var(--kds-color-background-paper);
2450
+ font-family: var(--kds-font-family-primary);
2451
+ font-size: var(--kds-font-size-xs);
2452
+ font-weight: var(--kds-font-weight-medium);
2453
+ line-height: var(--kds-line-height-normal);
2454
+ border-radius: var(--kds-radius-sm);
2455
+ padding: var(--kds-spacing-0-75) var(--kds-spacing-1-5);
2456
+ box-shadow: var(--kds-shadow-4);
2457
+ max-width: 280px;
2458
+ z-index: var(--kds-z-index-tooltip, 1500);
2459
+ user-select: none;
2460
+ /* Animación direccional según Radix data-side — coordinada con copy-row
2461
+ (cubic-bezier 0.2, 0.8, 0.2, 1) para un feel consistente del DS. */
2462
+ animation-duration: 240ms;
2463
+ animation-timing-function: cubic-bezier(0.2, 0.8, 0.2, 1);
2464
+ will-change: transform, opacity;
2465
+ }
2466
+
2467
+ .kds-tooltip[data-state='closed'] {
2468
+ animation-duration: 140ms;
2469
+ animation-timing-function: cubic-bezier(0.4, 0, 0.6, 1);
2470
+ }
2471
+
2472
+ /* Direccional según data-side (Radix añade el attr en runtime).
2473
+ Cada lado entra desde su dirección con ~8px de offset (más visible que 4px). */
2474
+ .kds-tooltip[data-side='top'][data-state='delayed-open'],
2475
+ .kds-tooltip[data-side='top'][data-state='instant-open'] { animation-name: kds-tooltip-in-top; }
2476
+ .kds-tooltip[data-side='bottom'][data-state='delayed-open'],
2477
+ .kds-tooltip[data-side='bottom'][data-state='instant-open'] { animation-name: kds-tooltip-in-bottom; }
2478
+ .kds-tooltip[data-side='left'][data-state='delayed-open'],
2479
+ .kds-tooltip[data-side='left'][data-state='instant-open'] { animation-name: kds-tooltip-in-left; }
2480
+ .kds-tooltip[data-side='right'][data-state='delayed-open'],
2481
+ .kds-tooltip[data-side='right'][data-state='instant-open'] { animation-name: kds-tooltip-in-right; }
2482
+
2483
+ /* Fallback cuando no hay data-side resuelto aún */
2484
+ .kds-tooltip[data-state='delayed-open']:not([data-side]),
2485
+ .kds-tooltip[data-state='instant-open']:not([data-side]) {
2486
+ animation-name: kds-tooltip-in-top;
2487
+ }
2488
+
2489
+ .kds-tooltip[data-state='closed'] { animation-name: kds-tooltip-out; }
2490
+
2491
+ @keyframes kds-tooltip-in-top { from { opacity: 0; transform: translateY(8px) scale(0.96); } to { opacity: 1; transform: none; } }
2492
+ @keyframes kds-tooltip-in-bottom { from { opacity: 0; transform: translateY(-8px) scale(0.96); } to { opacity: 1; transform: none; } }
2493
+ @keyframes kds-tooltip-in-left { from { opacity: 0; transform: translateX(8px) scale(0.96); } to { opacity: 1; transform: none; } }
2494
+ @keyframes kds-tooltip-in-right { from { opacity: 0; transform: translateX(-8px) scale(0.96); } to { opacity: 1; transform: none; } }
2495
+
2496
+ @keyframes kds-tooltip-out {
2497
+ from { opacity: 1; transform: none; }
2498
+ to { opacity: 0; transform: scale(0.96); }
2499
+ }
2500
+
2501
+ /* Arrow (SVG path generado por Radix) */
2502
+ .kds-tooltip-arrow {
2503
+ fill: var(--kds-color-text-primary);
2504
+ }
2505
+
2329
2506
  /* ========================================
2330
2507
  Material Symbols Icon Sizing
2331
2508
  ======================================== */
@@ -2742,7 +2919,8 @@ dialog.modal .field.border:focus-within {
2742
2919
  padding: var(--kds-spacing-2);
2743
2920
  }
2744
2921
 
2745
- .snackbar {
2922
+ .snackbar,
2923
+ .snackbar.active {
2746
2924
  min-width: calc(100% - 32px);
2747
2925
  left: 16px;
2748
2926
  right: 16px;
@@ -3041,6 +3219,32 @@ footer > .kds-container-center {
3041
3219
  color: var(--kds-color-error-dark);
3042
3220
  }
3043
3221
 
3222
+ /* Close button — icon-only, discreto, no usa kds-btn para no romper el flex layout del alert */
3223
+ .kds-alert-close {
3224
+ flex-shrink: 0;
3225
+ display: inline-flex;
3226
+ align-items: center;
3227
+ justify-content: center;
3228
+ width: 28px;
3229
+ height: 28px;
3230
+ padding: 0;
3231
+ background: transparent;
3232
+ border: 0;
3233
+ border-radius: 50%;
3234
+ color: inherit;
3235
+ cursor: pointer;
3236
+ transition: background-color 0.15s ease;
3237
+ }
3238
+
3239
+ .kds-alert-close:hover {
3240
+ background: rgba(0, 0, 0, 0.06);
3241
+ }
3242
+
3243
+ .kds-alert-close i {
3244
+ font-size: 18px;
3245
+ line-height: 1;
3246
+ }
3247
+
3044
3248
  /* Lists inside alerts */
3045
3249
  .kds-alert ul {
3046
3250
  padding-left: var(--kds-spacing-2);
@@ -4037,6 +4241,14 @@ dialog#surveyModal button.circle {
4037
4241
  text-align: center;
4038
4242
  }
4039
4243
 
4244
+ .kds-text-left {
4245
+ text-align: left;
4246
+ }
4247
+
4248
+ .kds-text-right {
4249
+ text-align: right;
4250
+ }
4251
+
4040
4252
  .kds-text-underline {
4041
4253
  text-decoration: underline;
4042
4254
  }
@@ -4053,6 +4265,54 @@ dialog#surveyModal button.circle {
4053
4265
  font-size: var(--kds-font-size-sm);
4054
4266
  }
4055
4267
 
4268
+ /* ── Font-size scale utilities (additive — opt-in companions to .kds-text-sm) ── */
4269
+ .kds-text-base {
4270
+ font-size: var(--kds-font-size-base);
4271
+ }
4272
+
4273
+ .kds-text-lg {
4274
+ font-size: var(--kds-font-size-lg);
4275
+ }
4276
+
4277
+ .kds-text-xl {
4278
+ font-size: var(--kds-font-size-xl);
4279
+ }
4280
+
4281
+ .kds-text-2xl {
4282
+ font-size: var(--kds-font-size-2xl);
4283
+ }
4284
+
4285
+ /* ── Font-weight utilities ── */
4286
+ .kds-fw-regular {
4287
+ font-weight: var(--kds-font-weight-regular);
4288
+ }
4289
+
4290
+ .kds-fw-medium {
4291
+ font-weight: var(--kds-font-weight-medium);
4292
+ }
4293
+
4294
+ .kds-fw-semibold {
4295
+ font-weight: var(--kds-font-weight-semibold);
4296
+ }
4297
+
4298
+ .kds-fw-bold {
4299
+ font-weight: var(--kds-font-weight-bold);
4300
+ }
4301
+
4302
+ /* ── Text-transform utilities ── */
4303
+ .kds-text-transform-none {
4304
+ text-transform: none;
4305
+ }
4306
+
4307
+ /* ── Soft background utilities (semantic muted backgrounds for callouts) ── */
4308
+ .kds-bg-warning-soft {
4309
+ background-color: var(--kds-color-warning-soft);
4310
+ }
4311
+
4312
+ .kds-bg-info-soft {
4313
+ background-color: var(--kds-color-info-soft);
4314
+ }
4315
+
4056
4316
  /* ── Typography variants ── */
4057
4317
  .kds-text-display1 {
4058
4318
  font-family: var(--kds-font-family-primary, 'Public Sans', sans-serif);
@@ -4263,7 +4523,9 @@ dialog#surveyModal button.circle {
4263
4523
  ======================================== */
4264
4524
 
4265
4525
  .kds-badge {
4266
- display: inline-block;
4526
+ display: inline-flex;
4527
+ align-items: center;
4528
+ gap: 4px;
4267
4529
  padding: 2px 8px;
4268
4530
  border-radius: var(--kds-radius-sm);
4269
4531
  font-size: var(--kds-font-size-xs);
@@ -4271,6 +4533,40 @@ dialog#surveyModal button.circle {
4271
4533
  line-height: 1.5;
4272
4534
  }
4273
4535
 
4536
+ /* Icon prefix inside chip — small inline icon */
4537
+ .kds-badge > i.material-symbols-outlined {
4538
+ font-size: 14px;
4539
+ line-height: 1;
4540
+ }
4541
+
4542
+ /* Deletable chip close button — discreto, sin kds-btn (eso lo agrandaba ridículo) */
4543
+ .kds-badge-close {
4544
+ display: inline-flex;
4545
+ align-items: center;
4546
+ justify-content: center;
4547
+ width: 16px;
4548
+ height: 16px;
4549
+ margin-right: -2px;
4550
+ padding: 0;
4551
+ background: transparent;
4552
+ border: 0;
4553
+ border-radius: 50%;
4554
+ color: inherit;
4555
+ cursor: pointer;
4556
+ opacity: 0.7;
4557
+ transition: opacity 0.15s, background-color 0.15s;
4558
+ }
4559
+
4560
+ .kds-badge-close:hover {
4561
+ opacity: 1;
4562
+ background: rgba(0, 0, 0, 0.1);
4563
+ }
4564
+
4565
+ .kds-badge-close i {
4566
+ font-size: 14px;
4567
+ line-height: 1;
4568
+ }
4569
+
4274
4570
  .kds-badge.success {
4275
4571
  background-color: var(--kds-color-success-container);
4276
4572
  color: var(--kds-color-success-dark);
@@ -4549,6 +4845,11 @@ dialog#surveyModal button.circle {
4549
4845
  color: var(--kds-color-text-primary);
4550
4846
  }
4551
4847
 
4848
+ /* Opt-in color modifier — switches the value to the LigoPay/khipu-blue tone */
4849
+ .kds-amount-value--info {
4850
+ color: var(--kds-color-info-blue); /* #5A5FE0 */
4851
+ }
4852
+
4552
4853
  .kds-amount-value small {
4553
4854
  font-size: 18px;
4554
4855
  font-weight: 500;
@@ -4906,7 +5207,7 @@ dialog#surveyModal button.circle {
4906
5207
  display: flex;
4907
5208
  align-items: center;
4908
5209
  justify-content: center;
4909
- gap: var(--kds-spacing-1);
5210
+ gap: var(--kds-spacing-0-5);
4910
5211
  color: var(--kds-color-gray-400);
4911
5212
  font-size: var(--kds-font-size-xs);
4912
5213
  letter-spacing: var(--kds-letter-spacing-wide);
@@ -4918,6 +5219,10 @@ dialog#surveyModal button.circle {
4918
5219
  display: none;
4919
5220
  }
4920
5221
 
5222
+ .kds-screen > form {
5223
+ margin-block-start: 0 !important;
5224
+ }
5225
+
4921
5226
  @media (max-width: 767px) {
4922
5227
  .kds-card-elevated > .kds-secure-footer {
4923
5228
  display: flex;
@@ -4967,14 +5272,20 @@ dialog#surveyModal button.circle {
4967
5272
  cursor: pointer;
4968
5273
  display: inline-flex;
4969
5274
  align-items: center;
4970
- gap: var(--kds-spacing-0-75);
5275
+ gap: 0;
4971
5276
  }
4972
5277
 
4973
- .kds-expand-toggle:hover {
5278
+ .kds-expand-toggle:hover,
5279
+ .kds-expand-toggle:focus,
5280
+ .kds-expand-toggle:active {
4974
5281
  background: transparent;
5282
+ outline: none;
5283
+ box-shadow: none;
4975
5284
  }
4976
5285
 
4977
- .kds-expand-toggle:hover span {
5286
+ .kds-expand-toggle:hover span,
5287
+ .kds-expand-toggle:focus span,
5288
+ .kds-expand-toggle:active span {
4978
5289
  text-decoration: underline;
4979
5290
  }
4980
5291
 
@@ -5154,11 +5465,11 @@ dialog#surveyModal button.circle {
5154
5465
  color: var(--kds-color-success-main);
5155
5466
  }
5156
5467
 
5157
- /* Variant: pending (animated spinner) */
5468
+ /* Variant: pending (animated blue spinner, sin icono interno) */
5158
5469
  .kds-status-block[data-status="pending"] .kds-status-block-icon {
5159
5470
  background: transparent;
5160
5471
  border: 3px solid var(--kds-color-divider);
5161
- border-top-color: var(--kds-color-primary-main);
5472
+ border-top-color: var(--kds-color-info-main);
5162
5473
  animation: kds-spin 1s linear infinite;
5163
5474
  }
5164
5475
 
@@ -5176,12 +5487,21 @@ dialog#surveyModal button.circle {
5176
5487
  color: var(--kds-color-error-main);
5177
5488
  }
5178
5489
 
5490
+ /* Variant: info — usar SIEMPRE con icon "info_i" (i minúscula sin glyph circular)
5491
+ para que solo se vea nuestro círculo decorativo. Iconos como "info" tienen
5492
+ su propio círculo built-in → causarían doble círculo. */
5493
+ .kds-status-block[data-status="info"] .kds-status-block-icon {
5494
+ background: var(--kds-color-info-soft);
5495
+ border: var(--kds-border-width-md) solid var(--kds-color-info-main);
5496
+ color: var(--kds-color-info-main);
5497
+ }
5498
+
5179
5499
  /* Inline variant: icon left + text right */
5180
5500
  .kds-status-block.inline {
5181
5501
  text-align: left;
5182
5502
  display: flex;
5183
5503
  align-items: center;
5184
- gap: var(--kds-spacing-3);
5504
+ gap: var(--kds-spacing-2);
5185
5505
  padding: var(--kds-spacing-1) 0;
5186
5506
  }
5187
5507
 
@@ -5243,6 +5563,40 @@ dialog#surveyModal button.circle {
5243
5563
  background: var(--kds-color-divider);
5244
5564
  }
5245
5565
 
5566
+ /* Close button — top-right discreto, NO usa kds-btn (rompía el flex layout) */
5567
+ .kds-bottom-sheet-close {
5568
+ position: absolute;
5569
+ top: var(--kds-spacing-1);
5570
+ right: var(--kds-spacing-1);
5571
+ width: 32px;
5572
+ height: 32px;
5573
+ display: inline-flex;
5574
+ align-items: center;
5575
+ justify-content: center;
5576
+ padding: 0;
5577
+ background: transparent;
5578
+ border: 0;
5579
+ border-radius: 50%;
5580
+ color: var(--kds-color-text-secondary);
5581
+ cursor: pointer;
5582
+ transition: background-color 0.15s ease;
5583
+ }
5584
+
5585
+ .kds-bottom-sheet-close:hover {
5586
+ background: rgba(0, 0, 0, 0.06);
5587
+ }
5588
+
5589
+ .kds-bottom-sheet-close i {
5590
+ font-size: 20px;
5591
+ line-height: 1;
5592
+ }
5593
+
5594
+ /* Body container — separa el content del title/actions */
5595
+ .kds-bottom-sheet-body {
5596
+ text-align: left;
5597
+ margin-top: var(--kds-spacing-1);
5598
+ }
5599
+
5246
5600
  .kds-bottom-sheet-icon {
5247
5601
  font-size: var(--kds-font-size-4xl);
5248
5602
  }
@@ -5336,6 +5690,7 @@ dialog#surveyModal button.circle {
5336
5690
  background: var(--kds-color-background-muted);
5337
5691
  border-radius: var(--kds-radius-lg);
5338
5692
  padding: var(--kds-spacing-0-25);
5693
+ margin-bottom: var(--kds-spacing-2);
5339
5694
  display: flex;
5340
5695
  position: relative;
5341
5696
  }
@@ -5571,6 +5926,13 @@ div.kds-invoice-header,
5571
5926
  align-content: initial;
5572
5927
  }
5573
5928
 
5929
+ /* Mobile collapsed state: center-align so merchant tile aligns with the smaller amount */
5930
+ @media (max-width: 767px) {
5931
+ .kds-invoice-sticky.is-collapsed .kds-invoice-header {
5932
+ align-items: center;
5933
+ }
5934
+ }
5935
+
5574
5936
  /* Reset BeerCSS sibling margin on <p> inside invoice header — specificity (0,4,1) ties BeerCSS, wins by source order */
5575
5937
  .kds-card-elevated.kds-invoice-sticky .kds-invoice-header p.kds-invoice-amount,
5576
5938
  .kds-card-elevated.kds-invoice-sticky .kds-invoice-header p.kds-invoice-code {
@@ -5578,7 +5940,7 @@ div.kds-invoice-header,
5578
5940
  }
5579
5941
 
5580
5942
  .kds-invoice-amount {
5581
- font-weight: var(--kds-font-weight-bold);
5943
+ font-weight: var(--kds-font-weight-semibold);
5582
5944
  font-size: var(--kds-font-size-3xl);
5583
5945
  line-height: var(--kds-line-height-tight);
5584
5946
  letter-spacing: var(--kds-letter-spacing-wide);
@@ -5599,11 +5961,17 @@ div.kds-invoice-header,
5599
5961
  color: var(--kds-color-gray-400);
5600
5962
  text-transform: uppercase;
5601
5963
  margin: 0;
5602
- margin-top: var(--kds-spacing-1);
5964
+ margin-block: unset;
5965
+ display: flex;
5966
+ gap: var(--kds-spacing-1-5);
5603
5967
  }
5604
5968
 
5605
- .kds-invoice-code::first-letter {
5606
- text-transform: uppercase;
5969
+ .kds-invoice-code-value {
5970
+ color: var(--kds-color-gray-400);
5971
+ }
5972
+
5973
+ .kds-invoice-code-value--lowercase {
5974
+ text-transform: lowercase;
5607
5975
  }
5608
5976
 
5609
5977
  .kds-invoice-merchant {
@@ -5642,20 +6010,30 @@ div.kds-invoice-header,
5642
6010
 
5643
6011
  /* -- Card Title -- */
5644
6012
  .kds-card-title {
5645
- font-weight: 700;
6013
+ font-weight: var(--kds-font-weight-semibold);
5646
6014
  font-size: var(--kds-font-size-base);
5647
6015
  line-height: 1.5;
5648
6016
  letter-spacing: -0.31px;
5649
6017
  color: var(--kds-color-text-primary);
5650
- margin: 0 0 var(--kds-spacing-2);
6018
+ margin-bottom: var(--kds-spacing-2) !important;
6019
+ }
6020
+
6021
+ /* Opt-in size modifiers (additive — do NOT change default 16/600) */
6022
+ .kds-card-title--lg {
6023
+ font-size: var(--kds-font-size-xl); /* 20px */
6024
+ font-weight: var(--kds-font-weight-bold); /* 700 */
6025
+ }
6026
+
6027
+ .kds-card-title--xl {
6028
+ font-size: var(--kds-font-size-2xl); /* 24px */
6029
+ font-weight: var(--kds-font-weight-bold); /* 700 */
5651
6030
  }
5652
6031
 
5653
6032
  /* -- Key-Value Grid -- */
5654
6033
  .kds-kv {
5655
6034
  display: grid;
5656
6035
  grid-template-columns: auto 1fr;
5657
- row-gap: var(--kds-spacing-1);
5658
- column-gap: var(--kds-spacing-1-5);
6036
+ column-gap: var(--kds-spacing-1);
5659
6037
  align-items: baseline;
5660
6038
  }
5661
6039
 
@@ -5670,12 +6048,15 @@ div.kds-invoice-header,
5670
6048
 
5671
6049
  .kds-kv dd {
5672
6050
  margin: 0;
5673
- font-size: var(--kds-font-size-xs);
6051
+ font-size: var(--kds-font-size-sm);
5674
6052
  line-height: var(--kds-line-height-relaxed);
5675
- font-weight: var(--kds-font-weight-bold);
6053
+ font-weight: var(--kds-font-weight-semibold);
5676
6054
  letter-spacing: normal;
5677
6055
  color: var(--kds-color-gray-800);
5678
6056
  min-width: 0;
6057
+ white-space: nowrap;
6058
+ overflow: hidden;
6059
+ text-overflow: ellipsis;
5679
6060
  }
5680
6061
 
5681
6062
  /* -- Dividers -- */
@@ -5699,7 +6080,13 @@ div.kds-invoice-header,
5699
6080
  flex-direction: column;
5700
6081
  gap: var(--kds-spacing-1-5);
5701
6082
  margin: 0;
5702
- padding: 0 0 var(--kds-spacing-1);
6083
+ padding: 0;
6084
+ }
6085
+
6086
+ @media (max-width: 767px) {
6087
+ .kds-detail-list {
6088
+ padding-bottom: var(--kds-spacing-2);
6089
+ }
5703
6090
  }
5704
6091
 
5705
6092
  .kds-detail-group {
@@ -5715,7 +6102,6 @@ div.kds-invoice-header,
5715
6102
  letter-spacing: var(--kds-letter-spacing-wide);
5716
6103
  color: var(--kds-color-text-hint);
5717
6104
  text-transform: uppercase;
5718
- margin: 0 0 var(--kds-spacing-0-5);
5719
6105
  }
5720
6106
 
5721
6107
  .kds-detail-group dd {
@@ -5784,16 +6170,16 @@ div.kds-invoice-header,
5784
6170
  font-size: var(--kds-font-size-sm);
5785
6171
  }
5786
6172
 
5787
- .kds-recap-list .k {
6173
+ .kds-recap-list .kds-key {
5788
6174
  color: var(--kds-color-text-secondary);
5789
6175
  }
5790
6176
 
5791
- .kds-recap-list .v {
6177
+ .kds-recap-list .kds-value {
5792
6178
  color: var(--kds-color-text-primary);
5793
6179
  font-weight: 500;
5794
6180
  }
5795
6181
 
5796
- .kds-recap-list .v.placeholder {
6182
+ .kds-recap-list .kds-value.placeholder {
5797
6183
  color: var(--kds-color-text-hint);
5798
6184
  }
5799
6185
 
@@ -5862,6 +6248,8 @@ button.kds-btn-success::after {
5862
6248
  /* -- Alert inline (borderless, used inside cards) -- */
5863
6249
  .kds-alert-inline {
5864
6250
  border: none;
6251
+ padding: var(--kds-spacing-1) var(--kds-spacing-1-5);
6252
+ margin-bottom: var(--kds-spacing-1-5);
5865
6253
  }
5866
6254
 
5867
6255
  /* -- Card dimmed (behind overlays) -- */
@@ -5883,7 +6271,11 @@ button.kds-btn-success::after {
5883
6271
  display: flex;
5884
6272
  flex-direction: column;
5885
6273
  gap: var(--kds-spacing-1);
5886
- margin-top: var(--kds-spacing-1);
6274
+ margin-bottom: var(--kds-spacing-1);
6275
+ }
6276
+
6277
+ .kds-bank-list:last-child {
6278
+ margin-bottom: 0;
5887
6279
  }
5888
6280
 
5889
6281
  /* -- Field group spacing -- */
@@ -5959,17 +6351,42 @@ button.kds-btn-success::after {
5959
6351
  }
5960
6352
 
5961
6353
  .kds-bill-description-picture {
5962
- width: 120px;
5963
- height: 120px;
6354
+ max-width: 100px;
5964
6355
  object-fit: contain;
5965
6356
  background: var(--kds-color-background-paper);
5966
- padding: var(--kds-spacing-1-25);
5967
- border-radius: var(--kds-radius-md);
5968
- margin-top: var(--kds-spacing-1);
6357
+ margin-top: var(--kds-spacing-1-25);
5969
6358
  display: block;
5970
6359
  box-sizing: content-box;
5971
6360
  }
5972
6361
 
6362
+ /* -- Bill Attachments -- */
6363
+ .kds-bill-attachments {
6364
+ display: flex;
6365
+ flex-direction: column;
6366
+ gap: var(--kds-spacing-0-75);
6367
+ }
6368
+
6369
+ .kds-bill-attachment {
6370
+ display: inline-flex;
6371
+ align-items: center;
6372
+ justify-content: flex-start;
6373
+ width: fit-content;
6374
+ color: var(--kds-color-info-main);
6375
+ font-size: var(--kds-font-size-sm);
6376
+ font-weight: var(--kds-font-weight-medium);
6377
+ text-decoration: none;
6378
+ }
6379
+
6380
+ .kds-bill-attachment:hover span {
6381
+ text-decoration: underline;
6382
+ }
6383
+
6384
+ .kds-bill-attachment i {
6385
+ font-size: var(--kds-font-size-lg);
6386
+ min-width: unset;
6387
+ justify-content: flex-start;
6388
+ }
6389
+
5973
6390
  /* -- Share Card (mustContinue) -- */
5974
6391
  .kds-share-card {
5975
6392
  margin-top: var(--kds-spacing-2);
@@ -6082,6 +6499,14 @@ button.kds-btn-success::after {
6082
6499
  padding-top: 0;
6083
6500
  padding-bottom: 0;
6084
6501
  }
6502
+
6503
+ /* Reset BeerCSS sibling margin on form/section inside payment cards.
6504
+ BeerCSS sets `:not(.grid,nav,.row) > … + form/section { margin-block-start:1rem }`
6505
+ which adds unwanted spacing inside cards that contain forms. */
6506
+ .kds-payment-flow .kds-card-elevated > form,
6507
+ .kds-payment-flow .kds-card-elevated > section {
6508
+ margin-block-start: 0;
6509
+ }
6085
6510
  .kds-payment-flow .kds-card-elevated.kds-invoice-sticky {
6086
6511
  padding-top: var(--kds-spacing-1);
6087
6512
  padding-bottom: 0;
@@ -6131,10 +6556,17 @@ button.kds-btn-success::after {
6131
6556
  padding-bottom: var(--kds-spacing-2);
6132
6557
  }
6133
6558
 
6134
- /* Invoice sticky card: progressive padding-top (expanded 20px → collapsed 8px).
6135
- Overrides base rule at same specificity; source order wins here. */
6559
+ /* Invoice sticky card padding (mobile).
6560
+ Top: estático 12px. Bottom: progresivo 20px (expandido) 8px (colapsado).
6561
+ El padding-bottom animado da breathing room natural cuando expandido y se
6562
+ reduce convencionalmente al colapsar — sin depender de que el clip-path
6563
+ corte el padding abruptamente. */
6136
6564
  .kds-payment-flow .kds-card-elevated.kds-invoice-sticky {
6137
6565
  padding-top: var(--kds-spacing-1-5);
6566
+ padding-bottom: calc(
6567
+ var(--kds-spacing-2-5)
6568
+ - var(--kds-spacing-1-5) * var(--collapse-progress, 0)
6569
+ );
6138
6570
  }
6139
6571
 
6140
6572
 
@@ -6173,7 +6605,8 @@ button.kds-btn-success::after {
6173
6605
  }
6174
6606
  .kds-brand-inner svg,
6175
6607
  .kds-brand-inner img {
6176
- height: 22px;
6608
+ width: calc(50px - 16px * var(--collapse-progress, 0));
6609
+ height: auto;
6177
6610
  display: block;
6178
6611
  }
6179
6612
 
@@ -6392,7 +6825,7 @@ button.kds-btn-success::after {
6392
6825
  inset: 0;
6393
6826
  background: var(--kds-modal-backdrop);
6394
6827
  display: none;
6395
- align-items: center;
6828
+ align-items: flex-start;
6396
6829
  justify-content: center;
6397
6830
  z-index: var(--kds-z-index-modal, 50);
6398
6831
  animation: kds-fade 0.2s ease both;
@@ -6420,7 +6853,7 @@ button.kds-btn-success::after {
6420
6853
  display: flex;
6421
6854
  align-items: center;
6422
6855
  justify-content: space-between;
6423
- padding: var(--kds-spacing-2) var(--kds-spacing-2) var(--kds-spacing-1);
6856
+ padding: var(--kds-spacing-1) var(--kds-spacing-2) var(--kds-spacing-1);
6424
6857
  }
6425
6858
 
6426
6859
  .kds-bank-modal-header h3 {
@@ -6567,7 +7000,7 @@ button.kds-btn-success::after {
6567
7000
  min-width: 0;
6568
7001
  }
6569
7002
 
6570
- .kds-qr-text .title {
7003
+ .kds-qr-text .kds-qr-title {
6571
7004
  font-family: var(--kds-font-family-primary);
6572
7005
  font-weight: 600;
6573
7006
  font-size: var(--kds-font-size-sm);
@@ -6575,10 +7008,15 @@ button.kds-btn-success::after {
6575
7008
  color: var(--kds-color-text-primary);
6576
7009
  }
6577
7010
 
6578
- .kds-qr-text .sub {
7011
+ .kds-qr-text .kds-qr-subtitle {
6579
7012
  font-family: var(--kds-font-family-primary);
6580
7013
  font-size: var(--kds-font-size-caption);
6581
7014
  color: var(--kds-color-text-secondary);
7015
+ /* Trunca con ellipsis en lugar de wrap a 2 líneas — evita apretar el row
7016
+ cuando el contenedor es angosto (mobile o decorator constrained). */
7017
+ overflow: hidden;
7018
+ text-overflow: ellipsis;
7019
+ white-space: nowrap;
6582
7020
  }
6583
7021
 
6584
7022
  /* QR Badge - "Rápido" indicator */
@@ -6601,46 +7039,26 @@ button.kds-btn-success::after {
6601
7039
  font-size: 20px;
6602
7040
  }
6603
7041
 
6604
- /* Mobile responsive: Ajustes para pantallas pequeñas */
7042
+ /* Mobile responsive (≤480px): respira más mantenemos padding/gap/avatar igual
7043
+ que desktop y solo agregamos truncation al subtitle y `flex-shrink: 0` en los
7044
+ ítems que deben mantener su tamaño (avatar, badge, chevron). */
6605
7045
  @media (max-width: 480px) {
6606
- .kds-qr-row {
6607
- gap: var(--kds-spacing-1-5);
6608
- padding: var(--kds-spacing-1-5);
6609
- }
6610
-
6611
7046
  .kds-qr-avatar {
6612
- width: var(--kds-spacing-4-5);
6613
- height: var(--kds-spacing-4-5);
6614
7047
  flex-shrink: 0;
6615
7048
  }
6616
7049
 
6617
- .kds-qr-avatar .material-symbols-outlined,
6618
- .kds-qr-avatar .material-icons-round {
6619
- font-size: var(--kds-font-size-lg);
6620
- }
6621
-
6622
- .kds-qr-text .title {
6623
- font-size: var(--kds-font-size-xs);
6624
- line-height: var(--kds-line-height-tight);
6625
- }
6626
-
6627
7050
  .kds-qr-text .sub {
6628
- font-size: var(--kds-font-size-caption);
6629
- line-height: var(--kds-line-height-tight);
6630
7051
  overflow: hidden;
6631
7052
  text-overflow: ellipsis;
6632
7053
  white-space: nowrap;
6633
7054
  }
6634
7055
 
6635
7056
  .kds-qr-badge {
6636
- font-size: var(--kds-font-size-caption);
6637
- padding: var(--kds-spacing-0-25) var(--kds-spacing-0-75);
6638
7057
  flex-shrink: 0;
6639
7058
  }
6640
7059
 
6641
7060
  .kds-qr-row .material-symbols-outlined:last-child,
6642
7061
  .kds-qr-row .material-icons-round:last-child {
6643
- font-size: var(--kds-font-size-base);
6644
7062
  flex-shrink: 0;
6645
7063
  }
6646
7064
  }
@@ -6669,7 +7087,11 @@ button.kds-btn-success::after {
6669
7087
  border-radius: var(--kds-spacing-0-75);
6670
7088
  font-size: var(--kds-font-size-sm);
6671
7089
  cursor: pointer;
6672
- transition: background 0.12s ease;
7090
+ /* Transición más amplia y suave: bg + color + border ease-out */
7091
+ transition:
7092
+ background-color 280ms cubic-bezier(0.2, 0.8, 0.2, 1),
7093
+ color 280ms cubic-bezier(0.2, 0.8, 0.2, 1),
7094
+ border-top-color 280ms ease-out;
6673
7095
  position: relative;
6674
7096
  user-select: none;
6675
7097
  }
@@ -6678,19 +7100,21 @@ button.kds-btn-success::after {
6678
7100
  border-top: 0;
6679
7101
  }
6680
7102
 
6681
- .kds-copyable-table-row:hover {
7103
+ /* Hover NO aplica mientras la row esté en `.copied` o `.settling`
7104
+ (evita el flicker del hover state al desaparecer el verde de "copiado") */
7105
+ .kds-copyable-table-row:not(.copied):not(.settling):hover {
6682
7106
  background: var(--kds-color-primary-faint);
6683
7107
  }
6684
7108
 
6685
- .kds-copyable-table-row:hover + .kds-copyable-table-row {
7109
+ .kds-copyable-table-row:not(.copied):not(.settling):hover + .kds-copyable-table-row {
6686
7110
  border-top-color: transparent;
6687
7111
  }
6688
7112
 
6689
- .kds-copyable-table-row:active {
7113
+ .kds-copyable-table-row:not(.copied):not(.settling):active {
6690
7114
  background: var(--kds-color-primary-selected);
6691
7115
  }
6692
7116
 
6693
- .kds-copyable-table-row .k {
7117
+ .kds-copyable-table-row .kds-key {
6694
7118
  color: var(--kds-color-text-secondary);
6695
7119
  font-size: var(--kds-font-size-caption);
6696
7120
  letter-spacing: 0.3px;
@@ -6699,7 +7123,7 @@ button.kds-btn-success::after {
6699
7123
  flex: 0 0 auto;
6700
7124
  }
6701
7125
 
6702
- .kds-copyable-table-row .v {
7126
+ .kds-copyable-table-row .kds-value {
6703
7127
  color: var(--kds-color-text-primary);
6704
7128
  font-family: 'JetBrains Mono', 'SF Mono', ui-monospace, Menlo, Consolas, monospace;
6705
7129
  font-weight: var(--kds-font-weight-medium);
@@ -6715,17 +7139,18 @@ button.kds-btn-success::after {
6715
7139
  flex: 1 1 auto;
6716
7140
  }
6717
7141
 
6718
- .kds-copyable-table-row .v::after {
7142
+ .kds-copyable-table-row .kds-value::after {
6719
7143
  content: 'content_copy';
6720
7144
  font-family: 'Material Symbols Outlined';
6721
7145
  font-size: var(--kds-font-size-sm);
6722
7146
  color: var(--kds-color-primary-main);
6723
7147
  opacity: 0;
6724
- transition: opacity 0.12s ease;
7148
+ /* Transición coordinada con la row */
7149
+ transition: opacity 280ms cubic-bezier(0.2, 0.8, 0.2, 1);
6725
7150
  flex: 0 0 auto;
6726
7151
  }
6727
7152
 
6728
- .kds-copyable-table-row:hover .v::after {
7153
+ .kds-copyable-table-row:not(.copied):not(.settling):hover .kds-value::after {
6729
7154
  opacity: 0.7;
6730
7155
  }
6731
7156
 
@@ -6733,17 +7158,25 @@ button.kds-btn-success::after {
6733
7158
  background: var(--kds-color-success-soft);
6734
7159
  }
6735
7160
 
6736
- .kds-copyable-table-row.copied .v {
7161
+ .kds-copyable-table-row.copied .kds-value {
6737
7162
  color: var(--kds-color-success-dark);
6738
7163
  }
6739
7164
 
6740
- .kds-copyable-table-row.copied .v::after {
7165
+ .kds-copyable-table-row.copied .kds-value::after {
6741
7166
  content: 'check';
6742
7167
  font-family: 'Material Symbols Outlined';
6743
7168
  color: var(--kds-color-success-dark);
6744
7169
  opacity: 1;
6745
7170
  }
6746
7171
 
7172
+ /* `.settling`: estado de "recién copiado" — la row vuelve al normal sin
7173
+ activar hover. Dura lo mismo que la transición (~300ms) y se aplica
7174
+ desde React tras quitar `.copied`. */
7175
+ .kds-copyable-table-row.settling .kds-value::after {
7176
+ /* Mantén el check con opacity 0 mientras settling, fade out suave */
7177
+ opacity: 0;
7178
+ }
7179
+
6747
7180
  /* Disable BeerCSS ripple on copyable table rows */
6748
7181
  .kds-copyable-table-row::after {
6749
7182
  display: none;
@@ -6806,6 +7239,14 @@ a.kds-copy-all-btn.copied:hover {
6806
7239
  min-height: unset;
6807
7240
  }
6808
7241
 
7242
+ /* Severity variants — default stays warning (backward-compatible) */
7243
+ .kds-section-note.kds-info { color: var(--kds-color-info-dark); }
7244
+ .kds-section-note.kds-info > i { color: var(--kds-color-info-dark); }
7245
+ .kds-section-note.kds-success { color: var(--kds-color-success-dark); }
7246
+ .kds-section-note.kds-success > i { color: var(--kds-color-success-dark); }
7247
+ .kds-section-note.kds-error { color: var(--kds-color-error-dark); }
7248
+ .kds-section-note.kds-error > i { color: var(--kds-color-error-dark); }
7249
+
6809
7250
  /* ========================================
6810
7251
  INFO TOOLTIP (.kds-info-tip)
6811
7252
  Inline info button with hover/click tooltip bubble.
@@ -6901,7 +7342,7 @@ a.kds-copy-all-btn.copied:hover {
6901
7342
  .kds-monto-row {
6902
7343
  display: flex;
6903
7344
  justify-content: space-between;
6904
- align-items: flex-end;
7345
+ align-items: flex-start;
6905
7346
  padding: var(--kds-spacing-1-75) 0 var(--kds-spacing-1);
6906
7347
  border-top: 1px dashed var(--kds-color-divider);
6907
7348
  margin-top: var(--kds-spacing-1-75);
@@ -6925,3 +7366,190 @@ a.kds-copy-all-btn.copied:hover {
6925
7366
  color: var(--kds-color-text-primary);
6926
7367
  }
6927
7368
 
7369
+ /* ========================================
7370
+ PAYMENT TOTAL (.kds-payment-total)
7371
+ Bloque "monto a pagar" para QR view y email templates.
7372
+ Portado desde paylink-ligopay → <kh:paymentTotal> + materialize-config.css.
7373
+ Variantes:
7374
+ - default: amount grande (3rem) en color primario Khipu.
7375
+ - email: amount compacto (1.5rem) en color texto primario.
7376
+ Responsive (default): mobile (≤ 1024px) centra y oculta titleMobile.
7377
+ ======================================== */
7378
+
7379
+ .kds-payment-total {
7380
+ /* Component-scoped tokens — overrideables sin tocar el CSS global. */
7381
+ --kds-payment-total-title-size: var(--kds-font-size-2xl); /* 24px */
7382
+ --kds-payment-total-label-size: var(--kds-font-size-xl); /* 20px */
7383
+ --kds-payment-amount-size: 3rem; /* 48px — destacado */
7384
+ --kds-payment-amount-line-height: var(--kds-line-height-snug);
7385
+ --kds-payment-amount-color: var(--kds-color-primary-main);
7386
+ --kds-payment-amount-weight: var(--kds-font-weight-medium);
7387
+
7388
+ text-align: left;
7389
+ }
7390
+
7391
+ .kds-payment-total-title,
7392
+ .kds-payment-total-title-mobile {
7393
+ font-size: var(--kds-payment-total-title-size);
7394
+ font-weight: var(--kds-font-weight-semibold);
7395
+ color: var(--kds-color-text-primary);
7396
+ margin-bottom: var(--kds-spacing-4);
7397
+ }
7398
+
7399
+ .kds-payment-total-title-mobile {
7400
+ display: none;
7401
+ }
7402
+
7403
+ .kds-payment-total .kds-payment-label {
7404
+ font-size: var(--kds-payment-total-label-size);
7405
+ font-weight: var(--kds-font-weight-semibold);
7406
+ color: var(--kds-color-text-primary);
7407
+ margin-bottom: var(--kds-spacing-1);
7408
+ padding-top: 0;
7409
+ }
7410
+
7411
+ .kds-payment-total .kds-payment-amount {
7412
+ font-size: var(--kds-payment-amount-size);
7413
+ font-weight: var(--kds-payment-amount-weight);
7414
+ line-height: var(--kds-payment-amount-line-height);
7415
+ color: var(--kds-payment-amount-color);
7416
+ margin-bottom: var(--kds-spacing-4);
7417
+ }
7418
+
7419
+ .kds-payment-total .kds-payment-amount .kds-payment-total-decimal-sup {
7420
+ font-size: var(--kds-font-size-decimal-sup);
7421
+ font-weight: var(--kds-font-weight-semibold);
7422
+ position: relative;
7423
+ top: 0;
7424
+ }
7425
+
7426
+ /* Variante email: amount compacto en color texto primario, alineación izquierda fija */
7427
+ .kds-payment-total--email {
7428
+ --kds-payment-amount-size: var(--kds-font-size-2xl); /* 24px */
7429
+ --kds-payment-amount-line-height: var(--kds-line-height-snug);
7430
+ --kds-payment-amount-color: var(--kds-color-text-primary);
7431
+ --kds-payment-amount-weight: var(--kds-font-weight-semibold);
7432
+ }
7433
+
7434
+ /* Tone modifier: swaps the amount color to the khipu-blue / LigoPay info blue.
7435
+ Combinable with --email or with the default variant. */
7436
+ .kds-payment-total--tone-info {
7437
+ --kds-payment-amount-color: var(--kds-color-info-blue); /* #5A5FE0 */
7438
+ }
7439
+
7440
+ /* Centered modifier: removes the asymmetric desktop padding (which exists for
7441
+ LigoPay QR view) and centers all internal text. Composable with --email and
7442
+ --tone-info. */
7443
+ .kds-payment-total--centered {
7444
+ padding-left: 0;
7445
+ padding-top: 0;
7446
+ text-align: center;
7447
+ }
7448
+ .kds-payment-total--centered .kds-payment-total-title,
7449
+ .kds-payment-total--centered .kds-payment-total-title-mobile,
7450
+ .kds-payment-total--centered .kds-payment-label,
7451
+ .kds-payment-total--centered .kds-payment-amount {
7452
+ text-align: center;
7453
+ }
7454
+
7455
+ /* Responsive: mobile ≤ 1024px — centra y conmuta los títulos (sólo variante default) */
7456
+ @media (max-width: 1024px) {
7457
+ .kds-payment-total {
7458
+ text-align: center;
7459
+ }
7460
+
7461
+ .kds-payment-total .kds-payment-total-title {
7462
+ display: none;
7463
+ }
7464
+
7465
+ .kds-payment-total .kds-payment-total-title-mobile {
7466
+ display: block;
7467
+ text-align: center;
7468
+ }
7469
+
7470
+ .kds-payment-total .kds-payment-label,
7471
+ .kds-payment-total .kds-payment-amount {
7472
+ text-align: center;
7473
+ }
7474
+
7475
+ /* Email mantiene alineación izquierda incluso en mobile (matchea email clients) */
7476
+ .kds-payment-total--email,
7477
+ .kds-payment-total--email .kds-payment-label,
7478
+ .kds-payment-total--email .kds-payment-amount {
7479
+ text-align: left;
7480
+ }
7481
+ }
7482
+
7483
+ /* ==========================================================================
7484
+ GRID UTILITIES — semantic aliases for BeerCSS .grid / .s* / .m* / .l*
7485
+
7486
+ Estas utilidades son ALIAS de las clases cortas de BeerCSS para que
7487
+ consumers (payment, LigoPay, Grails legacy) puedan escribir markup con
7488
+ nombres descriptivos sin renunciar al grid de 12 columnas de BeerCSS.
7489
+
7490
+ Convención (estilo Bootstrap responsive):
7491
+ - kds-grid → .grid (12-col CSS grid + 1rem gap)
7492
+ - kds-col-sm-{1..12} → .s{1..12} (mobile, siempre aplica)
7493
+ - kds-col-md-{1..12} → .m{1..12} (>=601px)
7494
+ - kds-col-lg-{1..12} → .l{1..12} (>=993px)
7495
+
7496
+ Las definiciones originales de BeerCSS NO se tocan; estas son aditivas.
7497
+ ========================================================================== */
7498
+
7499
+ .kds-grid {
7500
+ --_gap: 1rem;
7501
+ display: grid;
7502
+ grid-template-columns: repeat(12, 1fr);
7503
+ gap: var(--_gap);
7504
+ block-size: auto;
7505
+ }
7506
+
7507
+ .kds-grid.kds-grid-no-space { --_gap: 0rem; }
7508
+ .kds-grid.kds-grid-medium-space { --_gap: 1.5rem; }
7509
+ .kds-grid.kds-grid-large-space { --_gap: 2rem; }
7510
+
7511
+ .kds-grid > * { margin: 0; }
7512
+
7513
+ .kds-col-sm-1 { grid-area: auto/span 1; }
7514
+ .kds-col-sm-2 { grid-area: auto/span 2; }
7515
+ .kds-col-sm-3 { grid-area: auto/span 3; }
7516
+ .kds-col-sm-4 { grid-area: auto/span 4; }
7517
+ .kds-col-sm-5 { grid-area: auto/span 5; }
7518
+ .kds-col-sm-6 { grid-area: auto/span 6; }
7519
+ .kds-col-sm-7 { grid-area: auto/span 7; }
7520
+ .kds-col-sm-8 { grid-area: auto/span 8; }
7521
+ .kds-col-sm-9 { grid-area: auto/span 9; }
7522
+ .kds-col-sm-10 { grid-area: auto/span 10; }
7523
+ .kds-col-sm-11 { grid-area: auto/span 11; }
7524
+ .kds-col-sm-12 { grid-area: auto/span 12; }
7525
+
7526
+ @media only screen and (min-width: 601px) {
7527
+ .kds-col-md-1 { grid-area: auto/span 1; }
7528
+ .kds-col-md-2 { grid-area: auto/span 2; }
7529
+ .kds-col-md-3 { grid-area: auto/span 3; }
7530
+ .kds-col-md-4 { grid-area: auto/span 4; }
7531
+ .kds-col-md-5 { grid-area: auto/span 5; }
7532
+ .kds-col-md-6 { grid-area: auto/span 6; }
7533
+ .kds-col-md-7 { grid-area: auto/span 7; }
7534
+ .kds-col-md-8 { grid-area: auto/span 8; }
7535
+ .kds-col-md-9 { grid-area: auto/span 9; }
7536
+ .kds-col-md-10 { grid-area: auto/span 10; }
7537
+ .kds-col-md-11 { grid-area: auto/span 11; }
7538
+ .kds-col-md-12 { grid-area: auto/span 12; }
7539
+ }
7540
+
7541
+ @media only screen and (min-width: 993px) {
7542
+ .kds-col-lg-1 { grid-area: auto/span 1; }
7543
+ .kds-col-lg-2 { grid-area: auto/span 2; }
7544
+ .kds-col-lg-3 { grid-area: auto/span 3; }
7545
+ .kds-col-lg-4 { grid-area: auto/span 4; }
7546
+ .kds-col-lg-5 { grid-area: auto/span 5; }
7547
+ .kds-col-lg-6 { grid-area: auto/span 6; }
7548
+ .kds-col-lg-7 { grid-area: auto/span 7; }
7549
+ .kds-col-lg-8 { grid-area: auto/span 8; }
7550
+ .kds-col-lg-9 { grid-area: auto/span 9; }
7551
+ .kds-col-lg-10 { grid-area: auto/span 10; }
7552
+ .kds-col-lg-11 { grid-area: auto/span 11; }
7553
+ .kds-col-lg-12 { grid-area: auto/span 12; }
7554
+ }
7555
+