@dumiflex/wp-kit 0.0.0-stage → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/LICENSE +674 -0
  3. package/README.md +76 -3
  4. package/package.json +77 -6
  5. package/src/Avatar.vue +83 -0
  6. package/src/Badge.vue +97 -0
  7. package/src/Banner.vue +118 -0
  8. package/src/BookmarkButton.vue +27 -0
  9. package/src/BundleMeta.vue +51 -0
  10. package/src/Button.vue +103 -0
  11. package/src/Card.vue +68 -0
  12. package/src/Checkbox.vue +107 -0
  13. package/src/Chip.vue +97 -0
  14. package/src/ChipToggle.vue +92 -0
  15. package/src/ChoiceCards.vue +133 -0
  16. package/src/CloseButton.vue +69 -0
  17. package/src/CodeBlock.vue +119 -0
  18. package/src/ColorField.vue +206 -0
  19. package/src/ColorPicker.vue +201 -0
  20. package/src/Combobox.vue +334 -0
  21. package/src/ConfirmDialog.vue +163 -0
  22. package/src/ConfirmModal.vue +147 -0
  23. package/src/ConstraintMatrixPreview.vue +708 -0
  24. package/src/ContextMenu.vue +379 -0
  25. package/src/CopyButton.vue +156 -0
  26. package/src/DataTable.vue +292 -0
  27. package/src/DatePicker.vue +234 -0
  28. package/src/DescriptionList.vue +73 -0
  29. package/src/DiffView.vue +68 -0
  30. package/src/Disclosure.vue +166 -0
  31. package/src/DragHandle.vue +49 -0
  32. package/src/Drawer.vue +131 -0
  33. package/src/DropZone.vue +196 -0
  34. package/src/DropdownMenu.vue +72 -0
  35. package/src/EmptyState.vue +111 -0
  36. package/src/Field.vue +28 -0
  37. package/src/HsvPicker.vue +208 -0
  38. package/src/Icon.vue +39 -0
  39. package/src/IconPicker.vue +209 -0
  40. package/src/ImageGrid.vue +125 -0
  41. package/src/InlineEdit.vue +183 -0
  42. package/src/Input.vue +99 -0
  43. package/src/Kbd.vue +56 -0
  44. package/src/KindChip.vue +53 -0
  45. package/src/Lightbox.vue +173 -0
  46. package/src/ListFilter.vue +85 -0
  47. package/src/ListRow.vue +204 -0
  48. package/src/LoadingMark.vue +161 -0
  49. package/src/Logo.vue +60 -0
  50. package/src/Modal.vue +76 -0
  51. package/src/ModalShell.vue +107 -0
  52. package/src/Pagination.vue +106 -0
  53. package/src/Popover.vue +171 -0
  54. package/src/PostCard.vue +211 -0
  55. package/src/ProgressBar.vue +90 -0
  56. package/src/RadioGroup.vue +177 -0
  57. package/src/RangeSlider.vue +183 -0
  58. package/src/RatingBadge.vue +42 -0
  59. package/src/RelativeDate.vue +35 -0
  60. package/src/ResizeHandle.vue +143 -0
  61. package/src/SearchInput.vue +199 -0
  62. package/src/Select.vue +641 -0
  63. package/src/Separator.vue +54 -0
  64. package/src/Skeleton.vue +82 -0
  65. package/src/Slider.vue +198 -0
  66. package/src/SortableList.vue +260 -0
  67. package/src/SplitPane.vue +68 -0
  68. package/src/StarButton.vue +40 -0
  69. package/src/Stepper.vue +141 -0
  70. package/src/SupportLinks.vue +93 -0
  71. package/src/TagInput.vue +300 -0
  72. package/src/Textarea.vue +57 -0
  73. package/src/Timeline.vue +92 -0
  74. package/src/ToastCard.vue +119 -0
  75. package/src/ToastHost.vue +40 -0
  76. package/src/Toggle.vue +36 -0
  77. package/src/TokenizedValue.vue +310 -0
  78. package/src/Toolbar.vue +110 -0
  79. package/src/VirtualList.vue +87 -0
  80. package/src/VisuallyHidden.vue +29 -0
  81. package/src/WpButton.vue +75 -0
  82. package/src/WpCheck.vue +102 -0
  83. package/src/WpIconButton.vue +107 -0
  84. package/src/WpImageZoom.vue +544 -0
  85. package/src/WpNumber.vue +183 -0
  86. package/src/WpSegmented.vue +175 -0
  87. package/src/WpSelect.vue +89 -0
  88. package/src/WpSwitch.vue +163 -0
  89. package/src/WpTabs.vue +188 -0
  90. package/src/_modal-motion.css +33 -0
  91. package/src/_skeleton.css +50 -0
  92. package/src/axis-color.ts +42 -0
  93. package/src/button.css +169 -0
  94. package/src/calendar.ts +59 -0
  95. package/src/clipboard.ts +50 -0
  96. package/src/colour-presets.ts +12 -0
  97. package/src/diff.ts +51 -0
  98. package/src/drop-zone.ts +41 -0
  99. package/src/flip.ts +237 -0
  100. package/src/floating.ts +99 -0
  101. package/src/hsv.ts +100 -0
  102. package/src/icon-catalog.ts +52 -0
  103. package/src/image-zoom.ts +93 -0
  104. package/src/logo-paths.ts +21 -0
  105. package/src/matrix-axis.ts +91 -0
  106. package/src/pagination.ts +27 -0
  107. package/src/platform-keys.ts +29 -0
  108. package/src/rich-tokenize.ts +357 -0
  109. package/src/select-types.ts +32 -0
  110. package/src/slider-math.ts +45 -0
  111. package/src/sortable.ts +22 -0
  112. package/src/theme/fonts/OFL-Fraunces.txt +93 -0
  113. package/src/theme/fonts/OFL-JetBrainsMono.txt +93 -0
  114. package/src/theme/fonts/OFL-Manrope.txt +93 -0
  115. package/src/theme/fonts/fraunces-latin-wght-normal.woff2 +0 -0
  116. package/src/theme/fonts/jetbrains-mono-latin.woff2 +0 -0
  117. package/src/theme/fonts/manrope-latin-wght-normal.woff2 +0 -0
  118. package/src/theme/looks.css +428 -0
  119. package/src/theme/palettes.css +254 -0
  120. package/src/theme/tokens.css +2894 -0
  121. package/src/tokens.ts +56 -0
  122. package/src/tooltip.css +43 -0
  123. package/src/tooltip.ts +146 -0
  124. package/src/useDialogFocus.ts +73 -0
  125. package/src/useGrowableField.ts +357 -0
  126. package/src/useModalKeyShield.ts +116 -0
  127. package/src/useToast.ts +48 -0
  128. package/src/wp-logo.svg +14 -0
