/* ==========================================================================
   BSI UI - foundation stylesheet
   The Brussels School of International Studies design system.
   White surfaces, burgundy #9B0C23 accent, PT Serif, light weights,
   flat 4px corners on controls, soft 8px corners on cards and modals.
   Copy this file as-is into a new project and link it, then assemble
   screens with the documented classes. Pairs with icons.js for pictograms.
   ========================================================================== */

/* ─── Typeface ───────────────────────────────────────────────────────────
   PT Serif is served from this site, not from Google. Loading it from
   fonts.googleapis.com sends every visitor's IP address to Google before
   anything is displayed and without any consent, which German courts have
   already ruled against; self-hosting also removes a third-party DNS lookup
   and TLS handshake from the first paint.

   The two files are not in the repository. Fetch them once and drop them in
   fonts/ (they are around 40 kB each):

     https://fonts.gstatic.com/s/ptserif/v19/EJRVQgYoZZY2vCFuvAFYzr8.woff2  -> fonts/pt-serif-400.woff2
     https://fonts.gstatic.com/s/ptserif/v19/EJRSQgYoZZY2vCFuvAnt66qcVys.woff2 -> fonts/pt-serif-700.woff2

   Until they are there the site falls back to Georgia, which is what
   font-display: swap shows during the load anyway. */

@font-face {
    font-family: 'PT Serif';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('fonts/pt-serif-400.woff2') format('woff2');
    /* Latin and Latin Extended: enough for French, and the browser skips the
       download entirely on a page that needs no character from these ranges. */
    unicode-range: U+0000-00FF, U+0100-024F, U+0259, U+1E00-1EFF, U+2000-206F,
                   U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: 'PT Serif';
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url('fonts/pt-serif-700.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0100-024F, U+0259, U+1E00-1EFF, U+2000-206F,
                   U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
    /* Accent (burgundy). Used for primary actions, active items, links, focus. */
    --red:          #9B0C23;
    --red-dark:     #7a0a1c;   /* hover / pressed */
    --red-light:    #fef2f2;   /* faint tint background */
    --red-border:   #fecaca;   /* tint border */

    /* Text */
    --text:         #454545;   /* body and headings */
    --text-muted:   #787878;   /* secondary text, captions */
    --text-light:   #9b9b9b;   /* hints, disabled */

    /* Surfaces and lines */
    --surface:      #ffffff;   /* page and card background */
    --bg:           #fafafa;   /* inputs, sidebar, table headers, hovered rows */
    --border:       #e0e0e0;   /* card borders */
    --border-soft:  #e8e8e8;   /* table rows, sidebar edges */
    --border-input: #d0d0d0;   /* form field borders */
    --divider:      #f0f0f0;   /* 2px header/tab dividers */

    /* Status */
    --success-bg:   #f0fdf4;
    --success-text: #166534;
    --success-bdr:  #bbf7d0;
    --danger:       #dc3545;
    --danger-dark:  #c82333;

    /* Radii - flat controls, soft cards */
    --radius:       4px;   /* buttons, inputs, badges */
    --radius-card:  6px;   /* content cards */
    --radius-lg:    8px;   /* modals, login, large surfaces */
    --radius-pill:  20px;  /* status pills, counts */

    /* Shadows - soft and low */
    --shadow-sm:    0 2px 10px rgba(0, 0, 0, .04);
    --shadow:       0 2px 10px rgba(0, 0, 0, .08);
    --shadow-md:    0 4px 20px rgba(0, 0, 0, .10);
    --shadow-lg:    0 10px 40px rgba(0, 0, 0, .15);

    /* Type and metrics. PT Serif is loaded by the page (Google Fonts with
       font-display: swap), Arial covers the moment before it arrives. */
    --font:         'PT Serif', Georgia, 'Times New Roman', Arial, serif;
    --control-h:    42px;      /* shared height of inputs and buttons */
    --sidebar-width: 300px;    /* Layout A default; widen for a tree (dataroom uses 450px) */
    --sidebar-collapsed: 60px;
}

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: var(--font);
    background: var(--surface);
    color: var(--text);
    font-size: 14px;
    line-height: 1.6;
    min-height: 100vh;
}

a {
    color: var(--red);
    text-decoration: none;
}

a:hover {
    color: var(--red-dark);
    text-decoration: underline;
}

