@greese/ui 0.0.0-stage → 1.0.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/LICENSE +21 -0
- package/README.md +55 -2
- package/bin/greese-utilities.mjs +56 -0
- package/dist/_layers.scss +2 -0
- package/dist/_maps.scss +1884 -0
- package/dist/_tokens-base.scss +174 -0
- package/dist/_tokens.scss +2140 -0
- package/dist/base.css +67 -0
- package/dist/colorScheme.d.ts +16 -0
- package/dist/colorScheme.js +13 -0
- package/dist/contrast.d.ts +15 -0
- package/dist/contrast.js +43 -0
- package/dist/css/Accordion.css +9 -0
- package/dist/css/ActionSelect.css +6 -0
- package/dist/css/Alert.css +84 -0
- package/dist/css/AppBar.css +35 -0
- package/dist/css/AspectRatio.css +40 -0
- package/dist/css/AutoLayout.css +508 -0
- package/dist/css/Avatar.css +88 -0
- package/dist/css/Badge.css +66 -0
- package/dist/css/Box.css +640 -0
- package/dist/css/Breadcrumbs.css +57 -0
- package/dist/css/Button.css +275 -0
- package/dist/css/ButtonGroup.css +40 -0
- package/dist/css/Card.css +101 -0
- package/dist/css/Carousel.css +170 -0
- package/dist/css/Center.css +11 -0
- package/dist/css/ChatBubble.css +128 -0
- package/dist/css/Checkbox.css +65 -0
- package/dist/css/Chip.css +124 -0
- package/dist/css/ChoiceGroup.css +57 -0
- package/dist/css/Code.css +29 -0
- package/dist/css/Collapsible.css +126 -0
- package/dist/css/ColorPicker.css +191 -0
- package/dist/css/Combobox.css +90 -0
- package/dist/css/Container.css +30 -0
- package/dist/css/Countdown.css +25 -0
- package/dist/css/DateField.css +15 -0
- package/dist/css/Dialog.css +640 -0
- package/dist/css/Diff.css +103 -0
- package/dist/css/Divider.css +19 -0
- package/dist/css/Dock.css +91 -0
- package/dist/css/Field.css +33 -0
- package/dist/css/Fieldset.css +54 -0
- package/dist/css/FileInput.css +65 -0
- package/dist/css/Footer.css +72 -0
- package/dist/css/Grid.css +998 -0
- package/dist/css/Header.css +89 -0
- package/dist/css/Heading.css +6 -0
- package/dist/css/Icon.css +12 -0
- package/dist/css/IconButton.css +7 -0
- package/dist/css/Image.css +69 -0
- package/dist/css/Indicator.css +41 -0
- package/dist/css/Input.css +115 -0
- package/dist/css/Key.css +42 -0
- package/dist/css/Link.css +72 -0
- package/dist/css/List.css +52 -0
- package/dist/css/Media.css +8 -0
- package/dist/css/Menu.css +161 -0
- package/dist/css/Motion.css +1356 -0
- package/dist/css/NumberField.css +49 -0
- package/dist/css/OtpField.css +90 -0
- package/dist/css/PageTransition.css +979 -0
- package/dist/css/Pagination.css +43 -0
- package/dist/css/Popover.css +93 -0
- package/dist/css/Progress.css +101 -0
- package/dist/css/RadialProgress.css +44 -0
- package/dist/css/Radio.css +41 -0
- package/dist/css/Rating.css +100 -0
- package/dist/css/ScrollSpy.css +6 -0
- package/dist/css/SegmentedControl.css +101 -0
- package/dist/css/Select.css +115 -0
- package/dist/css/Sidebar.css +207 -0
- package/dist/css/Skeleton.css +48 -0
- package/dist/css/Slider.css +75 -0
- package/dist/css/Spacer.css +34 -0
- package/dist/css/SpeedDial.css +165 -0
- package/dist/css/Spinner.css +44 -0
- package/dist/css/Stack.css +528 -0
- package/dist/css/Stat.css +107 -0
- package/dist/css/Status.css +86 -0
- package/dist/css/Steps.css +201 -0
- package/dist/css/Swap.css +49 -0
- package/dist/css/Switch.css +66 -0
- package/dist/css/Table.css +269 -0
- package/dist/css/Tabs.css +119 -0
- package/dist/css/Text.css +60 -0
- package/dist/css/TextRotate.css +147 -0
- package/dist/css/Textarea.css +107 -0
- package/dist/css/ThemeProvider.css +6 -0
- package/dist/css/Tile.css +18 -0
- package/dist/css/Toast.css +110 -0
- package/dist/css/ToggleButton.css +20 -0
- package/dist/css/Tooltip.css +94 -0
- package/dist/css/Type.css +211 -0
- package/dist/css/Visibility.css +78 -0
- package/dist/css/VisuallyHidden.css +15 -0
- package/dist/css/core.css +251 -0
- package/dist/css.d.ts +29 -0
- package/dist/css.js +28 -0
- package/dist/effect-classes.d.ts +8 -0
- package/dist/effect-classes.js +5 -0
- package/dist/effects/css.d.ts +71 -0
- package/dist/effects/css.js +184 -0
- package/dist/effects/definitions.d.ts +555 -0
- package/dist/effects/definitions.js +379 -0
- package/dist/effects/frames.d.ts +18 -0
- package/dist/effects/frames.js +68 -0
- package/dist/effects/sequence.d.ts +33 -0
- package/dist/effects/sequence.js +106 -0
- package/dist/effects.d.ts +30 -0
- package/dist/effects.js +30 -0
- package/dist/greese.css +11907 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +10 -0
- package/dist/kebab.d.ts +2 -0
- package/dist/kebab.js +2 -0
- package/dist/palette.css +249 -0
- package/dist/palette.d.ts +599 -0
- package/dist/palette.js +334 -0
- package/dist/shapes.d.ts +193 -0
- package/dist/shapes.js +852 -0
- package/dist/storage.d.ts +47 -0
- package/dist/storage.js +118 -0
- package/dist/style-manifest.json +3010 -0
- package/dist/theme.d.ts +71 -0
- package/dist/theme.js +180 -0
- package/dist/tokens.css +253 -0
- package/dist/tokens.d.ts +343 -0
- package/dist/tokens.js +179 -0
- package/dist/typography.d.ts +55 -0
- package/dist/typography.js +144 -0
- package/dist/utilities.css +6975 -0
- package/dist/utilities.d.ts +82 -0
- package/dist/utilities.js +636 -0
- package/dist/utilitiesFiles.d.ts +18 -0
- package/dist/utilitiesFiles.js +26 -0
- package/dist/vite.d.ts +40 -0
- package/dist/vite.js +43 -0
- package/package.json +131 -4
- package/src/components/Accordion/Accordion.scss +9 -0
- package/src/components/ActionSelect/ActionSelect.scss +6 -0
- package/src/components/Alert/Alert.scss +71 -0
- package/src/components/AppBar/AppBar.scss +43 -0
- package/src/components/AspectRatio/AspectRatio.scss +22 -0
- package/src/components/AutoLayout/AutoLayout.scss +90 -0
- package/src/components/Avatar/Avatar.scss +91 -0
- package/src/components/Badge/Badge.scss +52 -0
- package/src/components/Box/Box.scss +63 -0
- package/src/components/Breadcrumbs/Breadcrumbs.scss +59 -0
- package/src/components/Button/Button.scss +231 -0
- package/src/components/ButtonGroup/ButtonGroup.scss +56 -0
- package/src/components/Card/Card.scss +99 -0
- package/src/components/Carousel/Carousel.scss +161 -0
- package/src/components/Center/Center.scss +11 -0
- package/src/components/ChatBubble/ChatBubble.scss +119 -0
- package/src/components/Checkbox/Checkbox.scss +66 -0
- package/src/components/Chip/Chip.scss +119 -0
- package/src/components/ChoiceGroup/ChoiceGroup.scss +69 -0
- package/src/components/Code/Code.scss +28 -0
- package/src/components/Collapsible/Collapsible.scss +136 -0
- package/src/components/ColorPicker/ColorPicker.scss +235 -0
- package/src/components/Combobox/Combobox.scss +83 -0
- package/src/components/Container/Container.scss +28 -0
- package/src/components/Countdown/Countdown.scss +28 -0
- package/src/components/DateField/DateField.scss +19 -0
- package/src/components/Dialog/Dialog.scss +268 -0
- package/src/components/Diff/Diff.scss +125 -0
- package/src/components/Divider/Divider.scss +22 -0
- package/src/components/Dock/Dock.scss +86 -0
- package/src/components/Field/Field.scss +38 -0
- package/src/components/Fieldset/Fieldset.scss +63 -0
- package/src/components/FileInput/FileInput.scss +66 -0
- package/src/components/Footer/Footer.scss +79 -0
- package/src/components/Grid/Grid.scss +86 -0
- package/src/components/Header/Header.scss +111 -0
- package/src/components/Heading/Heading.scss +7 -0
- package/src/components/Icon/Icon.scss +12 -0
- package/src/components/IconButton/IconButton.scss +6 -0
- package/src/components/Image/Image.scss +46 -0
- package/src/components/Indicator/Indicator.scss +48 -0
- package/src/components/Input/Input.scss +58 -0
- package/src/components/Key/Key.scss +48 -0
- package/src/components/Link/Link.scss +50 -0
- package/src/components/List/List.scss +62 -0
- package/src/components/Media/Media.scss +7 -0
- package/src/components/Menu/Menu.scss +91 -0
- package/src/components/Motion/Motion.scss +106 -0
- package/src/components/NumberField/NumberField.scss +44 -0
- package/src/components/OtpField/OtpField.scss +91 -0
- package/src/components/PageTransition/PageTransition.scss +168 -0
- package/src/components/Pagination/Pagination.scss +55 -0
- package/src/components/Popover/Popover.scss +13 -0
- package/src/components/Progress/Progress.scss +126 -0
- package/src/components/RadialProgress/RadialProgress.scss +65 -0
- package/src/components/Radio/Radio.scss +36 -0
- package/src/components/Rating/Rating.scss +121 -0
- package/src/components/ScrollSpy/ScrollSpy.scss +6 -0
- package/src/components/SegmentedControl/SegmentedControl.scss +107 -0
- package/src/components/Select/Select.scss +59 -0
- package/src/components/Sidebar/Sidebar.scss +88 -0
- package/src/components/Skeleton/Skeleton.scss +60 -0
- package/src/components/Slider/Slider.scss +96 -0
- package/src/components/Spacer/Spacer.scss +15 -0
- package/src/components/SpeedDial/SpeedDial.scss +109 -0
- package/src/components/Spinner/Spinner.scss +43 -0
- package/src/components/Stack/Stack.scss +57 -0
- package/src/components/Stat/Stat.scss +96 -0
- package/src/components/Status/Status.scss +60 -0
- package/src/components/Steps/Steps.scss +216 -0
- package/src/components/Swap/Swap.scss +62 -0
- package/src/components/Switch/Switch.scss +63 -0
- package/src/components/Table/Table.scss +183 -0
- package/src/components/Tabs/Tabs.scss +108 -0
- package/src/components/Text/Text.scss +34 -0
- package/src/components/TextRotate/TextRotate.scss +51 -0
- package/src/components/Textarea/Textarea.scss +56 -0
- package/src/components/ThemeProvider/ThemeProvider.scss +7 -0
- package/src/components/Tile/Tile.scss +23 -0
- package/src/components/Toast/Toast.scss +93 -0
- package/src/components/ToggleButton/ToggleButton.scss +23 -0
- package/src/components/Tooltip/Tooltip.scss +21 -0
- package/src/components/Type/Type.scss +35 -0
- package/src/components/Visibility/Visibility.scss +39 -0
- package/src/components/VisuallyHidden/VisuallyHidden.scss +17 -0
- package/src/styles/_breakpoint-vars.scss +16 -0
- package/src/styles/_config.scss +48 -0
- package/src/styles/_controls.scss +88 -0
- package/src/styles/_core.scss +4 -0
- package/src/styles/_effect.scss +51 -0
- package/src/styles/_floating.scss +141 -0
- package/src/styles/_kit.scss +1548 -0
- package/src/styles/_manifest.scss +670 -0
- package/src/styles/_mixins.scss +261 -0
- package/src/styles/_tones.scss +63 -0
- package/src/styles/_type-emit.scss +76 -0
- package/src/styles/_typography-vars.scss +8 -0
- package/src/styles/base.scss +80 -0
- package/src/styles/breakpoints.test.ts +73 -0
- package/src/styles/entryPoints.test.ts +68 -0
- package/src/styles/index.scss +93 -0
- package/src/styles/kit.test.ts +754 -0
- package/src/styles/public/_controls.scss +3 -0
- package/src/styles/public/_floating.scss +3 -0
- package/src/styles/public/_mixins.scss +5 -0
- package/src/styles/public/_tones.scss +4 -0
- package/themes/bevel.css +1077 -0
- package/themes/bevel.scss +1166 -0
- package/themes/depth.css +123 -0
- package/themes/depth.scss +46 -0
- package/themes/extrude.css +219 -0
- package/themes/extrude.scss +255 -0
- package/themes/folio.css +986 -0
- package/themes/folio.scss +1047 -0
- package/themes/gentle.css +66 -0
- package/themes/gentle.scss +39 -0
- package/themes/outline.css +127 -0
- package/themes/outline.scss +126 -0
- package/themes/pebble.css +65 -0
- package/themes/pebble.scss +69 -0
- package/themes/pocket.css +137 -0
- package/themes/pocket.scss +45 -0
- package/themes/ridge.css +927 -0
- package/themes/ridge.scss +998 -0
- package/themes/snappy.css +82 -0
- package/themes/snappy.scss +40 -0
- package/themes/soft.css +79 -0
- package/themes/soft.scss +84 -0
- package/themes/ticket.css +960 -0
- package/themes/ticket.scss +1031 -0
- package/themes/tilt.css +148 -0
- package/themes/tilt.scss +169 -0
- package/themes/wipe.css +186 -0
- package/themes/wipe.scss +46 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
// Page transitions (ADR 0029): greese effects played on the snapshots of a
|
|
2
|
+
// view transition. React's <ViewTransition> (or a page's own
|
|
3
|
+
// `view-transition-class`) names the classes below; the browser snapshots
|
|
4
|
+
// the old and new page, and these rules animate `::view-transition-old`
|
|
5
|
+
// (the page leaving) and `::view-transition-new` (the page arriving):
|
|
6
|
+
// greese-PageTransition every greese snapshot: the timing
|
|
7
|
+
// greese-PageTransition--theme the motion theme's page roles
|
|
8
|
+
// greese-PageTransition--theme-back the same, going back
|
|
9
|
+
// greese-PageTransition--enter-<name> an entrance on the new snapshot
|
|
10
|
+
// greese-PageTransition--exit-<name> an exit on the old snapshot
|
|
11
|
+
// greese-PageTransition--enter-none, --exit-none that side doesn't animate
|
|
12
|
+
// greese-PageTransition--share a shared element's morph (its group)
|
|
13
|
+
// greese-PageTransition--still not animated at all
|
|
14
|
+
// greese-PageTransition--page a whole page: only its screenful shows
|
|
15
|
+
// greese-PageTransition--left a page that left live: its rest fades
|
|
16
|
+
// Transition types (`greese-back`, …) pick between these classes in React's
|
|
17
|
+
// <ViewTransition> props, which works wherever React does; the CSS doesn't
|
|
18
|
+
// depend on `:active-view-transition-type()`. Entrances play the effects' own
|
|
19
|
+
// `@keyframes` (Motion.scss); exits play the `leave` keyframes written here.
|
|
20
|
+
// Every snapshot rule starts with `html`: the pseudo-elements belong to the
|
|
21
|
+
// root, and a selector with nothing before `::view-transition-*` is tried
|
|
22
|
+
// against every element at every style recalculation (it cost the homepage
|
|
23
|
+
// about 15 ms of blocking time; ADR 0029). With `html`, only the root.
|
|
24
|
+
// Every rule sits behind `prefers-reduced-motion: no-preference`, and under
|
|
25
|
+
// `reduce` greese snapshots don't animate: React doesn't honour it for view
|
|
26
|
+
// transitions, so this does.
|
|
27
|
+
|
|
28
|
+
@use 'sass:map';
|
|
29
|
+
@use '../../../dist/maps' as defaults;
|
|
30
|
+
@use '../../styles/effect';
|
|
31
|
+
|
|
32
|
+
@layer greese.utilities {
|
|
33
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
34
|
+
// The page's pacing: the theme's `page-duration` and `page-ease`, or a
|
|
35
|
+
// normal duration on the library's ease out. `both`: the old snapshot holds
|
|
36
|
+
// where its exit ends until the transition is over.
|
|
37
|
+
html::view-transition-old(*.greese-PageTransition),
|
|
38
|
+
html::view-transition-new(*.greese-PageTransition) {
|
|
39
|
+
animation-fill-mode: both;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// The group (where the pair moves and resizes) keeps the same pace as its
|
|
43
|
+
// snapshots, or it would morph at the browser's own 250 ms.
|
|
44
|
+
html::view-transition-group(*.greese-PageTransition),
|
|
45
|
+
html::view-transition-old(*.greese-PageTransition),
|
|
46
|
+
html::view-transition-new(*.greese-PageTransition) {
|
|
47
|
+
animation-duration: var(
|
|
48
|
+
--greese-motion-page-duration,
|
|
49
|
+
var(--greese-duration-normal)
|
|
50
|
+
);
|
|
51
|
+
animation-timing-function: var(--greese-motion-page-ease, var(--greese-ease-out));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// The theme's page roles (`motion-defaults()`), a cross-fade without them.
|
|
55
|
+
html::view-transition-new(*.greese-PageTransition--theme) {
|
|
56
|
+
animation-name: var(--greese-motion-page, greese-fade-in);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
html::view-transition-old(*.greese-PageTransition--theme) {
|
|
60
|
+
animation-name: var(--greese-motion-page-exit, greese-fade-out);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
html::view-transition-new(*.greese-PageTransition--theme-back) {
|
|
64
|
+
animation-name: var(
|
|
65
|
+
--greese-motion-page-back,
|
|
66
|
+
var(--greese-motion-page, greese-fade-in)
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
html::view-transition-old(*.greese-PageTransition--theme-back) {
|
|
71
|
+
animation-name: var(
|
|
72
|
+
--greese-motion-page-back-exit,
|
|
73
|
+
var(--greese-motion-page-exit, greese-fade-out)
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// A named effect, after the theme's rules so it wins where both are set.
|
|
78
|
+
@each $name, $plan in defaults.$effects {
|
|
79
|
+
@if map.get($plan, enter) {
|
|
80
|
+
html::view-transition-new(*.greese-PageTransition--enter-#{$name}) {
|
|
81
|
+
animation-name: greese-#{$name};
|
|
82
|
+
}
|
|
83
|
+
} @else {
|
|
84
|
+
html::view-transition-old(*.greese-PageTransition--exit-#{$name}) {
|
|
85
|
+
animation-name: greese-#{$name};
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// One side still while the other plays (`enter: 'none'` or `exit: 'none'`).
|
|
91
|
+
html::view-transition-new(*.greese-PageTransition--enter-none),
|
|
92
|
+
html::view-transition-old(*.greese-PageTransition--exit-none) {
|
|
93
|
+
animation-name: none;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// A shared element morphs from where it was to where it is: its group
|
|
97
|
+
// moves and resizes, at the theme's `share-duration` and `share-ease`.
|
|
98
|
+
html::view-transition-group(*.greese-PageTransition--share) {
|
|
99
|
+
animation-duration: var(
|
|
100
|
+
--greese-motion-share-duration,
|
|
101
|
+
var(--greese-motion-page-duration, var(--greese-duration-normal))
|
|
102
|
+
);
|
|
103
|
+
animation-timing-function: var(
|
|
104
|
+
--greese-motion-share-ease,
|
|
105
|
+
var(--greese-motion-page-ease, var(--greese-ease-out))
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// A page left live: its exit has played on the real page, so what's left
|
|
110
|
+
// of it (backgrounds, anything that isn't a member) fades beneath the new
|
|
111
|
+
// page's entrance. After the effects, so it wins over any exit it's
|
|
112
|
+
// joined with.
|
|
113
|
+
html::view-transition-old(*.greese-PageTransition--left) {
|
|
114
|
+
animation-name: greese-fade-out;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// A whole page is snapshotted whole, however tall, and an effect sized by
|
|
118
|
+
// its box (a pocket's 100%, a pop about its middle, a flip's axis) would
|
|
119
|
+
// play mostly off screen. Its snapshots show only the screenful in view,
|
|
120
|
+
// so the effects are sized by that: the new page from its top (it's
|
|
121
|
+
// scrolled there first), the old one from where the screen was on it
|
|
122
|
+
// (`--greese-page-scrolled`, which usePageNavigate measures at the click).
|
|
123
|
+
// Hidden from behind: a page turned half over (`flipOver…`) shows the
|
|
124
|
+
// other page on its back, not its own mirror image.
|
|
125
|
+
html::view-transition-old(*.greese-PageTransition--page),
|
|
126
|
+
html::view-transition-new(*.greese-PageTransition--page) {
|
|
127
|
+
backface-visibility: hidden;
|
|
128
|
+
block-size: min(100%, 100dvh);
|
|
129
|
+
object-fit: none;
|
|
130
|
+
object-position: 50% 0;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
html::view-transition-old(*.greese-PageTransition--page) {
|
|
134
|
+
inset-block-start: var(--greese-page-scrolled, 0);
|
|
135
|
+
object-position: 50% calc(-1 * var(--greese-page-scrolled, 0px));
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// The exits' keyframes, from rest to where each ends (src/effects.ts).
|
|
139
|
+
@each $name, $plan in defaults.$effects {
|
|
140
|
+
@if not map.get($plan, enter) {
|
|
141
|
+
@include effect.keyframes($name, $plan, $leave: true);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Kept in place: a header or footer the page change leaves alone, and every
|
|
147
|
+
// greese snapshot under reduced motion, where the page simply changes.
|
|
148
|
+
html::view-transition-group(*.greese-PageTransition--still),
|
|
149
|
+
html::view-transition-old(*.greese-PageTransition--still),
|
|
150
|
+
html::view-transition-new(*.greese-PageTransition--still) {
|
|
151
|
+
animation: none;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// And on top: the page moves beneath what stays, as it scrolls beneath a
|
|
155
|
+
// sticky header, rather than over it. Groups otherwise stack in the
|
|
156
|
+
// document's order, which puts the page over a header that comes first.
|
|
157
|
+
html::view-transition-group(*.greese-PageTransition--still) {
|
|
158
|
+
z-index: 1;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
@media (prefers-reduced-motion: reduce) {
|
|
162
|
+
html::view-transition-group(*.greese-PageTransition),
|
|
163
|
+
html::view-transition-old(*.greese-PageTransition),
|
|
164
|
+
html::view-transition-new(*.greese-PageTransition) {
|
|
165
|
+
animation: none;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
@use '../../styles/mixins';
|
|
2
|
+
|
|
3
|
+
@layer greese.components {
|
|
4
|
+
.greese-Pagination-list {
|
|
5
|
+
display: flex;
|
|
6
|
+
flex-wrap: wrap;
|
|
7
|
+
gap: var(--greese-space-1);
|
|
8
|
+
align-items: center;
|
|
9
|
+
padding: 0;
|
|
10
|
+
margin: 0;
|
|
11
|
+
list-style: none;
|
|
12
|
+
|
|
13
|
+
.greese-Button {
|
|
14
|
+
min-inline-size: 2rem;
|
|
15
|
+
font-variant-numeric: tabular-nums;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.greese-Pagination-step {
|
|
20
|
+
padding-inline: var(--greese-space-2);
|
|
21
|
+
|
|
22
|
+
> svg,
|
|
23
|
+
.greese-Button-icon > svg {
|
|
24
|
+
inline-size: 1.1em;
|
|
25
|
+
block-size: 1.1em;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// The chevron points to the inline start; flip it for "next", and mirror
|
|
30
|
+
// both in right-to-left.
|
|
31
|
+
.greese-Pagination-step--next svg {
|
|
32
|
+
scale: -1 1;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.greese-Pagination:dir(rtl) .greese-Pagination-step svg {
|
|
36
|
+
scale: -1 1;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.greese-Pagination:dir(rtl) .greese-Pagination-step--next svg {
|
|
40
|
+
scale: 1;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.greese-Pagination-ellipsis {
|
|
44
|
+
padding-inline: var(--greese-space-1);
|
|
45
|
+
color: var(--greese-color-fg-muted);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Phones: only previous, the current page and next.
|
|
49
|
+
@include mixins.down(sm) {
|
|
50
|
+
.greese-Pagination-page:not(.greese-Pagination-page--current),
|
|
51
|
+
.greese-Pagination-ellipsis {
|
|
52
|
+
display: none;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
@use '../../styles/floating';
|
|
2
|
+
|
|
3
|
+
@layer greese.components {
|
|
4
|
+
.greese-Popover {
|
|
5
|
+
@include floating.anchored;
|
|
6
|
+
@include floating.surface;
|
|
7
|
+
@include floating.enter-exit(':popover-open', 0 -0.25rem, popover);
|
|
8
|
+
|
|
9
|
+
inline-size: max-content;
|
|
10
|
+
max-inline-size: min(22rem, 100vw - 2 * var(--greese-space-3));
|
|
11
|
+
padding: var(--greese-space-4);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
@use '../../styles/mixins';
|
|
2
|
+
|
|
3
|
+
$sizes: (
|
|
4
|
+
xs: 0.125rem,
|
|
5
|
+
sm: 0.25rem,
|
|
6
|
+
md: 0.5rem,
|
|
7
|
+
lg: 0.75rem,
|
|
8
|
+
xl: 1rem,
|
|
9
|
+
);
|
|
10
|
+
|
|
11
|
+
/* stylelint-disable selector-no-vendor-prefix */
|
|
12
|
+
|
|
13
|
+
@layer greese.components {
|
|
14
|
+
.greese-Progress {
|
|
15
|
+
@include mixins.component-root;
|
|
16
|
+
|
|
17
|
+
display: block;
|
|
18
|
+
inline-size: 100%;
|
|
19
|
+
block-size: var(--greese-progress-height);
|
|
20
|
+
overflow: hidden;
|
|
21
|
+
color: var(--greese-color-primary);
|
|
22
|
+
background-color: var(--greese-color-track);
|
|
23
|
+
border: 0;
|
|
24
|
+
border-radius: var(--greese-corner-pill);
|
|
25
|
+
appearance: none;
|
|
26
|
+
|
|
27
|
+
&::-webkit-progress-bar {
|
|
28
|
+
background-color: var(--greese-color-track);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
&::-webkit-progress-value {
|
|
32
|
+
background-color: var(--greese-color-primary);
|
|
33
|
+
border-radius: var(--greese-corner-pill);
|
|
34
|
+
transition: inline-size var(--greese-duration-normal) var(--greese-easing-standard);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
&::-moz-progress-bar {
|
|
38
|
+
background-color: var(--greese-color-primary);
|
|
39
|
+
border-radius: var(--greese-corner-pill);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Indeterminate: a band sweeping across.
|
|
43
|
+
&:indeterminate {
|
|
44
|
+
background-image: linear-gradient(
|
|
45
|
+
to right,
|
|
46
|
+
transparent 0%,
|
|
47
|
+
var(--greese-color-primary) 50%,
|
|
48
|
+
transparent 100%
|
|
49
|
+
);
|
|
50
|
+
background-repeat: no-repeat;
|
|
51
|
+
background-size: 40% 100%;
|
|
52
|
+
|
|
53
|
+
@include mixins.motion-safe {
|
|
54
|
+
animation: greese-progress-sweep 1.2s var(--greese-easing-standard) infinite;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
&:indeterminate::-webkit-progress-bar {
|
|
59
|
+
background-color: transparent;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
&:indeterminate::-moz-progress-bar {
|
|
63
|
+
background-color: transparent;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Loading: the filled part striped on the diagonal, in the value's and the
|
|
68
|
+
// track's colors, running toward the end. A stripe pair is a square tile
|
|
69
|
+
// twice the bar's height, so the stripes stay at 45° at any thickness.
|
|
70
|
+
.greese-Progress--loading {
|
|
71
|
+
--greese-progress-stripes: linear-gradient(
|
|
72
|
+
-45deg,
|
|
73
|
+
var(--greese-color-primary) 25%,
|
|
74
|
+
var(--greese-color-track) 25% 50%,
|
|
75
|
+
var(--greese-color-primary) 50% 75%,
|
|
76
|
+
var(--greese-color-track) 75%
|
|
77
|
+
);
|
|
78
|
+
--greese-progress-tile: max(0.5rem, 2 * var(--greese-progress-height));
|
|
79
|
+
|
|
80
|
+
&::-webkit-progress-value {
|
|
81
|
+
background-image: var(--greese-progress-stripes);
|
|
82
|
+
background-size: var(--greese-progress-tile) var(--greese-progress-tile);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
&::-moz-progress-bar {
|
|
86
|
+
background-image: var(--greese-progress-stripes);
|
|
87
|
+
background-size: var(--greese-progress-tile) var(--greese-progress-tile);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
@include mixins.motion-safe {
|
|
91
|
+
&::-webkit-progress-value {
|
|
92
|
+
animation: greese-progress-stripes 0.8s linear infinite;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
&::-moz-progress-bar {
|
|
96
|
+
animation: greese-progress-stripes 0.8s linear infinite;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
@keyframes greese-progress-stripes {
|
|
102
|
+
from {
|
|
103
|
+
background-position: 0 0;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
to {
|
|
107
|
+
background-position: var(--greese-progress-tile) 0;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
@each $size, $value in $sizes {
|
|
112
|
+
.greese-Progress--#{$size} {
|
|
113
|
+
--greese-progress-height: #{$value};
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
@keyframes greese-progress-sweep {
|
|
118
|
+
from {
|
|
119
|
+
background-position: -60% 0;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
to {
|
|
123
|
+
background-position: 160% 0;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
@use '../../styles/mixins';
|
|
2
|
+
|
|
3
|
+
// Registered so the ring animates between values. Read only by the ring
|
|
4
|
+
// itself (::before), so nothing inherits it.
|
|
5
|
+
@property --greese-radialprogress-angle {
|
|
6
|
+
syntax: '<percentage>';
|
|
7
|
+
inherits: false;
|
|
8
|
+
initial-value: 0%;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
@layer greese.components {
|
|
12
|
+
// A conic-gradient disc, masked to a ring.
|
|
13
|
+
.greese-RadialProgress {
|
|
14
|
+
@include mixins.component-root;
|
|
15
|
+
|
|
16
|
+
position: relative;
|
|
17
|
+
display: inline-grid;
|
|
18
|
+
flex-shrink: 0;
|
|
19
|
+
place-items: center;
|
|
20
|
+
inline-size: var(--greese-radialprogress-size, 4rem);
|
|
21
|
+
aspect-ratio: 1;
|
|
22
|
+
font-size: calc(var(--greese-radialprogress-size, 4rem) / 4.5);
|
|
23
|
+
font-weight: var(--greese-font-weight-semibold);
|
|
24
|
+
font-variant-numeric: tabular-nums;
|
|
25
|
+
color: var(--greese-color-fg);
|
|
26
|
+
|
|
27
|
+
&::before {
|
|
28
|
+
--greese-radialprogress-angle: calc(var(--greese-radialprogress-value) * 1%);
|
|
29
|
+
|
|
30
|
+
position: absolute;
|
|
31
|
+
inset: 0;
|
|
32
|
+
content: '';
|
|
33
|
+
background: conic-gradient(
|
|
34
|
+
var(--greese-color-primary) var(--greese-radialprogress-angle),
|
|
35
|
+
var(--greese-color-track) 0
|
|
36
|
+
);
|
|
37
|
+
border-radius: 50%;
|
|
38
|
+
|
|
39
|
+
// Only the mask's alpha matters; the color is any opaque one.
|
|
40
|
+
mask: radial-gradient(
|
|
41
|
+
farthest-side,
|
|
42
|
+
transparent calc(100% - var(--greese-radialprogress-thickness, 10%) - 0.5px),
|
|
43
|
+
var(--greese-color-fg) calc(100% - var(--greese-radialprogress-thickness, 10%))
|
|
44
|
+
);
|
|
45
|
+
transition: --greese-radialprogress-angle var(--greese-duration-slow)
|
|
46
|
+
var(--greese-easing-standard);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.greese-RadialProgress-label {
|
|
51
|
+
position: relative;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.greese-RadialProgress--indeterminate::before {
|
|
55
|
+
@include mixins.motion-safe {
|
|
56
|
+
animation: greese-radialprogress-spin 1s linear infinite;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
@keyframes greese-radialprogress-spin {
|
|
61
|
+
to {
|
|
62
|
+
rotate: 1turn;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
@use '../../styles/mixins';
|
|
2
|
+
|
|
3
|
+
@layer greese.components {
|
|
4
|
+
.greese-Radio-input {
|
|
5
|
+
@include mixins.touch-target;
|
|
6
|
+
|
|
7
|
+
position: relative;
|
|
8
|
+
inline-size: 1.125rem;
|
|
9
|
+
block-size: 1.125rem;
|
|
10
|
+
margin: 0;
|
|
11
|
+
cursor: pointer;
|
|
12
|
+
background-color: var(--greese-color-canvas);
|
|
13
|
+
border: 1.5px solid var(--greese-color-border-strong);
|
|
14
|
+
border-radius: var(--greese-corner-round);
|
|
15
|
+
appearance: none;
|
|
16
|
+
|
|
17
|
+
&:disabled {
|
|
18
|
+
cursor: not-allowed;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
transition:
|
|
22
|
+
border-color var(--greese-duration-fast) var(--greese-easing-standard),
|
|
23
|
+
border-width var(--greese-duration-fast) var(--greese-easing-standard);
|
|
24
|
+
|
|
25
|
+
@include mixins.focus-ring;
|
|
26
|
+
|
|
27
|
+
// A thick primary ring around the canvas centre reads as the dot.
|
|
28
|
+
&:checked {
|
|
29
|
+
border: 5px solid var(--greese-color-primary);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
&[aria-invalid='true']:not(:checked) {
|
|
33
|
+
border-color: var(--greese-color-negative);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
@use '../../styles/mixins';
|
|
2
|
+
|
|
3
|
+
$sizes: (
|
|
4
|
+
xs: 0.75rem,
|
|
5
|
+
sm: 1.125rem,
|
|
6
|
+
md: 1.625rem,
|
|
7
|
+
lg: 2rem,
|
|
8
|
+
xl: 3rem,
|
|
9
|
+
);
|
|
10
|
+
|
|
11
|
+
@layer greese.components {
|
|
12
|
+
.greese-Rating {
|
|
13
|
+
@include mixins.component-root;
|
|
14
|
+
|
|
15
|
+
--greese-rating-size: 1.5rem;
|
|
16
|
+
--greese-rating-on: var(--greese-color-warning);
|
|
17
|
+
--greese-rating-off: var(--greese-color-border-strong);
|
|
18
|
+
|
|
19
|
+
display: inline-flex;
|
|
20
|
+
flex-direction: column;
|
|
21
|
+
gap: var(--greese-space-1);
|
|
22
|
+
min-inline-size: 0;
|
|
23
|
+
padding: 0;
|
|
24
|
+
margin: 0;
|
|
25
|
+
border: 0;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
@each $size, $value in $sizes {
|
|
29
|
+
.greese-Rating--#{$size} {
|
|
30
|
+
--greese-rating-size: #{$value};
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// The stars: an empty row with a filled row over it, clipped to the value
|
|
35
|
+
// (--greese-rating-fill), so any fraction draws exactly.
|
|
36
|
+
.greese-Rating-items,
|
|
37
|
+
.greese-Rating-stars {
|
|
38
|
+
position: relative;
|
|
39
|
+
display: inline-grid;
|
|
40
|
+
inline-size: max-content;
|
|
41
|
+
|
|
42
|
+
> * {
|
|
43
|
+
grid-area: 1 / 1;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.greese-Rating-items {
|
|
48
|
+
cursor: pointer;
|
|
49
|
+
touch-action: none;
|
|
50
|
+
|
|
51
|
+
&:has(.greese-Rating-input:focus-visible) {
|
|
52
|
+
border-radius: var(--greese-corner-inset);
|
|
53
|
+
outline: 2px solid var(--greese-color-focus-ring);
|
|
54
|
+
outline-offset: 2px;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// At least 44px tall to touch: the slices share the stars' cell, so they
|
|
59
|
+
// stretch over this padding too.
|
|
60
|
+
@media (pointer: coarse) {
|
|
61
|
+
.greese-Rating-items > .greese-Rating-stars {
|
|
62
|
+
padding-block: max(0px, (44px - var(--greese-rating-size)) / 2);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.greese-Rating:disabled .greese-Rating-items {
|
|
67
|
+
cursor: not-allowed;
|
|
68
|
+
opacity: 0.55;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.greese-Rating-empty,
|
|
72
|
+
.greese-Rating-filled {
|
|
73
|
+
display: inline-flex;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.greese-Rating-filled {
|
|
77
|
+
clip-path: inset(0 calc(100% - var(--greese-rating-fill)) 0 0);
|
|
78
|
+
transition: clip-path var(--greese-duration-fast) var(--greese-easing-standard);
|
|
79
|
+
|
|
80
|
+
&:dir(rtl) {
|
|
81
|
+
clip-path: inset(0 0 0 calc(100% - var(--greese-rating-fill)));
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.greese-Rating-icon {
|
|
85
|
+
color: var(--greese-rating-on);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.greese-Rating-icon {
|
|
90
|
+
display: inline-flex;
|
|
91
|
+
inline-size: var(--greese-rating-size);
|
|
92
|
+
block-size: var(--greese-rating-size);
|
|
93
|
+
padding: 0.0625rem;
|
|
94
|
+
color: var(--greese-rating-off);
|
|
95
|
+
|
|
96
|
+
> svg {
|
|
97
|
+
inline-size: 100%;
|
|
98
|
+
block-size: 100%;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// One slice per choice over the stars: clicking a slice chooses it.
|
|
103
|
+
.greese-Rating-choices {
|
|
104
|
+
display: flex;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.greese-Rating-choice {
|
|
108
|
+
position: relative;
|
|
109
|
+
flex: 1;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.greese-Rating-input {
|
|
113
|
+
position: absolute;
|
|
114
|
+
inset: 0;
|
|
115
|
+
inline-size: 100%;
|
|
116
|
+
block-size: 100%;
|
|
117
|
+
margin: 0;
|
|
118
|
+
cursor: inherit;
|
|
119
|
+
opacity: 0;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
@use 'sass:map';
|
|
2
|
+
@use '../../styles/mixins';
|
|
3
|
+
@use '../../styles/controls';
|
|
4
|
+
|
|
5
|
+
@layer greese.components {
|
|
6
|
+
.greese-SegmentedControl {
|
|
7
|
+
@include mixins.component-root;
|
|
8
|
+
|
|
9
|
+
display: inline-block;
|
|
10
|
+
min-inline-size: 0;
|
|
11
|
+
padding: 0;
|
|
12
|
+
margin: 0;
|
|
13
|
+
border: 0;
|
|
14
|
+
|
|
15
|
+
> legend {
|
|
16
|
+
padding: 0;
|
|
17
|
+
margin-block-end: var(--greese-space-2);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.greese-SegmentedControl--full {
|
|
22
|
+
display: block;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.greese-SegmentedControl-track {
|
|
26
|
+
display: flex;
|
|
27
|
+
gap: 2px;
|
|
28
|
+
padding: 3px;
|
|
29
|
+
background-color: var(--greese-color-surface);
|
|
30
|
+
border: 1px solid var(--greese-color-border);
|
|
31
|
+
border-radius: var(--greese-corner-control);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Sizes
|
|
35
|
+
@each $size, $spec in controls.$sizes {
|
|
36
|
+
.greese-SegmentedControl--size-#{$size} {
|
|
37
|
+
--greese-button-height: #{map.get($spec, height)};
|
|
38
|
+
--greese-button-padding: #{map.get($spec, padding)};
|
|
39
|
+
|
|
40
|
+
font-size: map.get($spec, font);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.greese-Segment {
|
|
45
|
+
position: relative;
|
|
46
|
+
display: flex;
|
|
47
|
+
flex: 1 1 0;
|
|
48
|
+
align-items: center;
|
|
49
|
+
justify-content: center;
|
|
50
|
+
min-block-size: var(--greese-segment-height);
|
|
51
|
+
padding-inline: var(--greese-space-3);
|
|
52
|
+
font-weight: var(--greese-font-weight-medium);
|
|
53
|
+
color: var(--greese-color-fg-muted);
|
|
54
|
+
white-space: nowrap;
|
|
55
|
+
cursor: pointer;
|
|
56
|
+
border-radius: calc(var(--greese-corner-control) - 3px);
|
|
57
|
+
transition:
|
|
58
|
+
background-color var(--greese-duration-fast) var(--greese-easing-standard),
|
|
59
|
+
color var(--greese-duration-fast) var(--greese-easing-standard);
|
|
60
|
+
|
|
61
|
+
@include mixins.hover {
|
|
62
|
+
color: var(--greese-color-fg);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// The chosen segment's fill and edge are hooks a theme reassigns (a color
|
|
66
|
+
// variant outlines it).
|
|
67
|
+
&:has(:checked) {
|
|
68
|
+
color: var(--greese-color-fg);
|
|
69
|
+
background-color: var(
|
|
70
|
+
--greese-segment-current-bg,
|
|
71
|
+
var(--greese-color-surface-overlay)
|
|
72
|
+
);
|
|
73
|
+
box-shadow: var(--greese-segment-current-edge, var(--greese-shadow-sm));
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
&:has(:focus-visible) {
|
|
77
|
+
outline: 2px solid var(--greese-color-focus-ring);
|
|
78
|
+
outline-offset: 1px;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
&:has(:disabled) {
|
|
82
|
+
cursor: not-allowed;
|
|
83
|
+
opacity: 0.5;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
@media (pointer: coarse) {
|
|
87
|
+
min-block-size: 2.75rem;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// The real radio covers the segment: it takes clicks, taps and focus.
|
|
92
|
+
// Icons and text centered as boxes: an inline icon sits on the text's
|
|
93
|
+
// middle, below the segment's.
|
|
94
|
+
.greese-Segment-label {
|
|
95
|
+
display: inline-flex;
|
|
96
|
+
gap: var(--greese-space-1);
|
|
97
|
+
align-items: center;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.greese-Segment-input {
|
|
101
|
+
position: absolute;
|
|
102
|
+
inset: 0;
|
|
103
|
+
margin: 0;
|
|
104
|
+
cursor: inherit;
|
|
105
|
+
opacity: 0;
|
|
106
|
+
}
|
|
107
|
+
}
|