/*! Copyright (c) 2025–2026 Franklin Softworks LLC. All rights reserved. https://docconverter.probablyfine.click */
/**
 * ui-v2.css
 * Zero UI Document Converter - Glassmorphism Dark Theme
 */

/* ===== DESIGN TOKENS ===== */
:root {
    /* Colors */
    --color-bg: #121212;
    --color-bg-elevated: #1e1e1e;
    --color-accent: #6366f1;
    --color-accent-glow: rgba(99, 102, 241, 0.3);
    --color-success: #22c55e;
    --color-error: #ef4444;
    /* BUG-74 (WCAG 2.2 AA, 1.4.3): text in the success and error colours, and the Download All
       button. #22c55e is 8.2:1 on --color-bg; #f87171 is 6.0:1 on --color-bg-elevated (#ef4444 was
       4.43:1); white on #15803d is 5.0:1 (white on #22c55e was 2.27:1). */
    --color-success-text: #22c55e;
    --color-error-text: #f87171;
    --color-success-button: #15803d;
    --color-text: #ffffff;
    --color-text-muted: rgba(255, 255, 255, 0.6);
    --color-glass: rgba(255, 255, 255, 0.03);
    --color-border: rgba(255, 255, 255, 0.1);
    --color-border-hover: rgba(255, 255, 255, 0.2);
    --shadow-glass: none;
    --color-drag-tint: rgba(99, 102, 241, 0.05);
    --color-warning-bg: rgba(245, 158, 11, 0.1);
    --color-warning-border: rgba(245, 158, 11, 0.3);
    --color-warning-text: #b45309;

    /* Glassmorphism */
    --blur-glass: 20px;
    --blur-glass-strong: 40px;

    /* Transitions */
    --transition-fast: 150ms ease;
    --transition-smooth: 300ms cubic-bezier(0.4, 0, 0.2, 1);
    --transition-spring: 500ms cubic-bezier(0.34, 1.56, 0.64, 1);

    /* Spacing */
    --space-xs: 0.25rem;
    --space-sm: 0.5rem;
    --space-md: 1rem;
    --space-lg: 1.5rem;
    --space-xl: 2rem;
    --space-2xl: 3rem;

    /* Border radius */
    --radius-sm: 0.5rem;
    --radius-md: 1rem;
    --radius-lg: 1.5rem;
    --radius-xl: 2rem;
}

/* ===== LIGHT THEME ===== */
html[data-theme="light"] {
    --color-bg: #f5f5f7;
    --color-bg-elevated: #ffffff;
    --color-accent: #4f46e5;
    --color-accent-glow: rgba(79, 70, 229, 0.2);
    --color-success: #16a34a;
    --color-error: #dc2626;
    /* BUG-74: #15803d is 4.85:1 on the download area (#16a34a was 3.18:1); #dc2626 is 4.79:1 on white. */
    --color-success-text: #15803d;
    --color-error-text: #dc2626;
    --color-success-button: #15803d;
    --color-text: #1a1a2e;
    /* W-9 (WCAG 2.2 AA, 1.4.3): 0.66 gives 5.35:1 on --color-bg and 5.49:1 on white (0.55 was 3.74:1). */
    --color-text-muted: rgba(26, 26, 46, 0.66);
    --color-glass: rgba(255, 255, 255, 0.6);
    --color-border: rgba(0, 0, 0, 0.08);
    --color-border-hover: rgba(0, 0, 0, 0.15);
    --shadow-glass: 0 2px 16px rgba(0, 0, 0, 0.06);
    --color-drag-tint: rgba(79, 70, 229, 0.04);
    --color-warning-bg: rgba(245, 158, 11, 0.08);
    --color-warning-border: rgba(245, 158, 11, 0.25);
    --color-warning-text: #92400e;
}

/* ===== RESET & BASE ===== */
*, *::before, *::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

html, body {
    height: 100%;
    overflow: hidden;
}

body {
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
    background: var(--color-bg);
    color: var(--color-text);
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;
}

/* Screen reader only */
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    border: 0;
}

/* ===== GLASSMORPHISM ===== */
.glass {
    background: var(--color-glass);
    backdrop-filter: blur(var(--blur-glass));
    -webkit-backdrop-filter: blur(var(--blur-glass));
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-glass);
}

/* ===== STATE CONTAINERS ===== */
.state {
    position: fixed;
    inset: 0;
    display: none;
    align-items: center;
    justify-content: center;
    padding: var(--space-lg);
}

.state.active {
    display: flex;
}

/* ===== STATE 1: DROP ZONE ===== */
#state-drop {
    flex-direction: column;
    gap: var(--space-lg);
    transition: transform var(--transition-smooth);
}

#state-drop.drag-over {
    background: var(--color-drag-tint);
}

#state-drop.drag-over .drop-zone-content {
    border-color: var(--color-accent);
    box-shadow: 0 0 40px var(--color-accent-glow);
    transform: scale(1.02);
}

.drop-zone-content {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;   /* wrapped lines (phone width) stay centred, not just their boxes */
    gap: var(--space-md);
    padding: var(--space-2xl);
    border: 2px dashed var(--color-border);
    border-radius: var(--radius-xl);
    cursor: pointer;
    transition: all var(--transition-smooth);
}

.drop-zone-content:hover {
    border-color: var(--color-border-hover);
}

.drop-zone-content:focus-visible {
    outline: 2px solid var(--color-accent);
    outline-offset: 4px;
    border-color: var(--color-accent);
}

.drop-icon {
    width: 80px;
    height: 80px;
    color: var(--color-text-muted);
    transition: color var(--transition-smooth);
}

#state-drop.drag-over .drop-icon {
    color: var(--color-accent);
}

.drop-text {
    font-size: 1.5rem;
    font-weight: 300;
    color: var(--color-text);
}

.drop-subtext {
    font-size: 0.875rem;
    color: var(--color-text-muted);
}

.drop-beta-notice {
    font-size: 0.75rem;
    color: var(--color-text-muted);
    margin-top: var(--space-xs);
    opacity: 0.8;
}
/* W-9: in the light theme an extra fade took these below 4.5:1 (the notice to 2.72:1); there they keep
   the muted colour only. Dark is unchanged (it passes with the fade). */
