/* ═══════════════════════════════════════════════════════════════════════════
   ChatBucket — msg-actions overlay  (PATCH LAYER · loaded AFTER index.css +
   perf-overlay.css so it wins the cascade without !important spam)

   WHAT THIS SOLVES
   ────────────────
   1. The .msg-actions cluster (copy/edit/delete) is too crowded on phones.
      → Touch mode keeps ONLY copy in the bubble. Edit/delete/reply/select
        move into a long-press "instrument tray" (context menu).
   2. On touch the cluster used to sit permanently at opacity .55 on EVERY
      bubble. → Now it is invisible until that one message is tapped (peek).
   3. Multi-select + bulk delete, entered by long-press → Select.

   DESIGN DIRECTION — "machined instrument panel"
   ──────────────────────────────────────────────
   The app is true-black, hairline-bordered, utilitarian. This layer leans
   all the way into that: graphite gradients, 1px machined edges, uppercase
   monospace micro-labels as readouts, ONE red accent reserved strictly for
   destruction, spring easing (0.16,1,0.3,1) on transform only. No webfont
   is loaded — this app runs over LAN/Tailscale and must not depend on a
   font CDN (same reasoning as --font in index.css).

   NON-INTRUSIVE CONTRACT (the hard requirement)
   ─────────────────────────────────────────────
   Nothing here ever changes document flow:
     · menu + select bar are position:fixed  → zero reflow, zero scroll jump
     · no backdrop, no dimming, no scroll lock, no body padding/margin
     · selection affordances are box-shadow / background / absolutely
       positioned chips placed in the row's EMPTY gutter — bubbles never move
     · every animation is opacity/transform only (compositor thread)
   ═══════════════════════════════════════════════════════════════════════════ */

/* --cb-spring, --cb-glass, --cb-smoke, --cb-blur, --cb-cast, --cb-lip are
   now defined once in index.css :root. This file only owns the tokens it
   is the sole consumer of. */
