/* File: TicketSys/css/admin_portal.css

   The Admin Control Center's own layer. Loaded AFTER ecvalla-identity.css,
   portal-shell.css and user_portal.css: everything structural (.up-shell, .up-card,
   .up-table, .up-modal, .pill, .dept-btn) comes from those; this file only adds the
   admin-specific components (.ad-*) and tightens density. Same identity, more
   information per screen. Layout mirrors itself in Arabic through logical
   properties; [dir="rtl"] appears only where an icon must be flipped. */

/* --- Shell: nine sections need a slightly narrower rail -------------------- */

.adm-shell.up-shell { grid-template-columns: 232px minmax(0, 1fr); }

.adm-nav a { padding: 9px 12px; font-size: 12.5px; }

.adm-shell .up-main {
    padding: 20px clamp(16px, 2.4vw, 40px) 20px;
    height: calc(100svh - var(--topbar-h, 64px));
    max-height: calc(100svh - var(--topbar-h, 64px));
    display: flex;
    flex-direction: column;
    box-sizing: border-box;
    overflow: hidden;
}

/* --- Sub-nav bar (sub tabs + actions in one line) ------------------------- */

/* Three slots: a spacer, the tabs, the page's actions. The tabs are centred on the BAR,
 * not on what is left over after the actions — which is what space-between gave, pushing the
 * strip off-centre by exactly the width of whatever buttons the page happened to have.
 *
 * The two outer slots are equally flexible (flex: 1 1 0), so they always claim the same width
 * and the middle lands on the centre line whatever is in them. */
.adm-subnav-bar {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    margin-bottom: 12px;
    gap: 12px;
    min-height: 38px;
    flex: 0 0 auto;
}

.adm-subnav-bar:empty,
.adm-subnav-bar:has(.adm-tabs:empty):not(:has(.adm-head-actions *)) {
    display: none !important;
    margin: 0 !important;
    min-height: 0 !important;
}

.adm-subnav-bar .adm-subnav-spacer {
    flex: 1 1 0;
    min-width: 0;
}

/* The middle slot. No auto margins: there were three of them in this row — two here and one
 * on the actions — and auto margins share the free space BETWEEN them, so the strip settled at
 * about a third of the bar and never at its centre. Centring is the outer slots' job. */
.adm-subnav-bar .adm-tabs {
    flex: 0 1 auto;
    margin: 0;
    width: auto;
    max-width: 100%;
    justify-content: center;
    /* One line, always. The base rule allows wrapping, which on a narrow content column turns
     * four tabs into a stack — and a tab strip that has become a list is no longer a tab
     * strip. It already scrolls sideways (overflow-x: auto), which is the behaviour that
     * belongs here: the row stays a row and you reach the rest of it by scrolling. */
    flex-wrap: nowrap;
}

.adm-subnav-bar .adm-tabs button {
    flex: 0 0 auto;
}

.adm-subnav-bar .adm-tabs:empty {
    display: none;
}

.adm-subnav-bar .adm-head-actions {
    flex: 1 1 0;
    min-width: 0;
    display: flex;
    justify-content: flex-end;
    align-items: center;
    gap: 8px;
    /* Not auto. The general .adm-head-actions rule pushes the block right with an auto margin,
     * which is right when it is the only thing in a header and wrong here: an auto margin
     * swallows all the free space, leaving none for the flex slots that do the centring. */
    margin-inline-start: 0;
}

/* NOT display: none when empty — this is what actually knocked the strip off centre.
 *
 * Only the Ticket Types tab puts a button here. On the other three the block is empty, was
 * hidden, and the bar was left with a flexible spacer on one side and nothing on the other:
 * the spacer took every pixel of free space and shoved the tabs hard against the far edge.
 *
 * The slot has to keep existing to keep its half of the width. It has no padding, no border
 * and no content, so an empty one shows nothing — it simply holds the centre line. */
.adm-subnav-bar .adm-head-actions:empty {
    display: flex;
}

.adm-head-actions {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    align-items: center;
    margin-inline-start: auto;
}

