/*!
 * GZ Chat Voice Recorder — shared module
 *
 * Plan 2026-05-26 Batch 4 : WhatsApp-style voice recording integrated into
 * the composer of the three customer-side chats (landing, support, panel).
 *
 * Loaded BEFORE the per-widget stylesheet so the widget can override the
 * accent color via --primary-rgb. The recorder UI takes over the
 * composer footprint when [data-rec-state] on the composer is anything
 * other than "idle" — no detached floating bar.
 *
 * Hard contracts (don't break):
 *   - Idle children of the composer (textarea, send, attach) are hidden
 *     via the [data-cvr-hidden] attribute (set by the JS, NOT a
 *     [data-rec-state] sibling selector) so the host's per-widget rules
 *     can still target those elements freely.
 *   - Latin digits only in the mm:ss readouts; dir-locked LTR.
 *   - RTL safe: every position uses logical properties; slide chevron
 *     mirrors via scaleX(-1).
 *   - Dark-mode hook reuses the chat-canon `[data-theme="dark"]` selector
 *     for the panel-chat surface (super-admin / admin canon).
 *   - prefers-reduced-motion drops the pulse and slide transitions.
 */

/* The recorder root. Inline-flex so it sits naturally between the
   composer's edge buttons when active. Hidden in idle. */
