@khipu/design-system 0.3.5-alpha.34 → 0.3.5-alpha.36
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.
- package/dist/beercss/khipu-beercss.css +964 -17
- package/dist/beercss/khipu-beercss.js +63 -0
- package/dist/beercss/khipu-beercss.min.css +1 -1
- package/dist/beercss/khipu-beercss.min.js +1 -1
- package/dist/beercss/khipu-beercss.scoped.css +964 -16
- package/dist/beercss/khipu-beercss.scoped.min.css +1 -1
- package/dist/beercss/metadata.json +5 -5
- package/dist/index.d.mts +367 -9
- package/dist/index.d.ts +367 -9
- package/dist/index.js +1113 -405
- package/dist/index.mjs +1078 -379
- package/package.json +1 -1
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
*
|
|
14
14
|
* AUTO-GENERATED FILE - DO NOT EDIT MANUALLY
|
|
15
15
|
* Source: design-system/src/tokens/tokens.json
|
|
16
|
-
* Generated: 2026-10-
|
|
16
|
+
* Generated: 2026-10-15T20:27:25.703Z
|
|
17
17
|
*
|
|
18
18
|
* To regenerate:
|
|
19
19
|
* cd design-system && npm run tokens:generate
|
|
@@ -1485,6 +1485,118 @@ a.kds-btn.kds-btn-md {
|
|
|
1485
1485
|
line-height: var(--kds-line-height-normal);
|
|
1486
1486
|
}
|
|
1487
1487
|
|
|
1488
|
+
/* Extra content under the description (e.g. a "Necesitarás" list). */
|
|
1489
|
+
.kds-card-selector-details {
|
|
1490
|
+
font-size: var(--kds-font-size-sm);
|
|
1491
|
+
color: var(--kds-color-text-primary);
|
|
1492
|
+
line-height: var(--kds-line-height-normal);
|
|
1493
|
+
}
|
|
1494
|
+
|
|
1495
|
+
/* !important on the top margin: BeerCSS adds 1rem to a list after a sibling with a higher
|
|
1496
|
+
specificity (same approach as .kds-card-plan ul). */
|
|
1497
|
+
.kds-card-selector-details :is(ul, ol) {
|
|
1498
|
+
margin: 0;
|
|
1499
|
+
margin-block-start: var(--kds-spacing-1) !important;
|
|
1500
|
+
padding-inline-start: var(--kds-spacing-2-5);
|
|
1501
|
+
}
|
|
1502
|
+
|
|
1503
|
+
/* Small section label inside the details, e.g. "Necesitarás". */
|
|
1504
|
+
.kds-card-selector-eyebrow {
|
|
1505
|
+
display: block;
|
|
1506
|
+
font-size: var(--kds-font-size-xs);
|
|
1507
|
+
font-weight: var(--kds-font-weight-bold);
|
|
1508
|
+
letter-spacing: var(--kds-letter-spacing-wide);
|
|
1509
|
+
text-transform: uppercase;
|
|
1510
|
+
color: var(--primary);
|
|
1511
|
+
}
|
|
1512
|
+
|
|
1513
|
+
/* Radio option (.kds-card-selector--radio): a <div> card with a native radio top-right
|
|
1514
|
+
and the title <label> stretched over the card, so any click selects it and cards
|
|
1515
|
+
sharing a `name` behave as one radio group (arrow keys, form submit) without JS.
|
|
1516
|
+
Same pattern as .kds-card-plan--selectable. */
|
|
1517
|
+
.kds-card-selector--radio {
|
|
1518
|
+
position: relative;
|
|
1519
|
+
padding: var(--kds-spacing-2-5);
|
|
1520
|
+
gap: var(--kds-spacing-1);
|
|
1521
|
+
}
|
|
1522
|
+
|
|
1523
|
+
/* Icon tile tinted from --primary (follows the merchant's brand; the base tile uses the
|
|
1524
|
+
fixed --kds-color-primary-focus). Base button-mode cards keep their tile. */
|
|
1525
|
+
.kds-card-selector--radio .kds-card-selector-icon {
|
|
1526
|
+
background: color-mix(in srgb, var(--primary) 12%, transparent);
|
|
1527
|
+
border-radius: var(--kds-radius-md);
|
|
1528
|
+
}
|
|
1529
|
+
|
|
1530
|
+
/* Selector group (KdsCardSelectorGroup): columns by the group's own width, like
|
|
1531
|
+
.kds-card-plan-group. */
|
|
1532
|
+
.kds-card-selector-group {
|
|
1533
|
+
display: grid;
|
|
1534
|
+
grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr));
|
|
1535
|
+
gap: var(--kds-spacing-2);
|
|
1536
|
+
align-items: stretch;
|
|
1537
|
+
}
|
|
1538
|
+
|
|
1539
|
+
.kds-card-selector-radio {
|
|
1540
|
+
position: absolute;
|
|
1541
|
+
top: var(--kds-spacing-2);
|
|
1542
|
+
right: var(--kds-spacing-2);
|
|
1543
|
+
z-index: 2;
|
|
1544
|
+
width: var(--kds-spacing-2-5);
|
|
1545
|
+
height: var(--kds-spacing-2-5);
|
|
1546
|
+
margin: 0;
|
|
1547
|
+
accent-color: var(--primary);
|
|
1548
|
+
cursor: pointer;
|
|
1549
|
+
}
|
|
1550
|
+
|
|
1551
|
+
/* BeerCSS positions and sizes bare <label>s; the title keeps its own type styles and
|
|
1552
|
+
must stay static so its ::after resolves against the card. */
|
|
1553
|
+
.kds-card-selector--radio label.kds-card-selector-title {
|
|
1554
|
+
position: static;
|
|
1555
|
+
padding-inline-end: var(--kds-spacing-4);
|
|
1556
|
+
cursor: pointer;
|
|
1557
|
+
}
|
|
1558
|
+
|
|
1559
|
+
.kds-card-selector--radio label.kds-card-selector-title::after {
|
|
1560
|
+
content: "";
|
|
1561
|
+
position: absolute;
|
|
1562
|
+
inset: 0;
|
|
1563
|
+
z-index: 1;
|
|
1564
|
+
border-radius: var(--kds-radius-md);
|
|
1565
|
+
}
|
|
1566
|
+
|
|
1567
|
+
/* Interactive content inside the card stays above the stretched label. */
|
|
1568
|
+
.kds-card-selector--radio :is(a, button, input:not(.kds-card-selector-radio), select, textarea, summary, [tabindex]) {
|
|
1569
|
+
position: relative;
|
|
1570
|
+
z-index: 2;
|
|
1571
|
+
}
|
|
1572
|
+
|
|
1573
|
+
/* Hover must not look like the checked state: neutral, darker border. Same specificity as
|
|
1574
|
+
the base `.kds-card-selector:hover:not(.selected)` (primary tint) and later, so it wins. */
|
|
1575
|
+
.kds-card-selector.kds-card-selector--radio:hover:not(.selected) {
|
|
1576
|
+
border-color: var(--kds-border-dark);
|
|
1577
|
+
background: var(--kds-color-background-paper);
|
|
1578
|
+
}
|
|
1579
|
+
|
|
1580
|
+
/* Checked and focus need :has. Without it the radio keeps its native look and focus
|
|
1581
|
+
ring, so the choice and the focus stay visible in older browsers. */
|
|
1582
|
+
@supports selector(:has(*)) {
|
|
1583
|
+
/* Same brand tint as the selected plan card (follows the merchant's --primary).
|
|
1584
|
+
Doubled class so it outranks the neutral hover above and stays selected on hover. */
|
|
1585
|
+
.kds-card-selector.kds-card-selector--radio:has(.kds-card-selector-radio:checked) {
|
|
1586
|
+
border-color: var(--primary);
|
|
1587
|
+
background: color-mix(in srgb, var(--primary) 5%, var(--kds-surface-base));
|
|
1588
|
+
}
|
|
1589
|
+
|
|
1590
|
+
.kds-card-selector--radio:has(.kds-card-selector-radio:focus-visible) {
|
|
1591
|
+
outline: 2px solid var(--primary);
|
|
1592
|
+
outline-offset: 2px;
|
|
1593
|
+
}
|
|
1594
|
+
|
|
1595
|
+
.kds-card-selector-radio:focus-visible {
|
|
1596
|
+
outline: none;
|
|
1597
|
+
}
|
|
1598
|
+
}
|
|
1599
|
+
|
|
1488
1600
|
/* Selected state - visual feedback via border only */
|
|
1489
1601
|
|
|
1490
1602
|
/* Pricing/Plan card */
|
|
@@ -1529,9 +1641,190 @@ a.kds-btn.kds-btn-md {
|
|
|
1529
1641
|
box-shadow: var(--kds-shadow-elevation-4);
|
|
1530
1642
|
}
|
|
1531
1643
|
|
|
1532
|
-
/*
|
|
1533
|
-
|
|
1534
|
-
|
|
1644
|
+
/* Selectable plan (.kds-card-plan--selectable): a native radio sits top-right and the
|
|
1645
|
+
title <label> is stretched over the whole card, so any click selects it and cards
|
|
1646
|
+
sharing a `name` behave as one radio group (arrow keys, form submit) without JS. */
|
|
1647
|
+
.kds-card-plan-radio {
|
|
1648
|
+
position: absolute;
|
|
1649
|
+
top: var(--kds-spacing-2);
|
|
1650
|
+
right: var(--kds-spacing-2);
|
|
1651
|
+
z-index: 2;
|
|
1652
|
+
width: var(--kds-spacing-2-5);
|
|
1653
|
+
height: var(--kds-spacing-2-5);
|
|
1654
|
+
margin: 0;
|
|
1655
|
+
accent-color: var(--primary);
|
|
1656
|
+
cursor: pointer;
|
|
1657
|
+
}
|
|
1658
|
+
|
|
1659
|
+
.kds-card-plan--selectable .kds-card-plan-header {
|
|
1660
|
+
padding-inline-end: var(--kds-spacing-4);
|
|
1661
|
+
}
|
|
1662
|
+
|
|
1663
|
+
/* BeerCSS makes header, h3 and label `position: relative`; they must stay static so the
|
|
1664
|
+
label's ::after resolves against the card, not against the label itself. */
|
|
1665
|
+
.kds-card-plan--selectable :is(.kds-card-plan-header, .kds-card-plan-header h3, .kds-card-plan-header label) {
|
|
1666
|
+
position: static;
|
|
1667
|
+
}
|
|
1668
|
+
|
|
1669
|
+
/* BeerCSS sizes bare <label>s; the title label must look like the h3 it lives in. */
|
|
1670
|
+
.kds-card-plan--selectable .kds-card-plan-header label {
|
|
1671
|
+
font: inherit;
|
|
1672
|
+
color: inherit;
|
|
1673
|
+
cursor: pointer;
|
|
1674
|
+
}
|
|
1675
|
+
|
|
1676
|
+
/* Above the (BeerCSS-positioned) feature items, below the radio and actions. */
|
|
1677
|
+
.kds-card-plan--selectable .kds-card-plan-header label::after {
|
|
1678
|
+
content: "";
|
|
1679
|
+
position: absolute;
|
|
1680
|
+
inset: 0;
|
|
1681
|
+
z-index: 1;
|
|
1682
|
+
border-radius: var(--kds-radius-lg);
|
|
1683
|
+
}
|
|
1684
|
+
|
|
1685
|
+
/* Interactive content inside the card stays above the stretched label, so it remains
|
|
1686
|
+
clickable (features may come as raw HTML from the consumer). */
|
|
1687
|
+
.kds-card-plan--selectable :is(a, button, input:not(.kds-card-plan-radio), select, textarea, summary, [tabindex]) {
|
|
1688
|
+
position: relative;
|
|
1689
|
+
z-index: 2;
|
|
1690
|
+
}
|
|
1691
|
+
|
|
1692
|
+
/* Optional plan description (KdsCardPlan `description`) — a <div>, so BeerCSS's sibling
|
|
1693
|
+
margin on <p> does not apply. */
|
|
1694
|
+
.kds-card-plan-description {
|
|
1695
|
+
font-size: var(--kds-font-size-sm);
|
|
1696
|
+
line-height: var(--kds-line-height-normal);
|
|
1697
|
+
color: var(--kds-color-text-secondary);
|
|
1698
|
+
}
|
|
1699
|
+
|
|
1700
|
+
/* Optional check per feature (KdsCardPlan `checkFeatures`), in the brand color. */
|
|
1701
|
+
.kds-card-plan-features--check li {
|
|
1702
|
+
display: flex;
|
|
1703
|
+
align-items: flex-start;
|
|
1704
|
+
gap: var(--kds-spacing-1);
|
|
1705
|
+
}
|
|
1706
|
+
|
|
1707
|
+
.kds-card-plan-features--check li > i {
|
|
1708
|
+
flex: none;
|
|
1709
|
+
margin-top: 2px;
|
|
1710
|
+
font-size: var(--kds-font-size-base);
|
|
1711
|
+
color: var(--primary);
|
|
1712
|
+
}
|
|
1713
|
+
|
|
1714
|
+
/* Selectable plan cards (new, onboarding): compact like the plan screen — badge on top,
|
|
1715
|
+
smaller title and price, and the divider above the feature list instead of under a big
|
|
1716
|
+
price. Plain .kds-card-plan (marketing/billing) keeps its larger layout. */
|
|
1717
|
+
.kds-card-plan--selectable {
|
|
1718
|
+
gap: var(--kds-spacing-1);
|
|
1719
|
+
}
|
|
1720
|
+
|
|
1721
|
+
/* Badge as a soft tag (not the solid pill of marketing plan cards), so it doesn't compete
|
|
1722
|
+
with the selected border. */
|
|
1723
|
+
.kds-card-plan--selectable .kds-card-plan-badge {
|
|
1724
|
+
order: -1;
|
|
1725
|
+
padding: var(--kds-spacing-0-25) var(--kds-spacing-1);
|
|
1726
|
+
background: color-mix(in srgb, var(--primary) 12%, var(--kds-surface-base));
|
|
1727
|
+
color: var(--primary);
|
|
1728
|
+
font-weight: var(--kds-font-weight-medium);
|
|
1729
|
+
line-height: var(--kds-line-height-normal);
|
|
1730
|
+
border-radius: var(--kds-radius-sm);
|
|
1731
|
+
}
|
|
1732
|
+
|
|
1733
|
+
.kds-card-plan--selectable .kds-card-plan-header h3 {
|
|
1734
|
+
font-size: var(--kds-font-size-lg);
|
|
1735
|
+
}
|
|
1736
|
+
|
|
1737
|
+
.kds-card-plan--selectable .kds-card-plan-price {
|
|
1738
|
+
gap: var(--kds-spacing-0-5);
|
|
1739
|
+
border-bottom: 0;
|
|
1740
|
+
}
|
|
1741
|
+
|
|
1742
|
+
.kds-card-plan--selectable .kds-price {
|
|
1743
|
+
font-size: var(--kds-font-size-sm);
|
|
1744
|
+
font-weight: var(--kds-font-weight-medium);
|
|
1745
|
+
line-height: var(--kds-line-height-normal);
|
|
1746
|
+
}
|
|
1747
|
+
|
|
1748
|
+
.kds-card-plan--selectable .kds-price-period {
|
|
1749
|
+
font-size: var(--kds-font-size-sm);
|
|
1750
|
+
}
|
|
1751
|
+
|
|
1752
|
+
.kds-card-plan--selectable .kds-card-plan-features {
|
|
1753
|
+
gap: var(--kds-spacing-0-75);
|
|
1754
|
+
margin-top: var(--kds-spacing-0-5);
|
|
1755
|
+
padding-top: var(--kds-spacing-1-5);
|
|
1756
|
+
border-top: 1px solid var(--kds-border-light);
|
|
1757
|
+
font-size: var(--kds-font-size-sm);
|
|
1758
|
+
line-height: var(--kds-line-height-snug);
|
|
1759
|
+
}
|
|
1760
|
+
|
|
1761
|
+
.kds-card-plan--selectable .kds-card-plan-features--check li > i {
|
|
1762
|
+
font-size: var(--kds-font-size-sm);
|
|
1763
|
+
margin-top: 3px;
|
|
1764
|
+
}
|
|
1765
|
+
|
|
1766
|
+
/* Plan group (KdsCardPlanGroup): as many columns as fit in the group's own width, so it
|
|
1767
|
+
also works in a narrow card next to the panel sidebar (a viewport breakpoint would put
|
|
1768
|
+
two 260px cards in a 300px card and overflow). Inside the group the cards fill their
|
|
1769
|
+
column; min(…, 100%) keeps a single column from overflowing very narrow containers. */
|
|
1770
|
+
.kds-card-plan-group {
|
|
1771
|
+
display: grid;
|
|
1772
|
+
grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));
|
|
1773
|
+
gap: var(--kds-spacing-2);
|
|
1774
|
+
align-items: stretch;
|
|
1775
|
+
}
|
|
1776
|
+
|
|
1777
|
+
.kds-card-plan-group > .kds-card-plan {
|
|
1778
|
+
min-width: 0;
|
|
1779
|
+
max-width: none;
|
|
1780
|
+
}
|
|
1781
|
+
|
|
1782
|
+
/* In a selection the border signals the choice, so `recommended` keeps only its badge. */
|
|
1783
|
+
.kds-card-plan--selectable.recommended {
|
|
1784
|
+
background: var(--kds-surface-base);
|
|
1785
|
+
box-shadow: none;
|
|
1786
|
+
}
|
|
1787
|
+
|
|
1788
|
+
/* Unselected border matches the sibling selector cards (border-light), lighter than the
|
|
1789
|
+
plain plan card's border-medium. Before the hover rule so hover still wins. */
|
|
1790
|
+
.kds-card-plan--selectable,
|
|
1791
|
+
.kds-card-plan--selectable.recommended {
|
|
1792
|
+
border-color: var(--kds-border-light);
|
|
1793
|
+
}
|
|
1794
|
+
|
|
1795
|
+
/* Hover must not look like the selected state (primary border): neutral, darker border.
|
|
1796
|
+
The selected card keeps its primary border on hover (the :checked rule outranks this). */
|
|
1797
|
+
.kds-card-plan--selectable:hover,
|
|
1798
|
+
.kds-card-plan--selectable.recommended:hover {
|
|
1799
|
+
border-color: var(--kds-border-dark);
|
|
1800
|
+
}
|
|
1801
|
+
|
|
1802
|
+
.kds-card-plan--selectable.recommended:hover {
|
|
1803
|
+
box-shadow: var(--kds-shadow-2);
|
|
1804
|
+
}
|
|
1805
|
+
|
|
1806
|
+
/* Selected and focus states need :has. Without it the radio keeps its native look and
|
|
1807
|
+
focus ring, so the choice and the focus stay visible in older browsers. */
|
|
1808
|
+
@supports selector(:has(*)) {
|
|
1809
|
+
.kds-card-plan--selectable:has(.kds-card-plan-radio:checked) {
|
|
1810
|
+
border-color: var(--primary);
|
|
1811
|
+
background: color-mix(in srgb, var(--primary) 5%, var(--kds-surface-base));
|
|
1812
|
+
}
|
|
1813
|
+
|
|
1814
|
+
/* Focus is shown on the whole card; the radio's own ring would draw a second one. */
|
|
1815
|
+
.kds-card-plan--selectable:has(.kds-card-plan-radio:focus-visible) {
|
|
1816
|
+
outline: 2px solid var(--primary);
|
|
1817
|
+
outline-offset: 2px;
|
|
1818
|
+
}
|
|
1819
|
+
|
|
1820
|
+
.kds-card-plan-radio:focus-visible {
|
|
1821
|
+
outline: none;
|
|
1822
|
+
}
|
|
1823
|
+
}
|
|
1824
|
+
|
|
1825
|
+
/* Recommended Badge — inline dentro del card (no flotante), alineado a la izquierda.
|
|
1826
|
+
KdsCardPlan lo renderiza después del precio; en las cards seleccionables
|
|
1827
|
+
(.kds-card-plan--selectable) `order: -1` lo sube arriba del título. */
|
|
1535
1828
|
.kds-card-plan-badge {
|
|
1536
1829
|
align-self: flex-start;
|
|
1537
1830
|
padding: var(--kds-spacing-0-5) var(--kds-spacing-1-5);
|
|
@@ -2151,6 +2444,154 @@ a.kds-btn.kds-btn-md {
|
|
|
2151
2444
|
}
|
|
2152
2445
|
}
|
|
2153
2446
|
|
|
2447
|
+
/* Stepper modifiers (additive: the base markup above, e.g. payment's mat:stepper,
|
|
2448
|
+
renders exactly as before without them). */
|
|
2449
|
+
|
|
2450
|
+
/* --numbered: step number inside the indicator. Bold 20px is "large text", so the
|
|
2451
|
+
white number on the info indicator (3.8:1) still meets AA. Completed steps hide the
|
|
2452
|
+
number and keep the ::after check. */
|
|
2453
|
+
.kds-stepper--numbered .kds-step-indicator {
|
|
2454
|
+
font-size: var(--kds-font-size-2xl);
|
|
2455
|
+
font-weight: var(--kds-font-weight-bold);
|
|
2456
|
+
line-height: 1;
|
|
2457
|
+
}
|
|
2458
|
+
|
|
2459
|
+
.kds-stepper--numbered .kds-step.current .kds-step-indicator {
|
|
2460
|
+
color: var(--kds-color-info-contrast);
|
|
2461
|
+
}
|
|
2462
|
+
|
|
2463
|
+
/* --on-primary follows the merchant's brand (KdsThemeProvider computes it from --primary). */
|
|
2464
|
+
.kds-stepper--numbered.kds-stepper--primary .kds-step.current .kds-step-indicator {
|
|
2465
|
+
color: var(--on-primary);
|
|
2466
|
+
}
|
|
2467
|
+
|
|
2468
|
+
.kds-stepper--numbered .kds-step.completed .kds-step-indicator {
|
|
2469
|
+
font-size: 0;
|
|
2470
|
+
}
|
|
2471
|
+
|
|
2472
|
+
/* --primary: current step in the brand color instead of info. */
|
|
2473
|
+
.kds-stepper--primary .kds-step.current .kds-step-indicator {
|
|
2474
|
+
background: var(--primary);
|
|
2475
|
+
box-shadow: 0 0 0 4px color-mix(in srgb, var(--primary) 15%, transparent);
|
|
2476
|
+
}
|
|
2477
|
+
|
|
2478
|
+
/* --numbered: pending steps and the connector must be visible on a white card (the base
|
|
2479
|
+
background-elevated #fafafa is ~1.04:1 against white). */
|
|
2480
|
+
.kds-stepper--numbered::before {
|
|
2481
|
+
background: var(--kds-color-gray-300);
|
|
2482
|
+
}
|
|
2483
|
+
|
|
2484
|
+
.kds-stepper--numbered .kds-step:not(.completed):not(.current) .kds-step-indicator {
|
|
2485
|
+
background: var(--kds-color-gray-200);
|
|
2486
|
+
box-shadow: none;
|
|
2487
|
+
}
|
|
2488
|
+
|
|
2489
|
+
/* --numbered + --primary (onboarding): compact 28px dots, small bold number (white on the
|
|
2490
|
+
brand color is 6:1, so it does not need large text), small labels, and a progress line
|
|
2491
|
+
per segment: green up to the current step, grey after it. */
|
|
2492
|
+
.kds-stepper--numbered.kds-stepper--primary::before {
|
|
2493
|
+
display: none;
|
|
2494
|
+
}
|
|
2495
|
+
|
|
2496
|
+
.kds-stepper--numbered.kds-stepper--primary .kds-step-indicator {
|
|
2497
|
+
width: var(--kds-spacing-3-5);
|
|
2498
|
+
height: var(--kds-spacing-3-5);
|
|
2499
|
+
font-size: var(--kds-font-size-sm);
|
|
2500
|
+
}
|
|
2501
|
+
|
|
2502
|
+
.kds-stepper--numbered.kds-stepper--primary .kds-step.completed .kds-step-indicator {
|
|
2503
|
+
font-size: 0;
|
|
2504
|
+
}
|
|
2505
|
+
|
|
2506
|
+
.kds-stepper--numbered.kds-stepper--primary .kds-step.completed .kds-step-indicator::after {
|
|
2507
|
+
font-size: var(--kds-font-size-lg);
|
|
2508
|
+
}
|
|
2509
|
+
|
|
2510
|
+
.kds-stepper--numbered.kds-stepper--primary .kds-step:not(:first-child)::before {
|
|
2511
|
+
content: "";
|
|
2512
|
+
position: absolute;
|
|
2513
|
+
top: calc(var(--kds-spacing-3-5) / 2 - 1px);
|
|
2514
|
+
left: -50%;
|
|
2515
|
+
right: 50%;
|
|
2516
|
+
height: 2px;
|
|
2517
|
+
background: var(--kds-color-gray-300);
|
|
2518
|
+
z-index: 0;
|
|
2519
|
+
}
|
|
2520
|
+
|
|
2521
|
+
.kds-stepper--numbered.kds-stepper--primary .kds-step:is(.completed, .current)::before {
|
|
2522
|
+
background: var(--kds-color-success-main);
|
|
2523
|
+
}
|
|
2524
|
+
|
|
2525
|
+
.kds-stepper--numbered.kds-stepper--primary .kds-step-label {
|
|
2526
|
+
margin-top: var(--kds-spacing-0-75);
|
|
2527
|
+
font-size: var(--kds-font-size-xs);
|
|
2528
|
+
}
|
|
2529
|
+
|
|
2530
|
+
.kds-stepper--numbered.kds-stepper--primary .kds-step.current .kds-step-label {
|
|
2531
|
+
font-weight: var(--kds-font-weight-bold);
|
|
2532
|
+
}
|
|
2533
|
+
|
|
2534
|
+
/* --current-label: when the stepper itself is narrow (≤ 560px of available width, e.g. a
|
|
2535
|
+
card next to the panel sidebar, or a phone) only the current step keeps a visible label;
|
|
2536
|
+
the others are visually hidden but still read by screen readers. The first/last current
|
|
2537
|
+
label hugs its edge so it is not cut. It is a container query so it reacts to the space
|
|
2538
|
+
the stepper gets, not to the viewport; browsers without container queries fall back to
|
|
2539
|
+
the viewport width. */
|
|
2540
|
+
/* Size containment drops the intrinsic width: without an explicit width the stepper would
|
|
2541
|
+
collapse to 0px inside content-sized parents (centered flex columns, inline-block). */
|
|
2542
|
+
.kds-stepper--current-label {
|
|
2543
|
+
container-type: inline-size;
|
|
2544
|
+
inline-size: 100%;
|
|
2545
|
+
}
|
|
2546
|
+
|
|
2547
|
+
@container (max-width: 560px) {
|
|
2548
|
+
.kds-stepper--current-label .kds-step:not(.current) .kds-step-label {
|
|
2549
|
+
position: absolute;
|
|
2550
|
+
width: 1px;
|
|
2551
|
+
height: 1px;
|
|
2552
|
+
overflow: hidden;
|
|
2553
|
+
clip-path: inset(50%);
|
|
2554
|
+
white-space: nowrap;
|
|
2555
|
+
}
|
|
2556
|
+
|
|
2557
|
+
.kds-stepper--current-label .kds-step.current .kds-step-label {
|
|
2558
|
+
white-space: nowrap;
|
|
2559
|
+
}
|
|
2560
|
+
|
|
2561
|
+
.kds-stepper--current-label .kds-step.current:first-child .kds-step-label {
|
|
2562
|
+
align-self: flex-start;
|
|
2563
|
+
text-align: start;
|
|
2564
|
+
}
|
|
2565
|
+
|
|
2566
|
+
.kds-stepper--current-label .kds-step.current:last-child .kds-step-label {
|
|
2567
|
+
align-self: flex-end;
|
|
2568
|
+
text-align: end;
|
|
2569
|
+
}
|
|
2570
|
+
}
|
|
2571
|
+
|
|
2572
|
+
@supports not (container-type: inline-size) {
|
|
2573
|
+
@media (max-width: 560px) {
|
|
2574
|
+
.kds-stepper--current-label .kds-step:not(.current) .kds-step-label {
|
|
2575
|
+
position: absolute;
|
|
2576
|
+
width: 1px;
|
|
2577
|
+
height: 1px;
|
|
2578
|
+
overflow: hidden;
|
|
2579
|
+
clip-path: inset(50%);
|
|
2580
|
+
white-space: nowrap;
|
|
2581
|
+
}
|
|
2582
|
+
|
|
2583
|
+
.kds-stepper--current-label .kds-step.current .kds-step-label {
|
|
2584
|
+
white-space: nowrap;
|
|
2585
|
+
}
|
|
2586
|
+
}
|
|
2587
|
+
}
|
|
2588
|
+
|
|
2589
|
+
/* Safety net for any stepper in a narrow box: a long word breaks inside its column
|
|
2590
|
+
instead of overlapping the next label. No effect where the words already fit. */
|
|
2591
|
+
.kds-step-label {
|
|
2592
|
+
overflow-wrap: break-word;
|
|
2593
|
+
}
|
|
2594
|
+
|
|
2154
2595
|
/* ========================================
|
|
2155
2596
|
Snackbar Positioning & Styling
|
|
2156
2597
|
======================================== */
|
|
@@ -3345,6 +3786,14 @@ label.radio span {
|
|
|
3345
3786
|
cursor: pointer;
|
|
3346
3787
|
}
|
|
3347
3788
|
|
|
3789
|
+
/* BeerCSS sets white-space: nowrap on the label, so a label longer than its container ran
|
|
3790
|
+
past it (e.g. on phones). Let the text wrap; labels that fit render as before. */
|
|
3791
|
+
label.checkbox > span,
|
|
3792
|
+
label.radio > span {
|
|
3793
|
+
white-space: normal;
|
|
3794
|
+
min-width: 0;
|
|
3795
|
+
}
|
|
3796
|
+
|
|
3348
3797
|
/* Checked state.
|
|
3349
3798
|
accent-color aplica al input nativo, que BeerCSS deja con opacity 0: no se ve.
|
|
3350
3799
|
Se mantiene igual por si algun consumidor no usa el markup de BeerCSS. */
|
|
@@ -4207,6 +4656,47 @@ footer > .kds-container-center {
|
|
|
4207
4656
|
transform: translateY(0);
|
|
4208
4657
|
}
|
|
4209
4658
|
|
|
4659
|
+
/* Menu toggle (KdsSidebar with a menu): a real <button> holding avatar, text and arrow,
|
|
4660
|
+
with the dropdown as its sibling — never links inside a button. It looks like the plain
|
|
4661
|
+
header content, so BeerCSS's button styles (fill, size, radius, ripple) are reset. The
|
|
4662
|
+
vanilla markup (sidebar.js) keeps the click handler on the header itself. */
|
|
4663
|
+
.kds-sidebar-header > .kds-sidebar-header-toggle {
|
|
4664
|
+
display: flex;
|
|
4665
|
+
flex: 1;
|
|
4666
|
+
min-width: 0;
|
|
4667
|
+
align-items: center;
|
|
4668
|
+
justify-content: flex-start;
|
|
4669
|
+
gap: var(--kds-spacing-3);
|
|
4670
|
+
block-size: auto;
|
|
4671
|
+
margin: 0;
|
|
4672
|
+
padding: 0;
|
|
4673
|
+
border: 0;
|
|
4674
|
+
border-radius: 0;
|
|
4675
|
+
background: transparent;
|
|
4676
|
+
box-shadow: none;
|
|
4677
|
+
color: inherit;
|
|
4678
|
+
font: inherit;
|
|
4679
|
+
letter-spacing: inherit;
|
|
4680
|
+
text-align: start;
|
|
4681
|
+
text-transform: none;
|
|
4682
|
+
cursor: pointer;
|
|
4683
|
+
}
|
|
4684
|
+
|
|
4685
|
+
/* Outranks BeerCSS's `:is(…, button):not([class*=ripple])::after` ripple (0,2,1), which
|
|
4686
|
+
would otherwise cover the whole header (the button is not positioned). */
|
|
4687
|
+
.kds-sidebar .kds-sidebar-header > .kds-sidebar-header-toggle::after {
|
|
4688
|
+
content: none;
|
|
4689
|
+
}
|
|
4690
|
+
|
|
4691
|
+
.kds-sidebar-header > .kds-sidebar-header-toggle:focus-visible {
|
|
4692
|
+
outline: 2px solid var(--primary);
|
|
4693
|
+
outline-offset: 2px;
|
|
4694
|
+
}
|
|
4695
|
+
|
|
4696
|
+
.kds-sidebar-header-toggle[aria-expanded="true"] .kds-sidebar-dropdown-icon {
|
|
4697
|
+
transform: rotate(180deg);
|
|
4698
|
+
}
|
|
4699
|
+
|
|
4210
4700
|
/* Navigation */
|
|
4211
4701
|
.kds-sidebar-nav {
|
|
4212
4702
|
padding: var(--kds-spacing-2) 0;
|
|
@@ -4370,6 +4860,10 @@ footer > .kds-container-center {
|
|
|
4370
4860
|
transition: transform var(--kds-transition-standard) var(--kds-easing-ease-out);
|
|
4371
4861
|
z-index: var(--kds-z-index-drawer);
|
|
4372
4862
|
border-radius: 0;
|
|
4863
|
+
/* Full-height fixed drawer: scroll instead of cutting off items below the fold
|
|
4864
|
+
(long menus, short screens in landscape). */
|
|
4865
|
+
overflow-y: auto;
|
|
4866
|
+
overscroll-behavior: contain;
|
|
4373
4867
|
}
|
|
4374
4868
|
|
|
4375
4869
|
/* Barra superior mobile visible */
|
|
@@ -4964,6 +5458,46 @@ dialog#surveyModal button.circle {
|
|
|
4964
5458
|
overflow-y: auto;
|
|
4965
5459
|
}
|
|
4966
5460
|
|
|
5461
|
+
/* Read-to-accept contract (.kds-contract): content + acceptance checkbox + hint. The
|
|
5462
|
+
checkbox stays disabled until the content is scrolled to the end (KdsContract, or
|
|
5463
|
+
[data-kds-contract] with Khipu.initContract in the BeerCSS bundle). */
|
|
5464
|
+
.kds-contract {
|
|
5465
|
+
display: flex;
|
|
5466
|
+
flex-direction: column;
|
|
5467
|
+
gap: var(--kds-spacing-2);
|
|
5468
|
+
}
|
|
5469
|
+
|
|
5470
|
+
/* Inside the read-to-accept block the box is denser and shorter than the standalone
|
|
5471
|
+
contract page (.kds-contract-content alone keeps its 48px padding / 400px height). */
|
|
5472
|
+
.kds-contract > .kds-contract-content {
|
|
5473
|
+
padding: var(--kds-spacing-2);
|
|
5474
|
+
max-height: 240px;
|
|
5475
|
+
}
|
|
5476
|
+
|
|
5477
|
+
/* Denser paragraphs in the read-to-accept box (BeerCSS gives <p> 0.5rem + 1rem siblings). */
|
|
5478
|
+
.kds-contract > .kds-contract-content p {
|
|
5479
|
+
margin: 0 0 var(--kds-spacing-1) !important;
|
|
5480
|
+
}
|
|
5481
|
+
|
|
5482
|
+
/* The content is focusable so it can be scrolled with the keyboard. */
|
|
5483
|
+
.kds-contract-content:focus-visible {
|
|
5484
|
+
outline: 2px solid var(--primary);
|
|
5485
|
+
outline-offset: 2px;
|
|
5486
|
+
}
|
|
5487
|
+
|
|
5488
|
+
/* BeerCSS pads label.checkbox; the gap of .kds-contract spaces the parts and the hint
|
|
5489
|
+
(a <div>: BeerCSS adds a 1rem top margin to a <p> after a sibling) sits close to the
|
|
5490
|
+
checkbox it explains. */
|
|
5491
|
+
.kds-contract > .kds-contract-accept {
|
|
5492
|
+
padding-block: 0;
|
|
5493
|
+
}
|
|
5494
|
+
|
|
5495
|
+
.kds-contract > .kds-contract-hint {
|
|
5496
|
+
margin: calc(var(--kds-spacing-1) * -1) 0 0;
|
|
5497
|
+
font-size: var(--kds-font-size-sm);
|
|
5498
|
+
color: var(--kds-color-text-secondary);
|
|
5499
|
+
}
|
|
5500
|
+
|
|
4967
5501
|
.kds-contract-content details {
|
|
4968
5502
|
margin-bottom: var(--kds-spacing-4);
|
|
4969
5503
|
}
|
|
@@ -5887,7 +6421,9 @@ dialog#surveyModal button.circle {
|
|
|
5887
6421
|
|
|
5888
6422
|
/* ========================================
|
|
5889
6423
|
05 - LOCKED FIELD (.field.locked)
|
|
5890
|
-
Read-only field with lock icon
|
|
6424
|
+
Read-only field with lock icon.
|
|
6425
|
+
Value and label use text-secondary (not text-disabled): unlike a disabled
|
|
6426
|
+
field, the user still has to read a locked value, so it must meet AA contrast.
|
|
5891
6427
|
======================================== */
|
|
5892
6428
|
|
|
5893
6429
|
.field.locked {
|
|
@@ -5896,40 +6432,57 @@ dialog#surveyModal button.circle {
|
|
|
5896
6432
|
|
|
5897
6433
|
.field.locked > input,
|
|
5898
6434
|
.field.locked > textarea {
|
|
5899
|
-
color: var(--kds-color-text-
|
|
6435
|
+
color: var(--kds-color-text-secondary);
|
|
5900
6436
|
cursor: default;
|
|
5901
6437
|
pointer-events: none;
|
|
5902
6438
|
}
|
|
5903
6439
|
|
|
5904
6440
|
.field.locked > label {
|
|
5905
|
-
color: var(--kds-color-text-
|
|
6441
|
+
color: var(--kds-color-text-secondary);
|
|
5906
6442
|
}
|
|
5907
6443
|
|
|
5908
|
-
/* Locked:
|
|
5909
|
-
.field.label.border:not(.fill).locked:hover:not(:focus-within) > label::after
|
|
5910
|
-
.field.label.border:not(.fill).locked:focus-within > label::after {
|
|
6444
|
+
/* Locked: no editable hover. */
|
|
6445
|
+
.field.label.border:not(.fill).locked:hover:not(:focus-within) > label::after {
|
|
5911
6446
|
border-block-start-color: var(--outline);
|
|
5912
6447
|
}
|
|
5913
|
-
.field.label.border:not(.fill).locked:hover:not(:focus-within) > :is(input, textarea, select)
|
|
5914
|
-
.field.label.border:not(.fill).locked:focus-within > :is(input, textarea, select) {
|
|
6448
|
+
.field.label.border:not(.fill).locked:hover:not(:focus-within) > :is(input, textarea, select) {
|
|
5915
6449
|
border-color: var(--outline);
|
|
5916
6450
|
}
|
|
5917
6451
|
.field.label.locked:hover:not(:focus-within) > label {
|
|
5918
|
-
color: var(--kds-color-text-
|
|
6452
|
+
color: var(--kds-color-text-secondary);
|
|
6453
|
+
}
|
|
6454
|
+
|
|
6455
|
+
/* Locked focus: a locked field stays reachable with Tab, so it needs a visible focus
|
|
6456
|
+
indicator (WCAG 2.4.7), but not the primary-colored one of an editable field.
|
|
6457
|
+
BeerCSS's 2px focus border is kept (its padding already compensates it) in the
|
|
6458
|
+
neutral text-secondary color, and the label does not turn primary. */
|
|
6459
|
+
.field.label.border:not(.fill).locked:focus-within > label::after {
|
|
6460
|
+
border-block-start-color: var(--kds-color-text-secondary);
|
|
6461
|
+
}
|
|
6462
|
+
.field.label.border:not(.fill).locked:focus-within > :is(input, textarea, select) {
|
|
6463
|
+
border-color: var(--kds-color-text-secondary);
|
|
6464
|
+
}
|
|
6465
|
+
.field.label.locked > :focus + label {
|
|
6466
|
+
color: var(--kds-color-text-secondary);
|
|
5919
6467
|
}
|
|
5920
6468
|
|
|
5921
|
-
.
|
|
6469
|
+
/* Lock icon only: a leading .prefix icon is the first child and keeps its place.
|
|
6470
|
+
text-secondary, not text-disabled: the lock is what tells locked from disabled,
|
|
6471
|
+
so as a meaningful graphic it needs 3:1 (WCAG 1.4.11). */
|
|
6472
|
+
.field.locked > i:not(:first-child) {
|
|
5922
6473
|
position: absolute;
|
|
5923
6474
|
right: var(--kds-spacing-1-5);
|
|
5924
|
-
|
|
6475
|
+
/* Center of the input (BeerCSS --_middle), not of the field: with helper text the
|
|
6476
|
+
field is taller than the input. Without it both are the same. */
|
|
6477
|
+
top: var(--_middle, 50%);
|
|
5925
6478
|
transform: translateY(-50%);
|
|
5926
|
-
color: var(--kds-color-text-
|
|
6479
|
+
color: var(--kds-color-text-secondary);
|
|
5927
6480
|
pointer-events: none;
|
|
5928
6481
|
font-size: 18px;
|
|
5929
6482
|
}
|
|
5930
6483
|
|
|
5931
6484
|
/* Verified variant (green check) */
|
|
5932
|
-
.field.locked.verified > i {
|
|
6485
|
+
.field.locked.verified > i:not(:first-child) {
|
|
5933
6486
|
color: var(--kds-color-success-main);
|
|
5934
6487
|
}
|
|
5935
6488
|
|
|
@@ -6770,6 +7323,15 @@ button.kds-fab:active:not(:disabled) {
|
|
|
6770
7323
|
flex-basis: 100%;
|
|
6771
7324
|
}
|
|
6772
7325
|
|
|
7326
|
+
/* The title column (KdsStatusBlock wraps the title in a div; HTML markup puts the h2 directly)
|
|
7327
|
+
takes the width the icon leaves and wraps its text there. Without it, flex-wrap moved a title
|
|
7328
|
+
that did not fit on one line below the icon (KTUF-394: "Pendiente de autorización de
|
|
7329
|
+
firmantes"). */
|
|
7330
|
+
.kds-status-block.inline.kds-status-block--described > :not(.kds-status-block-icon):not(.kds-status-block-description) {
|
|
7331
|
+
flex: 1 1 0;
|
|
7332
|
+
min-width: 0;
|
|
7333
|
+
}
|
|
7334
|
+
|
|
6773
7335
|
.kds-status-block--described + .kds-alert,
|
|
6774
7336
|
.kds-status-block--described + .kds-copy-row {
|
|
6775
7337
|
margin-top: var(--kds-spacing-2);
|
|
@@ -6841,6 +7403,260 @@ button.kds-fab:active:not(:disabled) {
|
|
|
6841
7403
|
}
|
|
6842
7404
|
}
|
|
6843
7405
|
|
|
7406
|
+
/* ========================================
|
|
7407
|
+
PROGRESS CHECKLIST (.kds-progress-checklist)
|
|
7408
|
+
Steps that advance pending → active → done (or error), e.g. an automatic
|
|
7409
|
+
validation. The list is aria-live; each item carries its status as visually
|
|
7410
|
+
hidden text (.kds-progress-checklist-status). Status modifiers are BEM
|
|
7411
|
+
(--pending/--active/--done/--error): BeerCSS already has global .error/.active.
|
|
7412
|
+
======================================== */
|
|
7413
|
+
|
|
7414
|
+
.kds-progress-checklist {
|
|
7415
|
+
list-style: none;
|
|
7416
|
+
margin: 0;
|
|
7417
|
+
padding: 0;
|
|
7418
|
+
display: flex;
|
|
7419
|
+
flex-direction: column;
|
|
7420
|
+
gap: var(--kds-spacing-0-75);
|
|
7421
|
+
text-align: start;
|
|
7422
|
+
}
|
|
7423
|
+
|
|
7424
|
+
.kds-progress-checklist-item {
|
|
7425
|
+
position: relative;
|
|
7426
|
+
display: flex;
|
|
7427
|
+
align-items: center;
|
|
7428
|
+
gap: var(--kds-spacing-1-25);
|
|
7429
|
+
margin: 0;
|
|
7430
|
+
font-size: var(--kds-font-size-base);
|
|
7431
|
+
color: var(--kds-color-text-primary);
|
|
7432
|
+
transition: color 0.25s ease;
|
|
7433
|
+
}
|
|
7434
|
+
|
|
7435
|
+
/* Inside a bottom sheet the list is a centered block, under the centered title. */
|
|
7436
|
+
.kds-bottom-sheet-body > .kds-progress-checklist {
|
|
7437
|
+
width: fit-content;
|
|
7438
|
+
margin-inline: auto;
|
|
7439
|
+
}
|
|
7440
|
+
|
|
7441
|
+
.kds-progress-checklist-item--pending {
|
|
7442
|
+
color: var(--kds-color-text-secondary);
|
|
7443
|
+
}
|
|
7444
|
+
|
|
7445
|
+
.kds-progress-checklist-mark {
|
|
7446
|
+
display: inline-flex;
|
|
7447
|
+
align-items: center;
|
|
7448
|
+
justify-content: center;
|
|
7449
|
+
flex: none;
|
|
7450
|
+
width: var(--kds-spacing-2-5);
|
|
7451
|
+
height: var(--kds-spacing-2-5);
|
|
7452
|
+
}
|
|
7453
|
+
|
|
7454
|
+
.kds-progress-checklist-mark > i {
|
|
7455
|
+
font-size: var(--kds-spacing-2-5);
|
|
7456
|
+
}
|
|
7457
|
+
|
|
7458
|
+
/* Smaller dots so the loader fits the 20px mark like the icons do. */
|
|
7459
|
+
.kds-progress-checklist-mark .kds-dots-loader > span {
|
|
7460
|
+
width: var(--kds-spacing-0-5);
|
|
7461
|
+
height: var(--kds-spacing-0-5);
|
|
7462
|
+
}
|
|
7463
|
+
|
|
7464
|
+
.kds-progress-checklist-item--done .kds-progress-checklist-mark {
|
|
7465
|
+
color: var(--kds-color-success-main);
|
|
7466
|
+
}
|
|
7467
|
+
|
|
7468
|
+
.kds-progress-checklist-item--error .kds-progress-checklist-mark {
|
|
7469
|
+
color: var(--kds-color-error-main);
|
|
7470
|
+
}
|
|
7471
|
+
|
|
7472
|
+
.kds-progress-checklist-item--active .kds-progress-checklist-mark {
|
|
7473
|
+
color: var(--kds-color-text-secondary);
|
|
7474
|
+
}
|
|
7475
|
+
|
|
7476
|
+
/* The pending dot is decorative (the status is in the hidden text), so it can be faint;
|
|
7477
|
+
the label keeps text-secondary for contrast. */
|
|
7478
|
+
.kds-progress-checklist-item--pending .kds-progress-checklist-mark {
|
|
7479
|
+
color: var(--kds-color-text-disabled);
|
|
7480
|
+
}
|
|
7481
|
+
|
|
7482
|
+
.kds-progress-checklist-dot {
|
|
7483
|
+
width: var(--kds-spacing-0-75);
|
|
7484
|
+
height: var(--kds-spacing-0-75);
|
|
7485
|
+
border-radius: var(--kds-radius-full);
|
|
7486
|
+
background: currentColor;
|
|
7487
|
+
}
|
|
7488
|
+
|
|
7489
|
+
.kds-progress-checklist-status {
|
|
7490
|
+
position: absolute;
|
|
7491
|
+
width: 1px;
|
|
7492
|
+
height: 1px;
|
|
7493
|
+
overflow: hidden;
|
|
7494
|
+
clip-path: inset(50%);
|
|
7495
|
+
white-space: nowrap;
|
|
7496
|
+
}
|
|
7497
|
+
|
|
7498
|
+
/* ========================================
|
|
7499
|
+
FEEDBACK CARD (.kds-feedback-card)
|
|
7500
|
+
Optional question (e.g. "¿Cómo nos conociste?") with an answer control and a
|
|
7501
|
+
submit button; turns into a thank-you note (--submitted) in the same aria-live
|
|
7502
|
+
region. Text blocks are <div>s: BeerCSS adds margins to a <p> after a sibling.
|
|
7503
|
+
======================================== */
|
|
7504
|
+
|
|
7505
|
+
.kds-feedback-card {
|
|
7506
|
+
display: flex;
|
|
7507
|
+
align-items: flex-start;
|
|
7508
|
+
gap: var(--kds-spacing-2);
|
|
7509
|
+
padding: var(--kds-spacing-2);
|
|
7510
|
+
border: 1px solid var(--kds-border-light);
|
|
7511
|
+
border-radius: var(--kds-radius-lg);
|
|
7512
|
+
background: var(--kds-color-background-elevated);
|
|
7513
|
+
}
|
|
7514
|
+
|
|
7515
|
+
.kds-feedback-card-icon {
|
|
7516
|
+
display: grid;
|
|
7517
|
+
place-items: center;
|
|
7518
|
+
flex: none;
|
|
7519
|
+
width: var(--kds-spacing-5);
|
|
7520
|
+
height: var(--kds-spacing-5);
|
|
7521
|
+
border-radius: var(--kds-radius-md);
|
|
7522
|
+
background: var(--kds-color-primary-focus);
|
|
7523
|
+
color: var(--kds-color-primary-main);
|
|
7524
|
+
}
|
|
7525
|
+
|
|
7526
|
+
.kds-feedback-card-body {
|
|
7527
|
+
flex: 1;
|
|
7528
|
+
min-width: 0;
|
|
7529
|
+
display: flex;
|
|
7530
|
+
flex-direction: column;
|
|
7531
|
+
gap: var(--kds-spacing-2);
|
|
7532
|
+
}
|
|
7533
|
+
|
|
7534
|
+
.kds-feedback-card-title {
|
|
7535
|
+
font-size: var(--kds-font-size-base);
|
|
7536
|
+
font-weight: var(--kds-font-weight-bold);
|
|
7537
|
+
color: var(--kds-color-text-primary);
|
|
7538
|
+
}
|
|
7539
|
+
|
|
7540
|
+
/* BeerCSS adds 1rem above a .field after a sibling; the body gap already spaces it. */
|
|
7541
|
+
.kds-feedback-card-body > .field {
|
|
7542
|
+
margin-block-start: 0 !important;
|
|
7543
|
+
}
|
|
7544
|
+
|
|
7545
|
+
.kds-feedback-card-description {
|
|
7546
|
+
font-size: var(--kds-font-size-sm);
|
|
7547
|
+
line-height: var(--kds-line-height-normal);
|
|
7548
|
+
color: var(--kds-color-text-secondary);
|
|
7549
|
+
}
|
|
7550
|
+
|
|
7551
|
+
.kds-feedback-card--submitted {
|
|
7552
|
+
align-items: center;
|
|
7553
|
+
border-color: var(--kds-color-success-border-light);
|
|
7554
|
+
background: var(--kds-color-success-soft);
|
|
7555
|
+
}
|
|
7556
|
+
|
|
7557
|
+
.kds-feedback-card--submitted .kds-feedback-card-icon {
|
|
7558
|
+
background: var(--kds-color-background-paper);
|
|
7559
|
+
color: var(--kds-color-success-main);
|
|
7560
|
+
}
|
|
7561
|
+
|
|
7562
|
+
/* ========================================
|
|
7563
|
+
CONSENT CARD (.kds-consent-card)
|
|
7564
|
+
Access consent on a .kds-card-elevated: "<requester> solicita acceso a
|
|
7565
|
+
<resource>", sections (data requested, validity, purpose) and
|
|
7566
|
+
Authorize / Reject. Headings are div[role=heading] so BeerCSS heading
|
|
7567
|
+
margins do not apply. The secure footer goes outside the card.
|
|
7568
|
+
======================================== */
|
|
7569
|
+
|
|
7570
|
+
.kds-consent-card {
|
|
7571
|
+
display: flex;
|
|
7572
|
+
flex-direction: column;
|
|
7573
|
+
gap: var(--kds-spacing-3);
|
|
7574
|
+
padding: var(--kds-spacing-3);
|
|
7575
|
+
}
|
|
7576
|
+
|
|
7577
|
+
.kds-consent-card-header {
|
|
7578
|
+
display: flex;
|
|
7579
|
+
flex-direction: column;
|
|
7580
|
+
align-items: center;
|
|
7581
|
+
gap: var(--kds-spacing-1);
|
|
7582
|
+
text-align: center;
|
|
7583
|
+
}
|
|
7584
|
+
|
|
7585
|
+
.kds-consent-card-title {
|
|
7586
|
+
font-size: var(--kds-font-size-xl);
|
|
7587
|
+
line-height: var(--kds-line-height-tight);
|
|
7588
|
+
color: var(--kds-color-text-primary);
|
|
7589
|
+
}
|
|
7590
|
+
|
|
7591
|
+
.kds-consent-card-title strong {
|
|
7592
|
+
color: var(--primary);
|
|
7593
|
+
font-weight: var(--kds-font-weight-semibold);
|
|
7594
|
+
}
|
|
7595
|
+
|
|
7596
|
+
.kds-consent-card-subtitle {
|
|
7597
|
+
font-size: var(--kds-font-size-sm);
|
|
7598
|
+
color: var(--kds-color-text-secondary);
|
|
7599
|
+
}
|
|
7600
|
+
|
|
7601
|
+
.kds-consent-card-body {
|
|
7602
|
+
display: flex;
|
|
7603
|
+
flex-direction: column;
|
|
7604
|
+
gap: var(--kds-spacing-2);
|
|
7605
|
+
}
|
|
7606
|
+
|
|
7607
|
+
.kds-consent-card-section {
|
|
7608
|
+
display: flex;
|
|
7609
|
+
flex-direction: column;
|
|
7610
|
+
gap: var(--kds-spacing-1);
|
|
7611
|
+
}
|
|
7612
|
+
|
|
7613
|
+
/* Dividers only between sections, not before the actions. */
|
|
7614
|
+
.kds-consent-card-section + .kds-consent-card-section {
|
|
7615
|
+
padding-block-start: var(--kds-spacing-2);
|
|
7616
|
+
border-block-start: 1px solid var(--kds-color-divider);
|
|
7617
|
+
}
|
|
7618
|
+
|
|
7619
|
+
.kds-consent-card-section-title {
|
|
7620
|
+
font-size: var(--kds-font-size-xs);
|
|
7621
|
+
font-weight: var(--kds-font-weight-semibold);
|
|
7622
|
+
letter-spacing: var(--kds-letter-spacing-wide);
|
|
7623
|
+
text-transform: uppercase;
|
|
7624
|
+
color: var(--kds-color-text-secondary);
|
|
7625
|
+
}
|
|
7626
|
+
|
|
7627
|
+
/* !important on the top margin: BeerCSS adds 1rem to a <ul> after a sibling with a
|
|
7628
|
+
higher specificity (same approach as .kds-card-elevated). */
|
|
7629
|
+
.kds-consent-card-items {
|
|
7630
|
+
list-style: none;
|
|
7631
|
+
margin: 0;
|
|
7632
|
+
margin-block-start: 0 !important;
|
|
7633
|
+
padding: 0;
|
|
7634
|
+
display: flex;
|
|
7635
|
+
flex-direction: column;
|
|
7636
|
+
gap: var(--kds-spacing-0-75);
|
|
7637
|
+
}
|
|
7638
|
+
|
|
7639
|
+
.kds-consent-card-item {
|
|
7640
|
+
display: flex;
|
|
7641
|
+
align-items: flex-start;
|
|
7642
|
+
gap: var(--kds-spacing-1-25);
|
|
7643
|
+
margin: 0;
|
|
7644
|
+
font-size: var(--kds-font-size-base);
|
|
7645
|
+
color: var(--kds-color-text-primary);
|
|
7646
|
+
}
|
|
7647
|
+
|
|
7648
|
+
.kds-consent-card-item > i {
|
|
7649
|
+
flex: none;
|
|
7650
|
+
font-size: var(--kds-spacing-2-5);
|
|
7651
|
+
color: var(--kds-color-text-secondary);
|
|
7652
|
+
}
|
|
7653
|
+
|
|
7654
|
+
.kds-consent-card-actions {
|
|
7655
|
+
display: flex;
|
|
7656
|
+
flex-direction: column;
|
|
7657
|
+
gap: var(--kds-spacing-1);
|
|
7658
|
+
}
|
|
7659
|
+
|
|
6844
7660
|
/* ========================================
|
|
6845
7661
|
14 - BOTTOM SHEET (.kds-bottom-sheet)
|
|
6846
7662
|
Modal bottom sheet for mobile confirmations
|
|
@@ -6870,12 +7686,33 @@ button.kds-fab:active:not(:disabled) {
|
|
|
6870
7686
|
background: var(--kds-color-background-paper);
|
|
6871
7687
|
border-radius: var(--kds-radius-2xl) var(--kds-radius-2xl) 0 0;
|
|
6872
7688
|
padding: var(--kds-spacing-3-5) var(--kds-spacing-3) var(--kds-spacing-3);
|
|
7689
|
+
/* iPhone home indicator: keep the actions clear of it on viewport-fit=cover pages. */
|
|
7690
|
+
padding-bottom: calc(var(--kds-spacing-3) + env(safe-area-inset-bottom, 0px));
|
|
6873
7691
|
box-shadow: var(--kds-bottom-sheet-shadow);
|
|
6874
7692
|
animation: kds-rise 0.28s cubic-bezier(0.2, 0.8, 0.2, 1) both;
|
|
6875
7693
|
text-align: center;
|
|
6876
7694
|
position: relative;
|
|
6877
7695
|
}
|
|
6878
7696
|
|
|
7697
|
+
/* The dialog container receives focus programmatically when it opens (Radix, tabindex=-1);
|
|
7698
|
+
the browser ring around the whole sheet is noise. Controls inside keep their own ring. */
|
|
7699
|
+
.kds-bottom-sheet:focus-visible {
|
|
7700
|
+
outline: none;
|
|
7701
|
+
}
|
|
7702
|
+
|
|
7703
|
+
/* As soon as the viewport is wider than the sheet (--kds-bottom-sheet-max-width = 420px;
|
|
7704
|
+
media queries cannot read tokens) the sheet no longer spans the screen, and glued to the
|
|
7705
|
+
bottom edge with square bottom corners it looks cut off. It stays anchored at the bottom
|
|
7706
|
+
(still a drawer) but floats: all corners rounded and a gap to the edge. The max-height
|
|
7707
|
+
also caps the full-height variant. */
|
|
7708
|
+
@media (min-width: 421px) {
|
|
7709
|
+
.kds-bottom-sheet {
|
|
7710
|
+
margin-bottom: var(--kds-spacing-3);
|
|
7711
|
+
border-radius: var(--kds-radius-2xl);
|
|
7712
|
+
max-height: calc(90dvh - var(--kds-spacing-3));
|
|
7713
|
+
}
|
|
7714
|
+
}
|
|
7715
|
+
|
|
6879
7716
|
.kds-bottom-sheet-grabber {
|
|
6880
7717
|
position: absolute;
|
|
6881
7718
|
left: 50%;
|
|
@@ -6939,6 +7776,92 @@ button.kds-fab:active:not(:disabled) {
|
|
|
6939
7776
|
flex-direction: column;
|
|
6940
7777
|
}
|
|
6941
7778
|
|
|
7779
|
+
/* Dialog variant (KdsBottomSheet variant="dialog"): a regular modal for desktop flows, with
|
|
7780
|
+
left-aligned text. On phones it stays a bottom sheet (stacked actions, primary first, as
|
|
7781
|
+
the DOM order); from 521px it is centered on the screen with the actions side by side and
|
|
7782
|
+
the primary on the right (row-reverse keeps the primary first in the tab order). 520px is
|
|
7783
|
+
where two buttons stop fitting side by side. The scrim modifier centers it vertically. */
|
|
7784
|
+
.kds-bottom-sheet--dialog {
|
|
7785
|
+
text-align: left;
|
|
7786
|
+
}
|
|
7787
|
+
|
|
7788
|
+
.kds-bottom-sheet--dialog .kds-bottom-sheet-title {
|
|
7789
|
+
font-weight: var(--kds-font-weight-bold);
|
|
7790
|
+
}
|
|
7791
|
+
|
|
7792
|
+
.kds-bottom-sheet--dialog .kds-bottom-sheet-description {
|
|
7793
|
+
font-size: var(--kds-font-size-sm);
|
|
7794
|
+
line-height: var(--kds-line-height-normal);
|
|
7795
|
+
color: var(--kds-color-text-primary);
|
|
7796
|
+
}
|
|
7797
|
+
|
|
7798
|
+
/* Status dialog (align="center"), e.g. a validation in progress with a loader on top. */
|
|
7799
|
+
.kds-bottom-sheet--dialog.kds-bottom-sheet--center {
|
|
7800
|
+
text-align: center;
|
|
7801
|
+
}
|
|
7802
|
+
|
|
7803
|
+
/* Icon / loader slot above the title (KdsBottomSheet `icon`): a flex row so a block child
|
|
7804
|
+
(a spinner) follows the text alignment too. */
|
|
7805
|
+
div.kds-bottom-sheet-icon {
|
|
7806
|
+
display: flex;
|
|
7807
|
+
justify-content: center;
|
|
7808
|
+
margin-bottom: var(--kds-spacing-1);
|
|
7809
|
+
}
|
|
7810
|
+
|
|
7811
|
+
.kds-bottom-sheet--dialog:not(.kds-bottom-sheet--center) div.kds-bottom-sheet-icon {
|
|
7812
|
+
justify-content: flex-start;
|
|
7813
|
+
}
|
|
7814
|
+
|
|
7815
|
+
/* An icon in the slot matches the default KdsSpinner (BeerCSS circle, 2.5rem), so swapping
|
|
7816
|
+
the loader for a result icon does not shift the content. */
|
|
7817
|
+
div.kds-bottom-sheet-icon > i {
|
|
7818
|
+
font-size: 2.5rem;
|
|
7819
|
+
inline-size: 2.5rem;
|
|
7820
|
+
block-size: 2.5rem;
|
|
7821
|
+
min-inline-size: unset;
|
|
7822
|
+
min-block-size: unset;
|
|
7823
|
+
}
|
|
7824
|
+
|
|
7825
|
+
/* Short note above the actions (KdsBottomSheet `hint`), e.g. "No cierres esta ventana." */
|
|
7826
|
+
.kds-bottom-sheet-hint {
|
|
7827
|
+
margin: var(--kds-spacing-2) 0 0;
|
|
7828
|
+
font-size: var(--kds-font-size-xs);
|
|
7829
|
+
line-height: var(--kds-line-height-normal);
|
|
7830
|
+
color: var(--kds-color-text-secondary);
|
|
7831
|
+
}
|
|
7832
|
+
|
|
7833
|
+
@media (min-width: 521px) {
|
|
7834
|
+
.kds-bottom-sheet-scrim--dialog {
|
|
7835
|
+
align-items: center;
|
|
7836
|
+
padding: var(--kds-spacing-2);
|
|
7837
|
+
}
|
|
7838
|
+
|
|
7839
|
+
.kds-bottom-sheet--dialog {
|
|
7840
|
+
margin: 0;
|
|
7841
|
+
padding: var(--kds-spacing-3);
|
|
7842
|
+
border-radius: var(--kds-radius-lg);
|
|
7843
|
+
max-height: 90dvh;
|
|
7844
|
+
}
|
|
7845
|
+
|
|
7846
|
+
.kds-bottom-sheet--dialog .kds-bottom-sheet-grabber {
|
|
7847
|
+
display: none;
|
|
7848
|
+
}
|
|
7849
|
+
|
|
7850
|
+
.kds-bottom-sheet--dialog .kds-bottom-sheet-title {
|
|
7851
|
+
margin-top: 0;
|
|
7852
|
+
}
|
|
7853
|
+
|
|
7854
|
+
.kds-bottom-sheet--dialog .kds-bottom-sheet-actions {
|
|
7855
|
+
flex-direction: row-reverse;
|
|
7856
|
+
margin-top: var(--kds-spacing-2);
|
|
7857
|
+
}
|
|
7858
|
+
|
|
7859
|
+
.kds-bottom-sheet--dialog .kds-bottom-sheet-actions > * {
|
|
7860
|
+
flex: 1;
|
|
7861
|
+
min-width: 0;
|
|
7862
|
+
}
|
|
7863
|
+
}
|
|
7864
|
+
|
|
6942
7865
|
/* ========================================
|
|
6943
7866
|
DOCUMENT FRAME (.kds-document-frame)
|
|
6944
7867
|
Documento embebido (iframe) que llena su contenedor. --kds-document-frame-scale achica
|
|
@@ -8131,6 +9054,12 @@ svg[fill='none'] {
|
|
|
8131
9054
|
background: var(--kds-color-background-paper);
|
|
8132
9055
|
}
|
|
8133
9056
|
|
|
9057
|
+
/* The operation code row that follows the share card (khenshin's pending signers screen) gets
|
|
9058
|
+
the same gap it has after the alert on the other result screens. */
|
|
9059
|
+
.kds-share-card + .kds-copy-row {
|
|
9060
|
+
margin-top: var(--kds-spacing-1-5);
|
|
9061
|
+
}
|
|
9062
|
+
|
|
8134
9063
|
.kds-share-eyebrow {
|
|
8135
9064
|
font-size: var(--kds-font-size-caption);
|
|
8136
9065
|
letter-spacing: var(--kds-letter-spacing-wide);
|
|
@@ -9271,6 +10200,22 @@ a.kds-copy-all-btn.copied:hover {
|
|
|
9271
10200
|
.kds-section-note.kds-error { color: var(--kds-color-error-dark); }
|
|
9272
10201
|
.kds-section-note.kds-error > i { color: var(--kds-color-error-dark); }
|
|
9273
10202
|
|
|
10203
|
+
/* Neutral tone: calm, non-alarming context (e.g. "Datos obtenidos de tu cuenta en…",
|
|
10204
|
+
"Khipu no almacena tus contraseñas"). Secondary text with the icon in the brand color. */
|
|
10205
|
+
.kds-section-note.kds-neutral { color: var(--kds-color-text-secondary); }
|
|
10206
|
+
.kds-section-note.kds-neutral > i { color: var(--primary); }
|
|
10207
|
+
|
|
10208
|
+
/* Neutral notes often wrap to two lines: icon pinned to the first line, with a gap. */
|
|
10209
|
+
.kds-section-note.kds-neutral {
|
|
10210
|
+
align-items: flex-start;
|
|
10211
|
+
gap: var(--kds-spacing-1);
|
|
10212
|
+
line-height: var(--kds-line-height-normal);
|
|
10213
|
+
}
|
|
10214
|
+
|
|
10215
|
+
.kds-section-note.kds-neutral > i {
|
|
10216
|
+
margin-top: 0.125em;
|
|
10217
|
+
}
|
|
10218
|
+
|
|
9274
10219
|
/* Dark: the semantic *-dark shades are near-invisible on the dark page bg —
|
|
9275
10220
|
use the alert *-text tokens (light shades in dark). Base note is warning. */
|
|
9276
10221
|
[data-theme="dark"] .kds-section-note,
|
|
@@ -9281,6 +10226,8 @@ a.kds-copy-all-btn.copied:hover {
|
|
|
9281
10226
|
[data-theme="dark"] .kds-section-note.kds-success > i { color: var(--kds-alert-success-text); }
|
|
9282
10227
|
[data-theme="dark"] .kds-section-note.kds-error,
|
|
9283
10228
|
[data-theme="dark"] .kds-section-note.kds-error > i { color: var(--kds-alert-error-text); }
|
|
10229
|
+
[data-theme="dark"] .kds-section-note.kds-neutral { color: var(--kds-color-text-secondary); }
|
|
10230
|
+
[data-theme="dark"] .kds-section-note.kds-neutral > i { color: var(--primary); }
|
|
9284
10231
|
|
|
9285
10232
|
/* ========================================
|
|
9286
10233
|
INFO TOOLTIP (.kds-info-tip)
|