/* ============================================================================
   Recorder — theme-aware styling.
   Colors, backgrounds, borders, and text come from the CMS theme tokens
   (--cms-bg, --cms-fg, --cms-muted, --cms-border, --cms-card-bg,
   --cms-input-bg, --cms-input-fg, --cms-link). Defined in the parent
   cms-core stylesheet and automatically light/dark aware.

   Only colours that are FUNCTIONAL (carry meaning) are declared here:
     - Record button red      → signals recording
     - Waveform / progress     → distinguishable audio visualization
     - Region highlight amber  → visible editable range
     - Level-meter green→red   → visual loudness scale
   Margins and layout use the CMS utility classes (row, flex-container,
   padding-small, …) wherever possible — see recorder.php.
   ============================================================================ */

:root {
    /* Functional, non-theme colors only — everything else uses --cms-*. */
    --rec-record:       #e74c3c;   /* record button red */
    --rec-record-hover: #c0392b;
    --rec-waveform:     var(--cms-muted);
    --rec-progress:     var(--cms-link);
    --rec-region:       rgba(255, 176, 32, 0.22);
    --rec-region-edge:  rgba(255, 176, 32, 0.9);
    --rec-meter-bg:     var(--cms-input-bg);
    --rec-meter-grad:   linear-gradient(90deg, #2ecc71, #ffb020 70%, #ff3b5c);
}

/* ---------------------------------------------------------------------------
   Unified button styling — every button in the recorder takes on the
   same bordered/rounded look as the ENABLED chip. Works in both themes
   because it references theme tokens only.
   --------------------------------------------------------------------------- */
main button,
.panel button,
.wave-editor button,
.editor-controls button,
.controls button,
.wave-controls-bar button {
    background: var(--cms-input-bg);
    color: var(--cms-fg);
    border: 1px solid var(--cms-border);
    border-radius: 8px;
    padding: 9px 14px;
    font-size: 14px;
    font-family: inherit;
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s, opacity 0.15s;
}
main button:hover:not(:disabled),
.panel button:hover:not(:disabled),
.wave-editor button:hover:not(:disabled),
.editor-controls button:hover:not(:disabled),
.controls button:hover:not(:disabled),
.wave-controls-bar button:hover:not(:disabled) {
    border-color: var(--cms-link);
    color: var(--cms-link);
}
main button:disabled,
.panel button:disabled,
.wave-editor button:disabled,
.editor-controls button:disabled,
.controls button:disabled,
.wave-controls-bar button:disabled {
    opacity: 0.45;
    cursor: not-allowed;
}

/* Thin utility — headings behave like normal text, not gradient. */
header h1 {
    margin: 0;
    font-size: 20px;
    display: inline;
}
header .subtitle {
    color: var(--cms-muted);
    font-size: 13px;
    margin-left: 12px;
}

/* ---------------------------------------------------------------------------
   Banners (permission / info warnings)
   Minimal accent tint; inherits --cms-border and --cms-fg otherwise.
   --------------------------------------------------------------------------- */
/* Plain block banners — no flex. Icons use `.left` (float:left), buttons
   use `.right` (float:right); the banner gets a clearfix so the floats
   don't escape its box. Visibility is controlled by the outer `.padding`
   wrapper's `[hidden]` attribute. */
.banner { font-size: 14px; }
.banner::after { content: ""; display: block; clear: both; }
.banner code {
    background: var(--cms-input-bg);
    padding: 2px 7px;
    border-radius: 4px;
    font-family: "SF Mono", Menlo, Consolas, monospace;
    font-size: 13px;
}
.banner.warn        { background: rgba(255, 176, 32, 0.12); border: 2px solid #ffb020; }
.banner.warn.denied { background: color-mix(in srgb, var(--rec-record) 12%, transparent); border: 2px solid var(--rec-record); }
.banner.info        { background: color-mix(in srgb, var(--cms-link) 12%, transparent); border: 2px solid var(--cms-link); }

/* Safari warning — icon floats left (text wraps around it), dismiss
   button floats right. `.big` bumps the icon + text sizes for the
   permission-needed state. */
.safari-warning-icon {
    width: 28px;
    height: 28px;
    margin-right: 12px;
    margin-bottom: 6px;
}
.safari-warning-title { font-weight: 700; }
.safari-warning-sub   { font-size: 13px; line-height: 1.45; opacity: 0.85; }
/* Action row — buttons in a banner sit on their own line under the text,
   cleared below any floated icon. */
.banner-actions { clear: both; margin-top: 12px; }

.safari-warning.big .safari-warning-icon  { width: 56px; height: 56px; margin-right: 16px; }
.safari-warning.big .safari-warning-title { font-size: 20px; margin-bottom: 4px; }
.safari-warning.big .safari-warning-sub   { font-size: 16px; opacity: 1; }

@media (max-width: 600px) {
    .safari-warning.big .safari-warning-icon  { width: 40px; height: 40px; }
    .safari-warning.big .safari-warning-title { font-size: 17px; }
    .safari-warning.big .safari-warning-sub   { font-size: 14px; }
}

/* ---------------------------------------------------------------------------
   Controls grid
   --------------------------------------------------------------------------- */
.controls-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 14px;
}
.field        { display: flex; flex-direction: column; gap: 6px; }
.field label  { font-size: 12px; color: var(--cms-muted); text-transform: uppercase; letter-spacing: 0.08em; }
.field .input-row { display: flex; gap: 6px; }

.checkbox-field {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 10px 12px;
    border: 1px solid var(--cms-border);
    border-radius: 8px;
    cursor: pointer; user-select: none;
    font-size: 14px;
    background: var(--cms-input-bg);
    opacity: 0.55;
    transition: border-color 0.15s, opacity 0.15s;
    /* Match the height of the adjacent <select> so the row aligns nicely. */
    min-height: 40px;
    /* Don't let the status label inherit the uppercase/letter-spacing the
       outer .field label styling forces on <label> elements. */
    text-transform: none;
    letter-spacing: 0;
    color: var(--cms-fg);
    font-size: 14px;
}
.checkbox-field:has(input:checked) {
    border-color: var(--cms-link);
    opacity: 1;
}
/* Hide the native checkbox but keep it focusable + click-targeted. */
.checkbox-field-input {
    position: absolute !important;
    left: -9999px !important;
    width: 1px !important;
    height: 1px !important;
    opacity: 0 !important;
    pointer-events: none !important;
}
/* Swap the two labels based on checkbox state. */
.checkbox-field .label-on  { display: none; font-weight: 600; }
.checkbox-field .label-off { display: inline; }
.checkbox-field:has(input:checked) .label-on  { display: inline; color: var(--cms-link); }
.checkbox-field:has(input:checked) .label-off { display: none; }

/* Microphone refresh button — SVG icon (currentColor) sits centered inside
   the standard bordered button chrome. Shape matches the ENABLED field next
   to it so the grid row reads as one coherent height. */
#refreshMicsBtn {
    padding: 0 12px;
    min-height: 40px;
    min-width: 40px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
}
#refreshMicsBtn svg { display: block; }

