PluginProbe
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin / 1.1.9
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin v1.1.9
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 0.8.6 All 33 releases
desktop-mode / apps / comments / comments.css

comments.css in OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin 1.1.9, at apps/comments/comments.css

687 lines 17.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /*
2 * Comments app — two-pane conversation view.
3 *
4 * Thread rail (left) + nested conversation (right) + composer.
5 * Variables come from `variables.css`; this file just maps them onto
6 * the comments-specific markup so the window picks up theme +
7 * color-scheme changes for free. Controls that have a `<os-*>`
8 * component are styled through that component's documented custom
9 * properties rather than re-implemented here.
10 */
11
12 .os-comments {
13 display: flex;
14 flex-direction: column;
15 /*
16 * `block-size` (not `min-block-size`) — pins the container to the
17 * window body's exact height so the inner flex column has a fixed
18 * frame to distribute against. With `min-block-size` the scrolling
19 * panes grew past the frame and pushed the composer off the bottom
20 * edge of the window. `box-sizing: border-box` keeps any padding
21 * inside the 100% box.
22 */
23 box-sizing: border-box;
24 block-size: 100%;
25 inline-size: 100%;
26 overflow: hidden;
27 position: relative;
28 /* A query container, so the one-pane rules at the end of this file
29 track the WINDOW's width — a phone, or a desktop window pulled in. */
30 container-type: inline-size;
31 color: var( --os-ui-fg, #1d2327 );
32 }
33
34 /*
35 * Any element inside the comments window that opts into HTML's
36 * `hidden` attribute is hidden — full stop. Without this rule the
37 * `display: flex` on `__msg-actions` would win against the UA
38 * stylesheet's bare `[hidden]` selector (class beats element), and
39 * the action row would stay on screen underneath the inline comment
40 * editor that just replaced it. Authoritative single override.
41 */
42 .os-comments [hidden] {
43 display: none !important;
44 }
45
46 /*
47 * Local fallback for core's visually-hidden helper. wp-admin defines
48 * `.screen-reader-text` and the shell renders inside wp-admin, but the
49 * status dots and link hints below are meaningless without it — worth
50 * not depending on load order for.
51 */
52 .os-comments .screen-reader-text {
53 position: absolute;
54 width: 1px;
55 height: 1px;
56 margin: -1px;
57 padding: 0;
58 overflow: hidden;
59 clip-path: inset( 50% );
60 white-space: nowrap;
61 border: 0;
62 }
63
64 /* ── Tab strip ───────────────────────────────────────────────── */
65 /*
66 * `<os-tabs>` brings its own chrome, roving tabindex and focus ring.
67 * All that's needed here is the strip's place in the column and the
68 * count chip slotted into each `<os-tab>` (light DOM, so a plain
69 * descendant selector reaches it).
70 */
71 .os-comments__tabrow {
72 flex: 0 0 auto;
73 padding-inline: 12px;
74 border-block-end: 1px solid var( --os-ui-border, #dcdcde );
75 }
76
77 /* `<os-badge no-dot>` owns the pill — this is spacing only. */
78 .os-comments__tab-count {
79 --os-ui-badge-padding: 1px 6px;
80 --os-ui-badge-font: 500 11px/1.4 var( --os-font, system-ui );
81 margin-inline-start: 6px;
82 font-variant-numeric: tabular-nums;
83 }
84
85 /* ── Split ───────────────────────────────────────────────────── */
86 .os-comments__split {
87 flex: 1 1 auto;
88 min-block-size: 0;
89 display: grid;
90 grid-template-columns: 306px 1fr;
91 overflow: hidden;
92 }
93
94 /* ── Left rail ───────────────────────────────────────────────── */
95 .os-comments__rail {
96 border-inline-end: 1px solid var( --os-ui-border, #dcdcde );
97 display: flex;
98 flex-direction: column;
99 min-block-size: 0;
100 background: var( --os-ui-surface-sunken, #fbfbfc );
101 }
102
103 .os-comments__search {
104 padding: 12px;
105 flex: 0 0 auto;
106 }
107
108 .os-comments__search os-text-field {
109 display: block;
110 width: 100%;
111 }
112
113 .os-comments__list {
114 overflow-y: auto;
115 flex: 1 1 auto;
116 min-block-size: 0;
117 }
118
119 /* "Scoped to one post" banner at the top of the rail. */
120 .os-comments__rail-filter {
121 display: flex;
122 align-items: center;
123 justify-content: space-between;
124 gap: 8px;
125 padding: 8px 14px;
126 font-size: 12px;
127 background: color-mix( in srgb, var( --os-ui-accent, #2271b1 ) 8%, transparent );
128 border-block-end: 1px solid var( --os-ui-border, #dcdcde );
129 }
130 .os-comments__rail-filter-label {
131 color: var( --os-ui-fg, #1d2327 );
132 font-weight: 600;
133 overflow: hidden;
134 text-overflow: ellipsis;
135 white-space: nowrap;
136 }
137 .os-comments__rail-filter-clear {
138 flex: 0 0 auto;
139 --os-ui-button-padding: 0;
140 font-size: 12px;
141 }
142
143 /* `role="listitem"` wrapper — the row itself has to stay a button. */
144 .os-comments__thread-slot {
145 display: block;
146 }
147
148 .os-comments__thread {
149 display: grid;
150 grid-template-columns: 36px 1fr auto;
151 gap: 10px;
152 padding: 12px 14px;
153 cursor: pointer;
154 border-block-end: 1px solid color-mix( in srgb, currentColor 6%, transparent );
155 position: relative;
156 text-align: start;
157 appearance: none;
158 background: transparent;
159 border-inline: 0;
160 border-block-start: 0;
161 font: inherit;
162 color: inherit;
163 width: 100%;
164 }
165
166 .os-comments__thread:hover {
167 background: var( --os-ui-hover, rgba( 0, 0, 0, 0.045 ) );
168 }
169
170 .os-comments__thread:focus-visible {
171 outline: 2px solid var( --os-ui-accent, #2271b1 );
172 outline-offset: -2px;
173 }
174
175 .os-comments__thread.is-selected {
176 background: color-mix( in srgb, var( --os-ui-accent, #2271b1 ) 8%, transparent );
177 }
178
179 .os-comments__thread.is-selected::before {
180 content: "";
181 position: absolute;
182 inset-inline-start: 0;
183 inset-block: 0;
184 width: 3px;
185 background: var( --os-ui-accent, #2271b1 );
186 }
187
188 /* In-flight moderation on this conversation. */
189 .os-comments__thread.is-busy {
190 opacity: 0.5;
191 pointer-events: none;
192 }
193
194 /*
195 * Avatar. `<os-avatar>` owns the circle, the hue, the initials
196 * fallback and its own sizing (via the `size` attribute) — anything
197 * set here would be a light-DOM author style overriding the
198 * component's `:host` rules, so this stays to layout only.
199 */
200 .os-comments__disc {
201 flex: 0 0 auto;
202 }
203
204 .os-comments__thread-main {
205 min-width: 0;
206 }
207
208 .os-comments__thread-name {
209 font-size: 13.5px;
210 font-weight: 600;
211 color: var( --os-ui-fg, #1d2327 );
212 display: flex;
213 align-items: center;
214 gap: 6px;
215 }
216
217 .os-comments__thread-snip {
218 font-size: 12.5px;
219 color: var( --os-ui-fg-muted, #50575e );
220 margin-block-start: 2px;
221 white-space: nowrap;
222 overflow: hidden;
223 text-overflow: ellipsis;
224 }
225
226 .os-comments__thread-post {
227 font-size: 11.5px;
228 color: var( --os-ui-fg-faint, #787c82 );
229 margin-block-start: 3px;
230 white-space: nowrap;
231 overflow: hidden;
232 text-overflow: ellipsis;
233 }
234
235 /*
236 * The rail before its first answer: silhouettes where the
237 * conversations land. Same shimmer the table's skeleton rows wear,
238 * through the palette's skeleton pair.
239 */
240 .os-comments__thread-slot--ghost .os-comments__thread {
241 cursor: default;
242 pointer-events: none;
243 }
244
245 .os-comments__ghost {
246 display: block;
247 border-radius: 3px;
248 background: linear-gradient(
249 90deg,
250 var( --os-skeleton-low, rgba( 0, 0, 0, 0.06 ) ) 0%,
251 var( --os-skeleton-high, rgba( 0, 0, 0, 0.14 ) ) 50%,
252 var( --os-skeleton-low, rgba( 0, 0, 0, 0.06 ) ) 100%
253 );
254 background-size: 200% 100%;
255 animation: os-comments-ghost 1.4s ease-in-out infinite;
256 }
257
258 .os-comments__ghost--disc {
259 width: 36px;
260 height: 36px;
261 border-radius: 50%;
262 }
263
264 .os-comments__ghost--line {
265 height: 12px;
266 width: 70%;
267 margin-block-start: 4px;
268 }
269
270 .os-comments__ghost--short {
271 width: 45%;
272 }
273
274 @keyframes os-comments-ghost {
275 0% {
276 background-position: 200% 50%;
277 }
278 100% {
279 background-position: -200% 50%;
280 }
281 }
282
283 @media ( prefers-reduced-motion: reduce ) {
284 .os-comments__ghost {
285 animation: none;
286 }
287 }
288
289 .os-comments__thread-meta {
290 display: flex;
291 flex-direction: column;
292 align-items: flex-end;
293 gap: 6px;
294 flex: 0 0 auto;
295 }
296
297 .os-comments__thread-time {
298 font-size: 11px;
299 color: var( --os-ui-fg-faint, #787c82 );
300 font-variant-numeric: tabular-nums;
301 white-space: nowrap;
302 }
303
304 /*
305 * Rail status: a `<os-badge>` with no room for its label, so the pill
306 * collapses to the tone dot the component already paints. Driven
307 * through the badge's own variable surface rather than by overriding
308 * its `:host` rules from the light DOM — the tone palette still owns
309 * the colour. The label rides along as slotted screen-reader text, so
310 * the hue is never the only carrier of the meaning.
311 */
312 .os-comments__status {
313 --os-ui-badge-padding: 0;
314 --os-ui-badge-bg: transparent;
315 --os-ui-badge-border: 0;
316 --os-ui-badge-gap: 0;
317 flex: 0 0 auto;
318 position: relative;
319 }
320
321 .os-comments__reply-count {
322 --os-ui-badge-padding: 1px 6px;
323 --os-ui-badge-font: 500 10.5px/1.4 var( --os-font, system-ui );
324 font-variant-numeric: tabular-nums;
325 white-space: nowrap;
326 position: relative;
327 }
328
329 .os-comments__load-more {
330 display: flex;
331 justify-content: center;
332 padding: 12px;
333 }
334
335 /* ── Right pane: conversation ────────────────────────────────── */
336 .os-comments__convo {
337 display: flex;
338 flex-direction: column;
339 min-width: 0;
340 min-block-size: 0;
341 background: var( --os-ui-surface, #fff );
342 }
343
344 /* `<os-empty-state>` owns the icon + copy; this is placement only. */
345 .os-comments__placeholder {
346 margin: auto;
347 padding: 40px 24px;
348 display: block;
349 }
350
351 .os-comments__convo-head {
352 display: flex;
353 align-items: center;
354 justify-content: space-between;
355 gap: 12px;
356 padding: 14px 18px;
357 border-block-end: 1px solid var( --os-ui-border, #dcdcde );
358 flex: 0 0 auto;
359 }
360 .os-comments__convo-context {
361 min-width: 0;
362 }
363 .os-comments__convo-kicker {
364 font-size: 11px;
365 letter-spacing: 0.06em;
366 text-transform: uppercase;
367 color: var( --os-ui-fg-faint, #787c82 );
368 font-weight: 600;
369 }
370 .os-comments__convo-post {
371 font-size: 15px;
372 font-weight: 600;
373 color: var( --os-ui-fg, #1d2327 );
374 margin-block-start: 2px;
375 display: block;
376 overflow: hidden;
377 text-overflow: ellipsis;
378 white-space: nowrap;
379 }
380
381 /*
382 * The post title doubles as the "edit this post" affordance. The
383 * pencil sits at 55% opacity so the title reads as interactive at
384 * rest — a hover-only hint would be invisible to anyone who never
385 * hovers, and invisible on touch entirely.
386 */
387 a.os-comments__convo-post--editable {
388 text-decoration: none;
389 color: var( --os-ui-fg, #1d2327 );
390 }
391 .os-comments__convo-post-pencil {
392 margin-inline-start: 6px;
393 vertical-align: -2px;
394 opacity: 0.55;
395 color: var( --os-ui-fg-muted, #50575e );
396 }
397 a.os-comments__convo-post--editable:hover,
398 a.os-comments__convo-post--editable:focus-visible {
399 color: var( --os-ui-accent, #2271b1 );
400 text-decoration: underline;
401 }
402 a.os-comments__convo-post--editable:hover .os-comments__convo-post-pencil,
403 a.os-comments__convo-post--editable:focus-visible .os-comments__convo-post-pencil {
404 opacity: 1;
405 color: inherit;
406 }
407 a.os-comments__convo-post--editable:focus-visible {
408 outline: 2px solid var( --os-ui-accent, #2271b1 );
409 outline-offset: 2px;
410 border-radius: 3px;
411 }
412
413 .os-comments__convo-head-actions {
414 display: flex;
415 align-items: center;
416 gap: 8px;
417 flex: 0 0 auto;
418 }
419 .os-comments__convo-link {
420 color: var( --os-ui-accent, #2271b1 );
421 font-size: 12.5px;
422 text-decoration: none;
423 white-space: nowrap;
424 display: inline-flex;
425 align-items: center;
426 gap: 4px;
427 }
428 .os-comments__convo-link:hover { text-decoration: underline; }
429 .os-comments__convo-link:focus-visible {
430 outline: 2px solid var( --os-ui-accent, #2271b1 );
431 outline-offset: 2px;
432 border-radius: 3px;
433 }
434
435 /* The block editor's `external` glyph — inherits the link colour. */
436 .os-comments__ext-icon {
437 width: 18px;
438 height: 18px;
439 fill: currentColor;
440 flex: 0 0 auto;
441 }
442
443 .os-comments__thread-scroll {
444 padding: 18px 18px 6px;
445 overflow-y: auto;
446 flex: 1 1 auto;
447 min-block-size: 0;
448 }
449
450 /* A message + its nested children */
451 .os-comments__msg {
452 display: grid;
453 grid-template-columns: 34px 1fr;
454 gap: 12px;
455 }
456 .os-comments__msg-rail {
457 display: flex;
458 flex-direction: column;
459 align-items: center;
460 }
461 .os-comments__msg-line {
462 flex: 1 1 auto;
463 width: 2px;
464 background: var( --os-ui-border, #dcdcde );
465 margin-block-start: 6px;
466 border-radius: 2px;
467 }
468 .os-comments__msg-body {
469 min-width: 0;
470 padding-block-end: 12px;
471 }
472 .os-comments__msg-head {
473 display: flex;
474 align-items: baseline;
475 gap: 8px;
476 flex-wrap: wrap;
477 }
478 .os-comments__msg-name {
479 font-weight: 600;
480 font-size: 13.5px;
481 color: var( --os-ui-fg, #1d2327 );
482 }
483 .os-comments__msg-you {
484 --os-ui-badge-padding: 0 5px;
485 --os-ui-badge-font: 600 10.5px/1.4 var( --os-font, system-ui );
486 }
487 .os-comments__msg-time {
488 font-size: 11.5px;
489 color: var( --os-ui-fg-faint, #787c82 );
490 font-variant-numeric: tabular-nums;
491 }
492
493 /*
494 * Status chip on any message that isn't approved. A pending reply
495 * buried in an approved thread is exactly what a moderator is
496 * looking for — the tint alone doesn't carry that.
497 */
498 /* Tone + pill come from `<os-badge>`; only the metrics are ours. */
499 .os-comments__msg-status {
500 --os-ui-badge-padding: 0 5px;
501 --os-ui-badge-font: 600 10.5px/1.4 var( --os-font, system-ui );
502 }
503
504 .os-comments__msg[ data-status="spam" ] .os-comments__msg-text,
505 .os-comments__msg[ data-status="trash" ] .os-comments__msg-text {
506 opacity: 0.65;
507 }
508
509 .os-comments__msg-text {
510 font-size: 13.5px;
511 line-height: 1.5;
512 color: var( --os-ui-fg, #2c3338 );
513 margin-block-start: 4px;
514 overflow-wrap: anywhere;
515 }
516
517 /*
518 * Per-message inline actions — always visible, the whole point.
519 *
520 * Styled as wp-admin's own comment row actions: chrome-less links
521 * separated by pipes (`Approve | Reply | Edit | Spam | Trash`) rather
522 * than a row of buttons. Each pipe is a real `__act-sep` node the view
523 * places between the actions this viewer actually got (every button
524 * is a shadow host, so generated content on it is at the mercy of
525 * slotting), never dangling at either end.
526 */
527 .os-comments__msg-actions {
528 display: flex;
529 align-items: center;
530 gap: 8px;
531 margin-block-start: 8px;
532 flex-wrap: wrap;
533 font-size: 12.5px;
534 }
535
536 .os-comments__act {
537 --os-ui-button-padding: 0;
538 --os-ui-button-fg: var( --os-ui-accent, #2271b1 );
539 font-size: 12.5px;
540 line-height: 1.4;
541 }
542
543 /*
544 * The separator belongs to the row, not to either link — so it stays
545 * out of the underline, out of both hit targets, and (via
546 * `aria-hidden`) out of the accessibility tree.
547 */
548 .os-comments__act-sep {
549 color: var( --os-ui-fg-faint, #c3c4c7 );
550 user-select: none;
551 pointer-events: none;
552 }
553
554 .os-comments__act.is-danger {
555 --os-ui-button-fg: var( --os-ui-danger, #b32d2e );
556 }
557
558 .os-comments__nested {
559 margin-block-start: 12px;
560 }
561
562 /* ── Composer ────────────────────────────────────────────────── */
563 .os-comments__composer {
564 border-block-start: 1px solid var( --os-ui-border, #dcdcde );
565 background: var( --os-ui-surface-elevated, #f6f7f7 );
566 padding: 12px 18px 16px;
567 flex: 0 0 auto;
568 }
569 .os-comments__composer.is-empty {
570 display: none;
571 }
572 .os-comments__composer-to {
573 font-size: 12px;
574 color: var( --os-ui-fg-muted, #50575e );
575 margin-block-end: 8px;
576 }
577 .os-comments__composer-to b {
578 color: var( --os-ui-fg, #1d2327 );
579 }
580 .os-comments__composer-row {
581 display: flex;
582 align-items: center;
583 justify-content: flex-end;
584 gap: 8px;
585 margin-block-start: 10px;
586 }
587 .os-comments__composer-hint {
588 font-size: 11.5px;
589 color: var( --os-ui-fg-faint, #787c82 );
590 margin-inline-end: auto;
591 }
592
593 .os-comments__reply-input {
594 display: block;
595 width: 100%;
596 }
597
598 /* Cursor override: the shell forces `cursor: default !important`. */
599 body.os-active .os-comments__thread,
600 body.os-active .os-comments__convo-link,
601 body.os-active a.os-comments__convo-post--editable {
602 cursor: pointer !important;
603 }
604
605 /* ── Narrow windows: one pane at a time ─────────────────────────── */
606 /*
607 * A phone, or a desktop window pulled in. The split cannot hold two
608 * panes, so it holds one: the rail (the list of conversations) until
609 * a conversation is picked, then the conversation, with a Back control
610 * in its head that returns to the list. The view stamps which pane
611 * is up as `data-os-comments-pane` on the root; at a wide width the
612 * stamp changes nothing, both panes are always up. The tab strip
613 * becomes a picker the same way (`data-os-comments-tabselect`, rendered
614 * beside the strip), so five tabs with counts do not wrap into two
615 * rows above a 360px list.
616 *
617 * Two ways in, the same rules twice: a container query for a window
618 * pulled narrow on a desk, and the shell's phone mode
619 * (`html[data-os-mode="mobile"]`), which is the phone experience at
620 * ANY width — a developer previewing it in a wide browser, a phone
621 * turned sideways past 720px — and cannot be expressed as a size. The
622 * rail is never hidden outright: on a phone it IS the list of
623 * conversations.
624 */
625 .os-comments__tabselect {
626 display: none;
627 padding: 8px 12px;
628 border-block-end: 1px solid var( --os-ui-border, #dcdcde );
629 flex: 0 0 auto;
630 }
631 .os-comments__convo-back {
632 display: none;
633 flex: 0 0 auto;
634 }
635
636 @container ( max-width: 720px ) {
637 .os-comments__tabrow {
638 display: none;
639 }
640 .os-comments__tabselect {
641 display: block;
642 }
643 .os-comments__split {
644 grid-template-columns: minmax( 0, 1fr );
645 }
646 .os-comments__rail {
647 border-inline-end: 0;
648 }
649 .os-comments[data-os-comments-pane='convo'] .os-comments__rail {
650 display: none;
651 }
652 .os-comments:not( [data-os-comments-pane='convo'] ) .os-comments__convo {
653 display: none;
654 }
655 .os-comments__convo-back {
656 display: inline-flex;
657 }
658 .os-comments__convo-head {
659 padding: 10px 12px;
660 }
661 }
662
663 html[data-os-mode="mobile"] .os-comments__tabrow {
664 display: none;
665 }
666 html[data-os-mode="mobile"] .os-comments__tabselect {
667 display: block;
668 }
669 html[data-os-mode="mobile"] .os-comments__split {
670 grid-template-columns: minmax( 0, 1fr );
671 }
672 html[data-os-mode="mobile"] .os-comments__rail {
673 border-inline-end: 0;
674 }
675 html[data-os-mode="mobile"] .os-comments[data-os-comments-pane='convo'] .os-comments__rail {
676 display: none;
677 }
678 html[data-os-mode="mobile"] .os-comments:not( [data-os-comments-pane='convo'] ) .os-comments__convo {
679 display: none;
680 }
681 html[data-os-mode="mobile"] .os-comments__convo-back {
682 display: inline-flex;
683 }
684 html[data-os-mode="mobile"] .os-comments__convo-head {
685 padding: 10px 12px;
686 }
687