@ponchia/ui 0.2.2 → 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/css/base.css CHANGED
@@ -161,26 +161,10 @@ input:focus-visible,
161
161
  select:focus-visible,
162
162
  textarea:focus-visible,
163
163
  [tabindex]:focus-visible {
164
- outline: 2px solid var(--accent);
164
+ outline: 2px solid var(--focus-ring);
165
165
  outline-offset: 2px;
166
166
  }
167
167
 
168
- .skip-link {
169
- background: var(--panel-strong);
170
- border: 1px solid var(--line-strong);
171
- border-radius: var(--radius-md);
172
- color: var(--text);
173
- inset-inline-start: 1rem;
174
- padding: 0.7rem 1rem;
175
- position: fixed;
176
- inset-block-start: -4rem;
177
- z-index: 40;
178
- }
179
-
180
- .skip-link:focus {
181
- inset-block-start: 1rem;
182
- }
183
-
184
168
  /* Small global helpers reused across apps. */
185
169
  .ui-muted {
186
170
  color: var(--text-dim);
@@ -236,6 +220,14 @@ textarea:focus-visible,
236
220
  outline-offset: -2px;
237
221
  }
238
222
 
223
+ /* The active tab signals selection only via accent colour/border, both
224
+ flattened by the forced palette — re-assert it with a system colour
225
+ so the selected tab stays distinguishable (a11y review L3). */
226
+ .ui-tab.is-active {
227
+ border-block-end-color: Highlight;
228
+ color: Highlight;
229
+ }
230
+
239
231
  /* Keyboard focus must never depend on a colour that gets overridden. */
240
232
  a:focus-visible,
241
233
  button:focus-visible,
@@ -262,11 +254,11 @@ textarea:focus-visible,
262
254
  /* Decorative / interactive chrome never prints. */
263
255
  .ui-dotfield,
264
256
  .ui-toast-stack,
265
- .app-rail,
266
- .app-topbar,
267
- .site-nav,
268
- .theme-toggle__button,
269
- .site-menu,
257
+ .ui-app-rail,
258
+ .ui-app-topbar,
259
+ .ui-sitenav,
260
+ .ui-themetoggle__button,
261
+ .ui-sitemenu,
270
262
  .ui-spinner,
271
263
  .ui-dotloader,
272
264
  .ui-dotspinner,
package/css/content.css CHANGED
@@ -120,7 +120,7 @@
120
120
 
121
121
  @media (hover: hover) {
122
122
  .ui-prose a:hover {
123
- color: var(--accent);
123
+ color: var(--accent-text);
124
124
  text-decoration-color: var(--accent);
125
125
  }
126
126
  }
@@ -136,7 +136,7 @@
136
136
  }
137
137
 
138
138
  .ui-prose li::marker {
139
- color: var(--accent);
139
+ color: var(--accent-text);
140
140
  }
141
141
 