:root {
    --cb-tray-bg:     linear-gradient(180deg, #1b1b1b 0%, #0d0d0d 100%);
    --cb-tray-edge:   #4a4a4a;
    --cb-tray-shadow: 0 20px 52px rgba(0, 0, 0, 0.76), 0 2px 8px rgba(0, 0, 0, 0.6);
    --cb-hairline:    inset 0 1px 0 rgba(255, 255, 255, 0.07);
    --cb-sel-tint:    rgba(125, 185, 255, 0.075);
    --cb-sel-edge:    rgba(125, 185, 255, 0.30);
}

/* ── extra mask icons (the base set has no reply/select/save/link) ────────
   Inline data-URI masks, same monochrome .icon contract as index.css —
   no extra HTTP requests, tinted by currentColor like everything else. */
.cb-ico {
    display: inline-block;
    width: 16px;
    height: 16px;
    flex-shrink: 0;
    background: currentColor;
    -webkit-mask-position: center;  mask-position: center;
    -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
    -webkit-mask-size: contain;     mask-size: contain;
}
.cb-ico.reply {
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='black' d='M10 9V5l-7 7 7 7v-4.1c5 0 8.5 1.6 11 5.1-1-5-4-10-11-11Z'/%3E%3C/svg%3E");
            mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='black' d='M10 9V5l-7 7 7 7v-4.1c5 0 8.5 1.6 11 5.1-1-5-4-10-11-11Z'/%3E%3C/svg%3E");
}
.cb-ico.select {
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='black' d='M18 7l-1.4-1.4-6.6 6.6 1.4 1.4L18 7Zm4.2-1.4L11.6 16.2 7.4 12 6 13.4l5.6 5.6 12-12-1.4-1.4ZM.4 13.4 6 19l1.4-1.4L1.8 12 .4 13.4Z'/%3E%3C/svg%3E");
            mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='black' d='M18 7l-1.4-1.4-6.6 6.6 1.4 1.4L18 7Zm4.2-1.4L11.6 16.2 7.4 12 6 13.4l5.6 5.6 12-12-1.4-1.4ZM.4 13.4 6 19l1.4-1.4L1.8 12 .4 13.4Z'/%3E%3C/svg%3E");
}
.cb-ico.save {
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='black' d='M5 20h14v-2H5v2ZM19 9h-4V3H9v6H5l7 7 7-7Z'/%3E%3C/svg%3E");
            mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='black' d='M5 20h14v-2H5v2ZM19 9h-4V3H9v6H5l7 7 7-7Z'/%3E%3C/svg%3E");
}
.cb-ico.link {
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='black' d='M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7a5 5 0 0 0 0 10h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1ZM8 13h8v-2H8v2Zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4a5 5 0 0 0 0-10Z'/%3E%3C/svg%3E");
            mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='black' d='M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7a5 5 0 0 0 0 10h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1ZM8 13h8v-2H8v2Zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4a5 5 0 0 0 0-10Z'/%3E%3C/svg%3E");
}

/* ═══ 1 · ZERO BUTTONS ON THE BUBBLE ═════════════════════════════════════
   [v2] The whole .msg-actions cluster is GONE on every pointer type. No
   copy, no edit, no delete floating over content — hovering a message is now
   a pure CSS transformation and nothing else. Every one of those functions
   lives in the long-press / right-click tray, which is also where copy now
   handles images (sent AND received).

   display:none rather than removing the node in JS: the markup keeps coming
   from index.js's buildMessageActionsHTML, so leaving it in the DOM but
   unrendered means zero risk to that contract, and index.js's delegated
   .copy-btn / .edit-btn / .delete-btn click handlers simply never fire. */
.msg-actions { display: none !important; }

/* ── hover = transformation only ────────────────────────────────────────────
   The bubble itself responds: a hair of lift, a lit top edge, and a faint
   sheen that sweeps in from the reading direction. GPU-only properties
   (transform / box-shadow / background-position), so no reflow and no
   neighbour repaint. Desktop-only: (hover:hover) keeps phones out of it,
   where a "hover" state would just be a stuck highlight after a tap. */
@media (hover: hover) and (pointer: fine) {
    .message > .bubble,
    .message > .bubble-file,
    .message > .bubble-audio,
    .message > .bubble-sticker,
    .message > .bubble-youtube {
        transition: transform var(--cb-t-quick, 190ms) var(--cb-spring),
                    box-shadow var(--cb-t-quick, 190ms) ease,
                    border-color var(--cb-t-micro, 120ms) ease;
    }
    .message:hover > .bubble,
    .message:hover > .bubble-file,
    .message:hover > .bubble-audio,
    .message:hover > .bubble-sticker,
    .message:hover > .bubble-youtube {
        transform: translateY(-1.5px);
        border-color: rgba(255, 255, 255, 0.17);
        box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.09),
                    0 8px 22px rgba(0, 0, 0, 0.5);
    }
    /* The tray is still one right-click / long-press away, but we no longer
       advertise it with `cursor: context-menu` — that glyph renders as an
       arrow with a little menu rectangle attached and reads as a broken
       custom cursor. The normal arrow (and the native I-beam over text)
       is the expected look; discoverability comes from the hover lift.
       `default` also lets the browser's own text cursor win inside
       bubbles, which `context-menu` was suppressing. */
    .message > .bubble,
    .message > .bubble-file,
    .message > .bubble-audio,
    .message > .bubble-sticker,
    .message > .bubble-youtube { cursor: default; }
    .message.message--deleted > .bubble { cursor: default; }
}

/* Touch gets the same language on press instead of hover — see .cb-pressing
   in block 2, which now carries a lit edge as well as the squeeze. */

/* ═══ 2 · PRESS / ANCHOR AFFORDANCE ══════════════════════════════════════
   Long-press feedback and "this is the message the tray belongs to".
   transform + box-shadow only → no reflow, no neighbour movement. */
.message.cb-pressing > .bubble,
.message.cb-pressing > .bubble-file,
.message.cb-pressing > .bubble-audio,
.message.cb-pressing > .bubble-sticker,
.message.cb-pressing > .bubble-youtube {
    /* Touch's answer to the desktop hover state: squeeze + the same lit top
       edge, so both pointer types speak one visual language. */
    transform: scale(0.976);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.10),
                0 6px 18px rgba(0, 0, 0, 0.45);
    transition: transform 200ms var(--cb-spring), box-shadow 200ms ease;
}
.message.cb-anchored > .bubble,
.message.cb-anchored > .bubble-file,
.message.cb-anchored > .bubble-audio,
.message.cb-anchored > .bubble-sticker,
.message.cb-anchored > .bubble-youtube {
    box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.22),
                inset 0 1px 0 rgba(255, 255, 255, 0.10),
                0 12px 34px rgba(0, 0, 0, 0.6);
    transition: box-shadow 180ms ease;
}

/* Touch: kill the native long-press callout/selection so OUR gesture owns
   the press. Desktop keeps normal text selection (nothing changes there). */
