/* ==========================================================================
   namirial-edf-web — application shell
   Builds on /design-system/colors_and_type.css + components.css.
   Layout per the Digtechs Design System: 264px sidebar, 64px topbar,
   content canvas on slate-50.
   ========================================================================== */

html, body {
    margin: 0;
    padding: 0;
    background: var(--bg-canvas, #f8fafc);
    color: var(--fg-default, #020617);
    font-family: "Open Sans", -apple-system, BlinkMacSystemFont, "Segoe UI",
        Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
    font-size: 14px;
    line-height: 1.5;
    min-height: 100vh;
}

* {
    box-sizing: border-box;
}

a {
    color: inherit;
    text-decoration: none;
}

/* ── App shell grid ──────────────────────────────────────────────────── */

.app-shell {
    display: grid;
    grid-template-columns: 264px 1fr;
    grid-template-rows: 64px 1fr;
    grid-template-areas:
        "sidebar topbar"
        "sidebar content";
    min-height: 100vh;
}

.app-sidebar {
    grid-area: sidebar;
    background: var(--bg-default, #ffffff);
    border-right: 1px solid var(--border-default, #e5e7eb);
    overflow-y: auto;
    position: sticky;
    top: 0;
    height: 100vh;
}

.app-topbar {
    grid-area: topbar;
    background: var(--bg-default, #ffffff);
    border-bottom: 1px solid var(--border-default, #e5e7eb);
    display: flex;
    align-items: center;
    padding: 0 24px;
    gap: 16px;
    position: sticky;
    top: 0;
    z-index: 10;
}

.app-content {
    grid-area: content;
    padding: 24px 32px 48px;
    background: var(--bg-canvas, #f8fafc);
    min-width: 0;       /* prevents grid blow-out from long table contents */
}

/* ── Sidebar ─────────────────────────────────────────────────────────── */

.sidebar-nav {
    display: flex;
    flex-direction: column;
    gap: 24px;
    padding: 20px 12px;
}

.sidebar-brand {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 4px 8px 16px;
    border-bottom: 1px solid var(--border-subtle, #f1f5f9);
}

.sidebar-brand-img {
    width: 36px;
    height: 36px;
    object-fit: contain;
}

.sidebar-brand-text {
    display: flex;
    flex-direction: column;
    line-height: 1.2;
}

.sidebar-brand-title {
    font-family: "Titillium Web", "Open Sans", sans-serif;
    font-weight: 700;
    font-size: 15px;
    color: var(--fg-default, #020617);
}

.sidebar-brand-subtitle {
    font-size: 11px;
    color: var(--fg-muted, #64748b);
    letter-spacing: 0.02em;
}

.sidebar-section {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.sidebar-section-label {
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-size: 11px;
    font-weight: 600;
    color: var(--fg-muted, #64748b);
    padding: 4px 12px 8px;
}

.sidebar-link {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px 12px;
    border-radius: 6px;
    color: var(--fg-default, #020617);
    cursor: pointer;
    transition: background-color 120ms ease;
    font-weight: 400;
}

.sidebar-link:hover {
    background: var(--bg-muted, #f1f5f9);
}

.sidebar-link.is-active {
    background: var(--bg-muted, #f1f5f9);
    font-weight: 500;
}

.sidebar-link.is-disabled {
    color: var(--fg-subtle, #94a3b8);
    cursor: not-allowed;
    pointer-events: auto;       /* keep title="" tooltip visible on hover */
}

.sidebar-link.is-disabled:hover {
    background: transparent;
}

.sidebar-link i[data-lucide] {
    width: 18px;
    height: 18px;
    flex-shrink: 0;
}

/* ── Topbar ──────────────────────────────────────────────────────────── */

.topbar {
    display: flex;
    align-items: center;
    width: 100%;
    gap: 16px;
}

/* Pushes the topbar actions to the right when the left side is empty. */
.topbar-spacer {
    flex: 1;
}

.topbar-actions {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 12px;
}

/* ── Language switcher (globe icon → dropdown) ──────────────────────── */

.lang-switcher {
    position: relative;
    display: inline-flex;
}

/* Globe button in the topbar */
.lang-trigger {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    padding: 0;
    background: transparent;
    border: none;
    border-radius: 6px;
    color: var(--fg-muted, #64748b);
    cursor: pointer;
    transition: background-color 120ms ease, color 120ms ease;
}

.lang-trigger:hover,
.lang-switcher.is-open .lang-trigger {
    background: var(--bg-muted, #f1f5f9);
    color: var(--fg-default, #020617);
}

.lang-trigger i[data-lucide] {
    width: 20px;
    height: 20px;
}

/* Dropdown menu */
.lang-menu {
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    margin: 0;
    padding: 6px;
    list-style: none;
    background: var(--bg-default, #ffffff);
    border: 1px solid var(--border-default, #e5e7eb);
    border-radius: 8px;
    box-shadow: 0 12px 24px rgba(15, 23, 42, 0.12);
    min-width: 200px;
    z-index: 200;
}

.lang-menu li {
    list-style: none;
    margin: 0;
    padding: 0;
}

.lang-menu-item {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    padding: 8px 10px;
    background: transparent;
    border: none;
    border-radius: 6px;
    color: var(--fg-default, #020617);
    cursor: pointer;
    font: inherit;
    text-align: left;
    transition: background-color 120ms ease, color 120ms ease;
}

.lang-menu-item:hover {
    background: var(--bg-muted, #f1f5f9);
}

.lang-menu-item.is-active {
    background: var(--informative-50, #f0faff);
    color: var(--informative-700, #0067bb);
    font-weight: 500;
}

/* Two-letter country code box on the left side of each row */
.lang-menu-code {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 28px;
    height: 20px;
    padding: 0 6px;
    border: 1px solid var(--border-default, #e5e7eb);
    border-radius: 4px;
    background: var(--bg-canvas, #f8fafc);
    color: var(--fg-muted, #64748b);
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    flex-shrink: 0;
}

.lang-menu-item.is-active .lang-menu-code {
    background: var(--bg-default, #ffffff);
    border-color: var(--informative-100, #b9eafe);
    color: var(--informative-700, #0067bb);
}

.lang-menu-name {
    flex: 1;
    font-size: 14px;
}

/* ── Page-level layout ───────────────────────────────────────────────── */

.page {
    max-width: 1280px;
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    gap: 24px;
}

/* List-page AJAX swap region. We moved the subtitle, filter trigger bar,
   chips, table and pagination into this wrapper so they all refresh together
   on filter submit. Without re-stating the column-gap layout the wrapper
   collapses everything to zero distance — make it inherit the same rhythm
   as the surrounding .page container. */
#results-region {
    display: flex;
    flex-direction: column;
    gap: 24px;
}

.page-header {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.page-title {
    margin: 0;
    font-size: 24px;
    font-weight: 600;
    line-height: 1.2;
}

.page-subtitle {
    margin: 0;
    color: var(--fg-muted, #64748b);
    font-size: 14px;
}

/* ── KPI strip ───────────────────────────────────────────────────────── */

.kpi-strip {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 16px;
}

.kpi-card {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 16px 20px;
}

.kpi-label {
    font-size: 12px;
    font-weight: 600;
    color: var(--fg-muted, #64748b);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.kpi-value {
    font-family: "Titillium Web", "Open Sans", sans-serif;
    font-size: 32px;
    font-weight: 700;
    line-height: 1;
    color: var(--fg-default, #020617);
}

.kpi-hint {
    font-size: 11px;
    color: var(--fg-subtle, #94a3b8);
    font-family: "JetBrains Mono", "Menlo", monospace;
    letter-spacing: 0.01em;
}

/* ── Empty state card ────────────────────────────────────────────────── */

.empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    padding: 48px 24px;
    gap: 8px;
}

.empty-state-icon {
    width: 40px;
    height: 40px;
    color: var(--fg-subtle, #94a3b8);
    margin-bottom: 8px;
}

.empty-state-title {
    margin: 0;
    font-size: 18px;
    font-weight: 600;
}

.empty-state-body {
    margin: 0;
    color: var(--fg-muted, #64748b);
    max-width: 480px;
}

.empty-state-body code {
    font-family: "JetBrains Mono", "Menlo", monospace;
    font-size: 12px;
    background: var(--bg-muted, #f1f5f9);
    padding: 1px 6px;
    border-radius: 4px;
}

.empty-state-compact {
    padding: 24px;
}

/* ── KPI link variant ────────────────────────────────────────────────── */

.kpi-card-link {
    cursor: pointer;
    transition: border-color 120ms ease, box-shadow 120ms ease;
}

.kpi-card-link:hover {
    border-color: var(--border-strong, #cbd5e1);
}

.kpi-card-attention {
    border-color: var(--negative-500, #ef4444) !important;
}

.kpi-card-attention .kpi-value {
    color: var(--negative-700, #b91c1c);
}

/* Table row attention — packet still in flight past the long-running threshold
   (default 3h). Soft red background so the row catches the eye without making
   the rest of the row text unreadable. */
.table tr.row-attention {
    background: var(--negative-50, #fef2f2);
}

.table tr.row-attention:hover {
    background: var(--negative-100, #fee2e2);
}

/* ── Badges (status + tone variants) ─────────────────────────────────── */

.badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 8px;
    border-radius: 9999px;
    font-size: 11px;
    font-weight: 600;
    line-height: 1.6;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    background: var(--bg-muted, #f1f5f9);
    color: var(--fg-default, #020617);
    border: 1px solid var(--border-default, #e5e7eb);
}

.badge-info     { background: var(--informative-50, #f0faff); color: var(--informative-700, #0067bb); border-color: var(--informative-100, #b9eafe); }
.badge-positive { background: var(--positive-50,    #f0fdf4); color: var(--positive-700,    #15803d); border-color: var(--positive-100,    #dcfce7); }
.badge-negative { background: var(--negative-50,    #fef2f2); color: var(--negative-700,    #b91c1c); border-color: var(--negative-100,    #fee2e2); }
.badge-warn     { background: var(--warning-50,     #fff7ed); color: var(--warning-600,     #ea580c); border-color: var(--warning-200,    #fed7aa); }
.badge-muted    { background: var(--bg-muted,       #f1f5f9); color: var(--fg-muted,        #64748b); border-color: var(--border-default, #e5e7eb); }

/* Status pills (used in table card headers) */
.status-pill {
    display: inline-flex;
    align-items: center;
    padding: 2px 10px;
    border-radius: 9999px;
    font-size: 12px;
    font-weight: 500;
    background: var(--bg-muted, #f1f5f9);
    color: var(--fg-muted, #64748b);
}
.status-pill-positive { background: var(--positive-50,    #f0fdf4); color: var(--positive-700,    #15803d); }
.status-pill-negative { background: var(--negative-50,    #fef2f2); color: var(--negative-700,    #b91c1c); }
.status-pill-info     { background: var(--informative-50, #f0faff); color: var(--informative-700, #0067bb); }

/* ── Buttons ─────────────────────────────────────────────────────────── */
/* Base classes (.btn, .btn-main, .btn-secondary, .btn-tertiary, .btn-ghost,
   .btn-destructive, .btn-link) and sizes (.btn-sm/.btn-md/.btn-lg/.btn-icon)
   live in design-system/components.css. We only add app-specific defaults:
   - default sizing for a bare .btn (the design system requires an explicit
     size modifier on every button; this fallback keeps templates terse)
   - icon sizing inside buttons (Lucide is not part of the design system)
   - is-disabled modifier with pointer-events:none. */

.btn:not(.btn-sm):not(.btn-md):not(.btn-lg):not(.btn-icon) {
    height: 36px;
    padding: 0 14px;
    font-size: 14px;
}

.btn i[data-lucide] {
    width: 14px;
    height: 14px;
}

.btn.is-disabled {
    opacity: 0.5;
    pointer-events: none;
}

/* ── Cards ───────────────────────────────────────────────────────────── */

.card {
    background: var(--bg-default, #ffffff);
    border: 1px solid var(--border-default, #e5e7eb);
    border-radius: 8px;
    padding: 20px;
}

.card-title {
    margin: 0 0 16px 0;
    font-size: 15px;
    font-weight: 600;
    color: var(--fg-default, #020617);
}

/* Sub-heading inside a card, for pages that group several blocks under one
   card title (the KPI page nests charts and tables under each of its six
   sections). Smaller and muted so the hierarchy against .card-title is
   unambiguous; the top margin separates it from whatever block precedes it. */
.card-subtitle {
    margin: 28px 0 12px 0;
    font-size: 13px;
    font-weight: 600;
    color: var(--fg-muted, #64748b);
}

/* No top margin when the subtitle is the first thing after the card title —
   the title already provides the spacing. */
.card-title + .card-subtitle {
    margin-top: 0;
}

.card-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 12px;
    margin-bottom: 16px;
}

.card-header .card-title {
    margin: 0;
}

.card-header-meta {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 12px;
    color: var(--fg-muted, #64748b);
}

/* Tables sit edge-to-edge inside their card.
   overflow-x:auto (was: overflow:hidden) makes the card the scroll container.
   With `hidden`, a table wider than the card was simply clipped and the
   right-hand columns were unreachable. `auto` still clips to the rounded
   corners — it only adds a scrollbar when there is actually something to
   reach. */
.table-card {
    padding: 0;
    overflow-x: auto;
}

.table-card > .card-header,
.table-card > .empty-state {
    padding: 20px;
}

/* ── Tables ──────────────────────────────────────────────────────────── */

.table {
    width: 100%;
    /* Fill the card when the columns fit, but be allowed to grow past it when
       they don't. Without min-width the table always squeezed itself into the
       available width, wrapping cell text into very tall rows — so there was
       never any overflow for .table-card to scroll. */
    min-width: max-content;
    border-collapse: collapse;
    font-size: 13px;
}

.table thead th {
    text-align: left;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-size: 11px;
    font-weight: 600;
    color: var(--fg-muted, #64748b);
    padding: 12px 16px;
    border-bottom: 1px solid var(--border-default, #e5e7eb);
    background: var(--bg-canvas, #f8fafc);
}

.table tbody td {
    padding: 12px 16px;
    border-bottom: 1px solid var(--border-subtle, #f1f5f9);
    vertical-align: middle;
}

/* Data cells stay on one line. A data table is scanned column by column, and
   letting cells wrap is what produced rows several lines tall whenever one
   value was long. Columns carrying free text (error messages) opt into
   .cell-truncate below instead of wrapping. */
.table thead th,
.table tbody td {
    white-space: nowrap;
}

/* Long free-text cell: cap the width and ellipsise the overflow. Every call
   site already puts the full value in a `title` attribute, so nothing becomes
   unreachable — it moves to the tooltip. Same treatment .audit-payload applies
   to the audit log's JSON blobs, generalised for reuse. */
.cell-truncate {
    max-width: 340px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.table tbody tr:last-child td {
    border-bottom: none;
}

.table tbody tr:hover {
    background: var(--bg-canvas, #f8fafc);
}

.table .num {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.table .mono,
.mono {
    font-family: "JetBrains Mono", "Menlo", monospace;
    font-size: 12px;
}

.table .small,
.small {
    font-size: 11px;
}

.text-muted { color: var(--fg-muted, #64748b); }

.cell-link {
    color: var(--brand-blue-700, #0067bb);
    font-weight: 500;
}
.cell-link:hover { text-decoration: underline; }

/* ── Sortable column header ─────────────────────────────────────────── */

/* The header label becomes a link that toggles asc ↔ desc on click. The
   idle column shows a faint up-down chevron to hint sortability; the
   active column shows a single bold up or down chevron in brand blue. */
.th-sort {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    color: inherit;     /* inherit the muted uppercase head colour */
    cursor: pointer;
    padding: 0;
    margin: 0;
    background: transparent;
    border: none;
    font: inherit;
    letter-spacing: inherit;
    text-transform: inherit;
    transition: color 120ms ease;
}

.th-sort:hover {
    color: var(--fg-default, #020617);
}

.th-sort.is-active {
    color: var(--brand-blue-700, #0067bb);
}

.th-sort i[data-lucide] {
    width: 12px;
    height: 12px;
    flex-shrink: 0;
}

/* Idle (un-sorted) chevron-up-down is muted and only hints at clickability */
.th-sort .th-sort-idle {
    color: var(--fg-subtle, #94a3b8);
    opacity: 0.6;
    transition: opacity 120ms ease;
}

.th-sort:hover .th-sort-idle {
    opacity: 1;
}

/* ── Filter trigger bar + active chips (above the table) ────────────── */

.filter-bar-trigger {
    display: flex;
    align-items: center;
    gap: 16px;
    flex-wrap: wrap;
}

/* Push an item to the right edge of the .filter-bar-trigger flex line. */
.filter-bar-trigger > .filter-export {
    margin-left: auto;
}

/* Group of right-aligned actions inside .filter-bar-trigger — used when there
   are multiple buttons that need to stay together on the right (e.g. on the
   /users page: Export, Import, New). A single `margin-left: auto` on the
   wrapper preserves the grouping; if we put `margin-left: auto` on each
   button directly, the flex engine distributes the free space between them
   and they spread out instead of clustering on the right. */
.filter-bar-actions {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 16px;
    flex-wrap: wrap;
}

/* Pulisci filtri = secondary action shown in negative tone */
.filter-clear {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--negative-700, #b91c1c);
    font-size: 13px;
    font-weight: 500;
}
.filter-clear:hover { text-decoration: underline; }
.filter-clear i[data-lucide] { width: 14px; height: 14px; }

/* Count badge inside the trigger button */
.filter-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 22px;
    height: 22px;
    padding: 0 6px;
    border-radius: 9999px;
    background: var(--bg-default, #ffffff);
    color: var(--brand-blue-700, #0067bb);
    font-size: 11px;
    font-weight: 700;
    margin-left: 4px;
}

.btn-main .filter-count {
    background: var(--bg-default, #ffffff);
    color: var(--brand-blue-700, #0067bb);
}

/* Active filter chips bar (server-rendered) */
.active-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.active-chip {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 4px 4px 4px 12px;
    border-radius: 9999px;
    background: var(--informative-50, #f0faff);
    border: 1px solid var(--informative-100, #b9eafe);
    color: var(--informative-700, #0067bb);
    font-size: 12px;
    font-weight: 500;
}

.active-chip-remove {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    border-radius: 9999px;
    color: var(--informative-700, #0067bb);
    background: transparent;
    transition: background-color 120ms ease;
}

.active-chip-remove:hover {
    background: var(--informative-100, #b9eafe);
}

.active-chip-remove i[data-lucide] {
    width: 12px;
    height: 12px;
}

/* ── Drawer (slide-in side panel) ────────────────────────────────────── */

/* Overlay sits above page content, dims it slightly. The drawer slides in
   from the right when [data-drawer-open] is set on the <html> element. */
.drawer-overlay {
    position: fixed;
    inset: 0;
    background: rgba(15, 23, 42, 0.32);   /* slate-900 @ 32% */
    opacity: 0;
    visibility: hidden;
    transition: opacity 160ms ease, visibility 0s linear 160ms;
    z-index: 100;
}

.drawer {
    position: fixed;
    top: 0;
    /* Slide via right-offset, NOT via transform: a transformed ancestor would
       create a new containing block for position:fixed descendants, which then
       breaks any popover (e.g. the multi-select dropdown) that needs to escape
       the drawer-body's overflow:auto clipping. */
    right: -100vw;
    height: 100vh;
    width: min(520px, 100vw);
    background: var(--bg-default, #ffffff);
    box-shadow: 0 24px 48px rgba(15, 23, 42, 0.18);
    display: flex;
    flex-direction: column;
    transition: right 200ms ease;
    z-index: 101;
}

html[data-drawer-open] .drawer-overlay {
    opacity: 1;
    visibility: visible;
    transition: opacity 160ms ease;
}

html[data-drawer-open] .drawer {
    right: 0;
}

html[data-drawer-open] {
    overflow: hidden;     /* lock scroll behind the drawer */
}

.drawer-header {
    display: flex;
    align-items: center;
    justify-content: space-between;     /* start group ←→ end group */
    gap: 12px;
    padding: 16px 20px;
    background: var(--brand-blue-700, #0067bb);
    /* Force white explicitly: some design-system base styles set
       h2/h3/etc. to a fixed dark color which would otherwise win over
       the inherited `color`. */
    color: #ffffff;
    flex-shrink: 0;
}

/* Two flex groups so the title + info icon stay together on the left, and the
   count badge + close button stick to the right edge of the header. */
.drawer-header-start,
.drawer-header-end {
    display: flex;
    align-items: center;
    gap: 12px;
}

.drawer-header i[data-lucide] {
    width: 20px;
    height: 20px;
    flex-shrink: 0;
    color: #ffffff;
}

.drawer-header h2 {
    margin: 0;
    font-size: 16px;
    font-weight: 600;
    color: #ffffff;
}

.drawer-header-close {
    background: transparent;
    border: none;
    color: #ffffff;     /* explicit, mirrors the rest of the drawer header */
    cursor: pointer;
    padding: 4px;
    border-radius: 6px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: background-color 120ms ease;
}

.drawer-header-close:hover {
    background: rgba(255, 255, 255, 0.18);
}

.drawer-body {
    flex: 1;
    overflow-y: auto;
    padding: 20px;
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.drawer-field {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.drawer-field-label {
    font-size: 12px;
    font-weight: 600;
    color: var(--fg-default, #020617);
}

.drawer-field-hint {
    font-size: 11px;
    color: var(--fg-muted, #64748b);
}

.drawer-field-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
}

.drawer-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 16px 20px;
    border-top: 1px solid var(--border-default, #e5e7eb);
    background: var(--bg-default, #ffffff);
    flex-shrink: 0;
}

/* ── Multi-select with chips ─────────────────────────────────────────── */

.multi-select {
    position: relative;
    width: 100%;
}

/* The visible "input"-like control */
.multi-select-control {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    width: 100%;
    min-height: 42px;
    padding: 6px 36px 6px 12px;
    border-radius: 6px;
    border: 1px solid var(--border-strong, #cbd5e1);
    background: var(--bg-default, #ffffff);
    color: var(--fg-default, #020617);
    font: inherit;
    cursor: pointer;
    transition: border-color 120ms ease, box-shadow 120ms ease;
}

.multi-select.is-open .multi-select-control,
.multi-select-control:focus {
    outline: none;
    border-color: var(--brand-blue-700, #0067bb);
    box-shadow: 0 0 0 3px rgba(0, 103, 187, 0.35);
}

/* Floating label appears only when at least one chip is in the field */
.multi-select-floating-label {
    position: absolute;
    top: -8px;
    left: 10px;
    padding: 0 4px;
    background: var(--bg-default, #ffffff);
    color: var(--brand-blue-700, #0067bb);
    font-size: 11px;
    font-weight: 600;
    display: none;
}

.multi-select.has-value .multi-select-floating-label {
    display: inline-block;
}

.multi-select-placeholder {
    color: var(--fg-subtle, #94a3b8);
    pointer-events: none;
}

.multi-select-tags {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 4px;
    align-items: center;
}

.multi-select-tag {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 4px 2px 10px;
    border-radius: 9999px;
    background: var(--bg-muted, #f1f5f9);
    border: 1px solid var(--border-default, #e5e7eb);
    color: var(--fg-default, #020617);
    font-size: 12px;
    font-weight: 500;
}

.multi-select-tag-remove {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    border-radius: 9999px;
    background: var(--fg-muted, #64748b);
    color: var(--fg-on-brand, #ffffff);
    border: none;
    cursor: pointer;
    transition: background-color 120ms ease;
}

.multi-select-tag-remove:hover {
    background: var(--fg-default, #020617);
}

.multi-select-tag-remove i[data-lucide] {
    width: 11px;
    height: 11px;
}

.multi-select-chevron {
    position: absolute;
    right: 12px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--fg-muted, #64748b);
    pointer-events: none;
    transition: transform 120ms ease;
}

.multi-select.is-open .multi-select-chevron {
    transform: translateY(-50%) rotate(180deg);
}

.multi-select-chevron i[data-lucide] {
    width: 16px;
    height: 16px;
}

/* Dropdown — positioned dynamically by JS via position:fixed so it can escape
   the drawer-body's overflow:auto clip. The drawer itself uses right-offset
   instead of transform precisely so position:fixed here resolves against the
   viewport (a transformed ancestor would steal the containing block). */
.multi-select-dropdown {
    position: fixed;
    margin: 0;
    padding: 4px;
    background: var(--bg-default, #ffffff);
    border: 1px solid var(--border-default, #e5e7eb);
    border-radius: 6px;
    box-shadow: 0 12px 24px rgba(15, 23, 42, 0.12);
    max-height: 280px;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    z-index: 200;     /* above the drawer (101) and the drawer-overlay (100) */
}

/* `display: flex` above has the same specificity as the HTML5 `[hidden] {
   display: none }` UA rule and, being defined later, would otherwise win —
   making every dropdown visible on page load. Force-hide it when the JS sets
   `hidden=true`. The selector specificity (.class[attr]) cleanly outranks the
   bare class so the open state still applies normally. */
.multi-select-dropdown[hidden] {
    display: none;
}

/* Search input shown at the top of dropdowns with more than N options.
   Sticky-ish header that doesn't scroll with the list. */
.multi-select-search {
    padding: 6px 4px 8px;
    border-bottom: 1px solid var(--border-default, #e5e7eb);
}

.multi-select-search-input {
    width: 100%;
    padding: 6px 10px;
    border: 1px solid var(--border-default, #e5e7eb);
    border-radius: 4px;
    font-size: 13px;
    background: var(--bg-default, #ffffff);
    color: inherit;
    box-sizing: border-box;
}

.multi-select-search-input:focus {
    outline: none;
    border-color: var(--informative-600, #0067bb);
    box-shadow: 0 0 0 2px rgba(0, 103, 187, 0.12);
}

/* The scrollable list under the (optional) search header. */
.multi-select-list {
    margin: 0;
    padding: 0;
    list-style: none;
    overflow-y: auto;
    min-height: 0;     /* allow flex shrink so the search box always stays visible */
}

.multi-select-item {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 10px;
    border-radius: 4px;
    cursor: pointer;
    font-size: 13px;
    transition: background-color 120ms ease;
}

/* Filter hides non-matching items via item.hidden = true. The class rule
   above would otherwise win on equal specificity — same trick as the
   dropdown wrapper. */
.multi-select-item[hidden] {
    display: none;
}

.multi-select-item:hover {
    background: var(--bg-muted, #f1f5f9);
}

.multi-select-item.is-selected {
    background: var(--informative-50, #f0faff);
    color: var(--informative-700, #0067bb);
    font-weight: 500;
}

.multi-select-item-check {
    margin-left: auto;
    width: 16px;
    height: 16px;
    color: var(--informative-700, #0067bb);
    visibility: hidden;
}

.multi-select-item.is-selected .multi-select-item-check {
    visibility: visible;
}

/* ── Floating-label field component ──────────────────────────────────── */
/* Used by free-text search and date-range pickers. The label is invisible
   when the field is empty (placeholder serves as the hint), and slides up
   to the top-left of the border when the field has a value or is focused. */

.field {
    position: relative;
    display: block;
}

.field .field-input {
    /* uses .input from components.css for padding/border/font, .field-input
       only adds component-local hooks for floating-label state */
    width: 100%;
}

.field-floating-label {
    position: absolute;
    top: -8px;
    left: 10px;
    padding: 0 4px;
    background: var(--bg-default, #ffffff);
    color: var(--brand-blue-700, #0067bb);
    font-size: 11px;
    font-weight: 600;
    pointer-events: none;
    opacity: 0;
    transform: translateY(4px);
    transition: opacity 120ms ease, transform 120ms ease;
}

.field.has-value .field-floating-label,
.field:focus-within .field-floating-label {
    opacity: 1;
    transform: translateY(0);
}

/* Trailing icon inside the field (e.g. calendar on the date range) */
.field-trailing-icon {
    position: absolute;
    right: 12px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--fg-muted, #64748b);
    pointer-events: none;
}

.field-trailing-icon i[data-lucide] {
    width: 16px;
    height: 16px;
}

/* Reserve space for the trailing icon so the input value doesn't overlap it. */
.field:has(.field-trailing-icon) .field-input {
    padding-right: 36px;
}

/* ── Info tooltip (CSS-only, hover-driven) ───────────────────────────── */

.info-tooltip {
    position: relative;
    display: inline-flex;
    align-items: center;
    cursor: help;
    color: inherit;
    opacity: 0.9;
}

.info-tooltip i[data-lucide] {
    width: 16px;
    height: 16px;
}

.info-tooltip::after {
    content: attr(data-tooltip);
    position: absolute;
    top: calc(100% + 6px);
    /* Anchor at the icon's left edge, expand to the right. The tooltip lives
       in the drawer-header-start group (near the title), so there's plenty
       of horizontal room before hitting the drawer's right edge. */
    left: 0;
    background: var(--fg-default, #020617);
    color: #ffffff;
    padding: 6px 10px;
    border-radius: 4px;
    font-size: 12px;
    font-weight: 400;
    white-space: nowrap;
    opacity: 0;
    pointer-events: none;
    transition: opacity 120ms ease;
    z-index: 250;
    box-shadow: 0 8px 16px rgba(15, 23, 42, 0.18);
}

.info-tooltip:hover::after,
.info-tooltip:focus-visible::after {
    opacity: 1;
}

.input {
    width: 100%;
    padding: 8px 12px;
    border-radius: 6px;
    border: 1px solid var(--border-strong, #cbd5e1);
    background: var(--bg-default, #ffffff);
    color: var(--fg-default, #020617);
    font-family: inherit;
    font-size: 14px;
    line-height: 1.4;
    transition: border-color 120ms ease, box-shadow 120ms ease;
}

.input:focus {
    outline: none;
    border-color: var(--brand-blue-700, #0067bb);
    box-shadow: 0 0 0 3px rgba(0, 103, 187, 0.35);
}

.input:disabled {
    background: var(--bg-muted, #f1f5f9);
    color: var(--fg-subtle, #94a3b8);
    cursor: not-allowed;
}

/* ── Pagination ──────────────────────────────────────────────────────── */

.pagination {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 12px;
}

.pagination-info {
    font-size: 12px;
    color: var(--fg-muted, #64748b);
}

.pagination-controls {
    display: inline-flex;
    gap: 4px;
}

/* ── Breadcrumb ──────────────────────────────────────────────────────── */

.breadcrumb {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 12px;
    color: var(--fg-muted, #64748b);
    margin-bottom: -8px;
}

.breadcrumb-link {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--fg-muted, #64748b);
}
.breadcrumb-link:hover {
    color: var(--brand-blue-700, #0067bb);
}
.breadcrumb-link i[data-lucide] { width: 14px; height: 14px; }

.page-subtitle-link {
    color: var(--brand-blue-700, #0067bb);
    margin-left: 8px;
}
.page-subtitle-link:hover { text-decoration: underline; }

/* ── Alerts ──────────────────────────────────────────────────────────── */

.alert {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 14px 16px;
    border-radius: 8px;
    border: 1px solid var(--border-default, #e5e7eb);
    background: var(--bg-default, #ffffff);
}

.alert > i[data-lucide] {
    width: 20px;
    height: 20px;
    flex-shrink: 0;
    margin-top: 2px;
}

.alert-body {
    margin: 4px 0 0 0;
    font-size: 13px;
    line-height: 1.5;
    color: var(--fg-default, #020617);
}

.alert-negative {
    background: var(--negative-50,  #fef2f2);
    border-color: var(--negative-100, #fee2e2);
    color: var(--negative-700, #b91c1c);
}

/* ── Detail page grid ────────────────────────────────────────────────── */

.detail-grid {
    display: grid;
    /* Timeline takes ~40% — vertical list of timestamps is naturally narrow.
       Side info takes ~60% — needs the room for filenames + lists of result
       files, which would otherwise wrap awkwardly. Was 2fr 1fr before. */
    grid-template-columns: 2fr 3fr;
    gap: 24px;
}

@media (max-width: 960px) {
    .detail-grid { grid-template-columns: 1fr; }
}

/* Result files list inside the side info card — mono spaced so SGNEDT names
   align, no bullets, minimal vertical rhythm. */
.file-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 2px;
}

.info-list {
    display: grid;
    grid-template-columns: 1fr 2fr;
    gap: 8px 16px;
    margin: 0;
    font-size: 13px;
}

.info-list dt {
    color: var(--fg-muted, #64748b);
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    align-self: center;
}

.info-list dd {
    margin: 0;
    color: var(--fg-default, #020617);
    word-break: break-all;
}

/* ── Timeline ────────────────────────────────────────────────────────── */

.timeline {
    list-style: none;
    margin: 0;
    padding: 0;
    position: relative;
}

.timeline::before {
    content: "";
    position: absolute;
    top: 6px;
    bottom: 6px;
    left: 7px;
    width: 2px;
    background: var(--border-default, #e5e7eb);
}

.timeline-step {
    display: grid;
    grid-template-columns: 16px 1fr;
    gap: 12px;
    padding: 6px 0;
    position: relative;
}

.timeline-dot {
    width: 16px;
    height: 16px;
    border-radius: 9999px;
    background: var(--bg-default, #ffffff);
    border: 2px solid var(--border-strong, #cbd5e1);
    margin-top: 4px;
    z-index: 1;
}

.timeline-step.is-reached .timeline-dot {
    background: var(--brand-blue-700, #0067bb);
    border-color: var(--brand-blue-700, #0067bb);
}

.timeline-step.is-error .timeline-dot {
    background: var(--negative-500, #ef4444);
    border-color: var(--negative-500, #ef4444);
}

.timeline-step:not(.is-reached) .timeline-label {
    color: var(--fg-subtle, #94a3b8);
}

.timeline-label {
    font-size: 13px;
    font-weight: 500;
}

.timeline-meta {
    display: flex;
    align-items: center;
    gap: 12px;
    color: var(--fg-muted, #64748b);
}

.timeline-delta {
    color: var(--fg-subtle, #94a3b8);
}

/* ── Login page ──────────────────────────────────────────────────────
   Standalone page, not inside .app-shell — centred card on slate-50.
   ====================================================================== */

.login-page {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
    padding: 24px;
    background: var(--bg-canvas, #f8fafc);
}

.login-card {
    width: 100%;
    max-width: 400px;
    background: var(--bg-default, #ffffff);
    border: 1px solid var(--border-default, #e5e7eb);
    border-radius: 12px;
    padding: 32px;
    box-shadow: 0 4px 12px rgba(15, 23, 42, 0.06);
}

.login-brand {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 24px;
}

.login-brand-img {
    width: 36px;
    height: 36px;
    flex: 0 0 auto;
}

.login-brand-text {
    display: flex;
    flex-direction: column;
    line-height: 1.2;
}

.login-brand-title {
    font-weight: 600;
    color: var(--fg-default, #020617);
}

.login-brand-subtitle {
    font-size: 12px;
    color: var(--fg-muted, #64748b);
}

.login-title {
    font-size: 20px;
    font-weight: 600;
    margin: 0 0 20px;
    color: var(--fg-default, #020617);
}

.login-form {
    display: flex;
    flex-direction: column;
    gap: 16px;
    margin-top: 12px;
}

.login-form .field {
    margin: 0;
}

.btn.btn-block {
    width: 100%;
    justify-content: center;
}

.login-footer-note {
    margin-top: 20px;
    padding-top: 16px;
    border-top: 1px solid var(--border-default, #e5e7eb);
    font-size: 12px;
    color: var(--fg-muted, #64748b);
    text-align: center;
}

.login-sso {
    margin-top: 16px;
}

.login-divider {
    display: flex;
    align-items: center;
    gap: 12px;
    margin: 16px 0;
    color: var(--fg-muted, #64748b);
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.login-divider::before,
.login-divider::after {
    content: "";
    flex: 1;
    height: 1px;
    background: var(--border-default, #e5e7eb);
}

/* Inline alerts above the form */
.login-card .alert {
    margin-bottom: 16px;
}

/* ── Topbar user menu ─────────────────────────────────────────────────
   Reuses the .lang-switcher / .lang-menu mechanics (same toggle JS) but
   adds a header row with name + email and a logout form-button styled
   to look like a regular dropdown item.
   ====================================================================== */

.user-menu-header {
    padding: 10px 12px;
    border-bottom: 1px solid var(--border-default, #e5e7eb);
    margin-bottom: 4px;
}

.user-menu-name {
    font-weight: 600;
    color: var(--fg-default, #020617);
}

.user-menu-username {
    font-size: 12px;
    color: var(--fg-muted, #64748b);
    word-break: break-all;
}

.user-menu-logout-form {
    margin: 0;
    padding: 0;
}

.user-menu-logout {
    width: 100%;
    border: 0;
    background: transparent;
    cursor: pointer;
    text-align: left;
    font: inherit;
    color: inherit;
}

/* ── Audit log ──────────────────────────────────────────────────────
   Pre/post action payloads can be long JSON blobs; truncate per row
   and let the user see the full text via the hover title attribute.
   ====================================================================== */

.audit-payload {
    max-width: 280px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Neutral badge for non-login audit actions (USER_CREATE etc.). */
.badge.badge-muted {
    background: var(--bg-subtle, #f1f5f9);
    color: var(--fg-muted, #64748b);
    border-color: var(--border-default, #e5e7eb);
}

/* ── Admin forms (users, groups, password reset) ───────────────────
   Vertical stack of fields with comfortable gap. Inline error/help
   styles, checkbox lists for multi-selects.
   ====================================================================== */

.form-grid {
    display: flex;
    flex-direction: column;
    gap: 16px;
    max-width: 560px;
}

.form-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 16px;
}

.form-actions {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    margin-top: 8px;
    padding-top: 16px;
    border-top: 1px solid var(--border-default, #e5e7eb);
}

.field-group {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 8px 0;
}

.field-group-label {
    font-weight: 500;
    color: var(--fg-default, #020617);
    margin-bottom: 4px;
}

.field-error {
    margin: 4px 0 0;
    font-size: 12px;
    color: var(--fg-negative, #dc2626);
}

.field-help {
    margin: 4px 0 0;
    font-size: 12px;
    color: var(--fg-muted, #64748b);
}

.field.is-hidden,
.is-hidden { display: none; }

.checkbox-line,
.radio-line {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 0;
    cursor: pointer;
}

.checkbox-line input[type="checkbox"],
.radio-line input[type="radio"] {
    margin: 0;
    accent-color: var(--brand-blue-700, #0067bb);
}

.form-hint {
    color: var(--fg-muted, #64748b);
    font-size: 12px;
    margin-left: 4px;
}

/* Roles shown as chips on the groups list. */
.role-chip {
    margin-right: 4px;
    margin-bottom: 4px;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 11px;
}

/* ── MFA setup ─────────────────────────────────────────────────────
   QR on the left, manual key on the right. Stack vertically on narrow
   screens.
   ====================================================================== */

.mfa-setup-grid {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 24px;
    align-items: center;
    margin: 16px 0;
}

.mfa-qr img {
    width: 200px;
    height: 200px;
    display: block;
}

.mfa-secret {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.mfa-secret span {
    color: var(--fg-muted, #64748b);
    font-size: 12px;
}

.mfa-secret code {
    padding: 8px 12px;
    border-radius: 6px;
    background: var(--bg-subtle, #f1f5f9);
    font-size: 14px;
    word-break: break-all;
}

@media (max-width: 600px) {
    .mfa-setup-grid {
        grid-template-columns: 1fr;
    }
}

/* Subtitle on the login-mfa standalone page. */
.login-subtitle {
    color: var(--fg-muted, #64748b);
    margin: 0 0 20px;
    font-size: 13px;
}

/* ── Analytics ─────────────────────────────────────────────────────
   Chart cards have a fixed-height wrapper so Chart.js can compute the
   canvas size without thrashing the page layout. The two-column row
   collapses to single column below 900px.
   ====================================================================== */

.analytics-window-picker {
    display: flex;
    gap: 8px;
    margin: 12px 0 20px;
}

.analytics-card {
    margin-bottom: 16px;
}

.chart-wrap {
    position: relative;
    height: 280px;
    margin-top: 12px;
}

.analytics-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 16px;
    margin-bottom: 16px;
}

@media (max-width: 900px) {
    .analytics-grid {
        grid-template-columns: 1fr;
    }
}

.table-compact td,
.table-compact th {
    padding: 6px 10px;
    font-size: 12px;
}

/* ── Bulk-actions toolbar ──────────────────────────────────────────
   Sits above a table inside <form data-bulk-form>. The submit button
   carries a count badge that bulk-actions.js keeps in sync. The narrow
   first column hosts the per-row checkboxes; centring them is a small
   QoL detail.
   ====================================================================== */

.bulk-toolbar {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 14px;
    border-bottom: 1px solid var(--border-default, #e5e7eb);
    background: var(--bg-subtle, #f8fafc);
}

.bulk-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 22px;
    padding: 2px 6px;
    margin-left: 4px;
    border-radius: 10px;
    background: rgba(255, 255, 255, 0.25);
    font-size: 11px;
    font-weight: 600;
}

th.bulk-col,
td.bulk-col {
    width: 32px;
    text-align: center;
    padding-left: 12px;
    padding-right: 4px;
}

th.bulk-col input[type="checkbox"],
td.bulk-col input[type="checkbox"] {
    margin: 0;
    accent-color: var(--brand-blue-700, #0067bb);
}
