@sovereignfs/ui 0.41.0 → 0.54.0
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/Accordion.module.css +3 -0
- package/dist/Alert.module.css +62 -0
- package/dist/AspectRatio.module.css +15 -0
- package/dist/Badge.module.css +75 -9
- package/dist/Breadcrumb.module.css +49 -0
- package/dist/Button.module.css +12 -3
- package/dist/ButtonGroup.module.css +29 -0
- package/dist/Card.module.css +6 -0
- package/dist/Checkbox.module.css +3 -1
- package/dist/Collapsible.module.css +70 -0
- package/dist/Combobox.module.css +122 -0
- package/dist/Command.module.css +80 -0
- package/dist/ConfirmDialog.module.css +5 -1
- package/dist/DataTable.module.css +28 -0
- package/dist/DatePicker.module.css +6 -2
- package/dist/Dialog.module.css +3 -0
- package/dist/HoverCard.module.css +3 -0
- package/dist/Input.module.css +6 -1
- package/dist/Item.module.css +70 -0
- package/dist/Kbd.module.css +14 -0
- package/dist/Label.module.css +11 -0
- package/dist/LegalLinks.module.css +24 -0
- package/dist/Markdown.module.css +49 -0
- package/dist/Marker.module.css +33 -0
- package/dist/Menu.module.css +8 -1
- package/dist/Message.module.css +99 -0
- package/dist/MessageScroller.module.css +54 -0
- package/dist/MobileAppsDrawer.module.css +81 -0
- package/dist/MobileFooter.module.css +73 -0
- package/dist/MobileHeader.module.css +63 -0
- package/dist/NavigationMenu.module.css +53 -0
- package/dist/PageContainer.module.css +20 -0
- package/dist/Pagination.module.css +98 -0
- package/dist/Progress.module.css +20 -0
- package/dist/RadioGroup.module.css +88 -0
- package/dist/Resizable.module.css +70 -0
- package/dist/ScrollArea.module.css +20 -0
- package/dist/Select.module.css +7 -3
- package/dist/Slider.module.css +95 -0
- package/dist/SwipableMobileCarousel.module.css +55 -0
- package/dist/SwipableMobileCarouselDots.module.css +49 -0
- package/dist/SwipableMobileCarouselSlideParts.module.css +29 -0
- package/dist/Table.module.css +45 -0
- package/dist/Tabs.module.css +6 -1
- package/dist/Toggle.module.css +6 -1
- package/dist/Typography.module.css +47 -0
- package/dist/index.d.ts +1268 -8
- package/dist/index.js +3046 -975
- package/dist/tokens/primitives.css +47 -8
- package/package.json +13 -9
- package/src/components/Accordion/Accordion.module.css +3 -0
- package/src/components/Accordion/Accordion.stories.tsx +110 -0
- package/src/components/Accordion/Accordion.tsx +53 -0
- package/src/components/Accordion/__tests__/Accordion.test.tsx +61 -0
- package/src/components/Alert/Alert.module.css +62 -0
- package/src/components/Alert/Alert.stories.tsx +96 -0
- package/src/components/Alert/Alert.tsx +58 -0
- package/src/components/Alert/__tests__/Alert.test.tsx +75 -0
- package/src/components/AspectRatio/AspectRatio.module.css +15 -0
- package/src/components/AspectRatio/AspectRatio.stories.tsx +78 -0
- package/src/components/AspectRatio/AspectRatio.tsx +21 -0
- package/src/components/AspectRatio/__tests__/AspectRatio.test.tsx +27 -0
- package/src/components/Badge/Badge.module.css +75 -9
- package/src/components/Badge/Badge.stories.tsx +109 -1
- package/src/components/Badge/Badge.tsx +31 -9
- package/src/components/Badge/__tests__/Badge.test.tsx +26 -2
- package/src/components/Breadcrumb/Breadcrumb.module.css +49 -0
- package/src/components/Breadcrumb/Breadcrumb.stories.tsx +47 -0
- package/src/components/Breadcrumb/Breadcrumb.tsx +57 -0
- package/src/components/Breadcrumb/__tests__/Breadcrumb.test.tsx +52 -0
- package/src/components/Button/Button.module.css +12 -3
- package/src/components/Button/Button.stories.tsx +3 -2
- package/src/components/Button/Button.tsx +1 -1
- package/src/components/Button/__tests__/Button.test.tsx +10 -0
- package/src/components/ButtonGroup/ButtonGroup.module.css +29 -0
- package/src/components/ButtonGroup/ButtonGroup.stories.tsx +57 -0
- package/src/components/ButtonGroup/ButtonGroup.tsx +27 -0
- package/src/components/ButtonGroup/__tests__/ButtonGroup.test.tsx +29 -0
- package/src/components/Card/Card.module.css +6 -0
- package/src/components/Checkbox/Checkbox.module.css +3 -1
- package/src/components/Collapsible/Collapsible.module.css +70 -0
- package/src/components/Collapsible/Collapsible.stories.tsx +62 -0
- package/src/components/Collapsible/Collapsible.tsx +66 -0
- package/src/components/Collapsible/__tests__/Collapsible.test.tsx +71 -0
- package/src/components/Combobox/Combobox.module.css +122 -0
- package/src/components/Combobox/Combobox.stories.tsx +79 -0
- package/src/components/Combobox/Combobox.tsx +186 -0
- package/src/components/Combobox/__tests__/Combobox.test.tsx +158 -0
- package/src/components/Command/Command.module.css +80 -0
- package/src/components/Command/Command.stories.tsx +104 -0
- package/src/components/Command/Command.tsx +168 -0
- package/src/components/Command/__tests__/Command.test.tsx +162 -0
- package/src/components/ConfirmDialog/ConfirmDialog.module.css +5 -1
- package/src/components/ContextMenu/ContextMenu.stories.tsx +81 -0
- package/src/components/ContextMenu/ContextMenu.tsx +100 -0
- package/src/components/ContextMenu/__tests__/ContextMenu.test.tsx +87 -0
- package/src/components/DataTable/DataTable.module.css +28 -0
- package/src/components/DataTable/DataTable.stories.tsx +74 -0
- package/src/components/DataTable/DataTable.tsx +154 -0
- package/src/components/DataTable/__tests__/DataTable.test.tsx +123 -0
- package/src/components/DatePicker/DatePicker.module.css +6 -2
- package/src/components/DeviceOnlyGate/DeviceOnlyGate.tsx +58 -0
- package/src/components/DeviceOnlyGate/__tests__/DeviceOnlyGate.test.tsx +45 -0
- package/src/components/DeviceStorageKeyGate/DeviceStorageKeyGate.tsx +100 -0
- package/src/components/DeviceStorageKeyGate/__tests__/DeviceStorageKeyGate.test.tsx +119 -0
- package/src/components/Dialog/Dialog.module.css +3 -0
- package/src/components/Dialog/Dialog.tsx +8 -59
- package/src/components/Drawer/Drawer.stories.tsx +44 -0
- package/src/components/Drawer/Drawer.tsx +18 -56
- package/src/components/Drawer/__tests__/Drawer.test.tsx +22 -0
- package/src/components/HoverCard/HoverCard.module.css +3 -0
- package/src/components/HoverCard/HoverCard.stories.tsx +66 -0
- package/src/components/HoverCard/HoverCard.tsx +111 -0
- package/src/components/HoverCard/__tests__/HoverCard.test.tsx +99 -0
- package/src/components/Icon/icons/circle-check.tsx +21 -0
- package/src/components/Icon/icons/circle-x.tsx +22 -0
- package/src/components/Icon/icons/index.ts +16 -0
- package/src/components/Icon/icons/menu.tsx +22 -0
- package/src/components/Icon/icons/smartphone.tsx +21 -0
- package/src/components/Input/Input.module.css +6 -1
- package/src/components/Item/Item.module.css +70 -0
- package/src/components/Item/Item.stories.tsx +62 -0
- package/src/components/Item/Item.tsx +54 -0
- package/src/components/Item/__tests__/Item.test.tsx +39 -0
- package/src/components/Kbd/Kbd.module.css +14 -0
- package/src/components/Kbd/Kbd.stories.tsx +32 -0
- package/src/components/Kbd/Kbd.tsx +12 -0
- package/src/components/Kbd/__tests__/Kbd.test.tsx +14 -0
- package/src/components/Label/Label.module.css +11 -0
- package/src/components/Label/Label.stories.tsx +40 -0
- package/src/components/Label/Label.tsx +24 -0
- package/src/components/Label/__tests__/Label.test.tsx +32 -0
- package/src/components/LegalLinks/LegalLinks.module.css +24 -0
- package/src/components/LegalLinks/LegalLinks.stories.tsx +22 -0
- package/src/components/LegalLinks/LegalLinks.tsx +40 -0
- package/src/components/Markdown/Markdown.module.css +49 -0
- package/src/components/Markdown/Markdown.stories.tsx +30 -0
- package/src/components/Markdown/Markdown.tsx +168 -0
- package/src/components/Marker/Marker.module.css +33 -0
- package/src/components/Marker/Marker.stories.tsx +39 -0
- package/src/components/Marker/Marker.tsx +34 -0
- package/src/components/Marker/__tests__/Marker.test.tsx +23 -0
- package/src/components/Menu/Menu.module.css +8 -1
- package/src/components/Menu/Menu.tsx +30 -8
- package/src/components/Menubar/Menubar.stories.tsx +52 -0
- package/src/components/Menubar/Menubar.tsx +42 -0
- package/src/components/Menubar/__tests__/Menubar.test.tsx +45 -0
- package/src/components/Message/Message.module.css +99 -0
- package/src/components/Message/Message.stories.tsx +79 -0
- package/src/components/Message/Message.tsx +41 -0
- package/src/components/Message/__tests__/Message.test.tsx +46 -0
- package/src/components/MessageScroller/MessageScroller.module.css +54 -0
- package/src/components/MessageScroller/MessageScroller.stories.tsx +84 -0
- package/src/components/MessageScroller/MessageScroller.tsx +72 -0
- package/src/components/MessageScroller/__tests__/MessageScroller.test.tsx +105 -0
- package/src/components/MobileAppsDrawer/MobileAppsDrawer.module.css +81 -0
- package/src/components/MobileAppsDrawer/MobileAppsDrawer.tsx +78 -0
- package/src/components/MobileAppsDrawer/__tests__/MobileAppsDrawer.test.tsx +80 -0
- package/src/components/MobileFooter/MobileFooter.module.css +73 -0
- package/src/components/MobileFooter/MobileFooter.stories.tsx +47 -0
- package/src/components/MobileFooter/MobileFooter.tsx +109 -0
- package/src/components/MobileFooter/__tests__/MobileFooter.test.tsx +71 -0
- package/src/components/MobileHeader/MobileHeader.module.css +63 -0
- package/src/components/MobileHeader/MobileHeader.stories.tsx +57 -0
- package/src/components/MobileHeader/MobileHeader.tsx +77 -0
- package/src/components/MobileHeader/__tests__/MobileHeader.test.tsx +58 -0
- package/src/components/NavTabs/NavTabs.tsx +39 -11
- package/src/components/NavigationMenu/NavigationMenu.module.css +53 -0
- package/src/components/NavigationMenu/NavigationMenu.stories.tsx +58 -0
- package/src/components/NavigationMenu/NavigationMenu.tsx +125 -0
- package/src/components/NavigationMenu/__tests__/NavigationMenu.test.tsx +93 -0
- package/src/components/OfflineGate/OfflineGate.tsx +44 -0
- package/src/components/OfflineGate/__tests__/OfflineGate.test.tsx +66 -0
- package/src/components/PageContainer/PageContainer.module.css +20 -0
- package/src/components/PageContainer/PageContainer.tsx +31 -0
- package/src/components/PageContainer/__tests__/PageContainer.test.tsx +37 -0
- package/src/components/PageHeader/PageHeader.tsx +16 -2
- package/src/components/Pagination/Pagination.module.css +98 -0
- package/src/components/Pagination/Pagination.stories.tsx +49 -0
- package/src/components/Pagination/Pagination.tsx +87 -0
- package/src/components/Pagination/__tests__/Pagination.test.tsx +56 -0
- package/src/components/Progress/Progress.module.css +20 -0
- package/src/components/Progress/Progress.stories.tsx +40 -0
- package/src/components/Progress/Progress.tsx +35 -0
- package/src/components/Progress/__tests__/Progress.test.tsx +31 -0
- package/src/components/RadioGroup/RadioGroup.module.css +88 -0
- package/src/components/RadioGroup/RadioGroup.stories.tsx +69 -0
- package/src/components/RadioGroup/RadioGroup.tsx +99 -0
- package/src/components/RadioGroup/__tests__/RadioGroup.test.tsx +59 -0
- package/src/components/Resizable/Resizable.module.css +70 -0
- package/src/components/Resizable/Resizable.stories.tsx +82 -0
- package/src/components/Resizable/Resizable.tsx +313 -0
- package/src/components/Resizable/__tests__/Resizable.test.tsx +128 -0
- package/src/components/ResponsiveSurface/ResponsiveSurface.tsx +24 -0
- package/src/components/ResponsiveSurface/__tests__/ResponsiveSurface.test.tsx +73 -0
- package/src/components/ScrollArea/ScrollArea.module.css +20 -0
- package/src/components/ScrollArea/ScrollArea.stories.tsx +57 -0
- package/src/components/ScrollArea/ScrollArea.tsx +27 -0
- package/src/components/ScrollArea/__tests__/ScrollArea.test.tsx +39 -0
- package/src/components/Select/Select.module.css +7 -3
- package/src/components/Sheet/Sheet.tsx +9 -51
- package/src/components/Slider/Slider.module.css +95 -0
- package/src/components/Slider/Slider.stories.tsx +64 -0
- package/src/components/Slider/Slider.tsx +77 -0
- package/src/components/Slider/__tests__/Slider.test.tsx +45 -0
- package/src/components/SwipableMobileCarousel/SwipableMobileCarousel.module.css +55 -0
- package/src/components/SwipableMobileCarousel/SwipableMobileCarousel.tsx +227 -0
- package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlide.tsx +35 -0
- package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlideBody.tsx +42 -0
- package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlideFooter.tsx +18 -0
- package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlideHeader.tsx +21 -0
- package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlideParts.module.css +29 -0
- package/src/components/SwipableMobileCarousel/__tests__/SwipableMobileCarousel.test.tsx +133 -0
- package/src/components/SwipableMobileCarousel/__tests__/SwipableMobileCarouselDevGuard.test.tsx +61 -0
- package/src/components/SwipableMobileCarousel/context.ts +13 -0
- package/src/components/SwipableMobileCarouselDots/SwipableMobileCarouselDots.module.css +49 -0
- package/src/components/SwipableMobileCarouselDots/SwipableMobileCarouselDots.tsx +62 -0
- package/src/components/SwipableMobileCarouselDots/__tests__/SwipableMobileCarouselDots.test.tsx +63 -0
- package/src/components/Table/Table.module.css +45 -0
- package/src/components/Table/Table.stories.tsx +125 -0
- package/src/components/Table/Table.tsx +51 -0
- package/src/components/Table/__tests__/Table.test.tsx +50 -0
- package/src/components/Tabs/Tabs.module.css +6 -1
- package/src/components/Toggle/Toggle.module.css +6 -1
- package/src/components/Typography/Typography.module.css +47 -0
- package/src/components/Typography/Typography.stories.tsx +62 -0
- package/src/components/Typography/Typography.tsx +30 -0
- package/src/components/Typography/__tests__/Typography.test.tsx +34 -0
- package/src/hooks/__tests__/useCarouselRouteSync.test.tsx +126 -0
- package/src/hooks/__tests__/useIsOffline.test.tsx +53 -0
- package/src/hooks/__tests__/useOfflineTileState.test.tsx +69 -0
- package/src/hooks/__tests__/useResponsiveLayout.test.tsx +87 -0
- package/src/hooks/__tests__/useSnapCarousel.test.tsx +93 -0
- package/src/hooks/__tests__/useSwipeReveal.test.tsx +110 -0
- package/src/hooks/index.ts +18 -0
- package/src/hooks/useCarouselRouteSync.ts +92 -0
- package/src/hooks/useIsOffline.ts +41 -0
- package/src/hooks/useOfflineTileState.ts +45 -0
- package/src/hooks/useResponsiveLayout.ts +36 -0
- package/src/hooks/useSnapCarousel.ts +79 -0
- package/src/hooks/useSwipeReveal.ts +107 -0
- package/src/index.ts +141 -3
- package/src/overlay-shell.ts +94 -0
- package/src/stories/DesignSystemOverview.stories.tsx +936 -3
- package/src/stories/DeviceOnlyGate.stories.tsx +35 -0
- package/src/stories/DeviceStorageKeyGate.stories.tsx +57 -0
- package/src/stories/InteractionHooks.stories.tsx +483 -0
- package/src/stories/MobilePatterns.stories.tsx +255 -4
- package/src/stories/NavTabs.stories.tsx +18 -0
- package/src/stories/OfflineGate.stories.tsx +42 -0
- package/src/stories/PageContainer.stories.tsx +37 -0
- package/src/stories/PageHeader.stories.tsx +11 -0
- package/src/stories/ResponsiveSurface.stories.tsx +47 -0
- package/src/stories/SwipableMobileCarousel.stories.tsx +304 -0
- package/src/stories/TokenGallery.stories.tsx +177 -16
- package/src/tokens/primitives.css +47 -8
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
.nav {
|
|
2
|
+
display: flex;
|
|
3
|
+
align-items: center;
|
|
4
|
+
gap: var(--sv-space-1);
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.list {
|
|
8
|
+
display: flex;
|
|
9
|
+
align-items: center;
|
|
10
|
+
gap: var(--sv-space-1);
|
|
11
|
+
margin: 0;
|
|
12
|
+
padding: 0;
|
|
13
|
+
list-style: none;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/* Icon-only nav buttons — same footprint as Dialog's close button. */
|
|
17
|
+
.navButton {
|
|
18
|
+
display: inline-flex;
|
|
19
|
+
align-items: center;
|
|
20
|
+
justify-content: center;
|
|
21
|
+
width: var(--sv-space-8);
|
|
22
|
+
height: var(--sv-space-8);
|
|
23
|
+
border: none;
|
|
24
|
+
border-radius: var(--sv-radius-md);
|
|
25
|
+
background: transparent;
|
|
26
|
+
color: var(--sv-color-text-primary);
|
|
27
|
+
cursor: pointer;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.navButton:disabled {
|
|
31
|
+
opacity: 0.5;
|
|
32
|
+
cursor: not-allowed;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@media (hover: hover) {
|
|
36
|
+
.navButton:not(:disabled):hover {
|
|
37
|
+
background: var(--sv-color-surface-sunken);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.navButton:focus-visible {
|
|
42
|
+
outline: 2px solid var(--sv-color-focus-ring);
|
|
43
|
+
outline-offset: 2px;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@media (pointer: coarse) {
|
|
47
|
+
.navButton {
|
|
48
|
+
width: var(--sv-touch-target-min, 44px);
|
|
49
|
+
height: var(--sv-touch-target-min, 44px);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.pageButton {
|
|
54
|
+
display: inline-flex;
|
|
55
|
+
align-items: center;
|
|
56
|
+
justify-content: center;
|
|
57
|
+
min-width: var(--sv-space-8);
|
|
58
|
+
height: var(--sv-space-8);
|
|
59
|
+
padding: 0 var(--sv-space-2);
|
|
60
|
+
border: none;
|
|
61
|
+
border-radius: var(--sv-radius-md);
|
|
62
|
+
background: transparent;
|
|
63
|
+
color: var(--sv-color-text-primary);
|
|
64
|
+
font-size: var(--sv-font-size-sm);
|
|
65
|
+
cursor: pointer;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
@media (hover: hover) {
|
|
69
|
+
.pageButton:not(.active):hover {
|
|
70
|
+
background: var(--sv-color-surface-sunken);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.pageButton:focus-visible {
|
|
75
|
+
outline: 2px solid var(--sv-color-focus-ring);
|
|
76
|
+
outline-offset: 2px;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.active {
|
|
80
|
+
background: var(--sv-color-accent);
|
|
81
|
+
color: var(--sv-color-text-on-accent);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
@media (pointer: coarse) {
|
|
85
|
+
.pageButton {
|
|
86
|
+
min-width: var(--sv-touch-target-min, 44px);
|
|
87
|
+
height: var(--sv-touch-target-min, 44px);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.ellipsis {
|
|
92
|
+
display: inline-flex;
|
|
93
|
+
align-items: center;
|
|
94
|
+
justify-content: center;
|
|
95
|
+
min-width: var(--sv-space-8);
|
|
96
|
+
height: var(--sv-space-8);
|
|
97
|
+
color: var(--sv-color-text-muted);
|
|
98
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
.track {
|
|
2
|
+
width: 100%;
|
|
3
|
+
height: 8px;
|
|
4
|
+
border-radius: var(--sv-radius-full);
|
|
5
|
+
background: var(--sv-color-surface-sunken);
|
|
6
|
+
overflow: hidden;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.fill {
|
|
10
|
+
height: 100%;
|
|
11
|
+
border-radius: var(--sv-radius-full);
|
|
12
|
+
background: var(--sv-color-accent);
|
|
13
|
+
transition: width 0.2s ease;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
@media (prefers-reduced-motion: reduce) {
|
|
17
|
+
.fill {
|
|
18
|
+
transition: none;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
.root {
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-direction: column;
|
|
4
|
+
gap: var(--sv-space-2);
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.option {
|
|
8
|
+
display: inline-flex;
|
|
9
|
+
align-items: center;
|
|
10
|
+
gap: var(--sv-space-2);
|
|
11
|
+
cursor: pointer;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/* The visual circle — same 18px size and touch-target-expansion technique
|
|
15
|
+
as Checkbox's box, radius-full instead of radius-sm. */
|
|
16
|
+
.circle {
|
|
17
|
+
--radio-circle-size: 18px;
|
|
18
|
+
position: relative;
|
|
19
|
+
flex-shrink: 0;
|
|
20
|
+
width: var(--radio-circle-size);
|
|
21
|
+
height: var(--radio-circle-size);
|
|
22
|
+
border-radius: var(--sv-radius-full);
|
|
23
|
+
border: 1.5px solid var(--sv-color-border-strong);
|
|
24
|
+
background: var(--sv-color-surface);
|
|
25
|
+
transition:
|
|
26
|
+
background-color 0.15s ease,
|
|
27
|
+
border-color 0.15s ease;
|
|
28
|
+
display: flex;
|
|
29
|
+
align-items: center;
|
|
30
|
+
justify-content: center;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.checked {
|
|
34
|
+
border-color: var(--sv-color-accent);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.dot {
|
|
38
|
+
width: 8px;
|
|
39
|
+
height: 8px;
|
|
40
|
+
border-radius: var(--sv-radius-full);
|
|
41
|
+
background: var(--sv-color-accent);
|
|
42
|
+
pointer-events: none;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/* Hide the native input visually but keep it accessible */
|
|
46
|
+
.input {
|
|
47
|
+
position: absolute;
|
|
48
|
+
inset: 0;
|
|
49
|
+
opacity: 0;
|
|
50
|
+
margin: 0;
|
|
51
|
+
width: 100%;
|
|
52
|
+
height: 100%;
|
|
53
|
+
cursor: pointer;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.input:disabled {
|
|
57
|
+
cursor: not-allowed;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/* Expand the tappable region to the platform's minimum touch target without
|
|
61
|
+
growing the visible circle. Gated to (pointer: coarse), the *primary*
|
|
62
|
+
pointer, so a touchscreen laptop with mouse/trackpad as primary keeps
|
|
63
|
+
desktop density — same reasoning as Checkbox. */
|
|
64
|
+
@media (pointer: coarse) {
|
|
65
|
+
.input {
|
|
66
|
+
inset: calc((var(--radio-circle-size) - var(--sv-touch-target-min, 44px)) / 2);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.input:focus-visible {
|
|
71
|
+
outline: none;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.circle:has(.input:focus-visible) {
|
|
75
|
+
outline: 2px solid var(--sv-color-focus-ring);
|
|
76
|
+
outline-offset: 2px;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.optionLabel {
|
|
80
|
+
font-size: var(--sv-font-size-sm);
|
|
81
|
+
color: var(--sv-color-text-primary);
|
|
82
|
+
user-select: none;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.disabled {
|
|
86
|
+
opacity: 0.5;
|
|
87
|
+
cursor: not-allowed;
|
|
88
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
.group {
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-direction: row;
|
|
4
|
+
width: 100%;
|
|
5
|
+
height: 100%;
|
|
6
|
+
min-height: 320px;
|
|
7
|
+
border: 1px solid var(--sv-color-border);
|
|
8
|
+
border-radius: var(--sv-radius-lg);
|
|
9
|
+
overflow: hidden;
|
|
10
|
+
background: var(--sv-color-surface);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.groupVertical {
|
|
14
|
+
flex-direction: column;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.panel {
|
|
18
|
+
min-width: 0;
|
|
19
|
+
min-height: 0;
|
|
20
|
+
overflow: auto;
|
|
21
|
+
background: var(--sv-color-surface);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.handle {
|
|
25
|
+
position: relative;
|
|
26
|
+
flex-shrink: 0;
|
|
27
|
+
width: 12px;
|
|
28
|
+
padding: 0;
|
|
29
|
+
border: 0;
|
|
30
|
+
border-inline: 1px solid var(--sv-color-border);
|
|
31
|
+
cursor: col-resize;
|
|
32
|
+
background: var(--sv-color-surface-sunken);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.handleVertical {
|
|
36
|
+
width: 100%;
|
|
37
|
+
height: 12px;
|
|
38
|
+
border-inline: 0;
|
|
39
|
+
border-block: 1px solid var(--sv-color-border);
|
|
40
|
+
cursor: row-resize;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.handle::before {
|
|
44
|
+
position: absolute;
|
|
45
|
+
inset-block: 50%;
|
|
46
|
+
inset-inline: 50%;
|
|
47
|
+
width: 2px;
|
|
48
|
+
height: 40px;
|
|
49
|
+
content: '';
|
|
50
|
+
background: var(--sv-color-border-strong);
|
|
51
|
+
border-radius: var(--sv-radius-full);
|
|
52
|
+
transform: translate(-50%, -50%);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.handleVertical::before {
|
|
56
|
+
width: 40px;
|
|
57
|
+
height: 2px;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
@media (hover: hover) {
|
|
61
|
+
.handle:hover {
|
|
62
|
+
background: var(--sv-color-accent-subtle);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.handle:focus-visible {
|
|
67
|
+
background: var(--sv-color-accent-subtle);
|
|
68
|
+
outline: 2px solid var(--sv-color-focus-ring);
|
|
69
|
+
outline-offset: -2px;
|
|
70
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
.root {
|
|
2
|
+
overflow: auto;
|
|
3
|
+
overscroll-behavior: contain;
|
|
4
|
+
scrollbar-width: thin;
|
|
5
|
+
scrollbar-color: var(--sv-color-border-strong) transparent;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.root::-webkit-scrollbar {
|
|
9
|
+
width: 8px;
|
|
10
|
+
height: 8px;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.root::-webkit-scrollbar-track {
|
|
14
|
+
background: transparent;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.root::-webkit-scrollbar-thumb {
|
|
18
|
+
background: var(--sv-color-border-strong);
|
|
19
|
+
border-radius: var(--sv-radius-full);
|
|
20
|
+
}
|
package/dist/Select.module.css
CHANGED
|
@@ -8,8 +8,11 @@
|
|
|
8
8
|
.select {
|
|
9
9
|
display: block;
|
|
10
10
|
width: 100%;
|
|
11
|
-
/*
|
|
12
|
-
|
|
11
|
+
/* 36px rendered height. Explicit height + border-box, same technique as
|
|
12
|
+
Input. Right-pad to clear the custom chevron. */
|
|
13
|
+
height: 36px;
|
|
14
|
+
box-sizing: border-box;
|
|
15
|
+
padding: 4px var(--sv-space-8) 4px var(--sv-space-3);
|
|
13
16
|
font-family: var(--sv-font-family);
|
|
14
17
|
font-size: var(--sv-font-size-sm);
|
|
15
18
|
line-height: 1.5;
|
|
@@ -25,8 +28,9 @@
|
|
|
25
28
|
box-shadow 0.15s ease;
|
|
26
29
|
}
|
|
27
30
|
|
|
28
|
-
/* sm — compact for table cells and inline controls */
|
|
31
|
+
/* sm — compact for table cells and inline controls. 32px height. */
|
|
29
32
|
.sm .select {
|
|
33
|
+
height: 32px;
|
|
30
34
|
padding: 2px var(--sv-space-6) 2px var(--sv-space-2);
|
|
31
35
|
font-size: var(--sv-font-size-sm);
|
|
32
36
|
line-height: 1.4;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
.root {
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-direction: column;
|
|
4
|
+
gap: var(--sv-space-2);
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.label {
|
|
8
|
+
font-size: var(--sv-font-size-sm);
|
|
9
|
+
color: var(--sv-color-text-primary);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.slider {
|
|
13
|
+
appearance: none;
|
|
14
|
+
width: 100%;
|
|
15
|
+
height: 20px;
|
|
16
|
+
background: transparent;
|
|
17
|
+
cursor: pointer;
|
|
18
|
+
margin: 0;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/* Expand the vertical hit area for touch dragging without thickening the
|
|
22
|
+
visible track — same rationale as Button/Checkbox's touch-target
|
|
23
|
+
expansion, gated to the primary pointer. */
|
|
24
|
+
@media (pointer: coarse) {
|
|
25
|
+
.slider {
|
|
26
|
+
height: var(--sv-touch-target-min, 44px);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.slider:disabled {
|
|
31
|
+
opacity: 0.5;
|
|
32
|
+
cursor: not-allowed;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.slider:focus-visible {
|
|
36
|
+
outline: 2px solid var(--sv-color-focus-ring);
|
|
37
|
+
outline-offset: 2px;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/* Track — WebKit/Blink. The filled portion is a gradient computed from the
|
|
41
|
+
--slider-fill custom property the component sets inline; no JS-measured
|
|
42
|
+
pixel math, just a CSS variable driving a hard color stop. */
|
|
43
|
+
.slider::-webkit-slider-runnable-track {
|
|
44
|
+
height: 4px;
|
|
45
|
+
border-radius: var(--sv-radius-full);
|
|
46
|
+
background: linear-gradient(
|
|
47
|
+
to right,
|
|
48
|
+
var(--sv-color-accent) var(--slider-fill),
|
|
49
|
+
var(--sv-color-border-strong) var(--slider-fill)
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.slider::-webkit-slider-thumb {
|
|
54
|
+
appearance: none;
|
|
55
|
+
width: 16px;
|
|
56
|
+
height: 16px;
|
|
57
|
+
margin-top: -6px;
|
|
58
|
+
border-radius: var(--sv-radius-full);
|
|
59
|
+
background: var(--sv-color-accent);
|
|
60
|
+
box-shadow: var(--sv-shadow-control);
|
|
61
|
+
cursor: pointer;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.slider:disabled::-webkit-slider-thumb {
|
|
65
|
+
cursor: not-allowed;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/* Track — Firefox. Separate track/progress pseudo-elements instead of a
|
|
69
|
+
gradient — Firefox renders the filled portion natively via
|
|
70
|
+
::-moz-range-progress. */
|
|
71
|
+
.slider::-moz-range-track {
|
|
72
|
+
height: 4px;
|
|
73
|
+
border-radius: var(--sv-radius-full);
|
|
74
|
+
background: var(--sv-color-border-strong);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.slider::-moz-range-progress {
|
|
78
|
+
height: 4px;
|
|
79
|
+
border-radius: var(--sv-radius-full);
|
|
80
|
+
background: var(--sv-color-accent);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.slider::-moz-range-thumb {
|
|
84
|
+
width: 16px;
|
|
85
|
+
height: 16px;
|
|
86
|
+
border: none;
|
|
87
|
+
border-radius: var(--sv-radius-full);
|
|
88
|
+
background: var(--sv-color-accent);
|
|
89
|
+
box-shadow: var(--sv-shadow-control);
|
|
90
|
+
cursor: pointer;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.slider:disabled::-moz-range-thumb {
|
|
94
|
+
cursor: not-allowed;
|
|
95
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
.wrap {
|
|
2
|
+
position: relative;
|
|
3
|
+
height: 100%;
|
|
4
|
+
width: 100%;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.scroller {
|
|
8
|
+
height: 100%;
|
|
9
|
+
width: 100%;
|
|
10
|
+
display: flex;
|
|
11
|
+
overflow-x: auto;
|
|
12
|
+
overflow-y: hidden;
|
|
13
|
+
scroll-snap-type: x mandatory;
|
|
14
|
+
/* Momentum + rubber-banding come from the browser's native scroll physics —
|
|
15
|
+
no hand-rolled pointer/touch dragging. Deliberately NOT
|
|
16
|
+
-webkit-overflow-scrolling: touch: that legacy iOS <13 hint promotes its
|
|
17
|
+
element to its own compositing layer for GPU-accelerated momentum
|
|
18
|
+
scroll, and that layer's paint order relative to siblings/fixed
|
|
19
|
+
descendants elsewhere in the tree isn't always reliable on real iOS
|
|
20
|
+
Safari (confirmed via sovereign-tasks' and sovereign-shopper's own
|
|
21
|
+
carousels, which hit and fixed this exact bug — a position:fixed
|
|
22
|
+
overlay opened above the scroller painted BEHIND it instead of above).
|
|
23
|
+
Removing it doesn't disable momentum scrolling on any iOS version this
|
|
24
|
+
platform realistically targets. */
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.slide {
|
|
28
|
+
flex: 0 0 100%;
|
|
29
|
+
width: 100%;
|
|
30
|
+
height: 100%;
|
|
31
|
+
min-width: 0;
|
|
32
|
+
overflow: hidden;
|
|
33
|
+
scroll-snap-align: start;
|
|
34
|
+
scroll-snap-stop: always;
|
|
35
|
+
/* Slide content is a flex column so Header/Footer stay their natural size
|
|
36
|
+
and Body (flex: 1 1 auto, min-height: 0) fills and scrolls the rest —
|
|
37
|
+
see SwipableMobileCarouselSlideParts.module.css. */
|
|
38
|
+
display: flex;
|
|
39
|
+
flex-direction: column;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.dots {
|
|
43
|
+
/* Overlays the bottom of .wrap rather than taking its own layout row —
|
|
44
|
+
matches both sovereign-tasks' and sovereign-shopper's existing dots
|
|
45
|
+
placement. */
|
|
46
|
+
position: absolute;
|
|
47
|
+
left: 0;
|
|
48
|
+
right: 0;
|
|
49
|
+
bottom: var(--sv-space-3);
|
|
50
|
+
pointer-events: none;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.dots > * {
|
|
54
|
+
pointer-events: auto;
|
|
55
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
.dots {
|
|
2
|
+
display: flex;
|
|
3
|
+
align-items: center;
|
|
4
|
+
justify-content: center;
|
|
5
|
+
gap: var(--sv-space-2);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.dot {
|
|
9
|
+
/* A 6px visible dot is too small a hit target on its own — the button's
|
|
10
|
+
real box is larger (20px) with the dot itself painted by ::before and
|
|
11
|
+
centered inside, so tap area grows without changing the visible dot
|
|
12
|
+
size or the row's gap-based spacing math. */
|
|
13
|
+
position: relative;
|
|
14
|
+
width: 20px;
|
|
15
|
+
height: 20px;
|
|
16
|
+
padding: 0;
|
|
17
|
+
border: none;
|
|
18
|
+
background: transparent;
|
|
19
|
+
cursor: pointer;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.dot::before {
|
|
23
|
+
content: '';
|
|
24
|
+
position: absolute;
|
|
25
|
+
top: 50%;
|
|
26
|
+
left: 50%;
|
|
27
|
+
width: 6px;
|
|
28
|
+
height: 6px;
|
|
29
|
+
border-radius: 50%;
|
|
30
|
+
background: var(--sv-color-border-strong);
|
|
31
|
+
transform: translate(-50%, -50%);
|
|
32
|
+
transition: background 0.15s ease;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.dot:focus-visible {
|
|
36
|
+
outline: 2px solid var(--sv-color-focus-ring);
|
|
37
|
+
outline-offset: 2px;
|
|
38
|
+
border-radius: 50%;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.dotActive::before {
|
|
42
|
+
background: var(--sv-color-text-primary);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
@media (hover: hover) {
|
|
46
|
+
.dot:not(.dotActive):hover::before {
|
|
47
|
+
background: var(--sv-color-text-muted);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
.header,
|
|
2
|
+
.footer {
|
|
3
|
+
flex: 0 0 auto;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.body {
|
|
7
|
+
flex: 1 1 auto;
|
|
8
|
+
min-height: 0; /* allow shrinking inside the slide's flex column, so it can scroll instead of overflowing */
|
|
9
|
+
overflow-y: auto;
|
|
10
|
+
overflow-x: hidden;
|
|
11
|
+
/* Deliberately does NOT set touch-action: pan-y here. touch-action's
|
|
12
|
+
effective value is the INTERSECTION of this element's and every
|
|
13
|
+
ancestor's value (docs/architecture-rules.md) — the ancestor .scroller
|
|
14
|
+
(SwipableMobileCarousel.module.css) needs the horizontal swipe gesture,
|
|
15
|
+
so pan-y here ∩ that horizontal handling would resolve to neither axis
|
|
16
|
+
working natively. Relying on the browser's default touch-action (auto)
|
|
17
|
+
here lets native gesture arbitration between the two nested scrollers
|
|
18
|
+
sort out which axis wins per-gesture — don't "fix" perceived nested-
|
|
19
|
+
scroll jank by adding pan-y; it silently breaks horizontal swipe instead. */
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.loading {
|
|
23
|
+
display: flex;
|
|
24
|
+
align-items: center;
|
|
25
|
+
justify-content: center;
|
|
26
|
+
height: 100%;
|
|
27
|
+
color: var(--sv-color-text-subtle);
|
|
28
|
+
font-size: var(--sv-font-size-sm);
|
|
29
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/* Horizontal scroll container — masked-edge fade + hidden scrollbar, same
|
|
2
|
+
technique as NavTabs. Always active (not gated to a narrow viewport):
|
|
3
|
+
unlike NavTabs' item count, a table's column count is content-driven and
|
|
4
|
+
can overflow at any screen size. */
|
|
5
|
+
.scrollContainer {
|
|
6
|
+
overflow-x: auto;
|
|
7
|
+
scrollbar-width: none;
|
|
8
|
+
-webkit-overflow-scrolling: touch;
|
|
9
|
+
mask-image: linear-gradient(to right, black calc(100% - 32px), transparent 100%);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.scrollContainer::-webkit-scrollbar {
|
|
13
|
+
display: none;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.table {
|
|
17
|
+
width: 100%;
|
|
18
|
+
border-collapse: collapse;
|
|
19
|
+
font-size: var(--sv-font-size-sm);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.head .row {
|
|
23
|
+
border-bottom: 1px solid var(--sv-color-border-strong);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.body .row {
|
|
27
|
+
border-bottom: 1px solid var(--sv-color-border);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.body .row:last-child {
|
|
31
|
+
border-bottom: none;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.th {
|
|
35
|
+
padding: var(--sv-space-2) var(--sv-space-3);
|
|
36
|
+
text-align: left;
|
|
37
|
+
font-weight: var(--sv-font-weight-semibold);
|
|
38
|
+
color: var(--sv-color-text-muted);
|
|
39
|
+
white-space: nowrap;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.td {
|
|
43
|
+
padding: var(--sv-space-2) var(--sv-space-3);
|
|
44
|
+
color: var(--sv-color-text-primary);
|
|
45
|
+
}
|
package/dist/Tabs.module.css
CHANGED
|
@@ -12,7 +12,12 @@
|
|
|
12
12
|
|
|
13
13
|
.tab {
|
|
14
14
|
flex-shrink: 0;
|
|
15
|
-
|
|
15
|
+
/* 36px rendered height, matching this scale's other 36px controls (Input,
|
|
16
|
+
Select). Vertical padding hardcoded to hit the exact height, same
|
|
17
|
+
reasoning as Button — accounting for the 2px border-bottom below,
|
|
18
|
+
which (content-box) adds to the rendered height on top of font-size +
|
|
19
|
+
padding. */
|
|
20
|
+
padding: 10px var(--sv-space-4);
|
|
16
21
|
border: none;
|
|
17
22
|
border-bottom: 2px solid transparent;
|
|
18
23
|
/* Negative margin pulls the 2px border flush with the tablist border-bottom */
|
package/dist/Toggle.module.css
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
.track {
|
|
2
|
-
/* 38×22px pill — spec dimensions
|
|
2
|
+
/* 38×22px pill — spec dimensions. Sizing audit: despite the component
|
|
3
|
+
name, this renders as a binary pill switch (role="switch"), not a
|
|
4
|
+
pressable toggle button — reviewed against this scale's other compact
|
|
5
|
+
controls with that in mind. Kept dimensions unchanged, generously
|
|
6
|
+
sized for touch-friendliness. (The name vs. actual behavior mismatch
|
|
7
|
+
is a separate, pre-existing naming note, not addressed here.) */
|
|
3
8
|
display: inline-flex;
|
|
4
9
|
align-items: center;
|
|
5
10
|
width: 38px;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
.h1 {
|
|
2
|
+
margin: 0;
|
|
3
|
+
font-size: var(--sv-font-size-2xl);
|
|
4
|
+
font-weight: var(--sv-font-weight-semibold);
|
|
5
|
+
color: var(--sv-color-text-primary);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.h2 {
|
|
9
|
+
margin: 0;
|
|
10
|
+
font-size: var(--sv-font-size-xl);
|
|
11
|
+
font-weight: var(--sv-font-weight-semibold);
|
|
12
|
+
color: var(--sv-color-text-primary);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.h3 {
|
|
16
|
+
margin: 0;
|
|
17
|
+
font-size: var(--sv-font-size-lg);
|
|
18
|
+
font-weight: var(--sv-font-weight-semibold);
|
|
19
|
+
color: var(--sv-color-text-primary);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.h4 {
|
|
23
|
+
margin: 0;
|
|
24
|
+
font-size: var(--sv-font-size-md);
|
|
25
|
+
font-weight: var(--sv-font-weight-semibold);
|
|
26
|
+
color: var(--sv-color-text-primary);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.body {
|
|
30
|
+
margin: 0;
|
|
31
|
+
font-size: var(--sv-font-size-sm);
|
|
32
|
+
color: var(--sv-color-text-primary);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.caption {
|
|
36
|
+
margin: 0;
|
|
37
|
+
font-size: var(--sv-font-size-caption);
|
|
38
|
+
color: var(--sv-color-text-muted);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.label {
|
|
42
|
+
font-size: var(--sv-font-size-label);
|
|
43
|
+
font-weight: var(--sv-font-weight-semibold);
|
|
44
|
+
color: var(--sv-color-text-muted);
|
|
45
|
+
text-transform: uppercase;
|
|
46
|
+
letter-spacing: 0.04em;
|
|
47
|
+
}
|