html[data-theme="light"] .drop-beta-notice,
html[data-theme="light"] .wordmark { opacity: 1; }

/* SITE-07, embed.html only (<html data-embed>): the page FLOWS from the top instead of
   being a fixed, viewport-sized, centred screen. The document then has a real height, which
   ui-v2.js reports to the framing page so it can size its frame to the content (no inner
   scroll, no empty space), and the drop zone sits at the top of the frame. The embed has no
   wordmark or footer (make_embed_page.py removes them; the brand page carries those links). */
html[data-embed], html[data-embed] body { height: auto; overflow: visible; }
html[data-embed] .state { position: relative; inset: auto; }
html[data-embed] .state.active { justify-content: flex-start; overflow: visible;
    padding-top: 3.5rem; padding-bottom: var(--space-lg); }

.site-footer {
    position: absolute;
    bottom: var(--space-md);
    left: 50%;
    transform: translateX(-50%);
    font-size: 0.8125rem;
    color: var(--color-text-muted);
    z-index: 100;
}

.site-footer a {
    color: var(--color-text-muted);
    text-decoration: none;
    transition: color var(--transition-smooth);
}

.site-footer a:hover {
    color: var(--color-accent);
}


/* Mobile upload button */
.mobile-upload-btn {
    display: none;
    align-items: center;
    gap: var(--space-sm);
    padding: var(--space-md) var(--space-xl);
    background: var(--color-accent);
    color: white;
    border: none;
    border-radius: var(--radius-md);
    font-size: 1rem;
    font-weight: 500;
    cursor: pointer;
    transition: transform var(--transition-spring), box-shadow var(--transition-smooth);
}

.mobile-upload-btn:hover {
    transform: scale(1.02);
    box-shadow: 0 0 30px var(--color-accent-glow);
}

.mobile-upload-btn svg {
    width: 20px;
    height: 20px;
}

.is-mobile .mobile-upload-btn {
    display: flex;
}

.is-mobile .drop-zone-content {
    border-style: solid;
}

/* ===== INLINE PROGRESS (inside DROP state) ===== */
.progress-inline {
    display: none;
    width: 100%;
    max-width: 400px;
}

/* When converting: hide drop content, show progress */
#state-drop.converting .drop-zone-content,
#state-drop.converting .mobile-upload-btn {
    display: none !important;
}

#state-drop.converting .progress-inline {
    display: block;
}

/* Pulse animation for inline progress bar */
#state-drop.converting .progress-bar {
    animation: pulse 2s ease-in-out infinite;
}

/* ===== STATE 2: FORMAT SELECTION ===== */
#state-format {
    flex-direction: column;
    gap: var(--space-lg);
}

.bento-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--space-md);
    max-width: 600px;
    width: 100%;
}

.source-card {
    grid-column: span 2;
    grid-row: span 4;
    padding: var(--space-xl);
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
}

.source-label {
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--color-accent);
}

.source-filename {
    font-size: 1.25rem;
    font-weight: 500;
    word-break: break-all;
}

.source-size {
    font-size: 0.875rem;
    color: var(--color-text-muted);
}

.format-tile {
    position: relative;
    padding: var(--space-lg);
    display: flex;
    flex-direction: column;
    gap: var(--space-xs);
    cursor: pointer;
    transition: all var(--transition-smooth);
    background: var(--color-glass);
    backdrop-filter: blur(var(--blur-glass));
    -webkit-backdrop-filter: blur(var(--blur-glass));
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
}

.format-tile:hover:not(:disabled) {
    transform: scale(1.02);
    border-color: var(--color-border-hover);
}

.format-tile.selected {
    border-color: var(--color-accent);
    box-shadow: 0 0 20px var(--color-accent-glow);
}

.format-tile:disabled {
    opacity: 0.3;
    cursor: not-allowed;
}

.format-name {
    font-size: 1rem;
    font-weight: 600;
    color: var(--color-text);
}

.format-desc {
    font-size: 0.75rem;
    color: var(--color-text-muted);
}

/* Countdown ring */
.countdown-ring {
    position: absolute;
    top: -4px;
    right: -4px;
    width: 24px;
    height: 24px;
    transform: rotate(-90deg);
    opacity: 0;
    transition: opacity var(--transition-fast);
}

.format-tile.selected .countdown-ring {
    opacity: 1;
}

.countdown-ring circle {
    stroke: var(--color-accent);
    stroke-linecap: round;
}

.countdown-text {
    font-size: 0.875rem;
    color: var(--color-text-muted);
    text-align: center;
}

/* M17: countdown controls (text + Pause button) */
.countdown-controls {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-sm);
}

.btn-countdown-pause {
    padding: var(--space-xs) var(--space-lg);
    background: transparent;
    color: var(--color-text-muted);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    font-size: 0.8125rem;
    font-weight: 500;
    cursor: pointer;
    transition: all var(--transition-smooth);
}

.btn-countdown-pause:hover:not(:disabled) {
    color: var(--color-text);
    border-color: var(--color-border-hover);
}

.btn-countdown-pause:disabled {
    opacity: 0.4;
    cursor: default;
}

.btn-countdown-pause:focus-visible {
    outline: 2px solid var(--color-accent);
    outline-offset: 2px;
}

/* ===== STATE 3: PROGRESS ===== */
.progress-card {
    width: 100%;
    max-width: 400px;
    padding: var(--space-xl);
    display: flex;
    flex-direction: column;
    gap: var(--space-md);
}

/* Queue position indicator (e.g., "Converting 2 of 5") */
.progress-queue-position {
    display: none;
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--color-accent);
    margin-bottom: var(--space-xs);
}

.progress-queue-position.visible {
    display: block;
}

#queue-current, #queue-total {
    font-variant-numeric: tabular-nums;
}

.progress-header {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    font-size: 0.875rem;
}

.progress-filename {
    color: var(--color-text);
    font-weight: 500;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 200px;
}

.progress-arrow {
    color: var(--color-text-muted);
}

.progress-target {
    color: var(--color-accent);
    font-weight: 600;
}

.progress-bar-container {
    height: 4px;
    background: var(--color-border);
    border-radius: 2px;
    overflow: hidden;
}

.progress-bar {
    height: 100%;
    background: var(--color-accent);
    border-radius: 2px;
    transition: width var(--transition-smooth);
    box-shadow: 0 0 10px var(--color-accent-glow);
}

