/*
 * OnPoint custom file explorer — visual component.
 *
 * BEM root: .c-fe (file-explorer). Paired with app-file-explorer.js.
 * Consumes semantic tokens only (--color-*, --space-*, --radius-*); no
 * primitives reached directly per the token tier contract.
 *
 * Layout per Document Manager UX spec:
 *
 *   ┌─ .c-fe ──────────────────────────────────────────────┐
 *   │ Breadcrumb                                           │
 *   │ Search row (icon + input)                            │
 *   │ Toolbar: [Upload] [New folder] [↻]  spacer  | [🗑]   │
 *   │ Alert (optional)                                     │
 *   │ List header (desktop only): Name | Modified | Size   │
 *   │ List of rows                                         │
 *   └──────────────────────────────────────────────────────┘
 *
 * Single DOM serves desktop and mobile. The list header is hidden under
 * 768px; row grid reflows there so Modified/Size columns disappear and
 * a combined "size · 2h ago" metadata string sits at the right.
 *
 * Icon set: FontAwesome (already loaded via wwwroot/css/fa/*.css). No
 * Syncfusion e-icons classes.
 */
@layer components {
    /* Host wrapper div that the explorer is mounted into (see
       Explorer.cshtml). Forced to fill its parent's content box so the
       file manager isn't shrink-wrapped by an ancestor flex container
       that sets align-items: flex-start (the typical .app-section
       behaviour). Without this, the explorer collapses to its toolbar's
       intrinsic width on every viewport. */
    .c-fe-mount {
        width: 100%;
    }

    .c-fe {
        display: flex;
        flex-direction: column;
        width: 100%;
        height: 70vh;
        min-height: 480px;
        border: 1px solid var(--color-line);
        border-radius: var(--radius-sm, 4px);
        background: var(--color-surface);
        overflow: hidden;
        color: var(--color-ink);
    }

    /* -------- Breadcrumb -------- */
    /* Top of the component; wraps on narrow viewports. The current
       segment renders as a non-link <span>; ancestor segments are
       <button> elements styled as inline links. */
    .c-fe__breadcrumb {
        display: flex;
        align-items: center;
        /* Whitespace between elements is built from THREE sources —
           container gap, crumb side-padding, separator side-padding.
           Keeping just one source (here: the crumb's own padding) gives
           a tight, consistent rhythm without aggregating into wasted
           space. Gap stays 0; separator padding is zero; crumbs carry
           the breathing room. */
        gap: 0;
        /* Tight vertical padding — reference chrome, not a focal
           section. Horizontal padding kept modest (8px) so the first
           crumb starts close to the edge. */
        padding: 0.25rem var(--space-2, 0.5rem);
        border-bottom: 1px solid var(--color-line);
        background: var(--color-surface-alt);
        flex: 0 0 auto;
        flex-wrap: wrap;
        font-size: var(--font-size-sm, 0.875rem);
    }
    .c-fe__crumb {
        /* No vertical padding: line-height already gives the click
           target enough body for mouse + a usable finger target. The
           link's hover background becomes a text-mark rather than a
           pill, which fits the inline-link visual we want here.
           Horizontal padding is the SOLE source of inter-element
           whitespace (see container note above). */
        padding: 0 var(--space-1, 0.25rem);
        border-radius: var(--radius-sm, 4px);
        font-size: var(--font-size-sm, 0.875rem);
        line-height: 1.4;
    }
    .c-fe__crumb--link {
        background: transparent;
        border: none;
        cursor: pointer;
        color: var(--color-info, var(--color-accent, #2563eb));
        font-family: inherit;
    }
    .c-fe__crumb--link:hover,
    .c-fe__crumb--link:focus-visible {
        background: var(--color-surface);
        text-decoration: underline;
        outline: none;
    }
    .c-fe__crumb--current {
        color: var(--color-ink);
        font-weight: 500;
    }
    .c-fe__crumb-sep {
        color: var(--color-ink-mute);
        font-size: var(--font-size-sm, 0.875rem);
        /* No padding — the adjacent crumbs' horizontal padding already
           provides the whitespace on both sides of the separator. */
        padding: 0;
    }

    /* -------- Search row -------- */
    /* Same position on every viewport (under the breadcrumb, above the
       toolbar). The input is full-width on phone, capped at 480px on
       desktop. The magnifying-glass icon sits inside the input via
       absolute positioning. */
    .c-fe__search-row {
        padding: var(--space-3, 0.75rem) var(--space-4, 1rem);
        border-bottom: 1px solid var(--color-line);
        background: var(--color-surface);
        flex: 0 0 auto;
    }
    .c-fe__search-wrap {
        position: relative;
        max-width: 480px;
        width: 100%;
    }
    .c-fe__search-icon {
        position: absolute;
        left: var(--space-3, 0.75rem);
        top: 50%;
        transform: translateY(-50%);
        color: var(--color-ink-mute);
        font-size: 0.875rem;
        pointer-events: none;
    }
    .c-fe__search {
        width: 100%;
        /* Right padding reserves space for the clear (X) button so the
           caret never collides with it. Calc'd so the button sits in
           the same visual rhythm as the icon on the left. */
        padding: var(--space-2, 0.5rem) calc(var(--space-3, 0.75rem) + 1.25rem) var(--space-2, 0.5rem) calc(var(--space-3, 0.75rem) + 1.25rem);
        border: 1px solid var(--color-line);
        border-radius: var(--radius-sm, 4px);
        font-family: inherit;
        font-size: var(--font-size-sm, 0.875rem);
        background: var(--color-surface);
        color: var(--color-ink);
        box-sizing: border-box;
    }
    .c-fe__search:focus-visible {
        outline: 2px solid var(--color-info, #2563eb);
        outline-offset: 1px;
        border-color: var(--color-info, #2563eb);
    }
    .c-fe__search:disabled {
        opacity: 0.55;
        cursor: not-allowed;
        background: var(--color-surface-alt);
    }
    /* Clear (X) button — only visible when the input has content (the
       JS toggles the [hidden] attribute). Sits inside the input via
       absolute positioning, mirroring the search icon on the left. */
    .c-fe__search-clear {
        position: absolute;
        right: var(--space-2, 0.5rem);
        top: 50%;
        transform: translateY(-50%);
        background: transparent;
        border: none;
        padding: 0.25rem 0.4rem;
        line-height: 1;
        color: var(--color-ink-mute);
        cursor: pointer;
        border-radius: var(--radius-sm, 4px);
        font-size: 0.875rem;
    }
    .c-fe__search-clear:hover,
    .c-fe__search-clear:focus-visible {
        color: var(--color-ink);
        background: var(--color-surface-alt);
        outline: none;
    }

    /* -------- Toolbar -------- */
    /* On desktop: Upload, New folder, Refresh, then flex spacer, then
       divider + Trash. On mobile: spacer collapses (display: none) and
       the labeled buttons share `flex: 1`. Icon-only buttons stay
       fixed-width on both. */
    .c-fe__toolbar {
        display: flex;
        align-items: center;
        gap: var(--space-2, 0.5rem);
        padding: var(--space-3, 0.75rem) var(--space-4, 1rem);
        border-bottom: 1px solid var(--color-line);
        background: var(--color-surface);
        flex: 0 0 auto;
    }
    .c-fe__btn {
        display: inline-flex;
        align-items: center;
        gap: var(--space-2, 0.5rem);
        padding: var(--space-2, 0.5rem) var(--space-3, 0.75rem);
        border: 1px solid var(--color-line);
        background: var(--color-surface);
        border-radius: var(--radius-sm, 4px);
        cursor: pointer;
        font-family: inherit;
        font-size: var(--font-size-sm, 0.875rem);
        color: var(--color-ink);
        line-height: 1.2;
        white-space: nowrap;
    }
    .c-fe__btn:not(:disabled):hover {
        background: var(--color-surface-alt);
        border-color: var(--color-line-strong, var(--color-line));
    }
    .c-fe__btn:focus-visible {
        outline: 2px solid var(--color-info, #2563eb);
        outline-offset: 1px;
    }
    .c-fe__btn:disabled {
        opacity: 0.45;
        cursor: not-allowed;
    }
    .c-fe__btn i {
        font-size: 0.875rem;
        line-height: 1;
    }
    /* Primary: filled with accent. Used on Upload because it's the
       most-frequent action and the spec gives it the visual lead. */
    .c-fe__btn--primary {
        background: var(--color-accent, var(--color-info, #2563eb));
        border-color: var(--color-accent, var(--color-info, #2563eb));
        color: var(--color-on-accent, #ffffff);
    }
    .c-fe__btn--primary:not(:disabled):hover {
        background: var(--color-accent-strong, var(--color-info-deep, #1d4ed8));
        border-color: var(--color-accent-strong, var(--color-info-deep, #1d4ed8));
    }
    /* Icon-only: square button, no label. Tooltip via title attribute. */
    .c-fe__btn--icon {
        padding: var(--space-2, 0.5rem);
        width: 36px;
        height: 36px;
        justify-content: center;
        flex: 0 0 auto;
    }
    .c-fe__btn--icon i {
        font-size: 0.9375rem;
    }
    .c-fe__toolbar-spacer {
        flex: 1 1 auto;
        min-width: 0;
    }
    .c-fe__toolbar-divider {
        width: 1px;
        height: 24px;
        background: var(--color-line);
        flex: 0 0 1px;
    }

    /* -------- Alert banner (top-of-component feedback) -------- */
    .c-fe__alert {
        display: flex;
        align-items: center;
        gap: var(--space-2, 0.5rem);
        padding: var(--space-2, 0.5rem) var(--space-3, 0.75rem);
        border-bottom: 1px solid var(--color-line);
        font-size: var(--font-size-sm, 0.875rem);
        flex: 0 0 auto;
    }
    .c-fe__alert[hidden] {
        display: none;
    }
    .c-fe__alert--error {
        background: var(--color-error-soft, var(--color-danger-soft, #fef2f2));
        color: var(--color-error-deep, var(--color-danger-strong, #991b1b));
        border-bottom-color: var(--color-error, var(--color-danger, #b91c1c));
    }
    .c-fe__alert--info {
        background: var(--color-info-soft, #eff6ff);
        color: var(--color-info-deep, #1e3a8a);
        border-bottom-color: var(--color-info, #2563eb);
    }
    .c-fe__alert-icon {
        flex: 0 0 auto;
    }
    .c-fe__alert-text {
        flex: 1;
    }
    .c-fe__alert-close {
        flex: 0 0 auto;
        background: transparent;
        border: none;
        cursor: pointer;
        color: inherit;
        font-size: 0.875rem;
        line-height: 1;
        padding: var(--space-1, 0.25rem) var(--space-2, 0.5rem);
        opacity: 0.7;
        border-radius: var(--radius-sm, 4px);
    }
    .c-fe__alert-close:hover {
        opacity: 1;
        background: rgba(0, 0, 0, 0.06);
    }

    /* -------- Read-only notice -------- */
    /* Persistent (not dismissable) info bar shown when the current folder
       grants no write operations. Same horizontal-bar shape as the alert;
       info palette. [hidden] override needed because display:flex would
       otherwise beat the hidden attribute. */
    .c-fe__readonly {
        display: flex;
        align-items: center;
        gap: var(--space-2, 0.5rem);
        padding: var(--space-2, 0.5rem) var(--space-3, 0.75rem);
        border-bottom: 1px solid var(--color-info, #2563eb);
        background: var(--color-info-soft, #eff6ff);
        color: var(--color-info-deep, #1e3a8a);
        font-size: var(--font-size-sm, 0.875rem);
        flex: 0 0 auto;
    }
    .c-fe__readonly[hidden] {
        display: none;
    }
    .c-fe__readonly-icon {
        flex: 0 0 auto;
    }
    .c-fe__readonly-text {
        flex: 1;
    }

    /* -------- List header (desktop only) -------- */
    /* Mirror the row grid so column labels align. Hidden under 768px.
       Column rationale (icon → name → kebab → modified → size → filler):
         icon  32px   — fixed; matches row glyph slot.
         name  24rem  — FIXED at ~384px (~40 chars). Fixed (not auto-
                       sizing) so the kebab anchors at the same x on
                       every row AND every folder visit. Long names
                       truncate via overflow:hidden + ellipsis; the
                       row's title= preserves the full name on hover.
         kebab 32px   — fixed; consistent action-button slot.
         modified 140px — fixed; sits immediately after the kebab so
                          metadata stays grouped with the row content
                          rather than orphaned at the far right edge.
         size 100px     — fixed.
         filler 1fr   — TRAILING flex track. Absorbs whatever horizontal
                       space is left on wider containers without
                       distributing it between the content columns —
                       so wide monitors get empty space on the RIGHT
                       of the metadata, not gaps between the columns.
    */
    .c-fe__list-header {
        display: grid;
        /* Name is minmax(12rem, 24rem) so it shrinks under pressure
           instead of forcing the grid to overflow. Title / type are
           also bounded by minmax so they collapse before name does.
           Description stays the 1fr filler (shrinks to 0 first). */
        grid-template-columns: 32px minmax(12rem, 24rem) 32px minmax(0, 12rem) minmax(0, 10rem) minmax(0, 1fr) 7rem 5rem;
        align-items: center;
        gap: var(--space-2, 0.5rem);
        padding: var(--space-2, 0.5rem) var(--space-4, 1rem);
        background: var(--color-surface-alt);
        border-bottom: 1px solid var(--color-line);
        font-size: var(--font-size-xs, 0.75rem);
        text-transform: uppercase;
        letter-spacing: 0.04em;
        color: var(--color-ink-soft);
        font-weight: 600;
        flex: 0 0 auto;
        position: sticky;
        top: 0;
        z-index: 1;
    }
    /* Header cell text clipping. Without this, a column whose track
       has shrunk (e.g. Description's 1fr at 0 under pressure) lets
       its label bleed into the next track visually — so "Description"
       would overlap "Modified" at intermediate widths. Mirrors the
       same overflow rules the row cells already carry. */
    .c-fe__list-header > span {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    /* -------- List + rows -------- */
    .c-fe__list {
        flex: 1 1 auto;
        overflow-y: auto;
        background: var(--color-surface);
    }
    .c-fe__banner {
        padding: var(--space-2, 0.5rem) var(--space-4, 1rem);
        background: var(--color-info-soft, #eff6ff);
        border-bottom: 1px solid var(--color-line);
        font-size: var(--font-size-sm, 0.875rem);
        color: var(--color-info-deep, #1e3a8a);
    }
    .c-fe__row {
        display: grid;
        /* Tracks match .c-fe__list-header exactly so rows and the
           header stay in lockstep at every width. Name + title + type
           use minmax bounds so they shrink under pressure rather than
           forcing the grid to overflow; description is 1fr (shrinks
           to 0 first); modified + size stay fixed at the right. */
        grid-template-columns: 32px minmax(12rem, 24rem) 32px minmax(0, 12rem) minmax(0, 10rem) minmax(0, 1fr) 7rem 5rem;
        align-items: center;
        gap: var(--space-2, 0.5rem);
        padding: var(--space-2, 0.5rem) var(--space-4, 1rem);
        border-bottom: 1px solid var(--color-line);
        font-size: var(--font-size-sm, 0.875rem);
        cursor: default;
        /* The combined metadata span (.c-fe__row-meta) is hidden on
           desktop; the dedicated modified + size cells take over. */
    }
    .c-fe__row:hover {
        background: var(--color-surface-alt);
    }
    .c-fe__row-icon {
        /* position:relative so the verified-badge absolute-positions
           relative to the icon, not the whole row. */
        position: relative;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        font-size: 1rem;
        line-height: 1;
    }
    .c-fe__row-icon--folder {
        color: var(--color-info, #2563eb);
    }
    .c-fe__row-icon--file {
        color: var(--color-ink-soft);
    }
    /* Verified-status badge overlaid on the top-right of the file
       icon. Presence-only signal: rendered only when the document is
       verified (green check). Unverified docs show no badge — clean
       icon as the default state. Sits inside the icon's bounding box
       so it never pushes the row layout. */
    .c-fe__row-verified-badge {
        position: absolute;
        top: -2px;
        right: -4px;
        font-size: 0.625rem;
        line-height: 1;
        color: var(--color-success, #16a34a);
        background: var(--color-surface);
        border-radius: 999px;
        padding: 0;
    }
    .c-fe__row-name {
        font-weight: 500;
        color: var(--color-ink);
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        cursor: pointer;
    }
    .c-fe__row--folder .c-fe__row-name {
        color: var(--color-info, #2563eb);
    }
    .c-fe__row-kebab {
        width: 32px;
        height: 32px;
        padding: 0;
        background: transparent;
        border: none;
        border-radius: var(--radius-sm, 4px);
        cursor: pointer;
        color: var(--color-ink-mute);
        display: inline-flex;
        align-items: center;
        justify-content: center;
        font-size: 0.875rem;
        line-height: 1;
    }
    .c-fe__row-kebab:not(:disabled):hover {
        background: var(--color-surface);
        color: var(--color-ink);
    }
    .c-fe__row-kebab:focus-visible {
        outline: 2px solid var(--color-info, #2563eb);
        outline-offset: 1px;
    }
    .c-fe__row-kebab:disabled {
        cursor: not-allowed;
        opacity: 0.45;
    }
    .c-fe__row-modified,
    .c-fe__row-size,
    .c-fe__row-type,
    .c-fe__row-title,
    .c-fe__row-description {
        color: var(--color-ink-mute);
        font-size: var(--font-size-sm, 0.875rem);
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }
    .c-fe__row-size {
        text-align: right;
    }
    /* Combined metadata cell — visible only on mobile (see media query
       below). Carries "size · 2h ago" for files, "2h ago" for folders. */
    .c-fe__row-meta {
        display: none;
        color: var(--color-ink-mute);
        font-size: var(--font-size-sm, 0.875rem);
        white-space: nowrap;
        text-align: right;
    }

    /* -------- Empty / loading -------- */
    .c-fe__loading,
    .c-fe__empty {
        padding: var(--space-6, 1.5rem);
        text-align: center;
        color: var(--color-ink-mute);
        font-size: var(--font-size-sm, 0.875rem);
    }

    /* -------- Responsive: progressive disclosure -------- */
    /* Drop description first (it's the 1fr filler — empty often
       anyway). Then drop type. Then drop title. By the time we hit
       the phone breakpoint below, only icon / name / kebab / modified
       / size remain — and that final collapse swaps to a one-line
       row layout. Each step keeps the visible columns at usable
       width without the grid overflowing the container. */

    /* ~1024px and narrower — description column out. */
    @media (max-width: 1023.98px) {
        .c-fe__list-header {
            grid-template-columns: 32px minmax(12rem, 24rem) 32px minmax(0, 12rem) minmax(0, 10rem) 7rem 5rem;
        }
        .c-fe__row {
            grid-template-columns: 32px minmax(12rem, 24rem) 32px minmax(0, 12rem) minmax(0, 10rem) 7rem 5rem;
        }
        .c-fe__col-description,
        .c-fe__row-description {
            display: none;
        }
    }

    /* ~900px and narrower — also drop type. */
    @media (max-width: 899.98px) {
        .c-fe__list-header {
            grid-template-columns: 32px minmax(10rem, 24rem) 32px minmax(0, 12rem) 7rem 5rem;
        }
        .c-fe__row {
            grid-template-columns: 32px minmax(10rem, 24rem) 32px minmax(0, 12rem) 7rem 5rem;
        }
        .c-fe__col-type,
        .c-fe__row-type {
            display: none;
        }
    }

    /* Phone (<768px) — collapse to single-line layout. */
    /* List header hides. Row grid collapses to icon / name / kebab /
       meta. The combined metadata cell takes over from the dedicated
       modified + size columns. Toolbar labeled buttons share width;
       spacer hides because the divider does the visual separation. */
    @media (max-width: 767.98px) {
        .c-fe__list-header {
            display: none;
        }
        .c-fe__row {
            grid-template-columns: 28px minmax(0, 1fr) 32px auto;
            padding: var(--space-3, 0.75rem);
            gap: var(--space-2, 0.5rem);
        }
        .c-fe__row-modified,
        .c-fe__row-size,
        .c-fe__row-type,
        .c-fe__row-title,
        .c-fe__row-description {
            display: none;
        }
        .c-fe__row-meta {
            display: inline;
        }

        .c-fe__toolbar {
            padding: var(--space-2, 0.5rem) var(--space-3, 0.75rem);
        }
        .c-fe__toolbar-spacer {
            display: none;
        }
        /* Labeled buttons (Upload, New folder) share remaining width.
           Icon buttons stay fixed-size so they don't blow out. */
        .c-fe__btn:not(.c-fe__btn--icon) {
            flex: 1 1 0;
            justify-content: center;
        }
    }

    /* -------- Context menu (row kebab popup) --------
     * Singleton <div role="menu"> rendered by app-file-explorer.js for
     * the document context menu. Positioned absolutely on document.body
     * so it can escape ancestor overflow:hidden. Standard popup-menu
     * idiom: icon + label per row, divider for the destructive group,
     * danger styling on Delete. */
    .c-fe-menu {
        position: absolute;
        z-index: 1000;
        min-width: 14rem;
        max-width: 22rem;
        padding: var(--space-1, 0.25rem) 0;
        background: var(--color-surface, #ffffff);
        color: var(--color-ink, #0f172a);
        border: 1px solid var(--color-line, #e2e8f0);
        border-radius: var(--radius-sm, 4px);
        box-shadow: 0 10px 24px -8px rgba(15, 23, 42, 0.25),
                    0 4px 8px rgba(15, 23, 42, 0.08);
        font-size: var(--font-size-sm, 0.875rem);
        line-height: 1.3;
    }
    .c-fe-menu[hidden] {
        display: none;
    }
    .c-fe-menu__item {
        display: flex;
        align-items: center;
        gap: var(--space-3, 0.75rem);
        width: 100%;
        padding: var(--space-2, 0.5rem) var(--space-3, 0.75rem);
        background: transparent;
        border: none;
        cursor: pointer;
        color: var(--color-ink, #0f172a);
        text-align: left;
        font-family: inherit;
        font-size: inherit;
        line-height: inherit;
    }
    .c-fe-menu__item:not(:disabled):hover,
    .c-fe-menu__item:not(:disabled):focus-visible {
        background: var(--color-surface-alt, #f1f5f9);
        outline: none;
    }
    .c-fe-menu__item--disabled,
    .c-fe-menu__item:disabled {
        opacity: 0.45;
        cursor: not-allowed;
    }
    .c-fe-menu__item--danger {
        color: var(--color-danger, #b91c1c);
    }
    .c-fe-menu__item--danger:not(:disabled):hover,
    .c-fe-menu__item--danger:not(:disabled):focus-visible {
        background: var(--color-danger-soft, #fef2f2);
    }
    .c-fe-menu__icon {
        flex: 0 0 auto;
        width: 1rem;
        text-align: center;
        font-size: 0.875rem;
        color: var(--color-ink-mute, #94a3b8);
    }
    .c-fe-menu__item--danger .c-fe-menu__icon {
        color: var(--color-danger, #b91c1c);
    }
    .c-fe-menu__label {
        flex: 1 1 auto;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    .c-fe-menu__divider {
        height: 1px;
        margin: var(--space-1, 0.25rem) 0;
        background: var(--color-line, #e2e8f0);
    }

    /* -------- Move picker dialog --------
     * Drill-down folder picker for the Move action. Mirrors the main
     * file manager's UX (breadcrumb at top, folder rows below) so
     * users don't need to learn a new interaction. Reuses existing
     * .c-fe__crumb / .c-fe__loading / .c-fe__empty rules where it
     * makes sense; row markup is its own thin class because we don't
     * need the kebab / modified / size columns. */
    .c-fe-move-picker {
        padding: 0;
        border: none;
        background: transparent;
        color: inherit;
        max-width: min(36rem, calc(100vw - 2rem));
        width: 100%;
    }
    .c-fe-move-picker::backdrop {
        background: rgba(15, 23, 42, 0.55);
        backdrop-filter: blur(2px);
        -webkit-backdrop-filter: blur(2px);
    }
    .c-fe-move-picker__panel {
        background: var(--color-surface, #ffffff);
        color: var(--color-ink, #0f172a);
        border-radius: var(--radius-lg, 0.75rem);
        box-shadow: 0 24px 48px -12px rgba(15, 23, 42, 0.35),
                    0 4px 10px rgba(15, 23, 42, 0.08);
        display: flex;
        flex-direction: column;
        max-height: calc(100vh - 4rem);
        overflow: hidden;
    }
    .c-fe-move-picker__header {
        padding: var(--space-5, 1.25rem) var(--space-6, 1.5rem) var(--space-2, 0.5rem);
        border-bottom: 1px solid var(--color-line, #e2e8f0);
    }
    .c-fe-move-picker__title {
        margin: 0;
        font-family: var(--font-family-heading, var(--font-family-base, system-ui, sans-serif));
        font-size: var(--font-size-lg, 1.125rem);
        font-weight: var(--font-weight-bold, 600);
        line-height: 1.3;
        color: var(--color-ink, #0f172a);
    }
    .c-fe-move-picker__from {
        margin: var(--space-1, 0.25rem) 0 0;
        font-size: var(--font-size-sm, 0.875rem);
        color: var(--color-ink-soft, #475569);
    }
    .c-fe-move-picker__breadcrumb {
        display: flex;
        align-items: center;
        gap: 0;
        padding: var(--space-2, 0.5rem) var(--space-6, 1.5rem);
        background: var(--color-surface-alt, #f8fafc);
        border-bottom: 1px solid var(--color-line, #e2e8f0);
        flex-wrap: wrap;
        font-size: var(--font-size-sm, 0.875rem);
    }
    .c-fe-move-picker__list {
        flex: 1 1 auto;
        overflow-y: auto;
        min-height: 12rem;
    }
    .c-fe-move-picker__row {
        display: flex;
        align-items: center;
        gap: var(--space-2, 0.5rem);
        padding: var(--space-2, 0.5rem) var(--space-6, 1.5rem);
        border-bottom: 1px solid var(--color-line, #e2e8f0);
        cursor: pointer;
        font-size: var(--font-size-sm, 0.875rem);
        color: var(--color-ink, #0f172a);
    }
    .c-fe-move-picker__row:hover,
    .c-fe-move-picker__row:focus-visible {
        background: var(--color-surface-alt, #f1f5f9);
        outline: none;
    }
    .c-fe-move-picker__row--disabled {
        cursor: not-allowed;
        opacity: 0.5;
    }
    .c-fe-move-picker__row--disabled:hover {
        background: transparent;
    }
    .c-fe-move-picker__row-icon {
        flex: 0 0 auto;
        color: var(--color-info, #2563eb);
        font-size: 1rem;
        line-height: 1;
    }
    .c-fe-move-picker__row-name {
        flex: 1 1 auto;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    .c-fe-move-picker__row-note {
        flex: 0 0 auto;
        font-size: var(--font-size-xs, 0.75rem);
        color: var(--color-ink-mute, #94a3b8);
        font-style: italic;
    }
    .c-fe-move-picker__footer {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: var(--space-3, 0.75rem);
        flex-wrap: wrap;
        padding: var(--space-3, 0.75rem) var(--space-6, 1.5rem) var(--space-4, 1rem);
        border-top: 1px solid var(--color-line, #e2e8f0);
        background: var(--color-surface-alt, #f8fafc);
    }
    .c-fe-move-picker__selected {
        font-size: var(--font-size-sm, 0.875rem);
        color: var(--color-ink-soft, #475569);
        flex: 1 1 12rem;
        min-width: 0;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    .c-fe-move-picker__actions {
        display: flex;
        gap: var(--space-2, 0.5rem);
    }

    /* Phone: stack footer like the upload prep dialog. */
    @media (max-width: 480px) {
        .c-fe-move-picker__footer {
            flex-direction: column;
            align-items: stretch;
        }
        .c-fe-move-picker__actions {
            justify-content: flex-end;
        }
    }

    /* -------- Upload prep dialog --------
     * Per-file metadata form shown BEFORE the upload starts. Collects
     * the same fields the legacy add-document view collects (Type /
     * Title / Description) plus a batch-level Overwrite flag. On
     * submit, transitions to the upload-progress dialog. Visually
     * parallel to .c-fe-upload so the two feel like one component in
     * two stages. */
    .c-fe-upload-prep {
        padding: 0;
        border: none;
        background: transparent;
        color: inherit;
        max-width: min(44rem, calc(100vw - 2rem));
        width: 100%;
    }
    .c-fe-upload-prep::backdrop {
        background: rgba(15, 23, 42, 0.55);
        backdrop-filter: blur(2px);
        -webkit-backdrop-filter: blur(2px);
    }
    .c-fe-upload-prep__panel {
        background: var(--color-surface, #ffffff);
        color: var(--color-ink, #0f172a);
        border-radius: var(--radius-lg, 0.75rem);
        box-shadow: 0 24px 48px -12px rgba(15, 23, 42, 0.35),
                    0 4px 10px rgba(15, 23, 42, 0.08);
        display: flex;
        flex-direction: column;
        max-height: calc(100vh - 4rem);
        overflow: hidden;
    }
    .c-fe-upload-prep__header {
        padding: var(--space-5, 1.25rem) var(--space-6, 1.5rem) var(--space-3, 0.75rem);
        border-bottom: 1px solid var(--color-line, #e2e8f0);
    }
    .c-fe-upload-prep__title {
        margin: 0;
        font-family: var(--font-family-heading, var(--font-family-base, system-ui, sans-serif));
        font-size: var(--font-size-lg, 1.125rem);
        font-weight: var(--font-weight-bold, 600);
        line-height: 1.3;
        color: var(--color-ink, #0f172a);
    }
    .c-fe-upload-prep__subtitle {
        margin: var(--space-1, 0.25rem) 0 0;
        font-size: var(--font-size-sm, 0.875rem);
        color: var(--color-ink-soft, #475569);
    }
    .c-fe-upload-prep__list {
        list-style: none;
        margin: 0;
        padding: var(--space-2, 0.5rem) var(--space-6, 1.5rem);
        overflow-y: auto;
        flex: 1 1 auto;
        min-height: 0;
    }
    .c-fe-upload-prep__item {
        padding: var(--space-4, 1rem) 0;
        border-bottom: 1px solid var(--color-line, #e2e8f0);
    }
    .c-fe-upload-prep__item:last-child {
        border-bottom: none;
    }
    .c-fe-upload-prep__filename {
        display: flex;
        align-items: center;
        gap: var(--space-2, 0.5rem);
        font-weight: 500;
        font-size: var(--font-size-sm, 0.875rem);
        color: var(--color-ink, #0f172a);
        margin-bottom: var(--space-2, 0.5rem);
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    .c-fe-upload-prep__filename i {
        flex: 0 0 auto;
        color: var(--color-ink-soft, #475569);
    }
    .c-fe-upload-prep__fields {
        display: grid;
        grid-template-columns: 14rem 1fr 1fr;
        gap: var(--space-3, 0.75rem);
    }
    .c-fe-upload-prep__field {
        display: flex;
        flex-direction: column;
        gap: var(--space-1, 0.25rem);
        min-width: 0;
    }
    .c-fe-upload-prep__field-label {
        font-size: var(--font-size-xs, 0.75rem);
        color: var(--color-ink-soft, #475569);
        font-weight: 500;
    }
    .c-fe-upload-prep__field-input,
    .c-fe-upload-prep__field-select {
        width: 100%;
        padding: var(--space-2, 0.5rem) var(--space-3, 0.75rem);
        border: 1px solid var(--color-line, #e2e8f0);
        border-radius: var(--radius-sm, 0.375rem);
        font-family: inherit;
        font-size: var(--font-size-sm, 0.875rem);
        line-height: 1.3;
        color: var(--color-ink, #0f172a);
        background: var(--color-surface, #ffffff);
        box-sizing: border-box;
    }
    .c-fe-upload-prep__field-input:focus-visible,
    .c-fe-upload-prep__field-select:focus-visible {
        outline: 2px solid var(--color-info, #2563eb);
        outline-offset: 1px;
        border-color: var(--color-info, #2563eb);
    }
    .c-fe-upload-prep__footer {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: var(--space-3, 0.75rem);
        flex-wrap: wrap;
        padding: var(--space-3, 0.75rem) var(--space-6, 1.5rem) var(--space-4, 1rem);
        border-top: 1px solid var(--color-line, #e2e8f0);
        background: var(--color-surface-alt, #f8fafc);
    }
    .c-fe-upload-prep__overwrite {
        display: inline-flex;
        align-items: center;
        gap: var(--space-2, 0.5rem);
        font-size: var(--font-size-sm, 0.875rem);
        color: var(--color-ink-soft, #475569);
        cursor: pointer;
    }
    .c-fe-upload-prep__actions {
        display: flex;
        gap: var(--space-2, 0.5rem);
    }

    /* Small viewports: stack metadata fields, full-width actions. */
    @media (max-width: 640px) {
        .c-fe-upload-prep__fields {
            grid-template-columns: 1fr;
        }
        .c-fe-upload-prep__footer {
            flex-direction: column;
            align-items: stretch;
        }
        .c-fe-upload-prep__actions {
            justify-content: flex-end;
        }
    }

    /* -------- Upload dialog --------
     * Native <dialog> rendered by app-file-explorer.js for the upload
     * progress UI. Lives outside the .c-fe subtree so showModal()'s
     * backdrop covers the whole viewport, not just the explorer pane.
     * Visual style tracks .c-confirm (token fallbacks included) so hosts
     * that haven't yet bound the full token set still get a readable
     * dialog. */
    .c-fe-upload {
        padding: 0;
        border: none;
        background: transparent;
        color: inherit;
        max-width: min(36rem, calc(100vw - 2rem));
        width: 100%;
    }
    .c-fe-upload::backdrop {
        background: rgba(15, 23, 42, 0.55);
        backdrop-filter: blur(2px);
        -webkit-backdrop-filter: blur(2px);
    }
    .c-fe-upload__panel {
        background: var(--color-surface, #ffffff);
        color: var(--color-ink, #0f172a);
        border-radius: var(--radius-lg, 0.75rem);
        box-shadow: 0 24px 48px -12px rgba(15, 23, 42, 0.35),
                    0 4px 10px rgba(15, 23, 42, 0.08);
        display: flex;
        flex-direction: column;
        max-height: calc(100vh - 4rem);
        overflow: hidden;
    }
    .c-fe-upload__header {
        padding: var(--space-5, 1.25rem) var(--space-6, 1.5rem) var(--space-3, 0.75rem);
        border-bottom: 1px solid var(--color-line, #e2e8f0);
    }
    .c-fe-upload__title {
        margin: 0;
        font-family: var(--font-family-heading, var(--font-family-base, system-ui, sans-serif));
        font-size: var(--font-size-lg, 1.125rem);
        font-weight: var(--font-weight-bold, 600);
        line-height: 1.3;
        color: var(--color-ink, #0f172a);
    }
    .c-fe-upload__subtitle {
        margin: var(--space-1, 0.25rem) 0 0;
        font-size: var(--font-size-sm, 0.875rem);
        color: var(--color-ink-soft, #475569);
    }
    .c-fe-upload__list {
        list-style: none;
        margin: 0;
        padding: var(--space-2, 0.5rem) var(--space-6, 1.5rem);
        overflow-y: auto;
        flex: 1 1 auto;
        min-height: 0;
    }
    .c-fe-upload__item {
        padding: var(--space-3, 0.75rem) 0;
        border-bottom: 1px solid var(--color-line, #e2e8f0);
    }
    .c-fe-upload__item:last-child {
        border-bottom: none;
    }
    .c-fe-upload__row {
        display: flex;
        justify-content: space-between;
        align-items: baseline;
        gap: var(--space-3, 0.75rem);
        font-size: var(--font-size-sm, 0.875rem);
    }
    .c-fe-upload__name {
        flex: 1 1 auto;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        color: var(--color-ink, #0f172a);
    }
    .c-fe-upload__status {
        flex: 0 0 auto;
        color: var(--color-ink-soft, #475569);
        font-variant-numeric: tabular-nums;
    }
    .c-fe-upload__bar {
        margin-top: var(--space-2, 0.5rem);
        height: 4px;
        background: var(--color-surface-alt, #f1f5f9);
        border-radius: 2px;
        overflow: hidden;
    }
    .c-fe-upload__bar-fill {
        height: 100%;
        width: 0%;
        background: var(--color-info, #2563eb);
        transition: width 120ms linear;
    }
    .c-fe-upload__item--done .c-fe-upload__bar-fill {
        background: var(--color-success, #16a34a);
    }
    .c-fe-upload__item--failed .c-fe-upload__bar-fill {
        background: var(--color-danger, #b91c1c);
    }
    .c-fe-upload__item--canceled .c-fe-upload__bar-fill {
        background: var(--color-ink-mute, #94a3b8);
    }
    .c-fe-upload__error {
        margin-top: var(--space-1, 0.25rem);
        font-size: var(--font-size-xs, 0.75rem);
        color: var(--color-danger, #b91c1c);
        word-break: break-word;
    }
    .c-fe-upload__footer {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: var(--space-3, 0.75rem);
        padding: var(--space-3, 0.75rem) var(--space-6, 1.5rem) var(--space-4, 1rem);
        border-top: 1px solid var(--color-line, #e2e8f0);
        background: var(--color-surface-alt, #f8fafc);
    }
    .c-fe-upload__summary {
        font-size: var(--font-size-sm, 0.875rem);
        color: var(--color-ink-soft, #475569);
    }
    .c-fe-upload__actions {
        display: flex;
        gap: var(--space-2, 0.5rem);
    }

    /* Small viewports: stack so neither the summary nor the action
       button gets squashed. */
    @media (max-width: 480px) {
        .c-fe-upload__footer {
            flex-direction: column;
            align-items: stretch;
        }
        .c-fe-upload__actions {
            justify-content: flex-end;
        }
    }
}
