/* Presentation for the shared file uploader + preview component (M-062, extracted from the documents
   module's M-048f/M-048g). Two cooperating pieces, styled here so every module (documents, Směrnice, …)
   that renders `<x-platform::file-uploader>` / `<x-platform::file-preview>` looks identical:
     • `.platform-uploader*`      — the editor's drop zone + reorderable file table;
     • `.platform-file-preview*`  — the preview pane (file list + native-HTML render stage).
   Colors, spacing, radii and type come from the platform design tokens (tokens.css) — themeable without
   touching markup (coding-standards §4 and §12). Mobile-first; no inline styles; no horizontal overflow
   at phone width. */

/* ---- Preview pane ------------------------------------------------------- */
/* The RIGHT column of a split editor, and the read-only preview on a detail page. Fills its card as a flex
   column: a wrapping file list on top, the preview stage below taking the remaining height. */
.platform-file-preview {
    display: flex;
    flex-direction: column;
    gap: var(--platform-space-md, 1rem);
    min-width: 0;
}

/* File list: selectable chips that wrap. Long, unbreakable filenames must not push the card wider than
   its column (min-width:0 on the flex parent + overflow-wrap here), so the pane never scrolls sideways. */
.platform-file-preview__files {
    display: flex;
    flex-wrap: wrap;
    gap: var(--platform-space-sm, 0.5rem);
    margin: 0;
    padding: 0;
    list-style: none;
}