.progress-footer {
    display: flex;
    justify-content: space-between;
    font-size: 0.75rem;
    color: var(--color-text-muted);
}

/* Stall warning message */
/* BUG-54: the file's own warnings on the progress card */
.progress-file-warning {
    margin: var(--space-sm) 0 0;
    padding: var(--space-sm) var(--space-md);
    background: var(--color-warning-bg);
    border: 1px solid var(--color-warning-border);
    border-radius: var(--radius-sm);
    color: var(--color-warning-text);
    font-size: 0.875rem;
}
.progress-file-warning[hidden] { display: none; }
/* ...and the finished file's tile when a warning describes the result */
.download-tile.has-warning { position: relative; border-color: var(--color-warning-border); }
.download-tile.has-warning::after {
    content: "!";
    position: absolute; top: 4px; right: 6px;
    font-weight: 700; font-size: 0.75rem;
    color: var(--color-warning-text);
}
.stall-warning {
    margin-top: var(--space-md);
    padding: var(--space-sm) var(--space-md);
    background: var(--color-warning-bg);
    border: 1px solid var(--color-warning-border);
    border-radius: var(--radius-sm);
    color: var(--color-warning-text);
    font-size: 0.875rem;
    text-align: center;
}

/* Cancel button */
.btn-cancel {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    padding: var(--space-sm) var(--space-md);
    margin-top: var(--space-md);
    background: transparent;
    color: var(--color-text-muted);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    font-size: 0.875rem;
    font-weight: 500;
    cursor: pointer;
    transition: all var(--transition-smooth);
}

.btn-cancel:hover {
    color: var(--color-error);
    border-color: var(--color-error);
}

.btn-cancel:focus-visible {
    outline: 2px solid var(--color-accent);
    outline-offset: 2px;
}

/* Buttons */
.btn-primary, .btn-secondary {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-sm);
    width: 100%;
    padding: var(--space-md) var(--space-xl);
    border: none;
    border-radius: var(--radius-md);
    font-size: 1rem;
    font-weight: 500;
    cursor: pointer;
    transition: all var(--transition-smooth);
}

.btn-primary {
    background: var(--color-accent);
    color: white;
}

.btn-primary:hover {
    transform: scale(1.02);
    box-shadow: 0 0 30px var(--color-accent-glow);
}

.btn-primary svg {
    width: 20px;
    height: 20px;
}

.btn-secondary {
    background: transparent;
    color: var(--color-text-muted);
    border: 1px solid var(--color-border);
    margin-top: var(--space-sm);
}

.btn-secondary:hover {
    color: var(--color-text);
    border-color: var(--color-text-muted);
}

/* ===== ERROR TOAST ===== */
.toast {
    position: fixed;
    bottom: var(--space-xl);
    left: 50%;
    transform: translateX(-50%) translateY(100px);
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    padding: var(--space-md) var(--space-lg);
    background: var(--color-error);
    color: white;
    border-radius: var(--radius-md);
    font-size: 0.875rem;
    font-weight: 500;
    opacity: 0;
    pointer-events: none;
    transition: all var(--transition-spring);
    z-index: 1000;
}

.toast.visible {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
}

.toast.shake {
    animation: shake 0.5s ease-in-out;
}

.toast-icon {
    width: 20px;
    height: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(255, 255, 255, 0.2);
    border-radius: 50%;
    font-size: 0.75rem;
    font-weight: 700;
}

/* ===== ANIMATIONS ===== */
@keyframes shake {
    0%, 100% { transform: translateX(-50%) translateY(0); }
    20%, 60% { transform: translateX(calc(-50% - 10px)) translateY(0); }
    40%, 80% { transform: translateX(calc(-50% + 10px)) translateY(0); }
}

@keyframes pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.6; }
}

/* ===== RESPONSIVE ===== */
@media (max-width: 600px) {
    .bento-grid {
        grid-template-columns: repeat(2, 1fr);
    }

    .source-card {
        grid-column: span 2;
        grid-row: span 1;
    }

    .drop-text {
        font-size: 1.25rem;
    }

    .drop-icon {
        width: 60px;
        height: 60px;
    }

    .download-area {
        max-width: 100%;
        margin-top: var(--space-lg);
    }

    .download-grid {
        grid-template-columns: repeat(3, 1fr);
    }

    .download-area-header {
        flex-direction: column;
        align-items: flex-start;
        gap: var(--space-xs);
    }
}

/* ===== BENTO DOWNLOAD AREA ===== */
.download-area {
    width: 100%;
    max-width: 500px;
    margin-top: var(--space-xl);
    opacity: 0;
    transform: translateY(20px);
    pointer-events: none;
    transition: opacity var(--transition-smooth), transform var(--transition-spring);
}

.download-area.visible {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
}

.download-area-content {
    display: flex;
    flex-direction: column;
    gap: var(--space-md);
    padding: var(--space-lg);
    border: 2px dashed var(--color-border);
    border-radius: var(--radius-xl);
    background: var(--color-glass);
    backdrop-filter: blur(var(--blur-glass));
    -webkit-backdrop-filter: blur(var(--blur-glass));
    transition: all var(--transition-smooth);
}

/* Drag-over state for download area (accepts drops) */
.download-area.drag-over .download-area-content {
    border-color: var(--color-accent);
    box-shadow: 0 0 40px var(--color-accent-glow);
}

.download-area-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.download-label {
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--color-success-text);
}

.download-hint {
    font-size: 0.625rem;
    color: var(--color-text-muted);
}

/* Bento Grid for download tiles */
.download-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(90px, 1fr));
    gap: var(--space-sm);
    /* C5: no queue cap — many tiles scroll within a bounded container instead of
       blowing out the page layout. ~3 rows tall before scrolling. */
    max-height: 320px;
    overflow-y: auto;
    padding-right: var(--space-xs);
}

/* Individual download tile */
.download-tile {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-xs);
    padding: var(--space-sm) var(--space-xs);
    background: var(--color-bg-elevated);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: all var(--transition-smooth);
}

.download-tile:hover {
    transform: scale(1.05);
    border-color: var(--color-accent);
    box-shadow: 0 0 20px var(--color-accent-glow);
}