/* Headings are light (font-weight: normal) - the BSI signature.
   Meaning is carried by size and the burgundy accent, never by bold weight. */
h1, h2, h3, h4 {
    color: var(--text);
    font-weight: normal;
    line-height: 1.3;
}

h1 { font-size: 24px; letter-spacing: -0.5px; }
h2 { font-size: 22px; }
h3 { font-size: 18px; }
h4 { font-size: 15px; }

/* ─── Buttons ────────────────────────────────────────────────────────────
   Every button shares the 42px control height and 4px radius, so it lines
   up with the fields beside it. Primary is a solid burgundy fill; secondary
   is an outline that inverts on hover; danger is red. */

.btn {
    height: var(--control-h);
    padding: 0 24px;
    background: var(--red);
    color: #ffffff;
    border: none;
    border-radius: var(--radius);
    font-family: var(--font);
    font-size: 14px;
    font-weight: normal;
    letter-spacing: 0.5px;
    cursor: pointer;
    transition: all 0.3s;
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
}

.btn:hover {
    background: var(--red-dark);
    color: #ffffff;
    text-decoration: none;
}

.btn-secondary {
    background: transparent;
    color: var(--red);
    border: 1px solid var(--red);
}

.btn-secondary:hover {
    background: var(--red);
    color: #ffffff;
}

.btn-danger {
    background: var(--danger);
    color: #ffffff;
}

.btn-danger:hover {
    background: var(--danger-dark);
}

.btn-full {
    width: 100%;
}

.btn-small {
    height: auto;
    padding: 8px 16px;
    font-size: 13px;
}

.btn svg {
    display: inline-block;
    vertical-align: -3px;
}

/* Square icon button for toolbars and table rows: outlined, neutral,
   turns burgundy on hover. */
.btn-icon {
    height: 34px;
    min-width: 34px;
    padding: 0 8px;
    background: transparent;
    color: var(--text-muted);
    border: 1px solid var(--border-input);
    border-radius: var(--radius);
    cursor: pointer;
    transition: all 0.3s;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.btn-icon:hover {
    color: var(--red);
    border-color: var(--red);
}

.btn-icon svg {
    display: block;
}

/* A borderless icon button used inside modal headers and toolbars. */
.icon-btn {
    background: none;
    border: none;
    color: var(--text-muted);
    cursor: pointer;
    padding: 6px;
    border-radius: var(--radius);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: all 0.2s;
}

.icon-btn:hover {
    color: var(--red);
    background: rgba(155, 12, 35, 0.08);
}

.icon-btn.active {
    color: var(--red);
    background: rgba(155, 12, 35, 0.12);
}

/* ─── Form fields ────────────────────────────────────────────────────────
   Inputs, selects and textareas share the same look: faint gray fill, thin
   border, burgundy focus that turns the fill white. Single-line controls
   sit at the 42px control height so buttons align with them. */

label {
    display: block;
    margin-bottom: 8px;
    color: var(--text);
    font-size: 14px;
    font-weight: normal;
}

input[type="text"],
input[type="password"],
input[type="email"],
input[type="search"],
input[type="number"],
input[type="date"],
textarea,
select {
    width: 100%;
    padding: 12px 15px;
    border: 1px solid var(--border-input);
    border-radius: var(--radius);
    font-family: var(--font);
    font-size: 14px;
    color: var(--text);
    background: var(--bg);
    transition: border-color 0.3s, background 0.3s;
}

input[type="text"],
input[type="password"],
input[type="email"],
input[type="search"],
input[type="number"],
input[type="date"],
select {
    height: var(--control-h);
    padding-top: 0;
    padding-bottom: 0;
}

textarea {
    resize: vertical;
    min-height: 80px;
    line-height: 1.6;
}

input:focus,
textarea:focus,
select:focus {
    outline: none;
    border-color: var(--red);
    background: var(--surface);
}

.form-group {
    margin-bottom: 25px;
}

/* Two-column grid for natural pairs; collapses on narrow screens. */
.form-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 20px;
}

/* ─── Alerts ─────────────────────────────────────────────────────────────
   Full-width tinted blocks, centered text, thin matching border. No colored
   left stripe. */

.error,
.alert-error {
    background: var(--red-light);
    color: var(--red);
    border: 1px solid var(--red-border);
    padding: 15px 20px;
    margin-bottom: 25px;
    text-align: center;
    font-size: 14px;
    border-radius: var(--radius);
    line-height: 1.5;
}

