@pinfold/css 0.0.0-stage → 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 +64 -2
- package/dist/accordion.css +455 -0
- package/dist/all.css +1043 -0
- package/dist/core.css +477 -0
- package/dist/packs.css +109 -0
- package/dist/reset.css +110 -0
- package/dist/shadcn.css +51 -0
- package/dist/tailwind.css +87 -0
- package/dist/tokens.css +366 -0
- package/package.json +55 -4
- package/tailwind/preset.cjs +146 -0
- package/tailwind/theme.css +87 -0
package/README.md
CHANGED
|
@@ -1,3 +1,65 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @pinfold/css
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
All of Pinfold's styling: design tokens, a scoped reset, one stylesheet per component, and
|
|
4
|
+
the Tailwind bridge. Plain CSS in cascade layers (`@layer pinfold.*`), so your own CSS and every
|
|
5
|
+
Tailwind utility override it without `!important`. Framework-free.
|
|
6
|
+
|
|
7
|
+
```js
|
|
8
|
+
import '@pinfold/css/core.css'; // reset + tokens, once
|
|
9
|
+
import '@pinfold/css/accordion.css'; // per component you use
|
|
10
|
+
// or: import '@pinfold/css/all.css';
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Using `unstyled: true` everywhere? Import only `@pinfold/css/tokens.css`, or nothing.
|
|
14
|
+
|
|
15
|
+
## Style packs
|
|
16
|
+
|
|
17
|
+
```js
|
|
18
|
+
import '@pinfold/css/packs.css';
|
|
19
|
+
// <PinfoldProvider stylePack="glass">, or data-pinfold-style="glass" on any element
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
`glass`, `bauhaus`, `brutalist`, `noise` and `soft` are token recipes (shape, depth, borders,
|
|
23
|
+
surfaces, type), so every component follows them with no extra CSS. Each one yields to
|
|
24
|
+
`prefers-reduced-transparency`, `prefers-contrast: more` and `forced-colors`, and glass surfaces
|
|
25
|
+
are tested to keep body text at WCAG AA over white, black and brand-coloured backdrops.
|
|
26
|
+
|
|
27
|
+
## shadcn/ui
|
|
28
|
+
|
|
29
|
+
```css
|
|
30
|
+
@import "@pinfold/css/core.css";
|
|
31
|
+
@import "@pinfold/css/shadcn.css"; /* after shadcn's own variables */
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Points shadcn's variables (`--background`, `--primary`, `--ring`, `--radius`, …) at Pinfold's
|
|
35
|
+
tokens, so both libraries share one theme. For dark mode set both `.dark` and
|
|
36
|
+
`data-pinfold-theme`, e.g. next-themes `attribute={['class', 'data-pinfold-theme']}`.
|
|
37
|
+
|
|
38
|
+
## Design tokens (DTCG)
|
|
39
|
+
|
|
40
|
+
`toDTCG(createTheme({ primary: 'emerald' }))` from `@pinfold/core/palette` returns the theme as
|
|
41
|
+
W3C Design Tokens (2025.10) for Tokens Studio, Style Dictionary and other DTCG tools.
|
|
42
|
+
|
|
43
|
+
## Tailwind
|
|
44
|
+
|
|
45
|
+
**v4:** import the theme after Tailwind.
|
|
46
|
+
|
|
47
|
+
```css
|
|
48
|
+
@import "tailwindcss";
|
|
49
|
+
@import "@pinfold/css/core.css";
|
|
50
|
+
@import "@pinfold/css/tailwind.css";
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**v3:** add the preset.
|
|
54
|
+
|
|
55
|
+
```js
|
|
56
|
+
// tailwind.config.js
|
|
57
|
+
module.exports = { presets: [require('@pinfold/css/tailwind')] };
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
`bg-primary-600`, `text-content-muted`, `border-line`, `rounded-lg`, `shadow-md` and
|
|
61
|
+
`ease-pinfold-out` all resolve to `--pinfold-*` custom properties, so they follow
|
|
62
|
+
`npx pinfold theme`, dark mode and any runtime override. Variants such as `open:`, `closed:` and
|
|
63
|
+
`disabled-row:` map to the `data-*` attributes Pinfold components already set.
|
|
64
|
+
|
|
65
|
+
MIT © Indranil Bhattacharya
|
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
/* Pinfold — accordion.
|
|
2
|
+
|
|
3
|
+
Two-layer variables: the `size` preset writes the `*-base` vars, and the
|
|
4
|
+
`dimensions` config writes `--pinfold-accordion-*` which wins through the
|
|
5
|
+
var() fallback. Overriding one measurement keeps the preset for the rest.
|
|
6
|
+
|
|
7
|
+
Nothing clips. Rounded rows give their trigger the matching radius instead
|
|
8
|
+
of relying on `overflow: hidden`, because a clipping ancestor would also cut
|
|
9
|
+
off the focus ring. Collapse is pure CSS (`grid-template-rows`) — no height
|
|
10
|
+
measurement, no ResizeObserver, no layout thrash. */
|
|
11
|
+
|
|
12
|
+
@layer pinfold.components {
|
|
13
|
+
|
|
14
|
+
.pinfold-accordion {
|
|
15
|
+
/* preset layer (set by [data-size]) */
|
|
16
|
+
--pinfold-acc-pad-x-base: var(--pinfold-space-4);
|
|
17
|
+
--pinfold-acc-pad-y-base: var(--pinfold-space-3);
|
|
18
|
+
--pinfold-acc-font-base: var(--pinfold-text-md);
|
|
19
|
+
--pinfold-acc-radius-base: var(--pinfold-radius-lg);
|
|
20
|
+
--pinfold-acc-gap-base: 0px;
|
|
21
|
+
|
|
22
|
+
/* config layer (set by `dimensions`) */
|
|
23
|
+
--pinfold-acc-pad-x: var(--pinfold-accordion-padding-x, var(--pinfold-acc-pad-x-base));
|
|
24
|
+
--pinfold-acc-pad-y: var(--pinfold-accordion-padding-y, var(--pinfold-acc-pad-y-base));
|
|
25
|
+
--pinfold-acc-panel-pad-x: var(--pinfold-accordion-panel-padding-x, var(--pinfold-acc-pad-x));
|
|
26
|
+
--pinfold-acc-panel-pad-y: var(--pinfold-accordion-panel-padding-y, var(--pinfold-acc-pad-y));
|
|
27
|
+
--pinfold-acc-font: var(--pinfold-accordion-font-size, var(--pinfold-acc-font-base));
|
|
28
|
+
--pinfold-acc-title: var(--pinfold-accordion-title-size, inherit);
|
|
29
|
+
--pinfold-acc-desc: var(--pinfold-accordion-description-size, var(--pinfold-text-sm));
|
|
30
|
+
--pinfold-acc-icon: var(--pinfold-accordion-icon-size, 1.5em);
|
|
31
|
+
--pinfold-acc-ind: var(--pinfold-accordion-indicator-size, 1em);
|
|
32
|
+
--pinfold-acc-radius: var(--pinfold-accordion-radius, var(--pinfold-acc-radius-base));
|
|
33
|
+
--pinfold-acc-gap: var(--pinfold-accordion-gap, var(--pinfold-acc-gap-base));
|
|
34
|
+
--pinfold-acc-border: var(--pinfold-accordion-border-width, var(--pinfold-border-width));
|
|
35
|
+
--pinfold-acc-duration: var(--pinfold-accordion-duration, var(--pinfold-duration-md));
|
|
36
|
+
|
|
37
|
+
--pinfold-acc-accent: var(--pinfold-color-accent);
|
|
38
|
+
--pinfold-acc-item-radius: 0px;
|
|
39
|
+
|
|
40
|
+
display: flex;
|
|
41
|
+
flex-direction: column;
|
|
42
|
+
gap: var(--pinfold-acc-gap);
|
|
43
|
+
/* Responds to its own width, not the viewport (see "responsive" below). */
|
|
44
|
+
container: pinfold-accordion / inline-size;
|
|
45
|
+
width: var(--pinfold-accordion-width, 100%);
|
|
46
|
+
min-width: var(--pinfold-accordion-min-width, 0);
|
|
47
|
+
max-width: var(--pinfold-accordion-max-width, none);
|
|
48
|
+
height: var(--pinfold-accordion-height, auto);
|
|
49
|
+
max-height: var(--pinfold-accordion-max-height, none);
|
|
50
|
+
font-size: var(--pinfold-acc-font);
|
|
51
|
+
letter-spacing: var(--pinfold-tracking-tight);
|
|
52
|
+
color: var(--pinfold-color-text);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/* `dimensions.maxHeight` caps the root and scrolls the rows. */
|
|
56
|
+
.pinfold-accordion[data-clamp] {
|
|
57
|
+
overflow-y: auto;
|
|
58
|
+
overscroll-behavior: contain;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/* ------------------------------------------------------------------ sizes */
|
|
62
|
+
.pinfold-accordion[data-size='sm'] {
|
|
63
|
+
--pinfold-acc-pad-x-base: var(--pinfold-space-3);
|
|
64
|
+
--pinfold-acc-pad-y-base: var(--pinfold-space-2);
|
|
65
|
+
--pinfold-acc-font-base: var(--pinfold-text-sm);
|
|
66
|
+
--pinfold-acc-radius-base: var(--pinfold-radius-md);
|
|
67
|
+
}
|
|
68
|
+
.pinfold-accordion[data-size='lg'] {
|
|
69
|
+
--pinfold-acc-pad-x-base: var(--pinfold-space-5);
|
|
70
|
+
--pinfold-acc-pad-y-base: var(--pinfold-space-4);
|
|
71
|
+
--pinfold-acc-font-base: var(--pinfold-text-lg);
|
|
72
|
+
--pinfold-acc-radius-base: var(--pinfold-radius-xl);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/* ------------------------------------------------------------------ tones */
|
|
76
|
+
.pinfold-accordion[data-tone='neutral'] { --pinfold-acc-accent: var(--pinfold-color-text); }
|
|
77
|
+
.pinfold-accordion[data-tone='success'] { --pinfold-acc-accent: var(--pinfold-success-500); }
|
|
78
|
+
.pinfold-accordion[data-tone='warning'] { --pinfold-acc-accent: var(--pinfold-warning-500); }
|
|
79
|
+
.pinfold-accordion[data-tone='danger'] { --pinfold-acc-accent: var(--pinfold-danger-500); }
|
|
80
|
+
.pinfold-accordion[data-tone='info'] { --pinfold-acc-accent: var(--pinfold-info-500); }
|
|
81
|
+
|
|
82
|
+
/* ------------------------------------------------------------------- item */
|
|
83
|
+
.pinfold-accordion__item {
|
|
84
|
+
position: relative;
|
|
85
|
+
border-radius: var(--pinfold-acc-item-radius);
|
|
86
|
+
}
|
|
87
|
+
.pinfold-accordion__header,
|
|
88
|
+
.pinfold-accordion__trigger {
|
|
89
|
+
border-radius: inherit;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/* Accent edge on the open row. Scales from the centre, so it reads as the row
|
|
93
|
+
opening rather than a bar appearing. */
|
|
94
|
+
.pinfold-accordion__item::before {
|
|
95
|
+
content: '';
|
|
96
|
+
position: absolute;
|
|
97
|
+
inset-block: 0;
|
|
98
|
+
inset-inline-start: 0;
|
|
99
|
+
width: 2px;
|
|
100
|
+
background: var(--pinfold-acc-accent);
|
|
101
|
+
border-start-start-radius: inherit;
|
|
102
|
+
border-end-start-radius: inherit;
|
|
103
|
+
transform: scaleY(0);
|
|
104
|
+
opacity: 0;
|
|
105
|
+
transition: transform var(--pinfold-acc-duration) var(--pinfold-ease-out),
|
|
106
|
+
opacity var(--pinfold-duration-fast) linear;
|
|
107
|
+
pointer-events: none;
|
|
108
|
+
}
|
|
109
|
+
.pinfold-accordion__item[data-state='open']::before {
|
|
110
|
+
transform: scaleY(1);
|
|
111
|
+
opacity: 1;
|
|
112
|
+
}
|
|
113
|
+
/* Bordered rows already signal state through the border; the bar would double up. */
|
|
114
|
+
.pinfold-accordion[data-variant='outline'] .pinfold-accordion__item::before,
|
|
115
|
+
.pinfold-accordion[data-variant='separated'] .pinfold-accordion__item::before {
|
|
116
|
+
content: none;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/* --------------------------------------------------------------- variants */
|
|
120
|
+
/* solid — one card, hairline-divided rows. Corners are rounded on the parts
|
|
121
|
+
that touch them rather than clipped off the container. */
|
|
122
|
+
.pinfold-accordion[data-variant='solid'] {
|
|
123
|
+
background: var(--pinfold-color-surface);
|
|
124
|
+
background-image: var(--pinfold-texture);
|
|
125
|
+
-webkit-backdrop-filter: var(--pinfold-backdrop);
|
|
126
|
+
backdrop-filter: var(--pinfold-backdrop);
|
|
127
|
+
border: var(--pinfold-acc-border) solid var(--pinfold-color-border);
|
|
128
|
+
border-radius: var(--pinfold-acc-radius);
|
|
129
|
+
box-shadow: var(--pinfold-shadow-sm), var(--pinfold-highlight);
|
|
130
|
+
}
|
|
131
|
+
.pinfold-accordion[data-variant='solid'][data-dividers] .pinfold-accordion__item + .pinfold-accordion__item {
|
|
132
|
+
border-top: var(--pinfold-acc-border) solid var(--pinfold-color-border);
|
|
133
|
+
}
|
|
134
|
+
.pinfold-accordion[data-variant='solid'] .pinfold-accordion__item:first-child .pinfold-accordion__trigger {
|
|
135
|
+
border-start-start-radius: var(--pinfold-acc-radius);
|
|
136
|
+
border-start-end-radius: var(--pinfold-acc-radius);
|
|
137
|
+
}
|
|
138
|
+
.pinfold-accordion[data-variant='solid'] .pinfold-accordion__item:last-child .pinfold-accordion__panel {
|
|
139
|
+
border-end-start-radius: var(--pinfold-acc-radius);
|
|
140
|
+
border-end-end-radius: var(--pinfold-acc-radius);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/* outline — each row is its own bordered box */
|
|
144
|
+
.pinfold-accordion[data-variant='outline'] {
|
|
145
|
+
--pinfold-acc-gap-base: var(--pinfold-space-2);
|
|
146
|
+
}
|
|
147
|
+
.pinfold-accordion[data-variant='outline'] .pinfold-accordion__item {
|
|
148
|
+
--pinfold-acc-item-radius: var(--pinfold-acc-radius);
|
|
149
|
+
border: var(--pinfold-acc-border) solid var(--pinfold-color-border);
|
|
150
|
+
transition: border-color var(--pinfold-duration-md) var(--pinfold-ease);
|
|
151
|
+
}
|
|
152
|
+
.pinfold-accordion[data-variant='outline'] .pinfold-accordion__item[data-state='open'] {
|
|
153
|
+
border-color: var(--pinfold-color-border-accent);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/* separated — cards with air and elevation */
|
|
157
|
+
.pinfold-accordion[data-variant='separated'] {
|
|
158
|
+
--pinfold-acc-gap-base: var(--pinfold-space-3);
|
|
159
|
+
}
|
|
160
|
+
.pinfold-accordion[data-variant='separated'] .pinfold-accordion__item {
|
|
161
|
+
--pinfold-acc-item-radius: var(--pinfold-acc-radius);
|
|
162
|
+
background: var(--pinfold-color-surface);
|
|
163
|
+
background-image: var(--pinfold-texture);
|
|
164
|
+
-webkit-backdrop-filter: var(--pinfold-backdrop);
|
|
165
|
+
backdrop-filter: var(--pinfold-backdrop);
|
|
166
|
+
border: var(--pinfold-acc-border) solid var(--pinfold-color-border);
|
|
167
|
+
box-shadow: var(--pinfold-shadow-sm), var(--pinfold-highlight);
|
|
168
|
+
transition: box-shadow var(--pinfold-duration-md) var(--pinfold-ease),
|
|
169
|
+
border-color var(--pinfold-duration-md) var(--pinfold-ease),
|
|
170
|
+
transform var(--pinfold-duration-md) var(--pinfold-ease-out);
|
|
171
|
+
}
|
|
172
|
+
.pinfold-accordion[data-variant='separated'] .pinfold-accordion__item:hover {
|
|
173
|
+
box-shadow: var(--pinfold-shadow-md), var(--pinfold-highlight);
|
|
174
|
+
}
|
|
175
|
+
.pinfold-accordion[data-variant='separated'] .pinfold-accordion__item[data-state='open'] {
|
|
176
|
+
border-color: var(--pinfold-color-border-accent);
|
|
177
|
+
box-shadow: var(--pinfold-shadow-md), var(--pinfold-highlight);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/* filled — tinted rows, no borders */
|
|
181
|
+
.pinfold-accordion[data-variant='filled'] {
|
|
182
|
+
--pinfold-acc-gap-base: var(--pinfold-space-2);
|
|
183
|
+
}
|
|
184
|
+
.pinfold-accordion[data-variant='filled'] .pinfold-accordion__item {
|
|
185
|
+
--pinfold-acc-item-radius: var(--pinfold-acc-radius);
|
|
186
|
+
background: var(--pinfold-color-bg-subtle);
|
|
187
|
+
background-image: var(--pinfold-texture);
|
|
188
|
+
-webkit-backdrop-filter: var(--pinfold-backdrop);
|
|
189
|
+
backdrop-filter: var(--pinfold-backdrop);
|
|
190
|
+
transition: background-color var(--pinfold-duration-md) var(--pinfold-ease);
|
|
191
|
+
}
|
|
192
|
+
.pinfold-accordion[data-variant='filled'] .pinfold-accordion__item[data-state='open'] {
|
|
193
|
+
background-color: var(--pinfold-color-surface-selected);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/* ghost — text only, hover reveals the row */
|
|
197
|
+
.pinfold-accordion[data-variant='ghost'] .pinfold-accordion__item {
|
|
198
|
+
--pinfold-acc-item-radius: var(--pinfold-acc-radius);
|
|
199
|
+
}
|
|
200
|
+
.pinfold-accordion[data-variant='ghost'][data-dividers] .pinfold-accordion__item + .pinfold-accordion__item {
|
|
201
|
+
border-top: var(--pinfold-acc-border) solid var(--pinfold-color-border);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/* ----------------------------------------------------------------- header */
|
|
205
|
+
.pinfold-accordion__header {
|
|
206
|
+
display: flex;
|
|
207
|
+
margin: 0;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
.pinfold-accordion__trigger {
|
|
211
|
+
display: flex;
|
|
212
|
+
align-items: center;
|
|
213
|
+
gap: var(--pinfold-space-3);
|
|
214
|
+
width: 100%;
|
|
215
|
+
padding: var(--pinfold-acc-pad-y) var(--pinfold-acc-pad-x);
|
|
216
|
+
font-size: inherit;
|
|
217
|
+
font-weight: var(--pinfold-weight-medium);
|
|
218
|
+
line-height: var(--pinfold-leading-tight);
|
|
219
|
+
text-align: start;
|
|
220
|
+
color: var(--pinfold-color-text);
|
|
221
|
+
transition: background-color var(--pinfold-duration-fast) var(--pinfold-ease),
|
|
222
|
+
color var(--pinfold-duration-fast) var(--pinfold-ease);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
.pinfold-accordion__trigger:hover {
|
|
226
|
+
background: var(--pinfold-color-surface-hover);
|
|
227
|
+
}
|
|
228
|
+
.pinfold-accordion__trigger:active {
|
|
229
|
+
background: var(--pinfold-color-surface-active);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/* Text in the accent: pulled toward the text colour so every tone (500 steps included) clears
|
|
233
|
+
4.5:1 on every variant's open background, in light and dark mode (the a11y report checks). */
|
|
234
|
+
.pinfold-accordion__trigger[data-state='open'] {
|
|
235
|
+
color: color-mix(in oklch, var(--pinfold-acc-accent) 62%, var(--pinfold-color-text));
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
.pinfold-accordion__trigger[data-disabled] {
|
|
239
|
+
color: var(--pinfold-color-text-disabled);
|
|
240
|
+
cursor: not-allowed;
|
|
241
|
+
}
|
|
242
|
+
.pinfold-accordion__trigger[data-disabled]:hover,
|
|
243
|
+
.pinfold-accordion__trigger[data-disabled]:active {
|
|
244
|
+
background: none;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/* The ring is drawn by the core reset as a box-shadow; raise the focused row
|
|
248
|
+
so a neighbouring row's background cannot paint over it. */
|
|
249
|
+
.pinfold-accordion__trigger:focus-visible {
|
|
250
|
+
position: relative;
|
|
251
|
+
z-index: 1;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
.pinfold-accordion[data-indicator-position='start'] .pinfold-accordion__trigger {
|
|
255
|
+
flex-direction: row-reverse;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/* ------------------------------------------------------------------ parts */
|
|
259
|
+
.pinfold-accordion__icon {
|
|
260
|
+
display: inline-flex;
|
|
261
|
+
flex: none;
|
|
262
|
+
align-items: center;
|
|
263
|
+
justify-content: center;
|
|
264
|
+
width: var(--pinfold-acc-icon);
|
|
265
|
+
height: var(--pinfold-acc-icon);
|
|
266
|
+
color: var(--pinfold-acc-accent);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
.pinfold-accordion__label {
|
|
270
|
+
display: flex;
|
|
271
|
+
flex: 1 1 auto;
|
|
272
|
+
flex-direction: column;
|
|
273
|
+
gap: 2px;
|
|
274
|
+
min-width: 0;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
.pinfold-accordion__title {
|
|
278
|
+
font-size: var(--pinfold-acc-title);
|
|
279
|
+
overflow-wrap: anywhere;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/* Overflow policy per slot: wrap (default for titles), truncate, or clamp to n lines. */
|
|
283
|
+
.pinfold-accordion [data-overflow='truncate'] {
|
|
284
|
+
overflow: hidden;
|
|
285
|
+
text-overflow: ellipsis;
|
|
286
|
+
white-space: nowrap;
|
|
287
|
+
}
|
|
288
|
+
.pinfold-accordion [data-overflow='clamp'] {
|
|
289
|
+
display: -webkit-box;
|
|
290
|
+
-webkit-box-orient: vertical;
|
|
291
|
+
-webkit-line-clamp: var(--pinfold-lines, 2);
|
|
292
|
+
line-clamp: var(--pinfold-lines, 2);
|
|
293
|
+
overflow: hidden;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
.pinfold-accordion__description {
|
|
297
|
+
font-size: var(--pinfold-acc-desc);
|
|
298
|
+
font-weight: var(--pinfold-weight-normal);
|
|
299
|
+
letter-spacing: var(--pinfold-tracking-normal);
|
|
300
|
+
color: var(--pinfold-color-text-muted);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
.pinfold-accordion__badge {
|
|
304
|
+
flex: none;
|
|
305
|
+
padding: 2px var(--pinfold-space-2);
|
|
306
|
+
font-size: var(--pinfold-text-xs);
|
|
307
|
+
font-weight: var(--pinfold-weight-semibold);
|
|
308
|
+
letter-spacing: var(--pinfold-tracking-wide);
|
|
309
|
+
/* Small text on a tint of its own colour: pulled halfway toward the text colour, so it
|
|
310
|
+
clears 4.5:1 in light and dark mode for every tone (checked by the a11y report). */
|
|
311
|
+
color: color-mix(in oklch, var(--pinfold-acc-accent) 55%, var(--pinfold-color-text));
|
|
312
|
+
background: color-mix(in oklch, var(--pinfold-acc-accent) 12%, transparent);
|
|
313
|
+
border-radius: var(--pinfold-radius-full);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
.pinfold-accordion__indicator {
|
|
317
|
+
display: inline-flex;
|
|
318
|
+
flex: none;
|
|
319
|
+
align-items: center;
|
|
320
|
+
justify-content: center;
|
|
321
|
+
font-size: var(--pinfold-acc-ind);
|
|
322
|
+
color: var(--pinfold-color-text-subtle);
|
|
323
|
+
transition: transform var(--pinfold-acc-duration) var(--pinfold-ease-out),
|
|
324
|
+
color var(--pinfold-duration-fast) var(--pinfold-ease);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
.pinfold-accordion__trigger:hover .pinfold-accordion__indicator {
|
|
328
|
+
color: var(--pinfold-color-text-muted);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
.pinfold-accordion__trigger[data-state='open'] .pinfold-accordion__indicator {
|
|
332
|
+
color: var(--pinfold-acc-accent);
|
|
333
|
+
transform: rotate(180deg);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/* The plus glyph morphs into a minus instead of spinning. */
|
|
337
|
+
.pinfold-accordion__indicator .pinfold-accordion__indicator-bar {
|
|
338
|
+
transform-origin: center;
|
|
339
|
+
transition: opacity var(--pinfold-acc-duration) var(--pinfold-ease),
|
|
340
|
+
transform var(--pinfold-acc-duration) var(--pinfold-ease-out);
|
|
341
|
+
}
|
|
342
|
+
.pinfold-accordion__trigger[data-state='open']
|
|
343
|
+
.pinfold-accordion__indicator:has(.pinfold-accordion__indicator-bar) {
|
|
344
|
+
transform: none;
|
|
345
|
+
}
|
|
346
|
+
.pinfold-accordion__trigger[data-state='open'] .pinfold-accordion__indicator-bar {
|
|
347
|
+
opacity: 0;
|
|
348
|
+
transform: rotate(90deg);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/* ------------------------------------------------------------------ panel */
|
|
352
|
+
.pinfold-accordion__panel {
|
|
353
|
+
display: grid;
|
|
354
|
+
grid-template-rows: 1fr;
|
|
355
|
+
color: var(--pinfold-color-text-muted);
|
|
356
|
+
font-size: var(--pinfold-text-sm);
|
|
357
|
+
line-height: var(--pinfold-leading-normal);
|
|
358
|
+
letter-spacing: var(--pinfold-tracking-normal);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
.pinfold-accordion__panel[data-state='closed'] {
|
|
362
|
+
grid-template-rows: 0fr;
|
|
363
|
+
/* Takes closed content out of the accessibility tree and the tab order once
|
|
364
|
+
the collapse finishes. */
|
|
365
|
+
visibility: hidden;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/* Find-in-page: once the inner box carries hidden="until-found", the browser
|
|
369
|
+
owns its visibility (content-visibility), so the panel itself must stay
|
|
370
|
+
visible for matches to be found. Before hydration the rule above applies. */
|
|
371
|
+
.pinfold-accordion__panel[data-state='closed']:has(> [hidden='until-found']) {
|
|
372
|
+
visibility: visible;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
.pinfold-accordion[data-animate] .pinfold-accordion__panel {
|
|
376
|
+
transition: grid-template-rows var(--pinfold-acc-duration) var(--pinfold-ease-out),
|
|
377
|
+
visibility 0s linear 0s;
|
|
378
|
+
}
|
|
379
|
+
.pinfold-accordion[data-animate] .pinfold-accordion__panel[data-state='closed'] {
|
|
380
|
+
transition: grid-template-rows var(--pinfold-acc-duration) var(--pinfold-ease),
|
|
381
|
+
visibility 0s linear var(--pinfold-acc-duration);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
.pinfold-accordion__panel-inner {
|
|
385
|
+
min-height: 0;
|
|
386
|
+
overflow: hidden;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
/* Content settles in slightly behind the row opening — the lag is what makes
|
|
390
|
+
the motion read as physical rather than mechanical. */
|
|
391
|
+
.pinfold-accordion[data-animate] .pinfold-accordion__content {
|
|
392
|
+
opacity: 0;
|
|
393
|
+
transform: translateY(-4px);
|
|
394
|
+
transition: opacity var(--pinfold-acc-duration) var(--pinfold-ease),
|
|
395
|
+
transform var(--pinfold-acc-duration) var(--pinfold-ease-out);
|
|
396
|
+
}
|
|
397
|
+
.pinfold-accordion[data-animate] .pinfold-accordion__panel[data-state='open'] .pinfold-accordion__content {
|
|
398
|
+
opacity: 1;
|
|
399
|
+
transform: none;
|
|
400
|
+
transition-delay: calc(var(--pinfold-acc-duration) * 0.35);
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
/* `dimensions.panelMaxHeight` caps the open panel and scrolls the rest. */
|
|
404
|
+
.pinfold-accordion[data-scroll] .pinfold-accordion__panel[data-state='open'] .pinfold-accordion__panel-inner {
|
|
405
|
+
max-height: var(--pinfold-accordion-panel-max-height);
|
|
406
|
+
overflow-y: auto;
|
|
407
|
+
overscroll-behavior: contain;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
.pinfold-accordion__content {
|
|
411
|
+
padding: 0 var(--pinfold-acc-panel-pad-x) var(--pinfold-acc-panel-pad-y);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
.pinfold-accordion[data-indicator-position='start'] .pinfold-accordion__content {
|
|
415
|
+
padding-inline-start: calc(var(--pinfold-acc-panel-pad-x) + var(--pinfold-acc-icon) + var(--pinfold-space-3));
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
/* ------------------------------------------------------------- responsive */
|
|
419
|
+
/* Narrow containers: the badge drops under the title so the title keeps its
|
|
420
|
+
width; the indicator stays on the first line. */
|
|
421
|
+
@container pinfold-accordion (max-width: 26rem) {
|
|
422
|
+
.pinfold-accordion__trigger {
|
|
423
|
+
flex-wrap: wrap;
|
|
424
|
+
row-gap: var(--pinfold-space-1);
|
|
425
|
+
}
|
|
426
|
+
/* Leaves room for the icon and indicator only, so the badge must wrap. */
|
|
427
|
+
.pinfold-accordion__label {
|
|
428
|
+
flex-basis: calc(100% - 4.5em);
|
|
429
|
+
}
|
|
430
|
+
.pinfold-accordion__indicator {
|
|
431
|
+
order: 1;
|
|
432
|
+
}
|
|
433
|
+
.pinfold-accordion__badge {
|
|
434
|
+
order: 2;
|
|
435
|
+
margin-inline-start: calc(var(--pinfold-acc-icon) + var(--pinfold-space-3));
|
|
436
|
+
}
|
|
437
|
+
.pinfold-accordion__trigger:not(:has(.pinfold-accordion__icon)) .pinfold-accordion__badge {
|
|
438
|
+
margin-inline-start: 0;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
/* Touch: every trigger is at least 44px tall (WCAG 2.5.5 / 2.5.8). */
|
|
443
|
+
@media (pointer: coarse) {
|
|
444
|
+
.pinfold-accordion__trigger {
|
|
445
|
+
min-height: 44px;
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
@supports not (color: color-mix(in oklch, red, blue)) {
|
|
450
|
+
.pinfold-accordion__badge {
|
|
451
|
+
background: var(--pinfold-color-bg-subtle);
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
}
|