.adm-head-actions .dept-btn {
    border-radius: var(--ecv-radius-control, 9px);
    font-size: 12px;
    font-weight: 600;
    gap: 7px;
    padding: 0 14px;
    min-height: 36px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.adm-sync-btn {
    border-radius: var(--ecv-radius-control, 9px);
    border: 1px solid var(--border-color);
    background: var(--card-bg, #fff);
    color: var(--text-color);
    font-size: 12px;
    font-weight: 600;
    gap: 7px;
    padding: 0 14px;
    min-height: 36px;
    transition: background-color var(--ecv-quick), border-color var(--ecv-quick);
}

.adm-sync-btn:hover:not(:disabled) {
    background: var(--hover-bg, #f5f5f3);
    border-color: var(--ecv-muted, #73787b);
}

/* --- Sub-tabs (People & Access, Rules, Content, Reports, Portals, System) --- */

.adm-tabs {
    display: flex;
    justify-content: center;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px;
    /* No bottom margin: inside a centred row it would lift the tabs off the line the actions
     * sit on. The bar below the strip is the .adm-subnav-bar's own margin. */
    margin-bottom: 0;
    border-bottom: none;
    /* Auto rather than 100%: a strip that claims the whole bar cannot be centred in it. It
     * still shrinks and scrolls when the three slots together exceed the width. */
    width: auto;
    max-width: 100%;
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: none;
    flex: 0 1 auto;
}

.adm-tabs button {
    appearance: none;
    background: none;
    border: none;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    padding: 8px 16px;
    font: inherit;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--text-light);
    cursor: pointer;
    white-space: nowrap;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    transition: color var(--ecv-quick), border-color var(--ecv-quick);
}

.adm-tabs button i { width: 14px; font-size: 12px; text-align: center; opacity: .78; }
.adm-tabs button.is-active i { opacity: 1; }

.adm-tabs::-webkit-scrollbar { display: none; }

.adm-tabs button:hover { color: var(--text-color); }

.adm-tabs button.is-active {
    color: var(--text-color);
    border-bottom-color: var(--ecv-ink);
}

[dir="rtl"] .adm-tabs button { letter-spacing: 0; }

#tabPanel {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

/* --- Sticky table header (People & Access) --------------------------------- */

.adm-sticky-table {
    flex: 1 1 auto;
    min-height: 0;
    max-height: 100%;
    height: 100%;
    overflow-y: auto;
    overflow-x: auto;
    position: relative;
    border-radius: var(--ecv-radius-card);
    border: 1px solid var(--border-color);
    background-color: var(--bg-white);
}

.adm-sticky-table table.up-table {
    border-collapse: separate;
    border-spacing: 0;
    width: 100%;
}

.adm-sticky-table thead {
    position: sticky;
    top: 0;
    z-index: 10;
}

.adm-sticky-table thead th {
    position: sticky;
    top: 0;
    z-index: 10;
    background: var(--bg-white, #fff);
    border-bottom: 1px solid var(--border-color);
    box-shadow: inset 0 -1px 0 var(--border-color);
}

/* --- Toolbar: search + filters above tables --------------------------------- */

.adm-toolbar {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    margin-bottom: 14px;
}

.adm-toolbar .up-search { flex: 1 1 240px; max-width: 380px; }
.adm-toolbar .up-select { min-width: 130px; }
.adm-toolbar-spacer { flex: 1; }

/* --- Filter bar --------------------------------------------------------------
 *
 * A toolbar whose controls span the panel instead of clustering at the inline start
 * and leaving the rest of the row empty. Every control grows from its own minimum, so
 * the row fills whatever width it is given and folds control-by-control on the way
 * down to a phone — no breakpoint, and no width at which it looks half-built.
 *
 * The ratios are the hierarchy: search takes the most because it is the filter people
 * reach for first, the two lists take the middle, and the dates take the least because
 * a date input has a fixed intrinsic width and gains nothing from more.
 */
.adm-filterbar { align-items: flex-end; width: 100%; }
.adm-filterbar .up-search { flex: 3 1 240px; max-width: none; }
.adm-filterbar .up-select { flex: 2 1 170px; min-width: 0; }
.adm-filterbar .up-field { flex: 1 1 150px; min-width: 0; margin: 0; }
.adm-filterbar .up-field input { width: 100%; }

/* Anchored to the end of the row, and to the end in Arabic too — hence the logical
 * margin. It drops to its own line only when the controls have already wrapped. */
.adm-filterbar-count {
    flex: 0 0 auto;
    align-self: center;
    margin-inline-start: auto;
    font-size: 12px;
    color: var(--text-light);
}

/* --- Dense KPI grid ---------------------------------------------------------- */

.adm-kpis {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(132px, 1fr));
    gap: 10px;
    margin-bottom: 18px;
}

.adm-kpis .up-kpi { padding: 12px 14px; }
.adm-kpis .up-kpi strong { font-size: 24px; margin-top: 6px; }
.adm-kpis .up-kpi b { font-size: 9.5px; letter-spacing: .14em; }
.adm-kpis .up-kpi small { display: block; margin-top: 4px; font-size: 11px; color: var(--text-light); }

.up-kpi.is-alert { border-color: var(--ecv-red-line); background-color: var(--ecv-red-wash); }
.up-kpi.is-alert strong { color: var(--ecv-red); }

/* --- Two-pane split (Tickets, Departments): list + sticky detail ------------- */

/* --- Department Modal & Management ----------------------------------------- */

.adm-dept-modal-backdrop {
    position: fixed;
    inset: 0;
    z-index: 80;
    background: rgba(15, 17, 19, 0.7);
    backdrop-filter: blur(4px);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
    animation: adFadeIn 0.2s ease-out;
}

.adm-dept-modal {
    background: var(--ecv-paper, var(--card-bg, #1e2124));
    border: 1px solid var(--ecv-line, var(--border-color, #e5e6e4));
    border-radius: var(--ecv-radius-card, 12px);
    width: 100%;
    max-width: 980px;
    max-height: 90vh;
    display: flex;
    flex-direction: column;
    box-shadow: 0 20px 40px rgba(0,0,0,0.35);
    animation: adScaleUp 0.25s cubic-bezier(0.16, 1, 0.3, 1);
    overflow: hidden;
}

.adm-dept-modal-head {
    padding: 16px 20px;
    border-bottom: 1px solid var(--ecv-line, var(--border-color, #e5e6e4));
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    background: var(--ecv-soft, #25282c);
    flex-shrink: 0;
}

.adm-dept-modal-body {
    padding: 20px;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 16px;
    scrollbar-width: thin;
}

.adm-dept-modal-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 14px;
}

.adm-dept-modal-grid > .adm-full-width {
    grid-column: 1 / -1;
}

.adm-dept-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 14px;
    flex-wrap: wrap;
}

/* Compact Single-Row KPI Cards */
.adm-compact-kpis {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 10px;
    margin-top: 0;
    margin-bottom: 12px;
}

.adm-compact-kpis .up-kpi {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 8px 14px;
    min-height: 42px;
    border-radius: var(--ecv-radius-card, 8px);
}

.adm-compact-kpis .adm-kpi-left {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
}

.adm-compact-kpis .adm-kpi-icon {
    display: grid;
    place-items: center;
    width: 28px;
    height: 28px;
    border-radius: 6px;
    background: var(--ecv-soft, #25282c);
    color: var(--text-color);
    font-size: 12px;
    flex-shrink: 0;
}

.adm-compact-kpis .up-kpi.is-alert .adm-kpi-icon {
    background: var(--ecv-red-wash, rgba(239, 68, 68, 0.12));
    color: var(--ecv-red, #ef4444);
}

.adm-compact-kpis .adm-kpi-left b {
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--text-light, #73787b);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.adm-dept-card {
    transition: transform 0.18s cubic-bezier(0.16, 1, 0.3, 1), border-color 0.18s ease, box-shadow 0.18s ease;
}

/* Hover raises the card; it does not ring it.
 *
 * This was `border-color: var(--ecv-ink) !important`, and --ecv-ink is #f2f2f0 in dark — so
 * pointing at a card drew a hard near-white outline around it. That reads as "selected", it
 * fights every neighbouring card, and the !important meant no theme could soften it. Elevation
 * on a dark surface reads as a step lighter, which is what the surface change below does; the
 * border only firms up.
 */
.adm-dept-card:hover {
    border-color: var(--sys-border-hover, #cfd1ce);
    background: var(--sys-surface-hover, var(--ecv-soft, #eff0ee));
    transform: translateY(-2px);
    box-shadow: 0 10px 26px rgba(0, 0, 0, .18);
}

/* The card is a button, so keyboard focus has to be at least as clear as hover. */
.adm-dept-card:focus-visible {
    outline: 2px solid var(--sys-action-primary, #17191b);
    outline-offset: 2px;
    border-color: var(--sys-border-strong, #73787b);
}

@media (prefers-reduced-motion: reduce) {
    .adm-dept-card,
    .adm-dept-card:hover { transform: none; }
}

@media (max-width: 900px) {
    .adm-compact-kpis {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@keyframes adFadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
}

@keyframes adScaleUp {
    from { opacity: 0; transform: scale(0.96) translateY(8px); }
    to { opacity: 1; transform: scale(1) translateY(0); }
}

/* --- Detail drawer (user configuration, ticket type editor) ------------------ */

.adm-drawer-backdrop {
    position: fixed;
    inset: 0;
    z-index: 70;
    background: rgba(23, 25, 27, .5);
    backdrop-filter: blur(2px);
}

.adm-drawer {
    position: fixed;
    top: 0;
    bottom: 0;
    inset-inline-end: 0;
    z-index: 71;
    width: min(560px, 96vw);
    display: flex;
    flex-direction: column;
    background: var(--card-bg);
    border-inline-start: 1px solid var(--border-color);
    box-shadow: var(--ecv-shadow-float);
}

.adm-drawer-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 16px 20px;
    border-bottom: 1px solid var(--border-color);
}

.adm-drawer-head h2 { margin: 0; font-size: 16px; }
.adm-drawer-head small { display: block; color: var(--text-light); font-size: 12px; margin-top: 2px; }

.adm-drawer-body {
    flex: 1;
    overflow-y: auto;
    padding: 18px 20px;
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.adm-drawer-foot {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    padding: 14px 20px;
    border-top: 1px solid var(--border-color);
    background: color-mix(in srgb, var(--bg-white) 96%, var(--ecv-ink) 4%);
}

/* --- Section blocks inside drawers/cards -------------------------------------- */

.adm-block > h3 {
    margin: 0 0 10px;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--text-light);
}

[dir="rtl"] .adm-block > h3 { letter-spacing: 0; }

.adm-facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 10px 16px; margin: 0; }
.adm-facts div { min-width: 0; }
.adm-facts dt { font-size: 10.5px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--text-light); }
.adm-facts dd { margin: 3px 0 0; font-size: 13px; overflow-wrap: anywhere; }
[dir="rtl"] .adm-facts dt { letter-spacing: 0; }

/* --- Toggle switch -------------------------------------------------------------- */

.adm-switch {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 10px 12px;
    border: 1px solid var(--border-color);
    border-radius: var(--ecv-radius-control);
    font-size: 13px;
}

.adm-switch input { appearance: none; position: relative; width: 36px; height: 20px; flex: none;
    border-radius: 999px; background: var(--ecv-soft); border: 1px solid var(--border-color);
    cursor: pointer; transition: background-color var(--ecv-quick); }
.adm-switch input::after { content: ''; position: absolute; top: 2px; inset-inline-start: 2px;
    width: 14px; height: 14px; border-radius: 50%; background: var(--bg-white);
    box-shadow: 0 1px 2px rgba(23,25,27,.2); transition: transform var(--ecv-quick); }
.adm-switch input:checked { background: var(--ecv-ink); border-color: var(--ecv-ink); }
.adm-switch input:checked::after { transform: translateX(16px); }
[dir="rtl"] .adm-switch input:checked::after { transform: translateX(-16px); }
.adm-switch input:focus-visible { outline: 2px solid var(--primary-color); outline-offset: 2px; }
.adm-switch input:disabled { opacity: .45; cursor: not-allowed; }

/* --- Permissions matrix ----------------------------------------------------------- */

.adm-matrix-wrap { overflow-x: auto; border: 1px solid var(--border-color);
    border-radius: var(--ecv-radius-card); background: var(--card-bg); }
.adm-matrix { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.adm-matrix th, .adm-matrix td { padding: 9px 12px; border-bottom: 1px solid var(--border-color-light); }
.adm-matrix th { font-size: 10px; letter-spacing: .12em; text-transform: uppercase; color: var(--text-light); text-align: start; }
.adm-matrix td:not(:first-child), .adm-matrix th:not(:first-child) { text-align: center; }
.adm-matrix td:first-child { font-weight: 600; white-space: nowrap; }
.adm-matrix tr:last-child td { border-bottom: none; }
.adm-matrix .fa-check { color: var(--success-color); }
.adm-matrix .fa-minus { color: var(--border-color); }
[dir="rtl"] .adm-matrix th { letter-spacing: 0; }

/* --- Priority + SLA pills (colour = state, never decoration) ----------------------- */

.pill.adm-prio-low      { background: var(--ecv-soft); color: var(--text-light); }
.pill.adm-prio-medium   { background: var(--ecv-soft); color: var(--text-color); }
.pill.adm-prio-high     { background: rgba(138, 106, 18, .12); color: var(--warning-color); }
.pill.adm-prio-critical { background: var(--ecv-red-wash); color: var(--ecv-red);
    border: 1px solid var(--ecv-red-line); }

.pill.adm-sla-ok       { background: var(--success-light); color: var(--success-color); }
.pill.adm-sla-warning  { background: rgba(138, 106, 18, .12); color: var(--warning-color); }
.pill.adm-sla-breached { background: var(--ecv-red-wash); color: var(--ecv-red);
    border: 1px solid var(--ecv-red-line); }
.adm-sla-none { color: var(--text-muted); font-size: 12px; }

/* --- Simple inline charts (SVG, greyscale identity) --------------------------------- */

.adm-chart { width: 100%; }
.adm-chart svg { display: block; width: 100%; height: auto; }
.adm-chart-bar { fill: var(--ecv-ink); opacity: .85; }
.adm-chart-bar.is-muted { fill: var(--ecv-soft); opacity: 1; }
.adm-chart-axis { font-size: 10px; fill: var(--text-light); }
.adm-chart-line { fill: none; stroke: var(--ecv-ink); stroke-width: 2; }
.adm-chart-area { fill: var(--ecv-soft); opacity: .6; }

.adm-bars { display: flex; flex-direction: column; gap: 8px; }
.adm-bar-row { display: grid; grid-template-columns: minmax(90px, 160px) 1fr auto; gap: 10px;
    align-items: center; font-size: 12.5px; }
.adm-bar-row .adm-bar-track { height: 8px; border-radius: 999px; background: var(--ecv-soft); overflow: hidden; }
.adm-bar-row .adm-bar-fill { height: 100%; border-radius: 999px; background: var(--ecv-ink); }
.adm-bar-row.is-danger .adm-bar-fill { background: var(--ecv-red); }
.adm-bar-row b { font-variant-numeric: tabular-nums; font-size: 12px; }

/* --- Two-column card grid ------------------------------------------------------------ */

.adm-grid-2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 16px; }
.adm-grid-2 > .up-card { min-width: 0; }

/* --- Form builder rows (Ticket Types) -------------------------------------------------- */

.adm-field-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    border: 1px solid var(--border-color);
    border-radius: var(--ecv-radius-control);
    background: var(--bg-white);
    font-size: 12.5px;
}

.adm-field-row .adm-field-name { font-weight: 700; }
.adm-field-row .adm-field-meta { color: var(--text-light); font-size: 11.5px; }
.adm-field-row .adm-field-grow { flex: 1; min-width: 0; }
.adm-field-row .adm-icon-btn { flex: none; }

.adm-icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    border: 1px solid var(--border-color);
    border-radius: var(--ecv-radius-control);
    background: var(--card-bg);
    color: var(--text-light);
    cursor: pointer;
    transition: color var(--ecv-quick), border-color var(--ecv-quick), background-color var(--ecv-quick);
}
.adm-icon-btn:hover { color: var(--text-color); border-color: var(--ecv-ink-soft); }
.adm-icon-btn.is-danger:hover { color: var(--ecv-red); border-color: var(--ecv-red-line); background: var(--ecv-red-wash); }

/* --- Rule cards (IF / THEN) -------------------------------------------------------------- */

.adm-rule { display: flex; flex-direction: column; gap: 8px; }
.adm-rule-clause { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; font-size: 12.5px; }
.adm-rule-clause .adm-kw { font-size: 10px; font-weight: 700; letter-spacing: .14em;
    text-transform: uppercase; color: var(--text-light); min-width: 34px; }
[dir="rtl"] .adm-rule-clause .adm-kw { letter-spacing: 0; }
.adm-chip-fact { padding: 3px 9px; border: 1px solid var(--border-color);
    border-radius: var(--ecv-radius-pill); background: var(--ecv-soft); font-size: 12px; }

/* --- Conversation thread (admin ticket view) ----------------------------------------------- */

.adm-thread { display: flex; flex-direction: column; gap: 10px; }
.adm-msg { padding: 10px 12px; border: 1px solid var(--border-color);
    border-radius: var(--ecv-radius-card); font-size: 13px; background: var(--bg-white); }
.adm-msg.is-staff { background: var(--ecv-soft); }
.adm-msg.is-note { background: rgba(138, 106, 18, .07); border-color: rgba(138, 106, 18, .25); }
.adm-msg header { display: flex; justify-content: space-between; gap: 10px; margin-bottom: 4px;
    font-size: 11px; color: var(--text-light); }
.adm-msg header b { color: var(--text-color); }
.adm-msg p { margin: 0; white-space: pre-wrap; overflow-wrap: anywhere; }

/* --- Stars (feedback) ------------------------------------------------------------------------ */

.adm-stars { color: var(--warning-color); letter-spacing: 2px; white-space: nowrap; }
.adm-stars .is-off { color: var(--border-color); }

/* --- Audit timeline --------------------------------------------------------------------------- */

.adm-timeline { display: flex; flex-direction: column; gap: 0; }
.adm-timeline-item { position: relative; padding: 10px 0 10px; padding-inline-start: 22px;
    border-inline-start: 1px solid var(--border-color); margin-inline-start: 6px; font-size: 12.5px; }
.adm-timeline-item::before { content: ''; position: absolute; inset-inline-start: -4px; top: 16px;
    width: 7px; height: 7px; border-radius: 50%; background: var(--ecv-ink); }
.adm-timeline-item small { display: block; color: var(--text-light); margin-top: 2px; }

/* --- Responsive -------------------------------------------------------------------------------- */

@media (max-width: 1100px) {
    .adm-split { grid-template-columns: 1fr; }
    .adm-detail { position: static; max-height: none; }
    .adm-detail-stack { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 920px) {
    /* Admin navigation always remains a vertical rail. Nine administrative destinations
       do not belong in a horizontal phone tab bar; the compact icon rail preserves every
       destination without taking over the content width. */
    .adm-shell.up-shell { grid-template-columns: 68px minmax(0, 1fr); }
    .adm-shell .up-sidebar {
        position: sticky;
        inset: auto;
        top: 0;
        align-self: start;
        width: 68px;
        height: 100svh;
        flex-direction: column;
        align-items: stretch;
        gap: 10px;
        padding: 12px 7px;
    }
    .adm-shell .up-brand { display: flex; padding: 5px 2px 10px; }
    .adm-shell .up-brand .brand-wordmark { width: 46px; height: auto; }
    .adm-shell .up-brand small { display: none; }
    .adm-shell .up-nav {
        display: flex;
        flex: 1;
        flex-direction: column;
        justify-content: flex-start;
        gap: 3px;
        overflow-x: hidden;
        overflow-y: auto;
    }
    .adm-nav a span { display: none; }
    .adm-nav a,
    .adm-nav a.up-nav-secondary {
        display: flex;
        position: relative;
        flex: none;
        flex-direction: row;
        justify-content: center;
        min-height: 42px;
        padding: 9px 6px;
    }
    .adm-nav a i { width: 18px; font-size: 15px; }
    .adm-shell .up-nav-badge { top: 2px; inset-inline-end: 2px; }
    .adm-shell .up-sidebar-foot {
        display: flex;
        flex-direction: column;
        border-top: 1px solid rgba(255,255,255,.12);
        padding-top: 6px;
    }
    .adm-shell .up-sidebar-foot .up-user { display: none; }
    .adm-shell .up-signout {
        display: flex;
        justify-content: center;
        padding: 9px 6px;
    }
    .adm-shell .up-signout span { display: none; }
    .adm-shell .up-main { padding-bottom: 72px; }
    .adm-shell .up-fab { display: none; }
    .adm-kpis { grid-template-columns: repeat(auto-fit, minmax(110px, 1fr)); }
    .adm-drawer { width: 100vw; border-inline-start: none; }
    /* SLA has only three short columns; keeping it tabular is clearer and far shorter
       than turning each of four priorities into a generic mobile record card. */
    .adm-sla-card .up-table { display: table; }
    .adm-sla-card .up-table thead { display: table-header-group; }
    .adm-sla-card .up-table tbody { display: table-row-group; }
    .adm-sla-card .up-table tr { display: table-row; padding: 0; }
    .adm-sla-card .up-table th,
    .adm-sla-card .up-table td { display: table-cell; padding: 7px 5px; }
    .adm-sla-card .up-table td::before { display: none !important; content: none !important; }
}

@media (max-width: 680px) {
    .adm-shell .up-main { padding-inline: 12px; }
    .adm-head { align-items: stretch; margin-bottom: 14px; }
    .adm-head-actions { width: 100%; margin-inline-end: 0; }
    .adm-head-actions .dept-btn { flex: 1; justify-content: center; }
    .adm-tabs { margin-inline: -12px; padding-inline: 12px; }

    /* On a phone the three-slot row has no room to balance anything, so the bar wraps: the
     * tabs take their own full-width line and stay centred on it, and the page's actions sit
     * on the line below. The strip itself still never wraps — it scrolls. */
    .adm-subnav-bar { flex-wrap: wrap; }
    .adm-subnav-bar .adm-subnav-spacer { display: none; }
    .adm-subnav-bar .adm-tabs { flex: 1 1 100%; margin-inline: -12px; padding-inline: 12px; }

    /* The general rule takes the full width at this size; inside the bar that would break the
     * row it belongs to. */
    .adm-subnav-bar .adm-head-actions { width: auto; flex: 1 1 100%; }
    .adm-tabs button { padding: 9px 11px; font-size: 11px; }
    .adm-kpis { gap: 8px; margin-bottom: 12px; grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .adm-kpis .up-kpi { padding: 10px 12px; }
    .adm-kpis .up-kpi strong { font-size: 21px; margin-top: 4px; }
    .adm-detail-stack { grid-template-columns: 1fr; }
    .adm-detail-stack > .up-card,
    .adm-detail-stack > .adm-detail-primary,
    .adm-detail-stack > .adm-detail-members { grid-column: 1; }
    .adm-detail-stack .adm-facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .adm-bar-row { grid-template-columns: minmax(72px, 110px) 1fr auto; gap: 7px; }
}

@media (max-width: 420px) {
    .adm-kpis { grid-template-columns: 1fr 1fr; }
    .adm-detail-stack .adm-facts { grid-template-columns: 1fr 1fr; }
    .adm-tabs button { flex-direction: column; gap: 3px; padding-inline: 10px; }
}


/* ------------------------------------------------------------------ *
 * Departments — the card grid
 *
 * The grid itself already fits: auto-fill tracks with a 280px floor. What did not fit was the
 * content inside a track. A grid item defaults to min-width: auto, so it refuses to shrink
 * below its content's intrinsic width — one long department name, code or description with no
 * break opportunity makes its track wider than its 1fr share, the row grows past the wrapper,
 * and the page gains a horizontal scrollbar that has nothing to do with the layout.
 *
 * min-width: 0 down the card's own boxes is the fix; the two clips are the guard. `clip`
 * rather than `hidden` on the wrapper, because the wrapper is already a vertical scroll
 * container and `hidden` on one axis would not leave the other alone.
 * ------------------------------------------------------------------ */

.adm-dept-grid-wrap {
    width: 100%;
    max-width: 100%;
    box-sizing: border-box;
    overflow-x: clip;
}

/* The grid is declared inline by departments.js; this is the only handle onto it. */
.adm-dept-grid-wrap > div {
    width: 100%;
    min-width: 0;
}

.adm-dept-card {
    min-width: 0;
    max-width: 100%;
    overflow-x: clip;
}

/* Every box inside the card may shrink. Icons and the code badge keep their size because they
 * carry an explicit width and flex-shrink: 0 — min-width: 0 lifts a floor, it does not set
 * one. */
.adm-dept-card div,
.adm-dept-card p,
.adm-dept-card h3,
.adm-dept-card dl,
.adm-dept-card dd {
    min-width: 0;
}

/* And when a single unbroken string is genuinely longer than the card, it breaks rather than
 * pushes. The name is already ellipsised; this catches the description and the free text. */
.adm-dept-card p,
.adm-dept-card dd {
    overflow-wrap: anywhere;
}


/* ------------------------------------------------------------------ *
 * Portals tab — settings across the width, not down a column
 *
 * The User and Department panels were one 560px card holding a vertical list of switches, so
 * on any real monitor the tab was a narrow strip with two thirds of the screen empty beside
 * it — and the list ran off the bottom instead. These settings are a flat set of independent
 * toggles: nothing about them is sequential, so nothing about them needs to be a column.
 *
 * The card now takes the width it is given and the switches flow into as many columns as fit
 * at a readable label width. Same behaviour as the Departments grid next door, which is the
 * point — two tabs of the same screen should not lay out on different principles.
 * ------------------------------------------------------------------ */

.adm-portal-card {
    width: 100%;
    max-width: none;
    box-sizing: border-box;
    padding: 18px 20px;
    min-width: 0;
}

.adm-switch-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    align-items: start;
    gap: 8px;
    min-width: 0;
}

/* The switch is a flex row of label and control; in a grid track it must be allowed to
 * shrink, or a long feature name widens its column and the row pushes past the card. */
.adm-switch-grid > .adm-switch {
    margin: 0;
    min-width: 0;
}

.adm-switch-grid > .adm-switch > span {
    min-width: 0;
    overflow-wrap: anywhere;
}

/* Form fields in a settings card follow the same rule as the switches: as many columns as fit
 * at a width a label and its control can live in. A lone select does not stretch to the width
 * of a monitor — the track has a ceiling, so one field stays one field's worth of width. */
.adm-field-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 340px));
    align-items: start;
    gap: 12px 16px;
    min-width: 0;
}

.adm-field-grid > .up-field {
    margin: 0;
    min-width: 0;
}

/* The fact lists on the System tab read across rather than down, for the same reason. */
.adm-portal-card .adm-facts {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 10px 20px;
}


/* ------------------------------------------------------------------ *
 * Group policy dialog — the permission matrix
 *
 * This is the one dialog in the portal that grants and withholds access, so it is allowed to
 * look like its own thing: the widest of the modal sizes, a lock in the head, and a matrix
 * built as a stack of section cards rather than the bare bordered divs it was.
 *
 * The shape carries the meaning. A section header sits on its own tone with its mode select
 * beside it; its children are indented rows beneath, each with the same control in the same
 * column, so the eye reads DOWN one column to compare modes instead of hunting across rows.
 * The section header sticks while its children scroll, because on a long matrix the question
 * being answered is always "which section am I in".
 * ------------------------------------------------------------------ */

.up-modal-xl {
    width: min(1060px, 100%);
}

.adm-policy-matrix {
    display: grid;
    gap: 12px;
    min-width: 0;
}

.adm-policy-matrix > div {
    border: 1px solid var(--border-color);
    border-radius: 12px;
    overflow: hidden;
    background: var(--bg-white);
    transition: border-color .18s ease, box-shadow .18s ease;
}

.adm-policy-matrix > div:hover {
    border-color: var(--ecv-muted, #73787b);
    box-shadow: 0 6px 18px rgba(23, 25, 27, .06);
}

/* The section header: its own tone, and it stays put while its rows scroll past. */
.adm-policy-matrix > div > div:first-child {
    position: sticky;
    top: 0;
    z-index: 1;
    background: var(--ecv-soft, #f0f0ee);
    border-bottom: 1px solid var(--border-color);
}

.adm-policy-matrix > div > div:first-child b {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    min-width: 0;
    font-size: 13px;
    letter-spacing: -.01em;
    color: var(--text-color);
}

.adm-policy-matrix > div > div:first-child b i {
    width: 18px;
    text-align: center;
    color: var(--text-light);
}

/* A child row. Hoverable, because every one of them is a control. */
.adm-policy-matrix label {
    cursor: pointer;
    font-size: 12.5px;
    transition: background-color .14s ease;
}

.adm-policy-matrix label:hover {
    background: var(--hover-bg, #f5f5f3);
}

.adm-policy-matrix label > span {
    min-width: 0;
    overflow-wrap: anywhere;
    color: var(--text-light);
}

/* The mode column. Same width on every row, section or child, so the controls line up into a
 * column that can be read down. */
.adm-policy-matrix .policyMode {
    width: 100%;
    min-width: 0;
    height: 34px;
    font-size: 12.5px;
}

.adm-policy-matrix .policySectionMode {
    font-weight: 700;
}

/* Narrow: the mode drops under its label rather than squeezing both into nothing. */
@media (max-width: 720px) {
    .adm-policy-matrix > div > div:first-child,
    .adm-policy-matrix label {
        grid-template-columns: 1fr !important;
        gap: 8px !important;
    }

    .adm-policy-matrix label > span {
        padding-inline-start: 0 !important;
    }
}
/* Typed operational feedback. Sync results use these variants so success and failure are
 * distinguishable at a glance while the message remains an accessible live region. */
.adm-page .up-toast,
.dp-portal .up-toast,
body.has-portal-chrome .up-toast {
    display: flex;
    align-items: center;
    gap: 10px;
    max-width: min(560px, calc(100vw - 32px));
    border: 1px solid transparent;
    box-shadow: 0 12px 34px rgba(0, 0, 0, .22);
    font-weight: 700;
}

body.has-portal-chrome .up-toast::before {
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    font-size: 13px;
    font-weight: 900;
}

body.has-portal-chrome .up-toast.is-success {
    border-color: #2f7d55;
    background: #123b2a;
    color: #f2fff8;
}

body.has-portal-chrome .up-toast.is-success::before {
    content: "✓";
    background: #dff7e9;
    color: #123b2a;
}

body.has-portal-chrome .up-toast.is-error {
    border-color: #b94a48;
    background: #551d1d;
    color: #fff7f7;
}

body.has-portal-chrome .up-toast.is-error::before {
    content: "!";
    background: #ffe2e0;
    color: #551d1d;
}

/* --- Organisation tree --------------------------------------------------------
 *
 * A tree drawn as rows, not as a diagram. Indentation carries the depth (set inline,
 * because depth is data and not a class), the row is the whole hit area for dragging,
 * and the drop target is marked on the row rather than the list — dropping "between"
 * two units means nothing here, since order inside a parent is alphabetical.
 *
 * No max depth in the CSS either: the indent is computed per row, so a tree eight
 * levels deep renders the same way a tree two levels deep does.
 */

.adm-tree-list {
    list-style: none;
    margin: 0;
    padding: 0;
}

.adm-tree-root {
    border: 1px solid var(--border-color);
    border-radius: var(--ecv-radius-card, 14px);
    overflow: hidden;
    background-color: var(--bg-white);
}

.adm-tree-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 12px;
    border-bottom: 1px solid var(--border-color-light, var(--border-color));
    font-size: 13px;
    cursor: grab;
}

.adm-tree-item:last-child > .adm-tree-row { border-bottom: 0; }

.adm-tree-row:hover { background-color: var(--ecv-soft); }

/* The drop target is stated, not implied: a dashed inset ring reads as "this will
 * receive it" without moving anything, so the row under the pointer never shifts. */
.adm-tree-row.is-drop-target {
    outline: 2px dashed var(--primary-color);
    outline-offset: -3px;
    background-color: var(--ecv-soft);
}

.adm-tree-row.is-muted { opacity: .55; }

.adm-tree-mark {
    flex: 0 0 auto;
    color: var(--text-light);
    font-size: 12px;
}

.adm-tree-name {
    font-weight: 700;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.adm-tree-type {
    flex: 0 0 auto;
    font-size: 10.5px;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--text-light);
}

.adm-tree-meta {
    flex: 0 0 auto;
    font-size: 11.5px;
    color: var(--text-light);
}

/* Actions sit at the end of the row in both directions — logical margin, not left/right. */
.adm-tree-actions {
    margin-inline-start: auto;
    display: flex;
    gap: 4px;
}

/* ---------------------------------------------------------------------------
 * Organisation policy — the radio list
 * ---------------------------------------------------------------------------
 *
 * Each option carries the sentence that says what it does, because these settings change
 * what every manager in the company can read and the difference between "metadata only"
 * and "all permitted" is not guessable from the label alone. The help text is therefore
 * part of the control, not a tooltip somebody has to go looking for.
 */
.adm-radio-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-top: 12px;
}

.adm-radio-row {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 12px 14px;
    border: 1px solid var(--adm-border, rgba(0, 0, 0, 0.12));
    border-radius: 8px;
    cursor: pointer;
    transition: border-color 0.15s ease, background 0.15s ease;
}

.adm-radio-row:hover {
    border-color: var(--adm-accent, #0f6f5c);
}

.adm-radio-row.is-active {
    border-color: var(--adm-accent, #0f6f5c);
    background: rgba(15, 111, 92, 0.06);
}

.adm-radio-row input {
    margin-top: 3px;
    flex: 0 0 auto;
}

.adm-radio-row span {
    display: flex;
    flex-direction: column;
    gap: 3px;
}

.adm-radio-row small {
    opacity: 0.78;
    line-height: 1.45;
}

.adm-radio-row input:disabled {
    cursor: not-allowed;
}

.adm-radio-row:has(input:disabled) {
    cursor: default;
    opacity: 0.8;
}

/* ---------------------------------------------------------------------------
 * Classification
 * ---------------------------------------------------------------------------
 *
 * A classified ticket has to announce itself before it is read, not after. The banner sits
 * directly under the ticket header for that reason, and the pill repeats it in the queue so
 * that opening one is never a surprise.
 *
 * The control itself is drawn DISABLED rather than hidden when the reader holds no clearance:
 * somebody who cannot reclassify a ticket still needs to see what it is classified as, and
 * hiding the field would keep the level from exactly the people most likely to mishandle it.
 */
.adm-classification-banner {
    /* The detail card is a 12-column grid; without this the banner is squeezed into one
       column and reads as a vertical ribbon of single words. */
    grid-column: 1 / -1;
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 0 0 4px;
    padding: 10px 16px;
    font-size: 0.83rem;
    font-weight: 600;
    line-height: 1.4;
    border-inline-start: 3px solid currentColor;
}

.adm-classification-banner[data-level="restricted"] {
    background: rgba(183, 121, 31, 0.1);
    color: #8a5a13;
}

.adm-classification-banner[data-level="confidential"] {
    background: rgba(155, 44, 44, 0.1);
    color: #86251f;
}

:root[data-theme="dark"] .adm-classification-banner[data-level="restricted"] {
    background: rgba(214, 158, 46, 0.14);
    color: #e5b95e;
}

:root[data-theme="dark"] .adm-classification-banner[data-level="confidential"] {
    background: rgba(197, 76, 68, 0.16);
    color: #f0928a;
}

.adm-classification-pill[data-level="restricted"] {
    background: rgba(183, 121, 31, 0.16);
    color: #8a5a13;
    border-color: rgba(183, 121, 31, 0.4);
}

.adm-classification-pill[data-level="confidential"] {
    background: rgba(155, 44, 44, 0.16);
    color: #86251f;
    border-color: rgba(155, 44, 44, 0.45);
}

:root[data-theme="dark"] .adm-classification-pill[data-level="restricted"] {
    background: rgba(214, 158, 46, 0.18);
    color: #e5b95e;
}

:root[data-theme="dark"] .adm-classification-pill[data-level="confidential"] {
    background: rgba(197, 76, 68, 0.2);
    color: #f0928a;
}

#mdConfidentiality:disabled {
    cursor: not-allowed;
    opacity: 0.75;
}

/* ---------------------------------------------------------------------------
 * Support queues
 * ---------------------------------------------------------------------------
 *
 * Cards rather than a table, because the useful comparison between two queues is "how is
 * this one staffed and how does it choose", which is four or five facts — a table of that
 * is mostly empty cells and a horizontal scroll on a laptop.
 */
.adm-queue-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr));
    gap: 14px;
}

.adm-queue-card {
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 16px;
}

/* An inactive queue routes nothing. Saying so quietly beats hiding it, because a queue that
   has vanished from the list looks like a queue somebody deleted. */
.adm-queue-card.is-off {
    opacity: 0.62;
}

.adm-queue-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 10px;
}

.adm-queue-head b {
    display: block;
    font-size: 1.02rem;
}

.adm-queue-head small {
    display: block;
    margin-top: 2px;
    opacity: 0.7;
}

.adm-queue-facts {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px 14px;
    margin: 0;
}

.adm-queue-facts dt {
    font-size: 0.74rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    opacity: 0.65;
}

.adm-queue-facts dd {
    margin: 2px 0 0;
    font-weight: 600;
}

.adm-queue-foot {
    display: flex;
    justify-content: flex-end;
    margin-top: auto;
}

/* One row per day, so a week reads as a week. */
.adm-hours-grid {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-top: 6px;
}

.adm-hours-row {
    display: grid;
    grid-template-columns: 3.2rem 1fr auto 1fr;
    align-items: center;
    gap: 8px;
}

.adm-hours-row label {
    text-transform: uppercase;
    font-size: 0.76rem;
    letter-spacing: 0.05em;
    opacity: 0.75;
}

.adm-check-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 190px), 1fr));
    gap: 6px 14px;
    margin-top: 6px;
}

/* The queue drawer carries a member table, which needs more room than the standard drawer. */
.adm-drawer.adm-drawer-wide {
    max-width: min(760px, 96vw);
}

/* A checkbox and its label belong on one line. Inside the category grid the label text is
   long enough to wrap, and without this the box sits above the text rather than beside it. */
.adm-check-grid .up-check {
    align-items: flex-start;
    line-height: 1.35;
}

.adm-check-grid .up-check input {
    flex: 0 0 auto;
    margin-top: 1px;
}

/* ---------------------------------------------------------------------------
 * The workflow editor
 * ---------------------------------------------------------------------------
 *
 * A card per state with its outgoing moves listed underneath, because "what can happen next"
 * is the question somebody opening this screen actually has. A from/to table answers it only
 * after you have read the whole thing.
 */
.adm-enforce-card {
    padding: 14px 16px;
    border-inline-start: 3px solid var(--ecv-line, rgba(0, 0, 0, 0.15));
}

/* An applied workflow refuses moves. That is worth seeing before you scroll. */
.adm-enforce-card.is-on {
    border-inline-start-color: #b7791f;
    background: rgba(183, 121, 31, 0.07);
}

.adm-enforce-state {
    margin: 8px 0 0;
    font-weight: 600;
    font-size: 0.84rem;
}

.adm-state-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 330px), 1fr));
    gap: 14px;
    margin-top: 14px;
}

