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