@tensor_1/tokens 2.11.0 → 2.13.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 (86) hide show
  1. package/README.md +8 -0
  2. package/build/css/components.css +1 -1847
  3. package/build/css/styles.css +1 -2188
  4. package/package.json +12 -2
  5. package/styles/components/alert.css +16 -0
  6. package/styles/components/app-shell.css +37 -0
  7. package/styles/components/attachment.css +10 -0
  8. package/styles/components/audit-log.css +11 -0
  9. package/styles/components/avatar.css +25 -0
  10. package/styles/components/brand-profiles.css +12 -0
  11. package/styles/components/breadcrumbs.css +10 -0
  12. package/styles/components/builder-canvas.css +17 -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/color-picker.css +14 -0
  19. package/styles/components/combobox.css +16 -0
  20. package/styles/components/command-palette.css +14 -0
  21. package/styles/components/comments.css +17 -0
  22. package/styles/components/contact-card.css +12 -0
  23. package/styles/components/date-range-picker.css +16 -0
  24. package/styles/components/description-list.css +6 -0
  25. package/styles/components/detail-layout.css +7 -0
  26. package/styles/components/diff-viewer.css +14 -0
  27. package/styles/components/drawer.css +24 -0
  28. package/styles/components/editorial-home.css +188 -0
  29. package/styles/components/file-upload.css +14 -0
  30. package/styles/components/flow.css +196 -0
  31. package/styles/components/form.css +14 -0
  32. package/styles/components/heartbeat.css +12 -0
  33. package/styles/components/inbox.css +13 -0
  34. package/styles/components/input.css +39 -0
  35. package/styles/components/kanban.css +14 -0
  36. package/styles/components/kbd.css +8 -0
  37. package/styles/components/labels.css +13 -0
  38. package/styles/components/license-position-bar.css +8 -0
  39. package/styles/components/lightbox.css +13 -0
  40. package/styles/components/link.css +98 -0
  41. package/styles/components/list.css +10 -0
  42. package/styles/components/match-review.css +11 -0
  43. package/styles/components/media.css +9 -0
  44. package/styles/components/menu.css +15 -0
  45. package/styles/components/meter.css +9 -0
  46. package/styles/components/metric-input.css +9 -0
  47. package/styles/components/modal.css +31 -0
  48. package/styles/components/notification-center.css +14 -0
  49. package/styles/components/page-header.css +9 -0
  50. package/styles/components/pagination.css +14 -0
  51. package/styles/components/peek.css +46 -0
  52. package/styles/components/pipeline.css +9 -0
  53. package/styles/components/popover.css +11 -0
  54. package/styles/components/progress.css +12 -0
  55. package/styles/components/prose.css +27 -0
  56. package/styles/components/radio.css +20 -0
  57. package/styles/components/reactions.css +22 -0
  58. package/styles/components/relationship-graph.css +21 -0
  59. package/styles/components/rule-builder.css +17 -0
  60. package/styles/components/scheduling-calendar.css +22 -0
  61. package/styles/components/segmented.css +12 -0
  62. package/styles/components/select.css +23 -0
  63. package/styles/components/sidebar.css +102 -0
  64. package/styles/components/sla.css +8 -0
  65. package/styles/components/slider.css +16 -0
  66. package/styles/components/spinner.css +10 -0
  67. package/styles/components/stat-tile.css +11 -0
  68. package/styles/components/states.css +13 -0
  69. package/styles/components/status-pill.css +37 -0
  70. package/styles/components/stepper.css +13 -0
  71. package/styles/components/steps.css +18 -0
  72. package/styles/components/switch.css +19 -0
  73. package/styles/components/table-toolbar.css +20 -0
  74. package/styles/components/table.css +160 -0
  75. package/styles/components/tabs.css +31 -0
  76. package/styles/components/tag-input.css +16 -0
  77. package/styles/components/textarea.css +15 -0
  78. package/styles/components/timeline.css +11 -0
  79. package/styles/components/toast.css +21 -0
  80. package/styles/components/tooltip.css +35 -0
  81. package/styles/components/tree.css +17 -0
  82. package/styles/components/typography.css +45 -0
  83. package/styles/components/utility-bits.css +14 -0
  84. package/styles/components/view-menu.css +14 -0
  85. package/styles/motion.css +35 -0
  86. package/styles/utilities.css +26 -0
