openvibers/openvibe.shared messages.css

messages.css

main 6.8 KB · 72 lines · css

1/* openvibe-shared/messages — Chat's two views (the owner, 11-09): a live room (lines like a stream's chat, wrapping
2 under the name on a phone) and texting bubbles (Android/iOS Messages: runs of bubbles with joined corners, the
3 avatar beside the first, the time under the last). The network's theme variables; dark and light; Calm fades. */
4.ovm-messages { list-style: none; margin: 0; padding: 12px clamp(10px, 3vw, 24px) 16px; display: flex; flex-direction: column; gap: 2px;
5 overflow: auto; min-height: 0; overscroll-behavior: contain; font-size: 15px; line-height: 1.42; color: var(--text-primary, #e8ecf3); }
6.ovm-day { position: sticky; top: 6px; z-index: 1; align-self: center; margin: 14px 0 6px; padding: 4px 12px; border-radius: 999px;
7 background: color-mix(in srgb, var(--bg-secondary, #141a24) 84%, transparent); -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
8 box-shadow: inset 0 0 0 1px var(--border, rgba(255, 255, 255, .08)); font-size: 12px; font-weight: 650; color: var(--text-secondary, #a8b3c4); }
9
10/* Bubbles */
11.ovm-group { display: flex; gap: 8px; align-items: flex-start; max-width: min(82%, 640px); margin: 8px 0 0; }
12.ovm-group[data-continued="true"] { margin-top: 2px; }
13.ovm-group[data-mine="true"] { align-self: flex-end; flex-direction: row-reverse; }
14.ovm-avatar { flex: none; display: block; width: 30px; height: 30px; border-radius: 50%; object-fit: cover; background: var(--bg-tertiary, #2a3140); }
15.ovm-group:not([data-continued="true"]) .ovm-avatar { margin-top: 19px; } /* level with the first bubble, under the name */
16.ovm-avatar.is-gap { height: 1px; background: none; } /* a run keeps the avatar's column */
17.ovm-avatar.is-initial { display: grid; place-items: center; background: hsl(var(--ovm-h, 215) 55% 46%); color: #fff; font-size: 13px; font-weight: 800; }
18.ovm-group-body { min-width: 0; display: flex; flex-direction: column; align-items: flex-start; }
19.ovm-group[data-mine="true"] .ovm-group-body { align-items: flex-end; }
20.ovm-author { margin: 0 0 3px 12px; font-size: 12px; font-weight: 700; color: var(--text-muted, #93a0b4); }
21.ovm-bubble { position: relative; max-width: 100%; padding: 8px 13px; border-radius: 20px; background: var(--bg-tertiary, #2a3140); overflow-wrap: anywhere; }
22.ovm-group[data-mine="true"] .ovm-bubble { background: var(--accent-strong, var(--accent, #2563eb)); color: var(--on-accent-strong, #fff); }
23/* A run of bubbles from one person joins on the inner side. */
24.ovm-group:not([data-mine="true"])[data-continued="true"] .ovm-bubble { border-top-left-radius: 6px; }
25.ovm-group:not([data-mine="true"])[data-tail="false"] .ovm-bubble { border-bottom-left-radius: 6px; }
26.ovm-group[data-mine="true"][data-continued="true"] .ovm-bubble { border-top-right-radius: 6px; }
27.ovm-group[data-mine="true"][data-tail="false"] .ovm-bubble { border-bottom-right-radius: 6px; }
28.ovm-text { white-space: pre-wrap; }
29.ovm-meta { display: flex; align-items: center; gap: 4px; margin: 3px 8px 0; font-size: 11px; color: var(--text-muted, #93a0b4); }
30.ovm-meta time { font-variant-numeric: tabular-nums; }
31.ovm-tick { letter-spacing: -.2em; color: var(--accent-light, var(--accent, #60a5fa)); }
32.ovm-emoji-only { padding: 0 2px; background: transparent !important; font-size: 2.2rem; line-height: 1.15; }
33.ovm-reply { display: block; margin-bottom: 6px; padding-left: 8px; border-left: 2px solid currentColor; font-size: .86em; opacity: .75; }
34.ovm-link { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
35/* A message's actions: one cluster just above its right end (openvibe.design rule 138), on hover or focus on a computer,
36 a tap on a phone; never in the words. "edited" is one quiet word after them. */
37.ovm-has-actions { position: relative; }
38.ovm-actions { position: absolute; bottom: calc(100% - 6px); right: 6px; z-index: 6; display: none; align-items: center; gap: 2px; padding: 2px; border: 1px solid var(--border, rgba(148, 163, 184, .22)); border-radius: 10px; background: var(--bg-card, #131c2e); box-shadow: 0 6px 18px rgba(0, 0, 0, .35); }
39.ovm-messages > :first-child .ovm-actions, .ovm-messages > :first-child.ovm-has-actions > .ovm-actions { bottom: auto; top: calc(100% - 6px); }
40.ovm-has-actions:hover > .ovm-actions, .ovm-has-actions:focus-within > .ovm-actions, .ovm-has-actions.is-acting > .ovm-actions { display: inline-flex; }
41.ovm-act { display: grid; place-items: center; width: 28px; height: 26px; padding: 0; border: 0; border-radius: 7px; background: transparent; color: var(--text-muted, #93a0b4); cursor: pointer; }
42.ovm-act:hover, .ovm-act:focus-visible { color: var(--text-primary, #e6edf7); background: color-mix(in srgb, var(--accent, #3b82f6) 22%, transparent); }
43.ovm-act:focus-visible { outline: 2px solid var(--accent-light, var(--accent, #60a5fa)); outline-offset: -2px; }
44.ovm-act-delete:hover { color: #fca5a5; background: color-mix(in srgb, #ef4444 20%, transparent); }
45@media (hover: none) {
46 .ovm-has-actions:hover:not(.is-acting):not(:focus-within) > .ovm-actions { display: none; }
47 .ovm-actions { right: 4px; border-radius: 12px; }
48 .ovm-act { width: 44px; height: 40px; border-radius: 9px; }
49 .ovm-act svg { width: 18px; height: 18px; }
50}
51@media (hover: hover) { .ovm-room.ovm-has-actions:hover { background: color-mix(in srgb, var(--text-primary, #fff) 4%, transparent); } }
52.ovm-room.is-acting { background: color-mix(in srgb, var(--accent, #3b82f6) 9%, transparent); }
53.ovm-edited { margin-left: 5px; font-size: .72em; color: var(--text-muted, #93a0b4); opacity: .85; white-space: nowrap; }
54.ovm-group[data-mine="true"] .ovm-edited { color: inherit; opacity: .7; }
55
56/* Room: one line per message, the name in its colour, the words wrapping under it on a phone. */
57.ovm-messages[data-view="room"] { gap: 0; }
58.ovm-room { display: block; padding: 3px 8px; border-radius: 8px; overflow-wrap: anywhere; }
59@media (hover: hover) { .ovm-room:hover { background: var(--bg-hover, rgba(255, 255, 255, .05)); } }
60.ovm-room time { margin-right: 7px; font-size: 11.5px; color: var(--text-muted, #93a0b4); font-variant-numeric: tabular-nums; }
61.ovm-room-author { font-weight: 750; color: var(--ov-author-color, hsl(var(--ovm-h, 215) 80% 68%)); }
62:root[data-theme="light"] .ovm-room-author { color: var(--ov-author-color, hsl(var(--ovm-h, 215) 72% 36%)); }
63.ovm-room-author::after { content: ":"; margin-right: 6px; font-weight: 600; color: var(--text-muted, #93a0b4); }
64.ovm-room .ovm-avatar { display: none; }
65
66/* The newest message arrives (only the last: a repaint never replays the whole list). */
67.ovm-group:last-child { animation: ovm-in .24s cubic-bezier(.2, .8, .2, 1) both; }
68.ovm-room:last-child { animation: ovm-fade .2s ease-out both; }
69@keyframes ovm-in { from { opacity: 0; transform: translateY(8px) scale(.97); } }
70@keyframes ovm-fade { from { opacity: 0; } }
71html[data-ov-motion=reduced] .ovm-group:last-child { animation-name: ovm-fade; }
72