@tensor_1/tokens 2.10.0 → 2.11.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/build/css/components.css +104 -129
- package/build/css/styles.css +111 -173
- package/build/css/tokens.css +7 -7
- package/build/ts/tokens.js +14 -7
- package/package.json +1 -1
- package/tokens/base/typography.json +7 -7
package/build/css/components.css
CHANGED
|
@@ -207,8 +207,7 @@
|
|
|
207
207
|
}
|
|
208
208
|
.uix-checkbox > input:checked + .uix-checkbox__box,
|
|
209
209
|
.uix-checkbox > input:indeterminate + .uix-checkbox__box { background: var(--uix-accent); border-color: var(--uix-accent); }
|
|
210
|
-
.uix-checkbox > input:checked + .uix-checkbox__box svg
|
|
211
|
-
.uix-checkbox > input:indeterminate + .uix-checkbox__box svg { opacity: 1; transform: none; } /* indeterminate shows its dash icon, not just the filled box (UIX-A11Y-3) */
|
|
210
|
+
.uix-checkbox > input:checked + .uix-checkbox__box svg { opacity: 1; transform: none; }
|
|
212
211
|
.uix-checkbox > input:focus-visible + .uix-checkbox__box { outline: 2px solid var(--uix-ring); outline-offset: 2px; }
|
|
213
212
|
.uix-checkbox > input:disabled ~ * { opacity: .5; }
|
|
214
213
|
}
|
|
@@ -260,7 +259,7 @@
|
|
|
260
259
|
transition: background-color var(--uix-dur-fast) var(--uix-ease-out), color var(--uix-dur-fast) var(--uix-ease-out);
|
|
261
260
|
}
|
|
262
261
|
.uix-segmented__option:hover { color: var(--uix-text); }
|
|
263
|
-
.uix-segmented__option[aria-pressed="true"] { background: var(--uix-surface); color: var(--uix-text); box-shadow: var(--uix-shadow-sm); }
|
|
262
|
+
.uix-segmented__option[aria-selected="true"], .uix-segmented__option[aria-pressed="true"] { background: var(--uix-surface); color: var(--uix-text); box-shadow: var(--uix-shadow-sm); }
|
|
264
263
|
.uix-segmented__option:focus-visible { outline: 2px solid var(--uix-ring); outline-offset: 1px; }
|
|
265
264
|
}
|
|
266
265
|
/* uix slider (native range, styled) — depends only on --uix-* tokens. */
|
|
@@ -334,9 +333,7 @@
|
|
|
334
333
|
display: inline-flex; align-items: center; gap: var(--uix-space-1); padding: var(--uix-space-1) var(--uix-space-1) var(--uix-space-1) var(--uix-space-2); border-radius: var(--uix-radius-sm);
|
|
335
334
|
background: var(--uix-bg-active); color: var(--uix-text); font-size: var(--uix-text-meta);
|
|
336
335
|
}
|
|
337
|
-
.uix-tag__remove {
|
|
338
|
-
/* Invisible overlay grows the 16px visual to a 24px hit target (UIX-A11Y-3). */
|
|
339
|
-
.uix-tag__remove::before { content: ""; position: absolute; inset: -4px; }
|
|
336
|
+
.uix-tag__remove { display: grid; place-items: center; width: 16px; height: 16px; border: 0; background: transparent; color: var(--uix-text-muted); cursor: pointer; border-radius: var(--uix-radius-xs); }
|
|
340
337
|
.uix-tag__remove:hover { background: var(--uix-bg-hover); color: var(--uix-text); }
|
|
341
338
|
.uix-tag__remove svg { width: 12px; height: 12px; }
|
|
342
339
|
}
|
|
@@ -345,11 +342,6 @@
|
|
|
345
342
|
.uix-form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--uix-space-5); }
|
|
346
343
|
.uix-fieldset { border: 1px solid var(--uix-border); border-radius: var(--uix-radius-lg); padding: var(--uix-space-6); }
|
|
347
344
|
.uix-fieldset > legend { padding: 0 var(--uix-space-2); font-size: var(--uix-text-meta); font-weight: 600; color: var(--uix-text); }
|
|
348
|
-
/* Labeled RadioGroup renders as a fieldset (UIX-A11Y-3): strip the UA chrome so it
|
|
349
|
-
looks identical to the plain-div group; the legend spaces itself (fieldset gap
|
|
350
|
-
doesn't reach a legend). */
|
|
351
|
-
fieldset.uix-radio-group { border: 0; margin: 0; padding: 0; min-inline-size: auto; }
|
|
352
|
-
.uix-radio-group__legend { padding: 0; margin: 0 0 var(--uix-space-2); font-size: var(--uix-text-meta); font-weight: 600; color: var(--uix-text); }
|
|
353
345
|
.uix-form-inline { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--uix-space-4); }
|
|
354
346
|
.uix-validation-summary {
|
|
355
347
|
border: 1px solid var(--uix-danger); background: var(--uix-danger-bg); color: var(--uix-text);
|
|
@@ -370,7 +362,7 @@
|
|
|
370
362
|
border: 1px solid var(--uix-border); border-radius: var(--uix-radius-lg); overflow: hidden;
|
|
371
363
|
transition: grid-template-columns var(--uix-dur) var(--uix-ease-out), grid-template-rows var(--uix-dur) var(--uix-ease-out);
|
|
372
364
|
}
|
|
373
|
-
.uix-shell__sidebar { grid-row: 1 / 3; background: var(--uix-bg-subtle); border-right: 1px solid var(--uix-border); overflow-y: auto; overflow-x: hidden;
|
|
365
|
+
.uix-shell__sidebar { grid-row: 1 / 3; background: var(--uix-bg-subtle); border-right: 1px solid var(--uix-border); overflow-y: auto; overflow-x: hidden; }
|
|
374
366
|
.uix-shell__topbar { grid-column: 2; display: flex; align-items: center; gap: var(--uix-space-3); padding: 0 var(--uix-space-6); background: var(--uix-bg-app); border-bottom: 1px solid var(--uix-border); }
|
|
375
367
|
.uix-shell__main { grid-column: 2; overflow: auto; padding: var(--uix-space-7); background: var(--uix-bg-app); }
|
|
376
368
|
|
|
@@ -379,39 +371,17 @@
|
|
|
379
371
|
only) → hidden (0). data-collapsed stays a back-compat alias for the rail. */
|
|
380
372
|
.uix-shell[data-nav="rail"], .uix-shell[data-collapsed] { grid-template-columns: var(--uix-sidebar-w-rail) 1fr; }
|
|
381
373
|
.uix-shell[data-nav="hidden"] { grid-template-columns: 0 1fr; }
|
|
382
|
-
/* the 0-width column still renders its links — visibility removes them from the tab
|
|
383
|
-
order / accessibility tree while keeping the width transition (UIX-A11Y-2) */
|
|
384
|
-
.uix-shell[data-nav="hidden"] .uix-shell__sidebar { visibility: hidden; }
|
|
385
374
|
|
|
386
375
|
/* ── focus / immersive mode ───────────────────────────────────────────────────
|
|
387
376
|
A table-scoped escape hatch: hide the sidebar AND the topbar so a dense grid
|
|
388
377
|
uses the whole frame. The app toggles [data-focus] (from a toolbar maximize
|
|
389
378
|
control) and restores the previous nav state + focus on Esc. */
|
|
390
379
|
.uix-shell[data-focus] { grid-template-columns: 0 1fr; grid-template-rows: 0 1fr; }
|
|
391
|
-
.uix-shell[data-focus] .uix-shell__sidebar { visibility: hidden; } /* see [data-nav="hidden"] above (UIX-A11Y-2) */
|
|
392
380
|
.uix-shell[data-focus] .uix-shell__topbar { display: none; }
|
|
393
381
|
|
|
394
382
|
/* a floating host for the "exit focus" affordance (Esc also exits) */
|
|
395
383
|
.uix-shell__focus-exit { position: absolute; top: var(--uix-space-3); right: var(--uix-space-3); z-index: var(--uix-z-overlay); }
|
|
396
384
|
|
|
397
|
-
/* ── skip link ────────────────────────────────────────────────────────────────
|
|
398
|
-
First tab stop in the shell (UIX-A11Y-2): visually hidden until keyboard focus,
|
|
399
|
-
then a small pill floating over the shell's top-left corner. */
|
|
400
|
-
.uix-skiplink {
|
|
401
|
-
position: absolute; top: var(--uix-space-3); left: var(--uix-space-3); z-index: var(--uix-z-overlay);
|
|
402
|
-
width: 1px; height: 1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap;
|
|
403
|
-
}
|
|
404
|
-
.uix-skiplink:focus-visible {
|
|
405
|
-
width: auto; height: auto; clip: auto;
|
|
406
|
-
display: inline-flex; align-items: center;
|
|
407
|
-
padding: var(--uix-space-2) var(--uix-space-4);
|
|
408
|
-
background: var(--uix-surface); color: var(--uix-text);
|
|
409
|
-
border: 1px solid var(--uix-border); border-radius: var(--uix-radius-pill);
|
|
410
|
-
box-shadow: var(--uix-shadow-popover);
|
|
411
|
-
outline: 2px solid var(--uix-ring); outline-offset: 2px;
|
|
412
|
-
font-size: var(--uix-text-meta); font-weight: 500; text-decoration: none;
|
|
413
|
-
}
|
|
414
|
-
|
|
415
385
|
/* ── full-bleed main ──────────────────────────────────────────────────────────
|
|
416
386
|
Opt-in per surface: a genuinely wide grid drops the content gutter and runs
|
|
417
387
|
edge to edge, reclaiming 2 x --uix-space-7. Not the default — most pages want
|
|
@@ -452,14 +422,9 @@
|
|
|
452
422
|
.uix-navitem__badge { font-size: var(--uix-text-meta); color: var(--uix-text-muted); }
|
|
453
423
|
/* on the active tint, muted badge dips below AA — hushed composites darker on the tint */
|
|
454
424
|
.uix-navitem[aria-current="page"] .uix-navitem__badge { color: var(--uix-text-hushed); }
|
|
455
|
-
.uix-navitem__star {
|
|
456
|
-
/* invisible halo → 24px effective target with zero visual change (UIX-A11Y-2) */
|
|
457
|
-
.uix-navitem__star::before { content: ""; position: absolute; inset: -1px; }
|
|
425
|
+
.uix-navitem__star { display: grid; place-items: center; width: 22px; height: 22px; border: 0; background: transparent; color: var(--uix-text-muted); cursor: pointer; border-radius: var(--uix-radius-xs); opacity: 0; transition: opacity var(--uix-dur-fast) var(--uix-ease-out); }
|
|
458
426
|
.uix-navitem__star svg { width: 15px; height: 15px; }
|
|
459
|
-
|
|
460
|
-
.uix-navitem:hover .uix-navitem__star,
|
|
461
|
-
.uix-navitem__star:focus-visible,
|
|
462
|
-
.uix-navitem:focus-within .uix-navitem__star { opacity: 1; }
|
|
427
|
+
.uix-navitem:hover .uix-navitem__star { opacity: 1; }
|
|
463
428
|
.uix-navitem__star[data-on] { opacity: 1; color: var(--uix-warning); }
|
|
464
429
|
.uix-navitem__star[data-on] svg { fill: currentColor; }
|
|
465
430
|
|
|
@@ -470,32 +435,19 @@
|
|
|
470
435
|
.uix-navgroup__chevron { width: var(--uix-icon-sm); height: var(--uix-icon-sm); }
|
|
471
436
|
.uix-navgroup__panel { display: grid; grid-template-rows: 1fr; transition: grid-template-rows var(--uix-dur) var(--uix-ease-out); }
|
|
472
437
|
.uix-navgroup__trigger[aria-expanded="false"] + .uix-navgroup__panel { grid-template-rows: 0fr; }
|
|
473
|
-
|
|
474
|
-
(UIX-A11Y-2); the transition delays hiding until the row collapse finishes, and
|
|
475
|
-
visibility snaps back to visible instantly on expand, so nothing visibly glitches. */
|
|
476
|
-
.uix-navgroup__panel > div { overflow: hidden; visibility: visible; transition: visibility var(--uix-dur) var(--uix-ease-out); }
|
|
477
|
-
.uix-navgroup__trigger[aria-expanded="false"] + .uix-navgroup__panel > div { visibility: hidden; }
|
|
438
|
+
.uix-navgroup__panel > div { overflow: hidden; }
|
|
478
439
|
.uix-subitem { padding-left: var(--uix-space-5); }
|
|
479
440
|
.uix-subitem .uix-navitem__label::before { content: ""; display: inline-block; width: 4px; height: 4px; border-radius: 50%; background: var(--uix-text-muted); margin-right: var(--uix-space-3); vertical-align: middle; }
|
|
480
441
|
|
|
481
442
|
/* collapsed rail */
|
|
482
443
|
.uix-sidebar[data-collapsed], .uix-sidebar[data-nav="rail"] { width: var(--uix-sidebar-w-rail); }
|
|
444
|
+
.uix-sidebar[data-collapsed] .uix-navitem__label,
|
|
483
445
|
.uix-sidebar[data-collapsed] .uix-navitem__badge,
|
|
484
446
|
.uix-sidebar[data-collapsed] .uix-navitem__star,
|
|
485
447
|
.uix-sidebar[data-collapsed] .uix-sidebar__eyebrow,
|
|
486
448
|
.uix-sidebar[data-collapsed] .uix-sidebar__brand,
|
|
487
449
|
.uix-sidebar[data-collapsed] .uix-navgroup__chevron,
|
|
488
450
|
.uix-sidebar[data-collapsed] .uix-navgroup__panel { display: none; }
|
|
489
|
-
/* rail labels stay in the accessibility tree — clip pattern (mirrors .uix-visually-hidden),
|
|
490
|
-
not display:none, so icon-only nav items keep their names (UIX-A11Y-2). position:absolute
|
|
491
|
-
removes the label from the flex row, so the centered rail layout is unaffected. */
|
|
492
|
-
.uix-sidebar[data-collapsed] .uix-navitem__label {
|
|
493
|
-
position: absolute !important;
|
|
494
|
-
width: 1px; height: 1px;
|
|
495
|
-
padding: 0; margin: -1px;
|
|
496
|
-
overflow: hidden; clip: rect(0, 0, 0, 0);
|
|
497
|
-
white-space: nowrap; border: 0;
|
|
498
|
-
}
|
|
499
451
|
/* center the icon-only rail; head keeps just the toggle, centered */
|
|
500
452
|
.uix-sidebar[data-collapsed] .uix-navitem { justify-content: center; padding: 0; gap: 0; }
|
|
501
453
|
.uix-sidebar[data-collapsed] .uix-sidebar__head { justify-content: center; padding-inline: 0; }
|
|
@@ -504,7 +456,9 @@
|
|
|
504
456
|
@layer uix.components {
|
|
505
457
|
.uix-breadcrumbs { display: flex; align-items: center; gap: var(--uix-space-2); flex-wrap: wrap; font-size: var(--uix-text-meta); color: var(--uix-text-muted); }
|
|
506
458
|
.uix-breadcrumbs a { color: var(--uix-text-muted); text-decoration: none; }
|
|
507
|
-
|
|
459
|
+
/* already a quiet link by its own design — hover/focus parity with the quiet-link
|
|
460
|
+
contract in link.css, so the keyboard state matches the pointer state. */
|
|
461
|
+
.uix-breadcrumbs a:is(:hover, :focus-visible) { color: var(--uix-text); text-decoration: underline; }
|
|
508
462
|
.uix-breadcrumbs__sep { opacity: .55; }
|
|
509
463
|
.uix-breadcrumbs [aria-current="page"] { color: var(--uix-text); font-weight: 500; }
|
|
510
464
|
}
|
|
@@ -576,9 +530,6 @@
|
|
|
576
530
|
.uix-cmdk { width: min(560px, 92vw); border: 1px solid var(--uix-border); border-radius: var(--uix-radius-lg); background: var(--uix-surface-2); box-shadow: var(--uix-shadow-overlay); overflow: hidden; }
|
|
577
531
|
.uix-cmdk__input { width: 100%; height: 48px; border: 0; border-bottom: 1px solid var(--uix-border); background: transparent; color: var(--uix-text); font: inherit; font-size: var(--uix-text-h3); padding: 0 var(--uix-space-4); }
|
|
578
532
|
.uix-cmdk__input:focus { outline: none; }
|
|
579
|
-
/* visible focus replacement for the suppressed outline (UIX-A11Y-1): the divider under the
|
|
580
|
-
input thickens to a 2px ring-colored line */
|
|
581
|
-
.uix-cmdk__input:focus-visible { border-bottom-color: var(--uix-ring); box-shadow: 0 1px 0 0 var(--uix-ring); }
|
|
582
533
|
.uix-cmdk__list { max-height: 320px; overflow-y: auto; padding: var(--uix-space-2); }
|
|
583
534
|
.uix-cmdk__group { font-size: var(--uix-text-eyebrow); letter-spacing: var(--uix-tracking-eyebrow); text-transform: uppercase; color: var(--uix-text-muted); padding: var(--uix-space-2) var(--uix-space-3) var(--uix-space-1); }
|
|
584
535
|
.uix-cmdk__item { display: flex; align-items: center; gap: var(--uix-space-3); padding: var(--uix-space-3) var(--uix-space-3); border-radius: var(--uix-radius-sm); color: var(--uix-text); cursor: pointer; font-size: var(--uix-text-body); }
|
|
@@ -637,8 +588,6 @@
|
|
|
637
588
|
.uix-stat__value { font-size: var(--uix-text-data-hero); font-weight: 600; line-height: var(--uix-leading-data-hero); margin-top: var(--uix-space-3); }
|
|
638
589
|
.uix-stat__meta { font-size: var(--uix-text-meta); color: var(--uix-text-muted); margin-top: var(--uix-space-2); display: flex; align-items: center; gap: var(--uix-space-2); }
|
|
639
590
|
.uix-stat__trend { display: inline-flex; align-items: center; gap: var(--uix-space-1); font-size: var(--uix-text-meta); font-weight: 600; padding: var(--uix-space-1) var(--uix-space-2); border-radius: var(--uix-radius-pill); }
|
|
640
|
-
/* direction glyph inside the chip (UIX-A11Y-4) — sized to sit on the text baseline row */
|
|
641
|
-
.uix-stat__trend svg { width: 10px; height: 10px; flex: none; }
|
|
642
591
|
.uix-stat__trend--up { color: var(--uix-success); background: var(--uix-success-bg); }
|
|
643
592
|
.uix-stat__trend--down { color: var(--uix-danger-text); background: var(--uix-danger-bg); }
|
|
644
593
|
}
|
|
@@ -699,28 +648,18 @@
|
|
|
699
648
|
/* multi-column sort ordinal (⇧+click adds a secondary key) */
|
|
700
649
|
.uix-table th[data-sort-order]::before { content: attr(data-sort-order); display: inline-block; margin-right: var(--uix-space-1); font-size: var(--uix-text-eyebrow); font-variant-numeric: tabular-nums; color: var(--uix-accent); }
|
|
701
650
|
|
|
702
|
-
/* sortable header's real <button> (UIX-A11Y-2): visually indistinguishable from the old
|
|
703
|
-
plain-text th — inherited font/colour, no chrome — with an inset overlay so the whole
|
|
704
|
-
cell stays the click target (the sticky th is its containing block). The sort arrow and
|
|
705
|
-
ordinal stay as th pseudo-content so they never pollute the button's accessible name. */
|
|
706
|
-
.uix-th__sortbtn { font: inherit; color: inherit; background: none; border: 0; padding: 0; text-align: inherit; cursor: pointer; }
|
|
707
|
-
.uix-th__sortbtn::before { content: ""; position: absolute; inset: 0; }
|
|
708
|
-
|
|
709
651
|
.uix-table td { padding: 0 var(--uix-space-4); height: var(--uix-row-h); border-bottom: 1px solid var(--uix-border); color: var(--uix-text); vertical-align: middle; }
|
|
710
652
|
.uix-table tbody tr { background: var(--uix-row); }
|
|
711
653
|
.uix-table tbody tr:nth-child(even) { background: var(--uix-row-alt); }
|
|
712
654
|
.uix-table--no-zebra tbody tr, .uix-table--no-zebra tbody tr:nth-child(even) { background: var(--uix-row); }
|
|
713
655
|
.uix-table tbody tr[data-pinned] { background: var(--uix-row-pinned-bg); }
|
|
714
|
-
|
|
715
|
-
table row — AT state comes from the row checkbox (UIX-A11Y-2). */
|
|
716
|
-
.uix-table tbody tr[data-selected] { background: var(--uix-row-selected-bg); }
|
|
656
|
+
.uix-table tbody tr[aria-selected="true"] { background: var(--uix-row-selected-bg); }
|
|
717
657
|
.uix-table tbody tr:hover { background: var(--uix-bg-hover); }
|
|
718
658
|
.uix-table[data-density="compact"] td, .uix-table--compact td { height: var(--uix-row-h-compact); }
|
|
719
659
|
.uix-table[data-density="comfortable"] td { height: var(--uix-row-h-comfortable); }
|
|
720
660
|
|
|
721
661
|
.uix-table__pin { border: 0; background: transparent; color: var(--uix-text-muted); cursor: pointer; padding: var(--uix-space-1); border-radius: var(--uix-radius-xs); opacity: 0; transition: opacity var(--uix-dur-fast) var(--uix-ease-out); }
|
|
722
|
-
|
|
723
|
-
.uix-table tbody tr:hover .uix-table__pin, .uix-table__pin:focus-visible, .uix-table__pin[data-on] { opacity: 1; }
|
|
662
|
+
.uix-table tbody tr:hover .uix-table__pin, .uix-table__pin[data-on] { opacity: 1; }
|
|
724
663
|
.uix-table__pin:hover { background: var(--uix-bg-active); color: var(--uix-text); }
|
|
725
664
|
.uix-table__pin[data-on] { color: var(--uix-accent); }
|
|
726
665
|
.uix-table__pin svg { width: 15px; height: 15px; }
|
|
@@ -734,7 +673,7 @@
|
|
|
734
673
|
.uix-table--pinned-col.uix-table--no-zebra tbody tr td:first-child,
|
|
735
674
|
.uix-table--pinned-col.uix-table--no-zebra tbody tr:nth-child(even) td:first-child { background: var(--uix-row); }
|
|
736
675
|
.uix-table--pinned-col tbody tr[data-pinned] td:first-child { background: var(--uix-row-pinned-bg); }
|
|
737
|
-
.uix-table--pinned-col tbody tr[
|
|
676
|
+
.uix-table--pinned-col tbody tr[aria-selected="true"] td:first-child { background: var(--uix-row-selected-bg); }
|
|
738
677
|
.uix-table--pinned-col tbody tr:hover td:first-child { background: var(--uix-bg-hover); }
|
|
739
678
|
|
|
740
679
|
/* ── column sizing + cell behaviour (a shared vocabulary, not per-app px) ──────── */
|
|
@@ -833,7 +772,7 @@
|
|
|
833
772
|
.uix-table--cards thead { position: absolute; width: 1px; height: 1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
|
|
834
773
|
.uix-table--cards tbody, .uix-table--cards tr, .uix-table--cards td { display: block; width: auto; }
|
|
835
774
|
.uix-table--cards tbody tr { border: 1px solid var(--uix-border); border-radius: var(--uix-radius-md); background: var(--uix-surface); margin: 0 0 var(--uix-space-3); padding: var(--uix-space-1) var(--uix-space-4); box-shadow: var(--uix-shadow-sm); }
|
|
836
|
-
.uix-table--cards tbody tr[
|
|
775
|
+
.uix-table--cards tbody tr[aria-selected="true"] { box-shadow: 0 0 0 2px var(--uix-accent); }
|
|
837
776
|
.uix-table--cards td { height: auto; display: flex; justify-content: space-between; align-items: center; gap: var(--uix-space-5); padding: var(--uix-space-2) 0; border-bottom: 1px solid var(--uix-border); text-align: right; white-space: normal; }
|
|
838
777
|
.uix-table--cards td:last-child { border-bottom: 0; }
|
|
839
778
|
.uix-table--cards td::before { content: attr(data-label); color: var(--uix-text-muted); font-size: var(--uix-text-meta); font-weight: 500; text-align: left; flex: none; }
|
|
@@ -939,8 +878,7 @@
|
|
|
939
878
|
background: var(--uix-text); color: var(--uix-bg-app);
|
|
940
879
|
font-size: var(--uix-text-meta); font-weight: 500; line-height: 1.4;
|
|
941
880
|
padding: var(--uix-space-2) var(--uix-space-3); border-radius: var(--uix-radius-sm);
|
|
942
|
-
|
|
943
|
-
box-shadow: var(--uix-shadow-popover); white-space: normal;
|
|
881
|
+
box-shadow: var(--uix-shadow-popover); white-space: normal; pointer-events: none;
|
|
944
882
|
opacity: 0; transition: opacity var(--uix-dur-fast) var(--uix-ease-out);
|
|
945
883
|
}
|
|
946
884
|
.uix-tooltip__bubble:popover-open { opacity: 1; }
|
|
@@ -983,8 +921,7 @@
|
|
|
983
921
|
}
|
|
984
922
|
/* uix timeline / activity feed — depends only on --uix-* tokens. */
|
|
985
923
|
@layer uix.components {
|
|
986
|
-
|
|
987
|
-
.uix-timeline { display: flex; flex-direction: column; list-style: none; margin: 0; padding: 0; }
|
|
924
|
+
.uix-timeline { display: flex; flex-direction: column; }
|
|
988
925
|
.uix-timeline__item { display: grid; grid-template-columns: 24px 1fr; gap: var(--uix-space-3); }
|
|
989
926
|
.uix-timeline__rail { display: flex; flex-direction: column; align-items: center; }
|
|
990
927
|
.uix-timeline__node { width: 12px; height: 12px; border-radius: 50%; background: var(--uix-accent); margin-top: var(--uix-space-1); flex: none; box-shadow: 0 0 0 3px var(--uix-brand-muted); }
|
|
@@ -1106,9 +1043,7 @@
|
|
|
1106
1043
|
@starting-style { .uix-dialog[open]::backdrop { opacity: 0; } }
|
|
1107
1044
|
|
|
1108
1045
|
.uix-dialog__header { display: flex; align-items: center; gap: var(--uix-space-3); padding: var(--uix-space-4) var(--uix-space-5); border-bottom: 1px solid var(--uix-border); }
|
|
1109
|
-
|
|
1110
|
-
heading font/tracking/leading so it renders exactly like the old <div> */
|
|
1111
|
-
.uix-dialog__title { font-size: var(--uix-text-h3); font-weight: 600; font-family: inherit; letter-spacing: inherit; line-height: inherit; }
|
|
1046
|
+
.uix-dialog__title { font-size: var(--uix-text-h3); font-weight: 600; }
|
|
1112
1047
|
.uix-dialog__close { margin-left: auto; border: 0; background: transparent; color: var(--uix-text-muted); cursor: pointer; width: 30px; height: 30px; display: grid; place-items: center; border-radius: var(--uix-radius-sm); }
|
|
1113
1048
|
.uix-dialog__close:hover { background: var(--uix-bg-hover); color: var(--uix-text); }
|
|
1114
1049
|
.uix-dialog__close svg { width: var(--uix-icon-md); height: var(--uix-icon-md); }
|
|
@@ -1168,13 +1103,7 @@
|
|
|
1168
1103
|
.uix-peek__nav { display: inline-flex; gap: var(--uix-space-1); }
|
|
1169
1104
|
.uix-peek__navbtn { width: 28px; height: 28px; display: grid; place-items: center; border: 1px solid var(--uix-border); background: var(--uix-surface); color: var(--uix-text); border-radius: var(--uix-radius-sm); cursor: pointer; }
|
|
1170
1105
|
.uix-peek__navbtn:hover { background: var(--uix-bg-hover); }
|
|
1171
|
-
|
|
1172
|
-
mute it and suppress the hover cue like a disabled control */
|
|
1173
|
-
.uix-peek__navbtn[aria-disabled="true"] { color: var(--uix-text-muted); cursor: default; }
|
|
1174
|
-
.uix-peek__navbtn[aria-disabled="true"]:hover { background: var(--uix-surface); }
|
|
1175
|
-
/* title is an <h2> for SR navigation (UIX-A11Y-1); inherits neutralize the base h2
|
|
1176
|
-
heading font/tracking/leading so it renders exactly like the old <div> */
|
|
1177
|
-
.uix-peek__title { font-size: var(--uix-text-h3); font-weight: 600; font-family: inherit; letter-spacing: inherit; line-height: inherit; }
|
|
1106
|
+
.uix-peek__title { font-size: var(--uix-text-h3); font-weight: 600; }
|
|
1178
1107
|
.uix-peek__title a { color: var(--uix-link); }
|
|
1179
1108
|
.uix-peek__close { margin-left: auto; border: 0; background: transparent; color: var(--uix-text-muted); cursor: pointer; width: 30px; height: 30px; display: grid; place-items: center; border-radius: var(--uix-radius-sm); }
|
|
1180
1109
|
.uix-peek__close:hover { background: var(--uix-bg-hover); color: var(--uix-text); }
|
|
@@ -1327,21 +1256,12 @@
|
|
|
1327
1256
|
.uix-inbox__list { border-right: 1px solid var(--uix-border); overflow-y: auto; background: var(--uix-surface); }
|
|
1328
1257
|
.uix-inbox__item { position: relative; display: flex; flex-direction: column; gap: var(--uix-space-1); padding: var(--uix-space-3) var(--uix-space-4); border-bottom: 1px solid var(--uix-border); cursor: pointer; }
|
|
1329
1258
|
.uix-inbox__item:hover { background: var(--uix-bg-hover); }
|
|
1330
|
-
/* keyboard active option (aria-activedescendant) mirrors the hover style (UIX-A11Y-2) */
|
|
1331
|
-
.uix-inbox__item[data-active] { background: var(--uix-bg-hover); }
|
|
1332
1259
|
.uix-inbox__item[aria-selected="true"] { background: linear-gradient(to right, var(--uix-accent) 3px, var(--uix-brand-muted) 3px); }
|
|
1333
1260
|
.uix-inbox__item[data-unread] .uix-inbox__subject { font-weight: 600; }
|
|
1334
1261
|
.uix-inbox__subject { font-size: var(--uix-text-body); }
|
|
1335
1262
|
.uix-inbox__preview { font-size: var(--uix-text-meta); color: var(--uix-text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
1336
1263
|
.uix-inbox__detail { overflow-y: auto; padding: var(--uix-space-5); background: var(--uix-bg-app); }
|
|
1337
|
-
|
|
1338
|
-
view="detail" — with a consumer-rendered Back control in the detail pane (UIX-A11Y-2) */
|
|
1339
|
-
@media (max-width: 700px) {
|
|
1340
|
-
.uix-inbox { grid-template-columns: 1fr; }
|
|
1341
|
-
.uix-inbox__detail { display: none; }
|
|
1342
|
-
.uix-inbox[data-view="detail"] .uix-inbox__list { display: none; }
|
|
1343
|
-
.uix-inbox[data-view="detail"] .uix-inbox__detail { display: block; }
|
|
1344
|
-
}
|
|
1264
|
+
@media (max-width: 700px) { .uix-inbox { grid-template-columns: 1fr; } .uix-inbox__detail { display: none; } }
|
|
1345
1265
|
}
|
|
1346
1266
|
/* uix notification center — depends only on --uix-* tokens. */
|
|
1347
1267
|
@layer uix.components {
|
|
@@ -1733,7 +1653,8 @@
|
|
|
1733
1653
|
.uix-section-head { min-height: 36px; margin-bottom: var(--uix-space-3); display: flex; align-items: center; justify-content: space-between; gap: var(--uix-space-4); }
|
|
1734
1654
|
.uix-section-title { margin: 0; font-family: var(--uix-font-heading); font-size: var(--uix-text-h2); font-weight: 400; letter-spacing: var(--uix-tracking-tight); }
|
|
1735
1655
|
.uix-section-link { color: var(--uix-text-hushed); font-size: var(--uix-text-meta); text-decoration: none; }
|
|
1736
|
-
|
|
1656
|
+
/* already a quiet link by its own design — hover/focus parity with link.css */
|
|
1657
|
+
.uix-section-link:is(:hover, :focus-visible) { color: var(--uix-text); text-decoration: underline; }
|
|
1737
1658
|
|
|
1738
1659
|
/* ── content grid + rail ───────────────────────────────────────────────────── */
|
|
1739
1660
|
.uix-content-grid { display: grid; grid-template-columns: minmax(0, 1.65fr) minmax(280px, 0.75fr); gap: var(--uix-space-7); align-items: start; }
|
|
@@ -1837,36 +1758,90 @@
|
|
|
1837
1758
|
* noise at list density (TENSOR INTRA-04, operator-rejected).
|
|
1838
1759
|
*
|
|
1839
1760
|
* A quiet link inherits the surrounding text colour and shows its underline on
|
|
1840
|
-
* hover/focus.
|
|
1841
|
-
*
|
|
1842
|
-
*
|
|
1761
|
+
* hover/focus. The global :focus-visible ring (base.css) still fires, so the keyboard
|
|
1762
|
+
* affordance never rests on the underline alone. WCAG 1.4.1 is not in play for anything
|
|
1763
|
+
* below: the link is the WHOLE text of its block — a title, a name, a data cell — or it
|
|
1764
|
+
* is the block itself. It is never a phrase inside a sentence.
|
|
1843
1765
|
*
|
|
1844
|
-
*
|
|
1845
|
-
*
|
|
1846
|
-
*
|
|
1847
|
-
*
|
|
1848
|
-
*
|
|
1849
|
-
*
|
|
1850
|
-
*
|
|
1766
|
+
* A slot earns quiet-BY-DEFAULT only when BOTH hold:
|
|
1767
|
+
* (i) the anchor fills a named title/name slot or a data cell — the link text IS the
|
|
1768
|
+
* block, not a phrase inside running copy; and
|
|
1769
|
+
* (ii) the surrounding row/card/tile already reads as interactive (hover state, cursor,
|
|
1770
|
+
* bordered unit), or the slot is that record's primary label.
|
|
1771
|
+
*
|
|
1772
|
+
* Deliberate exclusions, so the next person doesn't "finish the job":
|
|
1773
|
+
* • Prose and message bodies — .uix-prose, .uix-note, .uix-notice__copy,
|
|
1774
|
+
* .uix-timeline__body, .uix-audit__detail, .uix-notif copy. Links there sit inside
|
|
1775
|
+
* sentences: 1.4.1 applies and the base treatment is correct.
|
|
1776
|
+
* • .uix-alert, .uix-toast, .uix-peek__title — nothing else in those containers signals
|
|
1777
|
+
* that the link navigates, so the colour IS the affordance. peek.css sets --uix-link
|
|
1778
|
+
* on its title anchor on purpose; do not quiet it.
|
|
1779
|
+
* • .uix-comment__author — a byline renders "Author · 22m ago", so the name is a phrase
|
|
1780
|
+
* inside a text run, not the whole block, and .uix-comment__meta is not interactive.
|
|
1781
|
+
* It fails test (i) above. Products wanting the GitHub-style quiet byline opt in with
|
|
1782
|
+
* .uix-link--quiet; that is what the utility is for.
|
|
1783
|
+
* • .uix-navitem, .uix-breadcrumbs a, .uix-section-link are already quiet by their own
|
|
1784
|
+
* design and need no class here.
|
|
1785
|
+
*
|
|
1786
|
+
* Four forms:
|
|
1787
|
+
* 1 · `.uix-link--quiet` — the opt-in utility, for block links outside the registry.
|
|
1788
|
+
* 2 · TITLE / NAME SLOTS — quiet by default. `:not(.uix-btn)` so an anchor deliberately
|
|
1789
|
+
* styled as a button inside a title slot keeps its button treatment.
|
|
1790
|
+
* 3 · DATA CELLS — table cells and description-list values. `:not([class])` so
|
|
1791
|
+
* class-bearing anchors (`.uix-btn--link`, pills, tags) stay styled.
|
|
1792
|
+
* 4 · CONTAINER ANCHORS — the anchor IS the kit block (`<a class="uix-card">`). Without
|
|
1793
|
+
* this the base `a { color }` tints every word in the block brand-blue.
|
|
1851
1794
|
* Depends only on --uix-* tokens. */
|
|
1852
1795
|
@layer uix.components {
|
|
1853
1796
|
.uix-link--quiet,
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
.uix-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1797
|
+
|
|
1798
|
+
/* 2 · title / name slots */
|
|
1799
|
+
:is(
|
|
1800
|
+
/* editorial-home */
|
|
1801
|
+
.uix-featured__title, .uix-rail-card__title, .uix-news-lead__title,
|
|
1802
|
+
.uix-content-list__title, .uix-rundown__item-title, .uix-event-row__title,
|
|
1803
|
+
.uix-status-row__name,
|
|
1804
|
+
/* records, rows, cards */
|
|
1805
|
+
.uix-card__title, .uix-list__title, .uix-inbox__subject, .uix-kanban__card-title,
|
|
1806
|
+
.uix-media__name, .uix-attachment__name, .uix-contact__name, .uix-user-chip__name,
|
|
1807
|
+
.uix-audit__actor
|
|
1808
|
+
) a:not(.uix-btn),
|
|
1809
|
+
|
|
1810
|
+
/* 3 · data cells */
|
|
1811
|
+
:is(.uix-table td, .uix-dl dd) a:not([class]),
|
|
1812
|
+
|
|
1813
|
+
/* 4 · container anchors */
|
|
1814
|
+
a:is(
|
|
1815
|
+
.uix-card, .uix-stat, .uix-list__item, .uix-inbox__item, .uix-kanban__card,
|
|
1816
|
+
.uix-notif, .uix-media, .uix-attachment, .uix-contact, .uix-cmdk__item,
|
|
1817
|
+
.uix-content-list__item, .uix-event-row, .uix-status-row
|
|
1818
|
+
) { color: inherit; text-decoration: none; }
|
|
1819
|
+
|
|
1820
|
+
.uix-link--quiet:is(:hover, :focus-visible),
|
|
1821
|
+
|
|
1822
|
+
:is(
|
|
1823
|
+
.uix-featured__title, .uix-rail-card__title, .uix-news-lead__title,
|
|
1824
|
+
.uix-content-list__title, .uix-rundown__item-title, .uix-event-row__title,
|
|
1825
|
+
.uix-status-row__name,
|
|
1826
|
+
.uix-card__title, .uix-list__title, .uix-inbox__subject, .uix-kanban__card-title,
|
|
1827
|
+
.uix-media__name, .uix-attachment__name, .uix-contact__name, .uix-user-chip__name,
|
|
1828
|
+
.uix-audit__actor
|
|
1829
|
+
) a:not(.uix-btn):is(:hover, :focus-visible),
|
|
1830
|
+
|
|
1831
|
+
:is(.uix-table td, .uix-dl dd) a:not([class]):is(:hover, :focus-visible) { text-decoration: underline; }
|
|
1832
|
+
|
|
1833
|
+
/* Container anchors never underline: the anchor wraps the whole block, so an underline
|
|
1834
|
+
would strike through every word in it. They take the kit's standard row-hover tint
|
|
1835
|
+
instead — the same --uix-bg-hover that .uix-list__item / .uix-inbox__item / .uix-cmdk__item
|
|
1836
|
+
already use, so containers with a hover of their own just restate it. */
|
|
1837
|
+
a:is(
|
|
1838
|
+
.uix-card, .uix-stat, .uix-list__item, .uix-inbox__item, .uix-kanban__card,
|
|
1839
|
+
.uix-notif, .uix-media, .uix-attachment, .uix-contact, .uix-cmdk__item,
|
|
1840
|
+
.uix-content-list__item, .uix-event-row, .uix-status-row
|
|
1841
|
+
):is(:hover, :focus-visible) { background: var(--uix-bg-hover); }
|
|
1842
|
+
|
|
1843
|
+
/* Container anchors that declare no display of their own would render inline as an <a>.
|
|
1844
|
+
The rest of form 4 (flex/grid rows) set theirs already and must NOT be overridden —
|
|
1845
|
+
link.css is imported last, so a blanket display here would flatten them. */
|
|
1846
|
+
a:is(.uix-card, .uix-stat, .uix-kanban__card) { display: block; }
|
|
1872
1847
|
}
|
package/build/css/styles.css
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
@layer uix.tokens, uix.base, uix.util, uix.motion, uix.components
|
|
2
|
+
@layer uix.tokens, uix.base, uix.util, uix.motion, uix.components;
|
|
3
3
|
/* uix-styleguide — aggregate stylesheet. Declares the cascade-layer order, then imports each layer.
|
|
4
4
|
Component @imports are appended here as phases land (each component file declares @layer uix.components). */
|
|
5
5
|
/* uix tokens — REDIRECT (no longer hand-authored).
|
|
@@ -149,19 +149,19 @@
|
|
|
149
149
|
--uix-font-sans: "Inter",system-ui,sans-serif;
|
|
150
150
|
--uix-font-heading: "IBM Plex Sans","Inter",system-ui,sans-serif;
|
|
151
151
|
--uix-font-mono: "IBM Plex Mono",ui-monospace,monospace;
|
|
152
|
-
--uix-text-display:
|
|
152
|
+
--uix-text-display: 40px;
|
|
153
153
|
--uix-leading-display: 1.05;
|
|
154
|
-
--uix-text-data-hero:
|
|
154
|
+
--uix-text-data-hero: 34px;
|
|
155
155
|
--uix-leading-data-hero: 1.1;
|
|
156
|
-
--uix-text-h2:
|
|
156
|
+
--uix-text-h2: 24px;
|
|
157
157
|
--uix-leading-h2: 1.15;
|
|
158
|
-
--uix-text-h3:
|
|
158
|
+
--uix-text-h3: 15px;
|
|
159
159
|
--uix-leading-h3: 1.3;
|
|
160
|
-
--uix-text-body:
|
|
160
|
+
--uix-text-body: 14px;
|
|
161
161
|
--uix-leading-body: 1.5;
|
|
162
|
-
--uix-text-meta:
|
|
162
|
+
--uix-text-meta: 12.5px;
|
|
163
163
|
--uix-leading-meta: 1.4;
|
|
164
|
-
--uix-text-eyebrow:
|
|
164
|
+
--uix-text-eyebrow: 11px;
|
|
165
165
|
--uix-leading-eyebrow: 1.2;
|
|
166
166
|
--uix-tracking-tight: -0.02em;
|
|
167
167
|
--uix-tracking-eyebrow: 0.06em;
|
|
@@ -272,9 +272,6 @@
|
|
|
272
272
|
h3 { font-size: var(--uix-text-h3); line-height: var(--uix-leading-h3); }
|
|
273
273
|
|
|
274
274
|
img, svg, video, canvas { display: block; max-width: 100%; }
|
|
275
|
-
/* the display:block reset above (and any component display) would defeat the `hidden`
|
|
276
|
-
attribute; restore it globally. `until-found` keeps find-in-page auto-reveal (UIX-A11Y-4). */
|
|
277
|
-
[hidden]:not([hidden="until-found"]) { display: none !important; }
|
|
278
275
|
input, button, textarea, select { font: inherit; color: inherit; }
|
|
279
276
|
code, kbd, pre, samp { font-family: var(--uix-font-mono); }
|
|
280
277
|
|
|
@@ -506,8 +503,7 @@
|
|
|
506
503
|
}
|
|
507
504
|
.uix-checkbox > input:checked + .uix-checkbox__box,
|
|
508
505
|
.uix-checkbox > input:indeterminate + .uix-checkbox__box { background: var(--uix-accent); border-color: var(--uix-accent); }
|
|
509
|
-
.uix-checkbox > input:checked + .uix-checkbox__box svg
|
|
510
|
-
.uix-checkbox > input:indeterminate + .uix-checkbox__box svg { opacity: 1; transform: none; } /* indeterminate shows its dash icon, not just the filled box (UIX-A11Y-3) */
|
|
506
|
+
.uix-checkbox > input:checked + .uix-checkbox__box svg { opacity: 1; transform: none; }
|
|
511
507
|
.uix-checkbox > input:focus-visible + .uix-checkbox__box { outline: 2px solid var(--uix-ring); outline-offset: 2px; }
|
|
512
508
|
.uix-checkbox > input:disabled ~ * { opacity: .5; }
|
|
513
509
|
}
|
|
@@ -559,7 +555,7 @@
|
|
|
559
555
|
transition: background-color var(--uix-dur-fast) var(--uix-ease-out), color var(--uix-dur-fast) var(--uix-ease-out);
|
|
560
556
|
}
|
|
561
557
|
.uix-segmented__option:hover { color: var(--uix-text); }
|
|
562
|
-
.uix-segmented__option[aria-pressed="true"] { background: var(--uix-surface); color: var(--uix-text); box-shadow: var(--uix-shadow-sm); }
|
|
558
|
+
.uix-segmented__option[aria-selected="true"], .uix-segmented__option[aria-pressed="true"] { background: var(--uix-surface); color: var(--uix-text); box-shadow: var(--uix-shadow-sm); }
|
|
563
559
|
.uix-segmented__option:focus-visible { outline: 2px solid var(--uix-ring); outline-offset: 1px; }
|
|
564
560
|
}
|
|
565
561
|
/* uix slider (native range, styled) — depends only on --uix-* tokens. */
|
|
@@ -633,9 +629,7 @@
|
|
|
633
629
|
display: inline-flex; align-items: center; gap: var(--uix-space-1); padding: var(--uix-space-1) var(--uix-space-1) var(--uix-space-1) var(--uix-space-2); border-radius: var(--uix-radius-sm);
|
|
634
630
|
background: var(--uix-bg-active); color: var(--uix-text); font-size: var(--uix-text-meta);
|
|
635
631
|
}
|
|
636
|
-
.uix-tag__remove {
|
|
637
|
-
/* Invisible overlay grows the 16px visual to a 24px hit target (UIX-A11Y-3). */
|
|
638
|
-
.uix-tag__remove::before { content: ""; position: absolute; inset: -4px; }
|
|
632
|
+
.uix-tag__remove { display: grid; place-items: center; width: 16px; height: 16px; border: 0; background: transparent; color: var(--uix-text-muted); cursor: pointer; border-radius: var(--uix-radius-xs); }
|
|
639
633
|
.uix-tag__remove:hover { background: var(--uix-bg-hover); color: var(--uix-text); }
|
|
640
634
|
.uix-tag__remove svg { width: 12px; height: 12px; }
|
|
641
635
|
}
|
|
@@ -644,11 +638,6 @@
|
|
|
644
638
|
.uix-form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--uix-space-5); }
|
|
645
639
|
.uix-fieldset { border: 1px solid var(--uix-border); border-radius: var(--uix-radius-lg); padding: var(--uix-space-6); }
|
|
646
640
|
.uix-fieldset > legend { padding: 0 var(--uix-space-2); font-size: var(--uix-text-meta); font-weight: 600; color: var(--uix-text); }
|
|
647
|
-
/* Labeled RadioGroup renders as a fieldset (UIX-A11Y-3): strip the UA chrome so it
|
|
648
|
-
looks identical to the plain-div group; the legend spaces itself (fieldset gap
|
|
649
|
-
doesn't reach a legend). */
|
|
650
|
-
fieldset.uix-radio-group { border: 0; margin: 0; padding: 0; min-inline-size: auto; }
|
|
651
|
-
.uix-radio-group__legend { padding: 0; margin: 0 0 var(--uix-space-2); font-size: var(--uix-text-meta); font-weight: 600; color: var(--uix-text); }
|
|
652
641
|
.uix-form-inline { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--uix-space-4); }
|
|
653
642
|
.uix-validation-summary {
|
|
654
643
|
border: 1px solid var(--uix-danger); background: var(--uix-danger-bg); color: var(--uix-text);
|
|
@@ -669,7 +658,7 @@
|
|
|
669
658
|
border: 1px solid var(--uix-border); border-radius: var(--uix-radius-lg); overflow: hidden;
|
|
670
659
|
transition: grid-template-columns var(--uix-dur) var(--uix-ease-out), grid-template-rows var(--uix-dur) var(--uix-ease-out);
|
|
671
660
|
}
|
|
672
|
-
.uix-shell__sidebar { grid-row: 1 / 3; background: var(--uix-bg-subtle); border-right: 1px solid var(--uix-border); overflow-y: auto; overflow-x: hidden;
|
|
661
|
+
.uix-shell__sidebar { grid-row: 1 / 3; background: var(--uix-bg-subtle); border-right: 1px solid var(--uix-border); overflow-y: auto; overflow-x: hidden; }
|
|
673
662
|
.uix-shell__topbar { grid-column: 2; display: flex; align-items: center; gap: var(--uix-space-3); padding: 0 var(--uix-space-6); background: var(--uix-bg-app); border-bottom: 1px solid var(--uix-border); }
|
|
674
663
|
.uix-shell__main { grid-column: 2; overflow: auto; padding: var(--uix-space-7); background: var(--uix-bg-app); }
|
|
675
664
|
|
|
@@ -678,39 +667,17 @@
|
|
|
678
667
|
only) → hidden (0). data-collapsed stays a back-compat alias for the rail. */
|
|
679
668
|
.uix-shell[data-nav="rail"], .uix-shell[data-collapsed] { grid-template-columns: var(--uix-sidebar-w-rail) 1fr; }
|
|
680
669
|
.uix-shell[data-nav="hidden"] { grid-template-columns: 0 1fr; }
|
|
681
|
-
/* the 0-width column still renders its links — visibility removes them from the tab
|
|
682
|
-
order / accessibility tree while keeping the width transition (UIX-A11Y-2) */
|
|
683
|
-
.uix-shell[data-nav="hidden"] .uix-shell__sidebar { visibility: hidden; }
|
|
684
670
|
|
|
685
671
|
/* ── focus / immersive mode ───────────────────────────────────────────────────
|
|
686
672
|
A table-scoped escape hatch: hide the sidebar AND the topbar so a dense grid
|
|
687
673
|
uses the whole frame. The app toggles [data-focus] (from a toolbar maximize
|
|
688
674
|
control) and restores the previous nav state + focus on Esc. */
|
|
689
675
|
.uix-shell[data-focus] { grid-template-columns: 0 1fr; grid-template-rows: 0 1fr; }
|
|
690
|
-
.uix-shell[data-focus] .uix-shell__sidebar { visibility: hidden; } /* see [data-nav="hidden"] above (UIX-A11Y-2) */
|
|
691
676
|
.uix-shell[data-focus] .uix-shell__topbar { display: none; }
|
|
692
677
|
|
|
693
678
|
/* a floating host for the "exit focus" affordance (Esc also exits) */
|
|
694
679
|
.uix-shell__focus-exit { position: absolute; top: var(--uix-space-3); right: var(--uix-space-3); z-index: var(--uix-z-overlay); }
|
|
695
680
|
|
|
696
|
-
/* ── skip link ────────────────────────────────────────────────────────────────
|
|
697
|
-
First tab stop in the shell (UIX-A11Y-2): visually hidden until keyboard focus,
|
|
698
|
-
then a small pill floating over the shell's top-left corner. */
|
|
699
|
-
.uix-skiplink {
|
|
700
|
-
position: absolute; top: var(--uix-space-3); left: var(--uix-space-3); z-index: var(--uix-z-overlay);
|
|
701
|
-
width: 1px; height: 1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap;
|
|
702
|
-
}
|
|
703
|
-
.uix-skiplink:focus-visible {
|
|
704
|
-
width: auto; height: auto; clip: auto;
|
|
705
|
-
display: inline-flex; align-items: center;
|
|
706
|
-
padding: var(--uix-space-2) var(--uix-space-4);
|
|
707
|
-
background: var(--uix-surface); color: var(--uix-text);
|
|
708
|
-
border: 1px solid var(--uix-border); border-radius: var(--uix-radius-pill);
|
|
709
|
-
box-shadow: var(--uix-shadow-popover);
|
|
710
|
-
outline: 2px solid var(--uix-ring); outline-offset: 2px;
|
|
711
|
-
font-size: var(--uix-text-meta); font-weight: 500; text-decoration: none;
|
|
712
|
-
}
|
|
713
|
-
|
|
714
681
|
/* ── full-bleed main ──────────────────────────────────────────────────────────
|
|
715
682
|
Opt-in per surface: a genuinely wide grid drops the content gutter and runs
|
|
716
683
|
edge to edge, reclaiming 2 x --uix-space-7. Not the default — most pages want
|
|
@@ -751,14 +718,9 @@
|
|
|
751
718
|
.uix-navitem__badge { font-size: var(--uix-text-meta); color: var(--uix-text-muted); }
|
|
752
719
|
/* on the active tint, muted badge dips below AA — hushed composites darker on the tint */
|
|
753
720
|
.uix-navitem[aria-current="page"] .uix-navitem__badge { color: var(--uix-text-hushed); }
|
|
754
|
-
.uix-navitem__star {
|
|
755
|
-
/* invisible halo → 24px effective target with zero visual change (UIX-A11Y-2) */
|
|
756
|
-
.uix-navitem__star::before { content: ""; position: absolute; inset: -1px; }
|
|
721
|
+
.uix-navitem__star { display: grid; place-items: center; width: 22px; height: 22px; border: 0; background: transparent; color: var(--uix-text-muted); cursor: pointer; border-radius: var(--uix-radius-xs); opacity: 0; transition: opacity var(--uix-dur-fast) var(--uix-ease-out); }
|
|
757
722
|
.uix-navitem__star svg { width: 15px; height: 15px; }
|
|
758
|
-
|
|
759
|
-
.uix-navitem:hover .uix-navitem__star,
|
|
760
|
-
.uix-navitem__star:focus-visible,
|
|
761
|
-
.uix-navitem:focus-within .uix-navitem__star { opacity: 1; }
|
|
723
|
+
.uix-navitem:hover .uix-navitem__star { opacity: 1; }
|
|
762
724
|
.uix-navitem__star[data-on] { opacity: 1; color: var(--uix-warning); }
|
|
763
725
|
.uix-navitem__star[data-on] svg { fill: currentColor; }
|
|
764
726
|
|
|
@@ -769,32 +731,19 @@
|
|
|
769
731
|
.uix-navgroup__chevron { width: var(--uix-icon-sm); height: var(--uix-icon-sm); }
|
|
770
732
|
.uix-navgroup__panel { display: grid; grid-template-rows: 1fr; transition: grid-template-rows var(--uix-dur) var(--uix-ease-out); }
|
|
771
733
|
.uix-navgroup__trigger[aria-expanded="false"] + .uix-navgroup__panel { grid-template-rows: 0fr; }
|
|
772
|
-
|
|
773
|
-
(UIX-A11Y-2); the transition delays hiding until the row collapse finishes, and
|
|
774
|
-
visibility snaps back to visible instantly on expand, so nothing visibly glitches. */
|
|
775
|
-
.uix-navgroup__panel > div { overflow: hidden; visibility: visible; transition: visibility var(--uix-dur) var(--uix-ease-out); }
|
|
776
|
-
.uix-navgroup__trigger[aria-expanded="false"] + .uix-navgroup__panel > div { visibility: hidden; }
|
|
734
|
+
.uix-navgroup__panel > div { overflow: hidden; }
|
|
777
735
|
.uix-subitem { padding-left: var(--uix-space-5); }
|
|
778
736
|
.uix-subitem .uix-navitem__label::before { content: ""; display: inline-block; width: 4px; height: 4px; border-radius: 50%; background: var(--uix-text-muted); margin-right: var(--uix-space-3); vertical-align: middle; }
|
|
779
737
|
|
|
780
738
|
/* collapsed rail */
|
|
781
739
|
.uix-sidebar[data-collapsed], .uix-sidebar[data-nav="rail"] { width: var(--uix-sidebar-w-rail); }
|
|
740
|
+
.uix-sidebar[data-collapsed] .uix-navitem__label,
|
|
782
741
|
.uix-sidebar[data-collapsed] .uix-navitem__badge,
|
|
783
742
|
.uix-sidebar[data-collapsed] .uix-navitem__star,
|
|
784
743
|
.uix-sidebar[data-collapsed] .uix-sidebar__eyebrow,
|
|
785
744
|
.uix-sidebar[data-collapsed] .uix-sidebar__brand,
|
|
786
745
|
.uix-sidebar[data-collapsed] .uix-navgroup__chevron,
|
|
787
746
|
.uix-sidebar[data-collapsed] .uix-navgroup__panel { display: none; }
|
|
788
|
-
/* rail labels stay in the accessibility tree — clip pattern (mirrors .uix-visually-hidden),
|
|
789
|
-
not display:none, so icon-only nav items keep their names (UIX-A11Y-2). position:absolute
|
|
790
|
-
removes the label from the flex row, so the centered rail layout is unaffected. */
|
|
791
|
-
.uix-sidebar[data-collapsed] .uix-navitem__label {
|
|
792
|
-
position: absolute !important;
|
|
793
|
-
width: 1px; height: 1px;
|
|
794
|
-
padding: 0; margin: -1px;
|
|
795
|
-
overflow: hidden; clip: rect(0, 0, 0, 0);
|
|
796
|
-
white-space: nowrap; border: 0;
|
|
797
|
-
}
|
|
798
747
|
/* center the icon-only rail; head keeps just the toggle, centered */
|
|
799
748
|
.uix-sidebar[data-collapsed] .uix-navitem { justify-content: center; padding: 0; gap: 0; }
|
|
800
749
|
.uix-sidebar[data-collapsed] .uix-sidebar__head { justify-content: center; padding-inline: 0; }
|
|
@@ -803,7 +752,9 @@
|
|
|
803
752
|
@layer uix.components {
|
|
804
753
|
.uix-breadcrumbs { display: flex; align-items: center; gap: var(--uix-space-2); flex-wrap: wrap; font-size: var(--uix-text-meta); color: var(--uix-text-muted); }
|
|
805
754
|
.uix-breadcrumbs a { color: var(--uix-text-muted); text-decoration: none; }
|
|
806
|
-
|
|
755
|
+
/* already a quiet link by its own design — hover/focus parity with the quiet-link
|
|
756
|
+
contract in link.css, so the keyboard state matches the pointer state. */
|
|
757
|
+
.uix-breadcrumbs a:is(:hover, :focus-visible) { color: var(--uix-text); text-decoration: underline; }
|
|
807
758
|
.uix-breadcrumbs__sep { opacity: .55; }
|
|
808
759
|
.uix-breadcrumbs [aria-current="page"] { color: var(--uix-text); font-weight: 500; }
|
|
809
760
|
}
|
|
@@ -875,9 +826,6 @@
|
|
|
875
826
|
.uix-cmdk { width: min(560px, 92vw); border: 1px solid var(--uix-border); border-radius: var(--uix-radius-lg); background: var(--uix-surface-2); box-shadow: var(--uix-shadow-overlay); overflow: hidden; }
|
|
876
827
|
.uix-cmdk__input { width: 100%; height: 48px; border: 0; border-bottom: 1px solid var(--uix-border); background: transparent; color: var(--uix-text); font: inherit; font-size: var(--uix-text-h3); padding: 0 var(--uix-space-4); }
|
|
877
828
|
.uix-cmdk__input:focus { outline: none; }
|
|
878
|
-
/* visible focus replacement for the suppressed outline (UIX-A11Y-1): the divider under the
|
|
879
|
-
input thickens to a 2px ring-colored line */
|
|
880
|
-
.uix-cmdk__input:focus-visible { border-bottom-color: var(--uix-ring); box-shadow: 0 1px 0 0 var(--uix-ring); }
|
|
881
829
|
.uix-cmdk__list { max-height: 320px; overflow-y: auto; padding: var(--uix-space-2); }
|
|
882
830
|
.uix-cmdk__group { font-size: var(--uix-text-eyebrow); letter-spacing: var(--uix-tracking-eyebrow); text-transform: uppercase; color: var(--uix-text-muted); padding: var(--uix-space-2) var(--uix-space-3) var(--uix-space-1); }
|
|
883
831
|
.uix-cmdk__item { display: flex; align-items: center; gap: var(--uix-space-3); padding: var(--uix-space-3) var(--uix-space-3); border-radius: var(--uix-radius-sm); color: var(--uix-text); cursor: pointer; font-size: var(--uix-text-body); }
|
|
@@ -936,8 +884,6 @@
|
|
|
936
884
|
.uix-stat__value { font-size: var(--uix-text-data-hero); font-weight: 600; line-height: var(--uix-leading-data-hero); margin-top: var(--uix-space-3); }
|
|
937
885
|
.uix-stat__meta { font-size: var(--uix-text-meta); color: var(--uix-text-muted); margin-top: var(--uix-space-2); display: flex; align-items: center; gap: var(--uix-space-2); }
|
|
938
886
|
.uix-stat__trend { display: inline-flex; align-items: center; gap: var(--uix-space-1); font-size: var(--uix-text-meta); font-weight: 600; padding: var(--uix-space-1) var(--uix-space-2); border-radius: var(--uix-radius-pill); }
|
|
939
|
-
/* direction glyph inside the chip (UIX-A11Y-4) — sized to sit on the text baseline row */
|
|
940
|
-
.uix-stat__trend svg { width: 10px; height: 10px; flex: none; }
|
|
941
887
|
.uix-stat__trend--up { color: var(--uix-success); background: var(--uix-success-bg); }
|
|
942
888
|
.uix-stat__trend--down { color: var(--uix-danger-text); background: var(--uix-danger-bg); }
|
|
943
889
|
}
|
|
@@ -998,28 +944,18 @@
|
|
|
998
944
|
/* multi-column sort ordinal (⇧+click adds a secondary key) */
|
|
999
945
|
.uix-table th[data-sort-order]::before { content: attr(data-sort-order); display: inline-block; margin-right: var(--uix-space-1); font-size: var(--uix-text-eyebrow); font-variant-numeric: tabular-nums; color: var(--uix-accent); }
|
|
1000
946
|
|
|
1001
|
-
/* sortable header's real <button> (UIX-A11Y-2): visually indistinguishable from the old
|
|
1002
|
-
plain-text th — inherited font/colour, no chrome — with an inset overlay so the whole
|
|
1003
|
-
cell stays the click target (the sticky th is its containing block). The sort arrow and
|
|
1004
|
-
ordinal stay as th pseudo-content so they never pollute the button's accessible name. */
|
|
1005
|
-
.uix-th__sortbtn { font: inherit; color: inherit; background: none; border: 0; padding: 0; text-align: inherit; cursor: pointer; }
|
|
1006
|
-
.uix-th__sortbtn::before { content: ""; position: absolute; inset: 0; }
|
|
1007
|
-
|
|
1008
947
|
.uix-table td { padding: 0 var(--uix-space-4); height: var(--uix-row-h); border-bottom: 1px solid var(--uix-border); color: var(--uix-text); vertical-align: middle; }
|
|
1009
948
|
.uix-table tbody tr { background: var(--uix-row); }
|
|
1010
949
|
.uix-table tbody tr:nth-child(even) { background: var(--uix-row-alt); }
|
|
1011
950
|
.uix-table--no-zebra tbody tr, .uix-table--no-zebra tbody tr:nth-child(even) { background: var(--uix-row); }
|
|
1012
951
|
.uix-table tbody tr[data-pinned] { background: var(--uix-row-pinned-bg); }
|
|
1013
|
-
|
|
1014
|
-
table row — AT state comes from the row checkbox (UIX-A11Y-2). */
|
|
1015
|
-
.uix-table tbody tr[data-selected] { background: var(--uix-row-selected-bg); }
|
|
952
|
+
.uix-table tbody tr[aria-selected="true"] { background: var(--uix-row-selected-bg); }
|
|
1016
953
|
.uix-table tbody tr:hover { background: var(--uix-bg-hover); }
|
|
1017
954
|
.uix-table[data-density="compact"] td, .uix-table--compact td { height: var(--uix-row-h-compact); }
|
|
1018
955
|
.uix-table[data-density="comfortable"] td { height: var(--uix-row-h-comfortable); }
|
|
1019
956
|
|
|
1020
957
|
.uix-table__pin { border: 0; background: transparent; color: var(--uix-text-muted); cursor: pointer; padding: var(--uix-space-1); border-radius: var(--uix-radius-xs); opacity: 0; transition: opacity var(--uix-dur-fast) var(--uix-ease-out); }
|
|
1021
|
-
|
|
1022
|
-
.uix-table tbody tr:hover .uix-table__pin, .uix-table__pin:focus-visible, .uix-table__pin[data-on] { opacity: 1; }
|
|
958
|
+
.uix-table tbody tr:hover .uix-table__pin, .uix-table__pin[data-on] { opacity: 1; }
|
|
1023
959
|
.uix-table__pin:hover { background: var(--uix-bg-active); color: var(--uix-text); }
|
|
1024
960
|
.uix-table__pin[data-on] { color: var(--uix-accent); }
|
|
1025
961
|
.uix-table__pin svg { width: 15px; height: 15px; }
|
|
@@ -1033,7 +969,7 @@
|
|
|
1033
969
|
.uix-table--pinned-col.uix-table--no-zebra tbody tr td:first-child,
|
|
1034
970
|
.uix-table--pinned-col.uix-table--no-zebra tbody tr:nth-child(even) td:first-child { background: var(--uix-row); }
|
|
1035
971
|
.uix-table--pinned-col tbody tr[data-pinned] td:first-child { background: var(--uix-row-pinned-bg); }
|
|
1036
|
-
.uix-table--pinned-col tbody tr[
|
|
972
|
+
.uix-table--pinned-col tbody tr[aria-selected="true"] td:first-child { background: var(--uix-row-selected-bg); }
|
|
1037
973
|
.uix-table--pinned-col tbody tr:hover td:first-child { background: var(--uix-bg-hover); }
|
|
1038
974
|
|
|
1039
975
|
/* ── column sizing + cell behaviour (a shared vocabulary, not per-app px) ──────── */
|
|
@@ -1132,7 +1068,7 @@
|
|
|
1132
1068
|
.uix-table--cards thead { position: absolute; width: 1px; height: 1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
|
|
1133
1069
|
.uix-table--cards tbody, .uix-table--cards tr, .uix-table--cards td { display: block; width: auto; }
|
|
1134
1070
|
.uix-table--cards tbody tr { border: 1px solid var(--uix-border); border-radius: var(--uix-radius-md); background: var(--uix-surface); margin: 0 0 var(--uix-space-3); padding: var(--uix-space-1) var(--uix-space-4); box-shadow: var(--uix-shadow-sm); }
|
|
1135
|
-
.uix-table--cards tbody tr[
|
|
1071
|
+
.uix-table--cards tbody tr[aria-selected="true"] { box-shadow: 0 0 0 2px var(--uix-accent); }
|
|
1136
1072
|
.uix-table--cards td { height: auto; display: flex; justify-content: space-between; align-items: center; gap: var(--uix-space-5); padding: var(--uix-space-2) 0; border-bottom: 1px solid var(--uix-border); text-align: right; white-space: normal; }
|
|
1137
1073
|
.uix-table--cards td:last-child { border-bottom: 0; }
|
|
1138
1074
|
.uix-table--cards td::before { content: attr(data-label); color: var(--uix-text-muted); font-size: var(--uix-text-meta); font-weight: 500; text-align: left; flex: none; }
|
|
@@ -1283,8 +1219,7 @@
|
|
|
1283
1219
|
background: var(--uix-text); color: var(--uix-bg-app);
|
|
1284
1220
|
font-size: var(--uix-text-meta); font-weight: 500; line-height: 1.4;
|
|
1285
1221
|
padding: var(--uix-space-2) var(--uix-space-3); border-radius: var(--uix-radius-sm);
|
|
1286
|
-
|
|
1287
|
-
box-shadow: var(--uix-shadow-popover); white-space: normal;
|
|
1222
|
+
box-shadow: var(--uix-shadow-popover); white-space: normal; pointer-events: none;
|
|
1288
1223
|
opacity: 0; transition: opacity var(--uix-dur-fast) var(--uix-ease-out);
|
|
1289
1224
|
}
|
|
1290
1225
|
.uix-tooltip__bubble:popover-open { opacity: 1; }
|
|
@@ -1327,8 +1262,7 @@
|
|
|
1327
1262
|
}
|
|
1328
1263
|
/* uix timeline / activity feed — depends only on --uix-* tokens. */
|
|
1329
1264
|
@layer uix.components {
|
|
1330
|
-
|
|
1331
|
-
.uix-timeline { display: flex; flex-direction: column; list-style: none; margin: 0; padding: 0; }
|
|
1265
|
+
.uix-timeline { display: flex; flex-direction: column; }
|
|
1332
1266
|
.uix-timeline__item { display: grid; grid-template-columns: 24px 1fr; gap: var(--uix-space-3); }
|
|
1333
1267
|
.uix-timeline__rail { display: flex; flex-direction: column; align-items: center; }
|
|
1334
1268
|
.uix-timeline__node { width: 12px; height: 12px; border-radius: 50%; background: var(--uix-accent); margin-top: var(--uix-space-1); flex: none; box-shadow: 0 0 0 3px var(--uix-brand-muted); }
|
|
@@ -1450,9 +1384,7 @@
|
|
|
1450
1384
|
@starting-style { .uix-dialog[open]::backdrop { opacity: 0; } }
|
|
1451
1385
|
|
|
1452
1386
|
.uix-dialog__header { display: flex; align-items: center; gap: var(--uix-space-3); padding: var(--uix-space-4) var(--uix-space-5); border-bottom: 1px solid var(--uix-border); }
|
|
1453
|
-
|
|
1454
|
-
heading font/tracking/leading so it renders exactly like the old <div> */
|
|
1455
|
-
.uix-dialog__title { font-size: var(--uix-text-h3); font-weight: 600; font-family: inherit; letter-spacing: inherit; line-height: inherit; }
|
|
1387
|
+
.uix-dialog__title { font-size: var(--uix-text-h3); font-weight: 600; }
|
|
1456
1388
|
.uix-dialog__close { margin-left: auto; border: 0; background: transparent; color: var(--uix-text-muted); cursor: pointer; width: 30px; height: 30px; display: grid; place-items: center; border-radius: var(--uix-radius-sm); }
|
|
1457
1389
|
.uix-dialog__close:hover { background: var(--uix-bg-hover); color: var(--uix-text); }
|
|
1458
1390
|
.uix-dialog__close svg { width: var(--uix-icon-md); height: var(--uix-icon-md); }
|
|
@@ -1512,13 +1444,7 @@
|
|
|
1512
1444
|
.uix-peek__nav { display: inline-flex; gap: var(--uix-space-1); }
|
|
1513
1445
|
.uix-peek__navbtn { width: 28px; height: 28px; display: grid; place-items: center; border: 1px solid var(--uix-border); background: var(--uix-surface); color: var(--uix-text); border-radius: var(--uix-radius-sm); cursor: pointer; }
|
|
1514
1446
|
.uix-peek__navbtn:hover { background: var(--uix-bg-hover); }
|
|
1515
|
-
|
|
1516
|
-
mute it and suppress the hover cue like a disabled control */
|
|
1517
|
-
.uix-peek__navbtn[aria-disabled="true"] { color: var(--uix-text-muted); cursor: default; }
|
|
1518
|
-
.uix-peek__navbtn[aria-disabled="true"]:hover { background: var(--uix-surface); }
|
|
1519
|
-
/* title is an <h2> for SR navigation (UIX-A11Y-1); inherits neutralize the base h2
|
|
1520
|
-
heading font/tracking/leading so it renders exactly like the old <div> */
|
|
1521
|
-
.uix-peek__title { font-size: var(--uix-text-h3); font-weight: 600; font-family: inherit; letter-spacing: inherit; line-height: inherit; }
|
|
1447
|
+
.uix-peek__title { font-size: var(--uix-text-h3); font-weight: 600; }
|
|
1522
1448
|
.uix-peek__title a { color: var(--uix-link); }
|
|
1523
1449
|
.uix-peek__close { margin-left: auto; border: 0; background: transparent; color: var(--uix-text-muted); cursor: pointer; width: 30px; height: 30px; display: grid; place-items: center; border-radius: var(--uix-radius-sm); }
|
|
1524
1450
|
.uix-peek__close:hover { background: var(--uix-bg-hover); color: var(--uix-text); }
|
|
@@ -1671,21 +1597,12 @@
|
|
|
1671
1597
|
.uix-inbox__list { border-right: 1px solid var(--uix-border); overflow-y: auto; background: var(--uix-surface); }
|
|
1672
1598
|
.uix-inbox__item { position: relative; display: flex; flex-direction: column; gap: var(--uix-space-1); padding: var(--uix-space-3) var(--uix-space-4); border-bottom: 1px solid var(--uix-border); cursor: pointer; }
|
|
1673
1599
|
.uix-inbox__item:hover { background: var(--uix-bg-hover); }
|
|
1674
|
-
/* keyboard active option (aria-activedescendant) mirrors the hover style (UIX-A11Y-2) */
|
|
1675
|
-
.uix-inbox__item[data-active] { background: var(--uix-bg-hover); }
|
|
1676
1600
|
.uix-inbox__item[aria-selected="true"] { background: linear-gradient(to right, var(--uix-accent) 3px, var(--uix-brand-muted) 3px); }
|
|
1677
1601
|
.uix-inbox__item[data-unread] .uix-inbox__subject { font-weight: 600; }
|
|
1678
1602
|
.uix-inbox__subject { font-size: var(--uix-text-body); }
|
|
1679
1603
|
.uix-inbox__preview { font-size: var(--uix-text-meta); color: var(--uix-text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
1680
1604
|
.uix-inbox__detail { overflow-y: auto; padding: var(--uix-space-5); background: var(--uix-bg-app); }
|
|
1681
|
-
|
|
1682
|
-
view="detail" — with a consumer-rendered Back control in the detail pane (UIX-A11Y-2) */
|
|
1683
|
-
@media (max-width: 700px) {
|
|
1684
|
-
.uix-inbox { grid-template-columns: 1fr; }
|
|
1685
|
-
.uix-inbox__detail { display: none; }
|
|
1686
|
-
.uix-inbox[data-view="detail"] .uix-inbox__list { display: none; }
|
|
1687
|
-
.uix-inbox[data-view="detail"] .uix-inbox__detail { display: block; }
|
|
1688
|
-
}
|
|
1605
|
+
@media (max-width: 700px) { .uix-inbox { grid-template-columns: 1fr; } .uix-inbox__detail { display: none; } }
|
|
1689
1606
|
}
|
|
1690
1607
|
/* uix notification center — depends only on --uix-* tokens. */
|
|
1691
1608
|
@layer uix.components {
|
|
@@ -2077,7 +1994,8 @@
|
|
|
2077
1994
|
.uix-section-head { min-height: 36px; margin-bottom: var(--uix-space-3); display: flex; align-items: center; justify-content: space-between; gap: var(--uix-space-4); }
|
|
2078
1995
|
.uix-section-title { margin: 0; font-family: var(--uix-font-heading); font-size: var(--uix-text-h2); font-weight: 400; letter-spacing: var(--uix-tracking-tight); }
|
|
2079
1996
|
.uix-section-link { color: var(--uix-text-hushed); font-size: var(--uix-text-meta); text-decoration: none; }
|
|
2080
|
-
|
|
1997
|
+
/* already a quiet link by its own design — hover/focus parity with link.css */
|
|
1998
|
+
.uix-section-link:is(:hover, :focus-visible) { color: var(--uix-text); text-decoration: underline; }
|
|
2081
1999
|
|
|
2082
2000
|
/* ── content grid + rail ───────────────────────────────────────────────────── */
|
|
2083
2001
|
.uix-content-grid { display: grid; grid-template-columns: minmax(0, 1.65fr) minmax(280px, 0.75fr); gap: var(--uix-space-7); align-items: start; }
|
|
@@ -2181,70 +2099,90 @@
|
|
|
2181
2099
|
* noise at list density (TENSOR INTRA-04, operator-rejected).
|
|
2182
2100
|
*
|
|
2183
2101
|
* A quiet link inherits the surrounding text colour and shows its underline on
|
|
2184
|
-
* hover/focus.
|
|
2185
|
-
*
|
|
2186
|
-
*
|
|
2102
|
+
* hover/focus. The global :focus-visible ring (base.css) still fires, so the keyboard
|
|
2103
|
+
* affordance never rests on the underline alone. WCAG 1.4.1 is not in play for anything
|
|
2104
|
+
* below: the link is the WHOLE text of its block — a title, a name, a data cell — or it
|
|
2105
|
+
* is the block itself. It is never a phrase inside a sentence.
|
|
2106
|
+
*
|
|
2107
|
+
* A slot earns quiet-BY-DEFAULT only when BOTH hold:
|
|
2108
|
+
* (i) the anchor fills a named title/name slot or a data cell — the link text IS the
|
|
2109
|
+
* block, not a phrase inside running copy; and
|
|
2110
|
+
* (ii) the surrounding row/card/tile already reads as interactive (hover state, cursor,
|
|
2111
|
+
* bordered unit), or the slot is that record's primary label.
|
|
2112
|
+
*
|
|
2113
|
+
* Deliberate exclusions, so the next person doesn't "finish the job":
|
|
2114
|
+
* • Prose and message bodies — .uix-prose, .uix-note, .uix-notice__copy,
|
|
2115
|
+
* .uix-timeline__body, .uix-audit__detail, .uix-notif copy. Links there sit inside
|
|
2116
|
+
* sentences: 1.4.1 applies and the base treatment is correct.
|
|
2117
|
+
* • .uix-alert, .uix-toast, .uix-peek__title — nothing else in those containers signals
|
|
2118
|
+
* that the link navigates, so the colour IS the affordance. peek.css sets --uix-link
|
|
2119
|
+
* on its title anchor on purpose; do not quiet it.
|
|
2120
|
+
* • .uix-comment__author — a byline renders "Author · 22m ago", so the name is a phrase
|
|
2121
|
+
* inside a text run, not the whole block, and .uix-comment__meta is not interactive.
|
|
2122
|
+
* It fails test (i) above. Products wanting the GitHub-style quiet byline opt in with
|
|
2123
|
+
* .uix-link--quiet; that is what the utility is for.
|
|
2124
|
+
* • .uix-navitem, .uix-breadcrumbs a, .uix-section-link are already quiet by their own
|
|
2125
|
+
* design and need no class here.
|
|
2187
2126
|
*
|
|
2188
|
-
*
|
|
2189
|
-
*
|
|
2190
|
-
*
|
|
2191
|
-
*
|
|
2192
|
-
*
|
|
2193
|
-
*
|
|
2194
|
-
*
|
|
2127
|
+
* Four forms:
|
|
2128
|
+
* 1 · `.uix-link--quiet` — the opt-in utility, for block links outside the registry.
|
|
2129
|
+
* 2 · TITLE / NAME SLOTS — quiet by default. `:not(.uix-btn)` so an anchor deliberately
|
|
2130
|
+
* styled as a button inside a title slot keeps its button treatment.
|
|
2131
|
+
* 3 · DATA CELLS — table cells and description-list values. `:not([class])` so
|
|
2132
|
+
* class-bearing anchors (`.uix-btn--link`, pills, tags) stay styled.
|
|
2133
|
+
* 4 · CONTAINER ANCHORS — the anchor IS the kit block (`<a class="uix-card">`). Without
|
|
2134
|
+
* this the base `a { color }` tints every word in the block brand-blue.
|
|
2195
2135
|
* Depends only on --uix-* tokens. */
|
|
2196
2136
|
@layer uix.components {
|
|
2197
2137
|
.uix-link--quiet,
|
|
2198
|
-
.uix-content-list__title a,
|
|
2199
|
-
.uix-news-lead__title a,
|
|
2200
|
-
.uix-rundown__item-title a,
|
|
2201
|
-
.uix-event-row__title a,
|
|
2202
|
-
.uix-table td a:not([class]) { color: inherit; text-decoration: none; }
|
|
2203
|
-
|
|
2204
|
-
.uix-link--quiet:hover,
|
|
2205
|
-
.uix-link--quiet:focus-visible,
|
|
2206
|
-
.uix-content-list__title a:hover,
|
|
2207
|
-
.uix-content-list__title a:focus-visible,
|
|
2208
|
-
.uix-news-lead__title a:hover,
|
|
2209
|
-
.uix-news-lead__title a:focus-visible,
|
|
2210
|
-
.uix-rundown__item-title a:hover,
|
|
2211
|
-
.uix-rundown__item-title a:focus-visible,
|
|
2212
|
-
.uix-event-row__title a:hover,
|
|
2213
|
-
.uix-event-row__title a:focus-visible,
|
|
2214
|
-
.uix-table td a:not([class]):hover,
|
|
2215
|
-
.uix-table td a:not([class]):focus-visible { text-decoration: underline; }
|
|
2216
|
-
}
|
|
2217
|
-
/* forced-colors (WHCM) repairs — last layer so its system-color fixes win over component rules (UIX-A11Y-4) */
|
|
2218
|
-
/* uix forced-colors — Windows High Contrast / forced-colors repairs (UIX-A11Y-4).
|
|
2219
|
-
Forced-colors mode strips author backgrounds and box-shadows, so controls whose state or
|
|
2220
|
-
focus cue rides on those go invisible. Repairs below redraw ONLY those affordances with
|
|
2221
|
-
CSS system colors; everything else stays honest to the user's forced palette. Loaded as
|
|
2222
|
-
the last layer (see main.css) so these rules win over component declarations. */
|
|
2223
|
-
@layer uix.forced-colors {
|
|
2224
|
-
@media (forced-colors: active) {
|
|
2225
|
-
/* switch — track + thumb are background-only; redraw with system colors */
|
|
2226
|
-
.uix-switch__track { border: 1px solid ButtonText; background: Canvas; forced-color-adjust: none; }
|
|
2227
|
-
.uix-switch__track::after { background: ButtonText; box-shadow: none; }
|
|
2228
|
-
.uix-switch > input:checked + .uix-switch__track { background: SelectedItem; border-color: SelectedItem; }
|
|
2229
|
-
.uix-switch > input:checked + .uix-switch__track::after { background: SelectedItemText; }
|
|
2230
|
-
|
|
2231
|
-
/* radio — the checked ::after dot is a token background, forced away otherwise */
|
|
2232
|
-
.uix-radio > input:checked + .uix-radio__dot::after { background: SelectedItem; forced-color-adjust: none; }
|
|
2233
|
-
|
|
2234
|
-
/* checkbox — checked/indeterminate box fill + check glyph */
|
|
2235
|
-
.uix-checkbox > input:checked + .uix-checkbox__box,
|
|
2236
|
-
.uix-checkbox > input:indeterminate + .uix-checkbox__box {
|
|
2237
|
-
background: SelectedItem; border-color: SelectedItem; forced-color-adjust: none;
|
|
2238
|
-
}
|
|
2239
|
-
.uix-checkbox > input:checked + .uix-checkbox__box svg { color: SelectedItemText; }
|
|
2240
|
-
|
|
2241
|
-
/* progress + meter — track and fill are both plain backgrounds */
|
|
2242
|
-
.uix-progress, .uix-meter { border: 1px solid ButtonText; }
|
|
2243
|
-
.uix-progress__bar, .uix-meter__fill { background: SelectedItem; forced-color-adjust: none; }
|
|
2244
2138
|
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2139
|
+
/* 2 · title / name slots */
|
|
2140
|
+
:is(
|
|
2141
|
+
/* editorial-home */
|
|
2142
|
+
.uix-featured__title, .uix-rail-card__title, .uix-news-lead__title,
|
|
2143
|
+
.uix-content-list__title, .uix-rundown__item-title, .uix-event-row__title,
|
|
2144
|
+
.uix-status-row__name,
|
|
2145
|
+
/* records, rows, cards */
|
|
2146
|
+
.uix-card__title, .uix-list__title, .uix-inbox__subject, .uix-kanban__card-title,
|
|
2147
|
+
.uix-media__name, .uix-attachment__name, .uix-contact__name, .uix-user-chip__name,
|
|
2148
|
+
.uix-audit__actor
|
|
2149
|
+
) a:not(.uix-btn),
|
|
2150
|
+
|
|
2151
|
+
/* 3 · data cells */
|
|
2152
|
+
:is(.uix-table td, .uix-dl dd) a:not([class]),
|
|
2153
|
+
|
|
2154
|
+
/* 4 · container anchors */
|
|
2155
|
+
a:is(
|
|
2156
|
+
.uix-card, .uix-stat, .uix-list__item, .uix-inbox__item, .uix-kanban__card,
|
|
2157
|
+
.uix-notif, .uix-media, .uix-attachment, .uix-contact, .uix-cmdk__item,
|
|
2158
|
+
.uix-content-list__item, .uix-event-row, .uix-status-row
|
|
2159
|
+
) { color: inherit; text-decoration: none; }
|
|
2160
|
+
|
|
2161
|
+
.uix-link--quiet:is(:hover, :focus-visible),
|
|
2162
|
+
|
|
2163
|
+
:is(
|
|
2164
|
+
.uix-featured__title, .uix-rail-card__title, .uix-news-lead__title,
|
|
2165
|
+
.uix-content-list__title, .uix-rundown__item-title, .uix-event-row__title,
|
|
2166
|
+
.uix-status-row__name,
|
|
2167
|
+
.uix-card__title, .uix-list__title, .uix-inbox__subject, .uix-kanban__card-title,
|
|
2168
|
+
.uix-media__name, .uix-attachment__name, .uix-contact__name, .uix-user-chip__name,
|
|
2169
|
+
.uix-audit__actor
|
|
2170
|
+
) a:not(.uix-btn):is(:hover, :focus-visible),
|
|
2171
|
+
|
|
2172
|
+
:is(.uix-table td, .uix-dl dd) a:not([class]):is(:hover, :focus-visible) { text-decoration: underline; }
|
|
2173
|
+
|
|
2174
|
+
/* Container anchors never underline: the anchor wraps the whole block, so an underline
|
|
2175
|
+
would strike through every word in it. They take the kit's standard row-hover tint
|
|
2176
|
+
instead — the same --uix-bg-hover that .uix-list__item / .uix-inbox__item / .uix-cmdk__item
|
|
2177
|
+
already use, so containers with a hover of their own just restate it. */
|
|
2178
|
+
a:is(
|
|
2179
|
+
.uix-card, .uix-stat, .uix-list__item, .uix-inbox__item, .uix-kanban__card,
|
|
2180
|
+
.uix-notif, .uix-media, .uix-attachment, .uix-contact, .uix-cmdk__item,
|
|
2181
|
+
.uix-content-list__item, .uix-event-row, .uix-status-row
|
|
2182
|
+
):is(:hover, :focus-visible) { background: var(--uix-bg-hover); }
|
|
2183
|
+
|
|
2184
|
+
/* Container anchors that declare no display of their own would render inline as an <a>.
|
|
2185
|
+
The rest of form 4 (flex/grid rows) set theirs already and must NOT be overridden —
|
|
2186
|
+
link.css is imported last, so a blanket display here would flatten them. */
|
|
2187
|
+
a:is(.uix-card, .uix-stat, .uix-kanban__card) { display: block; }
|
|
2250
2188
|
}
|
package/build/css/tokens.css
CHANGED
|
@@ -138,19 +138,19 @@
|
|
|
138
138
|
--uix-font-sans: "Inter",system-ui,sans-serif;
|
|
139
139
|
--uix-font-heading: "IBM Plex Sans","Inter",system-ui,sans-serif;
|
|
140
140
|
--uix-font-mono: "IBM Plex Mono",ui-monospace,monospace;
|
|
141
|
-
--uix-text-display:
|
|
141
|
+
--uix-text-display: 40px;
|
|
142
142
|
--uix-leading-display: 1.05;
|
|
143
|
-
--uix-text-data-hero:
|
|
143
|
+
--uix-text-data-hero: 34px;
|
|
144
144
|
--uix-leading-data-hero: 1.1;
|
|
145
|
-
--uix-text-h2:
|
|
145
|
+
--uix-text-h2: 24px;
|
|
146
146
|
--uix-leading-h2: 1.15;
|
|
147
|
-
--uix-text-h3:
|
|
147
|
+
--uix-text-h3: 15px;
|
|
148
148
|
--uix-leading-h3: 1.3;
|
|
149
|
-
--uix-text-body:
|
|
149
|
+
--uix-text-body: 14px;
|
|
150
150
|
--uix-leading-body: 1.5;
|
|
151
|
-
--uix-text-meta:
|
|
151
|
+
--uix-text-meta: 12.5px;
|
|
152
152
|
--uix-leading-meta: 1.4;
|
|
153
|
-
--uix-text-eyebrow:
|
|
153
|
+
--uix-text-eyebrow: 11px;
|
|
154
154
|
--uix-leading-eyebrow: 1.2;
|
|
155
155
|
--uix-tracking-tight: -0.02em;
|
|
156
156
|
--uix-tracking-eyebrow: 0.06em;
|
package/build/ts/tokens.js
CHANGED
|
@@ -293,19 +293,19 @@ export const light = {
|
|
|
293
293
|
"font-sans": "\"Inter\",system-ui,sans-serif",
|
|
294
294
|
"font-heading": "\"IBM Plex Sans\",\"Inter\",system-ui,sans-serif",
|
|
295
295
|
"font-mono": "\"IBM Plex Mono\",ui-monospace,monospace",
|
|
296
|
-
"text-display": "
|
|
296
|
+
"text-display": "40px",
|
|
297
297
|
"leading-display": "1.05",
|
|
298
|
-
"text-data-hero": "
|
|
298
|
+
"text-data-hero": "34px",
|
|
299
299
|
"leading-data-hero": "1.1",
|
|
300
|
-
"text-h2": "
|
|
300
|
+
"text-h2": "24px",
|
|
301
301
|
"leading-h2": "1.15",
|
|
302
|
-
"text-h3": "
|
|
302
|
+
"text-h3": "15px",
|
|
303
303
|
"leading-h3": "1.3",
|
|
304
|
-
"text-body": "
|
|
304
|
+
"text-body": "14px",
|
|
305
305
|
"leading-body": "1.5",
|
|
306
|
-
"text-meta": "
|
|
306
|
+
"text-meta": "12.5px",
|
|
307
307
|
"leading-meta": "1.4",
|
|
308
|
-
"text-eyebrow": "
|
|
308
|
+
"text-eyebrow": "11px",
|
|
309
309
|
"leading-eyebrow": "1.2",
|
|
310
310
|
"tracking-tight": "-0.02em",
|
|
311
311
|
"tracking-eyebrow": "0.06em",
|
|
@@ -414,4 +414,11 @@ export const num = {
|
|
|
414
414
|
"space-10": 64,
|
|
415
415
|
"space-11": 80,
|
|
416
416
|
"space-12": 96,
|
|
417
|
+
"text-display": 40,
|
|
418
|
+
"text-data-hero": 34,
|
|
419
|
+
"text-h2": 24,
|
|
420
|
+
"text-h3": 15,
|
|
421
|
+
"text-body": 14,
|
|
422
|
+
"text-meta": 12.5,
|
|
423
|
+
"text-eyebrow": 11,
|
|
417
424
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tensor_1/tokens",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.11.0",
|
|
4
4
|
"description": "UIx v2 design tokens — the --uix-* contract for house products (Tensor, POSx, SHOPx). One DTCG source -> CSS variables, Tailwind theme, and typed TS constants.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -3,19 +3,19 @@
|
|
|
3
3
|
"font-heading": { "$type": "fontFamily", "$value": "\"IBM Plex Sans\",\"Inter\",system-ui,sans-serif" },
|
|
4
4
|
"font-mono": { "$type": "fontFamily", "$value": "\"IBM Plex Mono\",ui-monospace,monospace" },
|
|
5
5
|
|
|
6
|
-
"text-display": { "$type": "dimension", "$value": "
|
|
6
|
+
"text-display": { "$type": "dimension", "$value": "40px" },
|
|
7
7
|
"leading-display":{ "$type": "number", "$value": "1.05" },
|
|
8
|
-
"text-data-hero": { "$type": "dimension", "$value": "
|
|
8
|
+
"text-data-hero": { "$type": "dimension", "$value": "34px" },
|
|
9
9
|
"leading-data-hero": { "$type": "number", "$value": "1.1" },
|
|
10
|
-
"text-h2": { "$type": "dimension", "$value": "
|
|
10
|
+
"text-h2": { "$type": "dimension", "$value": "24px" },
|
|
11
11
|
"leading-h2":{ "$type": "number", "$value": "1.15" },
|
|
12
|
-
"text-h3": { "$type": "dimension", "$value": "
|
|
12
|
+
"text-h3": { "$type": "dimension", "$value": "15px" },
|
|
13
13
|
"leading-h3":{ "$type": "number", "$value": "1.3" },
|
|
14
|
-
"text-body": { "$type": "dimension", "$value": "
|
|
14
|
+
"text-body": { "$type": "dimension", "$value": "14px" },
|
|
15
15
|
"leading-body":{ "$type": "number", "$value": "1.5" },
|
|
16
|
-
"text-meta": { "$type": "dimension", "$value": "
|
|
16
|
+
"text-meta": { "$type": "dimension", "$value": "12.5px" },
|
|
17
17
|
"leading-meta":{ "$type": "number", "$value": "1.4" },
|
|
18
|
-
"text-eyebrow": { "$type": "dimension", "$value": "
|
|
18
|
+
"text-eyebrow": { "$type": "dimension", "$value": "11px" },
|
|
19
19
|
"leading-eyebrow":{ "$type": "number", "$value": "1.2" },
|
|
20
20
|
|
|
21
21
|
"tracking-tight": { "$type": "dimension", "$value": "-0.02em" },
|