@tensor_1/tokens 2.10.0 → 2.12.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.
Files changed (78) hide show
  1. package/README.md +2 -0
  2. package/build/css/components.css +1 -1872
  3. package/build/css/styles.css +1 -2250
  4. package/build/css/tokens.css +7 -7
  5. package/build/ts/tokens.js +14 -7
  6. package/package.json +12 -2
  7. package/styles/components/alert.css +16 -0
  8. package/styles/components/app-shell.css +37 -0
  9. package/styles/components/attachment.css +10 -0
  10. package/styles/components/audit-log.css +11 -0
  11. package/styles/components/avatar.css +25 -0
  12. package/styles/components/breadcrumbs.css +10 -0
  13. package/styles/components/button.css +49 -0
  14. package/styles/components/calendar.css +13 -0
  15. package/styles/components/card.css +9 -0
  16. package/styles/components/chart.css +9 -0
  17. package/styles/components/checkbox.css +20 -0
  18. package/styles/components/combobox.css +16 -0
  19. package/styles/components/command-palette.css +14 -0
  20. package/styles/components/comments.css +17 -0
  21. package/styles/components/contact-card.css +12 -0
  22. package/styles/components/description-list.css +6 -0
  23. package/styles/components/detail-layout.css +7 -0
  24. package/styles/components/drawer.css +24 -0
  25. package/styles/components/editorial-home.css +185 -0
  26. package/styles/components/file-upload.css +14 -0
  27. package/styles/components/flow.css +196 -0
  28. package/styles/components/form.css +14 -0
  29. package/styles/components/heartbeat.css +12 -0
  30. package/styles/components/inbox.css +13 -0
  31. package/styles/components/input.css +39 -0
  32. package/styles/components/kanban.css +14 -0
  33. package/styles/components/kbd.css +8 -0
  34. package/styles/components/labels.css +13 -0
  35. package/styles/components/lightbox.css +13 -0
  36. package/styles/components/link.css +98 -0
  37. package/styles/components/list.css +10 -0
  38. package/styles/components/media.css +9 -0
  39. package/styles/components/menu.css +15 -0
  40. package/styles/components/meter.css +9 -0
  41. package/styles/components/modal.css +31 -0
  42. package/styles/components/notification-center.css +14 -0
  43. package/styles/components/page-header.css +9 -0
  44. package/styles/components/pagination.css +14 -0
  45. package/styles/components/peek.css +46 -0
  46. package/styles/components/pipeline.css +9 -0
  47. package/styles/components/popover.css +11 -0
  48. package/styles/components/progress.css +12 -0
  49. package/styles/components/prose.css +27 -0
  50. package/styles/components/radio.css +20 -0
  51. package/styles/components/reactions.css +22 -0
  52. package/styles/components/segmented.css +12 -0
  53. package/styles/components/select.css +23 -0
  54. package/styles/components/sidebar.css +102 -0
  55. package/styles/components/sla.css +8 -0
  56. package/styles/components/slider.css +16 -0
  57. package/styles/components/spinner.css +10 -0
  58. package/styles/components/stat-tile.css +11 -0
  59. package/styles/components/states.css +13 -0
  60. package/styles/components/status-pill.css +37 -0
  61. package/styles/components/stepper.css +13 -0
  62. package/styles/components/steps.css +18 -0
  63. package/styles/components/switch.css +19 -0
  64. package/styles/components/table-toolbar.css +20 -0
  65. package/styles/components/table.css +160 -0
  66. package/styles/components/tabs.css +31 -0
  67. package/styles/components/tag-input.css +16 -0
  68. package/styles/components/textarea.css +15 -0
  69. package/styles/components/timeline.css +11 -0
  70. package/styles/components/toast.css +21 -0
  71. package/styles/components/tooltip.css +35 -0
  72. package/styles/components/tree.css +17 -0
  73. package/styles/components/typography.css +45 -0
  74. package/styles/components/utility-bits.css +14 -0
  75. package/styles/components/view-menu.css +14 -0
  76. package/styles/motion.css +35 -0
  77. package/styles/utilities.css +26 -0
  78. package/tokens/base/typography.json +7 -7
