/*!
 * Curious Research Metadata Inspector — front-end styles
 * Purple brand palette matches the Curious Research desktop app.
 */
.crmi-instance {
    --crmi-bg-dark: #241033;
    --crmi-bg-panel: #2f1747;
    --crmi-accent: #9b4fd1;
    --crmi-accent-hover: #b06fe0;
    --crmi-text-light: #f3ecfa;
    --crmi-text-muted: #c9b8dd;
    --crmi-success: #5fd68a;
    --crmi-warning: #f0b429;
    --crmi-error: #e05c5c;
    --crmi-row-alt: #3a1f57;

    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    color: var(--crmi-text-light);
    background: var(--crmi-bg-dark);
    border-radius: 10px;
    padding: 24px;
    max-width: 900px;
    margin: 0 auto;
    box-sizing: border-box;
}
.crmi-instance *, .crmi-instance *::before, .crmi-instance *::after { box-sizing: border-box; }

/* Logo stacked above the title, centered, on every screen size — a
   horizontal (logo | text) layout was overflowing the container on
   narrower pages, pushing "Metadata Inspector" off to the right. */
.crmi-header {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 8px;
    margin-bottom: 16px;
}
.crmi-header picture, .crmi-header img { display: block; max-width: 100%; }
.crmi-header img { height: 40px; width: auto; }
.crmi-header h3 { margin: 0; font-size: 1.25rem; color: var(--crmi-text-light); }
.crmi-privacy-note {
    background: rgba(95, 214, 138, 0.12);
    border: 1px solid var(--crmi-success);
    color: var(--crmi-text-light);
    border-radius: 6px;
    padding: 10px 14px;
    font-size: 0.875rem;
    margin-bottom: 18px;
    text-align: center;
    font-weight: 700;
}
.crmi-privacy-note strong { color: var(--crmi-success); }

