@webority/theme 0.7.4 → 0.7.6

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.
@@ -76,10 +76,13 @@
76
76
  transform: scaleY(-1);
77
77
  transition: color 0.15s;
78
78
  }
79
- .infotip-btn:hover,
79
+ .infotip-btn:hover {
80
+ color: var(--color-primary);
81
+ }
80
82
  .infotip-btn:focus-visible {
81
83
  color: var(--color-primary);
82
- outline: none;
84
+ outline: 2px solid var(--color-primary);
85
+ outline-offset: 2px;
83
86
  }
84
87
  .infotip-pop {
85
88
  position: absolute;
@@ -141,9 +144,91 @@
141
144
  }
142
145
 
143
146
  // ── Page header ──
147
+ // `.page-header` stacks an optional breadcrumbs row above `.page-header-bar` — the
148
+ // flex row that holds the title block on the left and the page actions on the right.
144
149
  .page-header {
145
150
  margin-bottom: 24px;
146
151
  }
152
+ .page-header-bar {
153
+ display: flex;
154
+ align-items: flex-end;
155
+ justify-content: space-between;
156
+ gap: 16px;
157
+ }
158
+ // Left block: an optional leading icon tile + the title stack, kept together.
159
+ .page-header-lead {
160
+ display: flex;
161
+ align-items: center;
162
+ gap: 12px;
163
+ min-width: 0;
164
+ }
165
+ // A breadcrumbs row above the masthead row.
166
+ .page-breadcrumbs {
167
+ margin-bottom: 10px;
168
+ }
169
+ // Leading icon tile — tinted by `tone` (default primary), matching the modal head icon.
170
+ .page-header-icon {
171
+ flex: none;
172
+ display: inline-grid;
173
+ place-items: center;
174
+ width: 40px;
175
+ height: 40px;
176
+ border-radius: var(--radius);
177
+ corner-shape: squircle;
178
+ background: var(--color-primary-soft);
179
+ color: var(--color-primary);
180
+ }
181
+ .page-header.tone-success .page-header-icon {
182
+ background: var(--color-success-soft);
183
+ color: var(--color-success-text);
184
+ }
185
+ .page-header.tone-warning .page-header-icon {
186
+ background: var(--color-warning-soft);
187
+ color: var(--color-warning-text);
188
+ }
189
+ .page-header.tone-danger .page-header-icon {
190
+ background: var(--color-danger-soft);
191
+ color: var(--color-danger-text);
192
+ }
193
+ .page-header.tone-info .page-header-icon {
194
+ background: var(--color-info-soft);
195
+ color: var(--color-info-text);
196
+ }
197
+ .page-header-titles {
198
+ min-width: 0;
199
+ }
200
+ // Eyebrow — a small kicker label above the title (a section / category marker).
201
+ .page-eyebrow {
202
+ font-size: 12px;
203
+ font-weight: 700;
204
+ letter-spacing: 0.06em;
205
+ text-transform: uppercase;
206
+ color: var(--color-primary);
207
+ margin-bottom: 3px;
208
+ }
209
+ .page-header.tone-success .page-eyebrow {
210
+ color: var(--color-success-text);
211
+ }
212
+ .page-header.tone-warning .page-eyebrow {
213
+ color: var(--color-warning-text);
214
+ }
215
+ .page-header.tone-danger .page-eyebrow {
216
+ color: var(--color-danger-text);
217
+ }
218
+ .page-header.tone-info .page-eyebrow {
219
+ color: var(--color-info-text);
220
+ }
221
+ // Title + an optional inline status pill, on one baseline.
222
+ .page-titlebar {
223
+ display: flex;
224
+ align-items: center;
225
+ gap: 10px;
226
+ flex-wrap: wrap;
227
+ }
228
+ .page-status {
229
+ display: inline-flex;
230
+ align-items: center;
231
+ }
147
232
  .page-title {
148
233
  font-size: 24px;
149
234
  font-weight: 600;
@@ -162,17 +247,67 @@
162
247
  align-items: center;
163
248
  }
164
249
 
250
+ // ── Size scale ── (`size`): the title and the block's rhythm scale together.
251
+ .page-header-sm {
252
+ margin-bottom: 16px;
253
+ }
254
+ .page-header-sm .page-title {
255
+ font-size: 20px;
256
+ }
257
+ .page-header-sm .page-header-icon {
258
+ width: 34px;
259
+ height: 34px;
260
+ }
261
+ .page-header-lg {
262
+ margin-bottom: 32px;
263
+ }
264
+ .page-header-lg .page-title {
265
+ font-size: 30px;
266
+ }
267
+ .page-header-lg .page-header-icon {
268
+ width: 48px;
269
+ height: 48px;
270
+ }
271
+
272
+ // ── Centre alignment ── (`align="center"`): for empty-state and wizard mastheads.
273
+ .page-header-center .page-header-bar {
274
+ justify-content: center;
275
+ text-align: center;
276
+ }
277
+ .page-header-center .page-header-lead {
278
+ flex-direction: column;
279
+ align-items: center;
280
+ }
281
+ .page-header-center .page-titlebar {
282
+ justify-content: center;
283
+ }
284
+
285
+ // ── Divider ── (`divider`): a hairline rule under the masthead.
286
+ .page-header-divider {
287
+ border-bottom: 1px solid var(--color-border);
288
+ padding-bottom: 16px;
289
+ }
290
+
291
+ // ── Sticky ── (`sticky`): pins the masthead to the top of its scroll container.
292
+ .page-header-sticky {
293
+ position: sticky;
294
+ top: 0;
295
+ z-index: 20;
296
+ background: var(--color-surface);
297
+ padding-top: 12px;
298
+ }
299
+
165
300
  // Tablet and below: the masthead stops being a single row — the title block and