.adm-state-card {
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 14px 16px;
}

.adm-state-card[data-category="done"] { opacity: 0.9; }

.adm-state-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 10px;
}

/* The stored value, shown as code because that is what it is — the string on the row, not a
   label. Keeping it visible is the whole defence against somebody "tidying up" a state name. */
.adm-state-key {
    display: block;
    margin-top: 2px;
    font-size: 0.74rem;
    opacity: 0.6;
}

.adm-move-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.adm-move-list li {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px;
    font-size: 0.86rem;
}

.adm-move-list code {
    font-size: 0.72rem;
    opacity: 0.7;
}

.adm-move-empty {
    opacity: 0.6;
    font-style: italic;
}

.adm-state-foot {
    display: flex;
    justify-content: flex-end;
    margin-top: auto;
}

/* Custom roles: the org permission catalogue, grouped by its own categories. Thirty
   checkboxes in one flat list is a list nobody reads to the end. */
.adm-perm-group {
    margin-top: 12px;
}

.adm-perm-group > b {
    display: block;
    margin-bottom: 6px;
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    opacity: 0.7;
}

/* A permission the catalogue marks dangerous. Not hidden and not disabled — the database
   decides whether it may be granted; this only makes sure nobody ticks one by accident. */
.up-check.is-dangerous span {
    color: #9b2c2c;
}