body.cb-touch .message {
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    user-select: none;
}
/* …but never cripple the composer or panels. */
body.cb-touch #message-input,
body.cb-touch input,
body.cb-touch textarea { -webkit-user-select: text; user-select: text; }

/* ═══ 3 · THE TRAY (context menu) ════════════════════════════════════════
   position:fixed + top-of-stack z-index. Appears over content, never
   displaces it; the page behind stays scrollable (we close on scroll). */
#cb-tray {
    position: fixed;
    top: 0; left: 0;
    z-index: 2147482000;
    min-width: 196px;
    max-width: min(78vw, 268px);
    padding: 5px;
    margin: 0;
    /* [v2] Smoked glass, matching shell-refine.css — a pseudo-transparent
       wash over blurred black instead of a flat graphite fill. */
    background: var(--cb-glass, linear-gradient(180deg, rgba(255,255,255,0.055), rgba(255,255,255,0.008))),
                var(--cb-smoke, rgba(10,10,10,0.72));
    -webkit-backdrop-filter: var(--cb-blur, blur(20px) saturate(155%));
            backdrop-filter: var(--cb-blur, blur(20px) saturate(155%));
    border: 1px solid rgba(255, 255, 255, 0.10);
    border-radius: 15px;
    box-shadow: var(--cb-cast, 0 18px 44px rgba(0,0,0,0.66)), var(--cb-lip, inset 0 1px 0 rgba(255,255,255,0.10));
    display: none;
    flex-direction: column;
    gap: 1px;
    opacity: 0;
    transform: scale(0.9);
    transform-origin: top left;
    transition: opacity 110ms ease, transform 210ms var(--cb-spring);
    will-change: transform, opacity;
    contain: layout paint style;
    overscroll-behavior: contain;
}
#cb-tray.is-mounted { display: flex; }
#cb-tray.is-open    { opacity: 1; transform: scale(1); }

/* Readout header: who/what this tray is acting on. Monospace, uppercase,
   tracked out — the "instrument label" of the whole design language. */
#cb-tray .cb-tray-head {
    font-family: var(--font-mono);
    font-size: 9.5px;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--text-4);
    padding: 6px 9px 5px;
    display: flex;
    gap: 6px;
    align-items: baseline;
    border-bottom: 1px solid rgba(255, 255, 255, 0.06);
    margin-bottom: 3px;
    white-space: nowrap;
    overflow: hidden;
}
#cb-tray .cb-tray-head b {
    font-weight: 600;
    color: var(--text-3);
    max-width: 118px;
    overflow: hidden;
    text-overflow: ellipsis;
}