/* C6: per-file failure tile (mid-batch error). Red, no success glow; click to dismiss.
   BUG-74: no opacity (0.85 took its text below 4.5:1), and its text in --color-error-text. */
.download-tile.failed {
    border-color: var(--color-error);
}

.download-tile.failed .download-tile-icon,
.download-tile.failed .download-tile-format {
    color: var(--color-error-text);
}

.download-tile.failed:hover {
    transform: scale(1.02);
    border-color: var(--color-error);
    box-shadow: 0 0 12px rgba(239, 68, 68, 0.3);
}

.download-tile:active {
    transform: scale(0.98);
}

.download-tile-icon {
    width: 28px;
    height: 28px;
    color: var(--color-accent);
}

.download-tile-format {
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--color-text);
    text-transform: uppercase;
}

.download-tile-name {
    font-size: 0.625rem;
    color: var(--color-text-muted);
    text-align: center;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 100%;
}

/* Download All button */
.btn-download-all {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-sm);
    padding: var(--space-sm) var(--space-lg);
    background: var(--color-success-button);
    color: white;
    border: none;
    border-radius: var(--radius-md);
    font-size: 0.875rem;
    font-weight: 500;
    cursor: pointer;
    transition: all var(--transition-smooth);
}

.btn-download-all:hover {
    transform: scale(1.02);
    box-shadow: 0 0 25px rgba(34, 197, 94, 0.4);
}

.btn-download-all:active {
    transform: scale(0.98);
}

.btn-download-all svg {
    width: 18px;
    height: 18px;
}

/* Focus states for download area elements */
.download-tile:focus-visible,
.btn-download-all:focus-visible {
    outline: 2px solid var(--color-accent);
    outline-offset: 2px;
}

/* ===== THEME TOGGLE ===== */
.theme-toggle {
    position: fixed;
    top: var(--space-md);
    right: var(--space-md);
    z-index: 100;
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--color-glass);
    backdrop-filter: blur(var(--blur-glass));
    -webkit-backdrop-filter: blur(var(--blur-glass));
    border: 1px solid var(--color-border);
    border-radius: 50%;
    box-shadow: var(--shadow-glass);
    cursor: pointer;
    color: var(--color-text-muted);
    transition: color var(--transition-smooth),
                border-color var(--transition-smooth),
                background var(--transition-smooth);
}

.theme-toggle:hover {
    color: var(--color-text);
    border-color: var(--color-border-hover);
}

.theme-toggle:focus-visible {
    outline: 2px solid var(--color-accent);
    outline-offset: 2px;
}

.theme-toggle svg {
    width: 20px;
    height: 20px;
    transition: transform var(--transition-smooth);
}

.theme-toggle:hover svg {
    transform: rotate(15deg);
}

.theme-toggle[hidden] {
    display: none;
}

/* Smooth theme transition (added by JS during switch, removed after) */
html.theme-transitioning,
html.theme-transitioning *,
html.theme-transitioning *::before,
html.theme-transitioning *::after {
    transition: background-color 300ms ease, color 300ms ease,
                border-color 300ms ease, box-shadow 300ms ease !important;
}

/* ===== ADVANCED OPTIONS ACCORDION (H6) ===== */
.advanced-options {
    width: 100%;
    max-width: 400px;
}

/* Hide the whole accordion while a conversion is running */
#state-drop.converting .advanced-options {
    display: none !important;
}

.advanced-toggle {
    display: block;
    width: 100%;
    padding: var(--space-sm) var(--space-md);
    background: transparent;
    color: var(--color-text-muted);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    font-size: 0.8125rem;
    font-weight: 500;
    cursor: pointer;
    text-align: left;
    transition: all var(--transition-smooth);
}

.advanced-toggle::before {
    content: '▸ ';
}

.advanced-toggle.expanded::before {
    content: '▾ ';
}

.advanced-toggle:hover {
    color: var(--color-text);
    border-color: var(--color-border-hover);
}

.advanced-toggle:focus-visible {
    outline: 2px solid var(--color-accent);
    outline-offset: 2px;
}

.advanced-content {
    margin-top: var(--space-sm);
}

.advanced-content.collapsed {
    display: none;
}

.advanced-staged {
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
    margin-bottom: var(--space-sm);
    padding: var(--space-md);
    background: var(--color-glass);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
}

.advanced-staged.hidden {
    display: none;
}

.advanced-staged-name {
    font-size: 0.875rem;
    color: var(--color-text);
    word-break: break-all;
}

.advanced-staged-actions {
    display: flex;
    gap: var(--space-sm);
}

.advanced-staged-actions .btn-primary,
.advanced-staged-actions .btn-secondary {
    width: auto;
    flex: 1;
    padding: var(--space-sm) var(--space-md);
    margin-top: 0;
    font-size: 0.875rem;
}

/* M4: ambiguous-PDF hint line in the format-selection state */
.format-hint {
    max-width: 400px;
    text-align: center;
    font-size: 0.875rem;
    color: var(--color-warning-text);
    background: var(--color-warning-bg);
    border: 1px solid var(--color-warning-border);
    border-radius: var(--radius-sm);
    padding: var(--space-sm) var(--space-md);
}

.format-hint[hidden] {
    display: none;
}

/* ===== CONVERSION OPTIONS PANELS ===== */
.conversion-options {
    margin-top: var(--space-md);
    padding: var(--space-md);
    background: var(--color-glass);
    backdrop-filter: blur(var(--blur-glass));
    -webkit-backdrop-filter: blur(var(--blur-glass));
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    width: 100%;
    max-width: 400px;
}
.conversion-options.hidden { display: none; }
.options-title {
    font-size: 13px;
    font-weight: 500;
    color: var(--color-text-muted);
    margin: 0 0 var(--space-sm);
}
.option-row {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    margin-bottom: var(--space-sm);
}
.option-row:last-child { margin-bottom: 0; }
/* BUG-55: an option that has no effect for this conversion is hidden with [hidden]; the
   display rules above would otherwise keep it on screen. */