/* ---------------------------------------------------------------------------
   Red accents — record + destructive actions (Clear all). Red carries
   meaning ("recording" or "will discard"), so it stays regardless of theme.
   --------------------------------------------------------------------------- */
.btn-record,
#clearBtn {
    background: var(--rec-record) !important;
    border: 1px solid var(--rec-record) !important;
    color: #ffffff !important;
    font-weight: 600;
}
.btn-record:hover:not(:disabled),
#clearBtn:hover:not(:disabled) {
    background: var(--rec-record-hover) !important;
    border-color: var(--rec-record-hover) !important;
    /* Override the generic button:hover above which flips text to the
       link colour — red record/clear buttons must stay white. */
    color: #ffffff !important;
}

/* ---------------------------------------------------------------------------
   Audio converter — two places that needed their own polish:
     1) The progress bar: the generic .level-meter is a 60 px peak meter
        (fine in the live-recording panel), but in the converter it needs
        to read as a real progress bar across the full card width.
     2) The format <select>: give it the same height + rounded look as
        the other fields so it sits consistently in the target-format row.
   --------------------------------------------------------------------------- */
#acProgressWrap .level-meter,
#compProgressWrap .level-meter {
    width: 100%;
    height: 10px;
}
#acProgressWrap .level-meter-fill,
#compProgressWrap .level-meter-fill {
    transition: width 0.15s ease-out;
}
#acProgressLabel,
#compProgressLabel {
    margin-bottom: 6px;
    font-variant-numeric: tabular-nums;
}