.crmi-dropzone {
    border: 2px dashed var(--crmi-accent);
    border-radius: 8px;
    padding: 36px 20px;
    text-align: center;
    cursor: pointer;
    background: var(--crmi-bg-panel);
    transition: background 0.15s ease, border-color 0.15s ease;
}
.crmi-dropzone:hover, .crmi-dropzone.crmi-dragover { background: #38205a; border-color: var(--crmi-accent-hover); }
.crmi-dropzone.crmi-processing { opacity: 0.6; pointer-events: none; }
.crmi-dropzone p { margin: 0 0 8px; color: var(--crmi-text-muted); }
.crmi-dropzone .crmi-dropzone-title { color: var(--crmi-text-light); font-weight: 600; font-size: 1rem; margin-bottom: 6px; }
.crmi-file-input { display: none; }
.crmi-browse-btn {
    display: inline-block;
    margin-top: 6px;
    background: var(--crmi-accent);
    color: #fff;
    border: none;
    border-radius: 5px;
    padding: 8px 18px;
    font-size: 0.9rem;
    cursor: pointer;
}
.crmi-browse-btn:hover { background: var(--crmi-accent-hover); }

.crmi-file-list { display: flex; flex-wrap: wrap; gap: 6px; margin: 14px 0; }
.crmi-file-chip {
    background: var(--crmi-bg-panel);
    color: var(--crmi-text-muted);
    border: 1px solid transparent;
    border-radius: 999px;
    padding: 5px 12px;
    font-size: 0.8rem;
    cursor: pointer;
}
.crmi-file-chip-active { color: var(--crmi-text-light); border-color: var(--crmi-accent); }

.crmi-warnings { margin: 14px 0; }
.crmi-warning {
    color: var(--crmi-warning);
    font-size: 0.85rem;
    background: rgba(240, 180, 41, 0.1);
    border-radius: 5px;
    padding: 6px 10px;
    margin-bottom: 6px;
}

.crmi-results { margin-top: 18px; }

/* Always-visible action bar for the whole result (currently just "Export
   Full Report") — deliberately OUTSIDE `.crmi-results-scroll` below, so it
   stays reachable without scrolling regardless of which tab is active or
   how tall that tab's content is. */
.crmi-report-bar { display: flex; gap: 8px; margin-bottom: 14px; flex-wrap: wrap; }
.crmi-report-btn {
    background: var(--crmi-accent); color: #fff; border: none; border-radius: 5px;
    padding: 9px 18px; font-size: 0.88rem; font-weight: 600; cursor: pointer;
}
.crmi-report-btn:hover { background: var(--crmi-accent-hover); }

/* Bounds the tab strip + all eleven tab panels to a fixed max height with
   its own vertical scrollbar, so a very tall tab's content (a spectrogram,
   a long tag list, ...) no longer makes the whole page balloon in height.
   `.crmi-main-tabs` below keeps its own independent `overflow-x: auto` for
   the horizontal tab-bar scroll — nesting one scroll container inside
   another here is intentional and doesn't conflict, since one scrolls X
   and the other Y. */
.crmi-results-scroll {
    max-height: 75vh;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
}

/* Always-visible dock for the active tab's "Using these controls" block
   (v1.15.0) — a sibling of `.crmi-results-scroll` (see cr-metadata-ui.js's
   switchMainTab()/updateHelpDock()), so the instructions never require
   scrolling the results area to reach, however tall that tab's own canvas/
   toolbar content is. Plain positioning container only — buildControlsHelp()
   already returns a fully self-styled `.crmi-controls-help` div, so this has
   no border/background of its own and takes up no visible space while empty
   (a tab with no controls, or between mounts). */
.crmi-controls-help-dock { margin-top: 16px; }
.crmi-controls-help-dock:empty { margin-top: 0; }

/* Top-level function tabs (Metadata/Exif, Image Adjustment, ...). With
   eight tabs as of v1.7.1, this row is wider than the container on most
   phone screens (and gets wider still every time a new tab is added) —
   rather than shrinking text or wrapping to a second line, this scrolls
   horizontally, the same swipeable-tab-strip pattern used by most mobile
   web apps. `overflow-x: auto` is unconditional (not gated to a mobile
   media query) so it's a no-op with no visible scrollbar whenever every
   tab already fits — desktop layout is unaffected either way. */
.crmi-main-tabs-wrap { position: relative; }

.crmi-main-tabs {
    display: flex; gap: 6px; margin-bottom: 18px;
    border-bottom: 2px solid var(--crmi-bg-panel);
    overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: thin;
}
.crmi-main-tab-btn {
    background: none; border: none; color: var(--crmi-text-muted);
    padding: 12px 20px; font-size: 1rem; font-weight: 600; cursor: pointer;
    border-bottom: 3px solid transparent; margin-bottom: -2px;
    flex: 0 0 auto; white-space: nowrap;
}
.crmi-main-tab-btn:hover { color: var(--crmi-text-light); }
.crmi-main-tab-btn.crmi-main-tab-active { color: var(--crmi-accent-hover); border-bottom-color: var(--crmi-accent); }

/* Hamburger toggle for the tab strip above (v1.18.0) — hidden here, at
   every width down to the 600px breakpoint, where the horizontally-
   scrollable strip already works fine as a swipeable row (see the comment
   on .crmi-main-tabs above). It's only switched to `display: flex` inside
   the @media (max-width: 600px) block further down, where the tab strip
   itself is switched to a collapsed dropdown instead. Kept unconditional
   (not nested in the media query) so its "hidden by default" state is
   obvious right next to the tab strip it toggles. */
.crmi-hamburger-btn {
    display: none;
    width: 100%; align-items: center; gap: 10px;
    background: var(--crmi-bg-panel); border: none; border-radius: 8px;
    padding: 12px 14px; margin-bottom: 14px; cursor: pointer;
    color: var(--crmi-text-light); font-size: 0.95rem; font-weight: 600; text-align: left;
}
.crmi-hamburger-btn:hover { background: #38205a; }
.crmi-hamburger-icon { display: flex; flex-direction: column; gap: 4px; flex: 0 0 auto; }
.crmi-hamburger-icon span { display: block; width: 20px; height: 2px; background: var(--crmi-text-light); border-radius: 1px; }
.crmi-hamburger-label { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.crmi-hamburger-caret { flex: 0 0 auto; font-size: 0.7rem; color: var(--crmi-text-muted); transition: transform 0.15s ease; }
.crmi-main-tabs-wrap.crmi-mobile-menu-open .crmi-hamburger-caret { transform: rotate(180deg); }

.crmi-tabs {
    display: flex; gap: 4px; border-bottom: 1px solid var(--crmi-bg-panel); margin-bottom: 14px;
    overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: thin;
}
.crmi-tab-btn {
    background: none; border: none; color: var(--crmi-text-muted);
    padding: 10px 16px; font-size: 0.9rem; cursor: pointer;
    border-bottom: 2px solid transparent;
    flex: 0 0 auto; white-space: nowrap;
}
.crmi-tab-btn.crmi-tab-active { color: var(--crmi-text-light); border-bottom-color: var(--crmi-accent); }

.crmi-section { margin-bottom: 20px; background: var(--crmi-bg-panel); border-radius: 8px; padding: 14px 16px; }
.crmi-section-title { margin: 0 0 10px; font-size: 0.95rem; color: var(--crmi-accent-hover); text-transform: uppercase; letter-spacing: 0.03em; }
.crmi-field-row { display: flex; justify-content: space-between; gap: 16px; padding: 6px 0; border-bottom: 1px solid rgba(255,255,255,0.05); font-size: 0.88rem; }
.crmi-field-row:last-child { border-bottom: none; }
.crmi-field-label { color: var(--crmi-text-muted); flex: 0 0 auto; }
.crmi-field-value { color: var(--crmi-text-light); text-align: right; word-break: break-word; }
.crmi-field-value.crmi-not-present { color: #8b7aa0; font-style: italic; }
.crmi-maps-link { color: var(--crmi-accent-hover); text-decoration: underline; }

/* Geolocation tab — unlike the canvas-based analysis tabs, the photo
   preview and map here are a plain <img>/<iframe>, so the responsive
   `max-width: 100%` behavior most themes apply is what we *want* rather
   than something to defend against with `!important` overrides. */
.crmi-geo-empty { color: var(--crmi-text-muted); font-style: italic; padding: 8px 2px; }
.crmi-geo-content {
    display: flex; gap: 16px; margin-bottom: 18px; flex-wrap: wrap;
}
.crmi-geo-photo, .crmi-geo-map {
    flex: 1 1 320px; min-width: 240px; background: var(--crmi-bg-panel);
    border-radius: 8px; overflow: hidden; display: flex; align-items: center;
    justify-content: center; min-height: 240px;
}
.crmi-geo-photo-img { display: block; width: 100%; height: 100%; max-height: 360px; object-fit: contain; }
.crmi-geo-photo-unsupported, .crmi-geo-map-placeholder p {
    color: var(--crmi-text-muted); font-style: italic; font-size: 0.85rem;
    text-align: center; padding: 16px;
}
.crmi-geo-map-placeholder {
    display: flex; flex-direction: column; align-items: center; gap: 10px; padding: 16px;
}
.crmi-geo-map-placeholder p { padding: 0; }
.crmi-geo-show-map-btn {
    background: var(--crmi-accent); color: #fff; border: none; border-radius: 5px;
    padding: 9px 18px; font-size: 0.88rem; font-weight: 600; cursor: pointer;
}
.crmi-geo-show-map-btn:hover { background: var(--crmi-accent-hover); }
.crmi-geo-map-iframe { width: 100%; height: 100%; min-height: 240px; border: none; display: block; }
.crmi-geo-links { display: flex; gap: 10px; flex-wrap: wrap; }
.crmi-geo-link-btn {
    background: transparent; border: 1px solid var(--crmi-accent); color: var(--crmi-text-light);
    border-radius: 5px; padding: 9px 16px; font-size: 0.85rem; text-decoration: none;
    display: inline-block; cursor: pointer;
}
.crmi-geo-link-btn:hover { background: rgba(155, 79, 209, 0.25); }

.crmi-tag-table { width: 100%; border-collapse: collapse; font-size: 0.82rem; }
.crmi-tag-table th { text-align: left; color: var(--crmi-accent-hover); padding: 8px; border-bottom: 1px solid var(--crmi-accent); }
.crmi-tag-table td { padding: 6px 8px; color: var(--crmi-text-light); vertical-align: top; }
.crmi-tag-table tbody tr:nth-child(even) { background: var(--crmi-row-alt); }
.crmi-tag-value { word-break: break-word; max-width: 420px; }
.crmi-empty { color: var(--crmi-text-muted); font-style: italic; }

.crmi-export-bar { display: flex; gap: 8px; margin-top: 16px; flex-wrap: wrap; }
.crmi-export-bar button {
    background: transparent; border: 1px solid var(--crmi-accent); color: var(--crmi-text-light);
    border-radius: 5px; padding: 7px 14px; font-size: 0.82rem; cursor: pointer;
}
.crmi-export-bar button:hover { background: var(--crmi-accent); }

/* -------------------------------------------------------------------- */
/* Image Adjustment tab                                                  */
/* -------------------------------------------------------------------- */
.crmi-imgadj { display: flex; flex-direction: column; gap: 12px; }
.crmi-imgadj-loading, .crmi-imgadj-unsupported {
    color: var(--crmi-text-muted); font-style: italic; padding: 24px; text-align: center;
    background: var(--crmi-bg-panel); border-radius: 8px;
}

.crmi-imgadj-toolbar {
    display: flex; flex-wrap: wrap; align-items: center; gap: 10px;
    background: var(--crmi-bg-panel); border-radius: 8px; padding: 10px 12px;
}
.crmi-imgadj-group { display: flex; gap: 4px; }
.crmi-imgadj-btn {
    background: transparent; border: 1px solid var(--crmi-accent); color: var(--crmi-text-light);
    border-radius: 5px; padding: 6px 12px; font-size: 0.82rem; cursor: pointer; line-height: 1.2;
}
.crmi-imgadj-btn:hover { background: rgba(155, 79, 209, 0.25); }
.crmi-imgadj-toggle.crmi-imgadj-toggle-active { background: var(--crmi-accent); color: #fff; }
.crmi-imgadj-contrast-label {
    display: flex; align-items: center; gap: 8px; color: var(--crmi-text-muted); font-size: 0.82rem;
}
.crmi-imgadj-contrast-slider { width: 120px; accent-color: var(--crmi-accent); }
.crmi-imgadj-contrast-value { min-width: 2.5em; text-align: right; color: var(--crmi-text-light); }

.crmi-imgadj-viewport {
    position: relative;
    width: 100%; height: 460px;
    overflow: hidden;
    border-radius: 8px;
    background-color: #1a0b26;
    background-image:
        linear-gradient(45deg, rgba(255,255,255,0.04) 25%, transparent 25%),
        linear-gradient(-45deg, rgba(255,255,255,0.04) 25%, transparent 25%),
        linear-gradient(45deg, transparent 75%, rgba(255,255,255,0.04) 75%),
        linear-gradient(-45deg, transparent 75%, rgba(255,255,255,0.04) 75%);
    background-size: 20px 20px;
    background-position: 0 0, 0 10px, 10px -10px, -10px 0px;
    cursor: grab;
    touch-action: none;
    /* Center the canvas with flexbox rather than the old "0x0 absolutely
       positioned anchor + -50%/-50% transform" trick. That trick made the
       0x0 div the percentage-resolution containing block for the canvas —
       and WordPress themes very commonly ship a global reset like
       `img, canvas, video { max-width:100%; height:auto }` for responsive
       media, which against a 0-width containing block collapses the canvas
       to nothing visible. Flexbox centering has no such trap. */
    display: flex; align-items: center; justify-content: center;
}
.crmi-imgadj-viewport.crmi-imgadj-dragging { cursor: grabbing; }
.crmi-imgadj-stage { position: relative; }
.crmi-imgadj-stage canvas {
    display: block;
    transform-origin: center center;
    image-rendering: pixelated;
    box-shadow: 0 4px 24px rgba(0,0,0,0.4);
    /* Belt-and-suspenders against that same theme reset: this canvas's
       real on-screen size is driven entirely by JS (its width/height
       attributes plus the transform below), never by CSS layout, so it
       opts out of any external max-width/height rule that might otherwise
       shrink or distort it. */
    max-width: none !important;
    max-height: none !important;
}

.crmi-imgadj-loupe {
    position: absolute;
    width: 160px; height: 160px;
    /* Rounded square rather than a full circle: a forensic magnifier is for
       reading pixels accurately, and a circular clip loses the corners of
       the zoomed window right when they might matter. */
    border-radius: 10px;
    border: 2px solid var(--crmi-accent-hover);
    box-shadow: 0 4px 16px rgba(0,0,0,0.5);
    pointer-events: none;
    overflow: hidden;
    opacity: 0;
    transition: opacity 0.08s ease;
    background: #000;
}
.crmi-imgadj-loupe canvas {
    width: 100% !important; height: 100% !important; max-width: none !important; max-height: none !important;
    image-rendering: pixelated; display: block;
}
/* Center crosshair — marks exactly which source pixel is under the cursor. */
.crmi-imgadj-loupe::before, .crmi-imgadj-loupe::after {
    content: "";
    position: absolute;
    background: rgba(255, 255, 255, 0.55);
    pointer-events: none;
}
.crmi-imgadj-loupe::before { left: 50%; top: 0; bottom: 0; width: 1px; transform: translateX(-0.5px); }
.crmi-imgadj-loupe::after { top: 50%; left: 0; right: 0; height: 1px; transform: translateY(-0.5px); }

.crmi-imgadj-histogram {
    background: var(--crmi-bg-panel); border-radius: 8px; padding: 12px;
}
.crmi-imgadj-histogram canvas { width: 100%; height: 160px; display: block; border-radius: 4px; }
.crmi-imgadj-histo-legend { display: flex; gap: 14px; margin-top: 8px; flex-wrap: wrap; font-size: 0.78rem; }
.crmi-histo-swatch { position: relative; padding-left: 16px; color: var(--crmi-text-muted); }
.crmi-histo-swatch::before {
    content: ""; position: absolute; left: 0; top: 3px; width: 10px; height: 10px; border-radius: 2px;
}
.crmi-histo-swatch.crmi-histo-r::before { background: #e05c5c; }
.crmi-histo-swatch.crmi-histo-g::before { background: #5fd68a; }
.crmi-histo-swatch.crmi-histo-b::before { background: #5f9fd6; }
.crmi-histo-swatch.crmi-histo-lum::before { background: #c9b8dd; }

/* -------------------------------------------------------------------- */
/* Clone Detection tab                                                   */
/* -------------------------------------------------------------------- */
.crmi-clone { display: flex; flex-direction: column; gap: 12px; }
.crmi-clone-loading, .crmi-clone-unsupported {
    color: var(--crmi-text-muted); font-style: italic; padding: 24px; text-align: center;
    background: var(--crmi-bg-panel); border-radius: 8px;
}

.crmi-clone-toolbar {
    display: flex; flex-wrap: wrap; align-items: flex-end; gap: 16px;
    background: var(--crmi-bg-panel); border-radius: 8px; padding: 12px 14px;
}
.crmi-clone-control { display: flex; flex-direction: column; gap: 4px; font-size: 0.8rem; color: var(--crmi-text-muted); }
.crmi-clone-control label { cursor: help; }
.crmi-clone-control-row { display: flex; align-items: center; gap: 8px; }
.crmi-clone-slider { width: 130px; accent-color: var(--crmi-accent); }
.crmi-clone-value { color: var(--crmi-text-light); min-width: 2.4em; text-align: right; font-size: 0.85rem; }
.crmi-clone-select {
    background: var(--crmi-bg-dark); color: var(--crmi-text-light);
    border: 1px solid var(--crmi-accent); border-radius: 5px; padding: 5px 8px; font-size: 0.85rem;
}
.crmi-clone-run-group { display: flex; gap: 8px; margin-left: auto; align-self: center; }
.crmi-clone-run-btn {
    background: var(--crmi-accent); color: #fff; border: none; border-radius: 5px;
    padding: 9px 18px; font-size: 0.88rem; font-weight: 600; cursor: pointer;
}
.crmi-clone-run-btn:hover { background: var(--crmi-accent-hover); }
.crmi-clone-run-btn:disabled { opacity: 0.6; cursor: default; }
.crmi-clone-cancel-btn {
    background: transparent; border: 1px solid var(--crmi-error); color: var(--crmi-text-light);
    border-radius: 5px; padding: 9px 16px; font-size: 0.85rem; cursor: pointer;
}
.crmi-clone-cancel-btn:hover { background: rgba(224, 92, 92, 0.2); }

.crmi-clone-status { font-size: 0.85rem; color: var(--crmi-text-muted); padding: 2px 2px; }
.crmi-clone-status-busy { color: var(--crmi-accent-hover); }
.crmi-clone-status-found { color: var(--crmi-warning); }
.crmi-clone-status-warning { color: var(--crmi-warning); }
.crmi-clone-status-error { color: var(--crmi-error); }

.crmi-clone-viewport {
    position: relative;
    width: 100%; height: 460px;
    overflow: hidden;
    border-radius: 8px;
    background-color: #1a0b26;
    background-image:
        linear-gradient(45deg, rgba(255,255,255,0.04) 25%, transparent 25%),
        linear-gradient(-45deg, rgba(255,255,255,0.04) 25%, transparent 25%),
        linear-gradient(45deg, transparent 75%, rgba(255,255,255,0.04) 75%),
        linear-gradient(-45deg, transparent 75%, rgba(255,255,255,0.04) 75%);
    background-size: 20px 20px;
    background-position: 0 0, 0 10px, 10px -10px, -10px 0px;
    /* Centered with flexbox rather than a 0x0 absolutely-positioned anchor —
       see the Image Adjustment viewport above (and the v1.1.2 changelog) for
       why: a 0-width containing block collapses to invisible against a
       WordPress theme's common `img, canvas, video { max-width:100%;
       height:auto }` reset. Flexbox centering has no such trap. */
    display: flex; align-items: center; justify-content: center;
}
.crmi-clone-stage { position: relative; }
.crmi-clone-stage canvas {
    display: block;
    image-rendering: pixelated;
    box-shadow: 0 4px 24px rgba(0,0,0,0.4);
    /* Belt-and-suspenders against that same theme reset, matching the JS-applied
       !important inline sizing set in cr-clone-detect.js. */
    max-width: none !important;
    max-height: none !important;
}

/* -------------------------------------------------------------------- */
/* Error Analysis tab                                                    */
/* -------------------------------------------------------------------- */
.crmi-ela { display: flex; flex-direction: column; gap: 12px; }
.crmi-ela-loading, .crmi-ela-unsupported {
    color: var(--crmi-text-muted); font-style: italic; padding: 24px; text-align: center;
    background: var(--crmi-bg-panel); border-radius: 8px;
}

.crmi-ela-toolbar {
    display: flex; flex-wrap: wrap; align-items: flex-end; gap: 16px;
    background: var(--crmi-bg-panel); border-radius: 8px; padding: 12px 14px;
}
.crmi-ela-control { display: flex; flex-direction: column; gap: 4px; font-size: 0.8rem; color: var(--crmi-text-muted); }
.crmi-ela-control label { cursor: help; }
.crmi-ela-control-row { display: flex; align-items: center; gap: 8px; }
.crmi-ela-slider { width: 130px; accent-color: var(--crmi-accent); }
.crmi-ela-value { color: var(--crmi-text-light); min-width: 2.6em; text-align: right; font-size: 0.85rem; }
.crmi-ela-select {
    background: var(--crmi-bg-dark); color: var(--crmi-text-light);
    border: 1px solid var(--crmi-accent); border-radius: 5px; padding: 5px 8px; font-size: 0.85rem;
}
.crmi-ela-reset-btn {
    background: transparent; border: 1px solid var(--crmi-accent); color: var(--crmi-text-light);
    border-radius: 5px; padding: 9px 16px; font-size: 0.85rem; cursor: pointer;
    margin-left: auto; align-self: center;
}
.crmi-ela-reset-btn:hover { background: rgba(155, 79, 209, 0.25); }

.crmi-ela-status { font-size: 0.85rem; color: var(--crmi-text-muted); padding: 2px 2px; min-height: 1.2em; }
.crmi-ela-status-busy { color: var(--crmi-accent-hover); }
.crmi-ela-status-error { color: var(--crmi-error); }

.crmi-ela-viewport {
    position: relative;
    width: 100%; height: 460px;
    overflow: hidden;
    border-radius: 8px;
    background-color: #1a0b26;
    background-image:
        linear-gradient(45deg, rgba(255,255,255,0.04) 25%, transparent 25%),
        linear-gradient(-45deg, rgba(255,255,255,0.04) 25%, transparent 25%),
        linear-gradient(45deg, transparent 75%, rgba(255,255,255,0.04) 75%),
        linear-gradient(-45deg, transparent 75%, rgba(255,255,255,0.04) 75%);
    background-size: 20px 20px;
    background-position: 0 0, 0 10px, 10px -10px, -10px 0px;
    /* Flexbox-centered, same reasoning as the Image Adjustment / Clone
       Detection viewports above — see the v1.1.2 changelog. */
    display: flex; align-items: center; justify-content: center;
    /* v1.17.0: zoom/pan, matching the Image Adjustment viewport. */
    cursor: grab; touch-action: none;
}
.crmi-ela-viewport.crmi-ela-dragging { cursor: grabbing; }
.crmi-ela-stage { position: relative; }
.crmi-ela-stage canvas {
    display: block;
    transform-origin: center center;
    image-rendering: pixelated;
    box-shadow: 0 4px 24px rgba(0,0,0,0.4);
    max-width: none !important;
    max-height: none !important;
}

/* -------------------------------------------------------------------- */
/* Analyze Noise tab                                                     */
/* -------------------------------------------------------------------- */
.crmi-noise { display: flex; flex-direction: column; gap: 12px; }
.crmi-noise-loading, .crmi-noise-unsupported {
    color: var(--crmi-text-muted); font-style: italic; padding: 24px; text-align: center;
    background: var(--crmi-bg-panel); border-radius: 8px;
}

.crmi-noise-toolbar {
    display: flex; flex-wrap: wrap; align-items: flex-end; gap: 16px;
    background: var(--crmi-bg-panel); border-radius: 8px; padding: 12px 14px;
}
.crmi-noise-control { display: flex; flex-direction: column; gap: 4px; font-size: 0.8rem; color: var(--crmi-text-muted); }
.crmi-noise-control label { cursor: help; }
.crmi-noise-control-row { display: flex; align-items: center; gap: 8px; }
.crmi-noise-slider { width: 130px; accent-color: var(--crmi-accent); }
.crmi-noise-value { color: var(--crmi-text-light); min-width: 2.6em; text-align: right; font-size: 0.85rem; }
.crmi-noise-select {
    background: var(--crmi-bg-dark); color: var(--crmi-text-light);
    border: 1px solid var(--crmi-accent); border-radius: 5px; padding: 5px 8px; font-size: 0.85rem;
}
.crmi-noise-reset-btn {
    background: transparent; border: 1px solid var(--crmi-accent); color: var(--crmi-text-light);
    border-radius: 5px; padding: 9px 16px; font-size: 0.85rem; cursor: pointer;
    margin-left: auto; align-self: center;
}
.crmi-noise-reset-btn:hover { background: rgba(155, 79, 209, 0.25); }

.crmi-noise-status { font-size: 0.85rem; color: var(--crmi-text-muted); padding: 2px 2px; min-height: 1.2em; }
.crmi-noise-status-busy { color: var(--crmi-accent-hover); }
.crmi-noise-status-error { color: var(--crmi-error); }

.crmi-noise-viewport {
    position: relative;
    width: 100%; height: 460px;
    overflow: hidden;
    border-radius: 8px;
    background-color: #1a0b26;
    background-image:
        linear-gradient(45deg, rgba(255,255,255,0.04) 25%, transparent 25%),
        linear-gradient(-45deg, rgba(255,255,255,0.04) 25%, transparent 25%),
        linear-gradient(45deg, transparent 75%, rgba(255,255,255,0.04) 75%),
        linear-gradient(-45deg, transparent 75%, rgba(255,255,255,0.04) 75%);
    background-size: 20px 20px;
    background-position: 0 0, 0 10px, 10px -10px, -10px 0px;
    /* Flexbox-centered, same reasoning as the other canvas-based viewports
       above — see the v1.1.2 changelog. */
    display: flex; align-items: center; justify-content: center;
    /* v1.17.0: zoom/pan, matching the Image Adjustment viewport. */
    cursor: grab; touch-action: none;
}
.crmi-noise-viewport.crmi-noise-dragging { cursor: grabbing; }
.crmi-noise-stage { position: relative; }
.crmi-noise-stage canvas {
    display: block;
    transform-origin: center center;
    image-rendering: pixelated;
    box-shadow: 0 4px 24px rgba(0,0,0,0.4);
    max-width: none !important;
    max-height: none !important;
}

/* -------------------------------------------------------------------- */
/* Sweep Levels tab                                                      */
/* -------------------------------------------------------------------- */
.crmi-sweep { display: flex; flex-direction: column; gap: 12px; }
.crmi-sweep-loading, .crmi-sweep-unsupported {
    color: var(--crmi-text-muted); font-style: italic; padding: 24px; text-align: center;
    background: var(--crmi-bg-panel); border-radius: 8px;
}

.crmi-sweep-toolbar {
    display: flex; flex-wrap: wrap; align-items: flex-end; gap: 16px;
    background: var(--crmi-bg-panel); border-radius: 8px; padding: 12px 14px;
}
.crmi-sweep-control { display: flex; flex-direction: column; gap: 4px; font-size: 0.8rem; color: var(--crmi-text-muted); }
.crmi-sweep-control label { cursor: help; }
.crmi-sweep-control-row { display: flex; align-items: center; gap: 8px; }
.crmi-sweep-slider { width: 130px; accent-color: var(--crmi-accent); }
.crmi-sweep-value { color: var(--crmi-text-light); min-width: 2.6em; text-align: right; font-size: 0.85rem; }
.crmi-sweep-reset-btn {
    background: transparent; border: 1px solid var(--crmi-accent); color: var(--crmi-text-light);
    border-radius: 5px; padding: 9px 16px; font-size: 0.85rem; cursor: pointer;
    margin-left: auto; align-self: center;
}
.crmi-sweep-reset-btn:hover { background: rgba(155, 79, 209, 0.25); }

.crmi-sweep-status { font-size: 0.85rem; color: var(--crmi-text-muted); padding: 2px 2px; min-height: 1.2em; }

.crmi-sweep-viewport {
    position: relative;
    width: 100%; height: 460px;
    overflow: hidden;
    border-radius: 8px;
    background-color: #1a0b26;
    background-image:
        linear-gradient(45deg, rgba(255,255,255,0.04) 25%, transparent 25%),
        linear-gradient(-45deg, rgba(255,255,255,0.04) 25%, transparent 25%),
        linear-gradient(45deg, transparent 75%, rgba(255,255,255,0.04) 75%),
        linear-gradient(-45deg, transparent 75%, rgba(255,255,255,0.04) 75%);
    background-size: 20px 20px;
    background-position: 0 0, 0 10px, 10px -10px, -10px 0px;
    /* Flexbox-centered, same reasoning as the other canvas-based viewports
       above — see the v1.1.2 changelog. */
    display: flex; align-items: center; justify-content: center;
    /* v1.17.0: zoom/pan, matching the Image Adjustment viewport. */
    cursor: grab; touch-action: none;
}
.crmi-sweep-viewport.crmi-sweep-dragging { cursor: grabbing; }
.crmi-sweep-stage { position: relative; }
.crmi-sweep-stage canvas {
    display: block;
    transform-origin: center center;
    image-rendering: pixelated;
    box-shadow: 0 4px 24px rgba(0,0,0,0.4);
    max-width: none !important;
    max-height: none !important;
}

/* -------------------------------------------------------------------- */
/* Luminance Grade tab                                                   */
/* -------------------------------------------------------------------- */
.crmi-luma { display: flex; flex-direction: column; gap: 12px; }
.crmi-luma-loading, .crmi-luma-unsupported {
    color: var(--crmi-text-muted); font-style: italic; padding: 24px; text-align: center;
    background: var(--crmi-bg-panel); border-radius: 8px;
}

.crmi-luma-toolbar {
    display: flex; flex-wrap: wrap; align-items: flex-end; gap: 16px;
    background: var(--crmi-bg-panel); border-radius: 8px; padding: 12px 14px;
}
.crmi-luma-control { display: flex; flex-direction: column; gap: 4px; font-size: 0.8rem; color: var(--crmi-text-muted); }
.crmi-luma-control label { cursor: help; }
.crmi-luma-control-row { display: flex; align-items: center; gap: 8px; }
.crmi-luma-slider { width: 130px; accent-color: var(--crmi-accent); }
.crmi-luma-value { color: var(--crmi-text-light); min-width: 2.6em; text-align: right; font-size: 0.85rem; }
.crmi-luma-toggle {
    background: transparent; border: 1px solid var(--crmi-accent); color: var(--crmi-text-light);
    border-radius: 5px; padding: 9px 14px; font-size: 0.85rem; cursor: pointer; align-self: center;
}
.crmi-luma-toggle:hover { background: rgba(155, 79, 209, 0.25); }
.crmi-luma-toggle.crmi-luma-toggle-active { background: var(--crmi-accent); color: #fff; }
.crmi-luma-reset-btn {
    background: transparent; border: 1px solid var(--crmi-accent); color: var(--crmi-text-light);
    border-radius: 5px; padding: 9px 16px; font-size: 0.85rem; cursor: pointer;
    margin-left: auto; align-self: center;
}
.crmi-luma-reset-btn:hover { background: rgba(155, 79, 209, 0.25); }

.crmi-luma-status { font-size: 0.85rem; color: var(--crmi-text-muted); padding: 2px 2px; min-height: 1.2em; }

.crmi-luma-viewport {
    position: relative;
    width: 100%; height: 460px;
    overflow: hidden;
    border-radius: 8px;
    background-color: #1a0b26;
    background-image:
        linear-gradient(45deg, rgba(255,255,255,0.04) 25%, transparent 25%),
        linear-gradient(-45deg, rgba(255,255,255,0.04) 25%, transparent 25%),
        linear-gradient(45deg, transparent 75%, rgba(255,255,255,0.04) 75%),
        linear-gradient(-45deg, transparent 75%, rgba(255,255,255,0.04) 75%);
    background-size: 20px 20px;
    background-position: 0 0, 0 10px, 10px -10px, -10px 0px;
    /* Flexbox-centered, same reasoning as the other canvas-based viewports
       above — see the v1.1.2 changelog. */
    display: flex; align-items: center; justify-content: center;
    /* v1.17.0: zoom/pan, matching the Image Adjustment viewport. */
    cursor: grab; touch-action: none;
}
.crmi-luma-viewport.crmi-luma-dragging { cursor: grabbing; }
.crmi-luma-stage { position: relative; }
.crmi-luma-stage canvas {
    display: block;
    transform-origin: center center;
    image-rendering: pixelated;
    box-shadow: 0 4px 24px rgba(0,0,0,0.4);
    max-width: none !important;
    max-height: none !important;
}

/* -------------------------------------------------------------------- */
/* Video-frame analysis (cr-video-frame.js) — shared by Clone Detection, */
/* Error Analysis, Analyze Noise, Sweep Levels, and Luminance Grade      */
/* whenever the uploaded file is a video: lets the visitor pick and      */
/* capture one still frame, then hands it to that tab's own unmodified   */
/* mount() exactly as if it were a photo.                                */
/* -------------------------------------------------------------------- */
.crmi-vframe { display: flex; flex-direction: column; gap: 12px; }
.crmi-vframe-loading, .crmi-vframe-unsupported {
    color: var(--crmi-text-muted); font-style: italic; padding: 24px; text-align: center;
    background: var(--crmi-bg-panel); border-radius: 8px;
}

/* "Video too long" block — reuses the same amber warning treatment as the
   Content Credentials tab's chain-of-trust caveat (.crmi-cc-caveat) and the
   --crmi-warning token used by .crmi-warning, rather than inventing a new
   visual language for a hard stop. */
.crmi-vframe-toolong {
    background: rgba(240, 180, 41, 0.12);
    border: 1px solid var(--crmi-warning);
    border-radius: 8px;
    padding: 14px 16px;
}
.crmi-vframe-toolong p { margin: 0; color: var(--crmi-text-light); font-size: 0.88rem; line-height: 1.5; }

.crmi-vframe-picker { display: flex; flex-direction: column; gap: 10px; }
.crmi-vframe-stage {
    width: 100%;
    background: #000;
    border-radius: 8px;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
}
.crmi-vframe-video {
    display: block;
    width: 100%;
    max-height: 460px;
    /* Belt-and-suspenders against the same theme-CSS-reset trap documented
       elsewhere in this file (see the v1.1.2 changelog): a <video> is one of
       the elements a common theme reset already targets
       (`img, canvas, video { max-width:100%; height:auto }`), and here that
       responsive behavior is exactly what we want — this just makes sure it
       still applies even if a theme's own rules would otherwise fight it. */
    max-width: 100% !important;
    height: auto !important;
}
.crmi-vframe-capture-btn {
    background: var(--crmi-accent); color: #fff; border: none; border-radius: 5px;
    padding: 10px 18px; font-size: 0.9rem; font-weight: 600; cursor: pointer;
    align-self: flex-start;
}
.crmi-vframe-capture-btn:hover { background: var(--crmi-accent-hover); }
.crmi-vframe-capture-btn:disabled { opacity: 0.6; cursor: default; }
.crmi-vframe-status { color: var(--crmi-text-muted); font-size: 0.85rem; margin: 0; }

/* Persistent "you're looking at one still moment" reminder, shown above the
   real tab's analysis output while it's mounted from a captured frame. */
.crmi-vframe-banner {
    display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap;
    background: rgba(155, 79, 209, 0.15);
    border: 1px solid var(--crmi-accent);
    border-radius: 8px;
    padding: 10px 14px;
}
.crmi-vframe-banner-text { color: var(--crmi-text-light); font-size: 0.85rem; }
.crmi-vframe-change-btn {
    background: transparent; border: 1px solid var(--crmi-accent); color: var(--crmi-text-light);
    border-radius: 5px; padding: 7px 14px; font-size: 0.82rem; cursor: pointer; white-space: nowrap;
}
.crmi-vframe-change-btn:hover { background: rgba(155, 79, 209, 0.25); }

/* -------------------------------------------------------------------- */
/* Content Credentials (C2PA) tab                                       */
/* -------------------------------------------------------------------- */
.crmi-cc { display: flex; flex-direction: column; gap: 12px; }
.crmi-cc-loading {
    color: var(--crmi-text-muted); font-style: italic; padding: 24px; text-align: center;
    background: var(--crmi-bg-panel); border-radius: 8px;
}

/* Mandatory scope-limitation caveat — visible by default whenever a
   manifest is found, same "honest scope" convention used by the Clone
   Detection tab's heuristic disclaimer, but styled to stand out more
   since this is the single most important thing on this tab: a
   "Verified" badge below means "internally self-consistent", not "from a
   trustworthy source". Reuses the warning-amber accent already used for
   .crmi-warning rather than inventing a new color. */
.crmi-cc-caveat {
    background: rgba(240, 180, 41, 0.12);
    border: 1px solid var(--crmi-warning);
    border-radius: 8px;
    padding: 14px 16px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.crmi-cc-caveat-title { margin: 0; font-weight: 700; color: var(--crmi-warning); font-size: 0.95rem; }
.crmi-cc-caveat-text { margin: 0; color: var(--crmi-text-light); font-size: 0.85rem; line-height: 1.5; }
.crmi-cc-caveat-link {
    color: var(--crmi-warning); font-weight: 600; font-size: 0.85rem; text-decoration: underline;
    align-self: flex-start;
}
.crmi-cc-caveat-link:hover { color: var(--crmi-accent-hover); }

.crmi-cc-manifest-selector {
    display: flex; flex-direction: column; gap: 8px; background: var(--crmi-bg-panel);
    border-radius: 8px; padding: 12px 14px;
}
.crmi-cc-manifest-selector-label { color: var(--crmi-text-muted); font-size: 0.82rem; }
.crmi-cc-manifest-selector-btns { display: flex; gap: 8px; flex-wrap: wrap; }
.crmi-cc-manifest-btn {
    background: transparent; border: 1px solid var(--crmi-accent); color: var(--crmi-text-light);
    border-radius: 999px; padding: 6px 14px; font-size: 0.8rem; cursor: pointer;
}
.crmi-cc-manifest-btn:hover { background: rgba(155, 79, 209, 0.25); }
.crmi-cc-manifest-btn-active { background: var(--crmi-accent); color: #fff; }

.crmi-cc-actions-section .crmi-section-body,
.crmi-cc-actions-list { display: flex; flex-direction: column; gap: 6px; }
.crmi-cc-action-row {
    display: flex; flex-wrap: wrap; gap: 6px 14px; align-items: baseline;
    padding: 8px 10px; border-radius: 6px; background: rgba(155, 79, 209, 0.12);
    font-size: 0.85rem;
}
.crmi-cc-action-name { color: var(--crmi-text-light); font-weight: 700; }
.crmi-cc-action-when { color: var(--crmi-text-muted); font-family: monospace, monospace; font-size: 0.8rem; }
.crmi-cc-action-agent { color: var(--crmi-accent-hover); font-size: 0.8rem; }

.crmi-cc-assertion-row {
    display: flex; justify-content: space-between; align-items: center; gap: 16px;
    padding: 8px 0; border-bottom: 1px solid rgba(255,255,255,0.05); font-size: 0.85rem;
}
.crmi-cc-assertion-row:last-child { border-bottom: none; }
.crmi-cc-assertion-label { color: var(--crmi-text-muted); flex: 0 0 auto; }
.crmi-cc-thumb {
    max-width: 96px; max-height: 96px; border-radius: 6px; display: block;
    box-shadow: 0 2px 10px rgba(0,0,0,0.4);
}

.crmi-cc-sig-status { font-size: 0.9rem; font-weight: 600; padding: 8px 0; margin: 0; }
.crmi-cc-sig-status-pending { color: var(--crmi-text-muted); font-weight: 400; font-style: italic; }
.crmi-cc-sig-status-verified { color: var(--crmi-success); }
.crmi-cc-sig-status-invalid { color: var(--crmi-error); }
.crmi-cc-sig-status-unsupported { color: var(--crmi-warning); }
.crmi-cc-sig-status-error { color: var(--crmi-error); }
.crmi-cc-cert-info { margin-top: 4px; }

/* -------------------------------------------------------------------- */
/* Audio Analysis tab (waveform + spectrogram)                          */
/* -------------------------------------------------------------------- */
.crmi-audio { display: flex; flex-direction: column; gap: 12px; }
.crmi-audio-loading, .crmi-audio-unsupported {
    color: var(--crmi-text-muted); font-style: italic; padding: 24px; text-align: center;
    background: var(--crmi-bg-panel); border-radius: 8px;
}

.crmi-audio-toolbar {
    display: flex; flex-wrap: wrap; align-items: flex-end; gap: 16px;
    background: var(--crmi-bg-panel); border-radius: 8px; padding: 12px 14px;
}
.crmi-audio-control { display: flex; flex-direction: column; gap: 4px; font-size: 0.8rem; color: var(--crmi-text-muted); }
.crmi-audio-control label { cursor: help; }
.crmi-audio-control-row { display: flex; align-items: center; gap: 8px; }
.crmi-audio-select {
    background: var(--crmi-bg-dark); color: var(--crmi-text-light); border: 1px solid var(--crmi-accent);
    border-radius: 5px; padding: 6px 8px; font-size: 0.85rem;
}
.crmi-audio-slider { width: 130px; accent-color: var(--crmi-accent); }
.crmi-audio-value { color: var(--crmi-text-light); min-width: 3.4em; text-align: right; font-size: 0.85rem; }
.crmi-audio-btn {
    background: transparent; border: 1px solid var(--crmi-accent); color: var(--crmi-text-light);
    border-radius: 5px; padding: 9px 14px; font-size: 0.85rem; cursor: pointer;
}
.crmi-audio-btn:hover { background: rgba(155, 79, 209, 0.25); }
.crmi-audio-group { display: flex; gap: 4px; align-self: center; margin-left: auto; }

.crmi-audio-status { font-size: 0.85rem; color: var(--crmi-text-muted); padding: 2px 2px; min-height: 1.2em; }
.crmi-audio-status-busy { color: var(--crmi-accent-hover); font-style: italic; }
.crmi-audio-status-error { color: var(--crmi-error); }

/* Soft, non-blocking heads-up for unusually long files — reuses the same
   amber warning treatment as .crmi-warning / .crmi-vframe-toolong, but
   unlike the video-frame feature's hard 3-minute stop, this never blocks
   anything: the file is still fully processed, just at a coarser time
   resolution (see adaptiveHopSize() in cr-audio-analysis.js). */
.crmi-audio-warning {
    background: rgba(240, 180, 41, 0.12);
    border: 1px solid var(--crmi-warning);
    border-radius: 8px;
    padding: 12px 14px;
    margin: 0;
    color: var(--crmi-text-light);
    font-size: 0.85rem;
    line-height: 1.5;
}

.crmi-audio-player {
    width: 100%;
    max-width: 100% !important; /* same theme-reset belt-and-suspenders as every other media element here */
}

/* Waveform + spectrogram share one scrollable-feeling timeline; each is
   its own canvas but they're kept visually stacked and the same width so
   the shared time axis (zoom/pan state) lines up between them. */
.crmi-audio-timeline { display: flex; flex-direction: column; gap: 2px; }
.crmi-audio-waveform-viewport, .crmi-audio-spectrogram-viewport {
    position: relative;
    width: 100%;
    overflow: hidden;
    border-radius: 8px;
    background-color: #1a0b26;
    cursor: grab;
    touch-action: none;
}
.crmi-audio-waveform-viewport.crmi-audio-dragging,
.crmi-audio-spectrogram-viewport.crmi-audio-dragging { cursor: grabbing; }
.crmi-audio-waveform-viewport canvas, .crmi-audio-spectrogram-viewport canvas {
    display: block;
    /* Same !important-sizing hardening as every other canvas-based tab in
       this plugin (see the v1.1.2 changelog) — cr-audio-analysis.js also
       sets these inline, this is the CSS-file-level backstop. */
    max-width: none !important;
    max-height: none !important;
}

/* -------------------------------------------------------------------- */
/* Audio Forensics tab (splice/edit-point detector)                     */
/* -------------------------------------------------------------------- */
.crmi-afx { display: flex; flex-direction: column; gap: 12px; }
.crmi-afx-loading, .crmi-afx-unsupported {
    color: var(--crmi-text-muted); font-style: italic; padding: 24px; text-align: center;
    background: var(--crmi-bg-panel); border-radius: 8px;
}

/* Mandatory heuristic-aid caveat — visible by default, same "honest
   scope" convention as .crmi-cc-caveat, reusing the same warning-amber
   accent rather than inventing a new color. */
.crmi-afx-caveat {
    background: rgba(240, 180, 41, 0.12);
    border: 1px solid var(--crmi-warning);
    border-radius: 8px;
    padding: 14px 16px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.crmi-afx-caveat-title { margin: 0; font-weight: 700; color: var(--crmi-warning); font-size: 0.95rem; }
.crmi-afx-caveat-text { margin: 0; color: var(--crmi-text-light); font-size: 0.85rem; line-height: 1.5; }
/* Sits ahead of the experimental-detectors caveat paragraph — same warning
   color as the caveat title, but a notch smaller/italic so it reads as a
   sub-heading within the caveat block rather than a second title. */
.crmi-afx-caveat-subtitle {
    margin: 0; font-weight: 700; font-style: italic; color: var(--crmi-warning); font-size: 0.85rem;
}

/* Shared zoom toolbar controls (Zoom In/Out, Fit, 100%) — v1.17.0 added the
   same zoom/pan interaction model Image Adjustment already had (see
   .crmi-imgadj-group/-btn above) to Error Analysis, Analyze Noise, Sweep
   Levels, and Luminance Grade. Rather than duplicating this small block
   four more times, it's pulled out into one shared pair of classes reused
   by all four of those tabs — visually identical to Image Adjustment's own
   zoom buttons, which are left as-is on their original classes since they
   already worked and didn't need touching. */
.crmi-zoom-group { display: flex; gap: 4px; }
.crmi-zoom-btn {
    background: transparent; border: 1px solid var(--crmi-accent); color: var(--crmi-text-light);
    border-radius: 5px; padding: 6px 12px; font-size: 0.82rem; cursor: pointer; line-height: 1.2;
}
.crmi-zoom-btn:hover { background: rgba(155, 79, 209, 0.25); }

/* Shared, plugin-wide "Using these controls" block — a permanently visible
   (not hover-gated) restatement of each slider/select/toggle's title-attr
   help text, generated from the same string as the tooltip so the two can
   never drift apart. Sits as the last child of each control-bearing tab,
   below its canvas/waveform/results area. Muted-text treatment consistent
   with .crmi-afx-caveat-text; a <dl> of label/description pairs so it
   reads correctly wrapped on narrow viewports. */
.crmi-controls-help {
    margin-top: 16px;
    padding-top: 14px;
    border-top: 1px solid rgba(243, 236, 250, 0.12);
}
.crmi-controls-help-title {
    margin: 0 0 8px; font-weight: 700; color: var(--crmi-text-muted); font-size: 0.85rem;
}
.crmi-controls-help-list {
    margin: 0; display: grid; grid-template-columns: max-content 1fr; column-gap: 12px; row-gap: 6px;
}
.crmi-controls-help-label {
    margin: 0; font-weight: 600; color: var(--crmi-text-light); font-size: 0.82rem; white-space: nowrap;
}
.crmi-controls-help-desc {
    margin: 0; color: var(--crmi-text-muted); font-size: 0.82rem; line-height: 1.5;
}
@media (max-width: 600px) {
    .crmi-controls-help-list { grid-template-columns: 1fr; row-gap: 2px; }
    .crmi-controls-help-label { white-space: normal; }
    .crmi-controls-help-desc { margin-bottom: 6px; }
}

/* Toolbar is now organized into three visually-grouped sub-sections rather
   than one flat row of controls, so the "Cut / Edit / Clone / Noise" (full-
   confidence), "Re-compression" (full-confidence), and "Pitch-Shift & Tempo
   (Experimental)" groups are scannable at a glance. */
.crmi-afx-toolbar {
    display: flex; flex-direction: column; gap: 12px;
    background: var(--crmi-bg-panel); border-radius: 8px; padding: 12px 14px;
}
.crmi-afx-toolbar-groups { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 16px 24px; }
.crmi-afx-toolbar-group { display: flex; flex-direction: column; gap: 8px; }
.crmi-afx-toolbar-group-title {
    margin: 0; font-size: 0.72rem; font-weight: 700; letter-spacing: 0.03em; text-transform: uppercase;
    color: var(--crmi-text-muted);
}
.crmi-afx-toolbar-group-controls { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 16px; }
.crmi-afx-control { display: flex; flex-direction: column; gap: 4px; font-size: 0.8rem; color: var(--crmi-text-muted); }
.crmi-afx-control label { cursor: help; }
.crmi-afx-control-row { display: flex; align-items: center; gap: 8px; }
/* Small pill marking a slider or result-row type as belonging to one of the
   two experimental (voice-only / rhythm-only) detectors, so it's never
   mistaken for the same full-confidence tier as the other five detectors. */
.crmi-afx-badge-experimental {
    display: inline-block; font-size: 0.65rem; font-weight: 700; letter-spacing: 0.02em; text-transform: uppercase;
    color: var(--crmi-warning); border: 1px solid var(--crmi-warning); border-radius: 4px;
    padding: 1px 5px; margin-left: 6px; vertical-align: middle;
}
.crmi-afx-slider { width: 130px; accent-color: var(--crmi-accent); }
.crmi-afx-value { color: var(--crmi-text-light); min-width: 3em; text-align: right; font-size: 0.85rem; }
.crmi-afx-select {
    background: var(--crmi-bg-dark); color: var(--crmi-text-light); border: 1px solid var(--crmi-accent);
    border-radius: 5px; padding: 6px 8px; font-size: 0.85rem;
}
.crmi-afx-run-group { display: flex; gap: 8px; margin-left: auto; align-self: center; }
.crmi-afx-run-btn {
    background: var(--crmi-accent); color: #fff; border: none; border-radius: 5px;
    padding: 9px 18px; font-size: 0.88rem; font-weight: 600; cursor: pointer;
}
.crmi-afx-run-btn:hover { background: var(--crmi-accent-hover); }
.crmi-afx-run-btn:disabled { opacity: 0.6; cursor: default; }
.crmi-afx-cancel-btn {
    background: transparent; border: 1px solid var(--crmi-error); color: var(--crmi-text-light);
    border-radius: 5px; padding: 9px 16px; font-size: 0.85rem; cursor: pointer;
}
.crmi-afx-cancel-btn:hover { background: rgba(224, 92, 92, 0.2); }

.crmi-afx-status { font-size: 0.85rem; color: var(--crmi-text-muted); padding: 2px 2px; min-height: 1.2em; }
.crmi-afx-status-busy { color: var(--crmi-accent-hover); font-style: italic; }
.crmi-afx-status-error { color: var(--crmi-error); }

/* Soft, non-blocking heads-up for unusually long files — same treatment
   as .crmi-audio-warning; never blocks anything, the whole file is still
   scanned, just at a coarser frame/segment resolution. */
.crmi-afx-warning {
    background: rgba(240, 180, 41, 0.12);
    border: 1px solid var(--crmi-warning);
    border-radius: 8px;
    padding: 12px 14px;
    margin: 0;
    color: var(--crmi-text-light);
    font-size: 0.85rem;
    line-height: 1.5;
}

.crmi-afx-player { width: 100%; max-width: 100% !important; }

.crmi-afx-waveform-viewport {
    position: relative;
    width: 100%;
    overflow: hidden;
    border-radius: 8px;
    background-color: #1a0b26;
    cursor: grab;
    touch-action: none;
}
.crmi-afx-waveform-viewport.crmi-afx-dragging { cursor: grabbing; }
.crmi-afx-waveform-viewport canvas {
    display: block;
    max-width: none !important;
    max-height: none !important;
}
.crmi-afx-zoomgroup { display: flex; gap: 4px; justify-content: flex-end; }
.crmi-afx-zoombtn {
    background: transparent; border: 1px solid var(--crmi-accent); color: var(--crmi-text-light);
    border-radius: 5px; padding: 6px 12px; font-size: 0.85rem; cursor: pointer;
}
.crmi-afx-zoombtn:hover { background: rgba(155, 79, 209, 0.25); }

.crmi-afx-results-list { display: flex; flex-direction: column; gap: 6px; }
.crmi-afx-empty { color: var(--crmi-text-muted); font-style: italic; padding: 8px 2px; }
.crmi-afx-row {
    display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px;
    background: var(--crmi-bg-panel); border: 1px solid transparent; border-radius: 6px;
    padding: 9px 12px; font-size: 0.85rem; color: var(--crmi-text-light);
    cursor: pointer; text-align: left; width: 100%;
}
.crmi-afx-row:hover { border-color: var(--crmi-accent); background: #38205a; }
.crmi-afx-row-swatch { width: 10px; height: 10px; border-radius: 50%; flex: 0 0 auto; }
.crmi-afx-row-type { font-weight: 700; flex: 0 0 auto; min-width: 190px; }
.crmi-afx-row-time { color: var(--crmi-text-muted); font-family: monospace, monospace; font-size: 0.82rem; }
.crmi-afx-row-extra { color: var(--crmi-accent-hover); font-size: 0.8rem; margin-left: auto; }

/* Per-category left-border accents so the list is scannable at a glance
   without relying on color alone (also readable if a viewer has a color-
   vision deficiency, since the TYPE label text is always present too). */
.crmi-afx-row-discontinuity { border-left: 3px solid #ffffff; }
.crmi-afx-row-abrupt-silence-transition { border-left: 3px solid #59c9c9; }
.crmi-afx-row-clipping { border-left: 3px solid var(--crmi-error); }
.crmi-afx-row-possible-duplicate-clone { border-left: 3px solid var(--crmi-accent); }
.crmi-afx-row-noise-floor-inconsistency { border-left: 3px solid var(--crmi-warning); }
.crmi-afx-row-possible-re-compression { border-left: 3px solid #3d84d9; }
.crmi-afx-row-possible-pitch-shift-experimental { border-left: 3px solid #e05fa0; }
.crmi-afx-row-tempo-change-experimental { border-left: 3px solid #f0932b; }

@media (max-width: 600px) {
    /* Shorter cap on narrow/short phone viewports — 75vh against a short
       landscape or a small phone's real available height (browser chrome
       already eats a chunk of the nominal viewport) can crowd out the
       always-visible report bar above it; 60vh leaves more breathing room
       while still fitting comfortably more than one screenful of content. */
    .crmi-results-scroll { max-height: 60vh; }
    .crmi-field-row { flex-direction: column; gap: 2px; }
    .crmi-field-value { text-align: left; }

    /* Traditional hamburger menu for the main tab strip (v1.18.0),
       replacing the horizontally-scrollable row below the breakpoint.
       The button becomes visible, and the strip itself is collapsed into
       an absolutely-positioned dropdown that only appears once
       cr-metadata-ui.js adds .crmi-mobile-menu-open to the wrap (on
       hamburger click) — removed again on tab selection or an outside
       click. None of the 12 tab buttons' own markup, data attributes, or
       click handlers change; only their layout inside the dropdown does. */
    .crmi-hamburger-btn { display: flex; }
    .crmi-main-tabs {
        display: none;
        position: absolute; top: 100%; left: 0; right: 0; z-index: 30;
        flex-direction: column; gap: 0; margin-bottom: 0; margin-top: -6px;
        border-bottom: none; border: 1px solid var(--crmi-accent);
        border-radius: 8px; background: var(--crmi-bg-panel);
        box-shadow: 0 10px 28px rgba(0, 0, 0, 0.45);
        max-height: 60vh; overflow-y: auto; overflow-x: hidden;
        -webkit-overflow-scrolling: touch;
    }
    .crmi-main-tabs-wrap.crmi-mobile-menu-open .crmi-main-tabs { display: flex; }
    .crmi-main-tabs .crmi-main-tab-btn {
        width: 100%; text-align: left; white-space: normal;
        border-bottom: 1px solid rgba(255, 255, 255, 0.08);
        border-left: 3px solid transparent; margin-bottom: 0;
        padding: 14px 16px;
    }
    .crmi-main-tabs .crmi-main-tab-btn:last-child { border-bottom: none; }
    .crmi-main-tabs .crmi-main-tab-btn.crmi-main-tab-active {
        border-bottom-color: rgba(255, 255, 255, 0.08);
        border-left-color: var(--crmi-accent);
        background: rgba(155, 79, 209, 0.14);
    }
    .crmi-imgadj-viewport { height: 320px; }
    .crmi-imgadj-contrast-slider { width: 90px; }
    .crmi-clone-viewport { height: 320px; }
    .crmi-clone-slider { width: 90px; }
    .crmi-clone-run-group { margin-left: 0; }
    .crmi-ela-viewport { height: 320px; }
    .crmi-ela-slider { width: 90px; }
    .crmi-ela-reset-btn { margin-left: 0; }
    .crmi-noise-viewport { height: 320px; }
    .crmi-noise-slider { width: 90px; }
    .crmi-noise-reset-btn { margin-left: 0; }
    .crmi-sweep-viewport { height: 320px; }
    .crmi-sweep-slider { width: 90px; }
    .crmi-sweep-reset-btn { margin-left: 0; }
    .crmi-luma-viewport { height: 320px; }
    .crmi-luma-slider { width: 90px; }
    .crmi-luma-reset-btn { margin-left: 0; }
    .crmi-geo-photo, .crmi-geo-map { min-height: 200px; flex-basis: 100%; }
    .crmi-vframe-video { max-height: 260px; }
    .crmi-audio-slider { width: 90px; }
    .crmi-audio-group { margin-left: 0; }
    .crmi-afx-slider { width: 90px; }
    .crmi-afx-run-group { margin-left: 0; }
    .crmi-afx-row-type { min-width: 0; }
    .crmi-afx-toolbar-groups { flex-direction: column; gap: 14px; }
}

/* Bigger tap targets on touchscreens — the desktop 9px/18px padding
   measures out to ~34px tall, under the ~44px minimum recommended for
   touch (Apple HIG / WCAG 2.5.5). Keyed off `pointer: coarse` rather
   than viewport width, since a touch-primary device (this specifically
   includes tablets in either orientation, e.g. a 768px-wide iPad, not
   just narrow phones caught by the max-width:600px block above) is what
   actually needs the bigger target, regardless of how much screen space
   it has. */
@media (pointer: coarse) {
    .crmi-geo-show-map-btn { padding: 13px 22px; }
    .crmi-geo-link-btn { padding: 13px 18px; }
    .crmi-vframe-capture-btn { padding: 13px 20px; }
    .crmi-vframe-change-btn { padding: 12px 16px; }
    .crmi-audio-btn { padding: 13px 16px; }
    .crmi-afx-zoombtn { padding: 12px 16px; }
    .crmi-afx-row { padding: 12px; }
    .crmi-hamburger-btn { padding: 14px 16px; }
    .crmi-main-tabs .crmi-main-tab-btn { padding: 16px; }
}
