@ponchia/ui 0.2.1 → 0.3.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 +128 -54
- package/behaviors/index.d.ts +36 -0
- package/behaviors/index.js +321 -7
- package/classes/index.d.ts +228 -3
- package/classes/index.js +139 -4
- package/css/app.css +64 -64
- package/css/base.css +136 -24
- package/css/content.css +324 -0
- package/css/core.css +9 -5
- package/css/disclosure.css +323 -0
- package/css/dots.css +125 -8
- package/css/feedback.css +243 -0
- package/css/fonts.css +11 -0
- package/css/forms.css +41 -14
- package/css/motion.css +29 -5
- package/css/navigation.css +22 -86
- package/css/overlay.css +206 -0
- package/css/primitives.css +37 -18
- package/css/site.css +295 -0
- package/css/table.css +9 -9
- package/css/tokens.css +84 -20
- package/dist/bronto.css +1 -0
- package/dist/css/app.css +1 -0
- package/dist/css/base.css +1 -0
- package/dist/css/content.css +1 -0
- package/dist/css/disclosure.css +1 -0
- package/dist/css/dots.css +1 -0
- package/dist/css/feedback.css +1 -0
- package/dist/css/fonts.css +1 -0
- package/dist/css/forms.css +1 -0
- package/dist/css/motion.css +1 -0
- package/dist/css/navigation.css +1 -0
- package/dist/css/overlay.css +1 -0
- package/dist/css/primitives.css +1 -0
- package/dist/css/site.css +1 -0
- package/dist/css/table.css +1 -0
- package/dist/css/tokens.css +1 -0
- package/package.json +62 -21
- package/shiki/nothing.json +83 -0
- package/tokens/index.d.ts +18 -10
- package/tokens/index.js +16 -14
- package/tokens/index.json +32 -28
- package/tokens/tokens.dtcg.json +589 -0
- package/css/cards.css +0 -336
- package/css/index.css +0 -5
- package/css/layout.css +0 -219
- package/css/responsive.css +0 -157
- package/css/typography.css +0 -139
package/css/content.css
ADDED
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
/* ==========================================================================
|
|
2
|
+
content — .ui-prose: long-form rich text, zero per-element classes.
|
|
3
|
+
|
|
4
|
+
Wrap the raw HTML a Markdown renderer emits in a single `.ui-prose`
|
|
5
|
+
and the document is styled in the Nothing aesthetic while the markup
|
|
6
|
+
stays semantic and machine-readable (no class-soup). Everything here
|
|
7
|
+
is an element selector scoped under `.ui-prose`, so it never leaks
|
|
8
|
+
into app UI.
|
|
9
|
+
========================================================================== */
|
|
10
|
+
|
|
11
|
+
.ui-prose {
|
|
12
|
+
color: var(--text-soft);
|
|
13
|
+
font-size: var(--text-base);
|
|
14
|
+
line-height: 1.7;
|
|
15
|
+
|
|
16
|
+
/* Readable measure; the container can still be wider for tables/media. */
|
|
17
|
+
--prose-measure: 72ch;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.ui-prose > * {
|
|
21
|
+
margin-block: 0;
|
|
22
|
+
max-inline-size: var(--prose-measure);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/* Flow rhythm — space comes from the following element. */
|
|
26
|
+
.ui-prose > * + * {
|
|
27
|
+
margin-block-start: var(--space-md);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.ui-prose > * + :is(h1, h2, h3, h4, h5, h6) {
|
|
31
|
+
margin-block-start: var(--space-2xl);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/* Full-bleed-ish elements opt out of the text measure. */
|
|
35
|
+
.ui-prose > :is(figure, pre, table, hr, .ui-dotrule) {
|
|
36
|
+
max-inline-size: none;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/* --- Headings — brand display face; only the top two shout --- */
|
|
40
|
+
|
|
41
|
+
.ui-prose :is(h1, h2, h3, h4, h5, h6) {
|
|
42
|
+
color: var(--text);
|
|
43
|
+
font-family: var(--display);
|
|
44
|
+
line-height: 1.12;
|
|
45
|
+
text-wrap: balance;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.ui-prose h1 {
|
|
49
|
+
font-size: var(--text-xl);
|
|
50
|
+
letter-spacing: var(--tracking-wide);
|
|
51
|
+
text-transform: uppercase;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.ui-prose h2 {
|
|
55
|
+
font-size: var(--text-lg);
|
|
56
|
+
letter-spacing: var(--tracking-wide);
|
|
57
|
+
padding-block-end: 0.3rem;
|
|
58
|
+
border-block-end: 1px solid var(--line);
|
|
59
|
+
text-transform: uppercase;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.ui-prose h3 {
|
|
63
|
+
font-size: var(--text-lg);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.ui-prose :is(h4, h5, h6) {
|
|
67
|
+
font-size: var(--text-base);
|
|
68
|
+
letter-spacing: var(--tracking-wide);
|
|
69
|
+
text-transform: uppercase;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.ui-prose :is(h5, h6) {
|
|
73
|
+
color: var(--text-dim);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/* Anchored headings clear a sticky chrome and expose a dot on hover. */
|
|
77
|
+
.ui-prose :is(h1, h2, h3, h4, h5, h6)[id] {
|
|
78
|
+
scroll-margin-block-start: 6rem;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/* --- Text-level --- */
|
|
82
|
+
|
|
83
|
+
.ui-prose :is(p, ul, ol, dl, blockquote, figure, pre, table) {
|
|
84
|
+
font-size: inherit;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.ui-prose a {
|
|
88
|
+
color: var(--text);
|
|
89
|
+
text-decoration: underline;
|
|
90
|
+
text-decoration-color: color-mix(in srgb, var(--accent) 55%, transparent);
|
|
91
|
+
text-decoration-thickness: 1px;
|
|
92
|
+
text-underline-offset: 0.22rem;
|
|
93
|
+
transition:
|
|
94
|
+
color var(--duration-fast) var(--ease-standard),
|
|
95
|
+
text-decoration-color var(--duration-fast) var(--ease-standard);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.ui-prose strong {
|
|
99
|
+
color: var(--text);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.ui-prose mark {
|
|
103
|
+
background: var(--accent-soft);
|
|
104
|
+
color: var(--text);
|
|
105
|
+
padding: 0.02em 0.22em;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.ui-prose small {
|
|
109
|
+
font-size: var(--text-xs);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.ui-prose abbr[title] {
|
|
113
|
+
text-decoration: underline dotted;
|
|
114
|
+
text-underline-offset: 0.2rem;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.ui-prose :is(sub, sup) {
|
|
118
|
+
font-size: 0.72em;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
@media (hover: hover) {
|
|
122
|
+
.ui-prose a:hover {
|
|
123
|
+
color: var(--accent-text);
|
|
124
|
+
text-decoration-color: var(--accent);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/* --- Lists — the Nothing dot/square marker --- */
|
|
129
|
+
|
|
130
|
+
.ui-prose :is(ul, ol) {
|
|
131
|
+
padding-inline-start: 1.4rem;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.ui-prose li + li {
|
|
135
|
+
margin-block-start: 0.4rem;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
.ui-prose li::marker {
|
|
139
|
+
color: var(--accent-text);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.ui-prose ul {
|
|
143
|
+
list-style: square;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.ui-prose :is(ul, ol) :is(ul, ol) {
|
|
147
|
+
margin-block-start: 0.4rem;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/* GitHub task lists stay semantic; just align them. */
|
|
151
|
+
.ui-prose li:has(> input[type='checkbox']) {
|
|
152
|
+
list-style: none;
|
|
153
|
+
margin-inline-start: -1.4rem;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
.ui-prose li > input[type='checkbox'] {
|
|
157
|
+
accent-color: var(--accent);
|
|
158
|
+
margin-inline-end: 0.4rem;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/* --- Quote --- */
|
|
162
|
+
|
|
163
|
+
.ui-prose blockquote {
|
|
164
|
+
border-inline-start: 2px solid var(--accent);
|
|
165
|
+
color: var(--text-dim);
|
|
166
|
+
font-style: normal;
|
|
167
|
+
padding-inline-start: var(--space-md);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
.ui-prose blockquote > * + * {
|
|
171
|
+
margin-block-start: var(--space-xs);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/* --- Definition list --- */
|
|
175
|
+
|
|
176
|
+
.ui-prose dt {
|
|
177
|
+
color: var(--text-dim);
|
|
178
|
+
font-family: var(--mono);
|
|
179
|
+
font-size: var(--text-2xs);
|
|
180
|
+
font-weight: 700;
|
|
181
|
+
letter-spacing: var(--tracking-wide);
|
|
182
|
+
text-transform: uppercase;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
.ui-prose dd {
|
|
186
|
+
margin-inline-start: 0;
|
|
187
|
+
padding-block: 0.16rem 0.6rem;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.ui-prose dd + dt {
|
|
191
|
+
border-block-start: 1px solid var(--line);
|
|
192
|
+
padding-block-start: 0.6rem;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/* --- Code --- */
|
|
196
|
+
|
|
197
|
+
.ui-prose :not(pre) > code {
|
|
198
|
+
font-size: 0.88em;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
.ui-prose pre {
|
|
202
|
+
font-size: var(--text-sm);
|
|
203
|
+
line-height: 1.6;
|
|
204
|
+
overflow-x: auto;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/* --- Rule — reuse the dot-matrix divider look --- */
|
|
208
|
+
|
|
209
|
+
.ui-prose hr {
|
|
210
|
+
background-image: radial-gradient(var(--line-strong) 1.4px, transparent 1.4px);
|
|
211
|
+
background-position: 0 50%;
|
|
212
|
+
background-size: 9px 9px;
|
|
213
|
+
block-size: 3px;
|
|
214
|
+
border: 0;
|
|
215
|
+
margin-block: var(--space-xl);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/* --- Media --- */
|
|
219
|
+
|
|
220
|
+
.ui-prose :is(img, video, svg) {
|
|
221
|
+
block-size: auto;
|
|
222
|
+
border-radius: var(--radius-sm);
|
|
223
|
+
max-inline-size: 100%;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
.ui-prose figure {
|
|
227
|
+
display: grid;
|
|
228
|
+
gap: 0.5rem;
|
|
229
|
+
justify-items: start;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
.ui-prose figcaption {
|
|
233
|
+
color: var(--text-dim);
|
|
234
|
+
font-family: var(--mono);
|
|
235
|
+
font-size: var(--text-2xs);
|
|
236
|
+
letter-spacing: var(--tracking-wide);
|
|
237
|
+
text-transform: uppercase;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/* --- Table — raw Markdown tables look like ui-table --- */
|
|
241
|
+
|
|
242
|
+
.ui-prose table {
|
|
243
|
+
border: 1px solid var(--line);
|
|
244
|
+
border-collapse: collapse;
|
|
245
|
+
border-radius: var(--radius-md);
|
|
246
|
+
display: block;
|
|
247
|
+
font-family: var(--mono);
|
|
248
|
+
font-size: var(--text-sm);
|
|
249
|
+
inline-size: 100%;
|
|
250
|
+
overflow-x: auto;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
.ui-prose :is(th, td) {
|
|
254
|
+
border-block-end: 1px solid var(--line);
|
|
255
|
+
padding: 0.6rem 0.8rem;
|
|
256
|
+
text-align: start;
|
|
257
|
+
vertical-align: top;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
.ui-prose th {
|
|
261
|
+
background: var(--panel);
|
|
262
|
+
color: var(--text-dim);
|
|
263
|
+
font-size: var(--text-2xs);
|
|
264
|
+
font-weight: 700;
|
|
265
|
+
letter-spacing: var(--tracking-wide);
|
|
266
|
+
text-transform: uppercase;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
.ui-prose td {
|
|
270
|
+
color: var(--text-soft);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
.ui-prose tbody tr:last-child :is(th, td) {
|
|
274
|
+
border-block-end: 0;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/* --- Compact variant — tighter rhythm for dense docs --- */
|
|
278
|
+
|
|
279
|
+
.ui-prose--compact {
|
|
280
|
+
line-height: 1.55;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
.ui-prose--compact > * + * {
|
|
284
|
+
margin-block-start: var(--space-sm);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
.ui-prose--compact > * + :is(h1, h2, h3, h4, h5, h6) {
|
|
288
|
+
margin-block-start: var(--space-lg);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/* ==========================================================================
|
|
292
|
+
ui-quote — pull-quote with attribution. A long-form companion to
|
|
293
|
+
.ui-prose (works inside it or standalone). Emphasis via scale + a
|
|
294
|
+
short accent rule, not a tinted box. Use <figure>/<blockquote> +
|
|
295
|
+
<figcaption>; tag-agnostic.
|
|
296
|
+
========================================================================== */
|
|
297
|
+
|
|
298
|
+
.ui-quote {
|
|
299
|
+
color: var(--text);
|
|
300
|
+
display: grid;
|
|
301
|
+
font-family: var(--display);
|
|
302
|
+
font-size: var(--text-xl);
|
|
303
|
+
gap: var(--space-sm);
|
|
304
|
+
line-height: 1.2;
|
|
305
|
+
margin-block: var(--space-xl);
|
|
306
|
+
max-inline-size: 40ch;
|
|
307
|
+
text-wrap: balance;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
.ui-quote::before {
|
|
311
|
+
background: var(--accent);
|
|
312
|
+
block-size: 2px;
|
|
313
|
+
content: '';
|
|
314
|
+
inline-size: 2.5rem;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
.ui-quote__cite {
|
|
318
|
+
color: var(--text-dim);
|
|
319
|
+
font-family: var(--mono);
|
|
320
|
+
font-size: var(--text-2xs);
|
|
321
|
+
font-style: normal;
|
|
322
|
+
letter-spacing: var(--tracking-wide);
|
|
323
|
+
text-transform: uppercase;
|
|
324
|
+
}
|
package/css/core.css
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
/* @ponchia/ui —
|
|
2
|
-
|
|
1
|
+
/* @ponchia/ui — the CSS bundle (single source entrypoint).
|
|
2
|
+
The legacy non-ui-* vocabulary and the separate responsive layer were
|
|
3
|
+
removed in 0.3.0; the ui-* components carry their own breakpoints, so
|
|
4
|
+
there is one bundle, not a core/full split.
|
|
3
5
|
|
|
4
6
|
Everything ships inside the `bronto` cascade layer. Any un-layered CSS
|
|
5
7
|
in the consuming app therefore wins over the framework without a
|
|
@@ -12,11 +14,13 @@
|
|
|
12
14
|
@import url('./base.css') layer(bronto);
|
|
13
15
|
@import url('./motion.css') layer(bronto);
|
|
14
16
|
@import url('./dots.css') layer(bronto);
|
|
15
|
-
@import url('./layout.css') layer(bronto);
|
|
16
17
|
@import url('./navigation.css') layer(bronto);
|
|
17
|
-
@import url('./
|
|
18
|
+
@import url('./site.css') layer(bronto);
|
|
19
|
+
@import url('./content.css') layer(bronto);
|
|
18
20
|
@import url('./primitives.css') layer(bronto);
|
|
19
21
|
@import url('./forms.css') layer(bronto);
|
|
22
|
+
@import url('./feedback.css') layer(bronto);
|
|
23
|
+
@import url('./overlay.css') layer(bronto);
|
|
24
|
+
@import url('./disclosure.css') layer(bronto);
|
|
20
25
|
@import url('./table.css') layer(bronto);
|
|
21
|
-
@import url('./cards.css') layer(bronto);
|
|
22
26
|
@import url('./app.css') layer(bronto);
|
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
/* ==========================================================================
|
|
2
|
+
disclosure — tabs / accordion / segmented / breadcrumb / pagination / avatar
|
|
3
|
+
Tabs use an ARIA + .is-active contract (toggle via your framework or the
|
|
4
|
+
shipped behaviors); accordion is native <details>; segmented is a
|
|
5
|
+
CSS-only :has() radio group. All Nothing-flat with the dot cue.
|
|
6
|
+
========================================================================== */
|
|
7
|
+
|
|
8
|
+
/* --- Tabs --- */
|
|
9
|
+
|
|
10
|
+
.ui-tabs {
|
|
11
|
+
display: grid;
|
|
12
|
+
gap: var(--space-md);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.ui-tabs__list {
|
|
16
|
+
border-block-end: 1px solid var(--line);
|
|
17
|
+
display: flex;
|
|
18
|
+
gap: 0.1rem;
|
|
19
|
+
overflow-x: auto;
|
|
20
|
+
scrollbar-width: none;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.ui-tabs__list::-webkit-scrollbar {
|
|
24
|
+
display: none;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.ui-tab {
|
|
28
|
+
background: transparent;
|
|
29
|
+
border: 0;
|
|
30
|
+
border-block-end: 2px solid transparent;
|
|
31
|
+
color: var(--text-dim);
|
|
32
|
+
cursor: pointer;
|
|
33
|
+
display: inline-flex;
|
|
34
|
+
flex: 0 0 auto;
|
|
35
|
+
font-family: var(--mono);
|
|
36
|
+
font-size: var(--text-xs);
|
|
37
|
+
gap: 0.4rem;
|
|
38
|
+
letter-spacing: var(--tracking-wide);
|
|
39
|
+
margin-block-end: -1px;
|
|
40
|
+
padding: 0.6rem 0.85rem;
|
|
41
|
+
text-transform: uppercase;
|
|
42
|
+
transition:
|
|
43
|
+
color var(--duration-fast) var(--ease-standard),
|
|
44
|
+
border-color var(--duration-fast) var(--ease-standard);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.ui-tab.is-active {
|
|
48
|
+
border-block-end-color: var(--accent);
|
|
49
|
+
color: var(--accent-text);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.ui-tab:focus-visible {
|
|
53
|
+
/* An inset box, deliberately distinct from the .is-active bottom-border
|
|
54
|
+
so focus ≠ selection for low-vision keyboard users: the global
|
|
55
|
+
button:focus-visible ring would otherwise sit exactly on the active
|
|
56
|
+
underline. Geometry (inset offset), not colour, carries the
|
|
57
|
+
distinction — colour stays the solid accent used by every other
|
|
58
|
+
control's ring (the --focus-ring token wiring is decided globally,
|
|
59
|
+
not per-component). */
|
|
60
|
+
outline: 2px solid var(--focus-ring);
|
|
61
|
+
outline-offset: -3px;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.ui-tabs__panel[hidden] {
|
|
65
|
+
display: none;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
@media (hover: hover) {
|
|
69
|
+
.ui-tab:hover:not(.is-active) {
|
|
70
|
+
color: var(--text);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/* --- Accordion — styled native <details> --- */
|
|
75
|
+
|
|
76
|
+
.ui-accordion {
|
|
77
|
+
display: grid;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.ui-accordion__item {
|
|
81
|
+
border-block-end: 1px solid var(--line);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.ui-accordion__summary {
|
|
85
|
+
align-items: center;
|
|
86
|
+
color: var(--text);
|
|
87
|
+
cursor: pointer;
|
|
88
|
+
display: flex;
|
|
89
|
+
font-family: var(--mono);
|
|
90
|
+
font-size: var(--text-sm);
|
|
91
|
+
gap: 0.6rem;
|
|
92
|
+
letter-spacing: var(--tracking-wide);
|
|
93
|
+
list-style: none;
|
|
94
|
+
padding: 0.85rem 0.2rem;
|
|
95
|
+
text-transform: uppercase;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.ui-accordion__summary::-webkit-details-marker {
|
|
99
|
+
display: none;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/* Dot marker rotates into an arrow cue when open. */
|
|
103
|
+
.ui-accordion__summary::before {
|
|
104
|
+
border-inline-end: 1.5px solid var(--text-dim);
|
|
105
|
+
border-block-end: 1.5px solid var(--text-dim);
|
|
106
|
+
content: '';
|
|
107
|
+
block-size: 0.4rem;
|
|
108
|
+
transform: rotate(-45deg);
|
|
109
|
+
transition: transform var(--duration-fast) var(--ease-spring);
|
|
110
|
+
inline-size: 0.4rem;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.ui-accordion__item[open] .ui-accordion__summary {
|
|
114
|
+
color: var(--accent-text);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.ui-accordion__item[open] .ui-accordion__summary::before {
|
|
118
|
+
border-color: var(--accent);
|
|
119
|
+
transform: rotate(45deg);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.ui-accordion__body {
|
|
123
|
+
color: var(--text-soft);
|
|
124
|
+
padding: 0 0.2rem 0.95rem;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.ui-accordion__body > :first-child {
|
|
128
|
+
margin-block-start: 0;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/* --- Segmented control — CSS-only radio group --- */
|
|
132
|
+
|
|
133
|
+
.ui-segmented {
|
|
134
|
+
background: var(--panel-soft);
|
|
135
|
+
border: 1px solid var(--line-strong);
|
|
136
|
+
border-radius: var(--radius-md);
|
|
137
|
+
display: inline-flex;
|
|
138
|
+
gap: 1px;
|
|
139
|
+
overflow: hidden;
|
|
140
|
+
padding: 2px;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.ui-segmented__option {
|
|
144
|
+
border-radius: var(--radius-sm);
|
|
145
|
+
color: var(--text-soft);
|
|
146
|
+
cursor: pointer;
|
|
147
|
+
flex: 1 0 auto;
|
|
148
|
+
font-family: var(--mono);
|
|
149
|
+
font-size: var(--text-xs);
|
|
150
|
+
letter-spacing: var(--tracking-wide);
|
|
151
|
+
padding: 0.42rem 0.8rem;
|
|
152
|
+
text-align: center;
|
|
153
|
+
text-transform: uppercase;
|
|
154
|
+
transition:
|
|
155
|
+
background-color var(--duration-fast) var(--ease-standard),
|
|
156
|
+
color var(--duration-fast) var(--ease-standard);
|
|
157
|
+
white-space: nowrap;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
.ui-segmented__option input {
|
|
161
|
+
position: absolute;
|
|
162
|
+
opacity: 0;
|
|
163
|
+
pointer-events: none;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
.ui-segmented__option:has(input:checked) {
|
|
167
|
+
background: var(--accent);
|
|
168
|
+
color: var(--button-text);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
.ui-segmented__option:has(input:focus-visible) {
|
|
172
|
+
outline: 2px solid var(--focus-ring);
|
|
173
|
+
outline-offset: 2px;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
@media (hover: hover) {
|
|
177
|
+
.ui-segmented__option:hover:not(:has(input:checked)) {
|
|
178
|
+
color: var(--text);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/* --- Breadcrumb --- */
|
|
183
|
+
|
|
184
|
+
.ui-breadcrumb {
|
|
185
|
+
align-items: center;
|
|
186
|
+
color: var(--text-dim);
|
|
187
|
+
display: flex;
|
|
188
|
+
flex-wrap: wrap;
|
|
189
|
+
font-family: var(--mono);
|
|
190
|
+
font-size: var(--text-2xs);
|
|
191
|
+
gap: 0.5rem;
|
|
192
|
+
letter-spacing: var(--tracking-wide);
|
|
193
|
+
list-style: none;
|
|
194
|
+
margin: 0;
|
|
195
|
+
padding: 0;
|
|
196
|
+
text-transform: uppercase;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
.ui-breadcrumb__item {
|
|
200
|
+
align-items: center;
|
|
201
|
+
color: var(--text-dim);
|
|
202
|
+
display: inline-flex;
|
|
203
|
+
gap: 0.5rem;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
.ui-breadcrumb__item:not(:last-child)::after {
|
|
207
|
+
background: var(--line-strong);
|
|
208
|
+
border-radius: 50%;
|
|
209
|
+
content: '';
|
|
210
|
+
block-size: 0.22rem;
|
|
211
|
+
inline-size: 0.22rem;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
.ui-breadcrumb__item[aria-current] {
|
|
215
|
+
color: var(--text);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
.ui-breadcrumb__item a {
|
|
219
|
+
color: inherit;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
@media (hover: hover) {
|
|
223
|
+
.ui-breadcrumb__item a:hover {
|
|
224
|
+
color: var(--accent-text);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/* --- Pagination --- */
|
|
229
|
+
|
|
230
|
+
.ui-pagination {
|
|
231
|
+
align-items: center;
|
|
232
|
+
display: flex;
|
|
233
|
+
flex-wrap: wrap;
|
|
234
|
+
gap: 0.3rem;
|
|
235
|
+
list-style: none;
|
|
236
|
+
margin: 0;
|
|
237
|
+
padding: 0;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
.ui-pagination__item {
|
|
241
|
+
align-items: center;
|
|
242
|
+
background: transparent;
|
|
243
|
+
border: 1px solid var(--line);
|
|
244
|
+
border-radius: var(--radius-sm);
|
|
245
|
+
color: var(--text-soft);
|
|
246
|
+
cursor: pointer;
|
|
247
|
+
display: inline-flex;
|
|
248
|
+
font-family: var(--mono);
|
|
249
|
+
font-size: var(--text-xs);
|
|
250
|
+
justify-content: center;
|
|
251
|
+
min-block-size: 2rem;
|
|
252
|
+
min-inline-size: 2rem;
|
|
253
|
+
padding: 0 0.5rem;
|
|
254
|
+
transition:
|
|
255
|
+
border-color var(--duration-fast) var(--ease-standard),
|
|
256
|
+
color var(--duration-fast) var(--ease-standard);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
.ui-pagination__item.is-active {
|
|
260
|
+
border-color: var(--accent);
|
|
261
|
+
color: var(--accent-text);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
.ui-pagination__item[aria-disabled='true'] {
|
|
265
|
+
cursor: not-allowed;
|
|
266
|
+
opacity: 0.4;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
@media (hover: hover) {
|
|
270
|
+
.ui-pagination__item:not(.is-active, [aria-disabled='true']):hover {
|
|
271
|
+
border-color: var(--line-strong);
|
|
272
|
+
color: var(--text);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/* --- Avatar — sharp, monospace initials or image --- */
|
|
277
|
+
|
|
278
|
+
.ui-avatar {
|
|
279
|
+
--av-size: 2.2rem;
|
|
280
|
+
|
|
281
|
+
align-items: center;
|
|
282
|
+
background: var(--panel-soft);
|
|
283
|
+
border: 1px solid var(--line-strong);
|
|
284
|
+
border-radius: var(--radius-sm);
|
|
285
|
+
color: var(--text);
|
|
286
|
+
display: inline-flex;
|
|
287
|
+
flex: 0 0 auto;
|
|
288
|
+
font-family: var(--mono);
|
|
289
|
+
font-size: calc(var(--av-size) * 0.38);
|
|
290
|
+
font-weight: 700;
|
|
291
|
+
block-size: var(--av-size);
|
|
292
|
+
justify-content: center;
|
|
293
|
+
letter-spacing: 0.04em;
|
|
294
|
+
overflow: hidden;
|
|
295
|
+
text-transform: uppercase;
|
|
296
|
+
inline-size: var(--av-size);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
.ui-avatar img {
|
|
300
|
+
block-size: 100%;
|
|
301
|
+
object-fit: cover;
|
|
302
|
+
inline-size: 100%;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
.ui-avatar--sm {
|
|
306
|
+
--av-size: 1.5rem;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
.ui-avatar--lg {
|
|
310
|
+
--av-size: 3.2rem;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
.ui-avatar-group {
|
|
314
|
+
display: inline-flex;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
.ui-avatar-group .ui-avatar {
|
|
318
|
+
box-shadow: 0 0 0 2px var(--bg);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
.ui-avatar-group .ui-avatar:not(:first-child) {
|
|
322
|
+
margin-inline-start: -0.5rem;
|
|
323
|
+
}
|