PluginProbe
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin / 1.1.13
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin v1.1.13
1.1.13 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 All 37 releases
← All changes | assets/css/my-wordpress.css +661 -142 1.1.3 → 1.1.13 View file →
@@ -846,9 +846,9 @@
846 846 font-size: 11px;
847 847 font-weight: 600;
848 848 text-transform: uppercase;
849 849 letter-spacing: 0.04em;
850 - background: rgba( 34, 113, 177, 0.12 );
850 + background: color-mix( in srgb, var( --wp-admin-theme-color, #2271b1 ) 12%, transparent );
851 851 color: var( --wp-admin-theme-color, #2271b1 );
852 852 }
853 853
854 854 .os-my-wordpress__user-links {
@@ -868,9 +868,9 @@
868 868
869 869 .os-my-wordpress__user-bio {
870 870 font-size: 14px;
871 871 line-height: 1.5;
872 - color: var( --os-fg, #1d2327 );
872 + color: var( --os-my-wordpress-fg, var( --os-ui-fg, #1d2327 ) );
873 873 margin: 0 0 16px;
874 874 padding-left: 12px;
875 875 border-left: 3px solid var( --os-ui-border, #dcdcde );
876 876 }
@@ -951,9 +951,9 @@
951 951 .os-my-wordpress__user-spark-bar {
952 952 background: linear-gradient(
953 953 180deg,
954 954 var( --wp-admin-theme-color, #2271b1 ) 0%,
955 - rgba( 34, 113, 177, 0.55 ) 100%
955 + color-mix( in srgb, var( --wp-admin-theme-color, #2271b1 ) 55%, transparent ) 100%
956 956 );
957 957 border-radius: 3px 3px 0 0;
958 958 min-height: 2px;
959 959 transition: height 0.3s ease;
@@ -1087,9 +1087,9 @@
1087 1087 }
1088 1088
1089 1089 .os-my-wordpress__term-icon--category {
1090 1090 background: linear-gradient( 135deg, var( --os-ui-accent, #2271b1 ) 0%, var( --os-ui-accent-strong, #135e96 ) 100% );
1091 - box-shadow: 0 4px 12px rgba( 34, 113, 177, 0.32 );
1091 + box-shadow: 0 4px 12px color-mix( in srgb, var( --wp-admin-theme-color, #2271b1 ) 32%, transparent );
1092 1092 }
1093 1093
1094 1094 .os-my-wordpress__term-icon--tag {
1095 1095 background: linear-gradient( 135deg, #7c3aed 0%, #5b21b6 100% );
@@ -1096,9 +1096,9 @@
1096 1096 box-shadow: 0 4px 12px rgba( 124, 58, 237, 0.32 );
1097 1097 }
1098 1098
1099 1099 .os-my-wordpress__user-role--category {
1100 - background: rgba( 34, 113, 177, 0.12 );
1100 + background: color-mix( in srgb, var( --wp-admin-theme-color, #2271b1 ) 12%, transparent );
1101 1101 color: var( --os-ui-accent-strong, #135e96 );
1102 1102 }
1103 1103
1104 1104 .os-my-wordpress__user-role--tag {
@@ -1158,9 +1158,9 @@
1158 1158 * for users with moderate_comments.
1159 1159 * --------------------------------------------------------------- */
1160 1160
1161 1161 .os-my-wordpress__comment-status--approved {
1162 - background: rgba( 34, 113, 177, 0.12 );
1162 + background: color-mix( in srgb, var( --wp-admin-theme-color, #2271b1 ) 12%, transparent );
1163 1163 color: var( --os-ui-accent-strong, #135e96 );
1164 1164 }
1165 1165
1166 1166 .os-my-wordpress__comment-status--pending {
@@ -1191,9 +1191,9 @@
1191 1191 .os-my-wordpress__comment-quote {
1192 1192 margin: 0 0 16px;
1193 1193 padding: 10px 14px;
1194 1194 border-left: 3px solid var( --wp-admin-theme-color, #2271b1 );
1195 - background: rgba( 34, 113, 177, 0.06 );
1195 + background: color-mix( in srgb, var( --wp-admin-theme-color, #2271b1 ) 6%, transparent );
1196 1196 border-radius: 0 6px 6px 0;
1197 1197 font-size: 13px;
1198 1198 }
1199 1199
@@ -1207,9 +1207,9 @@
1207 1207 }
1208 1208
1209 1209 .os-my-wordpress__comment-quote p {
1210 1210 margin: 0;
1211 - color: var( --os-fg, #1d2327 );
1211 + color: var( --os-my-wordpress-fg, var( --os-ui-fg, #1d2327 ) );
1212 1212 }
1213 1213
1214 1214 /* Comment body — same style as article-content but with a soft
1215 1215 * card background so it reads as the focal element. */
@@ -1299,9 +1299,9 @@
1299 1299
1300 1300 .os-my-wordpress__comment-reply-excerpt {
1301 1301 margin: 0;
1302 1302 font-size: 13px;
1303 - color: var( --os-fg, #1d2327 );
1303 + color: var( --os-my-wordpress-fg, var( --os-ui-fg, #1d2327 ) );
1304 1304 line-height: 1.45;
1305 1305 }
1306 1306
1307 1307 /* =================================================================== *
@@ -1336,10 +1336,10 @@
1336 1336 border-radius: 50%;
1337 1337 overflow: hidden;
1338 1338 background: linear-gradient(
1339 1339 135deg,
1340 - rgba( 34, 113, 177, 0.18 ),
1341 - rgba( 34, 113, 177, 0.04 )
1340 + color-mix( in srgb, var( --wp-admin-theme-color, #2271b1 ) 18%, transparent ),
1341 + color-mix( in srgb, var( --wp-admin-theme-color, #2271b1 ) 4%, transparent )
1342 1342 );
1343 1343 box-shadow:
1344 1344 inset 0 0 0 1px rgba( 0, 0, 0, 0.08 ),
1345 1345 0 2px 6px rgba( 0, 0, 0, 0.08 );
@@ -1460,10 +1460,10 @@
1460 1460 padding: 24px;
1461 1461 border-radius: 16px;
1462 1462 background: linear-gradient(
1463 1463 135deg,
1464 - rgba( 34, 113, 177, 0.10 ) 0%,
1465 - rgba( 34, 113, 177, 0.02 ) 60%,
1464 + color-mix( in srgb, var( --wp-admin-theme-color, #2271b1 ) 10%, transparent ) 0%,
1465 + color-mix( in srgb, var( --wp-admin-theme-color, #2271b1 ) 2%, transparent ) 60%,
1466 1466 transparent 100%
1467 1467 );
1468 1468 border: 1px solid var( --os-ui-border, #dcdcde );
1469 1469 }
@@ -1478,10 +1478,10 @@
1478 1478 inset 0 0 0 2px rgba( 255, 255, 255, 0.8 ),
1479 1479 0 6px 24px rgba( 0, 0, 0, 0.14 );
1480 1480 background: linear-gradient(
1481 1481 135deg,
1482 - rgba( 34, 113, 177, 0.18 ),
1483 - rgba( 34, 113, 177, 0.04 )
1482 + color-mix( in srgb, var( --wp-admin-theme-color, #2271b1 ) 18%, transparent ),
1483 + color-mix( in srgb, var( --wp-admin-theme-color, #2271b1 ) 4%, transparent )
1484 1484 );
1485 1485 display: inline-flex;
1486 1486 align-items: center;
1487 1487 justify-content: center;
@@ -1506,14 +1506,17 @@
1506 1506 flex-direction: column;
1507 1507 gap: 8px;
1508 1508 }
1509 1509
1510 +/* Window text reads the app's own foreground, never `--os-fg`: that token
1511 + * is the shell's text ON THE DESK, so a light theme (Legacy) leaves it
1512 + * white and the name vanished into the white hero. */
1510 1513 .os-my-wordpress__footprint-title {
1511 1514 margin: 0;
1512 1515 font-size: 28px;
1513 1516 line-height: 1.15;
1514 1517 font-weight: 700;
1515 - color: var( --os-fg, #1d2327 );
1518 + color: var( --os-my-wordpress-fg, var( --os-ui-fg, #1d2327 ) );
1516 1519 }
1517 1520
1518 1521 .os-my-wordpress__footprint-meta {
1519 1522 display: flex;
@@ -1613,17 +1616,17 @@
1613 1616 background: var( --os-ui-hover, rgba( 0, 0, 0, 0.06 ) );
1614 1617 }
1615 1618
1616 1619 .os-my-wordpress__footprint-cell--l1 {
1617 - background: rgba( 34, 113, 177, 0.25 );
1620 + background: color-mix( in srgb, var( --wp-admin-theme-color, #2271b1 ) 25%, transparent );
1618 1621 }
1619 1622
1620 1623 .os-my-wordpress__footprint-cell--l2 {
1621 - background: rgba( 34, 113, 177, 0.5 );
1624 + background: color-mix( in srgb, var( --wp-admin-theme-color, #2271b1 ) 50%, transparent );
1622 1625 }
1623 1626
1624 1627 .os-my-wordpress__footprint-cell--l3 {
1625 - background: rgba( 34, 113, 177, 0.75 );
1628 + background: color-mix( in srgb, var( --wp-admin-theme-color, #2271b1 ) 75%, transparent );
1626 1629 }
1627 1630
1628 1631 .os-my-wordpress__footprint-cell--l4 {
1629 1632 background: var( --wp-admin-theme-color, #2271b1 );
@@ -1693,9 +1696,9 @@
1693 1696 .os-my-wordpress__footprint-bar {
1694 1697 background: linear-gradient(
1695 1698 180deg,
1696 1699 var( --wp-admin-theme-color, #2271b1 ) 0%,
1697 - rgba( 34, 113, 177, 0.55 ) 100%
1700 + color-mix( in srgb, var( --wp-admin-theme-color, #2271b1 ) 55%, transparent ) 100%
1698 1701 );
1699 1702 border-radius: 3px 3px 0 0;
1700 1703 min-height: 2px;
1701 1704 transition: opacity 0.2s ease;
@@ -1727,10 +1730,10 @@
1727 1730 text-align: center;
1728 1731 padding: 20px 24px;
1729 1732 background: linear-gradient(
1730 1733 135deg,
1731 - rgba( 34, 113, 177, 0.10 ),
1732 - rgba( 34, 113, 177, 0.02 )
1734 + color-mix( in srgb, var( --wp-admin-theme-color, #2271b1 ) 10%, transparent ),
1735 + color-mix( in srgb, var( --wp-admin-theme-color, #2271b1 ) 2%, transparent )
1733 1736 );
1734 1737 }
1735 1738
1736 1739 .os-my-wordpress__footprint-callout-label {
@@ -1744,9 +1747,9 @@
1744 1747 .os-my-wordpress__footprint-callout-value {
1745 1748 margin: 2px 0;
1746 1749 font-size: 24px;
1747 1750 font-weight: 700;
1748 - color: var( --os-fg, #1d2327 );
1751 + color: var( --os-my-wordpress-fg, var( --os-ui-fg, #1d2327 ) );
1749 1752 }
1750 1753
1751 1754 .os-my-wordpress__footprint-callout-detail {
1752 1755 margin: 0;
@@ -2155,17 +2158,8 @@
2155 2158 overflow: hidden;
2156 2159 box-sizing: border-box;
2157 2160 }
2158 2161
2159 -/* The framework is opt-in but the section is always listed, so with
2160 - the option off the surface paints inert rather than vanishing.
2161 - Only the sidebar dims: the detail pane holds the empty state
2162 - explaining why, and the one button that undoes it — dimming the way
2163 - out along with everything else is how a disabled screen becomes a
2164 - dead end. */
2165 -.dm-agents.is-disabled .dm-agents__sidebar {
2166 - opacity: 0.6;
2167 -}
2168 2162
2169 2163 /* Section-level loading — same scale curve as the My WordPress
2170 2164 preview loader and the window-loading overlay, instead of the bare
2171 2165 48px component default. */
@@ -2180,103 +2174,8 @@
2180 2174 .dm-agents__loading os-spinner {
2181 2175 --os-ui-spinner-size: clamp( 96px, 14vw, 192px );
2182 2176 }
2183 2177
2184 -.dm-agents__layout {
2185 - display: flex;
2186 - flex: 1;
2187 - min-height: 0;
2188 - gap: 12px;
2189 -}
2190 -
2191 -/* Sidebar column: a fixed "Create agent" header over the scrolling
2192 - list. The button used to be the list's last child, which put it out
2193 - of reach on any site with enough agents to need it. */
2194 -.dm-agents__sidebar {
2195 - display: flex;
2196 - flex-direction: column;
2197 - flex: 0 0 260px;
2198 - /* `min-width: auto` on a flex item resolves to its min-content
2199 - width, and the rows carry long `white-space: nowrap` descriptions
2200 - — without this the column ignores its 260px basis and eats the
2201 - detail pane. The scroll container used to be this item, whose
2202 - non-visible overflow zeroed the minimum for free. */
2203 - min-width: 0;
2204 - min-height: 0;
2205 - border-inline-end: 1px solid var( --os-border, rgba( 0, 0, 0, 0.08 ) );
2206 -}
2207 -
2208 -.dm-agents__list-toolbar {
2209 - flex: none;
2210 - display: flex;
2211 - padding-block-end: 8px;
2212 - padding-inline-end: 8px;
2213 -}
2214 -
2215 -.dm-agents__list-toolbar .dm-agents__create {
2216 - flex: 1;
2217 -}
2218 -
2219 -.dm-agents__list {
2220 - display: flex;
2221 - flex-direction: column;
2222 - gap: 4px;
2223 - flex: 1;
2224 - min-height: 0;
2225 - overflow-y: auto;
2226 - padding-inline-end: 4px;
2227 -}
2228 -
2229 -.dm-agents__row {
2230 - display: flex;
2231 - align-items: center;
2232 - gap: 8px;
2233 - padding: 8px;
2234 - border-radius: 8px;
2235 - cursor: pointer;
2236 -}
2237 -
2238 -.dm-agents__row:hover {
2239 - background: var( --os-hover, rgba( 0, 0, 0, 0.06 ) );
2240 -}
2241 -
2242 -.dm-agents__row.is-selected {
2243 - background: var( --os-selected, rgba( 0, 0, 0, 0.1 ) );
2244 -}
2245 -
2246 -.dm-agents__row-avatar {
2247 - width: 32px;
2248 - height: 32px;
2249 - border-radius: 50%;
2250 - /* Placeholder behind the avatar image while it loads — follows the
2251 - palette so it isn't a white disc on a dark station. */
2252 - background: var( --os-ui-surface-elevated, #fff );
2253 - flex: none;
2254 -}
2255 -
2256 -.dm-agents__row-text {
2257 - display: flex;
2258 - flex-direction: column;
2259 - min-width: 0;
2260 - flex: 1;
2261 -}
2262 -
2263 -.dm-agents__row-name {
2264 - font-weight: 600;
2265 - white-space: nowrap;
2266 - overflow: hidden;
2267 - text-overflow: ellipsis;
2268 -}
2269 -
2270 -.dm-agents__row-desc {
2271 - font-size: 12px;
2272 - opacity: 0.65;
2273 - white-space: nowrap;
2274 - overflow: hidden;
2275 - text-overflow: ellipsis;
2276 -}
2277 -
2278 -
2279 2178 .dm-agents__detail {
2280 2179 flex: 1;
2281 2180 min-width: 0;
2282 2181 overflow-y: auto;
@@ -2385,31 +2284,156 @@
2385 2284 font-size: 12px;
2386 2285 opacity: 0.7;
2387 2286 }
2388 2287
2288 +/* Role first: least privilege is the decision, so the control holds
2289 + the mockup's width instead of stretching into a landing strip. */
2290 +.dm-agents__role-select {
2291 + max-width: 280px;
2292 +}
2293 +
2294 +/* The ability filter. Sized like the role select rather than the
2295 + full pane: it sits above a list of rules, and a search box as wide
2296 + as the rules reads as another one of them. */
2297 +.dm-agents__ability-search {
2298 + display: block;
2299 + max-width: 320px;
2300 + margin: 12px 0 4px;
2301 +}
2302 +
2303 +/* Each category is a native disclosure. `<details>` because the
2304 + behaviour is exactly what it is for: keyboard, screen-reader
2305 + semantics and the open/closed state all arrive for free, and the
2306 + only thing left to write is the costume. */
2307 +.dm-agents__ability-group {
2308 + border-bottom: 1px solid var( --os-border, rgba( 0, 0, 0, 0.08 ) );
2309 +}
2310 +
2311 +.dm-agents__ability-group:last-of-type {
2312 + border-bottom: 0;
2313 +}
2314 +
2389 2315 .dm-agents__category {
2390 - margin: 8px 0 0;
2391 - font-size: 12px;
2316 + margin: 18px 0 2px;
2317 + font-family: var( --os-ui-font-mono, ui-monospace, monospace );
2318 + font-size: 11px;
2319 + font-weight: 500;
2392 2320 text-transform: uppercase;
2393 - letter-spacing: 0.04em;
2394 - opacity: 0.6;
2321 + letter-spacing: 0.08em;
2322 + color: var( --os-ui-fg-muted, #646970 );
2395 2323 }
2396 2324
2325 +/* A `<summary>` is a button, so it gets a button's affordances: a
2326 + pointer, a hover, and a focus ring that is visible on the dark
2327 + surface the section is drawn on. */
2328 +summary.dm-agents__category {
2329 + display: flex;
2330 + align-items: center;
2331 + gap: 8px;
2332 + margin: 0;
2333 + padding: 10px 0;
2334 + cursor: pointer;
2335 + list-style: none;
2336 + user-select: none;
2337 +}
2338 +
2339 +summary.dm-agents__category::-webkit-details-marker {
2340 + display: none;
2341 +}
2342 +
2343 +/* The marker is drawn here rather than left to the UA so it can be
2344 + the same triangle in every browser and turn with the disclosure.
2345 + Rotation only: a transform, so opening a group of forty rows
2346 + costs no layout. */
2347 +summary.dm-agents__category::before {
2348 + content: '';
2349 + flex: none;
2350 + width: 0;
2351 + height: 0;
2352 + border-inline-start: 5px solid currentcolor;
2353 + border-block: 4px solid transparent;
2354 + transition: transform 120ms ease;
2355 +}
2356 +
2357 +.dm-agents__ability-group[ open ] > summary.dm-agents__category::before {
2358 + transform: rotate( 90deg );
2359 +}
2360 +
2361 +@media ( prefers-reduced-motion: reduce ) {
2362 + summary.dm-agents__category::before {
2363 + transition: none;
2364 + }
2365 +}
2366 +
2367 +summary.dm-agents__category:hover {
2368 + color: var( --os-ui-fg, #1e1e1e );
2369 +}
2370 +
2371 +summary.dm-agents__category:focus-visible {
2372 + outline: 2px solid var( --os-ui-accent, #3858e9 );
2373 + outline-offset: 2px;
2374 + border-radius: 4px;
2375 +}
2376 +
2377 +.dm-agents__category-name {
2378 + flex: 1 1 auto;
2379 +}
2380 +
2381 +/* "3 of 12" when some are ticked, otherwise just the size of the
2382 + group. The count is why a closed group is still informative:
2383 + collapsing must not hide the fact that something in there is
2384 + switched on. */
2385 +.dm-agents__category-count {
2386 + flex: none;
2387 + font-variant-numeric: tabular-nums;
2388 + opacity: 0.75;
2389 +}
2390 +
2391 +/* One ability per row, ruled like the mockup: tick and name on the
2392 + left, badge on the right, the description indented under the name
2393 + (the checkbox column is the control's own 26px). */
2397 2394 .dm-agents__ability {
2398 2395 display: grid;
2399 2396 grid-template-columns: 1fr auto;
2400 - gap: 2px 8px;
2401 - align-items: center;
2402 - padding: 4px 0;
2397 + gap: 2px 10px;
2398 + align-items: start;
2399 + padding: 11px 0;
2400 + border-bottom: 1px solid var( --os-border, rgba( 0, 0, 0, 0.08 ) );
2403 2401 }
2404 2402
2403 +.dm-agents__ability:last-of-type {
2404 + border-bottom: 0;
2405 +}
2406 +
2405 2407 .dm-agents__ability-desc {
2406 2408 grid-column: 1 / -1;
2407 2409 margin: 0;
2408 - font-size: 12px;
2409 - opacity: 0.6;
2410 + padding-inline-start: 26px;
2411 + font-size: 12.5px;
2412 + color: var( --os-ui-fg-muted, #646970 );
2410 2413 }
2411 2414
2415 +/* Access badges in the instrument voice. The palette's own warning
2416 + tokens carry the pale-yellow "can modify"; all this changes is the
2417 + costume: mono, uppercase, an outline instead of a wash. */
2418 +.dm-agents__ability os-badge {
2419 + --os-ui-badge-font: 500 10px/1.6 var( --os-ui-font-mono, ui-monospace, monospace );
2420 + --os-ui-badge-dot-size: 0;
2421 + --os-ui-badge-gap: 0;
2422 + --os-ui-badge-padding: 3px 8px;
2423 + --os-ui-badge-bg: transparent;
2424 + --os-ui-badge-border: 1px solid var( --os-border, rgba( 0, 0, 0, 0.12 ) );
2425 + text-transform: uppercase;
2426 + letter-spacing: 0.06em;
2427 + white-space: nowrap;
2428 + margin-top: 2px;
2429 +}
2430 +
2431 +.dm-agents__ability os-badge[ tone='warning' ] {
2432 + --os-ui-badge-border: 1px solid
2433 + var( --os-ui-warning-border, rgba( 154, 103, 0, 0.4 ) );
2434 +}
2435 +
2412 2436 .dm-agents__trigger {
2413 2437 border: 1px solid var( --os-border, rgba( 0, 0, 0, 0.08 ) );
2414 2438 border-radius: 8px;
2415 2439 padding: 8px 10px;
@@ -2423,15 +2447,12 @@
2423 2447 align-items: center;
2424 2448 gap: 8px;
2425 2449 }
2426 2450
2427 -.dm-agents__trigger-summary {
2428 - flex: 1;
2451 +.dm-agents__trigger-desc {
2452 + margin: 0;
2429 2453 font-size: 12px;
2430 - opacity: 0.65;
2431 - white-space: nowrap;
2432 - overflow: hidden;
2433 - text-overflow: ellipsis;
2454 + opacity: 0.75;
2434 2455 }
2435 2456
2436 2457 .dm-agents__trigger-config {
2437 2458 display: flex;
@@ -2441,5 +2462,503 @@
2441 2462
2442 2463 .dm-agents__actions {
2443 2464 display: flex;
2444 2465 gap: 8px;
2466 + align-items: center;
2467 + flex-wrap: wrap;
2468 + margin-block-start: 12px;
2469 +}
2470 +
2471 +/* ---------------------------------------------------------------------
2472 + The cast
2473 + ------------------------------------------------------------------ */
2474 +
2475 +/* One view at a time: the grid, an agent, or the wizard. A sidebar of
2476 + faces next to a detail form would leave neither enough room, and the
2477 + whole point of the grid is that the faces are big enough to tell
2478 + apart. */
2479 +/* The pane scrolls, and a scroll container clips ink overflow: a field
2480 + flush with its edge loses the focus halo the kit paints outside the
2481 + border (1px ring + 4px bloom), so the brief's ring read as a top and
2482 + bottom line with nothing at the sides. Trade 5px of the section's
2483 + 12px padding for a gutter inside the pane; the content does not move. */
2484 +.dm-agents__view {
2485 + display: flex;
2486 + flex-direction: column;
2487 + flex: 1;
2488 + min-height: 0;
2489 + overflow-y: auto;
2490 + gap: 12px;
2491 + margin-inline: -5px;
2492 + padding-inline: 5px;
2493 +}
2494 +
2495 +.dm-agents__cast-head {
2496 + display: flex;
2497 + align-items: baseline;
2498 + gap: 8px;
2499 +}
2500 +
2501 +.dm-agents__cast-head h3 {
2502 + margin: 0;
2503 +}
2504 +
2505 +.dm-agents__cast-count {
2506 + font-family: var( --os-ui-font-mono, ui-monospace, monospace );
2507 + font-size: 12px;
2508 + color: var( --os-ui-fg-muted, #646970 );
2509 +}
2510 +
2511 +.dm-agents__cast {
2512 + display: grid;
2513 + gap: 16px;
2514 + grid-template-columns: repeat( auto-fill, minmax( 288px, 1fr ) );
2515 + align-content: start;
2516 +}
2517 +
2518 +/* The card reacts like the mockup's: a lift and a brighter edge.
2519 + Transform and border-color only — both cheap, and the same pair the
2520 + mockup transitions. Document styles win over the component's own
2521 + :host rules, which is the sanctioned way to restyle a host. */
2522 +.dm-agents__cast-card,
2523 +.dm-agents__cast-new {
2524 + --os-ui-card-padding: 20px 18px 16px;
2525 + transition: border-color 0.18s ease, transform 0.18s ease;
2526 +}
2527 +
2528 +.dm-agents__cast-card:hover,
2529 +.dm-agents__cast-card:focus-within {
2530 + border-color: var( --os-ui-border-strong, #8c8f94 );
2531 + transform: translateY( -2px );
2532 +}
2533 +
2534 +/* The dashed door, same as the mockup's crew-new card. */
2535 +.dm-agents__cast-new {
2536 + border-style: dashed;
2537 + --os-ui-card-bg: var( --os-ui-surface-subtle, transparent );
2538 +}
2539 +
2540 +/* The crew breathes. Transform only, staggered so five faces do not
2541 + bob in lockstep, and gone entirely under reduced motion. */
2542 +@media ( prefers-reduced-motion: no-preference ) {
2543 + .dm-agents__cast-card .dm-agents__cast-face {
2544 + animation: dm-agents-bob 6s ease-in-out infinite;
2545 + }
2546 + .dm-agents__cast-card:nth-child( 2n ) .dm-agents__cast-face {
2547 + animation-duration: 7.2s;
2548 + animation-delay: -1.4s;
2549 + }
2550 + .dm-agents__cast-card:nth-child( 3n ) .dm-agents__cast-face {
2551 + animation-duration: 6.6s;
2552 + animation-delay: -2.8s;
2553 + }
2554 +}
2555 +
2556 +@keyframes dm-agents-bob {
2557 + 0%,
2558 + 100% {
2559 + transform: translateY( 0 );
2560 + }
2561 + 50% {
2562 + transform: translateY( -4px );
2563 + }
2564 +}
2565 +
2566 +/* The column lives on a wrapper we own, not on the host: the slotted
2567 + children sit inside the card's own container, so a flex rule on the
2568 + host never reaches them and the role badges land wherever the
2569 + description's line count leaves them. */
2570 +.dm-agents__cast-inner {
2571 + display: flex;
2572 + flex-direction: column;
2573 + align-items: center;
2574 + text-align: center;
2575 + gap: 2px;
2576 + height: 100%;
2577 +}
2578 +
2579 +/* The faces are the loud part of this surface, and deliberately so:
2580 + agent identity is the one place the station spends the mesh budget
2581 + on something other than a hero CTA. A cast has to be legible at a
2582 + glance, which is exactly what a flat accent cannot do. */
2583 +.dm-agents__cast-face {
2584 + width: 118px;
2585 + height: 118px;
2586 + margin: -10px 0 6px;
2587 + flex: none;
2588 +}
2589 +
2590 +.dm-agents__cast-name {
2591 + font-size: 17px;
2592 + font-weight: 600;
2593 + color: var( --os-ui-fg, #1d2327 );
2594 +}
2595 +
2596 +/* The voice line, in the instrument register: this is metadata about
2597 + the agent, not prose from it. */
2598 +.dm-agents__cast-vibes {
2599 + font-family: var( --os-ui-font-mono, ui-monospace, monospace );
2600 + font-size: 11.5px;
2601 + color: var( --os-ui-accent-strong, #2271b1 );
2602 +}
2603 +
2604 +.dm-agents__cast-good {
2605 + font-size: 13px;
2606 + color: var( --os-ui-fg-muted, #646970 );
2607 + margin-block: 4px 14px;
2608 + flex: 1;
2609 +}
2610 +
2611 +/* The role pill in the instrument voice: mono, uppercase, no status
2612 + dot — this is a fact about the agent, not a state to monitor. The
2613 + custom properties are the component's own theming hooks; the
2614 + inherited text properties flow into its shadow label. */
2615 +.dm-agents__cast-card os-badge {
2616 + --os-ui-badge-font: 500 11px/1.6 var( --os-ui-font-mono, ui-monospace, monospace );
2617 + --os-ui-badge-dot-size: 0;
2618 + --os-ui-badge-gap: 0;
2619 + --os-ui-badge-padding: 3px 10px;
2620 + text-transform: uppercase;
2621 + letter-spacing: 0.08em;
2622 +}
2623 +
2624 +/* The framework-off bar: the section's status and its one action, on
2625 + one line above the crew it would hire. It is deliberately not an
2626 + `os-empty-state` — that block is centred, icon-led and paragraph-
2627 + shaped, which is exactly the wall of text the cast replaced, and at
2628 + five cards tall it would push the button that undoes the situation
2629 + off the bottom of the window. `flex: none` because `.dm-agents__view`
2630 + is a scrolling flex column and the bar must not absorb the slack. */
2631 +.dm-agents__off-head {
2632 + display: flex;
2633 + align-items: center;
2634 + justify-content: space-between;
2635 + flex-wrap: wrap;
2636 + flex: none;
2637 + gap: 8px 16px;
2638 + padding: 12px 14px;
2639 + border-radius: 10px;
2640 + background: var( --os-ui-surface-elevated, #fff );
2641 + border: 1px solid var( --os-border, rgba( 0, 0, 0, 0.08 ) );
2642 +}
2643 +
2644 +.dm-agents__off-copy {
2645 + min-width: 0;
2646 +}
2647 +
2648 +.dm-agents__off-copy h3 {
2649 + margin: 0;
2650 +}
2651 +
2652 +.dm-agents__off-copy p {
2653 + margin: 2px 0 0;
2654 + font-size: 13px;
2655 + color: var( --os-ui-fg-muted, #646970 );
2656 +}
2657 +
2658 +/* The cast the site would get, drawn while the framework is off.
2659 + Dimmed as a whole rather than desaturated: the five hues ARE the
2660 + argument this state is making, and a greyscale filter would flatten
2661 + the crew into five identical blobs on the way to saying "not yet".
2662 + Opacity says inactive and leaves the faces telling each other apart.
2663 +
2664 + `pointer-events` is belt and braces — the cards are rendered without
2665 + `interactive` and without a click handler, so there is nothing to
2666 + press. It exists so a hover state cannot promise otherwise. */
2667 +.dm-agents__cast--preview {
2668 + opacity: 0.6;
2669 + pointer-events: none;
2670 +}
2671 +
2672 +.dm-agents__cast-new .dm-agents__cast-plus {
2673 + display: grid;
2674 + place-items: center;
2675 + width: 118px;
2676 + height: 118px;
2677 + margin: -10px 0 6px;
2678 + border-radius: 50%;
2679 + border: 1.5px dashed var( --os-ui-border-strong, #8c8f94 );
2680 + font-size: 30px;
2681 + font-weight: 300;
2682 + line-height: 1;
2683 + color: var( --os-ui-fg-muted, #646970 );
2684 +}
2685 +
2686 +/* ---------------------------------------------------------------------
2687 + The wizard
2688 + ------------------------------------------------------------------ */
2689 +
2690 +.dm-agents__wizard {
2691 + display: flex;
2692 + flex-direction: column;
2693 + gap: 10px;
2694 +}
2695 +
2696 +.dm-agents__wiz-head {
2697 + display: flex;
2698 + align-items: center;
2699 + justify-content: space-between;
2700 + gap: 8px 12px;
2701 + flex-wrap: wrap;
2702 +}
2703 +
2704 +.dm-agents__wiz-head h3 {
2705 + margin: 0;
2706 +}
2707 +
2708 +/* The trail wears the instrument voice: mono uppercase labels, 22px
2709 + dots, a thin rule between stations. All of it goes through the
2710 + component's own theming hooks; the host elements live in this light
2711 + DOM, so the per-state overrides below can select them directly. */
2712 +.dm-agents__trail {
2713 + margin-block: 6px 14px;
2714 + --os-ui-steps-gap: 10px;
2715 + --os-ui-step-gap: 7px;
2716 + --os-ui-step-chip-size: 22px;
2717 + --os-ui-step-chip-font-size: 11px;
2718 + --os-ui-step-chip-family: var( --os-ui-font-mono, ui-monospace, monospace );
2719 + --os-ui-step-title-size: 11px;
2720 + --os-ui-step-title-family: var( --os-ui-font-mono, ui-monospace, monospace );
2721 + --os-ui-step-title-transform: uppercase;
2722 + --os-ui-step-title-spacing: 0.08em;
2723 +}
2724 +
2725 +/* A station you have not reached is an outline, not a filled dot: the
2726 + mesh chip is where you ARE, and it only reads that way if it is the
2727 + only one lit. */
2728 +.dm-agents__trail os-step:not( [ done ] ):not( [ current ] ) {
2729 + --os-ui-step-chip-bg: transparent;
2730 + --os-ui-step-chip-border: 1px solid var( --os-ui-border-strong, #8c8f94 );
2731 + --os-ui-step-chip-fg: var( --os-ui-fg-muted, #646970 );
2732 +}
2733 +
2734 +/* Done is quiet: a filled tick on the elevated surface, muted like its
2735 + label. It reads as history, not as a second highlight. */
2736 +.dm-agents__trail os-step[ done ] {
2737 + --os-ui-step-chip-done-bg: var( --os-ui-surface-elevated, #f0f0f1 );
2738 + --os-ui-step-chip-fg: var( --os-ui-fg-muted, #646970 );
2739 +}
2740 +
2741 +.dm-agents__wiz-heading {
2742 + margin: 12px 0 2px;
2743 + font-size: 16px;
2744 + font-weight: 600;
2745 + color: var( --os-ui-fg, #1d2327 );
2746 +}
2747 +
2748 +/* The door. Five complete agents already ship with the plugin, and
2749 + until now the create flow showed them to nobody. */
2750 +.dm-agents__starters {
2751 + display: grid;
2752 + gap: 12px;
2753 + grid-template-columns: repeat( auto-fill, minmax( 148px, 1fr ) );
2754 + margin-block: 8px 16px;
2755 +}
2756 +
2757 +.dm-agents__starter {
2758 + display: flex;
2759 + flex-direction: column;
2760 + align-items: center;
2761 + text-align: center;
2762 + gap: 3px;
2763 + --os-ui-card-padding: 16px 14px;
2764 + --os-ui-card-radius: 10px;
2765 + --os-ui-card-bg: var( --os-ui-surface-subtle, transparent );
2766 + transition: border-color 0.18s ease;
2767 +}
2768 +
2769 +.dm-agents__starter:hover,
2770 +.dm-agents__starter:focus-within {
2771 + border-color: var( --os-ui-border-strong, #8c8f94 );
2772 +}
2773 +
2774 +.dm-agents__starter-face {
2775 + width: 76px;
2776 + height: 76px;
2777 + margin: -8px 0 4px;
2778 + flex: none;
2779 +}
2780 +
2781 +.dm-agents__starter-name {
2782 + font-size: 14px;
2783 + font-weight: 500;
2784 + color: var( --os-ui-fg, #1d2327 );
2785 +}
2786 +
2787 +.dm-agents__starter-vibes {
2788 + font-family: var( --os-ui-font-mono, ui-monospace, monospace );
2789 + font-size: 11.5px;
2790 + color: var( --os-ui-fg-muted, #646970 );
2791 +}
2792 +
2793 +/* Meet: the portrait beside the fields, so the thing being named is
2794 + visible while it is being named. */
2795 +.dm-agents__meet {
2796 + display: grid;
2797 + gap: 20px;
2798 + grid-template-columns: 220px 1fr;
2799 + align-items: start;
2800 +}
2801 +
2802 +/* The character card. Sunken rather than subtle: the portrait is the
2803 + hero of this step, and the mockup floats it on the darkest surface
2804 + so the face's own glow does the framing. */
2805 +.dm-agents__portrait {
2806 + display: flex;
2807 + flex-direction: column;
2808 + align-items: center;
2809 + gap: 10px;
2810 + padding: 20px 14px 14px;
2811 + border: 1px solid var( --os-border, rgba( 0, 0, 0, 0.08 ) );
2812 + border-radius: var( --os-ui-card-radius, 10px );
2813 + background: var( --os-ui-surface-sunken, #f6f7f7 );
2814 +}
2815 +
2816 +.dm-agents__portrait-face {
2817 + width: 176px;
2818 + height: 176px;
2819 + max-width: 100%;
2820 + margin-top: -12px;
2821 +}
2822 +
2823 +/* What this face is, in two words. */
2824 +.dm-agents__portrait-chips {
2825 + display: flex;
2826 + gap: 6px;
2827 + flex-wrap: wrap;
2828 + justify-content: center;
2829 +}
2830 +
2831 +.dm-agents__faces {
2832 + display: grid;
2833 + grid-template-columns: repeat( 6, 1fr );
2834 + gap: 2px;
2835 + width: 100%;
2836 +}
2837 +
2838 +.dm-agents__face-pick {
2839 + display: grid;
2840 + place-items: center;
2841 + padding: 2px;
2842 + border: 1px solid transparent;
2843 + border-radius: 8px;
2844 + background: none;
2845 + cursor: pointer;
2846 +}
2847 +
2848 +.dm-agents__face-pick img {
2849 + width: 100%;
2850 + height: auto;
2851 + display: block;
2852 +}
2853 +
2854 +.dm-agents__face-pick:hover {
2855 + border-color: var( --os-ui-border-strong, #8c8f94 );
2856 +}
2857 +
2858 +.dm-agents__face-pick.is-picked {
2859 + border-color: var( --os-ui-accent, #2271b1 );
2860 +}
2861 +
2862 +.dm-agents__face-pick:focus-visible {
2863 + outline: var( --os-ui-focus-ring, 2px solid #2271b1 );
2864 + outline-offset: 1px;
2865 +}
2866 +
2867 +.dm-agents__meet-fields {
2868 + display: flex;
2869 + flex-direction: column;
2870 + gap: 10px;
2871 + min-width: 0;
2872 +}
2873 +
2874 +/* Launch: one card, the brand's card radius, floating on the darkest
2875 + surface like the portrait it echoes. */
2876 +.dm-agents__summary {
2877 + display: grid;
2878 + grid-template-columns: 106px 1fr;
2879 + gap: 18px;
2880 + align-items: start;
2881 + --os-ui-card-padding: 18px;
2882 + --os-ui-card-radius: 10px;
2883 + --os-ui-card-bg: var( --os-ui-surface-sunken, #f6f7f7 );
2884 +}
2885 +
2886 +.dm-agents__summary-face {
2887 + width: 106px;
2888 + height: 106px;
2889 + flex: none;
2890 +}
2891 +
2892 +.dm-agents__summary-text h4 {
2893 + margin: 0 0 2px;
2894 + font-size: 17px;
2895 +}
2896 +
2897 +.dm-agents__summary-vibes {
2898 + font-family: var( --os-ui-font-mono, ui-monospace, monospace );
2899 + font-size: 11.5px;
2900 + color: var( --os-ui-accent-strong, #2271b1 );
2901 + margin: 0 0 6px;
2902 +}
2903 +
2904 +.dm-agents__summary-desc {
2905 + margin: 0;
2906 + font-size: 13px;
2907 + color: var( --os-ui-fg-muted, #646970 );
2908 +}
2909 +
2910 +.dm-agents__chips {
2911 + display: flex;
2912 + flex-wrap: wrap;
2913 + gap: 6px;
2914 + margin-block-start: 10px;
2915 +}
2916 +
2917 +/* What the agent will actually be told, under the chips. Clamped: a
2918 + summary card quotes the instructions, it does not host them. */
2919 +.dm-agents__summary-instr {
2920 + margin: 10px 0 0;
2921 + font-size: 13px;
2922 + color: var( --os-ui-fg-muted, #646970 );
2923 + display: -webkit-box;
2924 + -webkit-line-clamp: 3;
2925 + -webkit-box-orient: vertical;
2926 + overflow: hidden;
2927 +}
2928 +
2929 +/* Identity chips — role, abilities, silhouette, hue — all wear the
2930 + instrument voice: these are facts about the character, stamped
2931 + rather than said. */
2932 +.dm-agents__chips os-chip,
2933 +.dm-agents__portrait-chips os-chip {
2934 + --os-ui-chip-font-size: 10.5px;
2935 + --os-ui-chip-font-weight: 500;
2936 + --os-ui-chip-bg: transparent;
2937 + --os-ui-chip-fg: var( --os-ui-fg-muted, #646970 );
2938 + --os-ui-chip-border: 1px solid var( --os-border, rgba( 0, 0, 0, 0.12 ) );
2939 + font-family: var( --os-ui-font-mono, ui-monospace, monospace );
2940 + text-transform: uppercase;
2941 + letter-spacing: 0.06em;
2942 +}
2943 +
2944 +.dm-agents__spacer {
2945 + flex: 1;
2946 +}
2947 +
2948 +@media ( max-width: 640px ) {
2949 + .dm-agents__meet,
2950 + .dm-agents__summary {
2951 + grid-template-columns: 1fr;
2952 + }
2953 + .dm-agents__portrait-face {
2954 + width: 128px;
2955 + height: 128px;
2956 + }
2957 +}
2958 +
2959 +/* The way back to the grid. The window's own breadcrumb goes UP to the
2960 + folder, which is a different journey: this one returns to the cast. */
2961 +.dm-agents__back {
2962 + align-self: flex-start;
2963 + margin-block-end: 4px;
2445 2964 }