.option-row[hidden], .adv-group-optlabel[hidden] { display: none; }
.option-label {
    font-size: 13px;
    color: var(--color-text-muted);
    min-width: 70px;
}
.option-select, .option-input {
    background: var(--color-bg-elevated);
    color: var(--color-text);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    padding: 4px 8px;
    font-size: 13px;
    flex: 1;
}
.option-select:focus, .option-input:focus {
    outline: 2px solid var(--color-accent);
    outline-offset: 1px;
}

/* ===== CONVERSION SETTINGS (format locale, paper size) ===== */
.conversion-settings {
    width: 100%;
    max-width: 400px;
    margin-top: var(--space-sm);
    text-align: center;
}
.conversion-settings[hidden] { display: none; }
.settings-summary {
    font-size: 0.8125rem;
    color: var(--color-text-muted);
    margin: 0;
}
.settings-change {
    background: none;
    border: none;
    padding: 0 var(--space-xs);
    color: var(--color-accent);
    font: inherit;
    cursor: pointer;
    text-decoration: underline;
}
.settings-change:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }
.settings-change:disabled { color: var(--color-text-muted); text-decoration: none; cursor: default; opacity: 0.6; }
.settings-panel { text-align: left; }
.settings-panel[hidden] { display: none; }
.settings-locale-list { width: 100%; margin-bottom: var(--space-sm); }
.settings-paper { border: none; padding: 0; margin: 0 0 var(--space-sm); }
.settings-paper label { font-size: 13px; color: var(--color-text); margin-right: var(--space-md); }
.settings-time { border: none; padding: 0; margin: 0 0 var(--space-xs); min-width: 0; }
.settings-time legend { margin-bottom: var(--space-xs); }
.settings-time label { display: block; font-size: 13px; color: var(--color-text); margin: 0 0 var(--space-xs); }
.settings-time-pick { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-xs) var(--space-sm);
    margin: 0 0 var(--space-xs) 1.5em; }
.settings-time-pick .option-input { flex: 1 1 15rem; width: auto; min-width: 0; max-width: 17rem; }
/* FEAT-11: the time limit, a number box in minutes */
.settings-time-limit[hidden] { display: none; }
.settings-time-limit-row { display: flex; align-items: center; gap: var(--space-sm); }
.settings-time-limit-row .option-input { width: 7rem; flex: 0 0 auto; }
/* Pointed to after a conversion stopped at the time limit */
.settings-change.attention { outline: 2px solid var(--color-accent); outline-offset: 2px; border-radius: 4px; }
.settings-summary-explicit { color: var(--color-text); font-weight: 600; }
/* The site is dark unless html[data-theme="light"]: give the native date-time
   control (its text and calendar icon) the matching scheme. */
#settings-time-value { color-scheme: dark; }
html[data-theme="light"] #settings-time-value { color-scheme: light; }
.settings-note {
    font-size: 12px;
    color: var(--color-text-muted);
    margin: 0 0 var(--space-sm);
}
.settings-warning {
    font-size: 12px;
    color: var(--color-warning-text);
    background: var(--color-warning-bg);
    border: 1px solid var(--color-warning-border);
    border-radius: var(--radius-sm);
    padding: var(--space-xs) var(--space-sm);
    margin: 0 0 var(--space-sm);
}
.settings-actions { display: flex; gap: var(--space-sm); justify-content: flex-end; }
.settings-actions .btn-primary, .settings-actions .btn-secondary { width: auto; margin-top: 0; }
#state-drop.converting .conversion-settings { display: none; }
/* The open panel can outgrow a short (phone) viewport: let the drop state scroll
   from the top instead of centring content that no longer fits. */
@media (max-height: 900px) {
    /* padding-bottom: room above the site footer, which sits over the bottom edge */
    #state-drop.settings-open { justify-content: flex-start; overflow-y: auto; padding-bottom: 4rem; }
    #state-drop.settings-open > * { flex-shrink: 0; }
}

/* ===== ACCESSIBILITY ===== */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        transition-duration: 0.01ms !important;
    }
}

.format-tile:focus-visible,
.btn-primary:focus-visible,
.btn-secondary:focus-visible,
.mobile-upload-btn:focus-visible,
.queue-btn:focus-visible {
    outline: 2px solid var(--color-accent);
    outline-offset: 2px;
}

/* ===== Concept-6 "Swap" (Phase 0) ===== */
/* Two zones trade sizes when Advanced is opened. Positions never move (basic always
   on top), so tab order is stable and the motion is a calm see-saw. */
.zone { display: grid; overflow: hidden; transition: max-height var(--transition-smooth); }
/* BUG-59: in a short window (a landscape phone, a small laptop, a frame) the drop screen's
   flex items used to SHRINK below their content, and .zone's overflow:hidden then clipped the
   drop zone (on a 412 px-tall phone screen it was a 36 px sliver), with no way to scroll to
   the rest. Items keep their own height; a screen taller than the window scrolls instead, and
   `safe` keeps an overflowing centred column scrollable from its top. The bottom padding
   clears the footer; on narrow screens, where the column runs under the fixed corner items
   (wordmark, theme toggle), so does the top padding. */
#state-drop > * { flex-shrink: 0; }
.state.active { overflow-y: auto; justify-content: safe center; padding-bottom: max(var(--space-lg), 3rem); }
@media (max-width: 600px) { .state.active { padding-top: max(var(--space-lg), 4rem); } }
.zone > .zone-variant { grid-area: 1 / 1; transition: opacity var(--transition-smooth); }
.zone-adv { margin-top: var(--space-md); }
.zone-basic { max-height: 460px; }
.zone-adv { max-height: 3.5rem; }
.zone-basic .zv-slim, .zone-adv .zv-big { opacity: 0; pointer-events: none; }
.zone-basic .zv-big, .zone-adv .zv-slim { opacity: 1; }
#state-drop.adv-open .zone-basic { max-height: 3.5rem; }
#state-drop.adv-open .zone-adv { max-height: 640px; }
#state-drop.adv-open .zone-basic .zv-big,
#state-drop.adv-open .zone-adv .zv-slim { opacity: 0; pointer-events: none; }
#state-drop.adv-open .zone-basic .zv-slim,
#state-drop.adv-open .zone-adv .zv-big { opacity: 1; pointer-events: auto; }

.slimbar { display: flex; align-items: center; gap: .6rem; min-height: 3.25rem;
    padding: 0 var(--space-md); border: 1.5px dashed var(--color-border);
    border-radius: var(--radius-md); cursor: pointer; color: var(--color-text-muted);
    transition: all var(--transition-smooth); }