.success,
.alert-success {
    background: var(--success-bg);
    color: var(--success-text);
    border: 1px solid var(--success-bdr);
    padding: 15px 20px;
    margin-bottom: 25px;
    text-align: center;
    font-size: 14px;
    border-radius: var(--radius);
}

/* ─── App shell (Layout A: light sidebar) ────────────────────────────────
   A flex shell: a light sidebar next to a scrolling content column. The
   sidebar is not a colored block - it is a faint gray panel bordered off
   from the content. It sticks full height and collapses to an icon rail. */

.app-wrapper {
    display: flex;
    min-height: 100vh;
}

.sidebar {
    width: var(--sidebar-width);
    min-width: var(--sidebar-width);
    background: var(--bg);
    border-right: 1px solid var(--border-soft);
    display: flex;
    flex-direction: column;
    height: 100vh;
    position: sticky;
    top: 0;
    overflow: hidden;
    transition: width 0.25s ease, min-width 0.25s ease;
}

.sidebar-header {
    padding: 25px 20px;
    border-bottom: 1px solid var(--border-soft);
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 10px;
}

.sidebar-header-text {
    overflow: hidden;
}

.sidebar-header h1 {
    font-size: 18px;
    text-align: left;
    margin-bottom: 4px;
}

.sidebar-header .subtitle {
    text-align: left;
    margin-bottom: 0;
    font-size: 13px;
    color: var(--text-muted);
}

.sidebar-toggle {
    background: none;
    border: none;
    color: var(--text-muted);
    cursor: pointer;
    padding: 4px;
    border-radius: var(--radius);
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: all 0.2s;
}

.sidebar-toggle:hover {
    color: var(--red);
    background: rgba(155, 12, 35, 0.08);
}

.sidebar-nav {
    flex: 1;
    overflow-y: auto;
    padding: 15px 0;
}

/* A flat navigation item; the active one is a solid burgundy row with white
   text (the single place the accent fills a large surface). */
.nav-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 20px;
    color: var(--text);
    font-size: 14px;
    cursor: pointer;
    transition: background 0.2s, color 0.2s;
    text-decoration: none;
}

.nav-item:hover {
    background: var(--divider);
    text-decoration: none;
}

.nav-item.active {
    background: var(--red);
    color: #ffffff;
}

.nav-item .nav-count {
    margin-left: auto;
    font-size: 11px;
    background: var(--border-soft);
    color: var(--text-muted);
    padding: 2px 8px;
    border-radius: var(--radius-pill);
}

.nav-item.active .nav-count {
    background: rgba(255, 255, 255, 0.2);
    color: #ffffff;
}

.sidebar-footer {
    padding: 15px 20px;
    border-top: 1px solid var(--border-soft);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
}