.platform-file-preview__file {
    max-width: 100%;
    padding: var(--platform-space-xs, 0.25rem) var(--platform-space-sm, 0.5rem);
    font: inherit;
    color: var(--platform-color-text);
    text-align: left;
    background: var(--platform-color-surface-muted, #f6f8fa);
    border: 1px solid var(--platform-color-border);
    border-radius: var(--platform-radius-md, 0.375rem);
    cursor: pointer;
    overflow-wrap: anywhere;
    /* Reads as a switchable control, not a static label — the accent tint on hover/focus makes it obvious
       each chip is clickable (and, with 2+ chips, that you can switch between files). */
    transition: color 0.15s ease, background-color 0.15s ease, border-color 0.15s ease;
}

.platform-file-preview__file:hover,
.platform-file-preview__file:focus-visible {
    color: var(--platform-color-accent, #2563eb);
    background: var(--platform-color-surface, #fff);
    border-color: var(--platform-color-accent, #2563eb);
}

.platform-file-preview__file--active {
    color: var(--platform-color-on-accent, #fff);
    background: var(--platform-color-accent, #2563eb);
    border-color: var(--platform-color-accent, #2563eb);
}

/* ---- Detail file list (M-095) ------------------------------------------- */
/* The read-only "Files" list on a detail page's LEFT column. It adopts the editor pattern: each row is a
   preview ROW BUTTON that drives the sibling render stage (click → switch the right preview) plus a
   per-row download icon-button, so download stays explicit and separate from click-to-preview. Token-
   driven → themes light↔dark for free; mobile-first (the name wraps, the row never overflows sideways). */
.platform-file-list {
    margin: 0;
    padding: 0;
    list-style: none;
}

.platform-file-list__row {
    display: flex;
    align-items: center;
    gap: var(--platform-space-sm, 0.5rem);
    padding: var(--platform-space-sm, 0.5rem) 0;
    border-bottom: 1px solid var(--platform-color-border, #d0d7de);
}

/* The row body grows to fill the row between the file entry and the download button, stacking the clickable
   name over its version-history disclosure. */
.platform-file-list__body {
    display: flex;
    flex: 1 1 auto;
    min-width: 0;
    flex-direction: column;
    gap: var(--platform-space-xs, 0.25rem);
}

/* The clickable file entry: a single row — filename on the left, its size/date meta pinned at the end
   (right before the download icon), mirroring the edit screen's `.platform-uploader__line`. A chrome-less
   text button that tints to the accent on hover/focus so it reads as a switchable control. */
.platform-file-list__name {
    display: flex;
    align-items: center;
    justify-content: space-between;
    min-width: 0;
    flex-direction: row;
    gap: var(--platform-space-sm, 0.5rem);
    padding: 0;
    font: inherit;
    text-align: left;
    background: none;
    border: 0;
    cursor: pointer;
}

/* The filename grows to fill the line and ellipsises on one line when long, so the row never pushes the
   card wider than its column (min-width:0 lets the flex item shrink below its content width). */
.platform-file-list__name-text {
    flex: 1 1 auto;
    min-width: 0;
    color: var(--platform-color-accent, #0969da);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Keep the size · date meta as a fixed, non-wrapping chip at the END of the row. This is a SCOPED override
   of the GLOBAL `.platform-meta` (layout.css, also used by todos/directives lists): confine flex/nowrap to
   THIS file-list row so the shared class is untouched everywhere else (the shared-flex-item scoping trap). */
.platform-file-list__name .platform-meta {
    flex: 0 0 auto;
    white-space: nowrap;
}

.platform-file-list__name:hover .platform-file-list__name-text,
.platform-file-list__name:focus-visible .platform-file-list__name-text {
    text-decoration: underline;
}

/* The selected file's row — the `preview` controller toggles this via `data-preview-active-class`. */
.platform-file-list__name--active .platform-file-list__name-text {
    font-weight: 600;
}

/* Narrow/mobile: there isn't room for name + meta on one line, so stack them (meta drops below the name)
   and let the name wrap in full instead of ellipsising — graceful degradation, never a sideways scroll. */
@media (max-width: 40rem) {
    .platform-file-list__name {
        flex-direction: column;
        align-items: flex-start;
    }

    .platform-file-list__name-text {
        white-space: normal;
        overflow: visible;
        overflow-wrap: anywhere;
    }
}

/* ---- Preview controls (M-072 view toggle + M-259 fullscreen) ------------ */
/* The controls strip: a `role="toolbar"` revealed by the `preview` controller only for a previewable file.
   It holds the segmented view toggle (an inner `role="tablist"`) that stretches to fill the row, and the
   Fullscreen action button pinned to its end. Hidden for a download-only file or the empty state.
   Token-driven → themes light↔dark for free. */
.platform-file-preview__tabs {
    display: flex;
    align-items: stretch;
    gap: var(--platform-space-xs, 0.25rem);
    padding: var(--platform-space-xs, 0.25rem);
    background: var(--platform-color-surface-muted, #f6f8fa);
    border: 1px solid var(--platform-color-border);
    border-radius: var(--platform-radius-md, 0.375rem);
}

/* The two view tabs (Náhled | Text) share the row; the Fullscreen button sits beside them. */
.platform-file-preview__tablist {
    display: flex;
    flex: 1 1 auto;
    gap: var(--platform-space-xs, 0.25rem);
}

.platform-file-preview__tab {
    flex: 1 1 auto;
    padding: var(--platform-space-xs, 0.25rem) var(--platform-space-sm, 0.5rem);
    font: inherit;
    color: var(--platform-color-text-muted, #57606a);
    background: transparent;
    border: 0;
    border-radius: var(--platform-radius-sm, 0.25rem);
    cursor: pointer;
    transition: color 0.15s ease, background-color 0.15s ease;
}

.platform-file-preview__tab:hover,
.platform-file-preview__tab:focus-visible {
    color: var(--platform-color-accent, #2563eb);
}

.platform-file-preview__tab--active {
    color: var(--platform-color-text);
    background: var(--platform-color-surface, #fff);
    box-shadow: var(--platform-shadow-sm, 0 1px 2px rgba(44, 62, 80, 0.08));
}

/* Fullscreen action button (M-259): an icon-only control at the end of the toolbar that opens the overlay.
   It is NOT a tab — no `role="tab"`/`aria-selected` — so it does not read as a segmented option. The glyph is
   painted with a CSS mask (same technique as the placeholder icon / button glyphs, §4 — no markup in JS). */
.platform-file-preview__fullscreen {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    padding: var(--platform-space-xs, 0.25rem) var(--platform-space-sm, 0.5rem);
    color: var(--platform-color-text-muted, #57606a);
    background: transparent;
    border: 0;
    border-radius: var(--platform-radius-sm, 0.25rem);
    cursor: pointer;
    transition: color 0.15s ease, background-color 0.15s ease;
}

.platform-file-preview__fullscreen:hover,
.platform-file-preview__fullscreen:focus-visible {
    color: var(--platform-color-accent, #2563eb);
    background: var(--platform-color-surface, #fff);
}

.platform-file-preview__fullscreen-icon {
    width: 1.25rem;
    height: 1.25rem;
    background-color: currentColor;
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3'/%3E%3C/svg%3E") center / contain no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* A tab's content (the render stage under Náhled, the extraction under Text): a flex column that grows to
   fill the pane so both tabs are equally large, and the text area can stretch to the full height. */
.platform-file-preview__panel {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    min-height: 0;
}

/* Preview stage: holds the mutually-exclusive renderers (<embed>/<img>/none/placeholder); the controller
   reveals exactly one. A responsive min-height keeps it usefully tall while it also grows to fill the
   card when the form column is taller. */
.platform-file-preview__stage {
    display: flex;
    flex: 1 1 auto;
    align-items: center;
    justify-content: center;
    min-height: min(60vh, 32rem);
    padding: var(--platform-space-md, 1rem);
    text-align: center;
    background: var(--platform-color-surface-muted, #f6f8fa);
    border: 1px solid var(--platform-color-border);
    border-radius: var(--platform-radius-md, 0.375rem);
    overflow: hidden;
}

.platform-file-preview__frame {
    width: 100%;
    height: 100%;
    min-height: min(60vh, 32rem);
    border: 0;
}

.platform-file-preview__image {
    /* Fit the picture within the stage without cropping or stretching. */
    object-fit: contain;
}

.platform-file-preview__none {
    margin: 0;
    color: var(--platform-color-text-muted, #57606a);
}

.platform-file-preview__none-text {
    margin: 0 0 var(--platform-space-sm, 0.5rem);
}

/* Empty state: a centered document glyph over a short message, shown whenever nothing is previewed (a
   fileless record on a detail page, or before the first upload on the editor). It lives inside
   `.platform-file-preview__stage`, so it inherits the pane's sensible min-height and never looks tiny or
   broken — the feature reads as present, just fileless. Token-driven → light↔dark is a token switch. */
.platform-file-preview__placeholder {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--platform-space-sm, 0.5rem);
    margin: 0;
    color: var(--platform-color-text-muted, #57606a);
}

/* The glyph: a document icon painted in the muted text colour via a CSS mask (same technique as the
   button glyphs, buttons.css §glyph) — no external asset, no markup in JS (coding-standards §4). */
.platform-file-preview__placeholder-icon {
    width: 3rem;
    height: 3rem;
    background-color: currentColor;
    opacity: 0.55;
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z'/%3E%3Cpolyline points='14 2 14 8 20 8'/%3E%3Cline x1='16' y1='13' x2='8' y2='13'/%3E%3Cline x1='16' y1='17' x2='8' y2='17'/%3E%3Cpolyline points='10 9 9 9 8 9'/%3E%3C/svg%3E") center / contain no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z'/%3E%3Cpolyline points='14 2 14 8 20 8'/%3E%3Cline x1='16' y1='13' x2='8' y2='13'/%3E%3Cline x1='16' y1='17' x2='8' y2='17'/%3E%3Cpolyline points='10 9 9 9 8 9'/%3E%3C/svg%3E") center / contain no-repeat;
}

.platform-file-preview__placeholder-text {
    margin: 0;
    max-width: 22rem;
}

/* ---- Full-height / sticky preview card (M-069) -------------------------- */
/* When a record HAS a previewable file, the caller adds `platform-file-preview-card` to the preview
   `<x-platform::card>`. The pane then fills the card and, from the large (col-lg) breakpoint up, the
   card becomes a sticky, viewport-tall column: the PDF renders large + readable and stays pinned while
   the (now longer) left column — details + files + access + history + comments — scrolls past. Below
   that breakpoint the columns stack, so the card keeps its natural height and the stage falls back to
   its bounded `min-height` (a tall-but-sane mobile preview, never the whole screen). The empty state
   deliberately does NOT get this class, so a fileless record keeps the tidy M-058 box instead of a
   giant empty one. Offsets/heights come from spacing tokens, so this themes for free (§4/§12). */
.platform-card.platform-file-preview-card {
    display: flex;
    flex-direction: column;
}

.platform-card.platform-file-preview-card .platform-card__body {
    display: flex;
    flex: 1 1 auto;
    min-height: 0;
    flex-direction: column;
}

/* Let the pane and its render stage grow to fill the card body: the file list keeps its natural
   height and the stage takes the rest. */
.platform-card.platform-file-preview-card .platform-file-preview {
    flex: 1 1 auto;
    min-height: 0;
}

@media (min-width: 62rem) {
    .platform-card.platform-file-preview-card {
        position: sticky;
        top: var(--platform-space-lg, 1.5rem);
        /* One viewport tall, less a symmetric top/bottom gap, so the preview stays fully in view while
           the left column scrolls past it. */
        height: calc(100vh - 2 * var(--platform-space-lg, 1.5rem));
    }

    /* In the height-constrained card the stage/embed and the Text tab's textarea fill exactly — drop the
       tall min-heights that only exist to keep a stacked/standalone preview usefully large. */
    .platform-card.platform-file-preview-card .platform-file-preview__stage,
    .platform-card.platform-file-preview-card .platform-file-preview__frame,
    .platform-card.platform-file-preview-card .platform-ocr__text {
        min-height: 0;
    }
}

/* ---- On-demand text extraction (M-064 OCR, M-071 PDF, M-072 Text tab) --- */
/* The Text tab's content: a toolbar at the TOP (Extract button + Copy control + "?" help disclosure) over a
   status line and a large, selectable/copyable result textarea that fills the tab. Also carries the
   `.platform-file-preview__panel` flex-column growth. Token-driven so it themes light↔dark for free;
   mobile-first (wraps, no fixed widths). */
.platform-ocr {
    display: flex;
    flex-direction: column;
    gap: var(--platform-space-sm, 0.5rem);
}

.platform-ocr__toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--platform-space-sm, 0.5rem);
}

/* The "?" help disclosure: a round badge (the <summary>) that toggles the local-only notice. Pure HTML
   (native <details>) so it works with no JS and on touch — tap to expand. Pushed to the far end of the
   toolbar so the Extract + Copy actions group together on the left. */
.platform-ocr__help {
    position: relative;
    margin-inline-start: auto;
}

.platform-ocr__help-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.5rem;
    height: 1.5rem;
    font-size: var(--platform-font-size-sm, 0.875rem);
    font-weight: 700;
    line-height: 1;
    color: var(--platform-color-text-muted, #57606a);
    background: var(--platform-color-surface-muted, #f6f8fa);
    border: 1px solid var(--platform-color-border);
    border-radius: 50%;
    cursor: help;
    list-style: none;
}

/* Hide the native disclosure triangle across engines so only the round badge shows. */
.platform-ocr__help-badge::-webkit-details-marker {
    display: none;
}

.platform-ocr__help-text {
    max-width: 28rem;
    margin: var(--platform-space-xs, 0.25rem) 0 0;
    padding: var(--platform-space-sm, 0.5rem);
    font-size: var(--platform-font-size-sm, 0.875rem);
    color: var(--platform-color-text-muted, #57606a);
    background: var(--platform-color-surface-muted, #f6f8fa);
    border: 1px solid var(--platform-color-border);
    border-radius: var(--platform-radius-md, 0.375rem);
}

.platform-ocr__status {
    margin: 0;
    font-size: var(--platform-font-size-sm, 0.875rem);
    color: var(--platform-color-text-muted, #57606a);
}

.platform-ocr__status--error {
    color: var(--platform-color-error-text, #c0392b);
}

/* Extraction progress bar (M-079, enlarged M-090): a token-styled track (accent surface) with an accent
   fill whose width is driven by the preview controller via the `--platform-ocr-progress` custom property
   (0–100%). The track is ~2.5× the original height with an inset groove shadow so it reads as a real gauge,
   and the fill carries a moving diagonal stripe + a soft accent glow while active. Both colours are accent
   tokens, so it themes light↔dark for free; full-width so it reacts to the tab/grid width. Only shown while
   an extraction is reporting progress (the controller un-hides it). */
.platform-ocr__progress {
    width: 100%;
    height: 1.25rem;
    overflow: hidden;
    background: var(--platform-color-accent-surface, #d1f2eb);
    border-radius: 999px;
    box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.12);
}

.platform-ocr__progress-fill {
    display: block;
    width: var(--platform-ocr-progress, 0%);
    height: 100%;
    background-color: var(--platform-color-accent, #16a085);
    /* A translucent diagonal stripe overlaid on the solid accent; animated to slide, giving a lively
       "working" barber-pole while an extraction runs. */
    background-image: linear-gradient(
        45deg,
        rgba(255, 255, 255, 0.28) 25%,
        transparent 25%,
        transparent 50%,
        rgba(255, 255, 255, 0.28) 50%,
        rgba(255, 255, 255, 0.28) 75%,
        transparent 75%,
        transparent
    );
    background-size: 1.25rem 1.25rem;
    border-radius: inherit;
    box-shadow: 0 0 0.5rem var(--platform-color-accent, #16a085);
    transition: width 0.2s ease;
    animation: platform-ocr-progress-stripes 1s linear infinite;
}

@keyframes platform-ocr-progress-stripes {
    from {
        background-position: 0 0;
    }

    to {
        background-position: 1.25rem 0;
    }
}

/* Reduced motion: no sliding stripe, no width easing — a calm, static accent fill (glow kept; it doesn't
   move). */
@media (prefers-reduced-motion: reduce) {
    .platform-ocr__progress-fill {
        background-image: none;
        transition: none;
        animation: none;
    }
}

/* The result: a readonly textarea so the text is natively selectable/copyable on every device. Like the PDF
   preview stage (M-069), it claims as much height as possible — a tall responsive min-height on a
   stacked/standalone layout — while flex-growing to fill the Text tab; the full-height preview card (M-069)
   drops the min-height so it fits the pinned column exactly. */
.platform-ocr__text {
    width: 100%;
    flex: 1 1 auto;
    min-height: min(60vh, 32rem);
    padding: var(--platform-space-sm, 0.5rem);
    font: inherit;
    color: var(--platform-color-text);
    background: var(--platform-color-surface, #fff);
    border: 1px solid var(--platform-color-border);
    border-radius: var(--platform-radius-md, 0.375rem);
    resize: vertical;
}

/* ---- Live uploader ------------------------------------------------------ */
/* The no-JS fallback's native file input, layered ON TOP of `.platform-form__input` to strip the
   border/padding a native file input shouldn't have — the textbook "shared base + local override" case. */
.platform-uploader__file {
    padding: var(--platform-space-xs, 0.25rem) 0;
    border: 0;
}

/* The editor's file control: a drop zone + a reorderable file table that also drives the preview pane. */
.platform-uploader {
    display: flex;
    flex-direction: column;
    gap: var(--platform-space-sm, 0.5rem);
    min-width: 0;
}

/* Drop zone: a dashed target with a browse button; tints to the accent while a drag hovers over it. */
.platform-uploader__dropzone {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--platform-space-sm, 0.5rem);
    padding: var(--platform-space-md, 1rem);
    text-align: center;
    background: var(--platform-color-surface-muted, #f6f8fa);
    border: 1px dashed var(--platform-color-border);
    border-radius: var(--platform-radius-md, 0.375rem);
}

.platform-uploader__dropzone--over {
    background: var(--platform-color-surface, #fff);
    border-color: var(--platform-color-accent, #2563eb);
}

.platform-uploader__dropzone-text {
    margin: 0;
    color: var(--platform-color-text-muted, #57606a);
}

/* Accepted-formats / size hint (M-091): a small, muted line living INSIDE the dropzone beneath the browse
   button — thematically part of the drop target, deliberately unobtrusive (xs type, muted colour). */
.platform-uploader__dropzone-hint {
    margin: 0;
    font-size: var(--platform-font-size-xs, 0.675rem);
    color: var(--platform-color-text-muted, #57606a);
}

/* File table: a plain list of rows, each a grid of [handle | name | size | progress | remove] that
   collapses gracefully. min-width:0 + overflow-wrap on the name keep long filenames from overflowing. */
.platform-uploader__list {
    display: flex;
    flex-direction: column;
    gap: var(--platform-space-xs, 0.25rem);
    margin: 0;
    padding: 0;
    list-style: none;
}

.platform-uploader__row {
    display: flex;
    align-items: center;
    gap: var(--platform-space-sm, 0.5rem);
    padding: var(--platform-space-xs, 0.25rem) var(--platform-space-sm, 0.5rem);
    background: var(--platform-color-surface-muted, #f6f8fa);
    border: 1px solid var(--platform-color-border);
    border-radius: var(--platform-radius-md, 0.375rem);
}

.platform-uploader__handle {
    color: var(--platform-color-text-muted, #57606a);
    cursor: grab;
    user-select: none;
}

/* The row body stacks the file line (name + size + progress) above its version-history disclosure, and
   grows to fill the row between the handle and the action buttons. */
.platform-uploader__body {
    display: flex;
    flex: 1 1 auto;
    min-width: 0;
    flex-direction: column;
    gap: var(--platform-space-xs, 0.25rem);
}

.platform-uploader__line {
    display: flex;
    align-items: center;
    gap: var(--platform-space-sm, 0.5rem);
}

/* The clickable filename that previews the file — a text button that grows to fill the line and wraps a
   long, unbreakable name instead of pushing the row wider than the card. */
.platform-uploader__name {
    flex: 1 1 auto;
    min-width: 0;
    padding: 0;
    font: inherit;
    color: var(--platform-color-text);
    text-align: left;
    background: none;
    border: 0;
    cursor: pointer;
    overflow-wrap: anywhere;
}

.platform-uploader__name:hover {
    color: var(--platform-color-accent, #2563eb);
}

/* The preview controller toggles this class on the selected row's name button (its `row` target). */
.platform-uploader__name--active {
    font-weight: 600;
    color: var(--platform-color-accent, #2563eb);
}

.platform-uploader__size {
    flex: 0 0 auto;
    color: var(--platform-color-text-muted, #57606a);
    white-space: nowrap;
}

.platform-uploader__progress {
    flex: 1 1 auto;
    min-width: 0;
}

/* While a row is uploading it is not yet a real, reorderable/removable file: show only the name + the
   progress bar. */
.platform-uploader__row--uploading .platform-uploader__handle,
.platform-uploader__row--uploading .platform-uploader__size,
.platform-uploader__row--uploading .platform-uploader__versions,
.platform-uploader__row--uploading .platform-uploader__download,
.platform-uploader__row--uploading .platform-uploader__replace,
.platform-uploader__row--uploading .platform-uploader__remove {
    display: none;
}

/* ---- Version history (M-011b) -------------------------------------------- */

/* A compact disclosure under a file — the `v{N} · history` summary opens the list of prior versions.
   Shared by the editor's file row and the read-only detail preview, so history reads the same on both. */
.platform-uploader__versions {
    font-size: 0.85em;
}

.platform-uploader__versions-summary {
    color: var(--platform-color-text-muted, #57606a);
    cursor: pointer;
}

.platform-uploader__versions-summary:hover {
    color: var(--platform-color-accent, #2563eb);
}

.platform-uploader__version-list {
    display: flex;
    flex-direction: column;
    gap: var(--platform-space-xs, 0.25rem);
    margin: var(--platform-space-xs, 0.25rem) 0 0;
    padding: 0 0 0 var(--platform-space-sm, 0.5rem);
    list-style: none;
}

.platform-uploader__version {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--platform-space-xs, 0.25rem) var(--platform-space-sm, 0.5rem);
}

.platform-uploader__version-download {
    display: inline-flex;
    gap: var(--platform-space-xs, 0.25rem);
    overflow-wrap: anywhere;
}

.platform-uploader__version-size,
.platform-uploader__version-meta {
    color: var(--platform-color-text-muted, #57606a);
}

/* Separate the "who" and "when" with a middot without putting punctuation in the markup. */
.platform-uploader__version-when::before {
    content: "·";
    margin: 0 var(--platform-space-xs, 0.25rem);
}

/* ---- Fullscreen overlay (M-259) ----------------------------------------- */
/* The preview controller RELOCATES this `<dialog>` to `<body>` on connect, so it is styled as a top-level
   element (not nested under `.platform-file-preview`): no shell/embed wrapper sits between it and the
   viewport to trap its fixed box (the M-259 containing-block bug). Opened with `showModal()` — the native
   top layer stacks it above everything, so it needs no z-index.

   Two scrim-bearing surfaces, both covering the TRUE viewport, so no undimmed border and no click can reach
   the page behind (the QA-round-4 finding):
     1. the `<dialog>` box itself — filled edge-to-edge via `inset: 0` with `width/height: auto` (NOT
        `100vw/100dvh`, which over-constrains against `inset` and, with a real scrollbar, resolves to a box
        offset from the viewport on some engines — the border-gap QA saw). `background-clip: border-box`
        (the default) paints the scrim UNDER the padding, so the internal frame padding never shows chrome.
     2. its modal `::backdrop` — which the spec guarantees covers the whole viewport in the top layer and
        intercepts every click OUTSIDE the dialog box. Scrimming it means even a sub-pixel gap is dimmed and
        click-safe, and a scrim-click there still targets the dialog (so dismiss still fires).
   The box model reset (`margin: 0; max-*: none; border: 0`) clears the UA `<dialog>` defaults (centred,
   content-sized, `max-width: calc(100% - …)`). Token-driven → themes light↔dark for free (§12). */
.platform-file-preview__overlay {
    position: fixed;
    inset: 0;
    width: auto;
    height: auto;
    max-width: none;
    max-height: none;
    margin: 0;
    padding: clamp(0.5rem, 2vw, var(--platform-space-lg, 1.5rem));
    border: 0;
    background: var(--platform-color-scrim, rgba(15, 23, 42, 0.45));
    box-sizing: border-box;
}

/* The modal backdrop: the second, always-full-viewport scrim surface (see above). */
.platform-file-preview__overlay::backdrop {
    background: var(--platform-color-scrim, rgba(15, 23, 42, 0.45));
}

/* A closed native `<dialog>` is `display: none`; only lay the flex box out while it is open. */
.platform-file-preview__overlay[open] {
    display: flex;
    align-items: center;
    justify-content: center;
}

/* The large copy of the active renderer (PDF `<embed>` or `<img>`): fills the scrim's content box, sitting
   on an opaque surface so a transparent PDF/image is always readable. */
.platform-file-preview__overlay-frame {
    flex: 1 1 auto;
    width: 100%;
    height: 100%;
    min-height: 0;
    border: 0;
    background: var(--platform-color-surface, #fff);
    border-radius: var(--platform-radius-md, 0.375rem);
}

.platform-file-preview__overlay-image {
    /* Fit the picture within the frame without cropping or stretching. */
    object-fit: contain;
}

/* Close (×) button, floated in the top-right corner of the scrim, above the frame. */
.platform-file-preview__overlay-close {
    position: absolute;
    top: var(--platform-space-md, 1rem);
    right: var(--platform-space-md, 1rem);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.5rem;
    height: 2.5rem;
    color: var(--platform-color-text);
    background: var(--platform-color-surface, #fff);
    border: 1px solid var(--platform-color-border);
    border-radius: 50%;
    box-shadow: var(--platform-shadow-md, 0 4px 14px rgba(44, 62, 80, 0.10));
    cursor: pointer;
}

.platform-file-preview__overlay-close:hover,
.platform-file-preview__overlay-close:focus-visible {
    color: var(--platform-color-accent, #2563eb);
    background: var(--platform-color-surface-muted, #f6f8fa);
}

/* The × glyph, painted with a CSS mask (no markup in JS, §4). */
.platform-file-preview__overlay-close-icon {
    width: 1.25rem;
    height: 1.25rem;
    background-color: currentColor;
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='18' y1='6' x2='6' y2='18'/%3E%3Cline x1='6' y1='6' x2='18' y2='18'/%3E%3C/svg%3E") center / contain no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='18' y1='6' x2='6' y2='18'/%3E%3Cline x1='6' y1='6' x2='18' y2='18'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* Scroll lock while the overlay is open (M-259): the app scrolls on the ROOT, not just <body>, so the
   controller toggles this on BOTH `<html>` and `<body>` to freeze the page behind the overlay. */
.platform-scroll-locked {
    overflow: hidden;
}