.slimbar svg { width: 18px; height: 18px; flex: 0 0 auto; }
.slimbar .slim-lbl { color: var(--color-text); font-weight: 500; font-size: .9rem; }
.slimbar .slim-hint { font-size: .78rem; }
.slimbar .slim-chev { margin-left: auto; color: var(--color-text-muted); font-size: 1.1rem; }
.slimbar:hover { border-color: var(--color-border-hover); }
/* The Advanced bar is a TOGGLE, not a drop target (owner decision 2026-10-01): a solid
   border, because on this page a dashed border means "drop here". A file let go over it
   is an ordinary basic-zone drop (instant convert). */
.adv-bar { border-style: solid; }

#state-drop.has-staged .instant-bar { opacity: .5; pointer-events: none; }

.advbig { border: 2px dashed var(--color-accent); background: var(--color-drag-tint);
    border-radius: var(--radius-xl); box-shadow: 0 0 30px var(--color-accent-glow);
    padding: var(--space-lg); }
.advhead { display: flex; align-items: center; gap: .5rem; cursor: pointer;
    color: var(--color-text); font-weight: 500; font-size: .95rem;
    padding-bottom: var(--space-md); border-bottom: 1px solid var(--color-border);
    margin-bottom: var(--space-md); }
.advhead svg { width: 16px; height: 16px; }
.advhead-chev { margin-left: auto; color: var(--color-text-muted); transform: rotate(90deg); }

.slot { display: flex; flex-direction: column; align-items: center; gap: .4rem;
    padding: var(--space-lg); border: 2px dashed var(--color-border);
    border-radius: var(--radius-md); color: var(--color-text-muted); cursor: pointer;
    transition: all var(--transition-smooth); }
.slot:hover { border-color: var(--color-accent); color: var(--color-accent); background: var(--color-drag-tint); }
.slot svg { width: 30px; height: 30px; }
.slot-hint { font-size: .72rem; letter-spacing: .03em; text-transform: uppercase; opacity: .75; }
#state-drop.has-staged #advanced-slot { display: none; }

.zone-basic .drop-zone-content.drag-target { border-color: var(--color-accent);
    box-shadow: 0 0 40px var(--color-accent-glow); }

@media (prefers-reduced-motion: reduce) {
    .zone, .zone > .zone-variant { transition: none; }
}

/* ===== FF-3: grouped multi-file Advanced ===== */
.advanced-groups.hidden { display: none; }
#state-drop.grouped #advanced-slot { display: none; }
.adv-group { display: flex; flex-direction: column; gap: .5rem; padding: .7rem .9rem;
    margin-bottom: .55rem; border: 1.5px solid var(--color-border);
    border-radius: var(--radius-md); background: var(--color-glass); }
.adv-group-head { display: flex; align-items: center; gap: .6rem; }
.adv-group-opts { display: flex; flex-wrap: wrap; gap: .75rem; padding-top: .5rem;
    border-top: 1px solid var(--color-border); }
.adv-group-optlabel { display: inline-flex; align-items: center; gap: .35rem;
    font-size: .8rem; color: var(--color-text-muted); }
/* FF-4: per-file sheet rows */
.adv-group-files { display: flex; flex-direction: column; gap: .4rem; padding-top: .5rem;
    border-top: 1px solid var(--color-border); }