#acTargetSelect,
#compTargetSelect {
    width: 100%;
    min-height: 40px;
    /* Leave room on the right for the chevron arrow drawn by the core
       select rule (/elements/images/arrow-down.svg). Use background-color
       instead of the shorthand so we don't clobber background-image. */
    padding: 0 28px 0 12px;
    background-color: var(--cms-input-bg);
    color: var(--cms-input-fg, var(--cms-fg));
    border: 1px solid var(--cms-border);
    border-radius: 8px;
    font-size: 14px;
    font-family: inherit;
    cursor: pointer;
    transition: border-color 0.15s;
}
#acTargetSelect:hover:not(:disabled),
#compTargetSelect:hover:not(:disabled) { border-color: var(--cms-link); }
#acTargetSelect:focus,
#compTargetSelect:focus               { outline: 2px solid var(--cms-link); outline-offset: 1px; }
#acTargetSelect option:disabled,
#compTargetSelect option:disabled     { color: var(--cms-muted); }

/* Time badge sits alongside Play/Pause and Replace-file buttons inside
   `.controls`; the generic .badge rule is too small for that row. Match
   the adjacent .controls button sizing so the three items share a
   height. `.round` comes from the host chrome and rounds the corners. */
#compTimeBadge {
    font-size: 13px;
    padding: 7px 12px;
    border: 1px solid var(--cms-border);
    background: var(--cms-input-bg);
    color: var(--cms-fg);
    font-variant-numeric: tabular-nums;
}

/* Compression slider on the compressor page. Matches the module's
   overall input styling — full-width, themed accent, ew-resize cursor
   so it reads as draggable. */
.comp-slider {
    width: 100%;
    accent-color: var(--cms-link);
    cursor: ew-resize;
    margin: 0;
    padding: 0;
}
.comp-slider::-webkit-slider-thumb { cursor: ew-resize; }
.comp-slider::-moz-range-thumb     { cursor: ew-resize; }

/* ---------------------------------------------------------------------------
   Live recording canvas
   --------------------------------------------------------------------------- */
.live-wave {
    position: relative;
    height: 140px;
    overflow: hidden;
    border: 1px solid var(--cms-border);
    border-radius: 8px;
    background: var(--cms-input-bg);
}
.live-wave canvas { display: block; width: 100%; height: 100%; }
.live-overlay,
.live-level {
    position: absolute;
    top: 8px;
    font-size: 12px;
    color: var(--cms-muted);
    background: var(--cms-card-bg);
    padding: 3px 8px;
    border-radius: 4px;
    opacity: 0.9;
}
.live-overlay { left: 10px; font-variant-numeric: tabular-nums; }
.live-level   { right: 10px; display: flex; align-items: center; gap: 6px; font-size: 11px; }

.level-meter {
    width: 60px; height: 6px;
    background: var(--rec-meter-bg);
    border-radius: 3px;
    overflow: hidden;
}
.level-meter-fill {
    height: 100%; width: 0%;
    background: var(--rec-meter-grad);
    transition: width 0.05s;
}

