@khipu/design-system 0.2.0-alpha.117 → 0.2.0-alpha.119

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-07-09T20:18:21.242Z
14
+ * Generated: 2026-07-14T13:18:31.041Z
15
15
  *
16
16
  * To regenerate:
17
17
  * cd design-system && npm run tokens:generate
@@ -6735,8 +6735,6 @@ div.kds-invoice-header,
6735
6735
  place-items: center;
6736
6736
  color: #fff;
6737
6737
  flex-shrink: 0;
6738
- /* Clip the slightly-oversized logo (see `.kds-invoice-merchant img`) to the
6739
- rounded square so it can fully cover the deep-purple background. */
6740
6738
  overflow: hidden;
6741
6739
  }
6742
6740
 
@@ -6750,6 +6748,12 @@ div.kds-invoice-header,
6750
6748
  color: var(--kds-color-text-primary);
6751
6749
  }
6752
6750
 
6751
+ /* Neutro oscuro para logos claros (detección de luminancia — KTUF-204). */
6752
+ .kds-invoice-merchant-neutral.dark {
6753
+ background: var(--kds-color-gray-800);
6754
+ border-color: var(--kds-color-gray-700);
6755
+ }
6756
+
6753
6757
  .kds-invoice-merchant.initials {
6754
6758
  font-weight: 700;
6755
6759
  font-size: 11px;
@@ -6757,13 +6761,12 @@ div.kds-invoice-header,
6757
6761
  }
6758
6762
 
6759
6763
  .kds-invoice-merchant img {
6760
- /* Slightly larger than the container (+2px, centered by the grid) so the
6761
- logo overflows under the parent's rounded clip and the deep-purple
6762
- background never peeks through at the corners when the logo shrinks. */
6763
- width: calc(100% + 2px);
6764
- height: calc(100% + 2px);
6765
- object-fit: cover;
6766
- border-radius: var(--kds-radius-md);
6764
+ /* `contain` sobre el fondo neutro: el logo se muestra completo y las
6765
+ transparencias no quedan sobre el color de marca (KTUF-204). */
6766
+ width: 100%;
6767
+ height: 100%;
6768
+ object-fit: contain;
6769
+ padding: var(--kds-spacing-0-5);
6767
6770
  }
6768
6771
 
6769
6772
  /* -- Card Title -- */
@@ -894,10 +894,85 @@ const ui = _context.ui;
894
894
  initStickyInvoice();
895
895
  initHideOnScroll();
896
896
  initBankModal();
897
+ initMerchantLogoBackdrop();
897
898
 
898
899
  console.log('Material Design initialization complete!');
899
900
  }
900
901
 
902
+ /**
903
+ * Initialize merchant logo backdrop (KTUF-204)
904
+ * Los logos de comercio van sobre el fondo neutro, no sobre el color de marca (los PNG
905
+ * con transparencia se ahogan contra su propio color). La luminancia decide entre los
906
+ * dos neutros: paper para logos oscuros, gray-800 para logos claros. Espejo vanilla de
907
+ * KdsInvoiceMerchant/logoLuminance.ts para las vistas server-side (payment).
908
+ * @param {Element} root - Root element to scope the query (default: document)
909
+ */
910
+ function initMerchantLogoBackdrop(root) {
911
+ root = root || document;
912
+ var LIGHT_LOGO_LUMINANCE_THRESHOLD = 0.72;
913
+ var SAMPLE_SIZE = 16;
914
+ var ALPHA_THRESHOLD = 128;
915
+ var MIN_OPAQUE_RATIO = 0.02;
916
+
917
+ root.querySelectorAll('.kds-invoice-merchant').forEach(function(tile) {
918
+ var img = tile.querySelector('img');
919
+ if (!img) return;
920
+
921
+ /* Con logo: fondo neutro; el color de marca queda solo para el fallback. */
922
+ var brandBackground = tile.style.background;
923
+ tile.style.background = '';
924
+ tile.classList.add('kds-invoice-merchant-neutral');
925
+
926
+ /* Si el logo falla (el onerror server-side lo reemplaza por el ícono),
927
+ restaurar el tile de color de marca. */
928
+ img.addEventListener('error', function() {
929
+ tile.classList.remove('kds-invoice-merchant-neutral', 'dark');
930
+ tile.style.background = brandBackground;
931
+ });
932
+
933
+ measureLogoLuminance(img.getAttribute('src'), function(luminance) {
934
+ if (luminance != null && luminance > LIGHT_LOGO_LUMINANCE_THRESHOLD &&
935
+ tile.classList.contains('kds-invoice-merchant-neutral')) {
936
+ tile.classList.add('dark');
937
+ }
938
+ });
939
+ });
940
+
941
+ function measureLogoLuminance(url, callback) {
942
+ if (!url) { callback(null); return; }
943
+ var probe = new Image();
944
+ probe.crossOrigin = 'anonymous';
945
+ probe.onload = function() {
946
+ try {
947
+ var canvas = document.createElement('canvas');
948
+ canvas.width = SAMPLE_SIZE;
949
+ canvas.height = SAMPLE_SIZE;
950
+ var context = canvas.getContext('2d');
951
+ if (!context) { callback(null); return; }
952
+ context.drawImage(probe, 0, 0, SAMPLE_SIZE, SAMPLE_SIZE);
953
+ var data = context.getImageData(0, 0, SAMPLE_SIZE, SAMPLE_SIZE).data;
954
+ var sum = 0;
955
+ var opaquePixels = 0;
956
+ for (var i = 0; i < data.length; i += 4) {
957
+ if (data[i + 3] < ALPHA_THRESHOLD) continue;
958
+ sum += (0.2126 * data[i] + 0.7152 * data[i + 1] + 0.0722 * data[i + 2]) / 255;
959
+ opaquePixels++;
960
+ }
961
+ if (opaquePixels < SAMPLE_SIZE * SAMPLE_SIZE * MIN_OPAQUE_RATIO) {
962
+ callback(null);
963
+ return;
964
+ }
965
+ callback(sum / opaquePixels);
966
+ } catch (e) {
967
+ /* canvas tainted: el origen no permite CORS — no medible */
968
+ callback(null);
969
+ }
970
+ };
971
+ probe.onerror = function() { callback(null); };
972
+ probe.src = url;
973
+ }
974
+ }
975
+
901
976
  /**
902
977
  * Initialize sidenav for mobile navigation
903
978
  */