.adv-group-file { display: flex; align-items: center; gap: .5rem; font-size: .82rem; }
.adv-group-fname { color: var(--color-text); font-weight: 500; flex: 1;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.adv-group svg { width: 20px; height: 20px; color: var(--color-accent); flex: 0 0 auto; }
.adv-group .adv-group-name { font-weight: 600; font-size: .9rem; }
.adv-group .adv-group-count { color: var(--color-text-muted); font-size: .82rem; }
.adv-group .adv-group-to { margin-left: auto; color: var(--color-text-muted); font-size: .8rem; }
.adv-group .adv-group-select { padding: .4rem .7rem; border-radius: var(--radius-sm);
    border: 1px solid var(--color-border); background: var(--color-glass);
    color: var(--color-text); font-size: .85rem; }
.adv-group.unsupported { border-style: dashed; opacity: .6; }
.adv-group.unsupported .adv-group-name { color: var(--color-text-muted); }
/* FF-1 3b-full: PDF group export options (page range + quality) */
.adv-group-opts.hidden { display: none; }
.adv-group .adv-group-input { padding: .4rem .7rem; border-radius: var(--radius-sm);
    border: 1px solid var(--color-border); background: var(--color-glass);
    color: var(--color-text); font-size: .85rem; width: 7rem; }

/* ── Advanced output-format grid ───────────────────────────────────────────
   RESTORED 2026-07-26. The markup AND these styles were deleted by the Zero UI
   v2 rewrite (b9a7f12) while format_selector.js kept binding `.format-btn`, so
   the selector matched nothing: getSelectedFormat() could only return null and
   a staged Advanced convert always produced PDF, silently, while CLAUDE.md went
   on documenting the choice.
   Reuses the panel chrome of .conversion-options so the surface reads as one
   thing; the category colours are the documented ones (blue docs / green sheets
   / yellow slides / grey PDF). */
.advanced-format {
    margin-top: var(--space-md);
    padding: var(--space-md);
    background: var(--color-glass);
    backdrop-filter: blur(var(--blur-glass));
    -webkit-backdrop-filter: blur(var(--blur-glass));
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
}
.format-btn-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-xs, 6px);
}
.format-btn {
    padding: 7px 14px;
    border: 1px solid transparent;
    border-radius: var(--radius-md, 6px);
    font-size: 13px;
    font-weight: 600;
    color: #fff;
    cursor: pointer;
    transition: filter .15s ease, opacity .15s ease, box-shadow .15s ease;
}
.format-btn[data-category="documents"]     { background: #3B82F6; }
.format-btn[data-category="spreadsheets"]  { background: #22C55E; }
.format-btn[data-category="presentations"] { background: #EAB308; color: #1f2937; }
.format-btn[data-category="pdf"]           { background: #6B7280; }
.format-btn:hover:not(:disabled)  { filter: brightness(1.12); }
.format-btn:focus-visible         { outline: 2px solid var(--color-accent); outline-offset: 2px; }
/* Selected must be legible without relying on colour alone (a11y): it also
   gains a ring and a check mark. */
.format-btn.selected {
    box-shadow: 0 0 0 2px var(--color-accent), 0 0 14px var(--color-accent-glow);
}
.format-btn.selected::after { content: " ✓"; }
/* Disabled = incompatible with this input, or same-as-input. Set by
   FormatSelector.updateButtonStates() from the real compatibility table, not
   by hand here. */
.format-btn:disabled {
    opacity: .35;
    cursor: not-allowed;
    filter: grayscale(.6);
}
/* BUG-FMT-2: this stylesheet has NO global `.hidden` rule — every component
   declares its own (.conversion-options.hidden, .advanced-groups.hidden, ...).
   329745d added .advanced-format but not this line, so
   FormatSelector.setFormatGridVisible(false) added a class that did nothing and
   the grid stayed on screen with nothing staged (and would have stayed on screen
   for a PDF input, which INV7 routes to #state-format instead). */
.advanced-format.hidden { display: none; }

/* ── Format warning / info line ────────────────────────────────────────────
   RESTORED 2026-07-27 (BUG-FMT-1b). format_selector.js has always written to
   #format-warning / #format-warning-text, but the Zero UI v2 rewrite deleted
   the markup and 329745d restored only the grid, so showWarning()/showInfo()
   rendered nothing at all — replacing the staged file discarded the chosen
   output format in total silence.
   showInfo() overrides background/border/colour inline for the informational
   variant; these are the warning defaults. Both foreground and background are
   set explicitly, so the line stays legible in either theme. */
.format-warning {
    margin-top: var(--space-sm, 8px);
    padding: .55rem .8rem;
    border: 1px solid #f5c26b;
    border-radius: var(--radius-md, 6px);
    background: #fff3cd;
    color: #7a5300;
    font-size: .85rem;
    line-height: 1.35;
}
.format-warning.hidden { display: none; }

/* ── Wordmark ──────────────────────────────────────────────────────────────
   Short umbrella brand ("Probably Fine"), persistent and unobtrusive. The full
   product name lives in the visually-hidden <h1>; this is the visible mark.
   Deliberately NOT in web/js/* — the brand string must stay out of the shared
   JS bytes, which are byte-identical across every brand published from this
   codebase. That byte-identity is a cryptographic claim the provenance verifier
   uses to distinguish a sibling brand from an infringing mirror, and a brand
   string in shared JS would break it. If JS ever needs the name, read it from
   the DOM or a data- attribute set here in index.html. */
.wordmark {
    position: fixed;
    top: var(--space-md, 16px);
    left: var(--space-lg, 24px);
    font-size: 13px;
    font-weight: 600;
    letter-spacing: .02em;
    color: var(--color-text-muted);
    opacity: .75;
    user-select: none;
    pointer-events: none;   /* purely decorative; never intercepts a drop */
    z-index: 10;
}
@media (max-width: 560px) {
    .wordmark { font-size: 12px; top: var(--space-sm, 8px); left: var(--space-md, 16px); }
}

/* FG-021: the password prompt (ui-v2.js askForPassword). Hidden unless a file needs a password
   and the release-only flag passwordProtectedFiles is on. */
.password-prompt {
    margin: var(--space-md) auto;
    max-width: 480px;
    padding: var(--space-md);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
}
.password-prompt[hidden] { display: none; }
.pw-form { display: flex; flex-direction: column; gap: var(--space-sm); }
.pw-title { font-weight: 600; word-break: break-all; margin: 0; }
.pw-message { margin: 0; color: var(--color-text); }
.pw-wrong { color: var(--color-error); }
.pw-label { font-size: 0.875rem; color: var(--color-text-muted); }
.pw-form input[type="password"] {
    padding: var(--space-sm);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    background: var(--color-bg-elevated);
    color: var(--color-text);
    font: inherit;
}
.pw-problem { margin: 0; min-height: 1em; font-size: 0.8125rem; color: var(--color-error); }
.pw-problem:empty { min-height: 0; }
.pw-output { border: 1px solid var(--color-border); border-radius: var(--radius-sm); padding: var(--space-sm); margin: 0; }
.pw-output legend { font-size: 0.875rem; color: var(--color-text-muted); padding: 0 4px; }
.pw-choice { display: flex; align-items: center; gap: var(--space-sm); }
.pw-new { display: flex; flex-direction: column; gap: 4px; margin-top: var(--space-sm); }
/* A class that sets display wins over the hidden attribute, so every hideable class needs its
   own [hidden] rule (WAF V1, 2026-10-31: Protect the output's password fields and PDF boxes
   showed while it was unticked; the cell-comments row showed for XLSX to ODS). Gate
   engine_features check 6 holds it. .option-row[hidden] is also in #644; either can land first. */
.pw-new[hidden], .pw-form[hidden], .pw-choice[hidden], .option-row[hidden] { display: none; }
/* The same for main's classes that set display (gate engine_features check 6). */
.btn-cancel[hidden], .three-box-only[hidden] { display: none; }
.pw-note { margin: 0; font-size: 0.875rem; color: var(--color-text-muted); }
.pw-actions { display: flex; gap: var(--space-sm); justify-content: flex-end; flex-wrap: wrap; }

/* ===== FEAT-12: the three-box layout (html.three-box; release-only flag threeBoxLayout) =====
   Box 1 (the big drop zone), box 2 "Convert to…" (.zone-adv) and box 3 "Full control"
   (.zone-full), top to bottom, always in that order. One box is open at a time: the open one is
   the big surface in its own place (#state-drop[data-box]), the others are slim bars. Boxes 2
   and 3 share #advanced-surface, which ui-v2.js moves into the open box's zone. With the flag
   off none of this applies and the page is today's two-zone Swap. */
html:not(.three-box) .zone-full,
html:not(.three-box) .three-box-only { display: none !important; }
html.three-box .today-only { display: none !important; }

html.three-box .zone-full { margin-top: var(--space-md); max-height: 3.5rem; }
html.three-box .zone-full > .zone-variant { grid-area: 1 / 1; transition: opacity var(--transition-smooth); }
html.three-box .zone-full .zv-big { opacity: 0; pointer-events: none; }
/* Every bar is the same width and style, at least 56 px tall (owner review of the prototype). */
html.three-box .zone-adv, html.three-box .zone-full { width: min(450px, 100%); }
html.three-box .slimbar { min-height: 3.5rem; width: min(392px, 100%); box-sizing: border-box;
    margin: 0 auto; border-style: dashed; }
html.three-box .slimbar .slim-lbl { white-space: nowrap; }
html.three-box .zone-adv .zv-slim, html.three-box .zone-full .zv-slim,
html.three-box .zone-basic .zv-slim { display: flex; justify-content: center; align-items: flex-start; }
.full-bar .slim-hint { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }

/* Box 3 open: box 2 shows its bar, box 3's zone holds the surface. */
html.three-box #state-drop.adv-open[data-box="3"] .zone-adv { max-height: 3.5rem; }
html.three-box #state-drop.adv-open[data-box="3"] .zone-adv .zv-slim { opacity: 1; pointer-events: auto; }
html.three-box #state-drop.adv-open[data-box="3"] .zone-full { max-height: 4000px; }
html.three-box #state-drop.adv-open[data-box="3"] .zone-full .zv-slim { opacity: 0; pointer-events: none; }
html.three-box #state-drop.adv-open[data-box="3"] .zone-full .zv-big { opacity: 1; pointer-events: auto; }
html.three-box #state-drop.adv-open[data-box="2"] .zone-adv { max-height: 4000px; }

/* Box 2 shows the format grid and how a CSV is read; everything else is box 3's (and is not
   read in box 2: ui-v2.js boxAllowsFullOptions). */
html.three-box #state-drop[data-box="2"] :is(#pdf-options, #spreadsheet-options, #html-options,
    #protect-options, #cell-comments-row, #conversion-settings, .box3-only) { display: none !important; }
/* Outside box 3 the remembered settings show only as box 3's bar summary. */
html.three-box #state-drop:not([data-box="3"]) #conversion-settings { display: none !important; }
html.three-box #conversion-settings { margin-top: var(--space-md); padding-top: var(--space-md);
    border-top: 1px solid var(--color-border); }
html.three-box #settings-change, html.three-box #settings-done { display: none; }

/* The drag cue: only the box under the pointer lights up, with "Drop here" on it, never over
   its name (the label replaces the chevron at the right end). */
html.three-box .slimbar.drag-target, html.three-box .advbig.drag-target {
    border-color: var(--color-accent); border-style: solid; box-shadow: 0 0 0 3px var(--color-accent-glow); }
html.three-box .slimbar { position: relative; }
html.three-box .slimbar.drag-target .slim-chev { visibility: hidden; }
html.three-box .slimbar.drag-target::after { content: "Drop here"; position: absolute; right: 10px; top: 50%;
    transform: translateY(-50%); background: var(--color-accent); color: #fff; font-size: 12px; font-weight: 600;
    padding: 2px 10px; border-radius: 999px; pointer-events: none; }
html.three-box .zone-basic .drop-zone-content.drag-target { position: relative; }
html.three-box .zone-basic .drop-zone-content.drag-target::after { content: "Drop here"; position: absolute;
    right: 14px; top: 14px; background: var(--color-accent); color: #fff; font-size: 12px; font-weight: 600;
    padding: 2px 10px; border-radius: 999px; pointer-events: none; }
html.three-box .advbig.drag-target { box-shadow: 0 0 40px var(--color-accent-glow); }

/* Proposal 11: the footer is in the page flow (ui-v2.js moves it to the end of the drop screen). */
html.three-box #state-drop > .site-footer { position: static; transform: none; left: auto; bottom: auto;
    margin: var(--space-lg) auto 0; text-align: center; }
/* FEAT-11 + FEAT-12: after a stop at the time limit, the way to the setting is box 3's bar. */
html.three-box .full-bar.attention { outline: 2px solid var(--color-accent); outline-offset: 2px; }
/* FEAT-12: an empty (invisible) download area takes no room, so the three boxes and the footer fit
   an ordinary window without scrolling; it appears below the boxes once there is a result. */
html.three-box .download-area:not(.visible) { display: none; }
/* FEAT-12: a zone's single grid column never grows to its content (box 3's long, unwrapped
   summary made it as wide as the summary, pushing the centred bar off to the right). */
html.three-box .zone { grid-template-columns: minmax(0, 1fr); }

/* FEAT-12 queue model (three-box). */
html.three-box #skip-btn { margin-right: var(--space-sm); }
/* BUG-74: a downloaded tile is marked by its label and a dashed border, not by opacity (0.6 took its
   text, and the green label, below 4.5:1). */
html.three-box .download-tile.downloaded { border-style: dashed; padding-bottom: 18px; }   /* the label sits below the name, not on it */
html.three-box .download-tile.downloaded::after { content: "Downloaded"; position: absolute; left: 0; right: 0; bottom: 4px;
    font-size: 10px; color: var(--color-success-text); text-align: center; pointer-events: none; }
html.three-box .download-tile { position: relative; }
.download-clear { margin-left: auto; background: none; border: none; color: var(--color-text-muted); cursor: pointer;
    font: inherit; font-size: .75rem; text-decoration: underline; }
html.three-box .advanced-staged-actions #advanced-add-btn,
html.three-box .advanced-staged-actions #advanced-add-groups-btn { width: auto; }
[hidden].three-box-only, #skip-btn[hidden] { display: none !important; }

/* FEAT-19: "Conversion details file" (box 3), and the per-result "Download conversion details"
   button, which shares the tile's grid cell (a button cannot hold another). */
.conversion-details-row { flex-wrap: wrap; margin-top: var(--space-md); }
.conversion-details-row .settings-note { flex-basis: 100%; margin: var(--space-xs) 0 0; }
.download-cell { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.download-cell > .download-tile { width: 100%; }
.download-details-btn { font: inherit; font-size: 12px; line-height: 1.25; background: none; border: none; padding: 2px;
    color: var(--color-accent); text-decoration: underline; cursor: pointer; text-align: center; overflow-wrap: anywhere; }
.download-details-btn:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; border-radius: 4px; }
.download-details-btn:disabled { opacity: 0.6; cursor: progress; }