/* ---------------------------------------------------------------------------
   Timer + recording dot
   --------------------------------------------------------------------------- */
.timer {
    font-family: "SF Mono", Menlo, Consolas, monospace;
    font-size: 28px;
    font-variant-numeric: tabular-nums;
    letter-spacing: 1px;
}
.timer .rec-dot {
    display: inline-block;
    width: 10px; height: 10px;
    border-radius: 50%;
    background: var(--rec-record);
    margin-right: 8px;
    vertical-align: middle;
    opacity: 0.3;
}
.timer.recording .rec-dot { opacity: 1; animation: pulse 1.2s ease-in-out infinite; }
@keyframes pulse { 0%,100% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.3); opacity: 0.5; } }

/* ---------------------------------------------------------------------------
   Live transcript
   --------------------------------------------------------------------------- */
.live-transcript {
    font-size: 14px;
    line-height: 1.5;
    min-height: 40px;
    max-height: 180px;
    overflow-y: auto;
    border: 1px solid var(--cms-border);
    border-radius: 8px;
    padding: 12px;
    background: var(--cms-input-bg);
}
.live-transcript .interim { color: var(--cms-muted); font-style: italic; }

/* ---------------------------------------------------------------------------
   Recording cards + waveform editor
   --------------------------------------------------------------------------- */
.recording {
    /* No sub-container border — the outer .card already wraps us. */
    border: 0;
    background: transparent;
}
/* Visual separator between recordings. Hangs the rule off every
   recording that directly follows another — so #emptyState (same parent,
   hidden but still in the DOM) doesn't trip :last-child the way a naive
   bottom-border rule would. First recording never has a rule above it,
   last never has one below. */
.recording + .recording {
    border-top: 1px solid var(--cms-hr);
    padding-top: 20px;
    margin-top: 20px;
}
.rename {
    flex: 1 1 220px;
    min-width: 180px;
    font-size: 18px;
    font-weight: 600;
    /* No visible input chrome — just the editable text. */
    border: 0 !important;
    outline: none !important;
    background: transparent !important;
    box-shadow: none !important;
    padding: 4px 0 !important;
    margin-bottom: 12px;
}
.rename:focus {
    outline: none !important;
    border: 0 !important;
    box-shadow: none !important;
}
.info-badges {
    display: flex; gap: 8px;
    font-size: 12px;
    color: var(--cms-muted);
    align-items: center;
    flex-wrap: wrap;
    margin-bottom: 12px;
}
.badge {
    padding: 3px 8px;
    border-radius: 4px;
    border: 1px solid var(--cms-border);
    background: var(--cms-input-bg);
    /* Explicit color — otherwise inherits --cms-muted which becomes invisible
       against the light-theme white card background. */
    color: var(--cms-fg);
    font-size: 12px;
    line-height: 1.3;
}
/* Drop the plain duration badge — the play/pause panel on the left already
   shows current-time / duration, so this one is redundant. In JS app.js the
   order is: formatBadge, sizeBadge, durBadge, timeBadge. */
.info-badges .badge:nth-of-type(3) { display: none; }

.wave-editor { user-select: none; }
.wave-main {
    position: relative;
    height: 110px;
    overflow: hidden;
    touch-action: none;
    border: 1px solid var(--cms-border);
    border-radius: 8px;
    background: var(--cms-input-bg);
    margin-top: 12px;
}
.wave-main canvas { display: block; width: 100%; height: 100%; cursor: text; }
.wave-editor.loading .wave-main::after {
    content: attr(data-loading-label);
    position: absolute; inset: 0;
    display: flex; align-items: center; justify-content: center;
    color: var(--cms-muted);
    font-size: 13px;
    background: color-mix(in srgb, var(--cms-bg) 60%, transparent);
}