.cb-mi {
    all: unset;
    box-sizing: border-box;
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 9px 10px;
    border-radius: 9px;
    font-family: var(--font);
    font-size: 13.5px;
    letter-spacing: -0.008em;
    color: var(--text-2);
    cursor: pointer;
    user-select: none;
    /* staggered entrance — set per item by JS via --i */
    opacity: 0;
    transform: translateX(-5px);
    animation: cb-mi-in 260ms var(--cb-spring) forwards;
    animation-delay: calc(var(--i, 0) * 26ms + 40ms);
}
@keyframes cb-mi-in { to { opacity: 1; transform: none; } }
.cb-mi:hover,
.cb-mi.is-active { background: var(--surface-3); color: var(--text); }
.cb-mi:active    { background: var(--surface-4); }
.cb-mi .cb-ico,
.cb-mi .icon     { width: 15px; height: 15px; color: inherit; opacity: 0.85; }
.cb-mi-lbl       { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Keycap hint — desktop only; the tray is pointer-driven on touch. */
.cb-mi-key {
    font-family: var(--font-mono);
    font-size: 9.5px;
    color: var(--text-4);
    border: 1px solid var(--border-1);
    border-radius: 4px;
    padding: 1px 4px;
    line-height: 1.35;
}
body.cb-touch .cb-mi-key { display: none; }

.cb-tray-sep {
    height: 1px;
    margin: 4px 6px;
    background: rgba(255, 255, 255, 0.07);
}

/* Destruction is the only place red appears. Two-step, inside the tray:
   the item morphs into its own confirmation — no dialog, no layout shift,
   consistent with the existing tap-to-arm delete idiom. */
.cb-mi.is-danger        { color: var(--danger); }
.cb-mi.is-danger:hover,
.cb-mi.is-danger.is-active { background: rgba(255, 107, 107, 0.12); color: #ff8f8f; }
.cb-mi.is-armed {
    background: var(--danger);
    color: #12040a;
    font-weight: 650;
    animation: cb-armed 1.1s ease-in-out infinite;
}
.cb-mi.is-armed .cb-ico,
.cb-mi.is-armed .icon { color: #12040a; opacity: 1; }
@keyframes cb-armed {
    0%, 100% { box-shadow: 0 0 0 0 rgba(255, 107, 107, 0.45); }
    50%      { box-shadow: 0 0 0 5px rgba(255, 107, 107, 0); }
}

/* ═══ 4 · SELECTION MODE ═════════════════════════════════════════════════
   Zero movement: the check chip lives in the row gutter that is ALWAYS
   empty (bubbles cap at 78% width and hug one side), so no bubble has to
   translate to make room. */
body.cb-select #messages { cursor: pointer; }
body.cb-select .message  {
    position: relative;
    border-radius: 12px;
    transition: background 140ms ease, box-shadow 140ms ease;
}
body.cb-select .msg-actions { opacity: 0 !important; pointer-events: none; }
body.cb-select .message,
body.cb-select .bubble,
body.cb-select .bubble-text,
body.cb-select .bubble-caption { -webkit-user-select: none; user-select: none; }

.cb-check {
    position: absolute;
    top: 50%;
    width: 21px; height: 21px;
    margin-top: -10.5px;
    border-radius: 50%;
    border: 1.5px solid var(--border-3);
    background: rgba(0, 0, 0, 0.5);
    display: none;
    place-items: center;
    pointer-events: none;
    opacity: 0;
    transform: scale(0.6);
    transition: opacity 150ms ease, transform 220ms var(--cb-spring),
                background 140ms ease, border-color 140ms ease;
}
body.cb-select .cb-check { display: grid; opacity: 1; transform: scale(1); }
.message:not(.own-message) .cb-check { right: 10px; }
.message.own-message      .cb-check { left: 10px; }
.cb-check::after {
    content: "";
    width: 11px; height: 11px;
    background: #06080b;
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='black' d='M9 16.2 4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4Z'/%3E%3C/svg%3E");
            mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='black' d='M9 16.2 4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4Z'/%3E%3C/svg%3E");
    -webkit-mask-size: contain; mask-size: contain;
    -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
    -webkit-mask-position: center; mask-position: center;
    opacity: 0;
    transform: scale(0.4);
    transition: opacity 120ms ease, transform 200ms var(--cb-spring);
}
.message.cb-sel .cb-check {
    background: var(--link);
    border-color: var(--link);
}
.message.cb-sel .cb-check::after { opacity: 1; transform: scale(1); }
body.cb-select .message.cb-sel {
    background: var(--cb-sel-tint);
    box-shadow: inset 0 0 0 1px var(--cb-sel-edge);
}
/* Not yours → not deletable. Dim chip + one-shot nudge on refusal. */
body.cb-select .message:not(.own-message) .cb-check { opacity: 0.42; }
.message.cb-nope { animation: cb-nope 260ms ease; }
@keyframes cb-nope {
    0%, 100% { transform: translateX(0); }
    25%      { transform: translateX(-4px); }
    75%      { transform: translateX(4px); }
}
/* Pending server confirmation of a bulk delete. */
.message.cb-deleting { animation: cb-deleting 900ms ease-in-out infinite; }
@keyframes cb-deleting { 0%, 100% { opacity: 1; } 50% { opacity: 0.42; } }

/* ═══ 5 · SELECTION BAR ══════════════════════════════════════════════════
   Top-anchored (WhatsApp/Photos idiom) instead of bottom: it never fights
   the composer, and the mobile keyboard can never cover it. Fixed → the
   header simply sits underneath, nothing in the document moves. */
#cb-select-bar {
    position: fixed;
    top: 0; left: 0; right: 0;
    z-index: 2147481000;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 12px;
    /* Height is set from #header's measured box by the script, so the bar
       covers EXACTLY the header and never a single pixel of a message. No
       env(safe-area-inset-top) here on purpose: #header doesn't use it
       either, and being taller than the header is what clips messages. */
    min-height: var(--cb-bar-h, 56px);
    background: rgba(9, 9, 9, 0.9);
    -webkit-backdrop-filter: blur(16px) saturate(150%);
            backdrop-filter: blur(16px) saturate(150%);
    border-bottom: 1px solid var(--cb-tray-edge);
    box-shadow: 0 12px 34px rgba(0, 0, 0, 0.55), var(--cb-hairline);
    transform: translateY(-101%);
    transition: transform 300ms var(--cb-spring);
    will-change: transform;
}
body.cb-select #cb-select-bar { transform: none; }

#cb-select-bar .cb-count {
    font-family: var(--font-mono);
    font-size: 15px;
    font-weight: 600;
    color: var(--text);
    min-width: 2.1ch;
    text-align: right;
    font-variant-numeric: tabular-nums;
}
#cb-select-bar .cb-count-lbl {
    font-family: var(--font-mono);
    font-size: 9px;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--text-4);
    margin-right: auto;
    line-height: 1.1;
    display: flex;
    flex-direction: column;
}
#cb-select-bar .cb-count-note { color: var(--warn); letter-spacing: 0.08em; }

