PluginProbe
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin / 0.9.2
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin v0.9.2
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
desktop-mode / assets / css / plugins-window.css

plugins-window.css in OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin 0.9.2, at assets/css/plugins-window.css

1,038 lines 24.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * Native Plugins window — shell + tab styles.
3 *
4 * Bundle iterates fast; this stylesheet is `filemtime`-cache-busted
5 * via `wp_register_style`. Heavy view-specific styles (gallery
6 * cards, detail-flyout hero) ship here too so a single CSS handle
7 * covers the whole window.
8 */
9
10 .desktop-mode-plugins {
11 display: flex;
12 flex-direction: column;
13 height: 100%;
14 width: 100%;
15 min-height: 0;
16 min-width: 0;
17 max-width: 100%;
18 /* Clip horizontal overflow at every level — `<wpd-flyout>` when
19 * closed sits at `transform: translateX(110%)` and would
20 * otherwise create a phantom scroll out to its off-screen
21 * resting position. We need `overflow-x` AND `position:
22 * relative` so the flyout's `position: absolute` containing
23 * block resolves to THIS element (not a higher ancestor). */
24 overflow-x: hidden;
25 overflow-y: hidden;
26 position: relative;
27 box-sizing: border-box;
28 }
29
30 .desktop-mode-plugins__tabs {
31 border-block-end: 1px solid var( --wpd-border, rgba( 0, 0, 0, 0.08 ) );
32 flex: 0 0 auto;
33 }
34
35 .desktop-mode-plugins__panel {
36 flex: 1 1 auto;
37 min-height: 0;
38 min-width: 0;
39 max-width: 100%;
40 display: flex;
41 flex-direction: column;
42 box-sizing: border-box;
43 /* Belt + braces — never let a child stretch the panel past the
44 * window width. Earlier the right-hand side of the window would
45 * scroll into empty space because the wpd-table host was sized
46 * by content rather than container. */
47 overflow: hidden;
48 }
49
50 /* Honour the `hidden` attribute — `<wpd-tabs>` toggles it on inactive
51 * panels, but our explicit `display: flex` above wins by specificity.
52 * Without this rule every panel renders concurrently in the first
53 * panel slot. */
54 .desktop-mode-plugins__panel[ hidden ] {
55 display: none;
56 }
57
58 .desktop-mode-plugins__installed,
59 .desktop-mode-plugins__browse {
60 flex: 1 1 auto;
61 min-height: 0;
62 display: flex;
63 flex-direction: column;
64 }
65
66 /* ─── Toolbar ───────────────────────────────────────────────────── */
67
68 .desktop-mode-plugins__toolbar {
69 display: flex;
70 align-items: center;
71 gap: 12px;
72 padding: 12px 16px;
73 border-block-end: 1px solid var( --wpd-border, rgba( 0, 0, 0, 0.08 ) );
74 flex-wrap: wrap;
75 }
76
77 .desktop-mode-plugins__toolbar-left {
78 display: flex;
79 align-items: center;
80 gap: 12px;
81 flex: 1 1 auto;
82 min-width: 0;
83 }
84
85 .desktop-mode-plugins__toolbar-left wpd-text-field {
86 flex: 1 1 240px;
87 min-width: 200px;
88 max-width: 360px;
89 }
90
91 .desktop-mode-plugins__toolbar-right {
92 display: flex;
93 align-items: center;
94 gap: 8px;
95 }
96
97 .desktop-mode-plugins__toolbar-trailing {
98 display: flex;
99 align-items: center;
100 gap: 6px;
101 }
102
103 .desktop-mode-plugins__bulk {
104 display: flex;
105 align-items: center;
106 gap: 8px;
107 padding-inline: 8px;
108 }
109
110 .desktop-mode-plugins__bulk-count {
111 font-size: 0.85em;
112 color: var( --wpd-fg-muted, #555 );
113 }
114
115 /* ─── Body / table ──────────────────────────────────────────────── */
116
117 .desktop-mode-plugins__body {
118 flex: 1 1 auto;
119 min-height: 0;
120 min-width: 0;
121 max-width: 100%;
122 overflow: hidden;
123 display: flex;
124 flex-direction: column;
125 box-sizing: border-box;
126 /* Inset matching the Posts/Pages/Users windows so the table
127 * doesn't kiss the window's left/right borders. */
128 padding: 8px 12px 12px;
129 }
130
131 .desktop-mode-plugins__body wpd-table {
132 flex: 1 1 auto;
133 min-height: 0;
134 min-width: 0;
135 max-width: 100%;
136 width: 100%;
137 box-sizing: border-box;
138 /* The `<wpd-table>` ships with its own scroll container, but it
139 * needs a constrained height to know when to start scrolling.
140 * Without `--wpd-table-max-height` set, sticky-header silently
141 * disables itself and the table grows to its full intrinsic
142 * height instead of scrolling inside the panel.
143 *
144 * NO `overflow` here — wpd-table's internal `.scroll` div
145 * handles scrolling. An outer `overflow: auto` here was
146 * causing a phantom horizontal scrollbar that revealed empty
147 * space to the right of the table because the host was sized
148 * by content (icon cell + actions cell) rather than container. */
149 --wpd-table-max-height: 100%;
150 }
151
152 .desktop-mode-plugins__empty {
153 text-align: center;
154 padding: 32px 16px;
155 color: var( --wpd-fg-muted, #666 );
156 }
157
158 .desktop-mode-plugins__empty .dashicons {
159 font-size: 32px;
160 width: 32px;
161 height: 32px;
162 display: inline-block;
163 margin-block-end: 8px;
164 opacity: 0.6;
165 }
166
167 /* ─── Cells ─────────────────────────────────────────────────────── */
168
169 .desktop-mode-plugins__name-cell {
170 display: flex;
171 align-items: center;
172 gap: 12px;
173 min-width: 0;
174 padding-block: 4px;
175 }
176
177 .desktop-mode-plugins__name-icon {
178 flex: 0 0 40px;
179 width: 40px;
180 height: 40px;
181 max-width: 40px;
182 max-height: 40px;
183 border-radius: 8px;
184 overflow: hidden;
185 display: inline-flex;
186 align-items: center;
187 justify-content: center;
188 background: var( --wpd-bg-muted, rgba( 0, 0, 0, 0.04 ) );
189 }
190
191 /* Hard-clamp the inner image too — wp.org SVG icons are unsized,
192 * which left the user agent stretching them to the document's full
193 * width when the parent ever became `auto`. */
194 .desktop-mode-plugins__name-icon img,
195 .desktop-mode-plugins__name-icon svg {
196 width: 100%;
197 height: 100%;
198 max-width: 100%;
199 max-height: 100%;
200 object-fit: contain;
201 display: block;
202 transition: opacity 180ms ease;
203 }
204
205 .desktop-mode-plugins__name-icon-fallback {
206 font-size: 22px;
207 width: 22px;
208 height: 22px;
209 line-height: 22px;
210 color: var( --wpd-fg-muted, #888 );
211 }
212
213 .desktop-mode-plugins__name-text {
214 display: flex;
215 flex-direction: column;
216 gap: 2px;
217 min-width: 0;
218 flex: 1 1 auto;
219 }
220
221 /* Force the title + path to actually stack — `<strong>` and `<span>`
222 * are `display: inline` by default, and `display: flex` on the
223 * parent doesn't always force flex-item layout when the cell
224 * surrounding them comes from a third-party component (the user
225 * reported them rendering on the same line). */
226 .desktop-mode-plugins__name-text > strong,
227 .desktop-mode-plugins__name-text > span {
228 display: block;
229 }
230
231 .desktop-mode-plugins__name-text > strong {
232 font-weight: 600;
233 white-space: nowrap;
234 overflow: hidden;
235 text-overflow: ellipsis;
236 }
237
238 .desktop-mode-plugins__name-path {
239 font-size: 0.78em;
240 color: var( --wpd-fg-muted, #888 );
241 font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
242 white-space: nowrap;
243 overflow: hidden;
244 text-overflow: ellipsis;
245 }
246
247 .desktop-mode-plugins__badge {
248 display: inline-flex;
249 align-items: center;
250 gap: 6px;
251 padding: 2px 10px 2px 8px;
252 border-radius: 999px;
253 font-size: 0.78em;
254 font-weight: 600;
255 letter-spacing: 0.01em;
256 text-transform: none;
257 line-height: 1.4;
258 white-space: nowrap;
259 }
260
261 /* Coloured dot prepended to the badge label — provides the
262 * status-at-a-glance signal without relying on text alone. */
263 .desktop-mode-plugins__badge::before {
264 content: '';
265 width: 6px;
266 height: 6px;
267 border-radius: 50%;
268 background: currentColor;
269 flex: 0 0 auto;
270 display: inline-block;
271 }
272
273 .desktop-mode-plugins__badge.is-active {
274 background: rgba( 35, 165, 90, 0.14 );
275 color: rgb( 22, 110, 55 );
276 }
277
278 .desktop-mode-plugins__badge.is-inactive {
279 background: rgba( 120, 120, 120, 0.12 );
280 color: var( --wpd-fg-muted, #555 );
281 }
282
283 .desktop-mode-plugins__version-cell {
284 display: flex;
285 align-items: center;
286 gap: 6px;
287 flex-wrap: wrap;
288 }
289
290 .desktop-mode-plugins__update-badge {
291 font-size: 0.78em;
292 background: rgba( 250, 175, 0, 0.18 );
293 color: rgb( 145, 95, 0 );
294 padding: 1px 7px;
295 border-radius: 999px;
296 font-weight: 600;
297 }
298
299 .desktop-mode-plugins__author-cell {
300 white-space: nowrap;
301 overflow: hidden;
302 text-overflow: ellipsis;
303 }
304
305 .desktop-mode-plugins__row-actions {
306 display: inline-flex;
307 gap: 8px;
308 align-items: center;
309 justify-content: flex-end;
310 flex-wrap: nowrap;
311 }
312
313 .desktop-mode-plugins__row-actions wpd-button {
314 flex: 0 0 auto;
315 }
316
317 /* ─── Browse — gallery ──────────────────────────────────────────── */
318
319 .desktop-mode-plugins__gallery {
320 display: grid;
321 grid-template-columns: repeat( auto-fill, minmax( 280px, 1fr ) );
322 gap: 14px;
323 padding: 16px;
324 flex: 1 1 auto;
325 min-height: 0;
326 min-width: 0;
327 max-width: 100%;
328 /* Vertical scroll only — `auto-fill` with `1fr` already prevents
329 * children from exceeding the container width, but we still
330 * clamp `overflow-x` defensively so a misbehaving card can't
331 * stretch the gallery. */
332 overflow-x: hidden;
333 overflow-y: auto;
334 align-content: start;
335 box-sizing: border-box;
336 }
337
338 .desktop-mode-plugins__gallery-sentinel {
339 height: 1px;
340 }
341
342 .desktop-mode-plugins__gallery-status {
343 padding: 12px 16px;
344 color: var( --wpd-fg-muted, #666 );
345 text-align: center;
346 margin: 0;
347 }
348
349 /* ─── Browse — card ─────────────────────────────────────────────── */
350
351 /* The card chrome (padding, gap, border, radius, hover lift, focus
352 * ring, reduced-motion fallback) all comes from `<wpd-card>` —
353 * `:host([interactive])` handles the hover transform, the kit's
354 * `prefers-reduced-motion` rule kills the transition. We layer
355 * gallery-specific tweaks here; nothing duplicates the kit. */
356
357 .desktop-mode-plugins__card.desktop-mode-plugins__card--skeleton {
358 gap: 8px;
359 }
360
361 .desktop-mode-plugins__card-header {
362 display: flex;
363 gap: 12px;
364 align-items: center;
365 }
366
367 .desktop-mode-plugins__card-icon {
368 flex: 0 0 auto;
369 width: 56px;
370 height: 56px;
371 border-radius: 10px;
372 overflow: hidden;
373 display: inline-flex;
374 align-items: center;
375 justify-content: center;
376 background: var( --wpd-bg-muted, rgba( 0, 0, 0, 0.04 ) );
377 }
378
379 .desktop-mode-plugins__card-icon img {
380 width: 100%;
381 height: 100%;
382 object-fit: contain;
383 opacity: 0;
384 transition: opacity 180ms ease;
385 }
386
387 .desktop-mode-plugins__card-icon img.is-loaded {
388 opacity: 1;
389 }
390
391 .desktop-mode-plugins__card-icon-fallback {
392 font-size: 28px;
393 width: 28px;
394 height: 28px;
395 color: var( --wpd-fg-muted, #888 );
396 }
397
398 .desktop-mode-plugins__card-titleblock {
399 min-width: 0;
400 flex: 1 1 auto;
401 }
402
403 .desktop-mode-plugins__card-title {
404 margin: 0 0 2px 0;
405 font-size: 1rem;
406 font-weight: 600;
407 white-space: nowrap;
408 overflow: hidden;
409 text-overflow: ellipsis;
410 }
411
412 .desktop-mode-plugins__card-byline {
413 margin: 0;
414 color: var( --wpd-fg-muted, #777 );
415 font-size: 0.82rem;
416 white-space: nowrap;
417 overflow: hidden;
418 text-overflow: ellipsis;
419 }
420
421 .desktop-mode-plugins__card-desc {
422 margin: 0;
423 color: var( --wpd-fg, #333 );
424 font-size: 0.88rem;
425 line-height: 1.45;
426 display: -webkit-box;
427 -webkit-line-clamp: 3;
428 line-clamp: 3;
429 -webkit-box-orient: vertical;
430 overflow: hidden;
431 }
432
433 .desktop-mode-plugins__card-footer {
434 display: flex;
435 align-items: center;
436 justify-content: space-between;
437 gap: 8px;
438 margin-top: auto;
439 }
440
441 .desktop-mode-plugins__card-meta {
442 display: flex;
443 flex-direction: column;
444 gap: 2px;
445 font-size: 0.78rem;
446 color: var( --wpd-fg-muted, #666 );
447 }
448
449 /* ─── Stars ─────────────────────────────────────────────────────── */
450
451 .desktop-mode-plugins__stars {
452 display: inline-flex;
453 align-items: center;
454 gap: 2px;
455 }
456
457 .desktop-mode-plugins__star .dashicons {
458 font-size: 14px;
459 width: 14px;
460 height: 14px;
461 color: rgb( 245, 175, 0 );
462 }
463
464 .desktop-mode-plugins__star .dashicons-star-empty {
465 color: var( --wpd-fg-muted, rgba( 0, 0, 0, 0.25 ) );
466 }
467
468 .desktop-mode-plugins__stars-count {
469 margin-inline-start: 4px;
470 color: var( --wpd-fg-muted, #888 );
471 font-size: 0.78em;
472 }
473
474 .desktop-mode-plugins__card-installs {
475 font-size: 0.78em;
476 color: var( --wpd-fg-muted, #888 );
477 }
478
479 /* ─── Skeleton lines (gallery + flyout) ─────────────────────────── */
480
481 .desktop-mode-plugins__skeleton {
482 display: flex;
483 flex-direction: column;
484 gap: 8px;
485 padding: 16px;
486 }
487
488 .desktop-mode-plugins__skeleton-line {
489 display: block;
490 height: 12px;
491 border-radius: 4px;
492 background: linear-gradient(
493 90deg,
494 rgba( 0, 0, 0, 0.06 ) 0%,
495 rgba( 0, 0, 0, 0.10 ) 50%,
496 rgba( 0, 0, 0, 0.06 ) 100%
497 );
498 background-size: 200% 100%;
499 animation: dm-plugins-shimmer 1.4s linear infinite;
500 }
501
502 @keyframes dm-plugins-shimmer {
503 from {
504 background-position: 100% 0;
505 }
506 to {
507 background-position: -100% 0;
508 }
509 }
510
511 @media ( prefers-reduced-motion: reduce ) {
512 .desktop-mode-plugins__skeleton-line {
513 animation: none;
514 }
515 }
516
517 /* ─── Flyout detail ─────────────────────────────────────────────── */
518
519 [data-desktop-mode-plugins-flyout] {
520 width: min( 560px, calc( 100% - 28px ) );
521 }
522
523 .desktop-mode-plugins__flyout {
524 display: flex;
525 flex-direction: column;
526 height: 100%;
527 min-height: 0;
528 }
529
530 .desktop-mode-plugins__flyout-hero {
531 position: relative;
532 padding: 16px 56px 14px 18px;
533 border-block-end: 1px solid var( --wpd-border, rgba( 0, 0, 0, 0.08 ) );
534 flex: 0 0 auto;
535 overflow: hidden;
536 /* Mirror the flyout shell's outer corner radius (`<wpd-flyout>`
537 * uses 14px) so a banner background-image stops at the rounded
538 * top edge instead of bleeding past it. */
539 border-start-start-radius: 14px;
540 border-start-end-radius: 14px;
541 }
542
543 /* ─── Flyout close — circular glass button ──────────────────────── */
544
545 .desktop-mode-plugins__flyout-close {
546 position: absolute;
547 inset-block-start: 12px;
548 inset-inline-end: 12px;
549 width: 32px;
550 height: 32px;
551 padding: 0;
552 border: 1px solid rgba( 0, 0, 0, 0.08 );
553 border-radius: 50%;
554 background: rgba( 255, 255, 255, 0.78 );
555 -webkit-backdrop-filter: blur( 12px ) saturate( 160% );
556 backdrop-filter: blur( 12px ) saturate( 160% );
557 box-shadow:
558 0 1px 4px rgba( 0, 0, 0, 0.10 ),
559 0 0 0 1px rgba( 255, 255, 255, 0.4 ) inset;
560 color: var( --wpd-fg, #333 );
561 display: inline-flex;
562 align-items: center;
563 justify-content: center;
564 cursor: pointer;
565 z-index: 2;
566 transition:
567 transform 150ms ease,
568 background 150ms ease,
569 border-color 150ms ease,
570 box-shadow 150ms ease;
571 }
572
573 .desktop-mode-plugins__flyout-close:hover {
574 background: rgba( 255, 255, 255, 0.96 );
575 transform: scale( 1.06 );
576 border-color: rgba( 0, 0, 0, 0.16 );
577 box-shadow:
578 0 4px 10px rgba( 0, 0, 0, 0.14 ),
579 0 0 0 1px rgba( 255, 255, 255, 0.5 ) inset;
580 }
581
582 .desktop-mode-plugins__flyout-close:active {
583 transform: scale( 0.96 );
584 }
585
586 .desktop-mode-plugins__flyout-close:focus-visible {
587 outline: 2px solid var( --wp-admin-theme-color, #2271b1 );
588 outline-offset: 2px;
589 }
590
591 @media ( prefers-reduced-motion: reduce ) {
592 .desktop-mode-plugins__flyout-close {
593 transition: none;
594 }
595 .desktop-mode-plugins__flyout-close:hover,
596 .desktop-mode-plugins__flyout-close:active {
597 transform: none;
598 }
599 }
600
601 .desktop-mode-plugins__flyout-banner {
602 position: absolute;
603 inset: 0;
604 background-size: cover;
605 background-position: center;
606 opacity: 0;
607 transition: opacity 220ms ease;
608 z-index: 0;
609 }
610
611 .desktop-mode-plugins__flyout-banner.has-banner {
612 opacity: 0.18;
613 }
614
615 .desktop-mode-plugins__flyout-hero-inner {
616 position: relative;
617 display: flex;
618 gap: 12px;
619 align-items: center;
620 z-index: 1;
621 }
622
623 .desktop-mode-plugins__flyout-hero-icon {
624 width: 64px;
625 height: 64px;
626 border-radius: 12px;
627 overflow: hidden;
628 background: var( --wpd-bg-muted, rgba( 0, 0, 0, 0.04 ) );
629 flex: 0 0 auto;
630 display: inline-flex;
631 align-items: center;
632 justify-content: center;
633 }
634
635 .desktop-mode-plugins__flyout-hero-icon img {
636 width: 100%;
637 height: 100%;
638 object-fit: contain;
639 }
640
641 .desktop-mode-plugins__flyout-hero-text {
642 flex: 1 1 auto;
643 min-width: 0;
644 }
645
646 .desktop-mode-plugins__flyout-hero-title {
647 margin: 0 0 4px;
648 font-size: 1.2rem;
649 font-weight: 600;
650 }
651
652 .desktop-mode-plugins__flyout-hero-byline {
653 margin: 0 0 6px;
654 color: var( --wpd-fg-muted, #666 );
655 }
656
657 .desktop-mode-plugins__flyout-meta-row {
658 display: flex;
659 flex-wrap: wrap;
660 gap: 4px 16px;
661 font-size: 0.78rem;
662 color: var( --wpd-fg-muted, #666 );
663 margin-top: 6px;
664 }
665
666 .desktop-mode-plugins__flyout-tabs {
667 flex: 0 0 auto;
668 border-block-end: 1px solid var( --wpd-border, rgba( 0, 0, 0, 0.08 ) );
669 }
670
671 .desktop-mode-plugins__flyout-body {
672 padding: 16px 18px;
673 flex: 1 1 auto;
674 overflow: auto;
675 min-height: 0;
676 }
677
678 .desktop-mode-plugins__flyout-footer {
679 display: flex;
680 align-items: center;
681 justify-content: space-between;
682 gap: 8px;
683 padding: 12px 16px;
684 border-block-start: 1px solid var( --wpd-border, rgba( 0, 0, 0, 0.08 ) );
685 flex: 0 0 auto;
686 }
687
688 .desktop-mode-plugins__flyout-footer-right {
689 display: inline-flex;
690 gap: 6px;
691 }
692
693 .desktop-mode-plugins__flyout-wporg {
694 font-size: 0.86rem;
695 }
696
697 .desktop-mode-plugins__flyout-error {
698 color: rgb( 184, 50, 50 );
699 padding: 16px;
700 }
701
702 /* ─── Histogram (Reviews tab) ───────────────────────────────────── */
703
704 .desktop-mode-plugins__histogram {
705 display: flex;
706 flex-direction: column;
707 gap: 6px;
708 margin-block-end: 16px;
709 }
710
711 .desktop-mode-plugins__histogram-row {
712 display: grid;
713 grid-template-columns: 32px 1fr 48px;
714 gap: 8px;
715 align-items: center;
716 font-size: 0.82rem;
717 }
718
719 .desktop-mode-plugins__histogram-track {
720 background: var( --wpd-bg-muted, rgba( 0, 0, 0, 0.06 ) );
721 border-radius: 999px;
722 height: 6px;
723 overflow: hidden;
724 }
725
726 .desktop-mode-plugins__histogram-fill {
727 display: block;
728 height: 100%;
729 background: rgb( 245, 175, 0 );
730 border-radius: 999px;
731 transition: width 220ms ease;
732 }
733
734 .desktop-mode-plugins__histogram-count {
735 color: var( --wpd-fg-muted, #777 );
736 text-align: end;
737 }
738
739 .desktop-mode-plugins__reviews-list {
740 display: flex;
741 flex-direction: column;
742 gap: 12px;
743 }
744
745 .desktop-mode-plugins__review {
746 border: 1px solid var( --wpd-border, rgba( 0, 0, 0, 0.08 ) );
747 border-radius: 10px;
748 padding: 12px 14px;
749 background: var( --wpd-card-bg, #fff );
750 }
751
752 .desktop-mode-plugins__review-head {
753 display: flex;
754 align-items: center;
755 gap: 12px;
756 margin-block-end: 6px;
757 flex-wrap: wrap;
758 }
759
760 .desktop-mode-plugins__review-author {
761 font-weight: 600;
762 }
763
764 .desktop-mode-plugins__review-date {
765 margin-inline-start: auto;
766 font-size: 0.78em;
767 color: var( --wpd-fg-muted, #888 );
768 }
769
770 .desktop-mode-plugins__review-excerpt {
771 margin: 0;
772 font-size: 0.92em;
773 line-height: 1.5;
774 color: var( --wpd-fg, #333 );
775 }
776
777 .desktop-mode-plugins__review-link {
778 display: inline-block;
779 margin-block-start: 6px;
780 font-size: 0.82em;
781 }
782
783 .desktop-mode-plugins__reviews-loading,
784 .desktop-mode-plugins__reviews-fallback {
785 color: var( --wpd-fg-muted, #888 );
786 font-size: 0.92em;
787 }
788
789 .desktop-mode-plugins__html {
790 font-size: 0.92rem;
791 line-height: 1.5;
792 }
793
794 .desktop-mode-plugins__html h3,
795 .desktop-mode-plugins__html h4 {
796 margin-top: 1em;
797 }
798
799 .desktop-mode-plugins__screenshots {
800 display: flex;
801 flex-direction: column;
802 gap: 14px;
803 }
804
805 .desktop-mode-plugins__screenshot img {
806 max-width: 100%;
807 border-radius: 8px;
808 border: 1px solid var( --wpd-border, rgba( 0, 0, 0, 0.08 ) );
809 }
810
811 .desktop-mode-plugins__screenshot figcaption {
812 font-size: 0.84rem;
813 color: var( --wpd-fg-muted, #666 );
814 margin-top: 6px;
815 }
816
817 /* ─── Upload dialog ─────────────────────────────────────────────── */
818
819 .desktop-mode-plugins__upload-overlay {
820 position: absolute;
821 inset: 0;
822 background: rgba( 0, 0, 0, 0.32 );
823 display: flex;
824 align-items: center;
825 justify-content: center;
826 z-index: 20;
827 animation: dm-plugins-fade-in 180ms ease both;
828 }
829
830 .desktop-mode-plugins__upload-card {
831 width: min( 480px, calc( 100% - 32px ) );
832 background: var( --wpd-card-bg, #fff );
833 border-radius: 14px;
834 padding: 22px 22px 18px;
835 box-shadow: 0 16px 48px rgba( 0, 0, 0, 0.32 );
836 animation: dm-plugins-pop-in 220ms cubic-bezier( 0.22, 1, 0.36, 1 ) both;
837 }
838
839 @keyframes dm-plugins-fade-in {
840 from { opacity: 0; }
841 to { opacity: 1; }
842 }
843
844 @keyframes dm-plugins-pop-in {
845 from { transform: scale( 0.96 ); opacity: 0; }
846 to { transform: none; opacity: 1; }
847 }
848
849 @media ( prefers-reduced-motion: reduce ) {
850 .desktop-mode-plugins__upload-overlay,
851 .desktop-mode-plugins__upload-card {
852 animation: none;
853 }
854 }
855
856 .desktop-mode-plugins__upload-heading {
857 margin: 0 0 4px;
858 font-size: 1.1rem;
859 }
860
861 .desktop-mode-plugins__upload-lede {
862 margin: 0 0 16px;
863 color: var( --wpd-fg-muted, #666 );
864 font-size: 0.9em;
865 }
866
867 .desktop-mode-plugins__upload-dropzone {
868 border: 2px dashed var( --wpd-border-strong, rgba( 0, 0, 0, 0.18 ) );
869 border-radius: 12px;
870 padding: 24px 16px;
871 text-align: center;
872 cursor: pointer;
873 transition: border-color 150ms ease, background 150ms ease;
874 }
875
876 .desktop-mode-plugins__upload-dropzone.is-hovered,
877 .desktop-mode-plugins__upload-dropzone.has-file {
878 border-color: var( --wp-admin-theme-color, #2271b1 );
879 background: rgba( 34, 113, 177, 0.05 );
880 }
881
882 .desktop-mode-plugins__upload-icon {
883 font-size: 32px;
884 width: 32px;
885 height: 32px;
886 color: var( --wpd-fg-muted, #888 );
887 margin-block-end: 6px;
888 }
889
890 .desktop-mode-plugins__upload-hint {
891 margin: 0 0 4px;
892 }
893
894 .desktop-mode-plugins__upload-filename {
895 margin: 0;
896 font-size: 0.86em;
897 color: var( --wpd-fg, #333 );
898 font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
899 }
900
901 .desktop-mode-plugins__upload-status {
902 margin: 12px 0 0;
903 font-size: 0.86em;
904 }
905
906 .desktop-mode-plugins__upload-status[ data-tone='error' ] {
907 color: rgb( 184, 50, 50 );
908 }
909
910 .desktop-mode-plugins__upload-status[ data-tone='success' ] {
911 color: rgb( 25, 120, 65 );
912 }
913
914 .desktop-mode-plugins__upload-actions {
915 display: flex;
916 justify-content: flex-end;
917 gap: 8px;
918 margin-block-start: 14px;
919 }
920
921 .desktop-mode-plugins__upload-success-heading {
922 margin: 4px 0 6px;
923 font-size: 1rem;
924 color: rgb( 25, 120, 65 );
925 }
926
927 .desktop-mode-plugins__upload-success-detail {
928 margin: 0 0 6px;
929 color: var( --wpd-fg, #333 );
930 font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
931 font-size: 0.9em;
932 }
933
934 /* ─── Window-level .zip drop overlay ────────────────────────────── */
935
936 .desktop-mode-plugins__window-drop {
937 position: absolute;
938 inset: 12px;
939 border: 2px dashed var( --wp-admin-theme-color, #2271b1 );
940 border-radius: 14px;
941 background: rgba( 34, 113, 177, 0.08 );
942 color: var( --wp-admin-theme-color, #2271b1 );
943 display: flex;
944 align-items: center;
945 justify-content: center;
946 font-size: 1.05rem;
947 font-weight: 600;
948 pointer-events: none;
949 opacity: 0;
950 transition: opacity 180ms ease;
951 z-index: 9;
952 }
953
954 .has-zip-dragover .desktop-mode-plugins__window-drop {
955 opacity: 1;
956 }
957
958 /* ─── Drag ghost ────────────────────────────────────────────────── */
959
960 .desktop-mode-plugins__drag-ghost {
961 display: inline-flex;
962 align-items: center;
963 gap: 8px;
964 padding: 8px 14px;
965 background: var( --wpd-card-bg, #fff );
966 border-radius: 999px;
967 box-shadow: 0 6px 20px rgba( 0, 0, 0, 0.18 );
968 font-size: 0.92rem;
969 font-weight: 600;
970 max-width: 240px;
971 white-space: nowrap;
972 overflow: hidden;
973 text-overflow: ellipsis;
974 }
975
976 .desktop-mode-plugins__drag-ghost img {
977 width: 24px;
978 height: 24px;
979 border-radius: 6px;
980 }
981
982 .desktop-mode-plugins__drag-ghost-fallback {
983 color: var( --wpd-fg-muted, #888 );
984 font-size: 22px;
985 }
986
987 [ data-plugins-card-drop-active ] {
988 outline: 2px dashed var( --wp-admin-theme-color, #2271b1 );
989 outline-offset: 2px;
990 }
991 /* Row-click cue — pointer-cursor on Installed-tab body rows so users
992 * discover that clicking the plugin name expands the detail panel.
993 * `<wpd-table>` exposes each body `<tr>` as a `row` shadow part. */
994
995 wpd-table[ data-installed-rows ]::part( row ) {
996 cursor: pointer;
997 }
998
999 /* ─── Featured tab ─────────────────────────────────────────────── */
1000
1001 .desktop-mode-plugins__featured {
1002 display: flex;
1003 flex-direction: column;
1004 min-height: 0;
1005 flex: 1 1 auto;
1006 }
1007
1008 .desktop-mode-plugins__featured-intro {
1009 padding: 20px 20px 4px;
1010 display: flex;
1011 flex-direction: column;
1012 gap: 4px;
1013 }
1014
1015 .desktop-mode-plugins__featured-heading {
1016 margin: 0;
1017 font-size: 1.15em;
1018 font-weight: 600;
1019 }
1020
1021 .desktop-mode-plugins__featured-blurb {
1022 margin: 0;
1023 color: var( --wpd-fg-muted, #666 );
1024 font-size: 0.9em;
1025 line-height: 1.45;
1026 }
1027
1028 /* Curated cards get a soft inset border + a `<wpd-ribbon>` stamped
1029 * onto the top-end corner. The card host carries `position: relative`
1030 * so the ribbon's `position: absolute` anchors to the card itself,
1031 * not to whatever positioned ancestor lives further out. The ribbon
1032 * owns its own clipping geometry; nothing else here needs to know
1033 * about the diagonal. */
1034 .desktop-mode-plugins__card--featured {
1035 position: relative;
1036 box-shadow: 0 0 0 1px var( --wp-admin-theme-color, #2271b1 ) inset;
1037 }
1038