.cvr {
    display: none;
    align-items: center;
    gap: 8px;
    flex: 1 1 auto;
    min-width: 0;
    padding: 4px 6px;
    box-sizing: border-box;
    isolation: isolate;
    color: inherit;
    --cvr-accent: var(--primary-strong, #c14a00);
    --cvr-accent-rgb: var(--primary-rgb, 193, 74, 0);
    --cvr-danger: #dc2626;
    --cvr-danger-rgb: 220, 38, 38;
}

/* Wake the recorder when the composer is in any non-idle state. */
[data-rec-state="recording"] .cvr,
[data-rec-state="preview"] .cvr,
[data-rec-state="uploading"] .cvr {
    display: flex;
}

/* Hide idle composer children when the recorder is active. The host's
   JS marks the elements via [data-cvr-hidden="1"]; we hide them here. */
[data-cvr-hidden="1"] {
    display: none !important;
}

/* Show only the matching panel for the current state. */
.cvr__panel {
    display: none;
    align-items: center;
    gap: 8px;
    flex: 1 1 auto;
    min-width: 0;
}
.cvr[data-rec-state="recording"] .cvr__panel--recording,
.cvr[data-rec-state="preview"]   .cvr__panel--preview,
.cvr[data-rec-state="uploading"] .cvr__panel--preview {
    display: flex;
}

/* Pulse dot (recording state). */
.cvr__pulse {
    flex: 0 0 auto;
    inline-size: 10px;
    block-size: 10px;
    border-radius: 50%;
    background: var(--cvr-danger);
    box-shadow: 0 0 0 0 rgba(var(--cvr-danger-rgb), 0.45);
    animation: cvr-pulse 1.4s ease-out infinite;
}
@keyframes cvr-pulse {
    0%   { box-shadow: 0 0 0 0   rgba(var(--cvr-danger-rgb), 0.55); }
    70%  { box-shadow: 0 0 0 8px rgba(var(--cvr-danger-rgb), 0);    }
    100% { box-shadow: 0 0 0 0   rgba(var(--cvr-danger-rgb), 0);    }
}

/* Live waveform container. Flexes to fill, but never pushes the timer
   off the row. */
.cvr__live {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 1 1 auto;
    min-width: 0;
}
.cvr__wave {
    flex: 1 1 auto;
    min-inline-size: 60px;
    inline-size: 100%;
    block-size: 30px;
    display: block;
}
.cvr__wave--preview {
    block-size: 32px;
}

/* Timer mm:ss — dir-locked LTR (set on the element via attribute), font
   weight a bit heavier so it reads against the busy waveform. */
.cvr__timer {
    flex: 0 0 auto;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    font-size: 0.95rem;
    color: var(--text, #1f2937);
    min-inline-size: 2.7em;
    text-align: center;
}
.cvr__timer--preview {
    color: var(--cvr-accent);
}

/* Buttons. Round, 36x36, primary tint for send / play, danger tint for
   discard, red filled for stop. */
.cvr__btn {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: 36px;
    block-size: 36px;
    border-radius: 50%;
    border: 1px solid transparent;
    background: transparent;
    color: inherit;
    cursor: pointer;
    padding: 0;
    appearance: none;
    -webkit-appearance: none;
    transition: background-color 160ms ease, color 160ms ease, transform 120ms ease, border-color 160ms ease;
}
.cvr__btn:hover { background: rgba(0, 0, 0, 0.06); }
.cvr__btn:focus-visible {
    outline: 2px solid var(--cvr-accent);
    outline-offset: 2px;
}
.cvr__btn svg {
    inline-size: 18px;
    block-size: 18px;
}

.cvr__btn--discard {
    color: var(--cvr-danger);
    border-color: rgba(var(--cvr-danger-rgb), 0.35);
    background: rgba(var(--cvr-danger-rgb), 0.06);
}
.cvr__btn--discard:hover {
    background: rgba(var(--cvr-danger-rgb), 0.12);
}

.cvr__btn--stop {
    background: var(--cvr-danger);
    color: #ffffff;
    border-color: transparent;
}
.cvr__btn--stop:hover { filter: brightness(0.92); }

.cvr__btn--send {
    background: var(--cvr-accent);
    color: var(--primary-contrast, #ffffff);
    border-color: transparent;
}
.cvr__btn--send:hover { filter: brightness(0.92); }
.cvr__btn--send:disabled,
.cvr__btn:disabled {
    opacity: 0.55;
    cursor: not-allowed;
    filter: none;
}

.cvr__btn--play {
    background: rgba(var(--cvr-accent-rgb), 0.10);
    color: var(--cvr-accent);
    border-color: rgba(var(--cvr-accent-rgb), 0.30);
}
.cvr__btn--play:hover {
    background: rgba(var(--cvr-accent-rgb), 0.18);
}

/* Slide-to-cancel hint. Visible only on coarse pointer (touch); on a
   mouse / pen it's pointer-events:none and visually hidden so the
   recording bar stays clean. */
.cvr__slide {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    flex: 0 1 auto;
    min-width: 0;
    color: var(--muted, #6b7280);
    font-size: 0.85rem;
    transition: transform 160ms ease, opacity 160ms ease;
    pointer-events: none;
    /* Default to hidden on fine pointer. */
    display: none;
}
.cvr__slide svg {
    inline-size: 14px;
    block-size: 14px;
}
/* In RTL the chevron points the other way. */
.cvr[dir="rtl"] .cvr__slide svg {
    transform: scaleX(-1);
}
.cvr__slide-text {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 12em;
}
/* Cancel-armed: bring the entire recording panel to a red tone so the
   user knows release == cancel. */
.cvr--cancel-armed .cvr__pulse { animation-duration: 0.6s; }
.cvr--cancel-armed .cvr__wave  { filter: hue-rotate(-25deg) saturate(1.6); }
.cvr--cancel-armed .cvr__slide { color: var(--cvr-danger); }

/* On coarse pointer, surface the slide hint AND hide the desktop-only
   stop button (release-to-stop is the touch UX). */
@media (pointer: coarse), (hover: none) {
    .cvr__slide { display: inline-flex; }
    .cvr__btn--stop { display: none; }
}

/* On a fine pointer (mouse / pen) the inline discard button stays for
   click access and the stop button is the primary stop affordance. */
@media (pointer: fine) {
    .cvr__btn--stop { display: inline-flex; }
}

/* Player (preview state) — play/pause + frozen waveform feels like
   the bubble version so the visitor sees what they're about to send. */
.cvr__player {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 1 1 auto;
    min-width: 0;
}
.cvr__player .cvr__btn--play {
    inline-size: 34px;
    block-size: 34px;
}

/* Mic button state hooks — host's mic stays in its own DOM, but we add
   modifier classes for visual feedback. The host owns the actual
   shape/colour to avoid stepping on per-widget design tokens. */
[data-rec-state="recording"] .is-recording {
    /* tiny visual cue — host CSS can override or stack */
    box-shadow: 0 0 0 3px rgba(var(--cvr-danger-rgb, 220, 38, 38), 0.25);
}

/* Compact (mobile) tightening. */
@media (max-width: 420px) {
    .cvr { gap: 6px; padding: 4px; }
    .cvr__btn { inline-size: 34px; block-size: 34px; }
    .cvr__btn svg { inline-size: 16px; block-size: 16px; }
    .cvr__timer { font-size: 0.88rem; min-inline-size: 2.5em; }
    .cvr__slide { font-size: 0.78rem; }
    .cvr__wave { block-size: 26px; }
    .cvr__wave--preview { block-size: 28px; }
}

/* Dark mode hook for the panel surface (admin canon). */
[data-theme="dark"] .cvr,
.cvr[data-theme="dark"] {
    color: var(--text, #e5e7eb);
}
[data-theme="dark"] .cvr__timer {
    color: var(--text, #e5e7eb);
}
[data-theme="dark"] .cvr__btn:hover {
    background: rgba(255, 255, 255, 0.08);
}
[data-theme="dark"] .cvr__btn--discard {
    border-color: rgba(var(--cvr-danger-rgb), 0.55);
    background: rgba(var(--cvr-danger-rgb), 0.18);
    color: #fda4a4;
}
[data-theme="dark"] .cvr__btn--play {
    background: rgba(var(--cvr-accent-rgb), 0.18);
    border-color: rgba(var(--cvr-accent-rgb), 0.45);
}
[data-theme="dark"] .cvr__slide { color: rgba(229, 231, 235, 0.7); }

/* Reduce motion: kill the pulse and slide transition. */
@media (prefers-reduced-motion: reduce) {
    .cvr__pulse {
        animation: none;
        box-shadow: none;
    }
    .cvr__btn,
    .cvr__slide {
        transition: none;
    }
}

/* Keyboard focus visibility for the live wave (slider role on the
   preview canvas would be ambiguous — we keep the canvas plain). */
.cvr__btn--play:focus-visible,
.cvr__btn--send:focus-visible,
.cvr__btn--discard:focus-visible,
.cvr__btn--stop:focus-visible {
    outline: 2px solid var(--cvr-accent);
    outline-offset: 2px;
}