142
142
  .ui-prose ul {
@@ -287,3 +287,38 @@
287
287
  .ui-prose--compact > * + :is(h1, h2, h3, h4, h5, h6) {
288
288
  margin-block-start: var(--space-lg);
289
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 — core bundle (no breakpoint overrides).
2
- Consumers that manage their own responsive layer import this.
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,9 +14,8 @@
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('./typography.css') layer(bronto);
18
+ @import url('./site.css') layer(bronto);
18
19
  @import url('./content.css') layer(bronto);
19
20
  @import url('./primitives.css') layer(bronto);
20
21
  @import url('./forms.css') layer(bronto);
@@ -22,5 +23,4 @@
22
23
  @import url('./overlay.css') layer(bronto);
23
24
  @import url('./disclosure.css') layer(bronto);
24
25
  @import url('./table.css') layer(bronto);
25
- @import url('./cards.css') layer(bronto);
26
26
  @import url('./app.css') layer(bronto);
@@ -46,7 +46,19 @@
46
46
 
47
47
  .ui-tab.is-active {
48
48
  border-block-end-color: var(--accent);
49
- 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;
50
62
  }
51
63
 
52
64
  .ui-tabs__panel[hidden] {
@@ -99,7 +111,7 @@
99
111
  }
100
112
 
101
113
  .ui-accordion__item[open] .ui-accordion__summary {
102
- color: var(--accent);
114
+ color: var(--accent-text);
103
115
  }
104
116
 
105
117
  .ui-accordion__item[open] .ui-accordion__summary::before {
@@ -157,7 +169,7 @@
157
169
  }
158
170
 
159
171
  .ui-segmented__option:has(input:focus-visible) {
160
- outline: 2px solid var(--accent);
172
+ outline: 2px solid var(--focus-ring);
161
173
  outline-offset: 2px;
162
174
  }
163
175
 
@@ -209,7 +221,7 @@
209
221
 
210
222
  @media (hover: hover) {
211
223
  .ui-breadcrumb__item a:hover {
212
- color: var(--accent);
224
+ color: var(--accent-text);
213
225
  }
214
226
  }
215
227
 
@@ -246,7 +258,7 @@
246
258
 
247
259
  .ui-pagination__item.is-active {
248
260
  border-color: var(--accent);
249
- color: var(--accent);
261
+ color: var(--accent-text);
250
262
  }
251
263
 
252
264
  .ui-pagination__item[aria-disabled='true'] {
package/css/forms.css CHANGED
@@ -66,7 +66,7 @@
66
66
  .ui-input:focus-visible,
67
67
  .ui-select:focus-visible,
68
68
  .ui-textarea:focus-visible {
69
- outline: 2px solid var(--accent);
69
+ outline: 2px solid var(--focus-ring);
70
70
  outline-offset: 1px;
71
71
  }
72
72
 
@@ -183,7 +183,7 @@
183
183
  }
184
184
 
185
185
  .ui-switch input:focus-visible + .ui-switch__track {
186
- outline: 2px solid var(--accent);
186
+ outline: 2px solid var(--focus-ring);
187
187
  outline-offset: 2px;
188
188
  }
189
189
 
@@ -1,15 +1,10 @@
1
1
  /* ==========================================================================
2
- navigation — site nav, menu, theme toggle (Nothing flat, dot indicator)
3
- Class names kept stable for site-nav compatibility.
2
+ navigation — theme toggle (Nothing flat, dot-thumb switch).
3
+ Site nav/menu live in site.css as ui-sitenav / ui-sitemenu; the legacy
4
+ .site-nav / .site-menu vocabulary was removed in 0.3.0.
4
5
  ========================================================================== */
5
6
 
6
- .site-menu {
7
- display: none;
8
- position: relative;
9
- }
10
-
11
- .site-menu__toggle,
12
- .theme-toggle__button {
7
+ .ui-themetoggle__button {
13
8
  align-items: center;
14
9
  background: transparent;
15
10
  border: 1px solid var(--line-strong);
@@ -21,9 +16,10 @@
21
16
  font-size: var(--text-xs);
22
17
  font-weight: 600;
23
18
  gap: 0.4rem;
19
+ justify-content: center;
24
20
  letter-spacing: var(--tracking-wide);
25
- list-style: none;
26
21
  min-block-size: 2rem;
22
+ min-inline-size: 7rem;
27
23
  padding: 0.42rem 0.66rem;
28
24
  text-transform: uppercase;
29
25
  transition:
@@ -33,32 +29,21 @@
33
29
  white-space: nowrap;
34
30
  }
35
31
 
36
- .theme-toggle__button {
37
- justify-content: center;
38
- min-inline-size: 7rem;
39
- }
40
-
41
- .site-menu__toggle::-webkit-details-marker {
42
- display: none;
43
- }
44
-
45
- .site-menu[open] .site-menu__toggle,
46
- .site-menu__toggle:hover,
47
- .theme-toggle__button:hover {
32
+ .ui-themetoggle__button:hover {
48
33
  border-color: var(--accent);
49
- color: var(--accent);
34
+ color: var(--accent-text);
50
35
  }
51
36
 
52
- .theme-toggle__prefix {
37
+ .ui-themetoggle__prefix {
53
38
  color: var(--text-dim);
54
39
  }
55
40
 
56
- .theme-toggle__label {
41
+ .ui-themetoggle__label {
57
42
  color: var(--text);
58
43
  font-weight: 700;
59
44
  }
60
45
 
61
- .theme-toggle__track {
46
+ .ui-themetoggle__track {
62
47
  background: var(--panel-soft);
63
48
  border: 1px solid var(--line-strong);
64
49
  border-radius: var(--radius-pill);
@@ -68,7 +53,7 @@
68
53
  inline-size: 1.5rem;
69
54
  }
70
55
 
71
- .theme-toggle__thumb {
56
+ .ui-themetoggle__thumb {
72
57
  background: var(--text-dim);
73
58
  border-radius: 50%;
74
59
  display: block;
@@ -80,72 +65,18 @@
80
65
  inline-size: 0.56rem;
81
66
  }
82
67
 
83
- [data-theme='dark'] .theme-toggle__thumb {
68
+ [data-theme='dark'] .ui-themetoggle__thumb {
84
69
  background: var(--accent);
85
70
  transform: translateX(0.6rem);
86
71
  }
87
72
 
88
- [dir='rtl'][data-theme='dark'] .theme-toggle__thumb,
89
- [dir='rtl'] [data-theme='dark'] .theme-toggle__thumb {
73
+ [dir='rtl'][data-theme='dark'] .ui-themetoggle__thumb,
74
+ [dir='rtl'] [data-theme='dark'] .ui-themetoggle__thumb {
90
75
  transform: translateX(-0.6rem);
91
76
  }
92
77
 
93
- .site-nav {
94
- display: inline-flex;
95
- gap: 0.15rem;
96
- }
97
-
98
- .site-nav a {
99
- align-items: center;
100
- border: 1px solid transparent;
101
- border-radius: var(--radius-md);
102
- color: var(--text-soft);
103
- display: inline-flex;
104
- font-family: var(--mono);
105
- font-size: var(--text-xs);
106
- gap: 0.45rem;
107
- letter-spacing: var(--tracking-wide);
108
- padding: 0.4rem 0.6rem;
109
- position: relative;
110
- text-transform: uppercase;
111
- transition:
112
- border-color var(--duration-fast) var(--ease-standard),
113
- background-color var(--duration-fast) var(--ease-standard),
114
- color var(--duration-fast) var(--ease-standard);
115
- }
116
-
117
- /* Leading dot is the active/hover indicator — Nothing glyph cue. */
118
- .site-nav a::before {
119
- background: currentColor;
120
- border-radius: 50%;
121
- content: '';
122
- block-size: 0.32rem;
123
- opacity: 0;
124
- transform: scale(0.5);
125
- transition:
126
- opacity var(--duration-fast) var(--ease-standard),
127
- transform var(--duration-fast) var(--ease-spring);
128
- inline-size: 0.32rem;
129
- }
130
-
131
- .site-nav a:hover,
132
- .site-nav a.is-active {
133
- color: var(--text);
134
- }
135
-
136
- .site-nav a.is-active {
137
- color: var(--accent);
138
- }
139
-
140
- .site-nav a:hover::before,
141
- .site-nav a.is-active::before {
142
- opacity: 1;
143
- transform: scale(1);
144
- }
145
-
146
78
  @media (hover: hover) {
147
- .site-menu__toggle:active,
148
- .theme-toggle__button:active {
79
+ .ui-themetoggle__button:active {
149
80
  transform: translateY(1px);
150
81
  }
151
82
  }
package/css/overlay.css CHANGED
@@ -91,12 +91,20 @@
91
91
  @media (hover: hover) {
92
92
  .ui-modal__close:hover {
93
93
  border-color: var(--accent);
94
- color: var(--accent);
94
+ color: var(--accent-text);
95
95
  }
96
96
  }
97
97
 
98
98
  /* --- Dropdown menu — pairs with native <details> --- */
99
99
 
100
+ /* The positioned host for a <details> dropdown: .ui-menu is absolute, so
101
+ its <details> wrapper must establish a containing block. (Replaces the
102
+ role the legacy .site-menu wrapper served, now a first-class ui-*.) */
103
+ .ui-menu-host {
104
+ display: inline-block;
105
+ position: relative;
106
+ }
107
+
100
108
  .ui-menu {
101
109
  background: var(--panel-strong);
102
110
  border: 1px solid var(--line-strong);
@@ -78,7 +78,7 @@
78
78
  .ui-eyebrow {
79
79
  /* accent-strong, not accent: this is small bold text and must clear
80
80
  WCAG AA 4.5:1 on the soft/tinted surfaces eyebrows sit on too. */
81
- color: var(--accent-strong);
81
+ color: var(--accent-text);
82
82
  font-family: var(--display);
83
83
  font-size: var(--text-xs);
84
84
  font-weight: 700;
@@ -203,8 +203,10 @@
203
203
  }
204
204
 
205
205
  .ui-chip--accent {
206
+ /* accent-strong, not accent: chip text is small uppercase mono and must
207
+ clear WCAG AA 4.5:1 — same rule as .ui-eyebrow above. */
208
+ color: var(--accent-text);
206
209
  border-color: var(--accent);
207
- color: var(--accent);
208
210
  }
209
211
 
210
212
  /* --- Badge / status pill --- */
@@ -307,7 +309,7 @@
307
309
  }
308
310
 
309
311
  .ui-link:hover {
310
- color: var(--accent);
312
+ color: var(--accent-text);
311
313
  text-decoration-color: var(--accent);
312
314
  }
313
315