@carissa-io/theme-default 0.3.3 → 0.3.5

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/DESIGN.md CHANGED
@@ -253,6 +253,59 @@ and a **4px accent on the left edge** in the variant color (`--c-info`, `--c-suc
253
253
  The text and the title are `--c-text`, 14.8:1 or more on every tint in both modes; the accent and the icon are at least 3.8:1 on the tint (the status colors are not used for text: see the contrast notes in [Dark mode](#dark-mode)). The title is bold, the text
254
254
  0.875rem, square corners. The dismiss button is a plain "x" in `--c-muted`, `--c-text` on hover, with the usual focus ring.
255
255
 
256
+ ## Spinner
257
+ From [components-spinner](components/components-spinner): `Spinner` in three sizes (`sm` 1rem, `md` 1.5rem, `lg` 2.5rem). A 2px ring in `--c-surface-active` with a
258
+ `--c-primary` arc (black in light, white in dark), one turn every 0.75s, drawn with CSS only. The label is visually hidden text. With
259
+ `prefers-reduced-motion` the turn is replaced by a slow opacity pulse (2s) of the whole ring in `--c-primary`. The arc is 21:1 (light) and
260
+ 19.8:1 (dark) on the page background and 16.7:1 and 15.1:1 on its track, far above the 3:1 needed for a graphic; the track is a faint guide (1.3:1) on purpose.
261
+
262
+ ## Modal
263
+ From [components-modal](components/components-modal): `Modal`, a native `<dialog>` in three widths (`sm` 24rem, `md` 32rem, `lg` 48rem, never wider than the viewport
264
+ minus 1rem). The box is `--c-background` with `--c-text`, a **1px `--c-muted` border**, `$radius` (square) and a layered shadow (`0 4px 8px` at 8% and `0 16px 48px` at 20% of
265
+ black). As with the elevated Card the border stays on purpose: a shadow is almost invisible on the dark ground, the border keeps the edge in dark mode. Padding is
266
+ 1.5rem at the sides and 1.25rem above and below, like Card. The title is the Typography `Heading` (level 4 size) and the description the small muted `Text`.
267
+ The close button is a plain "x" in `--c-muted`, `--c-text` on hover, with the usual focus ring. The **backdrop** is `rgb(0 0 0 / 0.5)`, the one literal color of these
268
+ components, and it is the same in both modes (it dims whatever mode the page is in). The box fades in and rises 0.5rem in `$transition-duration`; with reduced motion it
269
+ just appears.
270
+
271
+ ## Toast
272
+ From [components-toast](components/components-toast): the fixed region of toasts (24rem wide, 1rem from the edges, 0.75rem between toasts, above the page content) and its six
273
+ placements. The look of each toast is the Alert's (see above), so its colors, roles and contrast are the Alert's in both modes. The action is a bold, underlined
274
+ 0.875rem button in `--c-text` (14.8:1 or more on every tint). A toast slides 0.75rem from its edge and fades in over `$transition-duration`; with reduced motion
275
+ only the fade stays. The region is in the page, not in the browser's top layer, so a toast shown while a modal is open sits behind the modal's backdrop.
276
+
277
+ ## Divider
278
+ From [components-divider](components/components-divider): `Divider`, a 1px line in `--c-muted` (the edge of the cards and fields: 4.74:1 on the background in light, 7.85:1 in dark),
279
+ 1rem of space around it. With a label the text is the small `--c-muted` text (0.875rem, same contrast) with 0.75rem between it and each line. Horizontal is an `hr`, vertical and labelled
280
+ ones are `role="separator"`.
281
+
282
+ ## Badge
283
+ From [components-badge](components/components-badge): `Badge` in six variants and two sizes (`md` 0.75rem, `sm` 0.6875rem, bold), square like the rest, plus a `dot`. The variants are **tinted
284
+ like the Alert**: 12% of the role color (`--c-primary`, `--c-success`, `--c-warning`, `--c-error`, `--c-info`) over `--c-background` with `color-mix`, a 1px border at 35% of the same color.
285
+ **The text is always `--c-text`**, never the status color: it is 13.6:1 or more on every tint in both modes (light 13.63 to 15.32, dark 13.63 to 15.87), where the raw light `error` on its own tint would
286
+ fail. Neutral is `--c-surface` with a `--c-muted` border (text 16.44:1). The **dot** carries the role color (`--c-muted` for neutral) and is 3:1 or more as a graphic on its tint in both modes: in light 3.81 (error), 4.21 (warning), 4.27 (success), 5.56 (info), 15.97 (primary) and 4.35 (neutral); in dark 6.25 or more. A dot has no text, so the caller gives it `aria-label`.
287
+
288
+ ## Tag
289
+ From [components-tag](components/components-tag): `Tag`, a chip with the same six tints, the same text rule (`--c-text`, same ratios) and square corners as the Badge, bold, 0.875rem (`md`) or 0.75rem (`sm`). A removable tag is
290
+ one tab stop and takes the theme focus ring (1px `--c-focus`, offset 2px). The remove "x" is the tag text color at 70%, full on hover. Disabled tags are exempt from contrast (55% opacity).
291
+
292
+ ## Link
293
+ From [components-link](components/components-link): `Link` in `default`, `subtle` and `inline`. The default is `--c-primary` (black in light, white in dark: 21:1 and 19.8:1 on the background), bold, **always underlined**: a black link
294
+ beside near-black text is told apart by the underline alone, so there is no un-underlined default. Hover is `--c-primary-hover`. `subtle` is `--c-muted` (4.74:1 light, 7.85:1 dark), `--c-text` on hover. Focus is the theme ring
295
+ (1px `--c-focus`, offset 2px). Disabled is `--c-disabled-text` at full opacity (exempt from contrast, as the other disabled states).
296
+
297
+ ## Avatar
298
+ From [components-avatar](components/components-avatar): `Avatar` in five sizes (`xs` 1.5rem to `xl` 5rem), a circle or a square (theme radius, so square). The initials are bold `--c-text` on `--c-surface-active`
299
+ (14.23:1 light, 13.88:1 dark); the placeholder without a name is the empty disc. `AvatarGroup` overlaps avatars by 0.5rem with a 2px ring in `--c-background`, so the separation works in both modes.
300
+
301
+ ## Skeleton
302
+ From [components-skeleton](components/components-skeleton): `Skeleton` as a text line, a circle or a rectangle, in `--c-surface-active` (a faint block on purpose: 1.26:1 on the light background, 1.31:1 in dark; it carries no information and is `aria-hidden`).
303
+ The sweep is a band of `--c-background` at 60%, 1.5s per pass; with `prefers-reduced-motion` it is removed and the block stays static.
304
+
305
+ ## Progress
306
+ From [components-progress](components/components-progress): `Progress` as a bar (0.25, 0.5 or 0.75rem tall, square ends) or a ring (1.5, 2.5 or 4rem). The track is `--c-surface-active` and the fill `--c-primary` (black in light, white in dark): 16.67:1 and 15.13:1 on
307
+ the track, well above the 3:1 of a graphic. The visible percentage is bold `--c-text`. Indeterminate slides (bar) or turns (ring) in 1.4s; with reduced motion both become a slow opacity pulse (2s).
308
+
256
309
  ## Keyboard focus (all controls)
257
310
  One rule keeps the controls coherent: **an outlined control thickens its own border from 1px to 2px, black** (text fields,
258
311
  select, combobox, date picker, textarea, upload, empty checkbox, off switch, radio, secondary and ghost buttons); **a filled
package/README.md CHANGED
@@ -142,7 +142,7 @@ it: check the names against the theme's `scss/_tokens.scss` before you switch.
142
142
 
143
143
  ## What it configures
144
144
  `components-input`, `-button`, `-checkbox`, `-switch`, `-radio-group`, `-slider`, `-popover`, `-listbox`, `-select`,
145
- `-combobox`, `-upload`, `-calendar`, `-date-picker`, `-search`, `-typography`, `-card` and `-alert`. `components-email`, `-password`, `-url` and `-textarea`
145
+ `-combobox`, `-upload`, `-calendar`, `-date-picker`, `-search`, `-typography`, `-card`, `-alert`, `-spinner`, `-modal`, `-toast`, `-divider`, `-badge`, `-tag`, `-link`, `-avatar`, `-skeleton` and `-progress`. `components-email`, `-password`, `-url` and `-textarea`
146
146
  are styled through the input.
147
147
 
148
148
  ## Change a value
package/dist/index.css CHANGED
@@ -1498,3 +1498,809 @@
1498
1498
  .c-alert--error .c-alert__title {
1499
1499
  color: var(--c-text);
1500
1500
  }
1501
+
1502
+ @keyframes c-spinner-rotate {
1503
+ to {
1504
+ transform: rotate(360deg);
1505
+ }
1506
+ }
1507
+ @keyframes c-spinner-pulse {
1508
+ 0%, 100% {
1509
+ opacity: 1;
1510
+ }
1511
+ 50% {
1512
+ opacity: 0.35;
1513
+ }
1514
+ }
1515
+ .c-spinner {
1516
+ --c-spinner-size: 1.5rem;
1517
+ box-sizing: border-box;
1518
+ display: inline-block;
1519
+ flex: none;
1520
+ width: var(--c-spinner-size);
1521
+ height: var(--c-spinner-size);
1522
+ vertical-align: middle;
1523
+ border: 2px solid var(--c-surface-active);
1524
+ border-top-color: var(--c-primary);
1525
+ border-radius: 50%;
1526
+ animation: c-spinner-rotate 0.75s linear infinite;
1527
+ }
1528
+ @media (prefers-reduced-motion: reduce) {
1529
+ .c-spinner {
1530
+ border-color: var(--c-primary);
1531
+ animation: c-spinner-pulse 2s ease-in-out infinite;
1532
+ }
1533
+ }
1534
+
1535
+ .c-spinner--sm {
1536
+ --c-spinner-size: 1rem;
1537
+ }
1538
+
1539
+ .c-spinner--md {
1540
+ --c-spinner-size: 1.5rem;
1541
+ }
1542
+
1543
+ .c-spinner--lg {
1544
+ --c-spinner-size: 2.5rem;
1545
+ }
1546
+
1547
+ .c-spinner__label {
1548
+ position: absolute;
1549
+ width: 1px;
1550
+ height: 1px;
1551
+ padding: 0;
1552
+ margin: -1px;
1553
+ overflow: hidden;
1554
+ white-space: nowrap;
1555
+ border: 0;
1556
+ clip-path: inset(50%);
1557
+ }
1558
+
1559
+ .c-modal-lock {
1560
+ overflow: hidden;
1561
+ }
1562
+
1563
+ .c-modal {
1564
+ box-sizing: border-box;
1565
+ width: 32rem;
1566
+ max-width: calc(100vw - 2 * 1rem);
1567
+ max-height: calc(100dvh - 2rem);
1568
+ padding: 0;
1569
+ color: var(--c-text);
1570
+ background: var(--c-background);
1571
+ border: 1px solid var(--c-muted);
1572
+ border-radius: 0;
1573
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.08), 0 16px 48px rgba(0, 0, 0, 0.2);
1574
+ opacity: 0;
1575
+ transition: opacity 0.2s ease-out, transform 0.2s ease-out, overlay 0.2s allow-discrete, display 0.2s allow-discrete;
1576
+ transform: translateY(0.5rem);
1577
+ }
1578
+ .c-modal[open] {
1579
+ display: flex;
1580
+ flex-direction: column;
1581
+ opacity: 1;
1582
+ transform: none;
1583
+ }
1584
+ @starting-style {
1585
+ .c-modal[open] {
1586
+ opacity: 0;
1587
+ transform: translateY(0.5rem);
1588
+ }
1589
+ }
1590
+ .c-modal::backdrop {
1591
+ background: rgba(0, 0, 0, 0.5);
1592
+ opacity: 0;
1593
+ transition: opacity 0.2s ease-out, overlay 0.2s allow-discrete, display 0.2s allow-discrete;
1594
+ }
1595
+ .c-modal[open]::backdrop {
1596
+ opacity: 1;
1597
+ }
1598
+ @starting-style {
1599
+ .c-modal[open]::backdrop {
1600
+ opacity: 0;
1601
+ }
1602
+ }
1603
+ @media (prefers-reduced-motion: reduce) {
1604
+ .c-modal {
1605
+ transform: none;
1606
+ transition: none;
1607
+ }
1608
+ @starting-style {
1609
+ .c-modal[open] {
1610
+ transform: none;
1611
+ }
1612
+ }
1613
+ .c-modal::backdrop {
1614
+ transition: none;
1615
+ }
1616
+ }
1617
+
1618
+ .c-modal--sm {
1619
+ width: 24rem;
1620
+ }
1621
+
1622
+ .c-modal--md {
1623
+ width: 32rem;
1624
+ }
1625
+
1626
+ .c-modal--lg {
1627
+ width: 48rem;
1628
+ }
1629
+
1630
+ .c-modal__header {
1631
+ display: flex;
1632
+ flex: none;
1633
+ gap: 1rem;
1634
+ align-items: flex-start;
1635
+ justify-content: space-between;
1636
+ padding: 1.25rem 1.5rem 0;
1637
+ }
1638
+
1639
+ .c-modal__heading {
1640
+ flex: 1 1 auto;
1641
+ min-width: 0;
1642
+ }
1643
+
1644
+ .c-modal__title {
1645
+ margin: 0;
1646
+ }
1647
+
1648
+ .c-modal__description {
1649
+ margin: 0.25rem 0 0;
1650
+ }
1651
+
1652
+ .c-modal__close {
1653
+ display: inline-flex;
1654
+ flex: none;
1655
+ align-items: center;
1656
+ justify-content: center;
1657
+ padding: 0;
1658
+ margin-left: auto;
1659
+ font-size: 1.25rem;
1660
+ line-height: 1;
1661
+ color: var(--c-muted);
1662
+ cursor: pointer;
1663
+ background: none;
1664
+ border: 0;
1665
+ }
1666
+ .c-modal__close:hover {
1667
+ color: var(--c-text);
1668
+ }
1669
+ .c-modal__close:focus-visible {
1670
+ outline: 2px solid currentColor;
1671
+ outline-offset: 2px;
1672
+ }
1673
+
1674
+ .c-modal__body {
1675
+ flex: 1 1 auto;
1676
+ min-height: 0;
1677
+ padding: 1.25rem 1.5rem;
1678
+ overflow-y: auto;
1679
+ }
1680
+
1681
+ .c-modal__footer {
1682
+ display: flex;
1683
+ flex: none;
1684
+ flex-wrap: wrap;
1685
+ gap: 1rem;
1686
+ justify-content: flex-end;
1687
+ padding: 0 1.5rem 1.25rem;
1688
+ }
1689
+
1690
+ @keyframes c-toast-enter {
1691
+ from {
1692
+ opacity: 0;
1693
+ transform: translateY(var(--c-toast-enter-shift));
1694
+ }
1695
+ to {
1696
+ opacity: 1;
1697
+ transform: none;
1698
+ }
1699
+ }
1700
+ @keyframes c-toast-fade {
1701
+ from {
1702
+ opacity: 0;
1703
+ }
1704
+ to {
1705
+ opacity: 1;
1706
+ }
1707
+ }
1708
+ .c-toast-region {
1709
+ position: fixed;
1710
+ z-index: 1100;
1711
+ display: flex;
1712
+ flex-direction: column;
1713
+ width: 24rem;
1714
+ max-width: calc(100vw - 2 * 1rem);
1715
+ pointer-events: none;
1716
+ }
1717
+
1718
+ .c-toast-region--top-left,
1719
+ .c-toast-region--top-center,
1720
+ .c-toast-region--top-right {
1721
+ top: 1rem;
1722
+ }
1723
+
1724
+ .c-toast-region--bottom-left,
1725
+ .c-toast-region--bottom-center,
1726
+ .c-toast-region--bottom-right {
1727
+ bottom: 1rem;
1728
+ }
1729
+
1730
+ .c-toast-region--top-left,
1731
+ .c-toast-region--bottom-left {
1732
+ left: 1rem;
1733
+ }
1734
+
1735
+ .c-toast-region--top-right,
1736
+ .c-toast-region--bottom-right {
1737
+ right: 1rem;
1738
+ }
1739
+
1740
+ .c-toast-region--top-center,
1741
+ .c-toast-region--bottom-center {
1742
+ left: 50%;
1743
+ transform: translateX(-50%);
1744
+ }
1745
+
1746
+ .c-toast-list {
1747
+ display: flex;
1748
+ flex-direction: column;
1749
+ gap: 0.75rem;
1750
+ padding: 0;
1751
+ margin: 0;
1752
+ list-style: none;
1753
+ }
1754
+
1755
+ .c-toast {
1756
+ --c-toast-enter-shift: 0.75rem;
1757
+ pointer-events: auto;
1758
+ animation: c-toast-enter 0.2s ease-out;
1759
+ }
1760
+ @media (prefers-reduced-motion: reduce) {
1761
+ .c-toast {
1762
+ animation-name: c-toast-fade;
1763
+ }
1764
+ }
1765
+
1766
+ .c-toast-region--top-left .c-toast,
1767
+ .c-toast-region--top-center .c-toast,
1768
+ .c-toast-region--top-right .c-toast {
1769
+ --c-toast-enter-shift: -0.75rem;
1770
+ }
1771
+
1772
+ .c-toast__action {
1773
+ display: block;
1774
+ padding: 0;
1775
+ margin-top: 0.5rem;
1776
+ font: inherit;
1777
+ font-size: 0.875rem;
1778
+ font-weight: 700;
1779
+ color: var(--c-text);
1780
+ text-decoration: underline;
1781
+ cursor: pointer;
1782
+ background: none;
1783
+ border: 0;
1784
+ }
1785
+ .c-toast__action:focus-visible {
1786
+ outline: 2px solid currentColor;
1787
+ outline-offset: 2px;
1788
+ }
1789
+
1790
+ .c-divider {
1791
+ box-sizing: border-box;
1792
+ }
1793
+
1794
+ .c-divider--horizontal {
1795
+ width: 100%;
1796
+ margin: 1rem 0;
1797
+ }
1798
+
1799
+ hr.c-divider {
1800
+ height: 0;
1801
+ border: 0;
1802
+ border-top: 1px solid var(--c-muted);
1803
+ }
1804
+
1805
+ .c-divider--vertical {
1806
+ display: inline-block;
1807
+ align-self: stretch;
1808
+ width: 0;
1809
+ min-height: 1em;
1810
+ margin: 0 1rem;
1811
+ vertical-align: middle;
1812
+ border-left: 1px solid var(--c-muted);
1813
+ }
1814
+
1815
+ .c-divider--labeled {
1816
+ display: flex;
1817
+ gap: 0.75rem;
1818
+ align-items: center;
1819
+ font-size: 0.875rem;
1820
+ color: var(--c-muted);
1821
+ }
1822
+ .c-divider--labeled::before, .c-divider--labeled::after {
1823
+ flex: 1 1 auto;
1824
+ height: 0;
1825
+ content: "";
1826
+ border-top: 1px solid var(--c-muted);
1827
+ }
1828
+
1829
+ .c-divider__label {
1830
+ flex: none;
1831
+ }
1832
+
1833
+ .c-badge {
1834
+ box-sizing: border-box;
1835
+ display: inline-flex;
1836
+ gap: 0.25em;
1837
+ align-items: center;
1838
+ justify-content: center;
1839
+ font-weight: 700;
1840
+ line-height: 1.5;
1841
+ white-space: nowrap;
1842
+ vertical-align: middle;
1843
+ border: 1px solid transparent;
1844
+ border-radius: 0;
1845
+ }
1846
+
1847
+ .c-badge--md {
1848
+ padding: 0.125rem 0.625rem;
1849
+ font-size: 0.75rem;
1850
+ }
1851
+
1852
+ .c-badge--sm {
1853
+ padding: 0 0.4375rem;
1854
+ font-size: 0.6875rem;
1855
+ }
1856
+
1857
+ .c-badge--neutral {
1858
+ color: var(--c-text);
1859
+ background: var(--c-surface);
1860
+ border-color: var(--c-muted);
1861
+ }
1862
+ .c-badge--neutral.c-badge--dot {
1863
+ background: var(--c-muted);
1864
+ border-color: var(--c-muted);
1865
+ }
1866
+
1867
+ .c-badge--primary {
1868
+ color: var(--c-text);
1869
+ background: color-mix(in srgb, var(--c-primary) 12%, var(--c-background));
1870
+ border-color: color-mix(in srgb, var(--c-primary) 35%, var(--c-background));
1871
+ }
1872
+ .c-badge--primary.c-badge--dot {
1873
+ background: var(--c-primary);
1874
+ border-color: var(--c-primary);
1875
+ }
1876
+
1877
+ .c-badge--success {
1878
+ color: var(--c-text);
1879
+ background: color-mix(in srgb, var(--c-success) 12%, var(--c-background));
1880
+ border-color: color-mix(in srgb, var(--c-success) 35%, var(--c-background));
1881
+ }
1882
+ .c-badge--success.c-badge--dot {
1883
+ background: var(--c-success);
1884
+ border-color: var(--c-success);
1885
+ }
1886
+
1887
+ .c-badge--warning {
1888
+ color: var(--c-text);
1889
+ background: color-mix(in srgb, var(--c-warning) 12%, var(--c-background));
1890
+ border-color: color-mix(in srgb, var(--c-warning) 35%, var(--c-background));
1891
+ }
1892
+ .c-badge--warning.c-badge--dot {
1893
+ background: var(--c-warning);
1894
+ border-color: var(--c-warning);
1895
+ }
1896
+
1897
+ .c-badge--error {
1898
+ color: var(--c-text);
1899
+ background: color-mix(in srgb, var(--c-error) 12%, var(--c-background));
1900
+ border-color: color-mix(in srgb, var(--c-error) 35%, var(--c-background));
1901
+ }
1902
+ .c-badge--error.c-badge--dot {
1903
+ background: var(--c-error);
1904
+ border-color: var(--c-error);
1905
+ }
1906
+
1907
+ .c-badge--info {
1908
+ color: var(--c-text);
1909
+ background: color-mix(in srgb, var(--c-info) 12%, var(--c-background));
1910
+ border-color: color-mix(in srgb, var(--c-info) 35%, var(--c-background));
1911
+ }
1912
+ .c-badge--info.c-badge--dot {
1913
+ background: var(--c-info);
1914
+ border-color: var(--c-info);
1915
+ }
1916
+
1917
+ .c-badge--dot {
1918
+ width: 0.5rem;
1919
+ height: 0.5rem;
1920
+ padding: 0;
1921
+ border-radius: 50%;
1922
+ }
1923
+ .c-badge--dot.c-badge--sm {
1924
+ width: 0.375rem;
1925
+ height: 0.375rem;
1926
+ }
1927
+
1928
+ .c-tag {
1929
+ box-sizing: border-box;
1930
+ display: inline-flex;
1931
+ gap: 0.375rem;
1932
+ align-items: center;
1933
+ max-width: 100%;
1934
+ font-weight: 700;
1935
+ line-height: 1.5;
1936
+ vertical-align: middle;
1937
+ border: 1px solid transparent;
1938
+ border-radius: 0;
1939
+ }
1940
+ .c-tag:focus-visible {
1941
+ outline: 1px solid var(--c-focus);
1942
+ outline-offset: 2px;
1943
+ }
1944
+
1945
+ .c-tag--md {
1946
+ padding: 0.125rem 0.625rem;
1947
+ font-size: 0.875rem;
1948
+ }
1949
+
1950
+ .c-tag--sm {
1951
+ padding: 0 0.5rem;
1952
+ font-size: 0.75rem;
1953
+ }
1954
+
1955
+ .c-tag__label {
1956
+ min-width: 0;
1957
+ overflow: hidden;
1958
+ text-overflow: ellipsis;
1959
+ white-space: nowrap;
1960
+ }
1961
+
1962
+ .c-tag__remove {
1963
+ display: inline-flex;
1964
+ flex: none;
1965
+ align-items: center;
1966
+ justify-content: center;
1967
+ padding: 0;
1968
+ font-size: 1em;
1969
+ line-height: 1;
1970
+ color: inherit;
1971
+ cursor: pointer;
1972
+ background: none;
1973
+ border: 0;
1974
+ border-radius: 50%;
1975
+ opacity: 0.7;
1976
+ }
1977
+ .c-tag__remove:hover:not(:disabled) {
1978
+ opacity: 1;
1979
+ }
1980
+
1981
+ .c-tag--disabled {
1982
+ cursor: not-allowed;
1983
+ opacity: 0.55;
1984
+ }
1985
+ .c-tag--disabled .c-tag__remove {
1986
+ cursor: not-allowed;
1987
+ }
1988
+
1989
+ .c-tag--neutral {
1990
+ color: var(--c-text);
1991
+ background: var(--c-surface);
1992
+ border-color: var(--c-muted);
1993
+ }
1994
+
1995
+ .c-tag--primary {
1996
+ color: var(--c-text);
1997
+ background: color-mix(in srgb, var(--c-primary) 12%, var(--c-background));
1998
+ border-color: color-mix(in srgb, var(--c-primary) 35%, var(--c-background));
1999
+ }
2000
+
2001
+ .c-tag--success {
2002
+ color: var(--c-text);
2003
+ background: color-mix(in srgb, var(--c-success) 12%, var(--c-background));
2004
+ border-color: color-mix(in srgb, var(--c-success) 35%, var(--c-background));
2005
+ }
2006
+
2007
+ .c-tag--warning {
2008
+ color: var(--c-text);
2009
+ background: color-mix(in srgb, var(--c-warning) 12%, var(--c-background));
2010
+ border-color: color-mix(in srgb, var(--c-warning) 35%, var(--c-background));
2011
+ }
2012
+
2013
+ .c-tag--error {
2014
+ color: var(--c-text);
2015
+ background: color-mix(in srgb, var(--c-error) 12%, var(--c-background));
2016
+ border-color: color-mix(in srgb, var(--c-error) 35%, var(--c-background));
2017
+ }
2018
+
2019
+ .c-tag--info {
2020
+ color: var(--c-text);
2021
+ background: color-mix(in srgb, var(--c-info) 12%, var(--c-background));
2022
+ border-color: color-mix(in srgb, var(--c-info) 35%, var(--c-background));
2023
+ }
2024
+
2025
+ .c-link {
2026
+ font-weight: 700;
2027
+ color: var(--c-primary);
2028
+ text-decoration: underline;
2029
+ cursor: pointer;
2030
+ }
2031
+ .c-link:hover {
2032
+ color: var(--c-primary-hover);
2033
+ text-decoration: underline;
2034
+ }
2035
+ .c-link:focus-visible {
2036
+ outline: 1px solid var(--c-focus);
2037
+ outline-offset: 2px;
2038
+ border-radius: 0;
2039
+ }
2040
+
2041
+ .c-link--subtle {
2042
+ color: var(--c-muted);
2043
+ }
2044
+ .c-link--subtle:hover {
2045
+ color: var(--c-text);
2046
+ }
2047
+
2048
+ .c-link--inline {
2049
+ text-decoration: underline;
2050
+ text-underline-offset: 0.15em;
2051
+ }
2052
+
2053
+ .c-link--disabled,
2054
+ .c-link--disabled:hover {
2055
+ color: var(--c-disabled-text);
2056
+ text-decoration: underline;
2057
+ cursor: not-allowed;
2058
+ opacity: 1;
2059
+ }
2060
+
2061
+ .c-avatar {
2062
+ --c-avatar-size: 2.5rem;
2063
+ position: relative;
2064
+ box-sizing: border-box;
2065
+ display: inline-flex;
2066
+ flex: none;
2067
+ align-items: center;
2068
+ justify-content: center;
2069
+ width: var(--c-avatar-size);
2070
+ height: var(--c-avatar-size);
2071
+ overflow: hidden;
2072
+ font-size: calc(var(--c-avatar-size) * 0.4);
2073
+ font-weight: 700;
2074
+ line-height: 1;
2075
+ color: var(--c-text);
2076
+ vertical-align: middle;
2077
+ user-select: none;
2078
+ background: var(--c-surface-active);
2079
+ }
2080
+
2081
+ .c-avatar--xs {
2082
+ --c-avatar-size: 1.5rem;
2083
+ }
2084
+
2085
+ .c-avatar--sm {
2086
+ --c-avatar-size: 2rem;
2087
+ }
2088
+
2089
+ .c-avatar--md {
2090
+ --c-avatar-size: 2.5rem;
2091
+ }
2092
+
2093
+ .c-avatar--lg {
2094
+ --c-avatar-size: 3.5rem;
2095
+ }
2096
+
2097
+ .c-avatar--xl {
2098
+ --c-avatar-size: 5rem;
2099
+ }
2100
+
2101
+ .c-avatar--circle {
2102
+ border-radius: 50%;
2103
+ }
2104
+
2105
+ .c-avatar--square {
2106
+ border-radius: 0;
2107
+ }
2108
+
2109
+ .c-avatar__initials {
2110
+ text-transform: uppercase;
2111
+ }
2112
+
2113
+ .c-avatar__image {
2114
+ position: absolute;
2115
+ inset: 0;
2116
+ width: 100%;
2117
+ height: 100%;
2118
+ object-fit: cover;
2119
+ }
2120
+
2121
+ .c-avatar-group {
2122
+ display: inline-flex;
2123
+ align-items: center;
2124
+ }
2125
+ .c-avatar-group > .c-avatar {
2126
+ box-shadow: 0 0 0 2px var(--c-background);
2127
+ }
2128
+ .c-avatar-group > .c-avatar + .c-avatar {
2129
+ margin-inline-start: -0.5rem;
2130
+ }
2131
+
2132
+ @keyframes c-skeleton-shimmer {
2133
+ from {
2134
+ background-position: 200% 0;
2135
+ }
2136
+ to {
2137
+ background-position: -200% 0;
2138
+ }
2139
+ }
2140
+ .c-skeleton {
2141
+ display: block;
2142
+ width: 100%;
2143
+ background-color: var(--c-surface-active);
2144
+ border-radius: 0;
2145
+ }
2146
+
2147
+ .c-skeleton--text {
2148
+ height: 1em;
2149
+ }
2150
+
2151
+ .c-skeleton--circle {
2152
+ flex: none;
2153
+ width: 2.5rem;
2154
+ height: 2.5rem;
2155
+ border-radius: 50%;
2156
+ }
2157
+
2158
+ .c-skeleton--rect {
2159
+ min-height: 1px;
2160
+ }
2161
+
2162
+ .c-skeleton--animated {
2163
+ background-image: linear-gradient(90deg, transparent 0%, color-mix(in srgb, var(--c-background) 60%, transparent) 50%, transparent 100%);
2164
+ background-repeat: no-repeat;
2165
+ background-size: 50% 100%;
2166
+ animation: c-skeleton-shimmer 1.5s linear infinite;
2167
+ }
2168
+ @media (prefers-reduced-motion: reduce) {
2169
+ .c-skeleton--animated {
2170
+ background-image: none;
2171
+ animation: none;
2172
+ }
2173
+ }
2174
+
2175
+ .c-skeleton-lines {
2176
+ display: flex;
2177
+ flex-direction: column;
2178
+ gap: 0.5rem;
2179
+ width: 100%;
2180
+ }
2181
+
2182
+ .c-skeleton--last {
2183
+ width: 60%;
2184
+ }
2185
+
2186
+ @keyframes c-progress-slide {
2187
+ from {
2188
+ transform: translateX(-100%);
2189
+ }
2190
+ to {
2191
+ transform: translateX(250%);
2192
+ }
2193
+ }
2194
+ @keyframes c-progress-spin {
2195
+ to {
2196
+ transform: rotate(360deg);
2197
+ }
2198
+ }
2199
+ @keyframes c-progress-pulse {
2200
+ 0%, 100% {
2201
+ opacity: 1;
2202
+ }
2203
+ 50% {
2204
+ opacity: 0.35;
2205
+ }
2206
+ }
2207
+ .c-progress {
2208
+ --c-progress-bar-height: 0.5rem;
2209
+ --c-progress-circular-size: 2.5rem;
2210
+ box-sizing: border-box;
2211
+ font-size: 0.75rem;
2212
+ font-weight: 700;
2213
+ line-height: 1;
2214
+ color: var(--c-text);
2215
+ }
2216
+
2217
+ .c-progress--sm {
2218
+ --c-progress-bar-height: 0.25rem;
2219
+ --c-progress-circular-size: 1.5rem;
2220
+ }
2221
+
2222
+ .c-progress--md {
2223
+ --c-progress-bar-height: 0.5rem;
2224
+ --c-progress-circular-size: 2.5rem;
2225
+ }
2226
+
2227
+ .c-progress--lg {
2228
+ --c-progress-bar-height: 0.75rem;
2229
+ --c-progress-circular-size: 4rem;
2230
+ }
2231
+
2232
+ .c-progress--bar {
2233
+ display: flex;
2234
+ gap: 0.75rem;
2235
+ align-items: center;
2236
+ width: 100%;
2237
+ }
2238
+ .c-progress--bar .c-progress__track {
2239
+ position: relative;
2240
+ flex: 1;
2241
+ height: var(--c-progress-bar-height);
2242
+ overflow: hidden;
2243
+ background: var(--c-surface-active);
2244
+ border-radius: 0;
2245
+ }
2246
+ .c-progress--bar .c-progress__fill {
2247
+ display: block;
2248
+ height: 100%;
2249
+ background: var(--c-primary);
2250
+ border-radius: inherit;
2251
+ transition: width 0.2s ease;
2252
+ }
2253
+ .c-progress--bar.c-progress--indeterminate .c-progress__fill {
2254
+ width: 40%;
2255
+ transition: none;
2256
+ animation: c-progress-slide 1.4s ease-in-out infinite;
2257
+ }
2258
+
2259
+ .c-progress--circular {
2260
+ position: relative;
2261
+ display: inline-flex;
2262
+ flex: none;
2263
+ align-items: center;
2264
+ justify-content: center;
2265
+ width: var(--c-progress-circular-size);
2266
+ height: var(--c-progress-circular-size);
2267
+ vertical-align: middle;
2268
+ }
2269
+ .c-progress--circular .c-progress__svg {
2270
+ position: absolute;
2271
+ inset: 0;
2272
+ width: 100%;
2273
+ height: 100%;
2274
+ transform: rotate(-90deg);
2275
+ }
2276
+ .c-progress--circular .c-progress__track {
2277
+ stroke: var(--c-surface-active);
2278
+ stroke-width: 8;
2279
+ }
2280
+ .c-progress--circular .c-progress__fill {
2281
+ stroke: var(--c-primary);
2282
+ stroke-width: 8;
2283
+ stroke-linecap: round;
2284
+ transition: stroke-dashoffset 0.2s ease;
2285
+ }
2286
+ .c-progress--circular .c-progress__value {
2287
+ position: relative;
2288
+ font-size: calc(var(--c-progress-circular-size) * 0.28);
2289
+ }
2290
+ .c-progress--circular.c-progress--indeterminate .c-progress__svg {
2291
+ animation: c-progress-spin 1.4s linear infinite;
2292
+ }
2293
+ .c-progress--circular.c-progress--indeterminate .c-progress__fill {
2294
+ stroke-dashoffset: 210;
2295
+ transition: none;
2296
+ }
2297
+
2298
+ @media (prefers-reduced-motion: reduce) {
2299
+ .c-progress--bar.c-progress--indeterminate .c-progress__fill {
2300
+ width: 100%;
2301
+ animation: c-progress-pulse 2s ease-in-out infinite;
2302
+ }
2303
+ .c-progress--circular.c-progress--indeterminate .c-progress__svg {
2304
+ animation: c-progress-pulse 2s ease-in-out infinite;
2305
+ }
2306
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@carissa-io/theme-default",
3
- "version": "0.3.3",
3
+ "version": "0.3.5",
4
4
  "description": "Carissa UI: the default theme (Swiss minimalism) as SCSS variable overrides of the Carissa components, with a compiled CSS build",
5
5
  "type": "module",
6
6
  "style": "dist/index.css",
@@ -54,7 +54,17 @@
54
54
  "@carissa-io/components-search": "^0.1.1",
55
55
  "@carissa-io/components-typography": "^0.1.0",
56
56
  "@carissa-io/components-card": "^0.1.0",
57
- "@carissa-io/components-alert": "^0.1.0"
57
+ "@carissa-io/components-alert": "^0.1.0",
58
+ "@carissa-io/components-spinner": "^0.1.0",
59
+ "@carissa-io/components-modal": "^0.1.0",
60
+ "@carissa-io/components-toast": "^0.1.0",
61
+ "@carissa-io/components-divider": "^0.1.0",
62
+ "@carissa-io/components-badge": "^0.1.0",
63
+ "@carissa-io/components-tag": "^0.1.0",
64
+ "@carissa-io/components-link": "^0.1.0",
65
+ "@carissa-io/components-avatar": "^0.1.0",
66
+ "@carissa-io/components-skeleton": "^0.1.0",
67
+ "@carissa-io/components-progress": "^0.1.0"
58
68
  },
59
69
  "peerDependenciesMeta": {
60
70
  "@carissa-io/components-input": {
@@ -119,24 +129,64 @@
119
129
  },
120
130
  "@carissa-io/components-alert": {
121
131
  "optional": true
132
+ },
133
+ "@carissa-io/components-spinner": {
134
+ "optional": true
135
+ },
136
+ "@carissa-io/components-modal": {
137
+ "optional": true
138
+ },
139
+ "@carissa-io/components-toast": {
140
+ "optional": true
141
+ },
142
+ "@carissa-io/components-divider": {
143
+ "optional": true
144
+ },
145
+ "@carissa-io/components-badge": {
146
+ "optional": true
147
+ },
148
+ "@carissa-io/components-tag": {
149
+ "optional": true
150
+ },
151
+ "@carissa-io/components-link": {
152
+ "optional": true
153
+ },
154
+ "@carissa-io/components-avatar": {
155
+ "optional": true
156
+ },
157
+ "@carissa-io/components-skeleton": {
158
+ "optional": true
159
+ },
160
+ "@carissa-io/components-progress": {
161
+ "optional": true
122
162
  }
123
163
  },
124
164
  "devDependencies": {
125
165
  "@carissa-io/components-alert": "^0.1.0",
166
+ "@carissa-io/components-avatar": "^0.1.0",
167
+ "@carissa-io/components-badge": "^0.1.0",
126
168
  "@carissa-io/components-button": "^0.1.1",
127
169
  "@carissa-io/components-calendar": "^0.1.1",
128
170
  "@carissa-io/components-card": "^0.1.0",
129
171
  "@carissa-io/components-checkbox": "^0.1.1",
130
172
  "@carissa-io/components-combobox": "^0.1.1",
131
173
  "@carissa-io/components-date-picker": "^0.1.1",
174
+ "@carissa-io/components-divider": "^0.1.0",
132
175
  "@carissa-io/components-input": "^0.2.1",
176
+ "@carissa-io/components-link": "^0.1.0",
133
177
  "@carissa-io/components-listbox": "^0.1.1",
178
+ "@carissa-io/components-modal": "^0.1.0",
134
179
  "@carissa-io/components-popover": "^0.1.1",
180
+ "@carissa-io/components-progress": "^0.1.0",
135
181
  "@carissa-io/components-radio-group": "^0.1.1",
136
182
  "@carissa-io/components-search": "^0.1.1",
137
183
  "@carissa-io/components-select": "^0.1.1",
184
+ "@carissa-io/components-skeleton": "^0.1.0",
138
185
  "@carissa-io/components-slider": "^0.1.1",
186
+ "@carissa-io/components-spinner": "^0.1.0",
139
187
  "@carissa-io/components-switch": "^0.1.1",
188
+ "@carissa-io/components-tag": "^0.1.0",
189
+ "@carissa-io/components-toast": "^0.1.0",
140
190
  "@carissa-io/components-typography": "^0.1.0",
141
191
  "@carissa-io/components-upload": "^0.1.1",
142
192
  "sass-embedded": "^1.105.1",
package/scss/index.scss CHANGED
@@ -630,3 +630,226 @@
630
630
  $c-alert-error-icon-color: $var-error,
631
631
  $c-alert-error-title-color: $var-text
632
632
  );
633
+
634
+ // Spinner: a thin ring in the surface-active gray with a primary arc (black in light, white in dark), turning at 0.75s per
635
+ // turn; with reduced motion the package swaps the turn for a slow pulse. Colors only through the custom properties.
636
+ @use '@carissa-io/components-spinner/scss' as spinner with (
637
+ $c-spinner-size-sm: 1rem,
638
+ $c-spinner-size-md: 1.5rem,
639
+ $c-spinner-size-lg: 2.5rem,
640
+ $c-spinner-thickness: 2px,
641
+ $c-spinner-color: $var-primary,
642
+ $c-spinner-track-color: $var-surface-active,
643
+ $c-spinner-duration: 0.75s,
644
+ $c-spinner-duration-reduced: 2s
645
+ );
646
+
647
+ // Modal: a box on the page background with a 1px muted border (the edge that still reads in dark, where a shadow is almost
648
+ // invisible), the theme radius, and the same 1.5rem / 1.25rem padding as Card. The backdrop is the one literal color: black
649
+ // at 50%, the same in both modes. Its index forwards the typography styles, already loaded and configured above, so this
650
+ // block goes after the Typography one (and after Card, which forwards it too).
651
+ @use '@carissa-io/components-modal/scss' as modal with (
652
+ $c-modal-background: $var-background,
653
+ $c-modal-color: $var-text,
654
+ $c-modal-border-width: 1px,
655
+ $c-modal-border-color: $var-muted,
656
+ $c-modal-radius: $radius,
657
+ $c-modal-shadow: (0 4px 8px rgb(0 0 0 / 0.08), 0 16px 48px rgb(0 0 0 / 0.2)),
658
+ $c-modal-padding-x: 1.5rem,
659
+ $c-modal-padding-y: 1.25rem,
660
+ $c-modal-gap: 1rem,
661
+ $c-modal-margin: 1rem,
662
+ $c-modal-width-sm: 24rem,
663
+ $c-modal-width-md: 32rem,
664
+ $c-modal-width-lg: 48rem,
665
+ $c-modal-close-size: 1.25rem,
666
+ $c-modal-close-color: $var-muted,
667
+ $c-modal-close-color-hover: $var-text,
668
+ $c-modal-backdrop-color: rgb(0 0 0 / 0.5),
669
+ $c-modal-transition-duration: $transition-duration,
670
+ $c-modal-enter-offset: 0.5rem
671
+ );
672
+
673
+ // Toast: the region and its placement only; the look of each toast is the Alert's (configured above). Its index forwards the
674
+ // alert styles, already loaded and configured by the Alert block, so this block goes after it. The action is a bold
675
+ // underlined 0.875rem button in the text color.
676
+ @use '@carissa-io/components-toast/scss' as toast with (
677
+ $c-toast-region-offset: 1rem,
678
+ $c-toast-region-z-index: 1100,
679
+ $c-toast-gap: 0.75rem,
680
+ $c-toast-width: 24rem,
681
+ $c-toast-action-margin-top: 0.5rem,
682
+ $c-toast-action-font-size: $font-size-small,
683
+ $c-toast-action-font-weight: $font-weight-bold,
684
+ $c-toast-action-color: $var-text,
685
+ $c-toast-enter-duration: $transition-duration,
686
+ $c-toast-enter-distance: 0.75rem
687
+ );
688
+
689
+ // Divider: a 1px line in the muted color (the same edge as the card and field borders), so it reads in both modes. The
690
+ // label is the small muted text, 0.75rem from each line. Spacing 1rem above and below (or at the sides when vertical).
691
+ @use '@carissa-io/components-divider/scss' as divider with (
692
+ $c-divider-color: $var-muted,
693
+ $c-divider-thickness: 1px,
694
+ $c-divider-spacing: 1rem,
695
+ $c-divider-label-color: $var-muted,
696
+ $c-divider-label-gap: 0.75rem,
697
+ $c-divider-label-font-size: $font-size-small
698
+ );
699
+
700
+ // Badge: a small status marker, square like everything else. The variants are tinted like the alerts (12% of the role over
701
+ // the page background, 35% for the border) and the text stays --c-text (14.8:1 or more on every tint): the raw status
702
+ // colors are under 4.5:1 on some tints, so they only color the dot. Neutral is the surface with the muted border.
703
+ // Primary is the tint of --c-primary (a light grey in light, a dark one in dark).
704
+ @use '@carissa-io/components-badge/scss' as badge with (
705
+ $c-badge-radius: $radius,
706
+ $c-badge-border-width: 1px,
707
+ $c-badge-font-weight: $font-weight-bold,
708
+ $c-badge-md-font-size: $font-size-caption,
709
+ $c-badge-sm-font-size: $font-size-overline,
710
+
711
+ // Neutral
712
+ $c-badge-neutral-background: $var-surface,
713
+ $c-badge-neutral-border-color: $var-muted,
714
+ $c-badge-neutral-color: $var-text,
715
+ $c-badge-neutral-dot-color: $var-muted,
716
+
717
+ // Primary
718
+ $c-badge-primary-background: color-mix(in srgb, $var-primary 12%, $var-background),
719
+ $c-badge-primary-border-color: color-mix(in srgb, $var-primary 35%, $var-background),
720
+ $c-badge-primary-color: $var-text,
721
+ $c-badge-primary-dot-color: $var-primary,
722
+
723
+ // Success
724
+ $c-badge-success-background: color-mix(in srgb, $var-success 12%, $var-background),
725
+ $c-badge-success-border-color: color-mix(in srgb, $var-success 35%, $var-background),
726
+ $c-badge-success-color: $var-text,
727
+ $c-badge-success-dot-color: $var-success,
728
+
729
+ // Warning
730
+ $c-badge-warning-background: color-mix(in srgb, $var-warning 12%, $var-background),
731
+ $c-badge-warning-border-color: color-mix(in srgb, $var-warning 35%, $var-background),
732
+ $c-badge-warning-color: $var-text,
733
+ $c-badge-warning-dot-color: $var-warning,
734
+
735
+ // Error
736
+ $c-badge-error-background: color-mix(in srgb, $var-error 12%, $var-background),
737
+ $c-badge-error-border-color: color-mix(in srgb, $var-error 35%, $var-background),
738
+ $c-badge-error-color: $var-text,
739
+ $c-badge-error-dot-color: $var-error,
740
+
741
+ // Info
742
+ $c-badge-info-background: color-mix(in srgb, $var-info 12%, $var-background),
743
+ $c-badge-info-border-color: color-mix(in srgb, $var-info 35%, $var-background),
744
+ $c-badge-info-color: $var-text,
745
+ $c-badge-info-dot-color: $var-info
746
+ );
747
+
748
+ // Tag: the same tints as the badge, square, with the label-sized text and the theme focus ring (1px, offset 2px) because a
749
+ // removable tag is a tab stop. The remove button is the tag's text color at 70%, full on hover.
750
+ @use '@carissa-io/components-tag/scss' as tag with (
751
+ $c-tag-radius: $radius,
752
+ $c-tag-border-width: 1px,
753
+ $c-tag-font-weight: $font-weight-bold,
754
+ $c-tag-md-font-size: $font-size-small,
755
+ $c-tag-sm-font-size: $font-size-caption,
756
+ $c-tag-focus-outline: $focus-width solid $var-focus,
757
+ $c-tag-focus-outline-offset: 2px,
758
+
759
+ // Neutral
760
+ $c-tag-neutral-background: $var-surface,
761
+ $c-tag-neutral-border-color: $var-muted,
762
+ $c-tag-neutral-color: $var-text,
763
+
764
+ // Primary
765
+ $c-tag-primary-background: color-mix(in srgb, $var-primary 12%, $var-background),
766
+ $c-tag-primary-border-color: color-mix(in srgb, $var-primary 35%, $var-background),
767
+ $c-tag-primary-color: $var-text,
768
+
769
+ // Success
770
+ $c-tag-success-background: color-mix(in srgb, $var-success 12%, $var-background),
771
+ $c-tag-success-border-color: color-mix(in srgb, $var-success 35%, $var-background),
772
+ $c-tag-success-color: $var-text,
773
+
774
+ // Warning
775
+ $c-tag-warning-background: color-mix(in srgb, $var-warning 12%, $var-background),
776
+ $c-tag-warning-border-color: color-mix(in srgb, $var-warning 35%, $var-background),
777
+ $c-tag-warning-color: $var-text,
778
+
779
+ // Error
780
+ $c-tag-error-background: color-mix(in srgb, $var-error 12%, $var-background),
781
+ $c-tag-error-border-color: color-mix(in srgb, $var-error 35%, $var-background),
782
+ $c-tag-error-color: $var-text,
783
+
784
+ // Info
785
+ $c-tag-info-background: color-mix(in srgb, $var-info 12%, $var-background),
786
+ $c-tag-info-border-color: color-mix(in srgb, $var-info 35%, $var-background),
787
+ $c-tag-info-color: $var-text
788
+ );
789
+
790
+ // Link: --c-primary (black in light, white in dark) with an underline, because a black link on black text is told apart
791
+ // by the underline alone; --c-primary-hover on hover. Subtle is --c-muted (4.7:1 on the background) and turns --c-text.
792
+ // Disabled is --c-disabled-text at full opacity. The focus ring is the theme's 1px ring, offset 2px.
793
+ @use '@carissa-io/components-link/scss' as link with (
794
+ $c-link-color: $var-primary,
795
+ $c-link-color-hover: $var-primary-hover,
796
+ $c-link-decoration: underline,
797
+ $c-link-hover-decoration: underline,
798
+ $c-link-font-weight: $font-weight-bold,
799
+ $c-link-subtle-color: $var-muted,
800
+ $c-link-subtle-color-hover: $var-text,
801
+ $c-link-inline-decoration: underline,
802
+ $c-link-inline-underline-offset: 0.15em,
803
+ $c-link-focus-outline: $focus-width solid $var-focus,
804
+ $c-link-focus-outline-offset: 2px,
805
+ $c-link-focus-radius: $radius,
806
+ $c-link-disabled-color: $var-disabled-text,
807
+ $c-link-disabled-opacity: 1
808
+ );
809
+
810
+ // Avatar: a --c-surface-active disc (or a square, with the theme radius) with --c-text initials, bold. The ring that
811
+ // separates overlapping avatars in a group is the page background, so it blends in both modes.
812
+ @use '@carissa-io/components-avatar/scss' as avatar with (
813
+ $c-avatar-background: $var-surface-active,
814
+ $c-avatar-color: $var-text,
815
+ $c-avatar-font-weight: $font-weight-bold,
816
+ $c-avatar-radius-square: $radius,
817
+ $c-avatar-group-overlap: -0.5rem,
818
+ $c-avatar-group-ring-width: 2px,
819
+ $c-avatar-group-ring-color: $var-background
820
+ );
821
+
822
+ // Skeleton: a --c-surface-active block, square, with a band of the page background at 60% sweeping across (a lighter band in
823
+ // light, a darker one in dark). Reduced motion removes the sweep (the package handles it).
824
+ @use '@carissa-io/components-skeleton/scss' as skeleton with (
825
+ $c-skeleton-background: $var-surface-active,
826
+ $c-skeleton-highlight: color-mix(in srgb, $var-background 60%, transparent),
827
+ $c-skeleton-radius: $radius,
828
+ $c-skeleton-text-height: 1em,
829
+ $c-skeleton-lines-gap: 0.5rem,
830
+ $c-skeleton-last-line-width: 60%,
831
+ $c-skeleton-circle-size: 2.5rem,
832
+ $c-skeleton-duration: 1.5s
833
+ );
834
+
835
+ // Progress: a --c-surface-active track with a --c-primary fill (black in light, white in dark), square ends, the
836
+ // percentage in --c-text. Indeterminate loops at 1.4s; with reduced motion the package swaps the motion for a slow pulse.
837
+ @use '@carissa-io/components-progress/scss' as progress with (
838
+ $c-progress-track-color: $var-surface-active,
839
+ $c-progress-fill-color: $var-primary,
840
+ $c-progress-color: $var-text,
841
+ $c-progress-font-size: $font-size-caption,
842
+ $c-progress-font-weight: $font-weight-bold,
843
+ $c-progress-gap: 0.75rem,
844
+ $c-progress-bar-height-sm: 0.25rem,
845
+ $c-progress-bar-height-md: 0.5rem,
846
+ $c-progress-bar-height-lg: 0.75rem,
847
+ $c-progress-bar-radius: $radius,
848
+ $c-progress-transition: width $transition-duration ease,
849
+ $c-progress-circular-size-sm: 1.5rem,
850
+ $c-progress-circular-size-md: 2.5rem,
851
+ $c-progress-circular-size-lg: 4rem,
852
+ $c-progress-circular-thickness: 8,
853
+ $c-progress-duration: 1.4s,
854
+ $c-progress-duration-reduced: 2s
855
+ );