.sidebar-footer .user-name {
    font-size: 13px;
    color: var(--text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.sidebar-footer .user-role {
    color: var(--text-muted);
    font-size: 12px;
    text-transform: capitalize;
}

.sidebar-footer .footer-actions {
    display: flex;
    gap: 6px;
    flex-shrink: 0;
}

/* Collapsed rail: hide the labels, keep the icons, center the header.
   Confined to the wide layout on purpose. Below the breakpoint the sidebar is
   no longer a column beside the content but a band stacked above it, and
   narrowing that band to 60px produced a dead strip with the whole navigation
   hidden inside it and no way to get it back on a phone. Under 900px the
   collapsed class is simply inert. */
@media (min-width: 901px) {
    .app-wrapper.sidebar-collapsed .sidebar {
        width: var(--sidebar-collapsed);
        min-width: var(--sidebar-collapsed);
    }

    .app-wrapper.sidebar-collapsed .sidebar-header-text,
    .app-wrapper.sidebar-collapsed .sidebar-nav .nav-label,
    .app-wrapper.sidebar-collapsed .sidebar-nav .nav-count,
    .app-wrapper.sidebar-collapsed .sidebar-footer .user-info {
        display: none;
    }

    .app-wrapper.sidebar-collapsed .sidebar-header {
        justify-content: center;
        padding: 20px 0;
    }

    .app-wrapper.sidebar-collapsed .nav-item {
        justify-content: center;
        padding: 10px 0;
    }

    .app-wrapper.sidebar-collapsed .sidebar-footer {
        justify-content: center;
        padding: 15px 0;
    }

    .app-wrapper.sidebar-collapsed .sidebar-footer .footer-actions {
        flex-direction: column;
        gap: 10px;
    }
}

/* ─── Upload queue progress ──────────────────────────────────────────────
   Shown in the bulk modal while the files go up one at a time. The fill width
   is set from JavaScript through the CSSOM, which the Content-Security-Policy
   allows; a style attribute would have been refused. */

.progress-track {
    height: 6px;
    background: var(--border-soft);
    border-radius: var(--radius-pill);
    overflow: hidden;
    margin-bottom: 12px;
}

.progress-fill {
    height: 100%;
    width: 0;
    background: var(--red);
    border-radius: var(--radius-pill);
    transition: width 0.2s ease;
}

.progress-line {
    font-size: 14px;
    color: var(--text);
    margin-bottom: 4px;
}

.progress-current {
    font-size: 13px;
    color: var(--text-muted);
    margin-bottom: 0;
    word-break: break-all;
}

/* Failures are listed rather than counted: with several hundred files, knowing
   which ones did not make it is the only way to send them again. */
.progress-errors {
    margin: 12px 0 0;
    padding: 10px 12px;
    list-style: none;
    max-height: 180px;
    overflow-y: auto;
    background: var(--bg);
    border: 1px solid var(--border-soft);
    border-radius: var(--radius);
    font-size: 13px;
    color: var(--text-muted);
}

.progress-errors li {
    padding: 3px 0;
    word-break: break-all;
}

/* The icon of a navigation item. It carries no meaning of its own while the
   labels are visible, and becomes the only thing left once they are not, so it
   must never be allowed to shrink out of the rail. */
.nav-item [data-icon] {
    display: inline-flex;
    align-items: center;
    flex-shrink: 0;
}

/* ─── Main content ───────────────────────────────────────────────────────*/

.main-content {
    flex: 1;
    padding: 30px 40px;
    overflow-y: auto;
    min-width: 0;
}

/* Page header: title on the left, actions on the right, a 2px light rule
   under the whole band. The title appears once, here. */
.content-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 30px;
    padding-bottom: 20px;
    border-bottom: 2px solid var(--divider);
}

.content-header h2 {
    font-size: 22px;
    font-weight: normal;
    color: var(--text);
}

.content-header .breadcrumb {
    font-size: 13px;
    color: var(--text-muted);
    margin-top: 4px;
}

.content-actions {
    display: flex;
    gap: 10px;
    align-items: center;
}

/* ─── Layout B: top header + tabs (no sidebar) ───────────────────────────
   A centered column with a white header band, a horizontal tab row under
   it, then the content. Chosen when screens read better full width or the
   sections are few. */

.dashboard,
.page-shell {
    width: 100%;
    max-width: 1200px;
    margin: 0 auto;
    padding: 20px;
}

.header {
    background: var(--surface);
    border-bottom: 2px solid var(--divider);
    padding: 30px 0;
    margin-bottom: 40px;
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.header h1 {
    font-size: 28px;
    font-weight: normal;
    text-align: left;
    margin: 0 0 5px 0;
}

.header .user-status {
    color: var(--text-muted);
    font-size: 14px;
    text-transform: capitalize;
}

/* ─── Tabs (top navigation and in-page tabs) ─────────────────────────────
   Transparent tabs on a 2px light rule; the active tab is burgundy with a
   3px burgundy underline. Never boxed, never a filled pill. */

.tabs,
.top-tabs {
    display: flex;
    gap: 0;
    border-bottom: 2px solid var(--divider);
    margin-bottom: 30px;
    overflow-x: auto;
}

.tab,
.top-tab {
    padding: 14px 28px;
    background: transparent;
    border: none;
    border-bottom: 3px solid transparent;
    color: var(--text-muted);
    font-family: var(--font);
    font-size: 15px;
    font-weight: normal;
    cursor: pointer;
    transition: all 0.3s;
    white-space: nowrap;
}

.tab:hover,
.top-tab:hover {
    color: var(--text);
}

.tab.active,
.top-tab.active {
    color: var(--red);
    border-bottom-color: var(--red);
}

.tab-panel,
.tab-content {
    display: none;
}

.tab-panel.active,
.tab-content.active {
    display: block;
}

/* ─── Cards ──────────────────────────────────────────────────────────────
   A plain white card with a 1px border and a 6px radius; hover lifts the
   border to burgundy with a soft tinted shadow. No colored left stripe. */

.card {
    background: var(--surface);
    border: 1px solid var(--border-soft);
    border-radius: var(--radius-card);
    padding: 30px;
}

.card-link {
    display: block;
    text-decoration: none;
    color: inherit;
    cursor: pointer;
    transition: all 0.3s;
}

.card-link:hover {
    border-color: var(--red);
    box-shadow: 0 4px 20px rgba(155, 12, 35, 0.1);
    text-decoration: none;
}

.card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
    gap: 30px;
    align-items: start;
}

/* Square burgundy icon chip that sits at the top of a card. */
.card-icon {
    width: 50px;
    height: 50px;
    background: var(--red);
    color: #ffffff;
    border-radius: var(--radius);
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 20px;
}

.card-title {
    font-size: 18px;
    font-weight: normal;
    color: var(--text);
    margin-bottom: 12px;
}

.card-text {
    color: var(--text-muted);
    font-size: 14px;
    line-height: 1.6;
}

/* ─── Tables ─────────────────────────────────────────────────────────────
   Full-width table, faint gray header (normal weight), thin row rules,
   rows hover in the same faint gray. Header can stick for long tables. */

.data-table {
    width: 100%;
    border-collapse: collapse;
}

.data-table th,
.data-table td {
    padding: 14px 15px;
    text-align: left;
    border-bottom: 1px solid var(--border-soft);
    font-size: 14px;
}

.data-table th {
    background: var(--bg);
    color: var(--text);
    font-weight: normal;
    position: sticky;
    top: 0;
    z-index: 2;
}

.data-table tr:hover {
    background: var(--bg);
}

.data-table .th-actions {
    text-align: right;
}

.data-table .actions-cell {
    display: flex;
    gap: 6px;
    justify-content: flex-end;
    white-space: nowrap;
}

.data-table .col-num {
    text-align: right;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

/* Sortable header: pointer cursor, burgundy on hover, arrow shows state. */
.sortable-th {
    cursor: pointer;
    user-select: none;
    transition: color 0.2s;
}

.sortable-th:hover {
    color: var(--red);
}

.sort-arrow {
    display: inline-block;
    vertical-align: -2px;
    margin-left: 4px;
    color: var(--red);
}

.sort-arrow-inactive {
    display: inline-block;
    vertical-align: -2px;
    margin-left: 4px;
    opacity: 0.25;
}

/* Drag-to-reorder rows: burgundy insertion line above or below the target. */
.drag-row { cursor: grab; }
.drag-row:active { cursor: grabbing; }
.dragging-row { opacity: 0.4; }
.insert-before td { box-shadow: inset 0 2px 0 var(--red); }
.insert-after td { box-shadow: inset 0 -2px 0 var(--red); }

.drag-handle {
    cursor: grab;
    color: var(--border-input);
    padding: 0 4px;
    user-select: none;
}

.drag-handle:hover { color: var(--red); }
.drag-handle:active { cursor: grabbing; }

/* ─── Badges ─────────────────────────────────────────────────────────────
   Two shapes, both tinted, both used in BSI: a flat 4px type badge
   (uppercase, for file types and short tags) and a soft pill (for roles and
   statuses). Pick per meaning. */

.badge {
    display: inline-block;
    padding: 4px 10px;
    border-radius: var(--radius);
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    font-weight: normal;
}

.badge-red    { background: var(--red-light); color: var(--red); }
.badge-blue   { background: #dbeafe; color: #1e40af; }
.badge-green  { background: #dcfce7; color: #166534; }
.badge-amber  { background: #fef3c7; color: #92400e; }
.badge-gray   { background: #f3f4f6; color: #374151; }

.pill {
    display: inline-block;
    padding: 4px 14px;
    border-radius: var(--radius-pill);
    font-size: 12px;
}

.pill-amber { background: #fef3c7; color: #92400e; }
.pill-blue  { background: #dbeafe; color: #1e40af; }
.pill-gray  { background: #f3f4f6; color: #374151; }
.pill-green { background: #dcfce7; color: #166534; }

/* ─── Empty state ────────────────────────────────────────────────────────*/

.empty-state {
    text-align: center;
    padding: 60px 20px;
    color: var(--text-muted);
}

.empty-state p {
    font-size: 15px;
    margin-bottom: 20px;
}

/* ─── Modal ──────────────────────────────────────────────────────────────
   Dark overlay, white card with an 8px radius, header / body / footer bands.
   Replaces every native alert / confirm / prompt. */

.modal-overlay {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 1000;
    justify-content: center;
    align-items: center;
    padding: 20px;
}

.modal-overlay.active {
    display: flex;
}

.modal {
    background: var(--surface);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    width: 100%;
    max-width: 600px;
    max-height: 90vh;
    overflow-y: auto;
}

.modal-large { max-width: 900px; }

.modal-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 25px 30px;
    border-bottom: 1px solid var(--border-soft);
}

.modal-header h3 {
    font-size: 18px;
    font-weight: normal;
    color: var(--text);
}

.modal-close {
    background: none;
    border: none;
    font-size: 22px;
    color: var(--text-muted);
    cursor: pointer;
    padding: 5px;
    line-height: 1;
    transition: color 0.2s;
}

.modal-close:hover { color: var(--text); }

.modal-body { padding: 30px; }

.modal-footer {
    padding: 20px 30px;
    border-top: 1px solid var(--border-soft);
    display: flex;
    justify-content: flex-end;
    gap: 10px;
}

/* ─── Upload drop zone ───────────────────────────────────────────────────*/

.upload-drop-zone {
    border: 2px dashed var(--border-input);
    border-radius: var(--radius-lg);
    padding: 40px 20px;
    text-align: center;
    cursor: pointer;
    transition: all 0.3s;
    margin-bottom: 20px;
}

.upload-drop-zone:hover,
.upload-drop-zone.dragover {
    border-color: var(--red);
    background: rgba(155, 12, 35, 0.03);
}

.upload-drop-zone p {
    color: var(--text-muted);
    font-size: 14px;
    margin-bottom: 5px;
}

.upload-drop-zone .formats {
    color: var(--text-light);
    font-size: 12px;
}

.upload-drop-zone input[type="file"] {
    display: none;
}

/* ─── Search bar ─────────────────────────────────────────────────────────*/

.search-bar {
    display: flex;
    gap: 10px;
    margin-bottom: 20px;
}

.search-bar input {
    flex: 1;
    max-width: 350px;
}

/* ─── Utilities ──────────────────────────────────────────────────────────*/

/* Visible to screen readers, invisible on screen. Used for the labels of
   controls that only show an icon or a placeholder. */
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

.empty-cell {
    text-align: center;
    color: var(--text-muted);
}

/* Keyboard focus must stay visible on the sortable headers and icon buttons,
   which have no border of their own. */
.sortable-th:focus-visible,
.th-sort:focus-visible,
.btn-icon:focus-visible,
.icon-btn:focus-visible {
    outline: 2px solid var(--red);
    outline-offset: 2px;
}

/* A server-sorted header is a real link, so it works without script and is
   reachable by keyboard on its own. It should still look like a header. */
.th-sort {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    color: inherit;
    text-decoration: none;
    font: inherit;
}

.th-sort:hover { color: var(--red); }

.hint {
    color: var(--text-muted);
    font-size: 13px;
    margin-bottom: 12px;
    max-width: 70ch;
}

/* Reorder mode: the category is listed whole and nothing may narrow it, so the
   search bar is replaced by a banner that says what is going on and how to
   leave. */
.reorder-banner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
    flex-wrap: wrap;
    margin-bottom: 20px;
    padding: 14px 18px;
    background: var(--red-light);
    border: 1px solid var(--red-border);
    border-radius: var(--radius-card);
}

.reorder-banner strong { font-weight: normal; color: var(--red-dark); }

/* ─── Utility classes ────────────────────────────────────────────────────
   These exist so no style="..." attribute is left in the markup. With none of
   them, Content-Security-Policy can drop 'unsafe-inline' from style-src and
   the policy has no exception left at all. Assignments made from JavaScript
   (element.style.display = 'none') go through the CSSOM and are unaffected. */

.is-hidden      { display: none; }
.w-560          { max-width: 560px; }
.w-460          { max-width: 460px; }
.w-220          { max-width: 220px; }
.mb-0           { margin-bottom: 0; }
.mb-16          { margin-bottom: 16px; }
.mb-20          { margin-bottom: 20px; }
.mb-30          { margin-bottom: 30px; }
.mt-20          { margin-top: 20px; }
.mt-4           { margin: 4px 0 0; }
.text-center    { text-align: center; }
.text-muted     { color: var(--text-muted); }
.text-sm        { font-size: 13px; }
.h-sub          { font-size: 18px; }

/* A checkbox and its wording on one line. The control keeps its natural size
   instead of the full-width shape inputs have in a form group. */
.check-row {
    display: flex;
    align-items: center;
    gap: 10px;
    font-weight: normal;
}

.check-row input[type="checkbox"] {
    width: auto;
    height: auto;
}

/* Label and value pairs in the Settings panel. */
.detail-list {
    display: grid;
    grid-template-columns: 160px 1fr;
    gap: 10px 20px;
}

.detail-list dt { color: var(--text-muted); }

@media (max-width: 600px) {
    .detail-list { grid-template-columns: 1fr; gap: 4px 0; }
    .detail-list dd { margin-bottom: 10px; }
}

/* The active view button in the public archive. */
.content-actions .btn-icon.active {
    color: var(--red);
    border-color: var(--red);
    background: var(--red-light);
}

/* While a column sort is active the visible order is not the stored one, so
   rows cannot be dragged. */
.no-drag .drag-row { cursor: default; }
.no-drag .drag-handle { opacity: .35; cursor: not-allowed; }

/* ─── Pagination ─────────────────────────────────────────────────────────*/

.pager {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 20px;
    font-size: 13px;
    color: var(--text-muted);
}

.pager a,
.pager span.current {
    display: inline-block;
    min-width: 32px;
    padding: 6px 10px;
    text-align: center;
    border: 1px solid var(--border-input);
    border-radius: var(--radius);
    text-decoration: none;
    color: var(--text);
}

.pager a:hover { border-color: var(--red); color: var(--red); }

.pager span.current {
    background: var(--red);
    border-color: var(--red);
    color: #fff;
}

.pager .pager-info { margin-left: auto; }

/* ─── Toast ──────────────────────────────────────────────────────────────
   Background saves have no page reload to carry a flash message, so a
   failure surfaces here instead of disappearing silently. */

.toast {
    position: fixed;
    top: 20px;
    left: 50%;
    transform: translateX(-50%) translateY(-20px);
    z-index: 2000;
    max-width: 480px;
    padding: 12px 18px;
    border-radius: var(--radius);
    border: 1px solid transparent;
    box-shadow: var(--shadow-md);
    font-size: 14px;
    opacity: 0;
    pointer-events: none;
    transition: opacity .2s ease, transform .2s ease;
}

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

.toast-error {
    background: var(--red-light);
    border-color: var(--red-border);
    color: var(--red-dark);
}

.toast-success {
    background: var(--success-bg);
    border-color: var(--success-bdr);
    color: var(--success-text);
}

/* ─── Login ──────────────────────────────────────────────────────────────
   A centered card on a plain page: institute name, title, fields, a
   full-width burgundy button. */

body.login-page {
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 20px;
}

.login-container {
    width: 100%;
    max-width: 400px;
}

.login-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow);
    padding: 50px 40px;
}

.login-card .institute-name {
    text-align: center;
    font-size: 18px;
    color: var(--text);
    margin-bottom: 5px;
    font-weight: normal;
}

.login-card h1 {
    text-align: center;
    margin-bottom: 10px;
}

.login-card .subtitle {
    text-align: center;
    color: var(--text-muted);
    font-size: 14px;
    margin-bottom: 40px;
}

/* ─── Responsive ─────────────────────────────────────────────────────────*/

@media (max-width: 900px) {
    .app-wrapper { flex-direction: column; }

    .sidebar {
        width: 100%;
        min-width: 100%;
        height: auto;
        position: relative;
        max-height: 50vh;
    }

    .main-content { padding: 20px; }
    .form-row { grid-template-columns: 1fr; }
    .card-grid { grid-template-columns: 1fr; }

    .content-header {
        flex-direction: column;
        gap: 15px;
        align-items: flex-start;
    }

    .data-table {
        display: block;
        overflow-x: auto;
    }
}