@@ -0,0 +1,188 @@
1
+ /* uix editorial-home kit — the intranet "editorial" landing patterns (INTRA-04):
2
+ * page intro + search, shortcut grid, notice queue, featured stage + rundown,
3
+ * section heads, content/rail grids, news lead, content list, resource grid,
4
+ * stat line, event + status rows. Ported 1:1 from the approved TENSOR intranet
5
+ * prototype (Docs/prototypes/intranet-reimagined/mockups.css); spacing/type
6
+ * snapped to the --uix-* scales per the contract gate, editorial display sizes
7
+ * justified in tests/raw-value-allowlist.json. Depends only on --uix-* tokens. */
8
+ @layer uix.components {
9
+ /* ── page intro — kicker/title/lede beside the search well ─────────────────── */
10
+ .uix-page-intro { margin-top: var(--uix-space-6); display: grid; grid-template-columns: minmax(300px, 0.8fr) minmax(460px, 1.2fr); align-items: end; gap: var(--uix-space-7); }
11
+ .uix-page-intro .uix-page-lede { margin-top: var(--uix-space-2); }
12
+ .uix-page-kicker { margin: 0 0 var(--uix-space-2); color: var(--uix-text-hushed); font-size: var(--uix-text-meta); }
13
+ .uix-page-title { max-width: 760px; margin: 0; font-family: var(--uix-font-heading); font-size: clamp(30px, 4vw, 48px); font-weight: 400; letter-spacing: -0.035em; line-height: 1.06; }
14
+ .uix-page-lede { max-width: 680px; margin: var(--uix-space-3) 0 0; color: var(--uix-text-hushed); font-size: var(--uix-text-h3); }
15
+ .uix-intro-search__label { margin: 0 0 var(--uix-space-2); color: var(--uix-text-hushed); font-size: var(--uix-text-meta); }
16
+
17
+ /* The well is 44px tall; the button beside it is a standard 36px control. Centre the
18
+ two and lift the button to the well's height so their edges line up (TENSOR portal
19
+ services search: the button sat 8px short of the input, top-aligned). */
20
+ .uix-searchbar { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--uix-space-2); align-items: center; }
21
+ .uix-searchbar .uix-input { min-height: 44px; padding-left: 42px; }
22
+ .uix-searchbar .uix-btn { min-height: 44px; }
23
+ .uix-searchbar__wrap { position: relative; }
24
+ .uix-searchbar__wrap > svg { position: absolute; top: 50%; left: 14px; z-index: var(--uix-z-raised); width: 17px; height: 17px; color: var(--uix-text-hushed); transform: translateY(-50%); pointer-events: none; }
25
+
26
+ .uix-shortcut-grid { grid-column: 1 / -1; margin-top: var(--uix-space-4); display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--uix-space-2); }
27
+ .uix-shortcut-grid .uix-btn { min-height: 42px; justify-content: flex-start; }
28
+
29
+ /* ── notice queue — rotating "important updates" banner ────────────────────── */
30
+ .uix-notice { min-height: 48px; padding: var(--uix-space-2) var(--uix-space-4); display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: var(--uix-space-3); border-left: 2px solid var(--uix-text); background: var(--uix-bg-subtle); }
31
+ .uix-notice__copy { margin: 0; font-size: var(--uix-text-body); }
32
+ .uix-notice__copy strong { font-weight: 600; }
33
+ .uix-notice__content { min-width: 0; }
34
+ .uix-notice__meta { margin: var(--uix-space-1) 0 0; color: var(--uix-text-hushed); font-size: var(--uix-text-eyebrow); }
35
+ .uix-notice__actions { display: flex; align-items: center; justify-content: flex-end; gap: var(--uix-space-2); }
36
+ .uix-notice__position { margin-right: var(--uix-space-1); color: var(--uix-text-hushed); font-size: var(--uix-text-eyebrow); white-space: nowrap; }
37
+ .uix-notice__arrow--previous svg { transform: rotate(180deg); }
38
+
39
+ /* ── featured briefing — ONE card: stage + rundown are zones inside it, split
40
+ by an internal hairline. The selected rundown item grows a caret that sits
41
+ on (and breaks) that hairline toward the stage, and its ordinal becomes a
42
+ filled chip echoed by .uix-featured__now in the stage eyebrow — that chip
43
+ pairing is what carries the selection link once the card stacks. ─────────── */
44
+ .uix-featured { display: grid; grid-template-columns: minmax(0, 1.7fr) minmax(300px, 0.7fr); align-items: stretch; overflow: hidden; border: 1px solid var(--uix-border); border-radius: var(--uix-radius-md); background: var(--uix-surface); }
45
+ .uix-page-intro + .uix-featured { margin-top: var(--uix-space-6); }
46
+
47
+ .uix-featured__stage { min-width: 0; min-height: 302px; display: grid; grid-template-columns: minmax(260px, 0.95fr) minmax(300px, 1.05fr); }
48
+ .uix-featured__visual {
49
+ min-height: 302px; padding: var(--uix-space-6) var(--uix-space-7); display: flex; align-items: flex-end;
50
+ position: relative; overflow: hidden;
51
+ background:
52
+ linear-gradient(135deg, transparent 20%, color-mix(in srgb, var(--uix-text) 8%, transparent)),
53
+ var(--uix-bg-subtle);
54
+ }
55
+ .uix-featured__visual::before,
56
+ .uix-featured__visual::after { content: ""; position: absolute; border: 1px solid var(--uix-border-strong); border-radius: 50%; }
57
+ .uix-featured__visual::before { width: 240px; height: 240px; top: -78px; right: -42px; }
58
+ .uix-featured__visual::after { width: 144px; height: 144px; top: 72px; right: 56px; }
59
+ .uix-featured__content { padding: var(--uix-space-7); display: flex; flex-direction: column; align-items: flex-start; justify-content: center; }
60
+ .uix-featured__eyebrow { margin: 0 0 var(--uix-space-4); color: var(--uix-text-hushed); font-size: var(--uix-text-eyebrow); letter-spacing: var(--uix-tracking-eyebrow); text-transform: uppercase; }
61
+ .uix-featured__title { margin: 0; font-family: var(--uix-font-heading); font-size: clamp(26px, 3vw, 38px); font-weight: 400; letter-spacing: -0.03em; line-height: 1.08; }
62
+ .uix-featured__description { margin: var(--uix-space-3) 0 var(--uix-space-5); color: var(--uix-text-hushed); }
63
+ .uix-featured__meta { margin: 0 0 var(--uix-space-5); color: var(--uix-text-hushed); font-size: var(--uix-text-meta); }
64
+ .uix-featured__now { min-width: 22px; height: 22px; display: inline-grid; place-items: center; margin-right: var(--uix-space-2); border-radius: var(--uix-radius-pill); background: var(--uix-text); color: var(--uix-bg-app); font-variant-numeric: tabular-nums; letter-spacing: 0; }
65
+
66
+ .uix-story-signal { position: absolute; top: 26px; left: 28px; z-index: var(--uix-z-raised); }
67
+ .uix-story-signal__value { display: block; font-family: var(--uix-font-heading); font-size: 48px; font-weight: 400; letter-spacing: -0.04em; line-height: 1; }
68
+ .uix-story-signal__label { display: block; margin-top: var(--uix-space-2); color: var(--uix-text-hushed); font-size: var(--uix-text-meta); }
69
+
70
+ .uix-story-diagram { width: min(100%, 500px); position: relative; z-index: var(--uix-z-raised); display: grid; grid-template-columns: repeat(3, 1fr); align-items: end; gap: var(--uix-space-3); }
71
+ .uix-story-diagram__bar { min-height: 52px; border: 1px solid var(--uix-border-strong); border-radius: var(--uix-radius-sm); background: color-mix(in srgb, var(--uix-surface) 84%, transparent); }
72
+ .uix-story-diagram__bar:nth-child(2) { min-height: 104px; }
73
+ .uix-story-diagram__bar:nth-child(3) { min-height: 126px; background: var(--uix-text); }
74
+
75
+ .uix-rundown { min-width: 0; padding: var(--uix-space-4); display: grid; grid-template-rows: auto minmax(0, 1fr); gap: var(--uix-space-3); border-left: 1px solid var(--uix-border); }
76
+ .uix-rundown__head { padding: var(--uix-space-1) var(--uix-space-1) var(--uix-space-3); display: flex; align-items: flex-start; justify-content: space-between; gap: var(--uix-space-3); border-bottom: 1px solid var(--uix-border); }
77
+ .uix-rundown__eyebrow { margin: 0; color: var(--uix-text-hushed); font-size: var(--uix-text-eyebrow); letter-spacing: 0.05em; text-transform: uppercase; }
78
+ .uix-rundown__title { margin: var(--uix-space-1) 0 0; font-family: var(--uix-font-heading); font-size: 18px; font-weight: 400; }
79
+ .uix-rundown__items { min-width: 0; display: grid; grid-template-rows: repeat(3, minmax(0, 1fr)); gap: var(--uix-space-2); }
80
+ .uix-rundown__item { position: relative; min-width: 0; min-height: 68px; padding: var(--uix-space-3); display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: var(--uix-space-3); border: 1px solid transparent; border-radius: var(--uix-radius-sm); background: transparent; color: var(--uix-text); cursor: pointer; font: inherit; text-align: left; }
81
+ .uix-rundown__item:hover { background: var(--uix-bg-hover); }
82
+ .uix-rundown__item[data-selected="true"] { border-color: var(--uix-border); background: var(--uix-bg-active); }
83
+ /* caret centered on the internal divider (16px zone pad + 1px hairline + half of the 12px glyph) */
84
+ .uix-rundown__item[data-selected="true"]::before { content: ""; position: absolute; top: 50%; left: -23px; width: 12px; height: 12px; transform: translateY(-50%) rotate(45deg); background: var(--uix-surface); border-left: 1px solid var(--uix-border-strong); border-bottom: 1px solid var(--uix-border-strong); }
85
+ .uix-rundown__number { color: var(--uix-text-hushed); font-size: var(--uix-text-eyebrow); font-variant-numeric: tabular-nums; }
86
+ .uix-rundown__item[data-selected="true"] .uix-rundown__number { min-width: 22px; height: 22px; display: inline-grid; place-items: center; border-radius: var(--uix-radius-pill); background: var(--uix-text); color: var(--uix-bg-app); }
87
+ .uix-rundown__topic,
88
+ .uix-rundown__item-title { display: block; }
89
+ .uix-rundown__topic { color: var(--uix-text-hushed); font-size: var(--uix-text-eyebrow); }
90
+ .uix-rundown__item-title { margin-top: var(--uix-space-1); font-weight: 600; line-height: 1.2; }
91
+
92
+ /* ── section heads ─────────────────────────────────────────────────────────── */
93
+ .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); }
94
+ .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); }
95
+ .uix-section-link { color: var(--uix-text-hushed); font-size: var(--uix-text-meta); text-decoration: none; }
96
+ /* already a quiet link by its own design — hover/focus parity with link.css */
97
+ .uix-section-link:is(:hover, :focus-visible) { color: var(--uix-text); text-decoration: underline; }
98
+
99
+ /* ── content grid + rail ───────────────────────────────────────────────────── */
100
+ .uix-content-grid { display: grid; grid-template-columns: minmax(0, 1.65fr) minmax(280px, 0.75fr); gap: var(--uix-space-7); align-items: start; }
101
+ .uix-content-grid--balanced { grid-template-columns: repeat(2, minmax(0, 1fr)); }
102
+ .uix-content-grid > * { min-width: 0; }
103
+ .uix-rail { display: grid; gap: var(--uix-space-4); }
104
+ .uix-rail-card { padding: var(--uix-space-5); }
105
+ .uix-rail-card__title { margin: 0; font-family: var(--uix-font-heading); font-size: 18px; font-weight: 400; }
106
+ .uix-rail-card__meta { margin: var(--uix-space-1) 0 0; color: var(--uix-text-hushed); font-size: var(--uix-text-meta); }
107
+
108
+ /* ── news lead + content list ──────────────────────────────────────────────── */
109
+ .uix-news-lead { padding: 0 0 var(--uix-space-5); border-bottom: 1px solid var(--uix-border); }
110
+ .uix-news-lead__meta,
111
+ .uix-list-meta { color: var(--uix-text-hushed); font-size: var(--uix-text-meta); }
112
+ .uix-news-lead__title { margin: var(--uix-space-2) 0 var(--uix-space-1); font-family: var(--uix-font-heading); font-size: var(--uix-text-h2); font-weight: 400; letter-spacing: var(--uix-tracking-tight); }
113
+ .uix-news-lead__summary { margin: 0; color: var(--uix-text-hushed); }
114
+
115
+ .uix-content-list { margin: 0; padding: 0; list-style: none; }
116
+ .uix-content-list__item { min-height: 68px; padding: var(--uix-space-3) 0; display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: var(--uix-space-4); border-bottom: 1px solid var(--uix-border); }
117
+ .uix-content-list__item:last-child { border-bottom: 0; }
118
+ .uix-content-list__title { margin: 0; font-weight: 600; }
119
+ .uix-content-list__meta { margin: var(--uix-space-1) 0 0; color: var(--uix-text-hushed); font-size: var(--uix-text-meta); }
120
+
121
+ /* ── resource grid ─────────────────────────────────────────────────────────── */
122
+ .uix-resource-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--uix-space-2); }
123
+ .uix-resource-grid .uix-btn { min-height: 44px; justify-content: flex-start; }
124
+
125
+ /* ── stat line ─────────────────────────────────────────────────────────────── */
126
+ .uix-stat-line { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); border-top: 1px solid var(--uix-border); }
127
+ .uix-stat-line__item { padding: var(--uix-space-4) var(--uix-space-2) var(--uix-space-1) 0; }
128
+ .uix-stat-line__value { display: block; font-size: 20px; font-variant-numeric: tabular-nums; }
129
+ .uix-stat-line__label { color: var(--uix-text-hushed); font-size: var(--uix-text-eyebrow); }
130
+
131
+ /* ── event + status rows ───────────────────────────────────────────────────── */
132
+ .uix-event-row { min-height: 64px; padding-block: var(--uix-space-3); display: grid; grid-template-columns: 42px minmax(0, 1fr); align-items: center; gap: var(--uix-space-3); border-bottom: 1px solid var(--uix-border); }
133
+ .uix-event-row:last-child { border-bottom: 0; }
134
+ .uix-event-date { text-align: center; }
135
+ .uix-event-date__month { display: block; color: var(--uix-text-hushed); font-size: var(--uix-text-eyebrow); text-transform: uppercase; }
136
+ .uix-event-date__day { display: block; font-size: 18px; font-variant-numeric: tabular-nums; }
137
+ .uix-event-row__title { margin: 0; font-weight: 600; }
138
+ .uix-event-row__meta { margin: var(--uix-space-1) 0 0; color: var(--uix-text-hushed); font-size: var(--uix-text-meta); }
139
+
140
+ .uix-status-row { min-height: 48px; display: flex; align-items: center; gap: var(--uix-space-3); border-bottom: 1px solid var(--uix-border); }
141
+ .uix-status-row:last-child { border-bottom: 0; }
142
+ .uix-status-row__name { flex: 1; }
143
+
144
+ /* ── responsive — ported 1:1 from the prototype's 920/620 breakpoints ──────── */
145
+ @media (max-width: 920px) {
146
+ .uix-page-intro,
147
+ .uix-content-grid,
148
+ .uix-content-grid--balanced,
149
+ .uix-featured { grid-template-columns: 1fr; }
150
+
151
+ .uix-rundown { border-left: 0; border-top: 1px solid var(--uix-border); }
152
+ .uix-rundown__items { grid-template-columns: repeat(3, minmax(0, 1fr)); grid-template-rows: 1fr; }
153
+ /* stacked zones: the caret flips to point up at the stage above */
154
+ .uix-rundown__item[data-selected="true"]::before { top: -23px; left: 22px; transform: rotate(45deg); border-bottom: 0; border-top: 1px solid var(--uix-border-strong); }
155
+
156
+ .uix-shortcut-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
157
+ }
158
+
159
+ @media (max-width: 620px) {
160
+ .uix-featured__stage { grid-template-columns: 1fr; }
161
+ .uix-featured__visual { min-height: 190px; }
162
+ .uix-featured__content { padding: var(--uix-space-6); }
163
+
164
+ .uix-rundown__items { grid-template-columns: 1fr; grid-template-rows: repeat(3, auto); }
165
+ /* vertical item stack: the directional caret stops making sense — the
166
+ ordinal chips (item number + .uix-featured__now) carry the pairing */
167
+ .uix-rundown__item[data-selected="true"]::before { display: none; }
168
+
169
+ .uix-notice { grid-template-columns: auto minmax(0, 1fr); }
170
+ .uix-notice > .uix-btn { grid-column: 2; justify-self: start; }
171
+ .uix-notice__actions { grid-column: 1 / -1; width: 100%; justify-content: flex-start; flex-wrap: wrap; }
172
+ .uix-notice__position { flex: 1; }
173
+
174
+ .uix-searchbar { grid-template-columns: 1fr; }
175
+
176
+ .uix-page-intro { margin-top: var(--uix-space-5); gap: var(--uix-space-5); }
177
+ .uix-shortcut-grid { grid-template-columns: 1fr 1fr; }
178
+ .uix-shortcut-grid .uix-btn { min-height: 48px; }
179
+
180
+ .uix-story-signal { top: 20px; left: 20px; }
181
+ .uix-story-signal__value { font-size: var(--uix-text-display); }
182
+
183
+ .uix-resource-grid { grid-template-columns: 1fr; }
184
+
185
+ .uix-stat-line { grid-template-columns: 1fr; }
186
+ .uix-stat-line__item { display: flex; align-items: baseline; justify-content: space-between; border-bottom: 1px solid var(--uix-border); }
187
+ }
188
+ }
@@ -0,0 +1,14 @@
1
+ /* uix file upload / dropzone — depends only on --uix-* tokens. */
2
+ @layer uix.components {
3
+ .uix-dropzone {
4
+ display: flex; flex-direction: column; align-items: center; gap: var(--uix-space-2); padding: var(--uix-space-7); text-align: center;
5
+ border: 1.5px dashed var(--uix-border-strong); border-radius: var(--uix-radius-lg);
6
+ background: var(--uix-bg-subtle); color: var(--uix-text-muted); cursor: pointer;
7
+ transition: border-color var(--uix-dur-fast) var(--uix-ease-out), background-color var(--uix-dur-fast) var(--uix-ease-out), color var(--uix-dur-fast) var(--uix-ease-out);
8
+ }
9
+ .uix-dropzone:hover, .uix-dropzone[data-dragover] { border-color: var(--uix-accent); background: var(--uix-brand-muted); color: var(--uix-text); }
10
+ .uix-dropzone svg { width: var(--uix-icon-lg); height: var(--uix-icon-lg); }
11
+ .uix-filelist { display: flex; flex-direction: column; gap: var(--uix-space-2); margin-top: var(--uix-space-3); }
12
+ .uix-filelist__item { display: flex; align-items: center; gap: var(--uix-space-3); padding: var(--uix-space-2) var(--uix-space-3); border: 1px solid var(--uix-border); border-radius: var(--uix-radius-md); background: var(--uix-surface); font-size: var(--uix-text-meta); color: var(--uix-text); }
13
+ .uix-filelist__size { margin-left: auto; color: var(--uix-text-muted); }
14
+ }
@@ -0,0 +1,196 @@
1
+ /* uix flow — workflow & pipeline diagrams: boxed nodes + connectors.
2
+ Depends only on --uix-* tokens. Edges are decorative inline SVG (aria-hidden);
3
+ straight runs use pure-CSS connectors. Node state follows the tone-API pattern
4
+ (see status-pill.css): state --modifiers set only --tone-* vars, the base reads them. */
5
+ @layer uix.components {
6
+
7
+ /* ============================================================ node */
8
+ .uix-node {
9
+ position: relative;
10
+ display: inline-grid; grid-template-columns: auto 1fr; align-items: center;
11
+ gap: var(--uix-space-3); min-width: 132px; width: max-content; max-width: 220px; padding: var(--uix-space-3) var(--uix-space-3);
12
+ background: var(--uix-surface);
13
+ border: 1px solid var(--tone-border, var(--uix-border-strong));
14
+ border-radius: var(--uix-radius-md);
15
+ box-shadow: var(--uix-shadow-sm);
16
+ color: var(--uix-text); font-size: var(--uix-text-body); text-align: left;
17
+ }
18
+ .uix-node__icon {
19
+ display: grid; place-items: center; width: 30px; height: 30px; flex: none;
20
+ border-radius: var(--uix-radius-sm);
21
+ background: var(--tone-bg, var(--uix-bg-subtle));
22
+ color: var(--tone-fg, var(--uix-text-muted));
23
+ }
24
+ .uix-node__icon svg { width: var(--uix-icon-sm); height: var(--uix-icon-sm); }
25
+ .uix-node__body { min-width: 0; }
26
+ .uix-node__title { font-weight: 500; line-height: 1.25; }
27
+ .uix-node__meta { font-size: var(--uix-text-meta); color: var(--uix-text-muted); }
28
+ .uix-node__status {
29
+ display: inline-flex; align-items: center; gap: var(--uix-space-2); margin-top: var(--uix-space-1);
30
+ font-size: var(--uix-text-eyebrow); letter-spacing: var(--uix-tracking-eyebrow);
31
+ text-transform: uppercase; color: var(--tone-fg, var(--uix-text-muted));
32
+ }
33
+ .uix-node__status::before {
34
+ content: ""; width: 7px; height: 7px; flex: none; border-radius: 50%;
35
+ background: var(--tone-dot, var(--uix-text-muted));
36
+ }
37
+
38
+ /* connection handles — decorative connection-point affordance */
39
+ .uix-node__handle {
40
+ position: absolute; top: 50%; width: 9px; height: 9px; border-radius: 50%;
41
+ background: var(--uix-surface); border: 1.5px solid var(--uix-border-strong);
42
+ transform: translateY(-50%);
43
+ }
44
+ .uix-node__handle--in { left: -5px; }
45
+ .uix-node__handle--out { right: -5px; }
46
+
47
+ /* ---- state modifiers: set tone vars only ---- */
48
+ .uix-node--pending { --tone-bg: var(--uix-bg-subtle); --tone-fg: var(--uix-text-muted); --tone-dot: var(--uix-text-muted); --tone-border: var(--uix-border); }
49
+ .uix-node--active { --tone-bg: var(--uix-brand-muted); --tone-fg: var(--uix-link); --tone-dot: var(--uix-accent); --tone-border: var(--uix-accent); }
50
+ .uix-node--running { --tone-bg: var(--uix-info-bg); --tone-fg: var(--uix-info-text); --tone-dot: var(--uix-info); --tone-border: var(--uix-info); }
51
+ .uix-node--done { --tone-bg: var(--uix-success-bg); --tone-fg: var(--uix-success); --tone-dot: var(--uix-success); --tone-border: var(--uix-success); }
52
+ .uix-node--error { --tone-bg: var(--uix-danger-bg); --tone-fg: var(--uix-danger-text); --tone-dot: var(--uix-danger); --tone-border: var(--uix-danger); }
53
+ /* active/running read as "current" via a soft halo in their own tone */
54
+ .uix-node--active, .uix-node--running { box-shadow: var(--uix-shadow-sm), 0 0 0 3px var(--tone-bg); }
55
+
56
+ /* running node spins its icon */
57
+ .uix-node--running .uix-node__icon svg { animation: uix-flow-spin 1s linear infinite; }
58
+
59
+ /* ---- decision / diamond ---- */
60
+ .uix-node--decision {
61
+ min-width: 0; width: 112px; height: 112px; padding: 0; overflow: visible;
62
+ /* reset the base node's `auto 1fr` columns to one full-width track, else the lone title is
63
+ trapped in the left `auto` column and place-items:center can't center it over the diamond. */
64
+ display: grid; grid-template-columns: 1fr; place-items: center; background: transparent; border: 0; box-shadow: none;
65
+ }
66
+ .uix-node--decision::before {
67
+ content: ""; position: absolute; left: 50%; top: 50%; width: 78px; height: 78px;
68
+ transform: translate(-50%, -50%) rotate(45deg);
69
+ background: var(--tone-bg, var(--uix-surface));
70
+ border: 1px solid var(--tone-border, var(--uix-border-strong));
71
+ border-radius: var(--uix-radius-sm); box-shadow: var(--uix-shadow-sm);
72
+ }
73
+ .uix-node--decision .uix-node__title {
74
+ position: relative; z-index: var(--uix-z-raised); max-width: 88px; text-align: center;
75
+ font-size: var(--uix-text-meta); color: var(--tone-fg, var(--uix-text));
76
+ }
77
+
78
+ /* ---- start / end terminals (pills) ---- */
79
+ .uix-node--start, .uix-node--end {
80
+ grid-template-columns: 1fr; min-width: 0; justify-items: center;
81
+ padding: var(--uix-space-2) var(--uix-space-5); border-radius: var(--uix-radius-pill);
82
+ background: var(--uix-bg-active); color: var(--uix-text-hushed); font-weight: 500;
83
+ }
84
+
85
+ /* ============================================================ flow + edges */
86
+ .uix-flow {
87
+ position: relative; width: 100%;
88
+ color: var(--uix-border-strong); /* edges inherit via currentColor */
89
+ }
90
+ .uix-flow__edges {
91
+ position: absolute; inset: 0; width: 100%; height: 100%;
92
+ overflow: visible; pointer-events: none; /* never block node hover/focus */
93
+ }
94
+ .uix-flow__edge { fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; }
95
+ .uix-flow__edge--branch-yes { stroke: var(--uix-success); }
96
+ .uix-flow__edge--branch-no { stroke: var(--uix-danger); }
97
+ .uix-flow__edge--loop { stroke: var(--uix-accent); stroke-dasharray: 5 4; }
98
+ .uix-flow__arrow { fill: currentColor; }
99
+ .uix-flow__edge-label { fill: var(--uix-text-muted); font-family: var(--uix-font-sans); font-size: var(--uix-text-eyebrow); }
100
+ .uix-flow__edge-label--loop { fill: var(--uix-accent); }
101
+
102
+ /* hovering/focusing a diagram sets its edges "flowing" (marching dashes) to read direction */
103
+ @media (hover: hover) and (pointer: fine) {
104
+ .uix-flow:hover .uix-flow__edge,
105
+ .uix-flow:focus-within .uix-flow__edge {
106
+ stroke-dasharray: 5 4; animation: uix-flow-march var(--uix-dur-slow) linear infinite;
107
+ }
108
+ }
109
+
110
+ /* ---- linear: flex row of nodes + pure-CSS connectors (no SVG) ---- */
111
+ .uix-flow--linear .uix-flow__row { display: flex; align-items: center; flex-wrap: wrap; gap: var(--uix-space-1); }
112
+ .uix-flow__connector {
113
+ position: relative; flex: 1 1 30px; min-width: 30px; height: 0;
114
+ border-top: 1.5px solid var(--uix-border-strong); margin: 0 var(--uix-space-1);
115
+ }
116
+ .uix-flow__connector::after {
117
+ content: ""; position: absolute; right: -1px; top: 50%; width: 6px; height: 6px;
118
+ border-top: 1.5px solid var(--uix-border-strong); border-right: 1.5px solid var(--uix-border-strong);
119
+ transform: translate(0, -50%) rotate(45deg);
120
+ }
121
+ .uix-flow__connector[data-done] { border-color: var(--uix-success); }
122
+ .uix-flow__connector[data-done]::after { border-color: var(--uix-success); }
123
+
124
+ /* ---- branch / loop / mindmap: absolutely-positioned nodes over an SVG edge layer.
125
+ Container aspect-ratio matches each SVG viewBox so % node positions and path
126
+ coordinates scale together (uniform), keeping edges glued to nodes at any width. */
127
+ .uix-flow--branch, .uix-flow--loop { aspect-ratio: 5 / 2; }
128
+ .uix-flow--mindmap { aspect-ratio: 2 / 1; }
129
+ .uix-flow--branch .uix-node,
130
+ .uix-flow--loop .uix-node,
131
+ .uix-flow--mindmap .uix-node,
132
+ .uix-flow--canvas .uix-node { position: absolute; transform: translate(-50%, -50%); }
133
+
134
+ /* mindmap leaves sit tighter than default nodes */
135
+ .uix-flow--mindmap .uix-node { min-width: 0; }
136
+ .uix-flow--mindmap .uix-node--hub { min-width: 120px; }
137
+
138
+ /* ============================================================ builder canvas */
139
+ .uix-flow--canvas {
140
+ display: grid; grid-template-columns: 188px 1fr;
141
+ border: 1px solid var(--uix-border); border-radius: var(--uix-radius-lg);
142
+ overflow: hidden; background: var(--uix-surface); width: 100%;
143
+ }
144
+ .uix-flow__palette {
145
+ display: flex; flex-direction: column; gap: var(--uix-space-2); padding: var(--uix-space-4);
146
+ border-right: 1px solid var(--uix-border); background: var(--uix-surface);
147
+ }
148
+ .uix-flow__palette-title {
149
+ font-size: var(--uix-text-eyebrow); letter-spacing: var(--uix-tracking-eyebrow);
150
+ text-transform: uppercase; color: var(--uix-text-muted); margin-bottom: var(--uix-space-1);
151
+ }
152
+ .uix-flow__chip {
153
+ display: flex; align-items: center; gap: var(--uix-space-2); padding: var(--uix-space-2) var(--uix-space-3);
154
+ border: 1px solid var(--uix-border); border-radius: var(--uix-radius-md);
155
+ background: var(--uix-surface); color: var(--uix-text);
156
+ font-size: var(--uix-text-meta); cursor: grab; box-shadow: var(--uix-shadow-sm);
157
+ transition: box-shadow var(--uix-dur-fast) var(--uix-ease-out),
158
+ transform var(--uix-dur-fast) var(--uix-ease-out);
159
+ }
160
+ .uix-flow__chip svg { width: var(--uix-icon-sm); height: var(--uix-icon-sm); color: var(--uix-text-muted); flex: none; }
161
+ .uix-flow__chip:active { cursor: grabbing; }
162
+ @media (hover: hover) and (pointer: fine) {
163
+ .uix-flow__chip:hover { box-shadow: var(--uix-shadow-popover); transform: translateY(calc(-1 * var(--uix-lift))); }
164
+ }
165
+ /* the canvas: a dotted grid, free-placed nodes, one SVG edge layer */
166
+ .uix-flow__canvas {
167
+ position: relative; aspect-ratio: 16 / 9; min-height: 280px;
168
+ background-color: var(--uix-bg-subtle);
169
+ background-image: radial-gradient(var(--uix-border-strong) 1px, transparent 1px);
170
+ background-size: 22px 22px; background-position: -1px -1px;
171
+ }
172
+ .uix-flow--canvas .uix-node { cursor: grab; }
173
+ .uix-flow--canvas .uix-node:active { cursor: grabbing; }
174
+
175
+ /* selected node ring — mirrors the focus-ring construction (double box-shadow on --uix-ring) */
176
+ .uix-flow .uix-node[data-selected] {
177
+ border-color: var(--uix-ring);
178
+ box-shadow: 0 0 0 2px var(--uix-surface), 0 0 0 4px var(--uix-ring);
179
+ }
180
+ /* keyboard/click selection on focusable canvas pieces — no JS needed */
181
+ .uix-flow__chip:focus-visible,
182
+ .uix-flow--canvas .uix-node:focus-visible {
183
+ outline: none; border-color: var(--uix-ring);
184
+ box-shadow: 0 0 0 2px var(--uix-surface), 0 0 0 4px var(--uix-ring);
185
+ }
186
+
187
+ /* ============================================================ motion */
188
+ @keyframes uix-flow-spin { to { transform: rotate(360deg); } }
189
+ @keyframes uix-flow-march { to { stroke-dashoffset: -18; } }
190
+
191
+ @media (prefers-reduced-motion: reduce) {
192
+ .uix-node--running .uix-node__icon svg,
193
+ .uix-flow:hover .uix-flow__edge,
194
+ .uix-flow:focus-within .uix-flow__edge { animation: none; }
195
+ }
196
+ }
@@ -0,0 +1,14 @@
1
+ /* uix form layout — depends only on --uix-* tokens. */
2
+ @layer uix.components {
3
+ .uix-form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--uix-space-5); }
4
+ .uix-fieldset { border: 1px solid var(--uix-border); border-radius: var(--uix-radius-lg); padding: var(--uix-space-6); }
5
+ .uix-fieldset > legend { padding: 0 var(--uix-space-2); font-size: var(--uix-text-meta); font-weight: 600; color: var(--uix-text); }
6
+ .uix-form-inline { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--uix-space-4); }
7
+ .uix-validation-summary {
8
+ border: 1px solid var(--uix-danger); background: var(--uix-danger-bg); color: var(--uix-text);
9
+ border-radius: var(--uix-radius-md); padding: var(--uix-space-3) var(--uix-space-4); font-size: var(--uix-text-meta);
10
+ }
11
+ .uix-validation-summary strong { color: var(--uix-danger-text); }
12
+ .uix-validation-summary ul { margin: var(--uix-space-2) 0 0; padding-left: var(--uix-space-5); }
13
+ .uix-validation-summary a { color: var(--uix-danger-text); text-decoration: underline; }
14
+ }
@@ -0,0 +1,12 @@
1
+ /* uix heartbeat / live status indicator — a pulsing ping. Respects reduced-motion (guard stops the ping). */
2
+ @layer uix.components {
3
+ .uix-heartbeat { position: relative; display: inline-grid; place-items: center; width: 8px; height: 8px; flex: none; }
4
+ .uix-heartbeat__dot { width: 8px; height: 8px; border-radius: 50%; background: var(--uix-success); z-index: var(--uix-z-raised); }
5
+ .uix-heartbeat__ping { position: absolute; inset: 0; border-radius: 50%; background: var(--uix-success); animation: uix-ping 1.6s var(--uix-ease-out) infinite; }
6
+ @keyframes uix-ping { 0% { transform: scale(1); opacity: .55; } 100% { transform: scale(2.8); opacity: 0; } }
7
+ .uix-heartbeat--warning .uix-heartbeat__dot, .uix-heartbeat--warning .uix-heartbeat__ping { background: var(--uix-warning); }
8
+ .uix-heartbeat--danger .uix-heartbeat__dot, .uix-heartbeat--danger .uix-heartbeat__ping { background: var(--uix-danger); }
9
+ .uix-heartbeat--idle .uix-heartbeat__dot { background: var(--uix-text-muted); }
10
+ .uix-heartbeat--idle .uix-heartbeat__ping { display: none; }
11
+ .uix-live { 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); }
12
+ }
@@ -0,0 +1,13 @@
1
+ /* uix inbox master-detail — depends only on --uix-* tokens. */
2
+ @layer uix.components {
3
+ .uix-inbox { display: grid; grid-template-columns: 300px 1fr; border: 1px solid var(--uix-border); border-radius: var(--uix-radius-lg); overflow: hidden; height: 420px; }
4
+ .uix-inbox__list { border-right: 1px solid var(--uix-border); overflow-y: auto; background: var(--uix-surface); }
5
+ .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; }
6
+ .uix-inbox__item:hover { background: var(--uix-bg-hover); }
7
+ .uix-inbox__item[aria-selected="true"] { background: linear-gradient(to right, var(--uix-accent) 3px, var(--uix-brand-muted) 3px); }
8
+ .uix-inbox__item[data-unread] .uix-inbox__subject { font-weight: 600; }
9
+ .uix-inbox__subject { font-size: var(--uix-text-body); }
10
+ .uix-inbox__preview { font-size: var(--uix-text-meta); color: var(--uix-text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
11
+ .uix-inbox__detail { overflow-y: auto; padding: var(--uix-space-5); background: var(--uix-bg-app); }
12
+ @media (max-width: 700px) { .uix-inbox { grid-template-columns: 1fr; } .uix-inbox__detail { display: none; } }
13
+ }
@@ -0,0 +1,39 @@
1
+ /* uix input + field wrapper — depends only on --uix-* tokens. */
2
+ @layer uix.components {
3
+ .uix-field { display: flex; flex-direction: column; gap: var(--uix-space-2); }
4
+ .uix-field__label { font-size: var(--uix-text-meta); font-weight: 500; color: var(--uix-text); }
5
+ .uix-field__label[data-required]::after { content: " *"; color: var(--uix-danger-text); }
6
+ /* message slot for hint / error / success — reserves one line so an appearing error never
7
+ shifts the layout (UIX-FIX-04); the React <Field> always renders it. */
8
+ .uix-field__msg { font-size: var(--uix-text-meta); line-height: 1.45; min-height: 1.45em; }
9
+ .uix-field__hint { font-size: var(--uix-text-meta); color: var(--uix-text-muted); }
10
+ .uix-field__error { font-size: var(--uix-text-meta); color: var(--uix-danger-text); display: inline-flex; align-items: center; gap: var(--uix-space-2); }
11
+ .uix-field__error svg, .uix-field__success svg { width: 14px; height: 14px; flex: none; }
12
+ .uix-field__success { font-size: var(--uix-text-meta); color: var(--uix-success); display: inline-flex; align-items: center; gap: var(--uix-space-2); }
13
+
14
+ .uix-input {
15
+ height: var(--uix-control-h); width: 100%;
16
+ padding: 0 var(--uix-space-3); border: 1px solid var(--uix-border); border-radius: var(--uix-radius-md);
17
+ background: var(--uix-surface); color: var(--uix-text); font: inherit; font-size: var(--uix-text-body);
18
+ transition: border-color var(--uix-dur-fast) var(--uix-ease-out), box-shadow var(--uix-dur-fast) var(--uix-ease-out);
19
+ }
20
+ .uix-input::placeholder { color: var(--uix-text-muted); }
21
+ .uix-input:hover { border-color: var(--uix-border-strong); }
22
+ .uix-input:focus { outline: none; border-color: var(--uix-ring); box-shadow: 0 0 0 3px var(--uix-brand-muted); }
23
+ .uix-input:disabled { opacity: .55; cursor: not-allowed; background: var(--uix-bg-subtle); }
24
+ .uix-input[readonly] { background: var(--uix-bg-subtle); }
25
+ .uix-input[aria-invalid="true"] { border-color: var(--uix-danger); }
26
+ .uix-input[aria-invalid="true"]:focus { box-shadow: 0 0 0 3px var(--uix-danger-bg); }
27
+ .uix-input--sm { height: 28px; font-size: var(--uix-text-meta); }
28
+
29
+ /* leading/trailing adornments */
30
+ .uix-input-group { position: relative; display: flex; align-items: center; }
31
+ .uix-input-group__icon { position: absolute; left: 10px; color: var(--uix-text-muted); display: inline-flex; pointer-events: none; }
32
+ .uix-input-group__icon svg { width: var(--uix-icon-md); height: var(--uix-icon-md); }
33
+ .uix-input-group--has-leading .uix-input { padding-left: 38px; }
34
+ /* validation microinteractions */
35
+ .uix-input[data-valid] { border-color: var(--uix-success); }
36
+ .uix-input[data-valid]:focus { box-shadow: 0 0 0 3px var(--uix-success-bg); }
37
+ .uix-input-group--has-trailing .uix-input { padding-right: 38px; }
38
+ .uix-input-group__icon--trailing { left: auto; right: 10px; }
39
+ }
@@ -0,0 +1,14 @@
1
+ /* uix kanban board / column — depends only on --uix-* tokens. */
2
+ @layer uix.components {
3
+ .uix-kanban { display: flex; gap: var(--uix-space-4); overflow-x: auto; padding-bottom: var(--uix-space-2); }
4
+ .uix-kanban__col { flex: 0 0 260px; background: var(--uix-bg-subtle); border: 1px solid var(--uix-border); border-radius: var(--uix-radius-lg); display: flex; flex-direction: column; max-height: 460px; }
5
+ .uix-kanban__head { display: flex; align-items: center; gap: var(--uix-space-2); padding: var(--uix-space-3) var(--uix-space-4); font-weight: 600; font-size: var(--uix-text-meta); }
6
+ .uix-kanban__count { margin-left: auto; color: var(--uix-text-muted); font-weight: 500; }
7
+ .uix-kanban__body { padding: 0 var(--uix-space-3) var(--uix-space-3); display: flex; flex-direction: column; gap: var(--uix-space-2); overflow-y: auto; }
8
+ .uix-kanban__card { background: var(--uix-surface); border: 1px solid var(--uix-border); border-radius: var(--uix-radius-md); padding: var(--uix-space-3); box-shadow: var(--uix-shadow-sm); cursor: grab; transition: box-shadow var(--uix-dur-fast) var(--uix-ease-out), transform var(--uix-dur-fast) var(--uix-ease-out); }
9
+ .uix-kanban__card:hover { box-shadow: var(--uix-shadow-popover); }
10
+ @media (hover: hover) and (pointer: fine) { .uix-kanban__card:hover { transform: translateY(calc(-1 * var(--uix-lift))); } }
11
+ .uix-kanban__card:active { cursor: grabbing; }
12
+ .uix-kanban__card-title { font-weight: 500; font-size: var(--uix-text-body); margin-bottom: var(--uix-space-2); }
13
+ .uix-kanban__card-meta { display: flex; align-items: center; gap: var(--uix-space-2); }
14
+ }
@@ -0,0 +1,8 @@
1
+ /* uix keyboard-shortcut chip — depends only on --uix-* tokens. */
2
+ @layer uix.components {
3
+ .uix-kbd {
4
+ display: inline-flex; align-items: center; justify-content: center; min-width: 18px; height: 18px; padding: 0 var(--uix-space-2);
5
+ font-family: var(--uix-font-mono); font-size: var(--uix-text-eyebrow); color: var(--uix-text-muted);
6
+ background: var(--uix-bg-subtle); border: 1px solid var(--uix-border); border-bottom-width: 2px; border-radius: var(--uix-radius-xs);
7
+ }
8
+ }
@@ -0,0 +1,13 @@
1
+ /* uix label / tag taxonomy — colored via --label-color (set to a --uix-chart-* token). */
2
+ @layer uix.components {
3
+ .uix-label {
4
+ display: inline-flex; align-items: center; gap: var(--uix-space-2); padding: 1px var(--uix-space-2); border-radius: var(--uix-radius-sm);
5
+ font-size: var(--uix-text-meta); font-weight: 500;
6
+ background: color-mix(in srgb, var(--label-color, var(--uix-accent)) 16%, transparent);
7
+ /* Pull the hue toward the theme foreground so the text clears WCAG AA on its own 16% tint.
8
+ Raw chart hues (esp. amber #F59E0B at 1.9:1) are tuned for fills, not text-on-tint; the dot
9
+ keeps the full hue. --uix-text flips per theme, so this darkens on light and lightens on dark. */
10
+ color: color-mix(in srgb, var(--label-color, var(--uix-accent)) 55%, var(--uix-text));
11
+ }
12
+ .uix-label__dot { width: 7px; height: 7px; border-radius: 50%; background: var(--label-color, var(--uix-accent)); }
13
+ }
@@ -0,0 +1,8 @@
1
+ @layer uix.components {
2
+ .uix-license-position { display:grid; gap:var(--uix-space-2); color:var(--uix-text); }
3
+ .uix-license-position__header { display:flex; align-items:center; justify-content:space-between; gap:var(--uix-space-3); }
4
+ .uix-license-position__value { font-variant-numeric:tabular-nums; font-weight:600; }
5
+ .uix-license-position__track { position:relative; padding-bottom:var(--uix-space-2); }
6
+ .uix-license-position__overflow { position:absolute; top:100%; right:0; height:var(--uix-space-2); border-radius:var(--uix-radius-pill); background:var(--uix-danger-solid); }
7
+ .uix-license-position--over .uix-meter { outline:2px solid var(--uix-danger); outline-offset:2px; }
8
+ }
@@ -0,0 +1,13 @@
1
+ /* uix image lightbox — native <dialog>, click a thumbnail to enlarge. Depends only on --uix-* tokens. */
2
+ @layer uix.components {
3
+ /* margin:auto centers the modal <dialog> in the viewport. Set explicitly (not
4
+ left to the UA default) so centering is robust regardless of any consumer
5
+ reset — base.css scopes its margin reset to typographic/form elements and
6
+ deliberately leaves <dialog> alone. Matches .uix-dialog. */
7
+ .uix-lightbox { margin: auto; border: 0; background: transparent; padding: 0; max-width: 92vw; max-height: 92vh; box-shadow: var(--uix-shadow-overlay); overflow: visible; }
8
+ /* A definite width is required: an SVG with a viewBox but no intrinsic width/height collapses to
9
+ 0×0 under width:auto, which then shrink-wraps the fit-content <dialog> to nothing (nothing shows
10
+ on open). min() keeps it within the viewport; height:auto preserves the aspect ratio. */
11
+ .uix-lightbox img { display: block; width: min(720px, 92vw); height: auto; max-height: 92vh; border-radius: var(--uix-radius-md); }
12
+ .uix-lightbox::backdrop { background: var(--uix-scrim-strong); }
13
+ }