@@ -0,0 +1,10 @@
1
+ /* uix list + list-item — depends only on --uix-* tokens. */
2
+ @layer uix.components {
3
+ .uix-list { display: flex; flex-direction: column; border: 1px solid var(--uix-border); border-radius: var(--uix-radius-lg); overflow: hidden; background: var(--uix-surface); }
4
+ .uix-list__item { 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); }
5
+ .uix-list__item:last-child { border-bottom: 0; }
6
+ .uix-list__item:hover { background: var(--uix-bg-hover); }
7
+ .uix-list__title { font-weight: 500; }
8
+ .uix-list__meta { font-size: var(--uix-text-meta); color: var(--uix-text-muted); }
9
+ .uix-list__trail { margin-left: auto; display: flex; align-items: center; gap: var(--uix-space-2); }
10
+ }
@@ -0,0 +1,9 @@
1
+ /* uix media / device-asset card — image (or icon placeholder) + name + meta. Depends only on --uix-* tokens. */
2
+ @layer uix.components {
3
+ .uix-media { display: flex; gap: var(--uix-space-3); align-items: center; }
4
+ .uix-media__thumb { width: 64px; height: 64px; flex: none; border-radius: var(--uix-radius-md); overflow: hidden; background: var(--uix-bg-subtle); border: 1px solid var(--uix-border); display: grid; place-items: center; }
5
+ .uix-media__thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
6
+ .uix-media__thumb svg { width: 28px; height: 28px; color: var(--uix-text-muted); }
7
+ .uix-media__name { font-weight: 600; }
8
+ .uix-media__meta { font-size: var(--uix-text-meta); color: var(--uix-text-muted); }
9
+ }
@@ -0,0 +1,15 @@
1
+ /* uix menu / dropdown / context menu — popover-anchored surface. Depends only on --uix-* tokens. */
2
+ @layer uix.components {
3
+ .uix-menu { min-width: 200px; margin: 0; padding: var(--uix-space-1); list-style: none; background: var(--uix-surface-2); border: 1px solid var(--uix-border); border-radius: var(--uix-radius-md); box-shadow: var(--uix-shadow-popover); }
4
+ .uix-menu__item {
5
+ display: flex; align-items: center; gap: var(--uix-space-3); width: 100%; text-align: left; padding: var(--uix-space-2) var(--uix-space-3);
6
+ border: 0; background: transparent; border-radius: var(--uix-radius-sm); color: var(--uix-text); font: inherit; font-size: var(--uix-text-body); cursor: pointer;
7
+ }
8
+ .uix-menu__item svg { width: var(--uix-icon-md); height: var(--uix-icon-md); color: var(--uix-text-muted); }
9
+ .uix-menu__item:hover, .uix-menu__item[data-active] { background: var(--uix-bg-hover); }
10
+ .uix-menu__item--danger { color: var(--uix-danger-text); }
11
+ .uix-menu__item--danger svg { color: var(--uix-danger-text); }
12
+ .uix-menu__item .uix-kbd { margin-left: auto; }
13
+ .uix-menu__sep { height: 1px; background: var(--uix-border); margin: var(--uix-space-1) 0; }
14
+ .uix-menu__label { 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); }
15
+ }
@@ -0,0 +1,9 @@
1
+ /* uix meter / utilization bar (threshold tones) — depends only on --uix-* tokens. */
2
+ @layer uix.components {
3
+ .uix-meter { height: 8px; background: var(--uix-bg-active); border-radius: var(--uix-radius-pill); overflow: hidden; }
4
+ .uix-meter__fill { height: 100%; border-radius: inherit; background: var(--uix-success); transition: width var(--uix-dur) var(--uix-ease-out); }
5
+ .uix-meter__fill[data-tone="warning"] { background: var(--uix-warning); }
6
+ .uix-meter__fill[data-tone="danger"] { background: var(--uix-danger); }
7
+ .uix-meter__fill[data-tone="attention"] { background: var(--uix-attention); }
8
+ .uix-meter__fill[data-tone="overdue"] { background: var(--uix-overdue); }
9
+ }
@@ -0,0 +1,31 @@
1
+ /* uix modal / dialog — native <dialog>, animated enter/exit via @starting-style + allow-discrete. */
2
+ @layer uix.components {
3
+ .uix-dialog {
4
+ margin: auto; width: 100%; max-width: min(520px, 92vw); padding: 0; color: var(--uix-text);
5
+ border: 1px solid var(--uix-border); border-radius: var(--uix-radius-lg);
6
+ background: var(--uix-surface-2); box-shadow: var(--uix-shadow-overlay);
7
+ opacity: 0; transform: translateY(8px) scale(.98);
8
+ transition: opacity var(--uix-dur-slow) var(--uix-ease-out), transform var(--uix-dur-slow) var(--uix-ease-out),
9
+ overlay var(--uix-dur-slow) allow-discrete, display var(--uix-dur-slow) allow-discrete;
10
+ /* Author display values for both states required for the fade-in to animate: the allow-discrete
11
+ `display` transition only engages with author values, which also lets @starting-style fire.
12
+ With only the UA dialog display, the modal stays at opacity:0. Closed = none; open = block. */
13
+ display: none;
14
+ }
15
+ .uix-dialog[open] { opacity: 1; transform: none; display: block; }
16
+ @starting-style { .uix-dialog[open] { opacity: 0; transform: translateY(8px) scale(.98); } }
17
+ .uix-dialog::backdrop {
18
+ background: var(--uix-scrim); opacity: 0;
19
+ transition: opacity var(--uix-dur-slow) var(--uix-ease-out), overlay var(--uix-dur-slow) allow-discrete, display var(--uix-dur-slow) allow-discrete;
20
+ }
21
+ .uix-dialog[open]::backdrop { opacity: 1; }
22
+ @starting-style { .uix-dialog[open]::backdrop { opacity: 0; } }
23
+
24
+ .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); }
25
+ .uix-dialog__title { font-size: var(--uix-text-h3); font-weight: 600; }
26
+ .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); }
27
+ .uix-dialog__close:hover { background: var(--uix-bg-hover); color: var(--uix-text); }
28
+ .uix-dialog__close svg { width: var(--uix-icon-md); height: var(--uix-icon-md); }
29
+ .uix-dialog__body { padding: var(--uix-space-5); color: var(--uix-text-hushed); }
30
+ .uix-dialog__footer { display: flex; gap: var(--uix-space-2); justify-content: flex-end; padding: var(--uix-space-4) var(--uix-space-5); border-top: 1px solid var(--uix-border); }
31
+ }
@@ -0,0 +1,14 @@
1
+ /* uix notification center — depends only on --uix-* tokens. */
2
+ @layer uix.components {
3
+ .uix-notifs { background: var(--uix-surface-2); border: 1px solid var(--uix-border); border-radius: var(--uix-radius-lg); overflow: hidden; }
4
+ .uix-notifs__head { display: flex; align-items: center; padding: var(--uix-space-3) var(--uix-space-4); border-bottom: 1px solid var(--uix-border); font-weight: 600; }
5
+ .uix-notif { display: grid; grid-template-columns: auto 1fr; gap: var(--uix-space-3); padding: var(--uix-space-3) var(--uix-space-4); border-bottom: 1px solid var(--uix-border); }
6
+ .uix-notif:last-child { border-bottom: 0; }
7
+ .uix-notif[data-unread] { background: var(--uix-brand-muted); }
8
+ .uix-notif__dot { width: 8px; height: 8px; border-radius: 50%; background: var(--uix-accent); margin-top: var(--uix-space-2); }
9
+ .uix-notif[data-unread] .uix-notif__dot { background: var(--uix-accent); }
10
+ .uix-notif:not([data-unread]) .uix-notif__dot { background: transparent; }
11
+ .uix-notif__meta { font-size: var(--uix-text-meta); color: var(--uix-text-muted); }
12
+ /* on the unread brand-muted tint, muted meta dips below AA — hushed composites darker on the tint */
13
+ .uix-notif[data-unread] .uix-notif__meta { color: var(--uix-text-hushed); }
14
+ }
@@ -0,0 +1,9 @@
1
+ /* uix page header — title/subtitle/actions row. Depends only on --uix-* tokens. */
2
+ @layer uix.components {
3
+ .uix-page-header { display: flex; align-items: flex-start; gap: var(--uix-space-5); flex-wrap: wrap; padding-bottom: var(--uix-space-6); margin-bottom: var(--uix-space-7); border-bottom: 1px solid var(--uix-border); }
4
+ .uix-page-header__titles { flex: 1; min-width: 220px; }
5
+ .uix-page-header__eyebrow { font-size: var(--uix-text-eyebrow); letter-spacing: var(--uix-tracking-eyebrow); text-transform: uppercase; font-weight: 600; color: var(--uix-text-muted); margin-bottom: var(--uix-space-2); }
6
+ .uix-page-header__title { font-size: var(--uix-text-h2); font-weight: 600; letter-spacing: var(--uix-tracking-tight); }
7
+ .uix-page-header__subtitle { color: var(--uix-text-muted); font-size: var(--uix-text-meta); margin-top: var(--uix-space-2); max-width: 70ch; }
8
+ .uix-page-header__actions { display: flex; gap: var(--uix-space-2); align-items: center; flex-wrap: wrap; }
9
+ }
@@ -0,0 +1,14 @@
1
+ /* uix pagination — depends only on --uix-* tokens. */
2
+ @layer uix.components {
3
+ .uix-pagination { display: inline-flex; align-items: center; gap: var(--uix-space-1); }
4
+ .uix-pagination__btn {
5
+ min-width: 32px; height: 32px; padding: 0 var(--uix-space-2); display: inline-flex; align-items: center; justify-content: center;
6
+ border: 1px solid var(--uix-border); border-radius: var(--uix-radius-sm); background: var(--uix-surface);
7
+ color: var(--uix-text); font: inherit; font-size: var(--uix-text-meta); line-height: 1; cursor: pointer;
8
+ transition: background-color var(--uix-dur-fast) var(--uix-ease-out), border-color var(--uix-dur-fast) var(--uix-ease-out);
9
+ }
10
+ .uix-pagination__btn:hover { background: var(--uix-bg-hover); }
11
+ .uix-pagination__btn[aria-current="page"] { background: var(--uix-accent); border-color: var(--uix-accent); color: var(--uix-accent-fg); }
12
+ .uix-pagination__btn:disabled { opacity: .45; pointer-events: none; }
13
+ .uix-pagination__ellipsis { padding: 0 var(--uix-space-1); color: var(--uix-text-muted); }
14
+ }
@@ -0,0 +1,46 @@
1
+ /* uix side-peek drawer (the §5.8 peek pattern, reused by table rows + sidebar items).
2
+ Native <dialog>, slides from the right; keyboard ↑/↓ navigates records (app.js). */
3
+ @layer uix.components {
4
+ .uix-peek {
5
+ margin: 0 0 0 auto; height: 100dvh; max-height: 100dvh; width: var(--uix-peek-w); padding: 0; color: var(--uix-text);
6
+ border: 0; border-left: 1px solid var(--uix-border); border-radius: 0;
7
+ background: var(--uix-surface); box-shadow: var(--uix-shadow-overlay);
8
+ transform: translateX(100%);
9
+ transition: transform var(--uix-dur-slow) var(--uix-ease-out),
10
+ overlay var(--uix-dur-slow) allow-discrete, display var(--uix-dur-slow) allow-discrete;
11
+ /* Author display values for BOTH states are required for the slide-in to animate: the
12
+ allow-discrete `display` transition only engages with author values, and that gating also
13
+ lets the @starting-style entrance fire. With only the UA dialog display, the panel stays
14
+ parked at translateX(100%). Closed = none; open = flex. */
15
+ display: none;
16
+ }
17
+ .uix-peek[open] { transform: none; display: flex; flex-direction: column; }
18
+ @starting-style { .uix-peek[open] { transform: translateX(100%); } }
19
+ .uix-peek::backdrop {
20
+ background: var(--uix-scrim); opacity: 0;
21
+ transition: opacity var(--uix-dur-slow) var(--uix-ease-out), overlay var(--uix-dur-slow) allow-discrete, display var(--uix-dur-slow) allow-discrete;
22
+ }
23
+ .uix-peek[open]::backdrop { opacity: 1; }
24
+ @starting-style { .uix-peek[open]::backdrop { opacity: 0; } }
25
+
26
+ .uix-peek__header { display: flex; align-items: center; gap: var(--uix-space-3); padding: var(--uix-space-4) var(--uix-space-4); border-bottom: 1px solid var(--uix-border); }
27
+ .uix-peek__nav { display: inline-flex; gap: var(--uix-space-1); }
28
+ .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; }
29
+ .uix-peek__navbtn:hover { background: var(--uix-bg-hover); }
30
+ .uix-peek__title { font-size: var(--uix-text-h3); font-weight: 600; }
31
+ .uix-peek__title a { color: var(--uix-link); }
32
+ .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); }
33
+ .uix-peek__close:hover { background: var(--uix-bg-hover); color: var(--uix-text); }
34
+ .uix-peek__body { padding: var(--uix-space-5); overflow-y: auto; flex: 1; }
35
+ .uix-peek__hint { font-size: var(--uix-text-meta); color: var(--uix-text-muted); }
36
+ .uix-peek__footer { display: flex; gap: var(--uix-space-2); padding: var(--uix-space-4) var(--uix-space-4); border-top: 1px solid var(--uix-border); }
37
+
38
+ /* a table wired to open the peek (app.js sets data-uix-rowpeek): its rows read as clickable,
39
+ since clicking a ticket row is the queue's primary way to open the side-peek. */
40
+ [data-uix-rowpeek] tbody tr { cursor: pointer; }
41
+ [data-uix-rowpeek] tbody tr:hover td { background: var(--uix-bg-hover); }
42
+
43
+ /* Column sizing + the id-cell click-through pattern now live in table.css (one story for
44
+ "table cells"). Size columns with .uix-col--w-* / .uix-col--flex + .uix-col--truncate
45
+ instead of the old [data-uix-table-v2] :nth-child(2) title cap. */
46
+ }
@@ -0,0 +1,9 @@
1
+ /* uix deal / pipeline stage bar — depends only on --uix-* tokens. */
2
+ @layer uix.components {
3
+ .uix-pipeline { display: flex; gap: var(--uix-space-1); }
4
+ .uix-pipeline__stage { flex: 1; text-align: center; padding: var(--uix-space-2) var(--uix-space-2); font-size: var(--uix-text-meta); color: var(--uix-text-muted); background: var(--uix-bg-subtle); }
5
+ .uix-pipeline__stage:first-child { border-radius: var(--uix-radius-pill) 0 0 var(--uix-radius-pill); }
6
+ .uix-pipeline__stage:last-child { border-radius: 0 var(--uix-radius-pill) var(--uix-radius-pill) 0; }
7
+ .uix-pipeline__stage[data-state="done"] { background: var(--uix-accent); color: var(--uix-accent-fg); }
8
+ .uix-pipeline__stage[data-state="active"] { background: var(--uix-brand-muted); color: var(--uix-link); font-weight: 600; }
9
+ }
@@ -0,0 +1,11 @@
1
+ /* uix popover — generic anchored surface via the native Popover API; animated with @starting-style. */
2
+ @layer uix.components {
3
+ .uix-popover { margin: 0; padding: var(--uix-space-2); background: var(--uix-surface-2); border: 1px solid var(--uix-border); border-radius: var(--uix-radius-md); box-shadow: var(--uix-shadow-popover); color: var(--uix-text); }
4
+ [popover].uix-popover {
5
+ opacity: 0; transform: translateY(calc(-1 * var(--uix-lift)));
6
+ transition: opacity var(--uix-dur-fast) var(--uix-ease-out), transform var(--uix-dur-fast) var(--uix-ease-out),
7
+ overlay var(--uix-dur-fast) allow-discrete, display var(--uix-dur-fast) allow-discrete;
8
+ }
9
+ [popover].uix-popover:popover-open { opacity: 1; transform: none; }
10
+ @starting-style { [popover].uix-popover:popover-open { opacity: 0; transform: translateY(calc(-1 * var(--uix-lift))); } }
11
+ }
@@ -0,0 +1,12 @@
1
+ /* uix progress bar + ring — depends only on --uix-* tokens. */
2
+ @layer uix.components {
3
+ .uix-progress { height: 8px; background: var(--uix-bg-active); border-radius: var(--uix-radius-pill); overflow: hidden; }
4
+ .uix-progress__bar { height: 100%; background: var(--uix-accent); border-radius: inherit; transition: width var(--uix-dur) var(--uix-ease-out); }
5
+ .uix-progress--indeterminate { position: relative; }
6
+ .uix-progress--indeterminate .uix-progress__bar { width: 40%; animation: uix-progress-slide 1.2s var(--uix-ease-in-out) infinite; }
7
+ @keyframes uix-progress-slide { 0% { transform: translateX(-110%); } 100% { transform: translateX(280%); } }
8
+
9
+ .uix-ring { width: 44px; height: 44px; border-radius: 50%; display: grid; place-items: center;
10
+ background: conic-gradient(var(--uix-accent) calc(var(--val, .66) * 360deg), var(--uix-bg-active) 0); }
11
+ .uix-ring__inner { width: 32px; height: 32px; border-radius: 50%; background: var(--uix-surface); display: grid; place-items: center; font-size: var(--uix-text-meta); font-weight: 600; }
12
+ }
@@ -0,0 +1,27 @@
1
+ /* uix prose content card + note callouts — for KB articles, descriptions, release notes. Depends only on --uix-* tokens. */
2
+ @layer uix.components {
3
+ .uix-prose { max-width: 66ch; color: var(--uix-text); }
4
+ .uix-prose > * + * { margin-top: var(--uix-space-3); }
5
+ .uix-prose h3 { font-size: var(--uix-text-h2); font-weight: 600; }
6
+ .uix-prose h4 { font-size: var(--uix-text-h3); font-weight: 600; margin-top: var(--uix-space-5); }
7
+ .uix-prose p { line-height: var(--uix-leading-body); color: var(--uix-text-hushed); }
8
+ .uix-prose a { color: var(--uix-link); }
9
+ .uix-prose ul, .uix-prose ol { padding-left: var(--uix-space-5); }
10
+ .uix-prose li + li { margin-top: var(--uix-space-1); }
11
+ .uix-prose code { font-family: var(--uix-font-mono); font-size: .9em; background: var(--uix-bg-subtle); padding: 1px var(--uix-space-2); border-radius: var(--uix-radius-xs); }
12
+ .uix-prose blockquote { border-left: 3px solid var(--uix-border-strong); padding-left: var(--uix-space-3); color: var(--uix-text-muted); }
13
+
14
+ .uix-note { display: flex; gap: var(--uix-space-3); padding: var(--uix-space-3) var(--uix-space-4); border-radius: var(--uix-radius-md); border: 1px solid var(--uix-border); background: var(--uix-surface); }
15
+ .uix-note__icon { flex: none; }
16
+ .uix-note__icon svg { width: var(--uix-icon-md); height: var(--uix-icon-md); }
17
+ .uix-note__body { font-size: var(--uix-text-body); color: var(--uix-text); }
18
+ .uix-note__body > * + * { margin-top: var(--uix-space-2); }
19
+ .uix-note--info { background: var(--uix-info-bg); border-color: color-mix(in srgb, var(--uix-info) 30%, transparent); }
20
+ .uix-note--info .uix-note__icon { color: var(--uix-info); }
21
+ .uix-note--success { background: var(--uix-success-bg); border-color: color-mix(in srgb, var(--uix-success) 30%, transparent); }
22
+ .uix-note--success .uix-note__icon { color: var(--uix-success); }
23
+ .uix-note--warning { background: var(--uix-warning-bg); border-color: color-mix(in srgb, var(--uix-warning) 30%, transparent); }
24
+ .uix-note--warning .uix-note__icon { color: var(--uix-warning); }
25
+ .uix-note--danger { background: var(--uix-danger-bg); border-color: color-mix(in srgb, var(--uix-danger) 30%, transparent); }
26
+ .uix-note--danger .uix-note__icon { color: var(--uix-danger); }
27
+ }
@@ -0,0 +1,20 @@
1
+ /* uix radio + radio-group — depends only on --uix-* tokens. */
2
+ @layer uix.components {
3
+ .uix-radio-group { display: flex; flex-direction: column; gap: var(--uix-space-2); }
4
+ .uix-radio { display: inline-flex; align-items: center; gap: var(--uix-space-2); cursor: pointer; font-size: var(--uix-text-body); color: var(--uix-text); }
5
+ .uix-radio > input { position: absolute; opacity: 0; width: 1px; height: 1px; }
6
+ .uix-radio__dot {
7
+ width: 18px; height: 18px; flex: none; border-radius: 50%;
8
+ border: 1px solid var(--uix-border-strong); background: var(--uix-surface);
9
+ display: grid; place-items: center;
10
+ transition: border-color var(--uix-dur-fast) var(--uix-ease-out);
11
+ }
12
+ .uix-radio__dot::after {
13
+ content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--uix-accent);
14
+ opacity: 0; transform: scale(.4); transition: opacity var(--uix-dur-fast) var(--uix-ease-out), transform var(--uix-dur-fast) var(--uix-ease-spring);
15
+ }
16
+ .uix-radio > input:checked + .uix-radio__dot { border-color: var(--uix-accent); }
17
+ .uix-radio > input:checked + .uix-radio__dot::after { opacity: 1; transform: none; }
18
+ .uix-radio > input:focus-visible + .uix-radio__dot { outline: 2px solid var(--uix-ring); outline-offset: 2px; }
19
+ .uix-radio > input:disabled ~ * { opacity: .5; }
20
+ }
@@ -0,0 +1,22 @@
1
+ /* uix emoji reactions — pills with counts + an add-reaction picker popover. Depends only on --uix-* tokens. */
2
+ @layer uix.components {
3
+ .uix-reactions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--uix-space-2); margin-top: var(--uix-space-2); }
4
+ .uix-reaction {
5
+ display: inline-flex; align-items: center; gap: var(--uix-space-2); padding: 1px var(--uix-space-2); line-height: 1.7;
6
+ border-radius: var(--uix-radius-pill); border: 1px solid var(--uix-border); background: var(--uix-surface);
7
+ color: var(--uix-text-hushed); font: inherit; font-size: var(--uix-text-meta); cursor: pointer;
8
+ }
9
+ .uix-reaction:hover { border-color: var(--uix-border-strong); }
10
+ .uix-reaction[data-mine] { background: var(--uix-brand-muted); border-color: var(--uix-accent); color: var(--uix-accent); }
11
+ .uix-reaction__count { font-variant-numeric: tabular-nums; }
12
+ .uix-reaction-add {
13
+ display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 24px;
14
+ border-radius: var(--uix-radius-pill); border: 1px dashed var(--uix-border-strong); background: transparent;
15
+ color: var(--uix-text-muted); cursor: pointer;
16
+ }
17
+ .uix-reaction-add:hover { color: var(--uix-text); border-color: var(--uix-text-muted); }
18
+ .uix-reaction-add svg { width: var(--uix-icon-sm); height: var(--uix-icon-sm); }
19
+ .uix-emoji-picker { display: flex; flex-wrap: wrap; gap: var(--uix-space-1); width: 196px; }
20
+ .uix-emoji-picker__btn { font-size: 18px; line-height: 1; padding: var(--uix-space-2); border: 0; background: transparent; border-radius: var(--uix-radius-sm); cursor: pointer; }
21
+ .uix-emoji-picker__btn:hover { background: var(--uix-bg-hover); }
22
+ }
@@ -0,0 +1,12 @@
1
+ /* uix segmented control — depends only on --uix-* tokens. */
2
+ @layer uix.components {
3
+ .uix-segmented { display: inline-flex; padding: var(--uix-space-1); gap: var(--uix-space-1); background: var(--uix-bg-subtle); border: 1px solid var(--uix-border); border-radius: var(--uix-radius-md); }
4
+ .uix-segmented__option {
5
+ border: 0; background: transparent; color: var(--uix-text-hushed); font: inherit; font-size: var(--uix-text-meta); font-weight: 500;
6
+ padding: var(--uix-space-2) var(--uix-space-3); border-radius: calc(var(--uix-radius-md) - 3px); cursor: pointer;
7
+ transition: background-color var(--uix-dur-fast) var(--uix-ease-out), color var(--uix-dur-fast) var(--uix-ease-out);
8
+ }
9
+ .uix-segmented__option:hover { color: var(--uix-text); }
10
+ .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); }
11
+ .uix-segmented__option:focus-visible { outline: 2px solid var(--uix-ring); outline-offset: 1px; }
12
+ }
@@ -0,0 +1,23 @@
1
+ /* uix select (native, styled) — depends only on --uix-* tokens. */
2
+ @layer uix.components {
3
+ .uix-select {
4
+ height: var(--uix-control-h); width: 100%; padding: 0 var(--uix-space-8) 0 var(--uix-space-3); appearance: none;
5
+ border: 1px solid var(--uix-border); border-radius: var(--uix-radius-md);
6
+ background-color: var(--uix-surface); color: var(--uix-text); font: inherit; font-size: var(--uix-text-body); cursor: pointer;
7
+ background-repeat: no-repeat; background-position: right 12px center;
8
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23737373' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
9
+ transition: border-color var(--uix-dur-fast) var(--uix-ease-out), box-shadow var(--uix-dur-fast) var(--uix-ease-out);
10
+ }
11
+ .uix-select:hover { border-color: var(--uix-border-strong); }
12
+ .uix-select:focus { outline: none; border-color: var(--uix-ring); box-shadow: 0 0 0 3px var(--uix-brand-muted); }
13
+ .uix-select:disabled { opacity: .55; cursor: not-allowed; background-color: var(--uix-bg-subtle); }
14
+ .uix-select--sm { height: 28px; font-size: var(--uix-text-meta); }
15
+
16
+ /* command-palette-style rich select: a trigger that opens a .uix-cmdk popover (search + options) */
17
+ .uix-select-trigger { display: inline-flex; align-items: center; gap: var(--uix-space-2); height: var(--uix-control-h); padding: 0 var(--uix-space-3); min-width: 220px;
18
+ border: 1px solid var(--uix-border); border-radius: var(--uix-radius-md); background: var(--uix-surface); color: var(--uix-text);
19
+ font: inherit; font-size: var(--uix-text-body); cursor: pointer; transition: border-color var(--uix-dur-fast) var(--uix-ease-out); }
20
+ .uix-select-trigger:hover { border-color: var(--uix-border-strong); }
21
+ .uix-select-trigger:focus-visible { outline: 2px solid var(--uix-ring); outline-offset: 2px; }
22
+ .uix-select-trigger__chevron { margin-left: auto; color: var(--uix-text-muted); width: var(--uix-icon-sm); height: var(--uix-icon-sm); }
23
+ }
@@ -0,0 +1,102 @@
1
+ /* uix sidebar nav — items, favorites, collapsible sub-items, collapsed rail. Depends only on --uix-* tokens. */
2
+ @layer uix.components {
3
+ .uix-sidebar { width: var(--uix-sidebar-w); background: var(--uix-bg-subtle); display: flex; flex-direction: column; gap: var(--uix-space-1); padding: var(--uix-space-2); overflow-x: hidden; overflow-y: auto; }
4
+ .uix-sidebar__eyebrow {
5
+ font-size: var(--uix-text-eyebrow); letter-spacing: var(--uix-tracking-eyebrow); text-transform: uppercase;
6
+ color: var(--uix-text-muted); padding: var(--uix-space-3) var(--uix-space-3) var(--uix-space-1);
7
+ }
8
+
9
+ /* brand header */
10
+ .uix-sidebar__head { display: flex; align-items: center; justify-content: space-between; gap: var(--uix-space-2); padding: var(--uix-space-1) var(--uix-space-2) var(--uix-space-2); }
11
+ .uix-sidebar__brand { min-width: 0; font-size: var(--uix-text-h3); font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
12
+ .uix-sidebar__toggle {
13
+ display: grid; place-items: center; width: 28px; height: 28px; flex: none;
14
+ border: 0; background: transparent; color: var(--uix-text-muted); cursor: pointer; border-radius: var(--uix-radius-sm);
15
+ transition: background-color var(--uix-dur-fast) var(--uix-ease-out), color var(--uix-dur-fast) var(--uix-ease-out);
16
+ }
17
+ .uix-sidebar__toggle:hover { background: var(--uix-bg-hover); color: var(--uix-text); }
18
+ .uix-sidebar__toggle svg { width: 18px; height: 18px; }
19
+
20
+ .uix-navitem {
21
+ display: flex; align-items: center; gap: var(--uix-space-3); height: 36px; padding: 0 var(--uix-space-3);
22
+ border-radius: var(--uix-radius-sm); color: var(--uix-text-hushed); cursor: pointer; text-decoration: none;
23
+ border: 0; background: transparent; font: inherit; font-size: var(--uix-text-body); width: 100%; text-align: left;
24
+ transition: background-color var(--uix-dur-fast) var(--uix-ease-out), color var(--uix-dur-fast) var(--uix-ease-out);
25
+ }
26
+ .uix-navitem:hover { background: var(--uix-bg-hover); color: var(--uix-text); text-decoration: none; }
27
+ /* active uses --uix-link (the brightened-on-dark accent) not raw --uix-accent: the deep accent
28
+ fails AA as text on the brand-muted tint in dark; link reads legibly in both themes. */
29
+ .uix-navitem[aria-current="page"] { background: var(--uix-brand-muted); color: var(--uix-link); font-weight: 500; }
30
+ .uix-navitem__icon { width: var(--uix-icon-md); height: var(--uix-icon-md); flex: none; }
31
+ .uix-navitem__label { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
32
+ .uix-navitem__badge { font-size: var(--uix-text-meta); color: var(--uix-text-muted); }
33
+ /* on the active tint, muted badge dips below AA — hushed composites darker on the tint */
34
+ .uix-navitem[aria-current="page"] .uix-navitem__badge { color: var(--uix-text-hushed); }
35
+ .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); }
36
+ .uix-navitem__star svg { width: 15px; height: 15px; }
37
+ .uix-navitem:hover .uix-navitem__star { opacity: 1; }
38
+ .uix-navitem__star[data-on] { opacity: 1; color: var(--uix-warning); }
39
+ .uix-navitem__star[data-on] svg { fill: currentColor; }
40
+
41
+ /* controlled favourites disclosure */
42
+ .uix-favourites { margin-bottom: var(--uix-space-1); }
43
+ .uix-favourites__chevron { flex-shrink: 0; }
44
+ .uix-favourites__heading {
45
+ display: flex; width: 100%; align-items: center; gap: calc(var(--uix-space-1) * 1.5);
46
+ padding: var(--uix-space-2) var(--uix-space-1) var(--uix-space-1);
47
+ border: 0; background: transparent; cursor: pointer; color: inherit;
48
+ }
49
+ .uix-favourites__list { display: flex; flex-direction: column; gap: calc(var(--uix-space-1) / 4); list-style: none; margin: 0; padding: 0; }
50
+ .uix-favourites__empty { padding: calc(var(--uix-space-1) * 1.5) var(--uix-space-2); color: color-mix(in srgb, var(--uix-text) 50%, transparent); }
51
+ .uix-favourites__row { position: relative; display: flex; align-items: center; }
52
+ .uix-favourites__link { min-width: 0; flex: 1; }
53
+ .uix-favourites__menu-trigger {
54
+ margin-left: auto; display: inline-flex; height: 20px; width: 20px; flex-shrink: 0;
55
+ align-items: center; justify-content: center; border: 0; border-radius: calc(var(--uix-radius-xs) / 2);
56
+ background: transparent; cursor: pointer; color: color-mix(in srgb, var(--uix-text) 50%, transparent);
57
+ opacity: 0; transition: opacity var(--uix-dur-fast) var(--uix-ease-out);
58
+ }
59
+ .uix-favourites__row:hover .uix-favourites__menu-trigger,
60
+ .uix-favourites__row:focus-within .uix-favourites__menu-trigger,
61
+ .uix-favourites__menu-trigger[aria-expanded="true"] { opacity: 1; }
62
+ .uix-favourites__backdrop { position: fixed; inset: 0; cursor: default; background: transparent; z-index: calc(var(--uix-z-tooltip) + 10); }
63
+ .uix-favourites__menu {
64
+ position: absolute; right: 0; top: calc(100% + 2px); z-index: calc(var(--uix-z-tooltip) + 20); min-width: 160px;
65
+ overflow: hidden; margin: 0; padding: var(--uix-space-1) 0; list-style: none;
66
+ border-radius: calc((var(--uix-radius-xs) + var(--uix-radius-sm)) / 2);
67
+ border: 1px solid var(--uix-border); background: var(--uix-surface); box-shadow: var(--uix-shadow-popover);
68
+ }
69
+ .uix-favourites__menu-item {
70
+ display: flex; width: 100%; align-items: center;
71
+ padding: calc(var(--uix-space-1) * 1.5) var(--uix-space-3); border: 0;
72
+ background: transparent; cursor: pointer; text-align: left;
73
+ font-size: calc(var(--uix-text-body) * 0.9285714286);
74
+ color: color-mix(in srgb, var(--uix-text) 85%, transparent);
75
+ transition: background-color var(--uix-dur-fast) var(--uix-ease-out);
76
+ }
77
+ .uix-favourites__menu-item:hover { background: var(--uix-bg-hover); }
78
+
79
+ /* collapsible group */
80
+ .uix-navgroup { }
81
+ .uix-navgroup__trigger .uix-navgroup__chevron { margin-left: auto; transition: transform var(--uix-dur) var(--uix-ease-out); }
82
+ .uix-navgroup__trigger[aria-expanded="false"] .uix-navgroup__chevron { transform: rotate(-90deg); }
83
+ .uix-navgroup__chevron { width: var(--uix-icon-sm); height: var(--uix-icon-sm); }
84
+ .uix-navgroup__panel { display: grid; grid-template-rows: 1fr; transition: grid-template-rows var(--uix-dur) var(--uix-ease-out); }
85
+ .uix-navgroup__trigger[aria-expanded="false"] + .uix-navgroup__panel { grid-template-rows: 0fr; }
86
+ .uix-navgroup__panel > div { overflow: hidden; }
87
+ .uix-subitem { padding-left: var(--uix-space-5); }
88
+ .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; }
89
+
90
+ /* collapsed rail */
91
+ .uix-sidebar[data-collapsed], .uix-sidebar[data-nav="rail"] { width: var(--uix-sidebar-w-rail); }
92
+ .uix-sidebar[data-collapsed] .uix-navitem__label,
93
+ .uix-sidebar[data-collapsed] .uix-navitem__badge,
94
+ .uix-sidebar[data-collapsed] .uix-navitem__star,
95
+ .uix-sidebar[data-collapsed] .uix-sidebar__eyebrow,
96
+ .uix-sidebar[data-collapsed] .uix-sidebar__brand,
97
+ .uix-sidebar[data-collapsed] .uix-navgroup__chevron,
98
+ .uix-sidebar[data-collapsed] .uix-navgroup__panel { display: none; }
99
+ /* center the icon-only rail; head keeps just the toggle, centered */
100
+ .uix-sidebar[data-collapsed] .uix-navitem { justify-content: center; padding: 0; gap: 0; }
101
+ .uix-sidebar[data-collapsed] .uix-sidebar__head { justify-content: center; padding-inline: 0; }
102
+ }
@@ -0,0 +1,8 @@
1
+ /* uix SLA indicator / timer (breach states) — depends only on --uix-* tokens. */
2
+ @layer uix.components {
3
+ .uix-sla { display: inline-flex; align-items: center; gap: var(--uix-space-2); font-size: var(--uix-text-meta); font-weight: 500; color: var(--uix-text-hushed); }
4
+ .uix-sla svg { width: 14px; height: 14px; }
5
+ .uix-sla[data-state="ok"] { color: var(--uix-success); }
6
+ .uix-sla[data-state="at-risk"] { color: var(--uix-warning-text); }
7
+ .uix-sla[data-state="breach"] { color: var(--uix-danger-text); }
8
+ }
@@ -0,0 +1,16 @@
1
+ /* uix slider (native range, styled) — depends only on --uix-* tokens. */
2
+ @layer uix.components {
3
+ .uix-slider { -webkit-appearance: none; appearance: none; width: 220px; height: 20px; background: transparent; cursor: pointer; }
4
+ .uix-slider::-webkit-slider-runnable-track { height: 6px; border-radius: var(--uix-radius-pill); background: var(--uix-bg-active); }
5
+ .uix-slider::-moz-range-track { height: 6px; border-radius: var(--uix-radius-pill); background: var(--uix-bg-active); }
6
+ .uix-slider::-moz-range-progress { height: 6px; border-radius: var(--uix-radius-pill); background: var(--uix-accent); }
7
+ .uix-slider::-webkit-slider-thumb {
8
+ -webkit-appearance: none; appearance: none; margin-top: -6px; width: 18px; height: 18px; border-radius: 50%;
9
+ background: var(--uix-surface); border: 2px solid var(--uix-accent); box-shadow: var(--uix-shadow-sm);
10
+ transition: transform var(--uix-dur-fast) var(--uix-ease-out);
11
+ }
12
+ .uix-slider::-moz-range-thumb { width: 18px; height: 18px; border: 2px solid var(--uix-accent); border-radius: 50%; background: var(--uix-surface); box-shadow: var(--uix-shadow-sm); }
13
+ .uix-slider:active::-webkit-slider-thumb { transform: scale(1.12); }
14
+ .uix-slider:focus-visible::-webkit-slider-thumb { outline: 2px solid var(--uix-ring); outline-offset: 2px; }
15
+ .uix-slider:disabled { opacity: .5; cursor: not-allowed; }
16
+ }
@@ -0,0 +1,10 @@
1
+ /* uix spinner + progress overlay — depends only on --uix-* tokens. */
2
+ @layer uix.components {
3
+ .uix-spinner { width: 20px; height: 20px; border: 2px solid var(--uix-border-strong); border-right-color: transparent; border-radius: 50%; display: inline-block; animation: uix-spin .6s linear infinite; }
4
+ .uix-spinner--accent { border-color: var(--uix-accent); border-right-color: transparent; }
5
+ .uix-spinner--lg { width: 32px; height: 32px; border-width: 3px; }
6
+ .uix-overlay-progress {
7
+ position: absolute; inset: 0; display: grid; place-items: center; border-radius: inherit;
8
+ background: color-mix(in srgb, var(--uix-bg-app) 60%, transparent); backdrop-filter: blur(2px);
9
+ }
10
+ }
@@ -0,0 +1,11 @@
1
+ /* uix KPI / stat tile — depends only on --uix-* tokens. */
2
+ @layer uix.components {
3
+ .uix-stat { background: var(--uix-surface); border: 1px solid var(--uix-border); border-radius: var(--uix-radius-lg); padding: var(--uix-space-6); }
4
+ .uix-stat__label { font-size: var(--uix-text-eyebrow); letter-spacing: var(--uix-tracking-eyebrow); text-transform: uppercase; color: var(--uix-text-muted); display: flex; align-items: center; justify-content: space-between; gap: var(--uix-space-2); }
5
+ .uix-stat__label svg { width: var(--uix-icon-md); height: var(--uix-icon-md); }
6
+ .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); }
7
+ .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); }
8
+ .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); }
9
+ .uix-stat__trend--up { color: var(--uix-success); background: var(--uix-success-bg); }
10
+ .uix-stat__trend--down { color: var(--uix-danger-text); background: var(--uix-danger-bg); }
11
+ }
@@ -0,0 +1,13 @@
1
+ /* uix states — empty + skeleton loaders. Depends only on --uix-* tokens. */
2
+ @layer uix.components {
3
+ .uix-empty { display: flex; flex-direction: column; align-items: center; gap: var(--uix-space-3); text-align: center; padding: var(--uix-space-8); color: var(--uix-text-muted); }
4
+ .uix-empty__icon { width: 44px; height: 44px; display: grid; place-items: center; border-radius: 50%; background: var(--uix-bg-subtle); color: var(--uix-text-muted); }
5
+ .uix-empty__icon svg { width: 22px; height: 22px; }
6
+ .uix-empty__title { font-size: var(--uix-text-h3); font-weight: 600; color: var(--uix-text); }
7
+ /* error tone — ErrorState reuses .uix-empty with a danger-toned icon */
8
+ .uix-empty__icon--danger { background: var(--uix-danger-bg); color: var(--uix-danger); }
9
+
10
+ .uix-skeleton { background: linear-gradient(90deg, var(--uix-bg-subtle) 25%, var(--uix-bg-hover) 50%, var(--uix-bg-subtle) 75%); background-size: 200% 100%; animation: uix-shimmer 1.4s linear infinite; border-radius: var(--uix-radius-sm); }
11
+ .uix-skeleton--text { height: 12px; border-radius: var(--uix-radius-pill); }
12
+ .uix-skeleton--circle { border-radius: 50%; }
13
+ }
@@ -0,0 +1,37 @@
1
+ /* uix status pill — tone API (status / priority / SLA). Depends only on --uix-* tokens. */
2
+ @layer uix.components {
3
+ .uix-pill {
4
+ display: inline-flex; align-items: center; gap: var(--uix-space-2); padding: var(--uix-space-1) var(--uix-space-3); border-radius: var(--uix-radius-pill);
5
+ font-size: var(--uix-text-meta); font-weight: 500; line-height: 1.4;
6
+ background: var(--tone-bg, var(--uix-bg-active)); color: var(--tone-fg, var(--uix-text-hushed));
7
+ }
8
+ .uix-pill__dot { width: 7px; height: 7px; border-radius: 50%; background: var(--tone-dot, currentColor); flex: none; }
9
+ .uix-pill--neutral { --tone-bg: var(--uix-bg-active); --tone-fg: var(--uix-text-hushed); --tone-dot: var(--uix-text-muted); }
10
+ .uix-pill--success { --tone-bg: var(--uix-success-bg); --tone-fg: var(--uix-success); --tone-dot: var(--uix-success); }
11
+ .uix-pill--info { --tone-bg: var(--uix-info-bg); --tone-fg: var(--uix-info-text); --tone-dot: var(--uix-info); }
12
+ .uix-pill--warning { --tone-bg: var(--uix-warning-bg); --tone-fg: var(--uix-warning-text); --tone-dot: var(--uix-warning); }
13
+ .uix-pill--danger { --tone-bg: var(--uix-danger-bg); --tone-fg: var(--uix-danger-text); --tone-dot: var(--uix-danger); }
14
+ /* critical = the one SOLID fill (most urgent); muted = a quiet, chrome-less label */
15
+ .uix-pill--critical { --tone-bg: var(--uix-danger); --tone-fg: var(--uix-danger-fg); --tone-dot: var(--uix-danger-fg); }
16
+ .uix-pill--muted { --tone-bg: transparent; --tone-fg: var(--uix-text-muted); --tone-dot: var(--uix-text-muted); }
17
+ /* time-pressure tones (U1 tokens — distinct from severity and validation-error) */
18
+ .uix-pill--attention { --tone-bg: var(--uix-attention-bg); --tone-fg: var(--uix-attention-text); --tone-dot: var(--uix-attention); }
19
+ .uix-pill--overdue { --tone-bg: var(--uix-overdue-bg); --tone-fg: var(--uix-overdue-text); --tone-dot: var(--uix-overdue); }
20
+ /* SLA tones — ok=success, at-risk=attention, breached=overdue */
21
+ .uix-pill--sla-ok { --tone-bg: var(--uix-success-bg); --tone-fg: var(--uix-success); --tone-dot: var(--uix-success); }
22
+ .uix-pill--sla-at-risk { --tone-bg: var(--uix-attention-bg); --tone-fg: var(--uix-attention-text); --tone-dot: var(--uix-attention); }
23
+ .uix-pill--sla-breached { --tone-bg: var(--uix-overdue-bg); --tone-fg: var(--uix-overdue-text); --tone-dot: var(--uix-overdue); }
24
+ /* Priority/severity tones — P1=danger, P2=warning, P3=amber, P4=info, P5=neutral (complete 5-tier ramp) */
25
+ .uix-pill--p1 { --tone-bg: var(--uix-danger-bg); --tone-fg: var(--uix-danger-text); --tone-dot: var(--uix-danger); }
26
+ .uix-pill--p2 { --tone-bg: var(--uix-warning-bg); --tone-fg: var(--uix-warning-text); --tone-dot: var(--uix-warning); }
27
+ .uix-pill--p3 { --tone-bg: var(--uix-amber-bg); --tone-fg: var(--uix-amber-text); --tone-dot: var(--uix-amber); }
28
+ .uix-pill--p4 { --tone-bg: var(--uix-info-bg); --tone-fg: var(--uix-info-text); --tone-dot: var(--uix-info); }
29
+ .uix-pill--p5 { --tone-bg: var(--uix-bg-active); --tone-fg: var(--uix-text-hushed); --tone-dot: var(--uix-text-muted); }
30
+
31
+ /* outline treatment — transparent fill, tone-tinted border, tone-colored text. The border tints
32
+ the tone hue (--tone-fg) at 40%; neutral/muted use the structural borders, critical reads strongest. */
33
+ .uix-pill--outline { background: transparent; border: 1px solid var(--tone-line, color-mix(in srgb, var(--tone-fg) 40%, transparent)); }
34
+ .uix-pill--outline.uix-pill--neutral { --tone-line: var(--uix-border-strong); }
35
+ .uix-pill--outline.uix-pill--muted { --tone-line: var(--uix-border); }
36
+ .uix-pill--outline.uix-pill--critical { color: var(--uix-danger-text); --tone-dot: var(--uix-danger); --tone-line: color-mix(in srgb, var(--uix-danger) 60%, transparent); }
37
+ }
@@ -0,0 +1,13 @@
1
+ /* uix number stepper — depends only on --uix-* tokens. */
2
+ @layer uix.components {
3
+ .uix-stepper { display: inline-flex; align-items: center; height: var(--uix-control-h); overflow: hidden;
4
+ border: 1px solid var(--uix-border); border-radius: var(--uix-radius-md); background: var(--uix-surface); }
5
+ .uix-stepper__btn { width: 32px; align-self: stretch; border: 0; background: transparent; color: var(--uix-text); cursor: pointer;
6
+ display: grid; place-items: center; transition: background-color var(--uix-dur-fast) var(--uix-ease-out); }
7
+ .uix-stepper__btn:hover { background: var(--uix-bg-hover); }
8
+ .uix-stepper__btn svg { width: var(--uix-icon-sm); height: var(--uix-icon-sm); }
9
+ .uix-stepper__input { width: 52px; text-align: center; border: 0; height: 100%; background: transparent; color: var(--uix-text);
10
+ font: inherit; border-inline: 1px solid var(--uix-border); -moz-appearance: textfield; }
11
+ .uix-stepper__input::-webkit-outer-spin-button, .uix-stepper__input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
12
+ .uix-stepper:focus-within { border-color: var(--uix-ring); box-shadow: 0 0 0 3px var(--uix-brand-muted); }
13
+ }
@@ -0,0 +1,18 @@
1
+ /* uix steps / wizard — depends only on --uix-* tokens. */
2
+ @layer uix.components {
3
+ .uix-steps { display: flex; align-items: center; gap: 0; }
4
+ .uix-step { display: flex; align-items: center; gap: var(--uix-space-3); color: var(--uix-text-muted); }
5
+ .uix-step__marker {
6
+ width: 26px; height: 26px; flex: none; border-radius: 50%; display: grid; place-items: center;
7
+ border: 1px solid var(--uix-border-strong); background: var(--uix-surface); font-size: var(--uix-text-meta); font-weight: 600;
8
+ line-height: 1; /* hug the glyph so place-items:center truly centers single digits/symbols */
9
+ }
10
+ .uix-step__label { font-size: var(--uix-text-meta); font-weight: 500; }
11
+ .uix-step__connector { flex: 1; height: 1px; min-width: 28px; background: var(--uix-border); margin: 0 var(--uix-space-3); }
12
+ .uix-step[data-state="active"] { color: var(--uix-text); }
13
+ .uix-step[data-state="active"] .uix-step__marker { border-color: var(--uix-accent); color: var(--uix-accent); box-shadow: 0 0 0 3px var(--uix-brand-muted); }
14
+ .uix-step[data-state="done"] { color: var(--uix-text); }
15
+ .uix-step[data-state="done"] .uix-step__marker { background: var(--uix-accent); border-color: var(--uix-accent); color: var(--uix-accent-fg); }
16
+ .uix-step[data-state="done"] + .uix-step__connector,
17
+ .uix-step__connector[data-done] { background: var(--uix-accent); }
18
+ }
@@ -0,0 +1,19 @@
1
+ /* uix switch — depends only on --uix-* tokens. */
2
+ @layer uix.components {
3
+ .uix-switch { display: inline-flex; align-items: center; gap: var(--uix-space-2); cursor: pointer; color: var(--uix-text); font-size: var(--uix-text-body); }
4
+ .uix-switch > input { position: absolute; opacity: 0; width: 1px; height: 1px; }
5
+ .uix-switch__track {
6
+ width: 36px; height: 20px; flex: none; border-radius: var(--uix-radius-pill);
7
+ background: var(--uix-bg-active); position: relative;
8
+ transition: background-color var(--uix-dur) var(--uix-ease-out);
9
+ }
10
+ .uix-switch__track::after {
11
+ content: ""; position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; border-radius: 50%;
12
+ background: var(--uix-text-reverse); box-shadow: var(--uix-shadow-sm);
13
+ transition: transform var(--uix-dur) var(--uix-ease-out);
14
+ }
15
+ .uix-switch > input:checked + .uix-switch__track { background: var(--uix-accent); }
16
+ .uix-switch > input:checked + .uix-switch__track::after { transform: translateX(16px); }
17
+ .uix-switch > input:focus-visible + .uix-switch__track { outline: 2px solid var(--uix-ring); outline-offset: 2px; }
18
+ .uix-switch > input:disabled + .uix-switch__track { opacity: .5; }
19
+ }
@@ -0,0 +1,20 @@
1
+ /* uix table toolbar + two-row filter bar (status / type). Depends only on --uix-* tokens. */
2
+ @layer uix.components {
3
+ .uix-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--uix-space-2); margin-bottom: var(--uix-space-3); }
4
+ .uix-toolbar__spacer { flex: 1; }
5
+
6
+ /* responsive: the status + type groups sit on ONE line when they fit, wrap to two only when cramped */
7
+ .uix-filterbar { display: flex; flex-wrap: wrap; gap: var(--uix-space-2) var(--uix-space-5); margin-bottom: var(--uix-space-3); }
8
+ .uix-filterrow { display: flex; flex-wrap: wrap; align-items: center; gap: var(--uix-space-2); }
9
+ .uix-filterrow__label { font-size: var(--uix-text-meta); color: var(--uix-text-muted); width: 54px; flex: none; }
10
+
11
+ .uix-chip {
12
+ display: inline-flex; align-items: center; gap: var(--uix-space-2); padding: var(--uix-space-1) var(--uix-space-3); border-radius: var(--uix-radius-pill);
13
+ border: 1px solid var(--uix-border); background: var(--uix-surface); color: var(--uix-text-hushed);
14
+ font: inherit; font-size: var(--uix-text-meta); cursor: pointer;
15
+ transition: background-color var(--uix-dur-fast) var(--uix-ease-out), border-color var(--uix-dur-fast) var(--uix-ease-out), color var(--uix-dur-fast) var(--uix-ease-out);
16
+ }
17
+ .uix-chip:hover { border-color: var(--uix-border-strong); color: var(--uix-text); }
18
+ .uix-chip[data-on] { background: var(--uix-brand-muted); border-color: var(--uix-accent); color: var(--uix-accent); }
19
+ .uix-chip__count { font-variant-numeric: tabular-nums; opacity: .7; }
20
+ }