166
301
  // its actions stack, and the actions stretch to the full width rather than
167
302
  // crowding the title. Bootstrap's lg tier (991.98px), not an invented breakpoint.
168
303
  //
169
- // Selectors are DOUBLED (`.page-header.page-header`) on purpose. A media query
170
- // adds no specificity, so a consumer's own single-class rule — written later in
171
- // the cascade, as a consuming app's stylesheet always is — silently beats the
304
+ // Selectors are DOUBLED (`.page-header-bar.page-header-bar`) on purpose. A media
305
+ // query adds no specificity, so a consumer's own single-class rule — written later
306
+ // in the cascade, as a consuming app's stylesheet always is — silently beats the
172
307
  // responsive rule and the layout never collapses. Doubling puts these at (0,2,0)
173
308
  // so they hold, while still leaving a consumer free to override deliberately.
174
309
  @media (max-width: 991.98px) {
175
- .page-header.page-header {
310
+ .page-header-bar.page-header-bar {
176
311
  flex-direction: column;
177
312
  align-items: stretch;
178
313
  gap: 12px;
@@ -261,6 +396,118 @@
261
396
  display: inline-block;
262
397
  }
263
398
 
399
+ // Page/system-level announcement bar (AppBanner / <app-banner>). Full-width and persistent —
400
+ // distinct from an inline .alert or a transient toast. Tones reuse the shared soft/text ramp.
401
+ .wui-banner {
402
+ display: flex;
403
+ align-items: center;
404
+ gap: 12px;
405
+ width: 100%;
406
+ padding: 12px 20px;
407
+ font-size: 14px;
408
+ line-height: 1.4;
409
+ }
410
+ .wui-banner-icon {
411
+ flex: none;
412
+ display: inline-flex;
413
+ align-items: center;
414
+ }
415
+ .wui-banner-body {
416
+ flex: 1 1 auto;
417
+ min-width: 0;
418
+ }
419
+ .wui-banner-dismiss {
420
+ flex: none;
421
+ display: inline-flex;
422
+ align-items: center;
423
+ justify-content: center;
424
+ padding: 4px;
425
+ border: none;
426
+ background: transparent;
427
+ color: inherit;
428
+ cursor: pointer;
429
+ opacity: 0.7;
430
+ border-radius: var(--radius-sm);
431
+ }
432
+ .wui-banner-dismiss:hover {
433
+ opacity: 1;
434
+ }
435
+ .wui-banner-dismiss:focus-visible {
436
+ outline: 2px solid currentColor;
437
+ outline-offset: 2px;
438
+ }
439
+ .wui-banner-info {
440
+ background: var(--color-info-soft);
441
+ color: var(--color-info-text);
442
+ }
443
+ .wui-banner-success {
444
+ background: var(--color-success-soft);
445
+ color: var(--color-success-text);
446
+ }
447
+ .wui-banner-warning {
448
+ background: var(--color-warning-soft);
449
+ color: var(--color-warning-text);
450
+ }
451
+ .wui-banner-danger {
452
+ background: var(--color-danger-soft);
453
+ color: var(--color-danger-text);
454
+ }
455
+ .wui-banner-neutral {
456
+ background: var(--color-bg-subtle);
457
+ color: var(--color-text);
458
+ border-bottom: 1px solid var(--color-border);
459
+ }
460
+
461
+ // Determinate progress-bar fill tones (AppProgress / AppMeter / <app-progress>) — the fill sits
462
+ // in Bootstrap's .progress track; only the bar colour is brand-toned.
463
+ //
464
+ // success + danger use the DEEPENED -strong fills, not the mid tones: when showLabel is set the
465
+ // bar carries Bootstrap's WHITE label text, and white on the mid --wui-success (#17C653) /
466
+ // --wui-danger (#F8285A) fails AA (2.78:1 / 3.86:1). The -strong fills clear it (both ~5.8:1),
467
+ // the same trick btn-danger uses. info/warning/neutral stay on their mid tones (info/neutral
468
+ // pass with white; warning is not shown with a white label).
469
+ .wui-progress-info {
470
+ background-color: var(--color-info);
471
+ }
472
+ .wui-progress-success {
473
+ background-color: var(--wui-success-strong);
474
+ }
475
+ .wui-progress-warning {
476
+ background-color: var(--color-warning);
477
+ }
478
+ .wui-progress-danger {
479
+ background-color: var(--wui-danger-strong);
480
+ }
481
+ .wui-progress-neutral {
482
+ background-color: var(--color-text-subtle);
483
+ }
484
+ // Thin bar for inline / table use.
485
+ .progress.progress-sm {
486
+ height: 4px;
487
+ }
488
+ // Indeterminate "working…" sweep — a partial segment that travels the track (the bar carries
489
+ // no width style in this mode, so the width + motion come from here).
490
+ .wui-progress-indeterminate {
491
+ width: 40%;
492
+ animation: wui-progress-indeterminate 1.1s ease-in-out infinite;
493
+ }
494
+ @keyframes wui-progress-indeterminate {
495
+ 0% {
496
+ margin-left: -40%;
497
+ }
498
+ 100% {
499
+ margin-left: 100%;
500
+ }
501
+ }
502
+ @media (prefers-reduced-motion: reduce) {
503
+ // No sweep for reduced-motion users — settle to a static full bar.
504
+ .wui-progress-indeterminate {
505
+ margin-left: 0;
506
+ width: 100%;
507
+ animation: none;
508
+ }
509
+ }
510
+
264
511
  // ── Spinner / shimmer ──
265
512
  .wui-spinner {
266
513
  width: 18px;