:root[data-theme="dark"] .up-check.is-dangerous span {
    color: #f0928a;
}

.up-check.is-dangerous i {
    margin-inline-start: 4px;
    font-size: 0.78em;
}

/* Approvals and coverage gaps on the ticket record. */
.adm-approval-block {
    grid-column: 1 / -1;
}

.adm-approval-state {
    margin: 6px 0;
    font-weight: 600;
    font-size: 0.88rem;
}

.adm-approval-state.is-ok { color: #276749; }
.adm-approval-state.is-no { color: #9b2c2c; }

/* "You are the one being asked" needs to read differently from "somebody is being asked". */
.adm-approval-state.is-you {
    padding: 8px 12px;
    border-radius: 6px;
    background: rgba(49, 130, 206, 0.12);
    color: #2a4365;
}

:root[data-theme="dark"] .adm-approval-state.is-ok { color: #7fd1a3; }
:root[data-theme="dark"] .adm-approval-state.is-no { color: #f0928a; }
:root[data-theme="dark"] .adm-approval-state.is-you {
    background: rgba(99, 179, 237, 0.16);
    color: #a8d4f5;
}

/* A ticket nobody qualified can take is not merely unassigned, and should not look it. */
.adm-approval-gap {
    margin: 0 0 10px;
    padding: 10px 14px;
    border-radius: 6px;
    border-inline-start: 3px solid #b7791f;
    background: rgba(183, 121, 31, 0.1);
    color: #8a5a13;
    font-size: 0.86rem;
    line-height: 1.45;
}

:root[data-theme="dark"] .adm-approval-gap {
    background: rgba(214, 158, 46, 0.14);
    color: #e5b95e;
}

/* The dashboard's scope band. */
.adm-scope-block {
    margin: 16px 0;
}

.adm-scope-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
}

.adm-scope-head h3 {
    margin: 0;
}

.adm-scope-picker {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 0.84rem;
}

.adm-scope-picker select {
    min-width: 200px;
}

.adm-workload-card {
    padding: 14px 16px;
}

.adm-workload-card h3 {
    margin: 0 0 10px;
    font-size: 0.92rem;
}

/* Two workload tables side by side on a laptop, stacked on a phone. */
@media (max-width: 860px) {
    .adm-scope-picker select { min-width: 0; width: 100%; }
    .adm-scope-picker { width: 100%; }
}

/* ---------------------------------------------------------------------------
 * The organisation tree
 * ---------------------------------------------------------------------------
 *
 * Depth was expressed as `padding-inline-start: depth * 22px` on the row and nothing else,
 * which reads as a slightly ragged flat list rather than a tree — at 22px a reader cannot
 * reliably tell a child from a sibling, and the screenshot that prompted this had queues,
 * functions and brands all apparently at the same level.
 *
 * So depth becomes a custom property driving both the indent AND a guide line per level, and
 * the row gains a disclosure arrow. Guides are drawn on the <ul>, not per row, so they run
 * the height of a branch instead of restarting on every line.
 */
.adm-tree-list {
    list-style: none;
    margin: 0;
    padding: 0;
}

.adm-tree-list .adm-tree-list {
    /* The guide for THIS level. Inline-start so it flips with the document direction. */
    position: relative;
    margin-inline-start: 1.35rem;
    border-inline-start: 1px solid var(--adm-border, rgba(128, 128, 128, 0.28));
}

.adm-tree-item.is-collapsed > .adm-tree-list {
    display: none;
}

.adm-tree-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 7px 10px;
    border-radius: 7px;
    /* The nested <ul> borders already carry the indent; this is the small step that separates
       a row from its own guide line. */
    padding-inline-start: 8px;
    transition: background 0.12s ease;
}

.adm-tree-row:hover {
    background: color-mix(in srgb, currentColor 6%, transparent);
}

.adm-tree-row.is-muted {
    opacity: 0.55;
}

/* The arrow is a real button: a branch you can only open by guessing is not navigable by
   keyboard, and these trees get deep. */
.adm-tree-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 1.15rem;
    height: 1.15rem;
    padding: 0;
    border: 0;
    border-radius: 4px;
    background: transparent;
    color: inherit;
    opacity: 0.75;
    cursor: pointer;
    font-size: 0.7rem;
}

.adm-tree-toggle:hover { opacity: 1; }
.adm-tree-toggle.is-leaf { cursor: default; opacity: 0; }
.adm-tree-toggle:focus-visible { outline: 2px solid currentColor; outline-offset: 1px; }

.adm-tree-name {
    font-weight: 600;
}

.adm-tree-type {
    font-size: 0.68rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    opacity: 0.55;
}

/* Counts are now shown only when non-zero, so they mean something when they appear —
   "0 member(s)" on forty rows was noise that made the real numbers hard to find. */
.adm-tree-meta {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 0.74rem;
    opacity: 0.7;
    white-space: nowrap;
}

.adm-tree-meta.is-folded {
    font-style: italic;
}

.adm-tree-actions {
    margin-inline-start: auto;
    display: inline-flex;
    gap: 4px;
    opacity: 0;
    transition: opacity 0.12s ease;
}

.adm-tree-row:hover .adm-tree-actions,
.adm-tree-row:focus-within .adm-tree-actions {
    opacity: 1;
}

/* On a touch screen there is no hover, so the actions are always there. */
@media (hover: none) {
    .adm-tree-actions { opacity: 1; }
}

/* The drop target while dragging a unit. */
.adm-tree-row.is-drop-target {
    background: color-mix(in srgb, var(--adm-accent, #0f6f5c) 16%, transparent);
    outline: 1px dashed var(--adm-accent, #0f6f5c);
}

/* "Live" — a claim, so it is only made while the channel is actually open. */
.adm-live-dot {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-inline-start: auto;
    font-size: 0.74rem;
    opacity: 0.7;
}

.adm-live-dot i {
    font-size: 0.5rem;
    color: #2f855a;
}

.adm-live-dot.is-pulsing i {
    animation: adm-live-pulse 1.6s ease-in-out infinite;
}

@keyframes adm-live-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.25; }
}

@media (prefers-reduced-motion: reduce) {
    .adm-live-dot.is-pulsing i { animation: none; }
}

/* A phone has no room for the type label or the manager beside a deep name. */
@media (max-width: 700px) {
    .adm-tree-list .adm-tree-list { margin-inline-start: 0.85rem; }
    .adm-tree-row { flex-wrap: wrap; gap: 6px; }
    .adm-tree-type { display: none; }
    .adm-tree-actions { margin-inline-start: auto; }
}

/* The tree toolbar: find, fold, and hide what is switched off. */
.adm-tree-toolbar {
    flex-wrap: wrap;
    gap: 10px;
}

.adm-tree-search {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 0 10px;
    min-width: min(100%, 240px);
    border: 1px solid var(--adm-border, rgba(128, 128, 128, 0.28));
    border-radius: 8px;
}

.adm-tree-search i {
    opacity: 0.55;
    font-size: 0.8rem;
}

.adm-tree-search input {
    border: 0;
    background: transparent;
    color: inherit;
    font: inherit;
    padding: 7px 0;
    min-width: 0;
    flex: 1;
}

.adm-tree-search input:focus { outline: none; }
.adm-tree-search:focus-within { border-color: var(--adm-accent, #0f6f5c); }

.adm-tree-toggle-disabled {
    font-size: 0.8rem;
    white-space: nowrap;
}

/* A queue reads differently from a brand. The type label already says which, but at twenty
   rows nobody reads twenty type labels — the weight does the work instead. */
.adm-tree-row .adm-tree-name { font-weight: 600; }

.adm-tree-item[data-depth="0"] > .adm-tree-row .adm-tree-name { font-weight: 700; }

@media (max-width: 700px) {
    .adm-tree-search { min-width: 100%; }
}
