PluginProbe
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin / 1.1.12
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin v1.1.12
1.1.12 1.1.11 1.1.10 1.1.9 1.1.8 1.1.7 1.1.6 1.1.5 1.1.4 1.1.3 1.1.2 1.1.1 1.1.0 1.0.1 1.0.0 0.9.8 0.9.7 0.9.6 0.9.4 0.9.5 0.9.3 0.9.2 0.9.1 0.9.0 0.8.9 All 36 releases
← All changes | assets/css/ai-assistant.css +385 -255 0.8.9 → 1.1.12 View file →
@@ -1,17 +1,38 @@
1 1 /**
2 - * Desktop Mode — AI Assistant spotlight overlay.
2 + * OpenStation — AI Assistant spotlight overlay.
3 3 *
4 4 * A system-level command palette that floats above the entire shell,
5 5 * including the WP admin bar. Visually modeled on macOS Spotlight and
6 6 * Linear's command menu — frosted-glass backdrop, spring-physics panel
7 - * entrance, large search input, accent-tinted header.
7 + * entrance, large search input.
8 8 *
9 - * z-index 10000 puts this above --desktop-mode-z-adminbar (9991) so the
10 - * overlay truly covers the full viewport. The panel itself is white/light
11 - * regardless of wallpaper, providing consistent contrast.
9 + * ## How much accent the chrome shows
12 10 *
13 - * @since 0.14.0
11 + * Every accent-derived surface below (the header tint and its mark, the
12 + * search icon, a selected or hovered row, the icon tiles) mixes the
13 + * accent by --os-ai-accent towards a neutral. Unset that is 100%, the
14 + * accent-tinted panel this has always been; the OpenStation palette
15 + * answers 0% and lifts rows and tiles with --os-ai-row-fill and
16 + * --os-ai-tile-fill instead. The command icons themselves are not part
17 + * of it: they read the accent directly, in every palette.
18 + *
19 + * z-index 10000 puts this above --os-z-adminbar (9991) so the
20 + * overlay truly covers the full viewport.
21 + *
22 + * ## Desktop-theme awareness
23 + *
24 + * The overlay mounts on `document.body`, so it sits inside the
25 + * `body.os-desktop-theme-<slug>` half of a compiled theme's
26 + * doubled selector and every `--os-ui-*` token below resolves against the
27 + * active theme. Each site reads `var( --os-ui-x, <the literal that was
28 + * always there> )`, so an unthemed shell paints exactly as before.
29 + *
30 + * Getting this half-right is worse than not doing it at all: when the
31 + * text tones followed the theme but the panel stayed hardcoded white,
32 + * a dark theme's light `--os-ui-fg` landed on white and the results were
33 + * unreadable. Any new surface added here MUST take its background,
34 + * border and text from the palette — not from a literal.
14 35 */
15 36
16 37 /* ---------------------------------------------------------------------------
17 38 * Root overlay — full viewport, fades in/out
@@ -16,9 +37,9 @@
16 37 /* ---------------------------------------------------------------------------
17 38 * Root overlay — full viewport, fades in/out
18 39 * ------------------------------------------------------------------------- */
19 40
20 -.desktop-mode-ai {
41 +.os-ai {
21 42 position: fixed;
22 43 inset: 0;
23 44 z-index: 10000;
24 45
@@ -39,13 +60,13 @@
39 60 }
40 61
41 62 /* [hidden] keeps the element out of the a11y tree between sessions.
42 63 Only removed while the overlay is visually visible (open or animating). */
43 -.desktop-mode-ai[hidden] {
64 +.os-ai[hidden] {
44 65 display: none;
45 66 }
46 67
47 -.desktop-mode-ai.is-open {
68 +.os-ai.is-open {
48 69 opacity: 1;
49 70 pointer-events: auto;
50 71 }
51 72
@@ -52,16 +73,21 @@
52 73 /* ---------------------------------------------------------------------------
53 74 * Backdrop — frosted glass
54 75 * ------------------------------------------------------------------------- */
55 76
56 -.desktop-mode-ai__backdrop {
77 +.os-ai__backdrop {
57 78 position: absolute;
58 79 inset: 0;
59 - background: rgba( 0, 0, 0, 0.36 );
80 + background-color: var( --os-ui-scrim, rgba( 0, 0, 0, 0.36 ) );
81 + /* Desktop-theme SCRIM texture slot: unset resolves to none. */
82 + background-image: var( --os-ui-scrim-image, none );
83 + background-repeat: var( --os-ui-scrim-image-repeat, repeat );
84 + background-size: var( --os-ui-scrim-image-size, auto );
85 + background-position: var( --os-ui-scrim-image-position, center );
60 86 backdrop-filter: blur( 8px ) saturate( 0.75 );
61 87 -webkit-backdrop-filter: blur( 8px ) saturate( 0.75 );
62 - /* Backdrop is intentionally non-interactive — the overlay stays open
63 - until the user explicitly clicks the × close button. */
88 + /* Non-interactive: clicks in the dimmed area fall through to the overlay
89 + container, which closes the assistant (click-outside-to-dismiss). */
64 90 pointer-events: none;
65 91 }
66 92
67 93 /* ---------------------------------------------------------------------------
@@ -67,20 +93,35 @@
67 93 /* ---------------------------------------------------------------------------
68 94 * Panel — the visible card
69 95 * ------------------------------------------------------------------------- */
70 96
71 -.desktop-mode-ai__panel {
97 +.os-ai__panel {
72 98 position: relative; /* sits above the backdrop */
73 99 width: 100%;
74 100 max-width: 600px;
75 101
76 - background: rgba( 255, 255, 255, 0.97 );
102 + /* Longhand on purpose: the DIALOG texture slot below owns
103 + background-image, and the shorthand would reset it. */
104 + background-color: var(
105 + --os-ai-panel-bg,
106 + var( --os-ui-surface, rgba( 255, 255, 255, 0.97 ) )
107 + );
108 + /* Desktop-theme DIALOG texture slot: unset resolves to none. */
109 + background-image: var( --os-ui-dialog-bg-image, none );
110 + background-repeat: var( --os-ui-dialog-bg-image-repeat, repeat );
111 + background-size: var( --os-ui-dialog-bg-image-size, auto );
112 + background-position: var( --os-ui-dialog-bg-image-position, center );
113 + color: var( --os-ui-fg, #1d2327 );
114 + font-family: var( --os-ui-font, inherit );
77 115 border-radius: 16px;
78 116 overflow: hidden;
79 117
80 - /* Tight under-shadow + wide atmospheric shadow */
118 + /* Tight under-shadow + wide atmospheric shadow. The hairline ring
119 + is the panel's only edge, so it follows the palette; the two
120 + atmospheric shadows stay black because they read as depth
121 + against the wallpaper, not as part of the surface. */
81 122 box-shadow:
82 - 0 0 0 1px rgba( 0, 0, 0, 0.07 ),
123 + 0 0 0 1px var( --os-ui-border, rgba( 0, 0, 0, 0.07 ) ),
83 124 0 4px 16px rgba( 0, 0, 0, 0.12 ),
84 125 0 24px 64px rgba( 0, 0, 0, 0.22 );
85 126
86 127 /* Spring-physics entrance: starts slightly small + shifted up,
@@ -89,57 +130,60 @@
89 130 transition: transform 0.28s cubic-bezier( 0.34, 1.56, 0.64, 1 );
90 131 will-change: transform;
91 132 }
92 133
93 -.desktop-mode-ai.is-open .desktop-mode-ai__panel {
134 +.os-ai.is-open .os-ai__panel {
94 135 transform: scale( 1 ) translateY( 0 );
95 136 }
96 137
97 -/* ---------------------------------------------------------------------------
98 - * Header — accent-tinted identity strip
99 - * ------------------------------------------------------------------------- */
138 +/* Mode switch (Commands ↔ AI) — a small segmented pill at the end of
139 + the input row. Always shown; replaces the `/` shortcut. */
140 +.os-ai__modes {
141 + flex-shrink: 0;
142 + display: inline-flex;
143 + gap: 2px;
144 + padding: 2px;
145 + border-radius: 999px;
146 + background: var( --os-ui-hover, rgba( 0, 0, 0, 0.05 ) );
147 +}
100 148
101 -.desktop-mode-ai__header {
102 - display: flex;
103 - align-items: center;
104 - gap: 8px;
105 - padding: 10px 14px;
106 - /* Gradient fades from a very faint accent tint to white — visible
107 - on fresh/blue schemes, subtle on light schemes. */
108 - background: linear-gradient(
109 - to bottom,
110 - color-mix( in srgb, var( --wp-admin-theme-color, #2271b1 ) 8%, #fff ),
111 - #fff
112 - );
113 - border-bottom: 1px solid rgba( 0, 0, 0, 0.06 );
149 +.os-ai__mode {
150 + appearance: none;
151 + border: 0;
152 + cursor: pointer;
153 + padding: 3px 12px;
154 + border-radius: 999px;
155 + background: transparent;
156 + color: var( --os-ui-fg-muted, #50575e );
157 + font-size: 11px;
158 + font-weight: 600;
159 + line-height: 1.6;
114 160 }
115 161
116 -.desktop-mode-ai__header-icon {
117 - display: flex;
118 - align-items: center;
119 - color: var( --wp-admin-theme-color, #2271b1 );
120 - /* Glow so the sparkle feels alive on dark or saturated themes */
121 - filter: drop-shadow(
122 - 0 0 5px color-mix( in srgb, var( --wp-admin-theme-color, #2271b1 ) 55%, transparent )
123 - );
162 +.os-ai__mode:hover {
163 + color: var( --os-ui-fg, #1d2327 );
124 164 }
125 165
126 -.desktop-mode-ai__header-label {
127 - flex: 1;
128 - font-size: 11px;
129 - font-weight: 700;
130 - letter-spacing: 0.09em;
131 - text-transform: uppercase;
166 +.os-ai__mode.is-active {
167 + /* Elevated first: the pill sits ON the panel, which is already
168 + `--os-ui-surface`, so a theme that distinguishes the two keeps the
169 + active segment readable. Falls through to plain surface, which is
170 + the default look. */
171 + background: var( --os-ui-surface-elevated, var( --os-ui-surface, #fff ) );
132 172 color: var( --wp-admin-theme-color, #2271b1 );
173 + box-shadow: 0 1px 2px rgba( 0, 0, 0, 0.12 );
133 174 }
134 175
135 -/* .desktop-mode-ai__close styles moved to the bottom results section */
176 +.os-ai__mode:focus-visible {
177 + outline: 2px solid var( --wp-admin-theme-color, #2271b1 );
178 + outline-offset: 1px;
179 +}
136 180
137 181 /* ---------------------------------------------------------------------------
138 182 * Input row — the main interaction surface
139 183 * ------------------------------------------------------------------------- */
140 184
141 -.desktop-mode-ai__input-wrap {
185 +.os-ai__input-wrap {
142 186 display: flex;
143 187 align-items: center;
144 188 gap: 10px;
145 189 padding: 14px 16px;
@@ -147,50 +191,92 @@
147 191 border-bottom: 1px solid transparent;
148 192 transition: border-color 0.15s ease;
149 193 }
150 194
151 -.desktop-mode-ai__input-wrap:has( .desktop-mode-ai__input:focus ) {
152 - border-bottom-color: rgba( 0, 0, 0, 0.06 );
195 +.os-ai__input-wrap:has( .os-ai__input:focus ) {
196 + border-bottom-color: var( --os-ui-border, rgba( 0, 0, 0, 0.06 ) );
153 197 }
154 198
155 -/* Input-row sparkle — visible always, tints toward the accent on focus
156 - so the panel reads as "AI assistant" rather than "search box". */
157 -.desktop-mode-ai__input-icon {
199 +/* Input-row icon: dim at rest, full strength on focus. At rest it is
200 + the accent at 55% alpha, mixed by --os-ai-accent towards the faint
201 + text colour; focused, the accent mixed towards the text colour. */
202 +.os-ai__input-icon {
158 203 flex-shrink: 0;
159 204 display: flex;
160 205 align-items: center;
161 - color: var( --wp-admin-theme-color, #2271b1 );
162 - opacity: 0.55;
163 - transition: opacity 0.18s ease, transform 0.18s ease;
206 + color: color-mix(
207 + in srgb,
208 + color-mix( in srgb, var( --wp-admin-theme-color, #2271b1 ) 55%, transparent ) var( --os-ai-accent, 100% ),
209 + var( --os-ui-fg-faint, #c3c4c7 )
210 + );
211 + transition: color 0.18s ease, transform 0.18s ease;
164 212 }
165 213
166 -.desktop-mode-ai__input-wrap:has( .desktop-mode-ai__input:focus ) .desktop-mode-ai__input-icon {
167 - opacity: 1;
214 +.os-ai__input-wrap:has( .os-ai__input:focus ) .os-ai__input-icon {
215 + color: color-mix(
216 + in srgb,
217 + var( --wp-admin-theme-color, #2271b1 ) var( --os-ai-accent, 100% ),
218 + var( --os-ui-fg, #1d2327 )
219 + );
168 220 transform: scale( 1.08 );
169 221 }
170 222
171 -.desktop-mode-ai__input {
223 +/*
224 + * The search field is a raw `<input type="text">` in the parent shell,
225 + * so core's `forms.css` reaches it:
226 + *
227 + * input[type="text"], … { background-color: #fff; color: #2c3338;
228 + * border: 1px solid #8c8f94;
229 + * border-radius: 4px;
230 + * box-shadow: 0 0 0 transparent }
231 + * input[type="text"]:focus { border-color: #2271b1;
232 + * box-shadow: 0 0 0 1px #2271b1 }
233 + *
234 + * That weighs (0,1,1) — one type selector plus one attribute selector —
235 + * which beats a bare `.os-ai__input` at (0,1,0). The result
236 + * was a bordered white box floating inside the panel: core's chrome,
237 + * core's text colour, ignoring both the design intent (a chromeless
238 + * Spotlight-style field) and any active desktop theme.
239 + *
240 + * Scoping to the overlay root takes the selector to (0,2,0) and wins.
241 + * Same fix as the native-window form-control rule in window-chrome.css.
242 + */
243 +.os-ai .os-ai__input {
172 244 flex: 1;
173 245 min-width: 0;
174 246 appearance: none;
175 247 border: none;
248 + border-radius: 0;
176 249 outline: none;
250 + box-shadow: none;
251 + padding: 0;
252 + /* Matches the height core gave the control, so the row keeps its
253 + comfortable hit target now that core's box is gone. */
254 + min-height: 30px;
177 255 background: transparent;
178 256 font: inherit;
179 257 font-size: 17px;
180 258 font-weight: 400;
181 259 line-height: 1.4;
182 - color: #1d2327;
260 + color: var( --os-ui-fg, #1d2327 );
183 261 }
184 262
185 -.desktop-mode-ai__input::placeholder {
186 - color: #c3c4c7;
263 +/* Core paints a focus border + ring on the element itself; the focus
264 + affordance here is the input row's bottom hairline instead. */
265 +.os-ai .os-ai__input:focus {
266 + border-color: transparent;
267 + box-shadow: none;
268 + outline: none;
269 +}
270 +
271 +.os-ai .os-ai__input::placeholder {
272 + color: var( --os-ui-fg-faint, #c3c4c7 );
187 273 font-weight: 400;
188 274 }
189 275
190 276 /* Submit button — hidden until the user types something, then
191 277 springs in via opacity + scale transition. */
192 -.desktop-mode-ai__submit {
278 +.os-ai__submit {
193 279 flex-shrink: 0;
194 280 display: flex;
195 281 align-items: center;
196 282 justify-content: center;
@@ -197,10 +283,25 @@
197 283 width: 30px;
198 284 height: 30px;
199 285 border: none;
200 286 border-radius: 8px;
201 - background: var( --wp-admin-theme-color, #2271b1 );
202 - color: #fff;
287 + /* An accent key at --os-ai-accent's strength. At 0 it is an icon tile
288 + like the command rows' (the neutral fill, the glyph in the accent);
289 + at 100% the filled accent button with its ink. */
290 + background-color: color-mix(
291 + in srgb,
292 + var( --wp-admin-theme-color, #2271b1 ) var( --os-ai-accent, 100% ),
293 + transparent
294 + );
295 + background-image: linear-gradient(
296 + var( --os-ai-tile-fill, transparent ),
297 + var( --os-ai-tile-fill, transparent )
298 + );
299 + color: color-mix(
300 + in srgb,
301 + var( --os-ui-accent-ink, var( --os-ui-fg-on-accent, #fff ) ) var( --os-ai-accent, 100% ),
302 + var( --wp-admin-theme-color, #2271b1 )
303 + );
203 304 cursor: pointer;
204 305 padding: 0;
205 306 opacity: 0;
206 307 transform: scale( 0.7 );
@@ -209,23 +310,23 @@
209 310 opacity 0.2s ease,
210 311 transform 0.2s cubic-bezier( 0.34, 1.56, 0.64, 1 );
211 312 }
212 313
213 -.desktop-mode-ai__submit.has-value {
314 +.os-ai__submit.has-value {
214 315 opacity: 1;
215 316 transform: scale( 1 );
216 317 pointer-events: auto;
217 318 }
218 319
219 -.desktop-mode-ai__submit:hover {
320 +.os-ai__submit:hover {
220 321 filter: brightness( 1.1 );
221 322 }
222 323
223 -.desktop-mode-ai__submit:active {
324 +.os-ai__submit:active {
224 325 transform: scale( 0.92 );
225 326 }
226 327
227 -.desktop-mode-ai__submit:focus-visible {
328 +.os-ai__submit:focus-visible {
228 329 outline: 2px solid var( --wp-admin-theme-color, #2271b1 );
229 330 outline-offset: 2px;
230 331 }
231 332
@@ -232,86 +333,34 @@
232 333 /* ---------------------------------------------------------------------------
233 334 * Footer — hints and keyboard shortcut legend
234 335 * ------------------------------------------------------------------------- */
235 336
236 -.desktop-mode-ai__footer {
337 +.os-ai__footer {
237 338 display: flex;
238 339 align-items: center;
239 340 justify-content: space-between;
240 341 gap: 8px;
241 342 padding: 8px 16px 10px;
242 - background: rgba( 0, 0, 0, 0.018 );
243 - border-top: 1px solid rgba( 0, 0, 0, 0.05 );
343 + background: var( --os-ui-hover, rgba( 0, 0, 0, 0.018 ) );
344 + border-top: 1px solid var( --os-ui-border, rgba( 0, 0, 0, 0.05 ) );
244 345 }
245 346
246 -.desktop-mode-ai__footer-hint {
347 +.os-ai__footer-hint {
247 348 font-size: 11px;
248 - color: #a7aaad;
349 + color: var( --os-ui-fg-muted, #a7aaad );
249 350 }
250 351
251 -.desktop-mode-ai__footer-keys {
252 - display: flex;
253 - align-items: center;
254 - gap: 2px;
255 - font-size: 11px;
256 - color: #b4b9be;
257 - white-space: nowrap;
258 - flex-shrink: 0;
259 -}
260 -
261 -.desktop-mode-ai__footer-keys kbd {
262 - font-family: inherit;
263 - font-size: 10px;
264 - padding: 1px 5px;
265 - border: 1px solid rgba( 0, 0, 0, 0.1 );
266 - border-radius: 4px;
267 - background: rgba( 0, 0, 0, 0.03 );
268 - color: #646970;
269 -}
270 -
271 352 /* ---------------------------------------------------------------------------
272 353 * Admin bar AI button — ⌘K badge + sparkle icon
273 354 * Styles applied via wp_add_inline_style( 'admin-bar', ... ) in PHP.
274 355 * The styles here are for reference; the actual output lives in
275 - * includes/admin-bar.php :: desktop_mode_enqueue_toggle_assets().
356 + * includes/admin-bar.php :: openstation_enqueue_toggle_assets().
276 357 * ------------------------------------------------------------------------- */
277 358
278 359 /* (The admin-bar button styles are added inline in PHP to keep them
279 - on the admin-bar handle so they load even before desktop-mode.js.) */
360 + on the admin-bar handle so they load even before os.js.) */
280 361
281 362 /* ---------------------------------------------------------------------------
282 - * Close button — × icon, top-right of header
283 - * ------------------------------------------------------------------------- */
284 -
285 -.desktop-mode-ai__close {
286 - display: inline-flex;
287 - align-items: center;
288 - justify-content: center;
289 - width: 28px;
290 - height: 28px;
291 - appearance: none;
292 - background: rgba( 0, 0, 0, 0.05 );
293 - border: 1px solid rgba( 0, 0, 0, 0.1 );
294 - border-radius: 6px;
295 - cursor: pointer;
296 - color: #646970;
297 - padding: 0;
298 - flex-shrink: 0;
299 - transition: background 0.1s, color 0.1s, border-color 0.1s;
300 -}
301 -
302 -.desktop-mode-ai__close:hover {
303 - background: rgba( 0, 0, 0, 0.09 );
304 - border-color: rgba( 0, 0, 0, 0.2 );
305 - color: #1d2327;
306 -}
307 -
308 -.desktop-mode-ai__close:focus-visible {
309 - outline: 2px solid var( --wp-admin-theme-color, #2271b1 );
310 - outline-offset: 2px;
311 -}
312 -
313 -/* ---------------------------------------------------------------------------
314 363 * Results / conversation area — three render modes:
315 364 * • Suggestions (empty state, example prompts)
316 365 * • Thinking (spinner + "Thinking…")
317 366 * • Response (assistant bubble + entity card | admin links | nothing)
@@ -316,10 +365,10 @@
316 365 * • Thinking (spinner + "Thinking…")
317 366 * • Response (assistant bubble + entity card | admin links | nothing)
318 367 * ------------------------------------------------------------------------- */
319 368
320 -.desktop-mode-ai__results {
321 - border-top: 1px solid rgba( 0, 0, 0, 0.06 );
369 +.os-ai__results {
370 + border-top: 1px solid var( --os-ui-border, rgba( 0, 0, 0, 0.06 ) );
322 371 max-height: 420px;
323 372 overflow-y: auto;
324 373 overflow-x: hidden;
325 374 padding: 14px 16px;
@@ -331,39 +380,39 @@
331 380 /* -----------------------------------------------------------------
332 381 * Suggestion chips (empty state)
333 382 * ---------------------------------------------------------------- */
334 383
335 -.desktop-mode-ai__suggestions-label {
384 +.os-ai__suggestions-label {
336 385 margin: 0 0 4px;
337 386 font-size: 11px;
338 387 font-weight: 600;
339 388 text-transform: uppercase;
340 389 letter-spacing: 0.08em;
341 - color: #8c8f94;
390 + color: var( --os-ui-fg-muted, #8c8f94 );
342 391 }
343 392
344 -.desktop-mode-ai__suggestions-list {
393 +.os-ai__suggestions-list {
345 394 display: flex;
346 395 flex-wrap: wrap;
347 396 gap: 6px;
348 397 }
349 398
350 -.desktop-mode-ai__suggestion {
399 +.os-ai__suggestion {
351 400 appearance: none;
352 - border: 1px solid rgba( 0, 0, 0, 0.1 );
353 - background: rgba( 0, 0, 0, 0.02 );
401 + border: 1px solid var( --os-ui-border, rgba( 0, 0, 0, 0.1 ) );
402 + background: var( --os-ui-hover, rgba( 0, 0, 0, 0.02 ) );
354 403 border-radius: 999px;
355 404 padding: 5px 12px;
356 405 font: inherit;
357 406 font-size: 12px;
358 - color: #50575e;
407 + color: var( --os-ui-fg-muted, #50575e );
359 408 cursor: pointer;
360 409 transition: background 0.12s, border-color 0.12s, color 0.12s;
361 410 }
362 411
363 -.desktop-mode-ai__suggestion:hover {
364 - background: color-mix( in srgb, var( --wp-admin-theme-color, #2271b1 ) 8%, #fff );
365 - border-color: color-mix( in srgb, var( --wp-admin-theme-color, #2271b1 ) 30%, rgba( 0, 0, 0, 0.1 ) );
412 +.os-ai__suggestion:hover {
413 + background: color-mix( in srgb, var( --wp-admin-theme-color, #2271b1 ) 8%, var( --os-ui-surface, #fff ) );
414 + border-color: color-mix( in srgb, var( --wp-admin-theme-color, #2271b1 ) 30%, var( --os-ui-border, rgba( 0, 0, 0, 0.1 ) ) );
366 415 color: var( --wp-admin-theme-color, #2271b1 );
367 416 }
368 417
369 418 /* -----------------------------------------------------------------
@@ -369,27 +418,60 @@
369 418 /* -----------------------------------------------------------------
370 419 * Thinking / error state
371 420 * ---------------------------------------------------------------- */
372 421
373 -.desktop-mode-ai__state {
422 +.os-ai__state {
374 423 display: flex;
375 424 align-items: center;
376 425 gap: 10px;
377 426 font-size: 13px;
378 - color: #646970;
427 + color: var( --os-ui-fg-muted, #646970 );
379 428 }
380 429
381 -.desktop-mode-ai__state--error {
382 - color: #d63638;
430 +.os-ai__state--error {
431 + color: var( --os-ui-danger, #d63638 );
383 432 align-items: flex-start;
384 433 }
385 434
386 -@keyframes desktop-mode-spin {
435 +/* Inline "AI Settings" link inside the "AI not enabled" error — opens
436 + * OS Settings on the AI tab. Styled as a link within the surrounding
437 + * error text, not a standalone button: inherits the error color and
438 + * flows with the sentence. */
439 +.os-ai__settings-link {
440 + appearance: none;
441 + border: 0;
442 + margin: 0;
443 + padding: 0;
444 + background: none;
445 + font: inherit;
446 + font-weight: 600;
447 + color: inherit;
448 + text-decoration: underline;
449 + text-underline-offset: 2px;
450 +}
451 +
452 +/* Keeps the underline and nudges the colour toward the foreground, so
453 + hovering reads as a response rather than the link going away. */
454 +.os-ai__settings-link:hover {
455 + color: color-mix( in srgb, currentColor 65%, var( --os-ui-fg, #1d2327 ) );
456 +}
457 +
458 +/* The shell forces `cursor: default !important` on every clickable
459 + * surface (see the cursor policy at the top of desktop.css). This
460 + * recovery link is an explicit, user-approved exception: it keeps a
461 + * pointer so it reads as the actionable link it is. Scoped under
462 + * `body.os-active` so it out-specifies the policy's
463 + * `!important` rule, same trick the resize-handle exceptions use. */
464 +body.os-active .os-ai__settings-link {
465 + cursor: pointer !important;
466 +}
467 +
468 +@keyframes os-spin {
387 469 to { transform: rotate( 360deg ); }
388 470 }
389 471
390 -.desktop-mode-ai__spinner-icon {
391 - animation: desktop-mode-spin 0.9s linear infinite;
472 +.os-ai__spinner-icon {
473 + animation: os-spin 0.9s linear infinite;
392 474 flex-shrink: 0;
393 475 color: var( --wp-admin-theme-color, #2271b1 );
394 476 }
395 477
@@ -396,15 +478,15 @@
396 478 /* -----------------------------------------------------------------
397 479 * Assistant message bubble — prefix for every response
398 480 * ---------------------------------------------------------------- */
399 481
400 -.desktop-mode-ai__bubble {
482 +.os-ai__bubble {
401 483 display: flex;
402 484 align-items: flex-start;
403 485 gap: 10px;
404 486 }
405 487
406 -.desktop-mode-ai__bubble-icon {
488 +.os-ai__bubble-icon {
407 489 flex-shrink: 0;
408 490 display: flex;
409 491 align-items: center;
410 492 justify-content: center;
@@ -410,17 +492,17 @@
410 492 justify-content: center;
411 493 width: 24px;
412 494 height: 24px;
413 495 border-radius: 50%;
414 - background: color-mix( in srgb, var( --wp-admin-theme-color, #2271b1 ) 12%, #fff );
496 + background: color-mix( in srgb, var( --wp-admin-theme-color, #2271b1 ) 12%, var( --os-ui-surface, #fff ) );
415 497 color: var( --wp-admin-theme-color, #2271b1 );
416 498 }
417 499
418 -.desktop-mode-ai__bubble-text {
500 +.os-ai__bubble-text {
419 501 padding-top: 3px;
420 502 font-size: 13px;
421 503 line-height: 1.5;
422 - color: #1d2327;
504 + color: var( --os-ui-fg, #1d2327 );
423 505 flex: 1;
424 506 min-width: 0;
425 507 }
426 508
@@ -428,41 +510,41 @@
428 510 <p>, <ul>/<ol>/<li>, <strong>, <em>, <code>, <a>. Reset margins on
429 511 outer paragraphs so single-paragraph replies (the common case)
430 512 don't get top/bottom spacing; list items get the usual disc/decimal
431 513 markers inside a compact indent. */
432 -.desktop-mode-ai__bubble-text > p,
433 -.desktop-mode-ai__bubble-text > ul,
434 -.desktop-mode-ai__bubble-text > ol {
514 +.os-ai__bubble-text > p,
515 +.os-ai__bubble-text > ul,
516 +.os-ai__bubble-text > ol {
435 517 margin: 0 0 6px;
436 518 }
437 -.desktop-mode-ai__bubble-text > :last-child {
519 +.os-ai__bubble-text > :last-child {
438 520 margin-bottom: 0;
439 521 }
440 -.desktop-mode-ai__bubble-text ul,
441 -.desktop-mode-ai__bubble-text ol {
522 +.os-ai__bubble-text ul,
523 +.os-ai__bubble-text ol {
442 524 padding-inline-start: 20px;
443 525 }
444 -.desktop-mode-ai__bubble-text li {
526 +.os-ai__bubble-text li {
445 527 margin-bottom: 2px;
446 528 }
447 -.desktop-mode-ai__bubble-text code {
448 - background: rgba( 0, 0, 0, 0.05 );
529 +.os-ai__bubble-text code {
530 + background: var( --os-ui-hover, rgba( 0, 0, 0, 0.05 ) );
449 531 padding: 1px 5px;
450 532 border-radius: 4px;
451 - font-family: Menlo, Consolas, monospace;
533 + font-family: var( --os-ui-font-mono, Menlo, Consolas, monospace );
452 534 font-size: 11.5px;
453 535 }
454 -.desktop-mode-ai__bubble-text a {
536 +.os-ai__bubble-text a {
455 537 color: var( --wp-admin-theme-color, #2271b1 );
456 538 text-decoration: underline;
457 539 text-underline-offset: 2px;
458 540 }
459 -.desktop-mode-ai__bubble-text a:hover {
541 +.os-ai__bubble-text a:hover {
460 542 text-decoration: none;
461 543 }
462 -.desktop-mode-ai__bubble-text strong {
544 +.os-ai__bubble-text strong {
463 545 font-weight: 600;
464 - color: #1d2327;
546 + color: var( --os-ui-fg, #1d2327 );
465 547 }
466 548
467 549 /* -----------------------------------------------------------------
468 550 * Entity card — shown under the bubble when answer_type=entity
@@ -467,19 +549,19 @@
467 549 /* -----------------------------------------------------------------
468 550 * Entity card — shown under the bubble when answer_type=entity
469 551 * ---------------------------------------------------------------- */
470 552
471 -.desktop-mode-ai__entity {
553 +.os-ai__entity {
472 554 display: flex;
473 555 flex-direction: column;
474 556 gap: 8px;
475 557 padding: 12px 14px;
476 - background: rgba( 0, 0, 0, 0.02 );
477 - border: 1px solid rgba( 0, 0, 0, 0.08 );
558 + background: var( --os-ui-hover, rgba( 0, 0, 0, 0.02 ) );
559 + border: 1px solid var( --os-ui-border, rgba( 0, 0, 0, 0.08 ) );
478 560 border-radius: 10px;
479 561 }
480 562
481 -.desktop-mode-ai__entity-header {
563 +.os-ai__entity-header {
482 564 display: flex;
483 565 align-items: center;
484 566 gap: 8px;
485 567 flex-wrap: wrap;
@@ -484,9 +566,9 @@
484 566 gap: 8px;
485 567 flex-wrap: wrap;
486 568 }
487 569
488 -.desktop-mode-ai__entity-topic {
570 +.os-ai__entity-topic {
489 571 display: inline-block;
490 572 font-size: 10px;
491 573 font-weight: 600;
492 574 text-transform: uppercase;
@@ -496,34 +578,34 @@
496 578 padding: 2px 7px;
497 579 border-radius: 999px;
498 580 }
499 581
500 -.desktop-mode-ai__entity-type {
582 +.os-ai__entity-type {
501 583 font-size: 10px;
502 584 font-weight: 600;
503 585 text-transform: uppercase;
504 586 letter-spacing: 0.07em;
505 - color: #8c8f94;
587 + color: var( --os-ui-fg-muted, #8c8f94 );
506 588 }
507 589
508 -.desktop-mode-ai__entity-title {
590 +.os-ai__entity-title {
509 591 margin: 0;
510 592 font-size: 14px;
511 593 font-weight: 600;
512 - color: #1d2327;
594 + color: var( --os-ui-fg, #1d2327 );
513 595 line-height: 1.35;
514 596 }
515 597
516 -.desktop-mode-ai__entity-summary {
598 +.os-ai__entity-summary {
517 599 margin: 0;
518 600 font-size: 12px;
519 601 line-height: 1.5;
520 - color: #50575e;
602 + color: var( --os-ui-fg-muted, #50575e );
521 603 }
522 604
523 605 /* Primary action — opens the entity in a legacy iframe window inside
524 606 the desktop (wp-admin edit URL). */
525 -.desktop-mode-ai__entity-open {
607 +.os-ai__entity-open {
526 608 appearance: none;
527 609 display: inline-flex;
528 610 align-items: center;
529 611 gap: 6px;
@@ -531,9 +613,9 @@
531 613 padding: 6px 14px;
532 614 border: none;
533 615 border-radius: 8px;
534 616 background: var( --wp-admin-theme-color, #2271b1 );
535 - color: #fff;
617 + color: var( --os-ui-accent-ink, var( --os-ui-fg-on-accent, #fff ) );
536 618 font: inherit;
537 619 font-size: 12px;
538 620 font-weight: 500;
539 621 cursor: pointer;
@@ -539,22 +621,22 @@
539 621 cursor: pointer;
540 622 transition: filter 0.1s, transform 0.1s;
541 623 }
542 624
543 -.desktop-mode-ai__entity-open:hover {
625 +.os-ai__entity-open:hover {
544 626 filter: brightness( 1.1 );
545 627 }
546 628
547 -.desktop-mode-ai__entity-open:active {
629 +.os-ai__entity-open:active {
548 630 transform: scale( 0.97 );
549 631 }
550 632
551 -.desktop-mode-ai__entity-open:focus-visible {
633 +.os-ai__entity-open:focus-visible {
552 634 outline: 2px solid var( --wp-admin-theme-color, #2271b1 );
553 635 outline-offset: 2px;
554 636 }
555 637
556 -.desktop-mode-ai__entity-open svg {
638 +.os-ai__entity-open svg {
557 639 margin-inline-start: 2px;
558 640 }
559 641
560 642 /* -----------------------------------------------------------------
@@ -560,22 +642,22 @@
560 642 /* -----------------------------------------------------------------
561 643 * Admin-links list — shown when answer_type=navigation
562 644 * ---------------------------------------------------------------- */
563 645
564 -.desktop-mode-ai__admin-links {
646 +.os-ai__admin-links {
565 647 display: flex;
566 648 flex-direction: column;
567 649 gap: 6px;
568 650 }
569 651
570 -.desktop-mode-ai__admin-link {
652 +.os-ai__admin-link {
571 653 appearance: none;
572 654 display: flex;
573 655 align-items: center;
574 656 gap: 12px;
575 657 padding: 10px 12px;
576 - background: rgba( 0, 0, 0, 0.02 );
577 - border: 1px solid rgba( 0, 0, 0, 0.08 );
658 + background: var( --os-ui-hover, rgba( 0, 0, 0, 0.02 ) );
659 + border: 1px solid var( --os-ui-border, rgba( 0, 0, 0, 0.08 ) );
578 660 border-radius: 10px;
579 661 cursor: pointer;
580 662 text-align: start;
581 663 font: inherit;
@@ -582,23 +664,23 @@
582 664 color: inherit;
583 665 transition: background 0.12s, border-color 0.12s, transform 0.08s;
584 666 }
585 667
586 -.desktop-mode-ai__admin-link:hover {
587 - background: color-mix( in srgb, var( --wp-admin-theme-color, #2271b1 ) 6%, #fff );
588 - border-color: color-mix( in srgb, var( --wp-admin-theme-color, #2271b1 ) 25%, rgba( 0, 0, 0, 0.08 ) );
668 +.os-ai__admin-link:hover {
669 + background: color-mix( in srgb, var( --wp-admin-theme-color, #2271b1 ) 6%, var( --os-ui-surface, #fff ) );
670 + border-color: color-mix( in srgb, var( --wp-admin-theme-color, #2271b1 ) 25%, var( --os-ui-border, rgba( 0, 0, 0, 0.08 ) ) );
589 671 }
590 672
591 -.desktop-mode-ai__admin-link:active {
673 +.os-ai__admin-link:active {
592 674 transform: scale( 0.99 );
593 675 }
594 676
595 -.desktop-mode-ai__admin-link:focus-visible {
677 +.os-ai__admin-link:focus-visible {
596 678 outline: 2px solid var( --wp-admin-theme-color, #2271b1 );
597 679 outline-offset: 2px;
598 680 }
599 681
600 -.desktop-mode-ai__admin-link-icon {
682 +.os-ai__admin-link-icon {
601 683 flex-shrink: 0;
602 684 display: flex;
603 685 align-items: center;
604 686 justify-content: center;
@@ -605,13 +687,13 @@
605 687 width: 32px;
606 688 height: 32px;
607 689 font-size: 18px;
608 690 color: var( --wp-admin-theme-color, #2271b1 );
609 - background: color-mix( in srgb, var( --wp-admin-theme-color, #2271b1 ) 10%, #fff );
691 + background: color-mix( in srgb, var( --wp-admin-theme-color, #2271b1 ) 10%, var( --os-ui-surface, #fff ) );
610 692 border-radius: 8px;
611 693 }
612 694
613 -.desktop-mode-ai__admin-link-body {
695 +.os-ai__admin-link-body {
614 696 flex: 1;
615 697 display: flex;
616 698 flex-direction: column;
617 699 gap: 2px;
@@ -617,17 +699,17 @@
617 699 gap: 2px;
618 700 min-width: 0;
619 701 }
620 702
621 -.desktop-mode-ai__admin-link-title {
703 +.os-ai__admin-link-title {
622 704 font-size: 13px;
623 705 font-weight: 600;
624 - color: #1d2327;
706 + color: var( --os-ui-fg, #1d2327 );
625 707 }
626 708
627 -.desktop-mode-ai__admin-link-desc {
709 +.os-ai__admin-link-desc {
628 710 font-size: 11px;
629 - color: #646970;
711 + color: var( --os-ui-fg-muted, #646970 );
630 712 line-height: 1.4;
631 713 overflow: hidden;
632 714 text-overflow: ellipsis;
633 715 white-space: nowrap;
@@ -632,15 +714,15 @@
632 714 text-overflow: ellipsis;
633 715 white-space: nowrap;
634 716 }
635 717
636 -.desktop-mode-ai__admin-link-arrow {
718 +.os-ai__admin-link-arrow {
637 719 flex-shrink: 0;
638 - color: #c3c4c7;
720 + color: var( --os-ui-fg-faint, #c3c4c7 );
639 721 transition: color 0.12s, transform 0.12s;
640 722 }
641 723
642 -.desktop-mode-ai__admin-link:hover .desktop-mode-ai__admin-link-arrow {
724 +.os-ai__admin-link:hover .os-ai__admin-link-arrow {
643 725 color: var( --wp-admin-theme-color, #2271b1 );
644 726 transform: translateX( 2px );
645 727 }
646 728
@@ -650,15 +732,15 @@
650 732 * admin-link list's visual shape (icon + title + description) but
651 733 * uses a dedicated set of classes so each can evolve independently.
652 734 * ---------------------------------------------------------------- */
653 735
654 -.desktop-mode-ai__cmd-list {
736 +.os-ai__cmd-list {
655 737 display: flex;
656 738 flex-direction: column;
657 739 gap: 4px;
658 740 }
659 741
660 -.desktop-mode-ai__cmd-item {
742 +.os-ai__cmd-item {
661 743 appearance: none;
662 744 display: flex;
663 745 align-items: flex-start;
664 746 gap: 10px;
@@ -673,24 +755,50 @@
673 755 transition: background 0.1s, border-color 0.1s;
674 756 }
675 757
676 758 /*
677 - * Single-line rows (no `.desktop-mode-ai__cmd-desc` child) need the
759 + * Single-line rows (no `.os-ai__cmd-desc` child) need the
678 760 * icon + label baseline-centered instead of top-aligned, otherwise
679 761 * the label floats to the top of the taller icon tile and reads as
680 762 * misaligned. `:has()` is widely supported in evergreen browsers the
681 763 * desktop shell already targets.
682 764 */
683 -.desktop-mode-ai__cmd-item:not(:has(.desktop-mode-ai__cmd-desc)) {
765 +.os-ai__cmd-item:not(:has(.os-ai__cmd-desc)) {
684 766 align-items: center;
685 767 }
686 768
687 -.desktop-mode-ai__cmd-item:hover,
688 -.desktop-mode-ai__cmd-item.is-selected {
689 - background: color-mix( in srgb, var( --wp-admin-theme-color, #2271b1 ) 8%, #fff );
690 - border-color: color-mix( in srgb, var( --wp-admin-theme-color, #2271b1 ) 25%, rgba( 0, 0, 0, 0.08 ) );
769 +/* The lit row: an accent wash and edge at --os-ai-accent's strength,
770 + over the row fill the palette names. Shared with the args-mode rows
771 + below through the same two custom properties. */
772 +.os-ai {
773 + --_row-wash: color-mix(
774 + in srgb,
775 + var( --wp-admin-theme-color, #2271b1 ) calc( var( --os-ai-accent, 100% ) * 0.08 ),
776 + var( --os-ui-surface, #fff )
777 + );
778 + --_row-edge: color-mix(
779 + in srgb,
780 + color-mix(
781 + in srgb,
782 + var( --wp-admin-theme-color, #2271b1 ) 25%,
783 + var( --os-ui-border, rgba( 0, 0, 0, 0.08 ) )
784 + )
785 + var( --os-ai-accent, 100% ),
786 + transparent
787 + );
788 + --_row-fill: linear-gradient(
789 + var( --os-ai-row-fill, transparent ),
790 + var( --os-ai-row-fill, transparent )
791 + );
691 792 }
692 793
794 +.os-ai__cmd-item:hover,
795 +.os-ai__cmd-item.is-selected {
796 + background-color: var( --_row-wash );
797 + background-image: var( --_row-fill );
798 + border-color: var( --_row-edge );
799 +}
800 +
693 801 /*
694 802 * When keyboard navigation is driving selection, suppress the :hover
695 803 * style on rows. Without this, arrowing the cursor past the row that
696 804 * happens to sit under the mouse pointer paints BOTH rows as active
@@ -697,23 +805,24 @@
697 805 * — the keyboard target from `.is-selected` and the pointer target
698 806 * from `:hover`. The JS toggles this class on the list container on
699 807 * ArrowUp/Down and clears it on the next real `mousemove`.
700 808 */
701 -.desktop-mode-ai__cmd-list--kb-nav .desktop-mode-ai__cmd-item:hover {
809 +.os-ai__cmd-list--kb-nav .os-ai__cmd-item:hover {
702 810 background: transparent;
703 811 border-color: transparent;
704 812 }
705 -.desktop-mode-ai__cmd-list--kb-nav .desktop-mode-ai__cmd-item.is-selected:hover {
706 - background: color-mix( in srgb, var( --wp-admin-theme-color, #2271b1 ) 8%, #fff );
707 - border-color: color-mix( in srgb, var( --wp-admin-theme-color, #2271b1 ) 25%, rgba( 0, 0, 0, 0.08 ) );
813 +.os-ai__cmd-list--kb-nav .os-ai__cmd-item.is-selected:hover {
814 + background-color: var( --_row-wash );
815 + background-image: var( --_row-fill );
816 + border-color: var( --_row-edge );
708 817 }
709 818
710 -.desktop-mode-ai__cmd-item:focus-visible {
819 +.os-ai__cmd-item:focus-visible {
711 820 outline: 2px solid var( --wp-admin-theme-color, #2271b1 );
712 821 outline-offset: 2px;
713 822 }
714 823
715 -.desktop-mode-ai__cmd-icon {
824 +.os-ai__cmd-icon {
716 825 flex-shrink: 0;
717 826 display: flex;
718 827 align-items: center;
719 828 justify-content: center;
@@ -719,10 +828,20 @@
719 828 justify-content: center;
720 829 width: 36px;
721 830 height: 36px;
722 831 font-size: 20px;
832 + /* The glyph is the accent in every palette; only its tile follows
833 + --os-ai-accent. */
723 834 color: var( --wp-admin-theme-color, #2271b1 );
724 - background: color-mix( in srgb, var( --wp-admin-theme-color, #2271b1 ) 10%, #fff );
835 + background-color: color-mix(
836 + in srgb,
837 + var( --wp-admin-theme-color, #2271b1 ) calc( var( --os-ai-accent, 100% ) * 0.1 ),
838 + var( --os-ui-surface, #fff )
839 + );
840 + background-image: linear-gradient(
841 + var( --os-ai-tile-fill, transparent ),
842 + var( --os-ai-tile-fill, transparent )
843 + );
725 844 border-radius: 7px;
726 845 }
727 846
728 847 /*
@@ -728,9 +847,9 @@
728 847 /*
729 848 * Dashicons ship at a 20px baseline; the tile was scaled up but
730 849 * dashicons glyphs need explicit sizing to follow.
731 850 */
732 -.desktop-mode-ai__cmd-icon.dashicons {
851 +.os-ai__cmd-icon.dashicons {
733 852 font-size: 22px;
734 853 width: 36px;
735 854 height: 36px;
736 855 line-height: 36px;
@@ -741,15 +860,15 @@
741 860 * `@wordpress/icons` markup). Constrain the inline SVG so it sits
742 861 * centered inside the tile regardless of the viewBox the source icon
743 862 * shipped with.
744 863 */
745 -.desktop-mode-ai__cmd-icon--svg svg {
864 +.os-ai__cmd-icon--svg svg {
746 865 width: 24px;
747 866 height: 24px;
748 867 fill: currentColor;
749 868 }
750 869
751 -.desktop-mode-ai__cmd-body {
870 +.os-ai__cmd-body {
752 871 flex: 1;
753 872 display: flex;
754 873 flex-direction: column;
755 874 gap: 2px;
@@ -755,58 +874,68 @@
755 874 gap: 2px;
756 875 min-width: 0;
757 876 }
758 877
759 -.desktop-mode-ai__cmd-title {
878 +.os-ai__cmd-title {
760 879 font-size: 13px;
761 880 font-weight: 600;
762 - color: #1d2327;
763 - font-family: Menlo, Consolas, monospace;
881 + color: var( --os-ui-fg, #1d2327 );
882 + font-family: var( --os-ui-font-mono, Menlo, Consolas, monospace );
764 883 letter-spacing: -0.01em;
765 884 }
766 885
767 -.desktop-mode-ai__cmd-hint {
886 +.os-ai__cmd-hint {
768 887 font-weight: 400;
769 - color: #8c8f94;
888 + color: var( --os-ui-fg-muted, #8c8f94 );
770 889 font-size: 12px;
771 890 margin-inline-start: 6px;
772 891 }
773 892
774 -.desktop-mode-ai__cmd-desc {
893 +.os-ai__cmd-desc {
775 894 font-size: 11.5px;
776 - color: #646970;
895 + color: var( --os-ui-fg-muted, #646970 );
777 896 line-height: 1.4;
778 897 font-family: inherit;
779 898 letter-spacing: 0;
780 899 }
781 900
901 +/* Entity search results (posts, pages) — rendered in the same list as
902 + commands but are navigable destinations, not actions. Use regular font
903 + (not the monospace used for slash-commands) so they read as content
904 + search results, matching the classic command palette UX. */
905 +.os-ai__cmd-item.is-entity-result .os-ai__cmd-title {
906 + font-family: inherit;
907 + letter-spacing: 0;
908 +}
909 +
782 910 /* Args mode — a single row showing the locked-in command. Same
783 911 visual language as the list item but with an "Enter to run" hint. */
784 -.desktop-mode-ai__cmd-active {
912 +.os-ai__cmd-active {
785 913 display: flex;
786 914 align-items: flex-start;
787 915 gap: 10px;
788 916 padding: 10px 12px;
789 - background: color-mix( in srgb, var( --wp-admin-theme-color, #2271b1 ) 10%, #fff );
790 - border: 1px solid color-mix( in srgb, var( --wp-admin-theme-color, #2271b1 ) 30%, rgba( 0, 0, 0, 0.08 ) );
917 + background-color: var( --_row-wash );
918 + background-image: var( --_row-fill );
919 + border: 1px solid var( --_row-edge );
791 920 border-radius: 8px;
792 921 }
793 922
794 -.desktop-mode-ai__cmd-enter-hint {
923 +.os-ai__cmd-enter-hint {
795 924 font-size: 11px;
796 - color: #646970;
925 + color: var( --os-ui-fg-muted, #646970 );
797 926 margin-top: 2px;
798 927 font-family: inherit;
799 928 }
800 929
801 -.desktop-mode-ai__cmd-enter-hint kbd {
930 +.os-ai__cmd-enter-hint kbd {
802 931 font-family: inherit;
803 932 font-size: 10px;
804 933 padding: 1px 4px;
805 - border: 1px solid rgba( 0, 0, 0, 0.12 );
934 + border: 1px solid var( --os-ui-border, rgba( 0, 0, 0, 0.12 ) );
806 935 border-radius: 3px;
807 - background: rgba( 0, 0, 0, 0.03 );
808 - color: #646970;
936 + background: var( --os-ui-hover, rgba( 0, 0, 0, 0.03 ) );
937 + color: var( --os-ui-fg-muted, #646970 );
809 938 }
810 939
811 940 /* Suggestion list shown under the locked-in command in args mode.
812 941 Visually identical to the command picker rows but without the
@@ -811,9 +940,9 @@
811 940 /* Suggestion list shown under the locked-in command in args mode.
812 941 Visually identical to the command picker rows but without the
813 942 border-highlight — the "active" glow already lives on the command
814 943 header directly above. */
815 -.desktop-mode-ai__cmd-suggest-list {
944 +.os-ai__cmd-suggest-list {
816 945 display: flex;
817 946 flex-direction: column;
818 947 gap: 2px;
819 948 margin-top: 6px;
@@ -818,9 +947,9 @@
818 947 gap: 2px;
819 948 margin-top: 6px;
820 949 }
821 950
822 -.desktop-mode-ai__cmd-suggest-item {
951 +.os-ai__cmd-suggest-item {
823 952 appearance: none;
824 953 display: flex;
825 954 align-items: flex-start;
826 955 gap: 10px;
@@ -834,23 +963,24 @@
834 963 color: inherit;
835 964 transition: background 0.1s, border-color 0.1s;
836 965 }
837 966
838 -.desktop-mode-ai__cmd-suggest-item:hover,
839 -.desktop-mode-ai__cmd-suggest-item.is-selected {
840 - background: color-mix( in srgb, var( --wp-admin-theme-color, #2271b1 ) 8%, #fff );
841 - border-color: color-mix( in srgb, var( --wp-admin-theme-color, #2271b1 ) 25%, rgba( 0, 0, 0, 0.08 ) );
967 +.os-ai__cmd-suggest-item:hover,
968 +.os-ai__cmd-suggest-item.is-selected {
969 + background-color: var( --_row-wash );
970 + background-image: var( --_row-fill );
971 + border-color: var( --_row-edge );
842 972 }
843 973
844 -.desktop-mode-ai__cmd-suggest-label {
974 +.os-ai__cmd-suggest-label {
845 975 font-size: 13px;
846 976 font-weight: 500;
847 - color: #1d2327;
977 + color: var( --os-ui-fg, #1d2327 );
848 978 }
849 979
850 980 /* Empty / "no matches" state for the palette */
851 -.desktop-mode-ai__state--empty {
852 - color: #8c8f94;
981 +.os-ai__state--empty {
982 + color: var( --os-ui-fg-muted, #8c8f94 );
853 983 font-size: 13px;
854 984 }
855 985
856 986 /* -----------------------------------------------------------------
@@ -856,9 +986,9 @@
856 986 /* -----------------------------------------------------------------
857 987 * Continue button (budget-exhausted state)
858 988 * ---------------------------------------------------------------- */
859 989
860 -.desktop-mode-ai__continue-btn {
990 +.os-ai__continue-btn {
861 991 appearance: none;
862 992 display: inline-flex;
863 993 align-items: center;
864 994 align-self: flex-start;
@@ -866,17 +996,17 @@
866 996 font: inherit;
867 997 font-size: 12px;
868 998 font-weight: 500;
869 999 padding: 6px 12px;
870 - border: 1px dashed rgba( 0, 0, 0, 0.2 );
1000 + border: 1px dashed var( --os-ui-border-strong, rgba( 0, 0, 0, 0.2 ) );
871 1001 border-radius: 6px;
872 1002 background: transparent;
873 - color: #50575e;
1003 + color: var( --os-ui-fg-muted, #50575e );
874 1004 cursor: pointer;
875 1005 transition: background 0.1s, border-color 0.1s, color 0.1s;
876 1006 }
877 1007
878 -.desktop-mode-ai__continue-btn:hover {
879 - background: rgba( 0, 0, 0, 0.04 );
880 - border-color: rgba( 0, 0, 0, 0.3 );
881 - color: #1d2327;
1008 +.os-ai__continue-btn:hover {
1009 + background: var( --os-ui-hover, rgba( 0, 0, 0, 0.04 ) );
1010 + border-color: var( --os-ui-border-strong, rgba( 0, 0, 0, 0.3 ) );
1011 + color: var( --os-ui-fg, #1d2327 );
882 1012 }