@getvitops/core 0.1.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/README.md +29 -0
- package/css/animation.css +526 -0
- package/css/global.css +17 -0
- package/css/index.css +58 -0
- package/css/layout.css +723 -0
- package/css/patterns/anchor-link.css +66 -0
- package/css/patterns/banner.css +64 -0
- package/css/patterns/carousel.css +269 -0
- package/css/patterns/cluster.css +64 -0
- package/css/patterns/code.css +17 -0
- package/css/patterns/combobox.css +97 -0
- package/css/patterns/comment.css +88 -0
- package/css/patterns/copy.css +82 -0
- package/css/patterns/details.css +87 -0
- package/css/patterns/dialog.css +99 -0
- package/css/patterns/drawer.css +108 -0
- package/css/patterns/dropdown.css +45 -0
- package/css/patterns/forms.css +335 -0
- package/css/patterns/grouped.css +86 -0
- package/css/patterns/horizontal-scroll.css +40 -0
- package/css/patterns/icon.css +72 -0
- package/css/patterns/lightbox.css +156 -0
- package/css/patterns/list.css +272 -0
- package/css/patterns/marquee.css +68 -0
- package/css/patterns/masonry.css +40 -0
- package/css/patterns/media.css +70 -0
- package/css/patterns/nav.css +241 -0
- package/css/patterns/notification.css +114 -0
- package/css/patterns/overlay.css +28 -0
- package/css/patterns/popover.css +68 -0
- package/css/patterns/pull-quote.css +71 -0
- package/css/patterns/scroll-based.css +227 -0
- package/css/patterns/scroll-target.css +124 -0
- package/css/patterns/separator.css +130 -0
- package/css/patterns/sitenav.css +582 -0
- package/css/patterns/split-link.css +113 -0
- package/css/patterns/splitter.css +212 -0
- package/css/patterns/stack.css +67 -0
- package/css/patterns/sticky.css +127 -0
- package/css/patterns/subgrid.css +178 -0
- package/css/patterns/svg.css +166 -0
- package/css/patterns/table.css +106 -0
- package/css/patterns/tag.css +75 -0
- package/css/patterns/text-effects.css +317 -0
- package/css/patterns/tooltip.css +68 -0
- package/css/patterns/tree.css +126 -0
- package/css/utilities.css +351 -0
- package/dist/deferred.js +1 -0
- package/dist/elements.js +887 -0
- package/dist/polyfills/adoptedStyleSheets.js +1 -0
- package/dist/polyfills/css-anchor-positioning-fn.js +17 -0
- package/dist/polyfills/global.esm.js +1 -0
- package/dist/polyfills/popover.js +63 -0
- package/dist/polyfills/template-shadowroot.js +24 -0
- package/dist/polyfills/webcomponents-bundle.js +27 -0
- package/dist/polyfills.js +1 -0
- package/package.json +33 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Split Link — a primary <a> paired with a <button> that toggles an anchored
|
|
3
|
+
* [popover] of secondary content (the "split button" pattern).
|
|
4
|
+
*
|
|
5
|
+
* No JS: the toggle uses the native Popover API (a `popovertarget` invoker); the
|
|
6
|
+
* panel is placed with CSS Anchor Positioning. Placement is authored via a single
|
|
7
|
+
* `--split-link-area` custom property (a `position-area` value expressed with
|
|
8
|
+
* logical keywords) — the Bricks control writes it onto the wrapper, where it
|
|
9
|
+
* inherits down to the panel.
|
|
10
|
+
*
|
|
11
|
+
* Anchoring: the panel lives in the top layer, so a plain `position: relative`
|
|
12
|
+
* parent can't contain it — each instance needs a unique `anchor-name`. The Bricks
|
|
13
|
+
* element sets `anchor-name` on the wrapper and a matching `position-anchor` on the
|
|
14
|
+
* panel inline (derived from the element id). For hand-authored one-offs, add your
|
|
15
|
+
* own matching pair.
|
|
16
|
+
*
|
|
17
|
+
* `.split-link--show-on-hover` (a CSS-only, non-top-layer hover reveal) lives in
|
|
18
|
+
* dropdown.css and is a separate mechanism from this click-to-toggle component.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/* ── Group — the link and its toggle sit flush as one control ──────────────── */
|
|
22
|
+
.split-link {
|
|
23
|
+
display: inline-flex;
|
|
24
|
+
align-items: stretch;
|
|
25
|
+
position: relative; /* containing-block fallback where anchoring is unsupported */
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.split-link__toggle {
|
|
29
|
+
display: inline-flex;
|
|
30
|
+
align-items: center;
|
|
31
|
+
justify-content: center;
|
|
32
|
+
padding-inline: var(--split-link-toggle-pad, 0.5rem);
|
|
33
|
+
background: transparent;
|
|
34
|
+
border: none;
|
|
35
|
+
color: inherit;
|
|
36
|
+
cursor: pointer;
|
|
37
|
+
line-height: 1;
|
|
38
|
+
transition: background-color 0.15s ease;
|
|
39
|
+
|
|
40
|
+
&:hover {
|
|
41
|
+
background: var(--color-surface-l);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
&:focus-visible {
|
|
45
|
+
outline: 2px solid var(--split-link-focus-color, var(--color-brand-primary-l));
|
|
46
|
+
outline-offset: 2px;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/* Caret flips while the panel is open (button reflects aria-expanded). */
|
|
50
|
+
.split-link__caret {
|
|
51
|
+
display: inline-block;
|
|
52
|
+
transition: rotate 0.15s ease;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
&[aria-expanded='true'] .split-link__caret {
|
|
56
|
+
rotate: 180deg;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/* ── Panel — the content box (shared by the live popover and the builder's
|
|
61
|
+
always-visible editing variant, which omits the `popover` attribute) ───── */
|
|
62
|
+
.split-link__panel {
|
|
63
|
+
--_p: var(--p-split-link, var(--p-split-link-group, var(--p-panel)));
|
|
64
|
+
--_b: var(--b-split-link, var(--b-split-link-group, var(--b-panel)));
|
|
65
|
+
--_br: var(--br-split-link, var(--br-split-link-group, var(--br-panel)));
|
|
66
|
+
--_ds: var(--ds-split-link, var(--ds-split-link-group, var(--ds-panel)));
|
|
67
|
+
|
|
68
|
+
min-inline-size: max-content;
|
|
69
|
+
max-inline-size: min(24rem, 90vw);
|
|
70
|
+
padding: var(--_p);
|
|
71
|
+
border: var(--_b);
|
|
72
|
+
border-radius: var(--_br);
|
|
73
|
+
box-shadow: var(--_ds);
|
|
74
|
+
background: var(--color-surface-xxl);
|
|
75
|
+
color: var(--color-surface-xxd);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/* Top-layer popover: anchored + placed via position-area. */
|
|
79
|
+
[popover].split-link__panel {
|
|
80
|
+
position: fixed;
|
|
81
|
+
inset: auto;
|
|
82
|
+
/* Logical default: open below the group, spanning toward inline-end. The
|
|
83
|
+
Bricks placement control overrides --split-link-area. position-area shifts
|
|
84
|
+
to stay on-screen (it does not flip — a click panel staying put is fine). */
|
|
85
|
+
position-area: var(--split-link-area, block-end span-inline-end);
|
|
86
|
+
margin: var(--split-link-gap, 0.5rem);
|
|
87
|
+
z-index: var(--z-tier-overlay);
|
|
88
|
+
|
|
89
|
+
/* Popover API toggles display; fade across the top-layer transition. */
|
|
90
|
+
opacity: 0;
|
|
91
|
+
transition:
|
|
92
|
+
opacity 0.15s ease,
|
|
93
|
+
overlay 0.15s allow-discrete,
|
|
94
|
+
display 0.15s allow-discrete;
|
|
95
|
+
|
|
96
|
+
&:popover-open {
|
|
97
|
+
opacity: 1;
|
|
98
|
+
|
|
99
|
+
@starting-style {
|
|
100
|
+
opacity: 0;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
&::backdrop {
|
|
105
|
+
background: transparent;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/* Builder-only: rendered without the `popover` attribute so nested content is
|
|
110
|
+
visible and droppable while editing (a live [popover] is display:none). */
|
|
111
|
+
.split-link__panel--editing {
|
|
112
|
+
margin-block-start: var(--split-link-gap, 0.5rem);
|
|
113
|
+
}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Splitter — pattern partial migrated from old-css-lib.
|
|
3
|
+
* Consumes the generated token cascade (src/css/generated/tokens.css).
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/* ── Splitter + Image-compare — CSS shell; drag behaviour lands via Lit ────── */
|
|
7
|
+
.splitter {
|
|
8
|
+
--_splitter-handle-size: var(--splitter-handle-size, 8px);
|
|
9
|
+
|
|
10
|
+
display: flex;
|
|
11
|
+
|
|
12
|
+
&:not(.splitter--vertical) {
|
|
13
|
+
flex-direction: row;
|
|
14
|
+
}
|
|
15
|
+
&.splitter--vertical {
|
|
16
|
+
flex-direction: column;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.splitter__panel {
|
|
20
|
+
overflow: auto;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.splitter__panel:first-child {
|
|
24
|
+
flex: var(--splitter-ratio, 1);
|
|
25
|
+
}
|
|
26
|
+
.splitter__panel:last-child {
|
|
27
|
+
flex: calc(2 - var(--splitter-ratio, 1));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.splitter__handle {
|
|
31
|
+
flex-shrink: 0;
|
|
32
|
+
background: currentColor;
|
|
33
|
+
opacity: 0.15;
|
|
34
|
+
transition: opacity 0.15s ease;
|
|
35
|
+
position: relative;
|
|
36
|
+
|
|
37
|
+
&:hover,
|
|
38
|
+
&:focus-visible {
|
|
39
|
+
opacity: 0.3;
|
|
40
|
+
}
|
|
41
|
+
&:focus-visible {
|
|
42
|
+
outline: 2px solid;
|
|
43
|
+
outline-offset: 2px;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
&::after {
|
|
47
|
+
content: '';
|
|
48
|
+
position: absolute;
|
|
49
|
+
inset: 50%;
|
|
50
|
+
translate: -50% -50%;
|
|
51
|
+
background: currentColor;
|
|
52
|
+
opacity: 0.3;
|
|
53
|
+
border-radius: 1px;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
&:not(.splitter--vertical) .splitter__handle {
|
|
58
|
+
inline-size: var(--_splitter-handle-size);
|
|
59
|
+
cursor: col-resize;
|
|
60
|
+
|
|
61
|
+
&::after {
|
|
62
|
+
inline-size: 2px;
|
|
63
|
+
block-size: 24px;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
&.splitter--vertical .splitter__handle {
|
|
68
|
+
block-size: var(--_splitter-handle-size);
|
|
69
|
+
cursor: row-resize;
|
|
70
|
+
|
|
71
|
+
&::after {
|
|
72
|
+
inline-size: 24px;
|
|
73
|
+
block-size: 2px;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.image-compare {
|
|
79
|
+
--_compare-position: var(--compare-position, 50%);
|
|
80
|
+
--_compare-handle-size: var(--compare-handle-size, 40px);
|
|
81
|
+
|
|
82
|
+
position: relative;
|
|
83
|
+
overflow: hidden;
|
|
84
|
+
touch-action: pan-y;
|
|
85
|
+
user-select: none;
|
|
86
|
+
|
|
87
|
+
.image-compare__before {
|
|
88
|
+
position: absolute;
|
|
89
|
+
inset: 0;
|
|
90
|
+
clip-path: inset(0 calc(100% - var(--_compare-position)) 0 0);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.image-compare__before > img {
|
|
94
|
+
inline-size: 100%;
|
|
95
|
+
block-size: 100%;
|
|
96
|
+
object-fit: cover;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.image-compare__after {
|
|
100
|
+
display: block;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.image-compare__after > img {
|
|
104
|
+
inline-size: 100%;
|
|
105
|
+
block-size: auto;
|
|
106
|
+
display: block;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.image-compare__handle {
|
|
110
|
+
position: absolute;
|
|
111
|
+
inset-block: 0;
|
|
112
|
+
inset-inline-start: var(--_compare-position);
|
|
113
|
+
translate: -50% 0;
|
|
114
|
+
inline-size: var(--_compare-handle-size);
|
|
115
|
+
display: flex;
|
|
116
|
+
flex-direction: column;
|
|
117
|
+
align-items: center;
|
|
118
|
+
cursor: ew-resize;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.image-compare__handle::before {
|
|
122
|
+
content: '';
|
|
123
|
+
position: absolute;
|
|
124
|
+
inset-block: 0;
|
|
125
|
+
inset-inline-start: 50%;
|
|
126
|
+
translate: -50% 0;
|
|
127
|
+
inline-size: 2px;
|
|
128
|
+
background: currentColor;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
.image-compare__grip {
|
|
132
|
+
position: absolute;
|
|
133
|
+
inset-block-start: 50%;
|
|
134
|
+
inset-inline-start: 50%;
|
|
135
|
+
translate: -50% -50%;
|
|
136
|
+
inline-size: var(--_compare-handle-size);
|
|
137
|
+
block-size: var(--_compare-handle-size);
|
|
138
|
+
background: currentColor;
|
|
139
|
+
border-radius: 50%;
|
|
140
|
+
display: flex;
|
|
141
|
+
align-items: center;
|
|
142
|
+
justify-content: center;
|
|
143
|
+
gap: 4px;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.image-compare__grip::before,
|
|
147
|
+
.image-compare__grip::after {
|
|
148
|
+
content: '';
|
|
149
|
+
inline-size: 0;
|
|
150
|
+
block-size: 0;
|
|
151
|
+
border: 5px solid transparent;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.image-compare__grip::before {
|
|
155
|
+
border-inline-end-color: currentColor;
|
|
156
|
+
}
|
|
157
|
+
.image-compare__grip::after {
|
|
158
|
+
border-inline-start-color: currentColor;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.image-compare__label {
|
|
162
|
+
position: absolute;
|
|
163
|
+
padding: 0.25rem 0.5rem;
|
|
164
|
+
font-size: 0.75rem;
|
|
165
|
+
text-transform: uppercase;
|
|
166
|
+
letter-spacing: 0.05em;
|
|
167
|
+
pointer-events: none;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
.image-compare__label--before {
|
|
171
|
+
inset-block-end: 1rem;
|
|
172
|
+
inset-inline-start: 1rem;
|
|
173
|
+
}
|
|
174
|
+
.image-compare__label--after {
|
|
175
|
+
inset-block-end: 1rem;
|
|
176
|
+
inset-inline-end: 1rem;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
&.image-compare--vertical {
|
|
180
|
+
touch-action: pan-x;
|
|
181
|
+
|
|
182
|
+
.image-compare__before {
|
|
183
|
+
clip-path: inset(0 0 calc(100% - var(--_compare-position)) 0);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
.image-compare__handle {
|
|
187
|
+
inset-block-start: var(--_compare-position);
|
|
188
|
+
inset-inline: 0;
|
|
189
|
+
inset-block-end: auto;
|
|
190
|
+
translate: 0 -50%;
|
|
191
|
+
flex-direction: row;
|
|
192
|
+
cursor: ns-resize;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
.image-compare__handle::before {
|
|
196
|
+
inset-inline: 0;
|
|
197
|
+
inset-block: auto;
|
|
198
|
+
inline-size: 100%;
|
|
199
|
+
block-size: 2px;
|
|
200
|
+
translate: 0 -50%;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
.image-compare__grip::before {
|
|
204
|
+
border-block-end-color: currentColor;
|
|
205
|
+
border-inline-end-color: transparent;
|
|
206
|
+
}
|
|
207
|
+
.image-compare__grip::after {
|
|
208
|
+
border-block-start-color: currentColor;
|
|
209
|
+
border-inline-start-color: transparent;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stack — pattern partial migrated from old-css-lib.
|
|
3
|
+
* Consumes the generated token cascade (src/css/generated/tokens.css).
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/* ── Stack — scroll-driven stacking cards (view-timeline) ──────────────────── */
|
|
7
|
+
.stack {
|
|
8
|
+
--stack-count: 4;
|
|
9
|
+
--stack-card-height: 60vh;
|
|
10
|
+
display: grid;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.stack__card {
|
|
14
|
+
--stack-index: 1;
|
|
15
|
+
position: sticky;
|
|
16
|
+
top: var(--stack-top, 10vh);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.stack__card__content {
|
|
20
|
+
box-shadow: var(--ds-card, var(--ds-card-group, var(--ds-default)));
|
|
21
|
+
border-radius: var(--br-card, var(--br-card-group, var(--br-default)));
|
|
22
|
+
min-block-size: var(--stack-card-height);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@supports (animation-timeline: view()) {
|
|
26
|
+
.stack__card {
|
|
27
|
+
--_index0: calc(var(--stack-index) - 1);
|
|
28
|
+
--_reverse-index: calc(var(--stack-count) - var(--_index0));
|
|
29
|
+
--_reverse-index0: calc(var(--_reverse-index) - 1);
|
|
30
|
+
|
|
31
|
+
view-timeline: --card block;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
@keyframes stack-scale {
|
|
35
|
+
to {
|
|
36
|
+
transform: scale(calc(1.1 - calc(0.1 * var(--_reverse-index))));
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.stack__card__content {
|
|
41
|
+
animation: stack-scale linear forwards;
|
|
42
|
+
animation-timeline: --card;
|
|
43
|
+
animation-range: contain 0% contain 100%;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@keyframes stack-fade {
|
|
47
|
+
to {
|
|
48
|
+
opacity: calc(0.5 + 0.5 * (var(--_reverse-index) / var(--stack-count)));
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.stack--fade .stack__card__content {
|
|
53
|
+
animation:
|
|
54
|
+
stack-scale linear forwards,
|
|
55
|
+
stack-fade linear forwards;
|
|
56
|
+
animation-timeline: --card, --card;
|
|
57
|
+
animation-range:
|
|
58
|
+
contain 0% contain 100%,
|
|
59
|
+
contain 0% contain 100%;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
@media (prefers-reduced-motion: reduce) {
|
|
64
|
+
.stack__card__content {
|
|
65
|
+
animation: none !important;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sticky — pattern partial migrated from old-css-lib.
|
|
3
|
+
* Consumes the generated token cascade (src/css/generated/tokens.css).
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/* ── Sticky — position:sticky variants + scroll-state() stuck detection ────── */
|
|
7
|
+
.sticky {
|
|
8
|
+
--_sticky-offset: var(--sticky-offset, 0);
|
|
9
|
+
|
|
10
|
+
position: sticky;
|
|
11
|
+
inset-block-start: var(--_sticky-offset);
|
|
12
|
+
z-index: var(--z-tier-sticky);
|
|
13
|
+
|
|
14
|
+
&.sticky--bottom {
|
|
15
|
+
inset-block-start: auto;
|
|
16
|
+
inset-block-end: var(--_sticky-offset);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
&.sticky--inline-start {
|
|
20
|
+
inset-inline-start: var(--_sticky-offset);
|
|
21
|
+
inset-block-start: auto;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
&.sticky--inline-end {
|
|
25
|
+
inset-inline-end: var(--_sticky-offset);
|
|
26
|
+
inset-inline-start: auto;
|
|
27
|
+
inset-block-start: auto;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.sticky-header {
|
|
32
|
+
--_sticky-offset: var(--sticky-header-offset, 0);
|
|
33
|
+
|
|
34
|
+
position: sticky;
|
|
35
|
+
inset-block-start: var(--_sticky-offset);
|
|
36
|
+
z-index: var(--z-tier-sticky);
|
|
37
|
+
container-type: scroll-state;
|
|
38
|
+
|
|
39
|
+
.sticky-header__stuck-only {
|
|
40
|
+
display: none;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
@container scroll-state(stuck: top) {
|
|
44
|
+
.sticky-header__logo {
|
|
45
|
+
scale: 0.85;
|
|
46
|
+
}
|
|
47
|
+
.sticky-header__stuck-only {
|
|
48
|
+
display: block;
|
|
49
|
+
}
|
|
50
|
+
.sticky-header__unstuck-only {
|
|
51
|
+
display: none;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.sticky-sidebar {
|
|
57
|
+
--_sticky-offset: var(--sticky-sidebar-offset, 1rem);
|
|
58
|
+
--_sticky-max-height: var(--sticky-sidebar-max-height, calc(100vh - 2rem));
|
|
59
|
+
|
|
60
|
+
position: sticky;
|
|
61
|
+
inset-block-start: var(--_sticky-offset);
|
|
62
|
+
max-block-size: var(--_sticky-max-height);
|
|
63
|
+
overflow-y: auto;
|
|
64
|
+
align-self: flex-start;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
table.sticky-table {
|
|
68
|
+
position: relative;
|
|
69
|
+
|
|
70
|
+
thead {
|
|
71
|
+
position: sticky;
|
|
72
|
+
inset-block-start: 0;
|
|
73
|
+
z-index: 10;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
thead th {
|
|
77
|
+
background: inherit;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
&.sticky-table--first-col th:first-child,
|
|
81
|
+
&.sticky-table--first-col td:first-child {
|
|
82
|
+
position: sticky;
|
|
83
|
+
inset-inline-start: 0;
|
|
84
|
+
z-index: 5;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
&.sticky-table--first-col thead th:first-child {
|
|
88
|
+
z-index: 15;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.sticky-footer {
|
|
93
|
+
--_sticky-offset: var(--sticky-footer-offset, 0);
|
|
94
|
+
|
|
95
|
+
position: sticky;
|
|
96
|
+
inset-block-end: var(--_sticky-offset);
|
|
97
|
+
z-index: var(--z-tier-sticky);
|
|
98
|
+
container-type: scroll-state;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.sticky-nav {
|
|
102
|
+
position: sticky;
|
|
103
|
+
inset-block-start: var(--sticky-nav-offset, 0);
|
|
104
|
+
z-index: var(--z-tier-sticky);
|
|
105
|
+
|
|
106
|
+
.sticky-nav__item {
|
|
107
|
+
container-type: scroll-state;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.sticky-nav__indicator {
|
|
111
|
+
opacity: 0;
|
|
112
|
+
scale: 0.8;
|
|
113
|
+
transition:
|
|
114
|
+
opacity 0.2s ease,
|
|
115
|
+
scale 0.2s ease;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
@container scroll-state(snapped: block) {
|
|
119
|
+
.sticky-nav__link {
|
|
120
|
+
font-weight: 600;
|
|
121
|
+
}
|
|
122
|
+
.sticky-nav__indicator {
|
|
123
|
+
opacity: 1;
|
|
124
|
+
scale: 1;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Subgrid — pattern partial migrated from old-css-lib.
|
|
3
|
+
* Consumes the generated token cascade (src/css/generated/tokens.css).
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/* ── Subgrid — content-aligned cards/tables via CSS subgrid ────────────────── */
|
|
7
|
+
.subgrid {
|
|
8
|
+
--_items-per-row: var(--items-per-row, 3);
|
|
9
|
+
--_rows-per-item: var(--rows-per-item, 2);
|
|
10
|
+
--_subgrid-gap: var(--subgrid-gap, 1.5rem);
|
|
11
|
+
|
|
12
|
+
display: grid;
|
|
13
|
+
grid-template-columns: repeat(var(--_items-per-row), 1fr);
|
|
14
|
+
gap: var(--_subgrid-gap);
|
|
15
|
+
|
|
16
|
+
> * {
|
|
17
|
+
grid-row: span var(--_rows-per-item);
|
|
18
|
+
display: grid;
|
|
19
|
+
grid-template-rows: subgrid;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
&.subgrid-cols-1 {
|
|
23
|
+
--_items-per-row: 1;
|
|
24
|
+
}
|
|
25
|
+
&.subgrid-cols-2 {
|
|
26
|
+
--_items-per-row: 2;
|
|
27
|
+
}
|
|
28
|
+
&.subgrid-cols-3 {
|
|
29
|
+
--_items-per-row: 3;
|
|
30
|
+
}
|
|
31
|
+
&.subgrid-cols-4 {
|
|
32
|
+
--_items-per-row: 4;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
&.subgrid-rows-2 {
|
|
36
|
+
--_rows-per-item: 2;
|
|
37
|
+
}
|
|
38
|
+
&.subgrid-rows-3 {
|
|
39
|
+
--_rows-per-item: 3;
|
|
40
|
+
}
|
|
41
|
+
&.subgrid-rows-4 {
|
|
42
|
+
--_rows-per-item: 4;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
&.subgrid-responsive {
|
|
46
|
+
@media (width < 60rem) {
|
|
47
|
+
--_items-per-row: min(var(--items-per-row, 3), 2);
|
|
48
|
+
}
|
|
49
|
+
@media (width < 40rem) {
|
|
50
|
+
--_items-per-row: 1;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/* Subgrid card — internal rows align across siblings */
|
|
56
|
+
.subgrid-card {
|
|
57
|
+
--_card-rows: var(--subgrid-card-rows, 4);
|
|
58
|
+
--_card-padding: var(--subgrid-card-padding, 1.5rem);
|
|
59
|
+
|
|
60
|
+
display: grid;
|
|
61
|
+
grid-template-rows: subgrid;
|
|
62
|
+
grid-row: span var(--_card-rows);
|
|
63
|
+
padding: var(--_card-padding);
|
|
64
|
+
border: var(--b-card, var(--b-card-group, var(--b-default)));
|
|
65
|
+
border-radius: var(--br-card, var(--br-card-group, var(--br-default)));
|
|
66
|
+
|
|
67
|
+
.subgrid-card__media {
|
|
68
|
+
margin-inline: calc(-1 * var(--_card-padding));
|
|
69
|
+
|
|
70
|
+
> img {
|
|
71
|
+
inline-size: 100%;
|
|
72
|
+
block-size: 100%;
|
|
73
|
+
object-fit: cover;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.subgrid-card__footer {
|
|
78
|
+
align-self: end;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/* Pricing table with aligned feature rows */
|
|
83
|
+
.pricing-grid {
|
|
84
|
+
display: grid;
|
|
85
|
+
grid-template-columns: repeat(var(--pricing-columns, 3), 1fr);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.pricing-card {
|
|
89
|
+
--_pricing-rows: var(--pricing-card-rows, auto);
|
|
90
|
+
|
|
91
|
+
display: grid;
|
|
92
|
+
grid-template-rows: subgrid;
|
|
93
|
+
grid-row: span var(--_pricing-rows);
|
|
94
|
+
gap: 0;
|
|
95
|
+
border: var(--b-card, var(--b-card-group, var(--b-default)));
|
|
96
|
+
border-radius: var(--br-card, var(--br-card-group, var(--br-default)));
|
|
97
|
+
overflow: hidden;
|
|
98
|
+
|
|
99
|
+
.pricing-card__header {
|
|
100
|
+
padding: var(--pricing-header-padding, 1.5rem);
|
|
101
|
+
text-align: center;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.pricing-card__price {
|
|
105
|
+
padding: var(--pricing-price-padding, 1rem 1.5rem);
|
|
106
|
+
text-align: center;
|
|
107
|
+
font-size: var(--pricing-price-size, 2.5rem);
|
|
108
|
+
font-weight: 700;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.pricing-card__features {
|
|
112
|
+
padding: var(--pricing-features-padding, 1.5rem);
|
|
113
|
+
list-style: none;
|
|
114
|
+
margin: 0;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.pricing-card__feature {
|
|
118
|
+
padding-block: 0.5rem;
|
|
119
|
+
border-block-end: var(--b-card, var(--b-card-group, var(--b-default)));
|
|
120
|
+
|
|
121
|
+
&:last-child {
|
|
122
|
+
border-block-end: none;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.pricing-card__cta {
|
|
127
|
+
padding: var(--pricing-cta-padding, 1.5rem);
|
|
128
|
+
text-align: center;
|
|
129
|
+
align-self: end;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
&.pricing-card--featured {
|
|
133
|
+
scale: 1.02;
|
|
134
|
+
z-index: var(--z-tier-raised);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/* Comparison table with subgrid columns */
|
|
139
|
+
.comparison-table {
|
|
140
|
+
--_comparison-columns: var(--comparison-columns, 4);
|
|
141
|
+
|
|
142
|
+
display: grid;
|
|
143
|
+
grid-template-columns:
|
|
144
|
+
minmax(150px, 1fr)
|
|
145
|
+
repeat(calc(var(--_comparison-columns) - 1), minmax(100px, 1fr));
|
|
146
|
+
border: var(--b-card, var(--b-card-group, var(--b-default)));
|
|
147
|
+
border-radius: var(--br-card, var(--br-card-group, var(--br-default)));
|
|
148
|
+
overflow: hidden;
|
|
149
|
+
|
|
150
|
+
.comparison-table__header,
|
|
151
|
+
.comparison-table__row {
|
|
152
|
+
display: contents;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
.comparison-table__header > * {
|
|
156
|
+
padding: var(--comparison-header-padding, 1rem);
|
|
157
|
+
font-weight: 600;
|
|
158
|
+
text-align: center;
|
|
159
|
+
border-block-end: var(--b-card, var(--b-card-group, var(--b-default)));
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
.comparison-table__row > * {
|
|
163
|
+
padding: var(--comparison-cell-padding, 1rem);
|
|
164
|
+
border-block-end: var(--b-card, var(--b-card-group, var(--b-default)));
|
|
165
|
+
display: flex;
|
|
166
|
+
align-items: center;
|
|
167
|
+
justify-content: center;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
.comparison-table__row > *:first-child {
|
|
171
|
+
justify-content: flex-start;
|
|
172
|
+
font-weight: 500;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
.comparison-table__row:last-child > * {
|
|
176
|
+
border-block-end: none;
|
|
177
|
+
}
|
|
178
|
+
}
|