#cb-select-bar button {
    all: unset;
    box-sizing: border-box;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 7px 11px;
    border-radius: 9px;
    border: 1px solid var(--border-1);
    background: var(--surface-2);
    color: var(--text-2);
    font-family: var(--font);
    font-size: 12.5px;
    font-weight: 600;
    letter-spacing: -0.005em;
    cursor: pointer;
    transition: background 120ms ease, color 120ms ease, border-color 120ms ease,
                transform 160ms var(--cb-spring);
}
#cb-select-bar button:hover  { background: var(--surface-3); color: var(--text); border-color: var(--border-2); }
#cb-select-bar button:active { transform: scale(0.94); }
#cb-select-bar button[disabled] { opacity: 0.36; pointer-events: none; }
#cb-select-bar button .cb-ico,
#cb-select-bar button .icon { width: 14px; height: 14px; color: inherit; }

#cb-select-bar #cb-sb-del {
    border-color: rgba(255, 107, 107, 0.4);
    color: var(--danger);
    background: rgba(255, 107, 107, 0.08);
}
#cb-select-bar #cb-sb-del:hover { background: rgba(255, 107, 107, 0.16); color: #ff8f8f; }
#cb-select-bar #cb-sb-del.is-armed {
    background: var(--danger);
    border-color: var(--danger);
    color: #12040a;
    animation: cb-armed 1.1s ease-in-out infinite;
}
#cb-select-bar #cb-sb-del.is-armed .cb-ico,
#cb-select-bar #cb-sb-del.is-armed .icon { color: #12040a; }
#cb-select-bar #cb-sb-close { border-color: transparent; background: transparent; padding: 7px; }

/* Self-correcting density: if the bar's natural content is taller than the
   header it mirrors, the script adds .is-compact and it tightens up rather
   than overhanging into the message list. */
#cb-select-bar.is-compact { padding: 3px 10px; gap: 6px; }
#cb-select-bar.is-compact button { padding: 5px 9px; font-size: 12px; }
#cb-select-bar.is-compact .cb-count { font-size: 13.5px; }
#cb-select-bar.is-compact .cb-count-lbl { font-size: 8px; }

/* Phone: labels collapse to icons so the bar never wraps or scrolls. */
@media (max-width: 480px) {
    #cb-select-bar { gap: 6px; padding-left: 10px; padding-right: 10px; }
    #cb-select-bar button .cb-lbl { display: none; }
    #cb-select-bar button { padding: 8px; }
    #cb-select-bar #cb-sb-del { padding: 8px 11px; }
    #cb-select-bar #cb-sb-del .cb-lbl { display: inline; }
}

/* ═══ 6 · A11Y / MOTION ══════════════════════════════════════════════════ */
.cb-mi:focus-visible,
#cb-select-bar button:focus-visible {
    outline: 2px solid var(--border-3);
    outline-offset: 1px;
}
@media (prefers-reduced-motion: reduce) {
    #cb-tray, #cb-select-bar, .cb-mi, .cb-check, .cb-check::after {
        transition-duration: 1ms !important;
        animation: none !important;
        opacity: 1;
    }
    #cb-tray            { transform: none; }
    .cb-mi              { opacity: 1; transform: none; }
    #cb-select-bar      { transform: translateY(-101%); }
    body.cb-select #cb-select-bar { transform: none; }
    .message.cb-deleting { animation: none !important; opacity: 0.5; }
    /* [v2] The hover/press transformation is the only message affordance now,
       so it must degrade to an instant, non-moving state change. */
    .message:hover > .bubble,
    .message:hover > .bubble-file,
    .message:hover > .bubble-audio,
    .message:hover > .bubble-sticker,
    .message:hover > .bubble-youtube,
    .message.cb-pressing > .bubble,
    .message.cb-pressing > .bubble-file,
    .message.cb-pressing > .bubble-audio,
    .message.cb-pressing > .bubble-sticker,
    .message.cb-pressing > .bubble-youtube {
        transform: none !important;
        transition-duration: 1ms !important;
    }
}