.wave-region {
    position: absolute; top: 0; bottom: 0;
    background: var(--rec-region);
    border-left: 2px solid var(--rec-region-edge);
    border-right: 2px solid var(--rec-region-edge);
    cursor: grab;
}
.wave-region:active { cursor: grabbing; }
.wave-region .handle       { position: absolute; top: 0; bottom: 0; width: 10px; cursor: ew-resize; }
.wave-region .handle-start { left: -5px; }
.wave-region .handle-end   { right: -5px; }
.wave-region .label {
    position: absolute;
    background: var(--cms-card-bg);
    color: var(--cms-fg);
    font-size: 10.5px;
    padding: 1px 5px;
    border-radius: 3px;
    font-variant-numeric: tabular-nums;
    pointer-events: none;
}
.wave-region .label-start { top: 2px;    left: 4px;  }
.wave-region .label-end   { bottom: 2px; right: 4px; }

.wave-playhead {
    position: absolute; top: 0; bottom: 0; width: 2px;
    background: var(--rec-progress);
    pointer-events: none;
    transform: translateX(-1px);
}
.wave-playhead .ph-label {
    position: absolute; bottom: 2px; left: 4px;
    background: var(--rec-progress);
    color: #ffffff;
    font-size: 10.5px;
    padding: 1px 5px;
    border-radius: 3px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.wave-controls-bar {
    /* Inline strip — no container chrome (border/bg/padding removed so the
       zoom controls sit directly on the card surface). */
    display: flex; align-items: center; gap: 10px;
    padding: 0;
    border: 0;
    background: transparent;
    font-size: 12px;
    margin-top: 12px;
}
/* Zoom +/- buttons — normal foreground, not the muted grey they had before. */
.wave-controls-bar .zoom-btn {
    padding: 2px 10px;
    font-size: 16px;
    min-width: 30px;
    line-height: 1;
    color: var(--cms-fg);
    font-weight: 600;
}
.wave-controls-bar .zoom-slider {
    flex: 1;
    accent-color: var(--cms-link);
    min-width: 60px;
    /* Strip the native lateral padding so the thumb actually reaches the
       visible left/right edges of the track at value 0 / 100. */
    margin: 0;
    padding: 0;
}
.wave-controls-bar .zoom-slider::-webkit-slider-runnable-track { margin: 0; padding: 0; }
.wave-controls-bar .zoom-slider::-moz-range-track              { margin: 0; padding: 0; }
/* Horizontal-resize cursor over the slider thumb (and the track as a whole
   for good measure) — signals the element is draggable left/right. */
.wave-controls-bar .zoom-slider                          { cursor: ew-resize; }
.wave-controls-bar .zoom-slider::-webkit-slider-thumb    { cursor: ew-resize; }
.wave-controls-bar .zoom-slider::-moz-range-thumb        { cursor: ew-resize; }
.wave-controls-bar .zoom-icon  { color: var(--cms-fg); font-size: 15px; }
.wave-controls-bar .view-info  {
    color: var(--cms-muted);
    font-variant-numeric: tabular-nums;
    font-family: "SF Mono", Menlo, Consolas, monospace;
    white-space: nowrap;
}

.wave-minimap {
    position: relative;
    height: 40px;
    overflow: hidden;
    touch-action: none;
    cursor: pointer;
    border: 1px solid var(--cms-border);
    border-radius: 8px;
    background: var(--cms-input-bg);
    margin-top: 12px;
}
.wave-minimap canvas { display: block; width: 100%; height: 100%; }
.minimap-window {
    position: absolute; top: 0; bottom: 0;
    background: color-mix(in srgb, var(--cms-link) 18%, transparent);
    border: 1px solid var(--cms-link);
    /* 7px = parent's 8px radius minus its 1px border. Matches the rounded
       shape of the minimap when the window spans the full width. */
    border-radius: 7px;
    cursor: grab;
    box-sizing: border-box;
}

/* Keep the drag cursor visible while the user is dragging, even when the
   pointer leaves the draggable element (browsers otherwise revert to the
   default arrow as soon as you move fast enough to overshoot). The JS
   adds / removes these body classes around the pointerdown-pointerup
   lifecycle. */
body.minimap-dragging,
body.minimap-dragging *,
body.wave-dragging,
body.wave-dragging *,
body.wave-selecting,
body.wave-selecting * { cursor: grabbing !important; }
body.wave-resizing,
body.wave-resizing * { cursor: ew-resize !important; }
.minimap-window:active { cursor: grabbing; }
.minimap-playhead {
    position: absolute; top: 0; bottom: 0;
    width: 1px; background: var(--cms-link);
    opacity: 0.7; pointer-events: none;
}
/* Selection overlay on the minimap — mirrors the main waveform's region
   so it's visible even when the main view is zoomed past the selection.
   Yellow in light mode so it reads against the pale minimap background;
   dark mode keeps the themed link color since that's already high-contrast. */
.minimap-region {
    position: absolute; top: 0; bottom: 0;
    background: color-mix(in srgb, #d4a017 28%, transparent);
    border-left: 1px solid #d4a017;
    border-right: 1px solid #d4a017;
    pointer-events: none;
}
html[data-theme="dark"] .minimap-region {
    background: color-mix(in srgb, var(--cms-link) 28%, transparent);
    border-left-color: var(--cms-link);
    border-right-color: var(--cms-link);
}

.controls         { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; margin-top: 12px; }
.controls button  { font-size: 13px; padding: 7px 12px; }

/* Editor section — label styled like the Transcript header, buttons full-round. */
.editor-controls {
    display: block;
    margin-top: 16px;
    margin-bottom: 20px;
}
.editor-controls h3.label,
.editor-controls .label {
    display: block;
    margin: 0 0 8px 0;
    font-size: 13px;
    font-weight: 600;
    color: var(--cms-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
}
/* Hide the editor hint; it's self-explanatory once you play with it. */
.editor-hint { display: none; }
/* Drop the old flex quirks and render each button normally, rounded. */
.editor-controls > button,
.editor-controls > span {
    display: inline-block;
    margin: 4px 6px 4px 0;
}

.transcript-section          { border-top: 1px solid var(--cms-border); padding-top: 14px; margin-top: 4px; }
.transcript-section h3,
.transcript-section h4       { margin: 0 0 8px 0; font-size: 13px; font-weight: 600; color: var(--cms-muted); text-transform: uppercase; letter-spacing: 0.06em; }
.transcript {
    font-size: 14px;
    line-height: 1.6;
    min-height: 60px;
    /* No visible text-area chrome. */
    outline: none !important;
    border: 0 !important;
    background: transparent !important;
    padding: 0;
    box-shadow: none !important;
}
.transcript:focus                     { outline: none !important; border: 0 !important; box-shadow: none !important; }
.transcript span[time]                { cursor: pointer; border-radius: 3px; padding: 0 1px; transition: background 0.1s; }
.transcript span[time]:hover          { background: color-mix(in srgb, var(--cms-link) 25%, transparent); }

.delay-control                        { display: flex; align-items: center; gap: 8px; font-size: 13px; }
.delay-control input[type="range"]    { width: 160px; accent-color: var(--cms-link); }

.empty-state {
    text-align: center;
    color: var(--cms-muted);
    border: 2px dashed var(--cms-border);
    border-radius: 10px;
}
.empty-state .icon { font-size: 32px; margin-bottom: 8px; }

.info-inline { color: var(--cms-muted); font-size: 12px; margin-left: 8px; }
.kbd {
    font-family: "SF Mono", Menlo, Consolas, monospace;
    font-size: 11px;
    padding: 2px 5px;
    border-radius: 3px;
    border: 1px solid var(--cms-border);
    color: var(--cms-muted);
    background: var(--cms-input-bg);
}