@@ -0,0 +1,428 @@
1
+ /* =========================================================
2
+ Looks — `data-wp-look` on <html> (tweaksStore.setLook).
3
+
4
+ A look is everything that is not colour: corner radius, type, borders vs
5
+ shadows, density and how a selected state is drawn. Any look works with
6
+ any colour theme (styles/themes.css), because these rules only read
7
+ colour tokens and never set one. Orbit is tokens.css itself.
8
+
9
+ Most of a look is the radius / font / height tokens. The rest is a few rules
10
+ per look on the shared pieces (buttons, inputs, cards, chips, nav,
11
+ segmented, tabs, checkboxes, tables). `html[data-wp-look=x] .wp-btn` (0,2,1)
12
+ beats a scoped `.wp-btn[data-v-…]` (0,2,0), so no component has to know
13
+ about looks. A new shared piece that should follow the looks gets its
14
+ rule here.
15
+
16
+ Fonts: Manrope (Soft) and Fraunces (Editorial headings) are OFL variable
17
+ latin subsets from Fontsource (licences beside them in fonts/). A browser
18
+ only downloads an @font-face when a rendered element uses its family, so a
19
+ look's font costs nothing until that look is picked.
20
+ ========================================================= */
21
+
22
+ @font-face {
23
+ font-family: "Manrope";
24
+ font-style: normal;
25
+ font-weight: 200 800;
26
+ font-display: swap;
27
+ src: url("./fonts/manrope-latin-wght-normal.woff2") format("woff2-variations"),
28
+ url("./fonts/manrope-latin-wght-normal.woff2") format("woff2");
29
+ }
30
+ @font-face {
31
+ font-family: "Fraunces";
32
+ font-style: normal;
33
+ font-weight: 100 900;
34
+ font-display: swap;
35
+ src: url("./fonts/fraunces-latin-wght-normal.woff2") format("woff2-variations"),
36
+ url("./fonts/fraunces-latin-wght-normal.woff2") format("woff2");
37
+ }
38
+ @font-face {
39
+ font-family: "JetBrains Mono";
40
+ font-style: normal;
41
+ font-weight: 100 900;
42
+ font-display: swap;
43
+ src: url("./fonts/jetbrains-mono-latin.woff2") format("woff2-variations"),
44
+ url("./fonts/jetbrains-mono-latin.woff2") format("woff2");
45
+ }
46
+
47
+ /* --wp-radius-cap: the roundest a corner may get in this look. Fixed radii
48
+ in components are written min(Npx, var(--wp-radius-cap, 999px)) and
49
+ pills var(--wp-radius-cap, 999px), so Orbit draws them as authored and a
50
+ square look squares them without a rule per component. Circles (50%)
51
+ stay circles. The theme audit (scripts/theme-audit) fails on a corner
52
+ rounder than the cap. */
53
+ html[data-wp-look="crisp"] { --wp-radius-cap: 4px; }
54
+ html[data-wp-look="terminal"],
55
+ html[data-wp-look="tui"] { --wp-radius-cap: 0px; }
56
+
57
+ /* Heading face; a look may swap it without touching body text. */
58
+ html.wp-manager { --wp-font-head: var(--wp-font); }
59
+ .wp-page__title, .wp-card__title { font-family: var(--wp-font-head); }
60
+
61
+ /* ================= Crisp: square, outlined, ruled ================= */
62
+ html[data-wp-look="crisp"] {
63
+ --wp-radius-sm: 2px;
64
+ --wp-radius: 3px;
65
+ --wp-radius-lg: 4px;
66
+ --wp-radius-xl: 4px;
67
+ }
68
+ html[data-wp-look="crisp"] :is(.wp-btn, .wp-btn--sm, .wp-btn--lg, .wp-nav, .wp-chip, .wp-check, .wp-topbar__icon-btn) { border-radius: 2px; }
69
+ html[data-wp-look="crisp"] .wp-btn--secondary { background: transparent; border-color: var(--wp-border-strong); }
70
+ html[data-wp-look="crisp"] .wp-btn--secondary:hover { background: var(--wp-bg-3); }
71
+ html[data-wp-look="crisp"] :is(.wp-input, .wp-select, .wp-textarea, .wp-input-group, .wp-cselect__field) { border-color: var(--wp-border-strong); }
72
+ html[data-wp-look="crisp"] :is(.wp-card, .wp-table-wrap) { border-color: var(--wp-border-strong); }
73
+ html[data-wp-look="crisp"] .wp-chip { background: transparent; }
74
+ html[data-wp-look="crisp"] .wp-nav[data-active] {
75
+ background: transparent;
76
+ border-color: var(--wp-accent-500);
77
+ font-weight: 600;
78
+ }
79
+ html[data-wp-look="crisp"] .wp-nav[data-active]::before { display: none; }
80
+ html[data-wp-look="crisp"] .wp-settings__section-link[data-active="true"] {
81
+ background: transparent;
82
+ box-shadow: inset 0 0 0 1px var(--wp-accent-500);
83
+ }
84
+ html[data-wp-look="crisp"] .wp-segmented { border-color: var(--wp-border-strong); background: transparent; }
85
+ html[data-wp-look="crisp"] .wp-segmented__opt { border-radius: 1px; }
86
+ html[data-wp-look="crisp"] .wp-segmented__opt[data-active="true"] {
87
+ background: color-mix(in oklab, var(--wp-accent-500) 16%, transparent);
88
+ box-shadow: inset 0 0 0 1px var(--wp-accent-500);
89
+ color: var(--wp-accent-text);
90
+ }
91
+ html[data-wp-look="crisp"] :is(.wp-table thead th, .wp-sidebar__section, .wp-field__label) {
92
+ font-family: var(--wp-font-mono);
93
+ letter-spacing: 0;
94
+ }
95
+ html[data-wp-look="crisp"] .wp-page__title { font-size: 18px; font-weight: 700; letter-spacing: 0; }
96
+
97
+ /* ================= Soft: pills, no outlines, lifted cards ================= */
98
+ html[data-wp-look="soft"] {
99
+ --wp-font: "Manrope", "Inter", ui-sans-serif, system-ui, sans-serif;
100
+ --wp-radius-sm: 10px;
101
+ --wp-radius: 14px;
102
+ --wp-radius-lg: 18px;
103
+ --wp-radius-xl: 22px;
104
+ }
105
+ html[data-wp-look="soft"] :is(.wp-btn, .wp-btn--sm, .wp-btn--lg) { border-radius: 999px; padding-inline: 16px; }
106
+ html[data-wp-look="soft"] .wp-btn--icon { padding-inline: 0; }
107
+ html[data-wp-look="soft"] .wp-btn--secondary { border-color: transparent; }
108
+ html[data-wp-look="soft"] .wp-btn--primary {
109
+ box-shadow: 0 4px 14px color-mix(in oklab, var(--wp-accent-600) 35%, transparent);
110
+ }
111
+ html[data-wp-look="soft"] :is(.wp-input, .wp-select, .wp-textarea, .wp-input-group, .wp-cselect__field) {
112
+ border-color: transparent;
113
+ background: var(--wp-bg-3);
114
+ }
115
+ html[data-wp-look="soft"] .wp-input-group .wp-input { background: transparent; }
116
+ html[data-wp-look="soft"] :is(.wp-card, .wp-table-wrap) {
117
+ border-color: transparent;
118
+ box-shadow: var(--wp-shadow-md);
119
+ }
120
+ html[data-wp-look="soft"] :is(.wp-topbar, .wp-sidebar) { border-color: transparent; background: var(--wp-bg); }
121
+ html[data-wp-look="soft"] .wp-chip { border-color: transparent; }
122
+ html[data-wp-look="soft"] .wp-nav { border-radius: 999px; padding-inline: 14px; }
123
+ html[data-wp-look="soft"] .wp-nav[data-active] {
124
+ background: var(--wp-accent-600);
125
+ border-color: transparent;
126
+ color: #fff; /* audit-exempt: white on accent-600, 4.5:1+ in every theme */
127
+ }
128
+ html[data-wp-look="soft"] .wp-nav[data-active]::before { display: none; }
129
+ html[data-wp-look="soft"] .wp-settings__section-link { border-radius: 999px; padding-inline: 14px; }
130
+ html[data-wp-look="soft"] .wp-settings__section-link[data-active="true"] {
131
+ background: var(--wp-accent-600);
132
+ color: #fff; /* audit-exempt: white on accent-600 */
133
+ }
134
+ html[data-wp-look="soft"] .wp-segmented { border-color: transparent; border-radius: 999px; background: var(--wp-bg-3); }
135
+ html[data-wp-look="soft"] .wp-segmented__opt { border-radius: 999px; }
136
+ html[data-wp-look="soft"] .wp-segmented__opt[data-active="true"] {
137
+ background: var(--wp-accent-600);
138
+ box-shadow: none;
139
+ color: #fff; /* audit-exempt: white on accent-600 */
140
+ }
141
+ html[data-wp-look="soft"] .wp-segmented__opt[data-active="true"] .pi { color: inherit; }
142
+ html[data-wp-look="soft"] .wp-check { border-radius: 6px; }
143
+ html[data-wp-look="soft"] .wp-page__title { font-size: 22px; font-weight: 700; }
144
+
145
+ /* ================= Terminal: mono, zero radius, dashed ================= */
146
+ html[data-wp-look="terminal"] {
147
+ --wp-font: var(--wp-font-mono);
148
+ --wp-radius-sm: 0px;
149
+ --wp-radius: 0px;
150
+ --wp-radius-lg: 0px;
151
+ --wp-radius-xl: 0px;
152
+ }
153
+ html[data-wp-look="terminal"] body { font-size: 12.5px; }
154
+ html[data-wp-look="terminal"] :is(.wp-btn, .wp-btn--sm, .wp-btn--lg, .wp-nav, .wp-chip, .wp-check, .wp-segmented, .wp-segmented__opt, .wp-topbar__icon-btn, .wp-nav__count) { border-radius: 0; }
155
+ html[data-wp-look="terminal"] :is(.wp-card, .wp-table-wrap, .wp-input-group--readonly) { border-style: dashed; border-color: var(--wp-border-strong); }
156
+ html[data-wp-look="terminal"] .wp-card__header { border-bottom-style: dashed; }
157
+ html[data-wp-look="terminal"] .wp-table tbody tr:not(:last-child) td { border-bottom-style: dashed; }
158
+ html[data-wp-look="terminal"] .wp-topbar { border-bottom-style: dashed; }
159
+ html[data-wp-look="terminal"] .wp-sidebar { border-right-style: dashed; }
160
+ html[data-wp-look="terminal"] .wp-btn--primary {
161
+ background: color-mix(in oklab, var(--wp-accent-500) 14%, transparent);
162
+ border-color: var(--wp-accent-text);
163
+ color: var(--wp-accent-text);
164
+ }
165
+ html[data-wp-look="terminal"] .wp-btn--primary:hover {
166
+ background: color-mix(in oklab, var(--wp-accent-500) 24%, transparent);
167
+ border-color: var(--wp-accent-text-strong);
168
+ }
169
+ html[data-wp-look="terminal"] .wp-btn--secondary { background: transparent; border-color: var(--wp-border-strong); }
170
+ html[data-wp-look="terminal"] .wp-chip { background: transparent; }
171
+ html[data-wp-look="terminal"] .wp-nav[data-active] {
172
+ background: transparent;
173
+ border-color: transparent;
174
+ color: var(--wp-accent-text);
175
+ font-weight: 600;
176
+ }
177
+ html[data-wp-look="terminal"] .wp-nav[data-active]::before {
178
+ content: ">";
179
+ width: auto;
180
+ top: 50%;
181
+ bottom: auto;
182
+ left: 0;
183
+ transform: translateY(-50%);
184
+ background: none;
185
+ color: var(--wp-accent-text);
186
+ font-weight: 700;
187
+ }
188
+ html[data-wp-look="terminal"] .wp-sidebar__section { text-transform: none; letter-spacing: 0; }
189
+ html[data-wp-look="terminal"] .wp-sidebar__section::before { content: "# "; }
190
+ html[data-wp-look="terminal"] .wp-settings__section-link[data-active="true"] { background: transparent; }
191
+ html[data-wp-look="terminal"] .wp-settings__section-link[data-active="true"]::before { content: ">"; margin-right: -4px; font-weight: 700; }
192
+ html[data-wp-look="terminal"] .wp-segmented { border-color: transparent; background: transparent; gap: 4px; }
193
+ html[data-wp-look="terminal"] .wp-segmented__opt[data-active="true"] {
194
+ background: transparent;
195
+ box-shadow: inset 0 0 0 1px var(--wp-accent-text);
196
+ color: var(--wp-accent-text);
197
+ }
198
+ html[data-wp-look="terminal"] .wp-tabset__tab[data-active="true"] { border-bottom-style: dashed; }
199
+ /* A switch that is on reads like the outlined primary button: a tinted
200
+ track ruled in accent text, not a solid fill. The knob squares with the
201
+ track through --wp-radius-cap. */
202
+ html[data-wp-look="terminal"] .wp-switch[aria-checked="true"] .wp-switch__track {
203
+ background: color-mix(in oklab, var(--wp-accent-500) 14%, transparent);
204
+ border-color: var(--wp-accent-text);
205
+ }
206
+ html[data-wp-look="terminal"] .wp-switch[aria-checked="true"] .wp-switch__knob { background: var(--wp-accent-text); }
207
+ html[data-wp-look="terminal"] .wp-page__title { font-size: 17px; font-weight: 600; letter-spacing: 0; }
208
+
209
+ /* ================= Editorial: serif headings, open, underlined ================= */
210
+ html[data-wp-look="editorial"] {
211
+ --wp-font-head: "Fraunces", Georgia, "Times New Roman", serif;
212
+ --wp-radius-sm: 4px;
213
+ --wp-radius: 4px;
214
+ --wp-radius-lg: 6px;
215
+ }
216
+ html[data-wp-look="editorial"] .wp-page__title { font-size: 28px; line-height: 1.2; font-weight: 500; letter-spacing: -0.01em; }
217
+ html[data-wp-look="editorial"] .wp-card__title { font-size: 16px; font-weight: 500; letter-spacing: 0; }
218
+ html[data-wp-look="editorial"] .wp-content { padding-inline: 36px; --wp-content-px: 36px; }
219
+ html[data-wp-look="editorial"] :is(.wp-topbar, .wp-sidebar) { background: var(--wp-bg); }
220
+ html[data-wp-look="editorial"] .wp-card {
221
+ background: transparent;
222
+ border: 0;
223
+ border-top: 1px solid var(--wp-text);
224
+ border-radius: 0;
225
+ }
226
+ html[data-wp-look="editorial"] .wp-card__header { padding-inline: 0; }
227
+ html[data-wp-look="editorial"] .wp-card__body { padding-inline: 0; }
228
+ html[data-wp-look="editorial"] .wp-table-wrap { background: transparent; border: 0; border-radius: 0; }
229
+ html[data-wp-look="editorial"] .wp-table thead th {
230
+ background: transparent;
231
+ border-bottom-color: var(--wp-text);
232
+ text-transform: none;
233
+ letter-spacing: 0;
234
+ font-size: 12px;
235
+ }
236
+ html[data-wp-look="editorial"] .wp-nav[data-active] { background: transparent; border-color: transparent; font-weight: 600; }
237
+ html[data-wp-look="editorial"] .wp-nav[data-active]::before { display: none; }
238
+ html[data-wp-look="editorial"] .wp-settings__section-link[data-active="true"] {
239
+ background: transparent;
240
+ color: var(--wp-text);
241
+ text-decoration: underline;
242
+ text-decoration-color: var(--wp-accent-500);
243
+ text-decoration-thickness: 2px;
244
+ text-underline-offset: 5px;
245
+ }
246
+ html[data-wp-look="editorial"] .wp-nav[data-active] .wp-nav__label {
247
+ text-decoration: underline;
248
+ text-decoration-color: var(--wp-accent-500);
249
+ text-decoration-thickness: 2px;
250
+ text-underline-offset: 5px;
251
+ }
252
+ html[data-wp-look="editorial"] .wp-btn--secondary { background: transparent; border-color: transparent; text-decoration: underline; text-underline-offset: 3px; }
253
+ html[data-wp-look="editorial"] .wp-btn--secondary:hover { background: var(--wp-bg-3); }
254
+ html[data-wp-look="editorial"] .wp-segmented { background: transparent; border: 0; border-radius: 0; gap: 14px; padding-inline: 0; box-shadow: inset 0 -1px 0 var(--wp-border); }
255
+ html[data-wp-look="editorial"] .wp-segmented__opt { padding-inline: 0; border-radius: 0; }
256
+ html[data-wp-look="editorial"] .wp-segmented__opt:hover:not(:disabled) { background: transparent; }
257
+ html[data-wp-look="editorial"] .wp-segmented__opt[data-active="true"] {
258
+ background: transparent;
259
+ box-shadow: inset 0 -2px 0 var(--wp-accent-500);
260
+ }
261
+ html[data-wp-look="editorial"] .wp-sidebar__section { text-transform: none; letter-spacing: 0; font-size: 11px; font-style: italic; }
262
+
263
+ /* ================= Compact: tight rows, small type ================= */
264
+ html[data-wp-look="compact"] {
265
+ --wp-radius-sm: 3px;
266
+ --wp-radius: 4px;
267
+ --wp-radius-lg: 5px;
268
+ --wp-radius-xl: 6px;
269
+ --wp-control-h-md-base: 28px;
270
+ --wp-control-h-lg-base: 32px;
271
+ --wp-topbar-h: 40px;
272
+ }
273
+ html[data-wp-look="compact"] body { font-size: 12.5px; }
274
+ html[data-wp-look="compact"] :is(.wp-btn, .wp-nav, .wp-topbar__icon-btn) { border-radius: 4px; }
275
+ html[data-wp-look="compact"] .wp-btn { font-size: 12px; padding-inline: 10px; }
276
+ html[data-wp-look="compact"] .wp-btn--icon { padding-inline: 0; }
277
+ html[data-wp-look="compact"] .wp-nav { padding: 5px 8px; font-size: 12.5px; }
278
+ html[data-wp-look="compact"] .wp-content { padding: 12px 16px 28px; --wp-content-px: 16px; }
279
+ html[data-wp-look="compact"] .wp-page__title { font-size: 16px; }
280
+ html[data-wp-look="compact"] .wp-card__header { padding: 8px 10px; }
281
+ html[data-wp-look="compact"] .wp-card__body { padding: 10px; }
282
+ html[data-wp-look="compact"] .wp-table thead th { padding: 6px 10px; }
283
+ html[data-wp-look="compact"] .wp-table tbody td { padding: 5px 10px; font-size: 12px; }
284
+ html[data-wp-look="compact"] .wp-table tbody tr:nth-child(even) td { background: var(--wp-bg-2); }
285
+ html[data-wp-look="compact"] .wp-table tbody tr:hover td { background: var(--wp-bg-3); }
286
+
287
+ /* ================= TUI: boxed panels, inverse selection, [x] ================= */
288
+ html[data-wp-look="tui"] {
289
+ --wp-font: var(--wp-font-mono);
290
+ --wp-radius-sm: 0px;
291
+ --wp-radius: 0px;
292
+ --wp-radius-lg: 0px;
293
+ --wp-radius-xl: 0px;
294
+ --wp-topbar-h: 40px;
295
+ }
296
+ html[data-wp-look="tui"] body { font-size: 12.5px; }
297
+ html[data-wp-look="tui"] :is(.wp-btn, .wp-btn--sm, .wp-btn--lg, .wp-nav, .wp-chip, .wp-segmented, .wp-segmented__opt, .wp-topbar__icon-btn, .wp-nav__count, .wp-tabset__tab) { border-radius: 0; }
298
+ html[data-wp-look="tui"] .wp-topbar { background: var(--wp-bg-3); border-bottom-color: var(--wp-border-strong); }
299
+ html[data-wp-look="tui"] .wp-sidebar {
300
+ margin: 8px 0 8px 8px;
301
+ border: 1px solid var(--wp-border-strong);
302
+ background: transparent;
303
+ }
304
+ html[data-wp-look="tui"] :is(.wp-card, .wp-table-wrap) { border-color: var(--wp-border-strong); background: transparent; }
305
+ html[data-wp-look="tui"] .wp-card__header { background: var(--wp-bg-3); border-bottom-color: var(--wp-border-strong); padding-block: 6px; }
306
+ html[data-wp-look="tui"] .wp-card__title { color: var(--wp-accent-text); font-weight: 700; }
307
+ html[data-wp-look="tui"] .wp-table thead th { background: var(--wp-bg-3); border-bottom-color: var(--wp-border-strong); text-transform: none; letter-spacing: 0; }
308
+ html[data-wp-look="tui"] .wp-table tbody td { border-bottom: 0; padding-block: 5px; }
309
+ html[data-wp-look="tui"] .wp-table tbody tr:hover td { background: var(--wp-bg-3); }
310
+ html[data-wp-look="tui"] .wp-nav { padding-block: 4px; }
311
+ html[data-wp-look="tui"] .wp-nav[data-active],
312
+ html[data-wp-look="tui"] .wp-segmented__opt[data-active="true"],
313
+ html[data-wp-look="tui"] .wp-tabset__tab[data-active="true"],
314
+ html[data-wp-look="tui"] .wp-settings__section-link[data-active="true"],
315
+ html[data-wp-look="tui"] .wp-trr__row[data-active="true"],
316
+ html[data-wp-look="tui"] .wp-pack__steps li[data-on] {
317
+ background: var(--wp-accent-600);
318
+ border-color: transparent;
319
+ box-shadow: none;
320
+ color: #fff; /* audit-exempt: white on accent-600, 4.5:1+ in every theme */
321
+ }
322
+ html[data-wp-look="tui"] :is(.wp-nav[data-active], .wp-segmented__opt[data-active="true"], .wp-tabset__tab[data-active="true"], .wp-settings__section-link[data-active="true"], .wp-trr__row[data-active="true"], .wp-pack__steps li[data-on]) :is(.pi, *) { color: inherit; }
323
+ html[data-wp-look="tui"] .wp-nav[data-active]::before { display: none; }
324
+ /* A count on an inverse tab or nav row reads on the accent fill, not as an
325
+ accent chip on it (3:1 before). */
326
+ html[data-wp-look="tui"] :is(.wp-tabset__tab[data-active="true"] .wp-tabset__count, .wp-nav[data-active] .wp-nav__count) {
327
+ background: color-mix(in oklab, #fff 18%, transparent); /* audit-exempt: lightens the accent fill under white text */
328
+ color: inherit;
329
+ }
330
+ html[data-wp-look="tui"] .wp-sidebar__section { text-transform: none; letter-spacing: 0; color: var(--wp-accent-text); }
331
+ html[data-wp-look="tui"] .wp-segmented { border-color: transparent; background: transparent; gap: 6px; }
332
+ html[data-wp-look="tui"] .wp-tabset__tab { padding-inline: 8px; }
333
+ /* Buttons read [ Save ]; an icon-only or link button stays as it is. */
334
+ html[data-wp-look="tui"] .wp-btn { border-color: transparent; }
335
+ html[data-wp-look="tui"] .wp-btn--secondary { background: transparent; }
336
+ html[data-wp-look="tui"] .wp-btn--secondary:hover { background: var(--wp-bg-3); }
337
+ html[data-wp-look="tui"] .wp-btn:not(.wp-btn--icon, .wp-btn--link) .wp-btn__label::before { content: "[ "; }
338
+ html[data-wp-look="tui"] .wp-btn:not(.wp-btn--icon, .wp-btn--link) .wp-btn__label::after { content: " ]"; }
339
+ html[data-wp-look="tui"] :is(.wp-input, .wp-select, .wp-textarea, .wp-input-group, .wp-cselect__field) {
340
+ border-color: var(--wp-border-strong);
341
+ background: var(--wp-bg);
342
+ }
343
+ html[data-wp-look="tui"] .wp-input-group .wp-input { background: transparent; }
344
+ /* Checkboxes read [ ] / [x]; the drawn tick hides. */
345
+ html[data-wp-look="tui"] .wp-check {
346
+ width: auto;
347
+ min-width: 3ch;
348
+ border: 0;
349
+ border-radius: 0;
350
+ background: transparent;
351
+ color: var(--wp-text-muted);
352
+ font-family: var(--wp-font-mono);
353
+ font-size: 12px;
354
+ line-height: 1;
355
+ }
356
+ /* State comes from aria-checked or, on a decorative box (aria-hidden, no
357
+ role), data-checked / data-indeterminate. Nothing may set an inline
358
+ display on the tick: it would beat this rule and draw both marks. */
359
+ html[data-wp-look="tui"] .wp-check svg { display: none; }
360
+ html[data-wp-look="tui"] .wp-check::before { content: "[ ]"; }
361
+ html[data-wp-look="tui"] .wp-check:is([aria-checked="true"], [data-checked="true"])::before { content: "[x]"; color: var(--wp-accent-text); }
362
+ html[data-wp-look="tui"] .wp-check:is([aria-checked="mixed"], [data-indeterminate="true"]):not([data-checked="true"])::before { content: "[-]"; color: var(--wp-accent-text); }
363
+ html[data-wp-look="tui"] .wp-page__title { font-size: 16px; font-weight: 700; letter-spacing: 0; }
364
+ /* Radios read ( ) / (*) beside the [ ] / [x] checkboxes; the drawn dot
365
+ hides. RadioGroup marks the picked option on the row (data-checked), the
366
+ plain .wp-radio is a real input (:checked). */
367
+ html[data-wp-look="tui"] .wp-radio-group__opt .wp-radio-group__dot,
368
+ html[data-wp-look="tui"] .wp-radio {
369
+ width: auto;
370
+ min-width: 3ch;
371
+ height: auto;
372
+ border: 0;
373
+ border-radius: 0;
374
+ background: transparent;
375
+ color: var(--wp-text-muted);
376
+ font-family: var(--wp-font-mono);
377
+ font-size: 12px;
378
+ line-height: 16px;
379
+ }
380
+ html[data-wp-look="tui"] .wp-radio-group__opt[data-checked] .wp-radio-group__dot::after { display: none; }
381
+ html[data-wp-look="tui"] .wp-radio-group__dot::before { content: "( )"; }
382
+ html[data-wp-look="tui"] .wp-radio-group__opt[data-checked] .wp-radio-group__dot::before { content: "(*)"; color: var(--wp-accent-text); }
383
+ html[data-wp-look="tui"] .wp-radio-group__opt[aria-disabled="true"][data-checked] .wp-radio-group__dot::before { color: var(--wp-text-dim); }
384
+ html[data-wp-look="tui"] .wp-radio::before,
385
+ html[data-wp-look="tui"] .wp-radio:disabled::before {
386
+ content: "( )";
387
+ width: auto;
388
+ height: auto;
389
+ border-radius: 0;
390
+ background: transparent;
391
+ transform: none;
392
+ }
393
+ html[data-wp-look="tui"] .wp-radio:checked::before { content: "(*)"; color: var(--wp-accent-text); }
394
+ html[data-wp-look="tui"] .wp-radio:disabled:checked::before { content: "(*)"; color: var(--wp-text-dim); }
395
+ html[data-wp-look="tui"] .wp-radio:checked,
396
+ html[data-wp-look="tui"] .wp-radio:disabled:checked { background: transparent; }
397
+
398
+ /* ================= Canvas previews ignore the look =================
399
+ The canvas keeps ComfyUI's ground in every look (only the accent follows
400
+ the manager), so the Settings › Canvas live preview draws canvas pieces
401
+ with the canvas's own corners and type, not the manager look's. */
402
+ html.wp-manager .wp-pg-mockup {
403
+ --wp-radius-cap: 999px;
404
+ --wp-radius-sm: 6px;
405
+ --wp-radius: 8px;
406
+ --wp-radius-lg: 12px;
407
+ --wp-radius-xl: 16px;
408
+ --wp-font: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
409
+ font-family: var(--wp-font);
410
+ }
411
+
412
+ /* ---------- PostCard in each look ----------
413
+ * The card draws its own box (src/PostCard.vue), so the looks restyle it like
414
+ * a .wp-card: firmer, softer, dashed, ruled, tighter or boxed. */
415
+ html[data-wp-look="crisp"] .wp-post-card { border-color: var(--wp-border-strong); }
416
+ html[data-wp-look="soft"] .wp-post-card { border-color: transparent; box-shadow: var(--wp-shadow-md); }
417
+ html[data-wp-look="terminal"] .wp-post-card { border-style: dashed; border-color: var(--wp-border-strong); }
418
+ html[data-wp-look="editorial"] .wp-post-card {
419
+ background: transparent;
420
+ border: 0;
421
+ border-top: 1px solid var(--wp-text);
422
+ border-radius: 0;
423
+ }
424
+ html[data-wp-look="editorial"] .wp-post-card:hover { transform: none; box-shadow: none; }
425
+ html[data-wp-look="editorial"] .wp-post-card__slug { font-family: var(--wp-font-head, var(--wp-font)); font-size: 16px; }
426
+ html[data-wp-look="compact"] .wp-post-card { padding: 12px 14px; gap: 8px; }
427
+ html[data-wp-look="tui"] .wp-post-card { border-color: var(--wp-border-strong); background: transparent; }
428
+ html[data-wp-look="tui"] .wp-post-card:hover { transform: none; box-shadow: none; background: var(--wp-bg-2); }
@@ -0,0 +1,254 @@
1
+ /* =========================================================
2
+ Colour themes — `data-wp-palette` on <html> (tweaksStore.setPalette).
3
+
4
+ A theme sets surfaces, borders, the three text tiers and its own accent
5
+ ramp. It never changes kind colours, variable colours or teal-for-picked:
6
+ those mean the same thing in every theme. Orbit is tokens.css itself, so it
7
+ has no block here.
8
+
9
+ Dark rules are `html[data-wp-palette=x]:not(.wp-theme-light)` and light
10
+ rules `html.wp-theme-light[data-wp-palette=x]`, so each beats tokens.css's
11
+ `:root` / `.wp-theme-light` blocks without depending on load order.
12
+
13
+ A preset or custom accent from the Accent setting is written inline on
14
+ <html>, so it wins over a theme's ramp; "Theme's own" removes it.
15
+ Ramps are shifted where a theme needs it so `--wp-accent-600` (the primary
16
+ fill, white text) stays at 4.5:1 or better.
17
+
18
+ Contrast: every text tier passes 4.5:1 on bg … bg-3 in both modes, and
19
+ the focus colour 3:1 (checked 2026-10-28, values in
20
+ pr-drafts/themes/theme-palettes-2026-10-28.json in the project files).
21
+ ========================================================= */
22
+
23
+ /* Accent-derived tints follow whichever ramp is live (theme or picked). */
24
+ html.wp-manager {
25
+ --wp-focus-ring: 0 0 0 3px color-mix(in oklab, var(--wp-accent-500) 45%, transparent);
26
+ --wp-row-active: color-mix(in oklab, var(--wp-accent-600) 6%, transparent);
27
+ }
28
+ html.wp-manager.wp-theme-light {
29
+ --wp-focus-ring: 0 0 0 3px color-mix(in oklab, var(--wp-accent-600) 35%, transparent);
30
+ --wp-row-active: color-mix(in oklab, var(--wp-accent-600) 9%, transparent);
31
+ }
32
+
33
+ /* ---------- Native: ComfyUI's own greys, indigo accent ---------- */
34
+ html[data-wp-palette="native"]:not(.wp-theme-light) {
35
+ --wp-bg: #18181a;
36
+ --wp-bg-1: #202123;
37
+ --wp-bg-2: #262729;
38
+ --wp-bg-3: #313235;
39
+ --wp-bg-4: #3b3c40;
40
+ --wp-border: rgba(255, 255, 255, 0.07);
41
+ --wp-border-strong: rgba(255, 255, 255, 0.14);
42
+ --wp-text: #ececed;
43
+ --wp-text-muted: #a8a9ad;
44
+ --wp-text-dim: #9c9da3;
45
+ }
46
+ html.wp-theme-light[data-wp-palette="native"] {
47
+ --wp-bg: #f3f3f3;
48
+ --wp-bg-1: #ffffff;
49
+ --wp-bg-2: #ffffff;
50
+ --wp-bg-3: #e9e9e9;
51
+ --wp-bg-4: #d9d9d9;
52
+ --wp-border: rgba(0, 0, 0, 0.10);
53
+ --wp-border-strong: rgba(0, 0, 0, 0.19);
54
+ --wp-text: #171718;
55
+ --wp-text-muted: #494a50;
56
+ --wp-text-dim: #5c5d63;
57
+ }
58
+
59
+ /* ---------- Nebula: violet night, violet accent ---------- */
60
+ html[data-wp-palette="nebula"] {
61
+ --wp-accent-50: #f5f3ff;
62
+ --wp-accent-100: #ede9fe;
63
+ --wp-accent-200: #ddd6fe;
64
+ --wp-accent-300: #c4b5fd;
65
+ --wp-accent-400: #a78bfa;
66
+ --wp-accent-500: #8b5cf6;
67
+ --wp-accent-600: #7c3aed;
68
+ --wp-accent-700: #6d28d9;
69
+ --wp-accent-800: #5b21b6;
70
+ --wp-accent-900: #4c1d95;
71
+ }
72
+ html[data-wp-palette="nebula"]:not(.wp-theme-light) {
73
+ --wp-bg: #0d0a16;
74
+ --wp-bg-1: #130f1f;
75
+ --wp-bg-2: #181327;
76
+ --wp-bg-3: #211a33;
77
+ --wp-bg-4: #2a2140;
78
+ --wp-border: rgba(255, 255, 255, 0.08);
79
+ --wp-border-strong: rgba(255, 255, 255, 0.15);
80
+ --wp-text: #ece8f6;
81
+ --wp-text-muted: #aba4c0;
82
+ --wp-text-dim: #958dac;
83
+ }
84
+ html.wp-theme-light[data-wp-palette="nebula"] {
85
+ --wp-bg: #f8f6fd;
86
+ --wp-bg-1: #ffffff;
87
+ --wp-bg-2: #ffffff;
88
+ --wp-bg-3: #f1edfa;
89
+ --wp-bg-4: #e6e0f4;
90
+ --wp-border: rgba(29, 23, 41, 0.10);
91
+ --wp-border-strong: rgba(29, 23, 41, 0.18);
92
+ --wp-text: #1d1729;
93
+ --wp-text-muted: #5d5470;
94
+ --wp-text-dim: #665d7a;
95
+ }
96
+
97
+ /* ---------- Tide: slate blue, sky accent (ramp shifted one step) ---------- */
98
+ html[data-wp-palette="tide"] {
99
+ --wp-accent-50: #f0f9ff;
100
+ --wp-accent-100: #e0f2fe;
101
+ --wp-accent-200: #bae6fd;
102
+ --wp-accent-300: #7dd3fc;
103
+ --wp-accent-400: #38bdf8;
104
+ --wp-accent-500: #0ea5e9;
105
+ --wp-accent-600: #0369a1; /* sky-700: white 5.9:1 */
106
+ --wp-accent-700: #075985;
107
+ --wp-accent-800: #0c4a6e;
108
+ --wp-accent-900: #082f49;
109
+ }
110
+ html[data-wp-palette="tide"]:not(.wp-theme-light) {
111
+ --wp-bg: #0a1018;
112
+ --wp-bg-1: #0f1722;
113
+ --wp-bg-2: #131c29;
114
+ --wp-bg-3: #1a2534;
115
+ --wp-bg-4: #223042;
116
+ --wp-border: rgba(255, 255, 255, 0.08);
117
+ --wp-border-strong: rgba(255, 255, 255, 0.15);
118
+ --wp-text: #e4ebf3;
119
+ --wp-text-muted: #a0aebe;
120
+ --wp-text-dim: #8898aa;
121
+ }
122
+ html.wp-theme-light[data-wp-palette="tide"] {
123
+ --wp-bg: #f4f7fa;
124
+ --wp-bg-1: #ffffff;
125
+ --wp-bg-2: #ffffff;
126
+ --wp-bg-3: #eaf0f5;
127
+ --wp-bg-4: #dde5ee;
128
+ --wp-border: rgba(15, 26, 38, 0.10);
129
+ --wp-border-strong: rgba(15, 26, 38, 0.19);
130
+ --wp-text: #0f1a26;
131
+ --wp-text-muted: #4d5b6b;
132
+ --wp-text-dim: #58677a;
133
+ }
134
+
135
+ /* ---------- Ember: warm charcoal, copper accent (ramp shifted one step) ---------- */
136
+ html[data-wp-palette="ember"] {
137
+ --wp-accent-50: #fff7ed;
138
+ --wp-accent-100: #ffedd5;
139
+ --wp-accent-200: #fed7aa;
140
+ --wp-accent-300: #fdba74;
141
+ --wp-accent-400: #fb923c;
142
+ --wp-accent-500: #f97316;
143
+ --wp-accent-600: #c2410c; /* orange-700: white 5.2:1 */
144
+ --wp-accent-700: #9a3412;
145
+ --wp-accent-800: #7c2d12;
146
+ --wp-accent-900: #431407;
147
+ }
148
+ html[data-wp-palette="ember"]:not(.wp-theme-light) {
149
+ --wp-bg: #110d0b;
150
+ --wp-bg-1: #17120f;
151
+ --wp-bg-2: #1c1613;
152
+ --wp-bg-3: #251d19;
153
+ --wp-bg-4: #2f2520;
154
+ --wp-border: rgba(255, 255, 255, 0.08);
155
+ --wp-border-strong: rgba(255, 255, 255, 0.15);
156
+ --wp-text: #f1e9e4;
157
+ --wp-text-muted: #b5a89f;
158
+ --wp-text-dim: #9e9188;
159
+ }
160
+ html.wp-theme-light[data-wp-palette="ember"] {
161
+ --wp-bg: #faf7f4;
162
+ --wp-bg-1: #ffffff;
163
+ --wp-bg-2: #ffffff;
164
+ --wp-bg-3: #f3ede7;
165
+ --wp-bg-4: #e9e0d7;
166
+ --wp-border: rgba(35, 26, 20, 0.10);
167
+ --wp-border-strong: rgba(35, 26, 20, 0.19);
168
+ --wp-text: #231a14;
169
+ --wp-text-muted: #62554b;
170
+ --wp-text-dim: #6c5f55;
171
+ }
172
+
173
+ /* ---------- Community: Orbit's night, rust accent, warm cream light ----------
174
+ * The community site's own theme, the counterpart to the extension's Orbit.
175
+ * Dark surfaces are Orbit's, so it has no dark block. Ramp shifted one step
176
+ * from the site's old values so the fill takes white text. */
177
+ html[data-wp-palette="community"] {
178
+ --wp-accent-50: #fef5f0;
179
+ --wp-accent-100: #fde6db;
180
+ --wp-accent-200: #fbcdb7;
181
+ --wp-accent-300: #f6a583;
182
+ --wp-accent-400: #ed8861;
183
+ --wp-accent-500: #d97757;
184
+ --wp-accent-600: #a44a2d; /* white 5.8:1 */
185
+ --wp-accent-700: #82391f;
186
+ --wp-accent-800: #5c2715;
187
+ --wp-accent-900: #3f1a0e;
188
+ }
189
+ html.wp-theme-light[data-wp-palette="community"] {
190
+ --wp-bg: #f7f5f0;
191
+ --wp-bg-1: #ffffff;
192
+ --wp-bg-2: #f1ede4;
193
+ --wp-bg-3: #e9e4d8;
194
+ --wp-bg-4: #ddd6c5;
195
+ --wp-border: rgba(20, 18, 15, 0.08);
196
+ --wp-border-strong: rgba(20, 18, 15, 0.16);
197
+ --wp-text: #1a1815;
198
+ --wp-text-muted: #595449;
199
+ --wp-text-dim: #6b6559;
200
+ --wp-row-hover: rgba(20, 18, 15, 0.03);
201
+ }
202
+
203
+ /* ---------- High contrast: black / white, solid borders, yellow focus ----------
204
+ * Keeps its own accent (the Accent setting is off). The fill is a deep
205
+ * indigo so white text on it reads at 10:1; light accent text carries links
206
+ * and selection on black. */
207
+ html[data-wp-palette="contrast"] {
208
+ --wp-accent-50: #eef2ff;
209
+ --wp-accent-100: #e0e7ff;
210
+ --wp-accent-200: #e0e7ff;
211
+ --wp-accent-300: #c7d2fe;
212
+ --wp-accent-400: #a5b4fc;
213
+ --wp-accent-500: #818cf8;
214
+ --wp-accent-600: #3730a3;
215
+ --wp-accent-700: #312e81;
216
+ --wp-accent-800: #1e1b4b;
217
+ --wp-accent-900: #1e1b4b;
218
+ }
219
+ html[data-wp-palette="contrast"]:not(.wp-theme-light) {
220
+ --wp-bg: #000000;
221
+ --wp-bg-1: #0a0a0a;
222
+ --wp-bg-2: #111111;
223
+ --wp-bg-3: #1a1a1a;
224
+ --wp-bg-4: #262626;
225
+ --wp-border: rgba(255, 255, 255, 0.40);
226
+ --wp-border-strong: rgba(255, 255, 255, 0.70);
227
+ --wp-text: #ffffff;
228
+ --wp-text-muted: #d6d6d6;
229
+ --wp-text-dim: #bcbcbc;
230
+ --wp-accent-text: #c7d2fe;
231
+ --wp-accent-text-strong: #e0e7ff;
232
+ --wp-border-focus: #facc15;
233
+ --wp-focus-ring: 0 0 0 3px #facc15;
234
+ --wp-row-hover: rgba(255, 255, 255, 0.08);
235
+ --wp-row-active: rgba(165, 180, 252, 0.16);
236
+ }
237
+ html.wp-theme-light[data-wp-palette="contrast"] {
238
+ --wp-bg: #ffffff;
239
+ --wp-bg-1: #ffffff;
240
+ --wp-bg-2: #ffffff;
241
+ --wp-bg-3: #f0f0f0;
242
+ --wp-bg-4: #dedede;
243
+ --wp-border: rgba(0, 0, 0, 0.40);
244
+ --wp-border-strong: rgba(0, 0, 0, 0.70);
245
+ --wp-text: #000000;
246
+ --wp-text-muted: #2e2e2e;
247
+ --wp-text-dim: #454545;
248
+ --wp-accent-text: #3730a3;
249
+ --wp-accent-text-strong: #1e1b4b;
250
+ --wp-border-focus: #000000;
251
+ --wp-focus-ring: 0 0 0 3px #000000;
252
+ --wp-row-hover: rgba(0, 0, 0, 0.06);
253
+ --wp-row-active: rgba(55, 48, 163, 0.12);
254
+ }