/* ==========================================================================
   MTCOM — New Visual Identity  ("Campus Operations Console")
   --------------------------------------------------------------------------
   Owner-approved direction (2026-09-23): deep INDIGO structure + a single
   SAFFRON accent, Readex Pro (Latin + Arabic) with IBM Plex Mono for codes.

   This layer is loaded AFTER mtcom-design-system.css and OVERRIDES the
   identity only — colour, type, and the treatment of shared components. The
   original stylesheet stays as structural scaffolding (layout, spacing,
   responsive, RTL plumbing) and as the rollback (remove this <link> to revert).
   Because the whole console reads its identity from these ~120 tokens,
   redefining them re-skins every page at once.

   Contrast note: the indigo carries white text (--on-brand); the bright
   saffron carries DARK text (--on-accent). Never white on saffron.
   ========================================================================== */

:root {
    /* Brand = indigo structure (safe with white text) */
    --brand-primary:        #26365F;
    --brand-primary-hover:  #1E2B4C;
    --brand-primary-dark:   #16203A;
    --brand-primary-light:  #33477A;
    --brand-primary-tint:   #EEF1F8;
    --brand-primary-border: #C6CFE4;

    /* Accent = saffron (highlights, active marks, focus, key figures) */
    --brand-accent:         #F4A62A;
    --brand-accent-hover:   #DD8E12;
    --brand-accent-tint:    #FCEFD6;
    --brand-accent-border:  #F6D79B;

    /* Text colours ON the brand / accent fills */
    --on-brand:             #FFFFFF;
    --on-accent:            #2A1B02;

    /* Indigo used AS TEXT (links, selected labels, icons). --brand-primary
       stays for fills; in dark it is too dim to read as text (2.5:1), so
       every "indigo as text" rule uses this token instead. */
    --brand-link:           #26365F;
    --brand-link-hover:     #1E2B4C;
    /* Saffron label on an indigo fill (active navigation, 5.8:1). */
    --accent-on-brand:      #F4A62A;
    --nav-active-bg:        #26365F;
    /* Saffron as text/icon on a light tint (the fill itself is too pale). */
    --accent-text:          #8A5A0C;
    /* Warning glyph on the warning tint (the accent is 2.3:1 there). */
    --warning-icon:         #B8601C;

    /* Solid semantic fills that carry WHITE text (all >= 5:1). Warning is
       the saffron fill with --on-accent (dark) text instead. */
    --success-fill: #17744A; --success-fill-hover: #14663F;
    --danger-fill:  #C62F35; --danger-fill-hover:  #A32126;
    --info-fill:    #2F5BC4; --info-fill-hover:    #1E4293;
    --neutral-fill: #56627C; --neutral-fill-hover: #454F66;
    /* Neutral (closed / secondary) chips */
    --neutral-bg: #EDF0F6; --neutral-border: #C9D0E0; --neutral-text: #4A5570;

    /* Form-control outline in dark (kept for parity; light uses the base) */
    --border-control:       #C9D0E0;

    /* Surfaces — cool porcelain */
    --bg-page:              #EEF1F7;
    --bg-page-subtle:       #E6EAF3;
    --bg-card:              #FFFFFF;
    --bg-card-subtle:       #F6F7FB;
    --bg-card-hover:        #F1F3FA;
    --bg-card-active:       #E7EBF4;
    --bg-surface:           #FFFFFF;
    --bg-surface-glass:     rgba(255, 255, 255, 0.90);
    --bg-overlay:           rgba(16, 22, 43, 0.62);

    /* Ink — deep indigo-ink */
    --ink-primary:          #14203B;
    --ink-secondary:        #2A3654;
    --ink-muted:            #55617C;
    --ink-subtle:           #636E88;  /* was #8892A8 (3.1:1 on white); now >= 4.5:1 on the page ground */
    --ink-inverse:          #FFFFFF;

    /* Borders */
    --border-light:         #E2E6F0;
    --border-subtle:        #EDF0F7;
    --border-strong:        #C9D0E0;
    --border-focus:         #F4A62A;

    /* Semantic status */
    --success-bg:           #E4F5EC; --success-border: #B6E3CB; --success-text: #14663F; --success-accent: #1F9D6B;
    --danger-bg:            #FBE5E6; --danger-border: #F3C3C5; --danger-text: #A32126; --danger-accent: #E5484D; --danger-hover: #CE3238;
    --warning-bg:           #FBEAD8; --warning-border: #F4CFA6; --warning-text: #8A4B12; --warning-accent: #E8823A;
    --info-bg:              #E4ECFB; --info-border: #BFD2F5; --info-text: #1E4293; --info-accent: #3B6FE0;

    /* KPI category tiles (kept meaningful, retuned to the palette) */
    --kpi-tickets-bg:       linear-gradient(145deg, #E9EFFC 0%, #FFFFFF 100%);
    --kpi-tickets-border:   #BFD2F5; --kpi-tickets-top: #3B6FE0; --kpi-tickets-text: #17356E; --kpi-tickets-label: #2F55B5;

    --kpi-tasks-bg:         linear-gradient(145deg, #FCEFD6 0%, #FFFFFF 100%);
    --kpi-tasks-border:     #F6D79B; --kpi-tasks-top: #E08E12; --kpi-tasks-text: #7A4B08; --kpi-tasks-label: #A9660C;

    --kpi-critical-bg:      linear-gradient(145deg, #FBE5E6 0%, #FFFFFF 100%);
    --kpi-critical-border:  #F3C3C5; --kpi-critical-top: #E5484D; --kpi-critical-text: #8F1E22; --kpi-critical-label: #B4292E;

    --kpi-inventory-bg:     linear-gradient(145deg, #FBEAD8 0%, #FFFFFF 100%);
    --kpi-inventory-border: #F4CFA6; --kpi-inventory-top: #E8823A; --kpi-inventory-text: #7A3F14; --kpi-inventory-label: #99521B;

    --kpi-facility-bg:      linear-gradient(145deg, #E4F5EC 0%, #FFFFFF 100%);
    --kpi-facility-border:  #B6E3CB; --kpi-facility-top: #1F9D6B; --kpi-facility-text: #124D34; --kpi-facility-label: #16663F;

    /* Type — Readex Pro (display + body, incl. Arabic), IBM Plex Mono (codes) */
    --font-sans:   'Readex Pro', 'Segoe UI', system-ui, -apple-system, 'Google Sans', sans-serif;
    --font-arabic: 'Readex Pro', 'Noto Kufi Arabic', Tahoma, 'Segoe UI', sans-serif;
    --font-mono:   'IBM Plex Mono', ui-monospace, 'JetBrains Mono', SFMono-Regular, Menlo, Consolas, monospace;
    --font-family-base: var(--font-sans);
    --font-primary: var(--font-family-base);
    --bs-body-font-family: var(--font-family-base);
    --bs-font-sans-serif: var(--font-family-base);
}

[data-theme="dark"] {
    --brand-primary:        #4A62A0;
    --brand-primary-hover:  #5A73B5;
    --brand-primary-dark:   #33477A;
    --brand-primary-light:  #7186C4;
    --brand-primary-tint:   rgba(74, 98, 160, 0.18);
    --brand-primary-border: rgba(110, 134, 200, 0.42);

    --brand-accent:         #F7B441;
    --brand-accent-hover:   #FFC766;
    --brand-accent-tint:    rgba(247, 180, 65, 0.16);
    --brand-accent-border:  rgba(247, 180, 65, 0.40);

    --on-brand:             #FFFFFF;
    --on-accent:            #2A1B02;

    --brand-link:           #A9B8EC;  /* 8.5:1 on #151E33, 7.5:1 on #1E293B */
    --brand-link-hover:     #C9D3F5;
    --accent-on-brand:      #FFC766;  /* on --nav-active-bg: 5.9:1 */
    --nav-active-bg:        #33477A;
    --accent-text:          #F7C877;
    --warning-icon:         #F0A567;

    --success-fill: #17744A; --success-fill-hover: #1B8556;
    --danger-fill:  #C62F35; --danger-fill-hover:  #B3292F;
    --info-fill:    #2F5BC4; --info-fill-hover:    #2A52B2;
    --neutral-fill: #56627C; --neutral-fill-hover: #5F6B85;
    --neutral-bg: rgba(154, 163, 188, 0.16); --neutral-border: rgba(154, 163, 188, 0.34); --neutral-text: #C7CEE0;

    --border-control:       #46557F;

    --bg-page:              #0D1322;
    --bg-page-subtle:       #131B2D;
    --bg-card:              #151E33;
    --bg-card-subtle:       #1B2540;
    --bg-card-hover:        #212C4A;
    --bg-card-active:       #2A375A;
    --bg-surface:           #151E33;
    --bg-surface-glass:     rgba(21, 30, 51, 0.92);
    --bg-overlay:           rgba(0, 0, 0, 0.72);

    --ink-primary:          #E8ECF7;
    --ink-secondary:        #C7CEE0;
    --ink-muted:            #9AA3BC;
    --ink-subtle:           #8A94AE;  /* was #6E7893 (3.8:1 on cards) */
    --ink-inverse:          #0D1322;

    --border-light:         #26314C;
    --border-subtle:        #1D2740;
    --border-strong:        #35426A;
    --border-focus:         #F7B441;

    --success-bg: rgba(31,157,107,0.16); --success-border: rgba(31,157,107,0.40); --success-text: #40C892; --success-accent: #26A877;
    --danger-bg:  rgba(229,72,77,0.16);  --danger-border: rgba(229,72,77,0.40);  --danger-text: #F1888C; --danger-accent: #EC5B60; --danger-hover: #E5484D;
    --warning-bg: rgba(232,130,58,0.16); --warning-border: rgba(232,130,58,0.40); --warning-text: #F0A567; --warning-accent: #EE9350;
    --info-bg:    rgba(59,111,224,0.16); --info-border: rgba(59,111,224,0.40); --info-text: #7EA0F0; --info-accent: #547FE6;

    --kpi-tickets-bg:   linear-gradient(145deg, rgba(59,111,224,0.15) 0%, #151E33 100%);
    --kpi-tickets-border: rgba(59,111,224,0.40); --kpi-tickets-top: #547FE6; --kpi-tickets-text: #9DB6F2; --kpi-tickets-label: #BFD2F5;

    --kpi-tasks-bg:     linear-gradient(145deg, rgba(244,166,42,0.15) 0%, #151E33 100%);
    --kpi-tasks-border: rgba(244,166,42,0.40); --kpi-tasks-top: #F7B441; --kpi-tasks-text: #F7C877; --kpi-tasks-label: #F6D79B;

    --kpi-critical-bg:  linear-gradient(145deg, rgba(229,72,77,0.15) 0%, #151E33 100%);
    --kpi-critical-border: rgba(229,72,77,0.40); --kpi-critical-top: #EC5B60; --kpi-critical-text: #F1888C; --kpi-critical-label: #F3C3C5;

    --kpi-inventory-bg: linear-gradient(145deg, rgba(232,130,58,0.15) 0%, #151E33 100%);
    --kpi-inventory-border: rgba(232,130,58,0.40); --kpi-inventory-top: #EE9350; --kpi-inventory-text: #F0A567; --kpi-inventory-label: #F4CFA6;

    --kpi-facility-bg:  linear-gradient(145deg, rgba(31,157,107,0.15) 0%, #151E33 100%);
    --kpi-facility-border: rgba(31,157,107,0.40); --kpi-facility-top: #26A877; --kpi-facility-text: #40C892; --kpi-facility-label: #B6E3CB;
}

/* --------------------------------------------------------------------------
   Component polish — a few deliberate treatments beyond the tokens.
   Kept minimal and safe; per-page refinement follows.
   -------------------------------------------------------------------------- */

/* Focus is the saffron accent everywhere (distinctive, high-visibility). */
:where(a, button, input, select, textarea, [tabindex]):focus-visible {
    outline: 2px solid var(--brand-accent) !important;
    outline-offset: 2px !important;
    border-radius: var(--radius-xs);
}

/* The brand mark / avatars: indigo with a saffron base edge. The white
   letter never sits on saffron (an indigo -> saffron gradient left the
   letter at 2.0:1 where it crossed the saffron end); fixed hexes, so the
   dark tokens cannot thin it out: white on #26365F..#33477A >= 9:1. */
.brand-logo, .brand-logo-icon, .drawer-user-avatar, .avatar-bubble, .topbar-brand-mark {
    background: linear-gradient(150deg, #26365F, #33477A) !important;
    box-shadow: inset 0 -3px 0 #F4A62A !important;
    color: var(--on-brand) !important;
}
/* Profile button: was indigo -> cyan (white letter 4.1:1); now all indigo. */
.topbar-user-avatar {
    background: linear-gradient(135deg, var(--brand-primary-dark), var(--brand-primary)) !important;
}

/* Active navigation: indigo fill with a saffron label and edge (matches the
   approved preview). The label was --brand-accent-hover, 4.5:1 in light and
   3.8:1 in dark; --accent-on-brand on --nav-active-bg is 5.8 / 5.9:1. */
.desktop-nav a.active,
.nav-dropdown-menu a.active,
.drawer-content a.active {
    background: var(--nav-active-bg) !important;
    color: var(--accent-on-brand) !important;
    border-color: var(--brand-accent) !important;
    box-shadow: 0 2px 8px rgba(22, 32, 58, 0.28) !important;
}

/* Selected filter pill = a selection, so indigo (not saffron text, which
   read 2.3:1 on the tint). Same shape the base gives hover + active. */
.mtcom-filter-pill:hover,
.filter-pill:hover,
.mtcom-filter-pill.active,
.filter-pill.active,
[data-theme="dark"] .mtcom-filter-pill:hover,
[data-theme="dark"] .filter-pill:hover,
[data-theme="dark"] .mtcom-filter-pill.active,
[data-theme="dark"] .filter-pill.active {
    background: var(--brand-primary-tint) !important;
    border-color: var(--brand-link) !important;
    color: var(--brand-link) !important;
}

/* Links: indigo at rest, deeper indigo on hover (saffron only as the
   underline colour; saffron text is 2.6:1 on white).
   :where() keeps this rule as weak as a bare `a`, so every component that
   paints its own anchor colour (facet chips, code pills, tiles, tabs, menu
   items, pagination) keeps it; only plain text links take the link colour. */
:where(.mtcom-page) a:where(:not(.btn):not(.nav-link):not(.mtcom-filter-pill):not([class*="badge"])) {
    color: var(--brand-link);
    text-underline-offset: 2px;
}
:where(.mtcom-page) a:where(:not(.btn):not(.nav-link):not(.mtcom-filter-pill):not([class*="badge"])):hover {
    color: var(--brand-link-hover);
    text-decoration-color: var(--brand-accent);
}

/* Numeric/code columns read in the mono face for alignment and character. */
.mono, .tid, .num, code, kbd, .code-chip { font-family: var(--font-mono); }

/* --------------------------------------------------------------------------
   Type fix. The legacy base (soft-ui) sets `.card .card-body` to "Open Sans"
   with NO fallback, and Open Sans was never loaded — so every card body in
   the console fell back to the browser's serif. It now uses the house face.
   -------------------------------------------------------------------------- */
.card .card-body { font-family: var(--font-family-base); }
.text-sans-serif { font-family: var(--font-family-base) !important; }

/* --------------------------------------------------------------------------
   Literal colours that the legacy design system hard-codes (not tokens),
   re-pointed at the new palette. Selections -> indigo; "live/online" -> green;
   icons -> contrast-safe. Same selectors, loaded later, so these win.
   -------------------------------------------------------------------------- */

/* KPI tile accent stripes (decorative). Scheduled work = saffron. */
.tile-blue   { --tile-accent: var(--info-accent); }
.tile-purple { --tile-accent: var(--brand-accent); }
.tile-green  { --tile-accent: var(--success-accent); }
.tile-red    { --tile-accent: var(--danger-accent); }
.tile-amber  { --tile-accent: var(--warning-accent); }
.tile-slate  { --tile-accent: var(--ink-subtle); }
.tile-teal   { --tile-accent: var(--brand-primary); }

/* KPI icon glyphs (need contrast, so indigo rather than saffron). */
.kpi-blue .kpi-icon-box    { color: var(--info-accent); }
.kpi-emerald .kpi-icon-box { color: var(--success-accent); }
.kpi-violet .kpi-icon-box  { color: var(--brand-link); }

/* The active dashboard / Command Center tab is a selection -> indigo.
   `.cc-nav-tabs` prefix: the Command Center page styles its own active tab
   green after this file loads; green is reserved for done/live/success. */
.cc-nav-pill.active,
.cc-nav-tabs .cc-nav-pill.active {
    background: var(--brand-primary);
    color: var(--on-brand) !important;
    box-shadow: 0 2px 8px rgba(38, 54, 95, 0.28);
}
.cc-nav-pill.active .badge,
.cc-nav-tabs .cc-nav-pill.active .badge {
    background: #ffffff !important;
    color: var(--brand-primary) !important;
    border-color: #ffffff !important;
}
/* Icons in the selected tab follow its white label (a coloured icon on the
   indigo fill read 1.9-2.9:1). */
.cc-nav-tabs .cc-nav-pill.active > :is(i, svg) { color: inherit !important; }
/* Its hover was a hard-coded light grey, so in dark the label vanished. */
[data-theme="dark"] .cc-nav-tabs .cc-nav-pill:not(.active):hover {
    background: var(--bg-card-hover);
    color: var(--ink-primary);
}

/* Live / online indicators keep their meaning: green. The base states these
   with !important, so they are restated the same way. */
.clock-badge.clock-server,
[data-theme="dark"] .clock-badge.clock-server {
    background: var(--success-bg) !important;
    border-color: var(--success-border) !important;
    color: var(--success-text) !important;
}
.clock-dot.server-pulse,
.live-dot-pulse {
    background: var(--success-accent) !important;
    box-shadow: 0 0 0 2px rgba(31, 157, 107, 0.30) !important;
}
@keyframes pulseDot {
    0%   { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(31, 157, 107, 0.7); }
    70%  { transform: scale(1);    box-shadow: 0 0 0 6px rgba(31, 157, 107, 0); }
    100% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(31, 157, 107, 0); }
}

/* Hover / edit affordances. */
.action-icon-btn.btn-edit:hover { color: var(--brand-link); }
.text-purple                    { color: var(--brand-link) !important; }

/* Dark theme: the same selections and focus, readable on dark surfaces.
   (!important: the base states each of these with !important.) */
[data-theme="dark"] .mega-apps-search-box:focus-within {
    border-color: var(--brand-accent) !important;
    box-shadow: 0 0 0 3px rgba(247, 180, 65, 0.20) !important;
}
[data-theme="dark"] .mega-app-card:hover,
[data-theme="dark"] .drawer-launcher-btn,
[data-theme="dark"] .hover-shadow:hover { border-color: var(--brand-primary-light) !important; }
[data-theme="dark"] .topbar-mega-icon-btn {
    background: var(--bg-card-subtle) !important;
    border-color: var(--border-strong) !important;
    color: var(--brand-accent) !important;
}

/* --------------------------------------------------------------------------
   Indigo as TEXT. The base paints these with --brand-primary, which in dark
   (#4A62A0) reads 2.5-2.9:1 on the dark cards; --brand-link is the same
   indigo in light and a readable light indigo in dark.
   -------------------------------------------------------------------------- */
.desktop-nav a:where(:not(.active)):hover,
.nav-dropdown-btn:where(:not(.active)):hover,
.nav-dropdown-menu a:where(:not(.active)):hover,
.nav-dropdown-menu button:hover,
.user-menu-item:where(:not(.active)):hover,
.nav-dropdown-menu a:where(:not(.active)):hover svg,
.nav-dropdown-menu a:where(:not(.active)):hover i,
.user-menu-item:where(:not(.active)):hover svg,
.user-menu-item:where(:not(.active)):hover i,
.user-menu-role,
.theme-toggle-btn:hover,
.drawer-user-role,
.drawer-content a:where(:not(.active)):hover,
.drawer-content button:hover,
.mobile-bottom-nav a:hover,
.mobile-bottom-more:hover,
.mobile-bottom-nav a.active,
.mega-app-card:hover .mega-app-action-arrow,
.drawer-launcher-btn:not(:hover):not(:active) svg,
.dashboard-tabs a:hover,
.dashboard-tab-btn:hover,
.dropdown-item:hover,
.breadcrumb-item a,
.breadcrumb-item a:hover,
.th-sortable:hover,
.th-sortable a:hover {
    color: var(--brand-link) !important;
}
.btn-outline-primary {
    color: var(--brand-link) !important;
    border-color: var(--brand-link) !important;
}
/* Logout keeps its red, on the palette (#EF4444 on white was 3.8:1). Same
   selectors and weight as the base, so they still beat the hover above. */
.user-menu-logout,
.nav-dropdown-menu a[href*="logout"],
.user-menu-logout svg,
.user-menu-logout i,
.nav-dropdown-menu a[href*="logout"] svg,
.nav-dropdown-menu a[href*="logout"] i,
.user-menu-logout:hover,
.nav-dropdown-menu a[href*="logout"]:hover,
.user-menu-logout:hover svg,
.user-menu-logout:hover i,
.nav-dropdown-menu a[href*="logout"]:hover svg,
.nav-dropdown-menu a[href*="logout"]:hover i { color: var(--danger-text) !important; }
.user-menu-logout:hover,
.nav-dropdown-menu a[href*="logout"]:hover { background: var(--danger-bg) !important; }
.mtcom-kpi-icon.primary,
[data-theme="dark"] .mtcom-kpi-icon.primary {
    background: var(--brand-primary-tint);
    color: var(--brand-link);
    border-color: var(--brand-primary-border);
}
/* The campus icon in the top bar is not a "success": indigo like its label. */
.school-selector-btn .text-success { color: var(--brand-link) !important; }

/* --------------------------------------------------------------------------
   Dark ground and surfaces. The base pins the dark page, cards, table heads
   and inputs to legacy slate (#0B1120 / #1E293B / #0F172A) with !important,
   so the new tokens never reached them. Same selectors, restated.
   -------------------------------------------------------------------------- */
[data-theme="dark"] body.app-body {
    background-color: var(--bg-page) !important;
    color: var(--ink-primary) !important;
}
/* The sign-in layout (admin/layout/auth) keeps Soft-UI's light grey body
   (.bg-gray-100 !important) around the dark card. */
[data-theme="dark"] body.bg-gray-100 { background-color: var(--bg-page) !important; }
[data-theme="dark"] .topbar {
    background: var(--bg-surface-glass) !important;
    border-color: var(--border-light) !important;
}
[data-theme="dark"] .card,
[data-theme="dark"] .table-responsive,
[data-theme="dark"] .card-header {
    background: var(--bg-card) !important;
    border-color: var(--border-light) !important;
    color: var(--ink-primary) !important;
}
[data-theme="dark"] .card-header h4,
[data-theme="dark"] .card-header h5,
[data-theme="dark"] .card-header h6 { color: var(--ink-primary) !important; }
[data-theme="dark"] .table thead th {
    background: var(--bg-page-subtle) !important;
    color: var(--ink-muted) !important;
    border-color: var(--border-light) !important;
}
[data-theme="dark"] .table tbody td {
    color: var(--ink-primary) !important;
    border-color: var(--border-light) !important;
}
[data-theme="dark"] .table tbody tr:hover td { background: var(--bg-card-hover) !important; }
[data-theme="dark"] .form-control,
[data-theme="dark"] .form-select {
    background: var(--bg-page-subtle) !important;
    border-color: var(--border-control) !important;
    color: var(--ink-primary) !important;
}
[data-theme="dark"] .form-label,
[data-theme="dark"] label { color: var(--ink-secondary) !important; }
/* Focus on a field: indigo border (the base's) under the saffron focus glow
   the field and visitor pages use; the base glow was the old green. */
.form-control:focus,
.form-select:focus,
[data-theme="dark"] .form-control:focus,
[data-theme="dark"] .form-select:focus { box-shadow: 0 0 0 3px rgba(244, 166, 42, 0.32) !important; }
[data-theme="dark"] .form-control:focus,
[data-theme="dark"] .form-select:focus { border-color: var(--brand-link) !important; }
/* Soft-UI headings (and .h1-.h6) are #344767 in both themes (1.6:1 on a
   dark card). :where() keeps these as weak as Soft-UI's own rule, so any
   component that colours its heading still wins. */
:where([data-theme="dark"]) :is(h1, h2, h3, h4, h5, h6),
:where([data-theme="dark"]) :is(.h1, .h2, .h3, .h4, .h5, .h6) { color: var(--ink-primary); }

/* Modules launcher (dark) */
[data-theme="dark"] .mega-apps-modal,
[data-theme="dark"] .mega-apps-head,
[data-theme="dark"] .mega-apps-search-container {
    background: var(--bg-card) !important;
    border-color: var(--border-light) !important;
}
[data-theme="dark"] .mega-apps-close-btn,
[data-theme="dark"] .mega-apps-search-box {
    background: var(--bg-card-subtle) !important;
    border-color: var(--border-strong) !important;
}
[data-theme="dark"] .mega-apps-close-btn:hover { background: var(--bg-card-hover) !important; }
[data-theme="dark"] .mega-app-card {
    background: var(--bg-card-subtle) !important;
    border-color: var(--border-light) !important;
}
[data-theme="dark"] .mega-app-card:hover { background: var(--bg-card-hover) !important; }

/* --------------------------------------------------------------------------
   Emerald / teal / violet left in the base that still reached the screen.
   Selections and brand -> indigo; live/done -> the new green; focus rings
   and glows -> indigo or saffron.
   -------------------------------------------------------------------------- */
.brand-logo-icon         { box-shadow: 0 2px 10px rgba(38, 54, 95, 0.30) !important; }
.topbar-quick-add-btn    { box-shadow: 0 2px 8px rgba(38, 54, 95, 0.28) !important; }
.quick-action-card:hover { box-shadow: 0 4px 12px rgba(38, 54, 95, 0.12) !important; }
.mega-apps-search-box:focus-within { box-shadow: 0 0 0 3px rgba(244, 166, 42, 0.22) !important; }
.mobile-fab-btn {
    background: linear-gradient(135deg, var(--brand-primary), var(--brand-primary-light)) !important;
    box-shadow: 0 8px 24px rgba(38, 54, 95, 0.40) !important;
}
.drawer-launcher-btn {
    background: linear-gradient(135deg, rgba(38, 54, 95, 0.08), rgba(244, 166, 42, 0.10)) !important;
}
[data-theme="dark"] .drawer-launcher-btn {
    background: linear-gradient(135deg, rgba(74, 98, 160, 0.20), rgba(247, 180, 65, 0.10)) !important;
}
/* Page-head eyebrow chips: brand (indigo) in both themes. */
[data-theme="dark"] .eyebrow-badge {
    background: var(--brand-primary-tint) !important;
    color: var(--brand-link) !important;
    border-color: var(--brand-primary-border) !important;
}
/* KPI icon chips in dark (base: Tailwind emerald/amber/rose/sky/indigo). */
.mtcom-kpi-icon.secondary,
[data-theme="dark"] .mtcom-kpi-icon.secondary {
    background: var(--brand-accent-tint);
    color: var(--accent-text);
    border-color: var(--brand-accent-border);
}
.mtcom-kpi-icon.warning { color: var(--warning-icon); }
[data-theme="dark"] .mtcom-kpi-icon.success { background: var(--success-bg); color: var(--success-text); border-color: var(--success-border); }
[data-theme="dark"] .mtcom-kpi-icon.warning { background: var(--warning-bg); color: var(--warning-icon); border-color: var(--warning-border); }
[data-theme="dark"] .mtcom-kpi-icon.danger  { background: var(--danger-bg);  color: var(--danger-text);  border-color: var(--danger-border); }
[data-theme="dark"] .mtcom-kpi-icon.info    { background: var(--info-bg);    color: var(--info-text);    border-color: var(--info-border); }
[data-theme="dark"] .mtcom-kpi-trend.positive { color: var(--success-text); }
[data-theme="dark"] .mtcom-kpi-trend.negative { color: var(--danger-text); }
[data-theme="dark"] .mtcom-kpi-trend.warning  { color: var(--warning-text); }
.mtcom-kpi-tile.active { box-shadow: 0 0 0 3px var(--brand-primary-tint), var(--surface-shadow) !important; }

/* --------------------------------------------------------------------------
   Status chips (Bootstrap .badge.bg-*, soft badges, status + priority
   badges). The base hard-codes Tailwind hexes per theme; one token rule per
   meaning covers both themes. Only colours are set — widths stay the base's.
   Priority follows the ticket pages: low = neutral, normal = info,
   high = warning, critical = danger (green stays for done only).
   -------------------------------------------------------------------------- */
:is(.badge.bg-primary, .badge-primary, .badge-soft-primary, .badge.bg-primary-subtle, .badge-purple),
[data-theme="dark"] :is(.badge.bg-primary, .badge-primary, .badge-soft-primary, .badge.bg-primary-subtle, .badge-purple) {
    background: var(--brand-primary-tint) !important;
    border-color: var(--brand-primary-border) !important;
    color: var(--brand-link) !important;
}
:is(.badge.bg-success, .badge-success, .badge-soft-success, .badge-status-resolved, .badge.bg-success-subtle),
[data-theme="dark"] :is(.badge.bg-success, .badge-success, .badge-soft-success, .badge-status-resolved, .badge.bg-success-subtle) {
    background: var(--success-bg) !important;
    border-color: var(--success-border) !important;
    color: var(--success-text) !important;
}
:is(.badge.bg-warning, .badge-warning, .badge-soft-warning, .badge-status-open, .badge-priority-high, .badge.bg-warning-subtle),
[data-theme="dark"] :is(.badge.bg-warning, .badge-warning, .badge-soft-warning, .badge-status-open, .badge-priority-high, .badge.bg-warning-subtle) {
    background: var(--warning-bg) !important;
    border-color: var(--warning-border) !important;
    color: var(--warning-text) !important;
}
:is(.badge.bg-info, .badge-info, .badge-soft-info, .badge-status-in-progress, .badge-priority-normal, .badge.bg-info-subtle),
[data-theme="dark"] :is(.badge.bg-info, .badge-info, .badge-soft-info, .badge-status-in-progress, .badge-priority-normal, .badge.bg-info-subtle) {
    background: var(--info-bg) !important;
    border-color: var(--info-border) !important;
    color: var(--info-text) !important;
}
:is(.badge.bg-danger, .badge-danger, .badge-soft-danger, .badge-status-rejected, .badge-status-overdue, .badge-priority-critical, .badge.bg-danger-subtle),
[data-theme="dark"] :is(.badge.bg-danger, .badge-danger, .badge-soft-danger, .badge-status-rejected, .badge-status-overdue, .badge-priority-critical, .badge.bg-danger-subtle) {
    background: var(--danger-bg) !important;
    border-color: var(--danger-border) !important;
    color: var(--danger-text) !important;
}
:is(.badge.bg-secondary, .badge-secondary, .badge-soft-secondary, .badge-status-closed, .badge-priority-low, .badge.bg-secondary-subtle),
[data-theme="dark"] :is(.badge.bg-secondary, .badge-secondary, .badge-soft-secondary, .badge-status-closed, .badge-priority-low, .badge.bg-secondary-subtle) {
    background: var(--neutral-bg) !important;
    border-color: var(--neutral-border) !important;
    color: var(--neutral-text) !important;
}
@keyframes criticalPulse {
    0%   { box-shadow: 0 0 0 0 rgba(229, 72, 77, 0.4); }
    70%  { box-shadow: 0 0 0 6px rgba(229, 72, 77, 0); }
    100% { box-shadow: 0 0 0 0 rgba(229, 72, 77, 0); }
}

/* --------------------------------------------------------------------------
   Soft-UI / Bootstrap buttons still carried the old kit: magenta, lime with
   white text (1.8:1), white on yellow (1.5:1), cyan (1.9:1), grey outline on
   the new page ground (2.8:1). Each keeps its MEANING on the new palette.
   Kept to one class each and placed BEFORE the text utilities below, so a
   `.text-*` class on a button still decides its label colour.
   -------------------------------------------------------------------------- */
.btn-success,
.btn-danger,
.btn-info,
.btn-secondary,
.btn-dark { color: #FFFFFF !important; background-image: none !important; }
.btn-success   { background-color: var(--success-fill) !important; border-color: var(--success-fill) !important; }
.btn-danger    { background-color: var(--danger-fill) !important;  border-color: var(--danger-fill) !important; }
.btn-info      { background-color: var(--info-fill) !important;    border-color: var(--info-fill) !important; }
.btn-secondary { background-color: var(--neutral-fill) !important; border-color: var(--neutral-fill) !important; }
.btn-dark      { background-color: #16203A !important; border-color: #16203A !important; }
.btn-success:hover, .btn-success:focus-visible, .btn-success:active { background-color: var(--success-fill-hover) !important; border-color: var(--success-fill-hover) !important; color: #FFFFFF !important; }
.btn-danger:hover,  .btn-danger:focus-visible,  .btn-danger:active  { background-color: var(--danger-fill-hover) !important;  border-color: var(--danger-fill-hover) !important;  color: #FFFFFF !important; }
.btn-info:hover,    .btn-info:focus-visible,    .btn-info:active    { background-color: var(--info-fill-hover) !important;    border-color: var(--info-fill-hover) !important;    color: #FFFFFF !important; }
.btn-secondary:hover, .btn-secondary:focus-visible, .btn-secondary:active { background-color: var(--neutral-fill-hover) !important; border-color: var(--neutral-fill-hover) !important; color: #FFFFFF !important; }
/* Warning = the saffron fill, which only ever carries DARK text. */
.btn-warning {
    background-color: var(--brand-accent) !important;
    border-color: var(--brand-accent) !important;
    background-image: none !important;
    color: var(--on-accent) !important;
}
.btn-warning:hover,
.btn-warning:focus-visible,
.btn-warning:active {
    background-color: var(--brand-accent-hover) !important;
    border-color: var(--brand-accent-hover) !important;
    color: var(--on-accent) !important;
}
/* Outline variants: tinted label + border, fill on hover. */
.btn-outline-secondary {
    color: var(--ink-secondary) !important;
    border-color: var(--border-strong) !important;
    background-color: transparent !important;
    opacity: 1 !important;
}
.btn-outline-secondary:hover,
.btn-outline-secondary:focus-visible,
.btn-outline-secondary.active {
    color: var(--ink-primary) !important;
    border-color: var(--ink-subtle) !important;
    background-color: var(--bg-card-hover) !important;
}
.btn-outline-success { color: var(--success-text) !important; border-color: var(--success-accent) !important; background-color: transparent !important; opacity: 1 !important; }
.btn-outline-warning { color: var(--warning-text) !important; border-color: var(--warning-accent) !important; background-color: transparent !important; opacity: 1 !important; }
.btn-outline-info    { color: var(--info-text) !important;    border-color: var(--info-accent) !important;    background-color: transparent !important; opacity: 1 !important; }
.btn-outline-danger  { color: var(--danger-text) !important;  border-color: var(--danger-accent) !important;  background-color: transparent !important; opacity: 1 !important; }
.btn-outline-dark    { color: var(--ink-secondary) !important; border-color: var(--ink-secondary) !important; background-color: transparent !important; }
.btn-outline-success:hover, .btn-outline-success.active { background-color: var(--success-fill) !important; border-color: var(--success-fill) !important; color: #FFFFFF !important; }
.btn-outline-info:hover,    .btn-outline-info.active    { background-color: var(--info-fill) !important;    border-color: var(--info-fill) !important;    color: #FFFFFF !important; }
.btn-outline-danger:hover,  .btn-outline-danger.active  { background-color: var(--danger-fill) !important;  border-color: var(--danger-fill) !important;  color: #FFFFFF !important; }
.btn-outline-warning:hover, .btn-outline-warning.active { background-color: var(--warning-bg) !important;   color: var(--warning-text) !important; }
/* Link buttons: set through Bootstrap's own variables so a `.text-*` or
   `.text-white-50` class on the button still wins. */
.btn-link {
    --bs-btn-color: var(--brand-link);
    --bs-btn-hover-color: var(--brand-link-hover);
    --bs-btn-active-color: var(--brand-link-hover);
}
.btn.btn-link { color: var(--brand-link); }

/* --------------------------------------------------------------------------
   Text utilities. Soft-UI: primary magenta, success lime (1.5:1), warning
   yellow (1.3:1), info cyan, dark/body/secondary slate that disappears on
   a dark card (1.6:1). Now the palette's text tokens, which flip per theme.
   -------------------------------------------------------------------------- */
.text-primary   { color: var(--brand-link) !important; }
.text-success   { color: var(--success-text) !important; }
.text-warning   { color: var(--warning-text) !important; }
.text-info      { color: var(--info-text) !important; }
.text-danger    { color: var(--danger-text) !important; }
.text-dark      { color: var(--ink-secondary) !important; }
.text-body,
.text-secondary,
.text-muted     { color: var(--ink-muted) !important; }
.text-gradient.text-primary,
.text-gradient.text-success,
.text-gradient.text-warning,
.text-gradient.text-info,
.text-gradient.text-danger,
.text-gradient.text-dark {
    background-image: none !important;
    -webkit-text-fill-color: currentColor !important;
}
/* A heading inside a `.text-white` / `.text-dark` block (coloured modal
   headers) follows that block; Soft-UI pins every heading to #344767. */
:is(.text-white, .text-dark) :is(h1, h2, h3, h4, h5, h6) { color: inherit; }
/* Dark text that sits on the saffron fill must stay dark in dark mode
   (a warning BADGE is a tint, not the fill, so it is left to the chip rule). */
[data-theme="dark"] .btn-warning.text-dark,
[data-theme="dark"] .bg-warning:not(.bg-opacity-10):not(.badge).text-dark,
[data-theme="dark"] .bg-warning:not(.bg-opacity-10):not(.badge) .text-dark { color: var(--on-accent) !important; }
/* Soft-UI's table-info line under simple-datatables (#8392AB, 3.2:1). */
.dataTable-info,
.dataTable-wrapper .dataTable-bottom .dataTable-info { color: var(--ink-muted); }
/* Bootstrap's field help text (#6C757D): 3.9:1 on the light grey panels and
   3.2-3.8:1 on the dark cards. */
.form-text { color: var(--ink-muted); }

/* --------------------------------------------------------------------------
   Background utilities (fills keep their meaning; tints where the markup
   asks for bg-opacity-10, which Soft-UI's solid hexes ignored).
   -------------------------------------------------------------------------- */
.bg-primary   { background-color: var(--brand-primary) !important; }
.bg-success   { background-color: var(--success-fill) !important; }
.bg-warning   { background-color: var(--brand-accent) !important; }
.bg-info      { background-color: var(--info-fill) !important; }
.bg-danger    { background-color: var(--danger-fill) !important; }
.bg-secondary { background-color: var(--neutral-fill) !important; }
.bg-dark      { background-color: #16203A !important; }
.bg-light     { background-color: var(--bg-page-subtle) !important; }
[data-theme="dark"] .bg-light { background-color: var(--bg-card-subtle) !important; }
[data-theme="dark"] .bg-white { background-color: var(--bg-card) !important; }
.bg-success.bg-opacity-10 { background-color: var(--success-bg) !important; }
.bg-warning.bg-opacity-10 { background-color: var(--warning-bg) !important; }
.bg-danger.bg-opacity-10  { background-color: var(--danger-bg) !important; }
.bg-info.bg-opacity-10    { background-color: var(--info-bg) !important; }
.bg-primary.bg-opacity-10 { background-color: var(--brand-primary-tint) !important; }
/* Bootstrap 5.3 "-subtle" tints the markup already uses; Soft-UI (5.2) has
   none, so these panels rendered with no background at all. */
.bg-primary-subtle   { background-color: var(--brand-primary-tint) !important; }
.bg-success-subtle   { background-color: var(--success-bg) !important; }
.bg-warning-subtle   { background-color: var(--warning-bg) !important; }
.bg-danger-subtle    { background-color: var(--danger-bg) !important; }
.bg-info-subtle      { background-color: var(--info-bg) !important; }
.bg-secondary-subtle { background-color: var(--neutral-bg) !important; }
.border-primary-subtle { border-color: var(--brand-primary-border) !important; }
.border-success-subtle { border-color: var(--success-border) !important; }
.border-warning-subtle { border-color: var(--warning-border) !important; }
.border-danger-subtle  { border-color: var(--danger-border) !important; }
.border-info-subtle    { border-color: var(--info-border) !important; }
.border-primary { border-color: var(--brand-primary) !important; }
.border-success { border-color: var(--success-accent) !important; }
.border-warning { border-color: var(--warning-accent) !important; }
.border-danger  { border-color: var(--danger-accent) !important; }
.border-info    { border-color: var(--info-accent) !important; }
.bg-gradient-primary { background-image: linear-gradient(310deg, var(--brand-primary-dark), var(--brand-primary-light)); }
.bg-gradient-success { background-image: linear-gradient(310deg, #14663F, #17744A); }
.bg-gradient-info    { background-image: linear-gradient(310deg, #1E4293, #2F5BC4); }
.bg-gradient-warning { background-image: linear-gradient(310deg, #DD8E12, #F4A62A); }
.bg-gradient-danger  { background-image: linear-gradient(310deg, #A32126, #C62F35); }
.bg-gradient-dark    { background-image: linear-gradient(310deg, #16203A, #33477A); }

/* Alerts: Soft-UI paints gradients (lime, red->yellow...) under a dark label
   (about 2:1). Now the palette's tint + text in both themes; this also wins
   over a `.text-white` on the alert, which would be white-on-tint. */
.alert.alert-success   { background: var(--success-bg) !important;  border-color: var(--success-border) !important; color: var(--success-text) !important; }
.alert.alert-danger    { background: var(--danger-bg) !important;  border-color: var(--danger-border) !important;  color: var(--danger-text) !important; }
.alert.alert-warning   { background: var(--warning-bg) !important;  border-color: var(--warning-border) !important; color: var(--warning-text) !important; }
.alert.alert-info      { background: var(--info-bg) !important;    border-color: var(--info-border) !important;    color: var(--info-text) !important; }
.alert.alert-secondary { background: var(--neutral-bg) !important;  border-color: var(--neutral-border) !important; color: var(--neutral-text) !important; }
.alert.alert-primary   { background: var(--brand-primary-tint) !important;  border-color: var(--brand-primary-border) !important; color: var(--brand-link) !important; }
[data-theme="dark"] .alert .btn-close { filter: invert(1) grayscale(1) brightness(1.8); }

/* --------------------------------------------------------------------------
   Dark mode: Bootstrap surfaces that stayed white (modals, dropdowns, list
   groups, pill tabs). Their text now follows the dark tokens, so the surface
   has to follow too — a white modal with light text was unreadable.
   -------------------------------------------------------------------------- */
[data-theme="dark"] .modal .modal-content {
    background: var(--bg-card);
    color: var(--ink-primary);
    border-color: var(--border-light);
}
[data-theme="dark"] .modal .modal-header,
[data-theme="dark"] .modal .modal-footer { background-color: transparent; border-color: var(--border-light); }
[data-theme="dark"] .modal .btn-close { filter: invert(1) grayscale(1) brightness(1.8); }
[data-theme="dark"] .dropdown-menu {
    --bs-dropdown-bg: var(--bg-card);
    --bs-dropdown-color: var(--ink-secondary);
    --bs-dropdown-border-color: var(--border-light);
    --bs-dropdown-link-color: var(--ink-secondary);
    --bs-dropdown-link-hover-color: var(--ink-primary);
    --bs-dropdown-link-hover-bg: var(--bg-card-hover);
    --bs-dropdown-link-active-color: var(--ink-primary);
    --bs-dropdown-link-active-bg: var(--bg-card-active);
    --bs-dropdown-divider-bg: var(--border-light);
    background-color: var(--bg-card);
    color: var(--ink-secondary);
}
[data-theme="dark"] .list-group {
    --bs-list-group-bg: var(--bg-card);
    --bs-list-group-color: var(--ink-primary);
    --bs-list-group-border-color: var(--border-light);
    --bs-list-group-action-color: var(--ink-secondary);
    --bs-list-group-action-hover-bg: var(--bg-card-hover);
    --bs-list-group-action-hover-color: var(--ink-primary);
}
[data-theme="dark"] .list-group-item { background-color: var(--bg-card); color: var(--ink-primary); border-color: var(--border-light); }
[data-theme="dark"] .input-group-text { background-color: var(--bg-card-subtle); color: var(--ink-secondary); border-color: var(--border-control); }
[data-theme="dark"] .nav.nav-pills { background: var(--bg-card-subtle); border-color: var(--border-light); }
[data-theme="dark"] .nav.nav-pills .nav-link { color: var(--ink-secondary); }
[data-theme="dark"] .nav.nav-pills .nav-link:hover { background: var(--bg-card-hover); color: var(--ink-primary); }
[data-theme="dark"] .nav.nav-pills .nav-link.active,
[data-theme="dark"] .nav.nav-pills .moving-tab .nav-link { background: var(--bg-card); color: var(--brand-link); }
[data-theme="dark"] .nav.nav-pills .moving-tab { background: var(--bg-card); box-shadow: none; }
/* DataTables 2 greys its disabled pager arrows with black at 50% (1.2:1 on a
   dark card). */
[data-theme="dark"] div.dt-container .dt-paging .dt-paging-button.disabled,
[data-theme="dark"] div.dt-container .dt-paging .dt-paging-button.disabled:hover { color: var(--ink-subtle) !important; }
[data-theme="dark"] .nav-tabs .nav-link.active { background-color: var(--bg-card); color: var(--brand-link); border-color: var(--border-light) var(--border-light) var(--bg-card); }
/* Contextual table rows (low-stock rows etc.): Soft-UI pastel hexes stayed
   light in dark mode under light text. The palette's tints, both themes. */
.table-danger    { --bs-table-bg: var(--danger-bg);  --bs-table-striped-bg: var(--danger-bg);  --bs-table-hover-bg: var(--danger-bg); }
.table-warning   { --bs-table-bg: var(--warning-bg); --bs-table-striped-bg: var(--warning-bg); --bs-table-hover-bg: var(--warning-bg); }
.table-success   { --bs-table-bg: var(--success-bg); --bs-table-striped-bg: var(--success-bg); --bs-table-hover-bg: var(--success-bg); }
.table-info      { --bs-table-bg: var(--info-bg);    --bs-table-striped-bg: var(--info-bg);    --bs-table-hover-bg: var(--info-bg); }
.table-primary   { --bs-table-bg: var(--brand-primary-tint); --bs-table-striped-bg: var(--brand-primary-tint); --bs-table-hover-bg: var(--brand-primary-tint); }
.table-secondary { --bs-table-bg: var(--neutral-bg); --bs-table-striped-bg: var(--neutral-bg); --bs-table-hover-bg: var(--neutral-bg); }
:is(.table-danger, .table-warning, .table-success, .table-info, .table-primary, .table-secondary) {
    --bs-table-color: var(--ink-primary);
    --bs-table-border-color: var(--border-light);
}

/* --------------------------------------------------------------------------
   Light "islands" in dark mode. A few page-local widgets paint themselves
   white / #F8FAFC in BOTH themes, and two previews must stay paper white.
   Dark mode turns the text utilities, headings, labels and outline buttons
   light (with !important), so on those widgets the words went light-on-white.
   Inside an island every theme token keeps its LIGHT value, and text that
   only inherits takes the light ink (a zero-specificity rule, so a widget's
   own colour still wins). Remove an entry once its page gives the widget a
   dark variant (the ticket detail page has: its widgets follow the tokens).
     tasks/show ............. tab strip, checklist rows, photo cards
     escalations/index ...... decision modal: task / reporter context cards
     cross-campus-banner .... notice banner + confirmation modal (inline #FFF)
     escalation-history ..... timeline cards
     tasks/_form ............ per-room quantities, weekend policy box
     custom-reports/wizard .. the "done" step number (green on pale green)
     qr-codes ............... QR preview frame + link box (paper white)
     settings ............... report-logo preview (paper white)
   -------------------------------------------------------------------------- */
[data-theme="dark"] :is(
    .fd-nav-tabs, .fd-checklist-row, .fd-photo-card,
    .hud-context-card,
    #crossCampusBanner, #crossCampusConfirmModal .modal-content,
    .timeline-item > .timeline-content,
    .option-quantities, #weekend_options_container .rounded-3,
    .cr-step.is-done .cr-step-num,
    #qrPreviewContent .bg-white, #qrPreviewContent .text-start.rounded-3,
    img.bg-white
) {
    --brand-primary: #26365F; --brand-primary-hover: #1E2B4C; --brand-primary-dark: #16203A;
    --brand-primary-light: #33477A; --brand-primary-tint: #EEF1F8; --brand-primary-border: #C6CFE4;
    --brand-accent: #F4A62A; --brand-accent-hover: #DD8E12; --brand-accent-tint: #FCEFD6; --brand-accent-border: #F6D79B;
    --brand-link: #26365F; --brand-link-hover: #1E2B4C;
    --accent-on-brand: #F4A62A; --nav-active-bg: #26365F; --accent-text: #8A5A0C; --warning-icon: #B8601C;
    --success-fill-hover: #14663F; --danger-fill-hover: #A32126; --info-fill-hover: #1E4293; --neutral-fill-hover: #454F66;
    --neutral-bg: #EDF0F6; --neutral-border: #C9D0E0; --neutral-text: #4A5570;
    --border-control: #C9D0E0;
    --bg-page: #EEF1F7; --bg-page-subtle: #E6EAF3;
    --bg-card: #FFFFFF; --bg-card-subtle: #F6F7FB; --bg-card-hover: #F1F3FA; --bg-card-active: #E7EBF4;
    --bg-surface: #FFFFFF; --bg-surface-glass: rgba(255, 255, 255, 0.90);
    --ink-primary: #14203B; --ink-secondary: #2A3654; --ink-muted: #55617C; --ink-subtle: #636E88; --ink-inverse: #FFFFFF;
    --border-light: #E2E6F0; --border-subtle: #EDF0F7; --border-strong: #C9D0E0; --border-focus: #F4A62A;
    --success-bg: #E4F5EC; --success-border: #B6E3CB; --success-text: #14663F; --success-accent: #1F9D6B;
    --danger-bg: #FBE5E6;  --danger-border: #F3C3C5;  --danger-text: #A32126;  --danger-accent: #E5484D; --danger-hover: #CE3238;
    --warning-bg: #FBEAD8; --warning-border: #F4CFA6; --warning-text: #8A4B12; --warning-accent: #E8823A;
    --info-bg: #E4ECFB;    --info-border: #BFD2F5;    --info-text: #1E4293;    --info-accent: #3B6FE0;
}
:where([data-theme="dark"]) :where(
    .fd-nav-tabs, .fd-checklist-row, .fd-photo-card,
    .hud-context-card,
    #crossCampusBanner, #crossCampusConfirmModal .modal-content,
    .timeline-item > .timeline-content,
    .option-quantities, #weekend_options_container .rounded-3,
    .cr-step.is-done .cr-step-num
) { color: var(--ink-primary); }
/* The dark theme inverts a modal's close cross; on this light header it vanished. */
[data-theme="dark"] #crossCampusConfirmModal .btn-close { filter: none; }
/* System check paints its cards from the DEVICE scheme, not the console
   theme: console dark + device light leaves .sc-tools pale, and its heading
   (no colour of its own) took the dark theme's light ink. */
@media (prefers-color-scheme: light) {
    [data-theme="dark"] .sc-tools h3 { color: #14203B; }
}
/* Every label's colour is forced (!important) by the base, in both themes;
   the chosen option of the report wizard's mode switch sits on the indigo
   fill, so it has to stay white (it read 1.0:1 light, 3.8:1 dark). */
.cr-mode-switch label:has(input:checked) { color: var(--on-brand) !important; }
/* ...and the reverse: a dark chip on a photo, or a dark fill, in light mode. */
:is(.bg-dark, .tkt-photo-badge) {
    --brand-link: #A9B8EC; --ink-primary: #E8ECF7; --ink-secondary: #C7CEE0; --ink-muted: #9AA3BC; --ink-subtle: #8A94AE;
    --success-text: #40C892; --danger-text: #F1888C; --warning-text: #F0A567; --warning-icon: #F0A567; --info-text: #7EA0F0;
    --neutral-text: #C7CEE0; --accent-text: #F7C877;
}

/* --------------------------------------------------------------------------
   Page gutter. The layout pads the canvas `px-3 px-md-4`, but the base zeroes
   .main-content's side padding with !important, so every page sat flush at
   x = 0. Restored on the canvas only (pages themselves stay padding: 0).
   -------------------------------------------------------------------------- */
body.app-body main.main-content {
    padding-left: 24px !important;
    padding-right: 24px !important;
}
@media (max-width: 767.98px) {
    body.app-body main.main-content {
        padding-left: 16px !important;
        padding-right: 16px !important;
    }
}

/* --------------------------------------------------------------------------
   KPI tiles whose label / value / caption are direct children (Tasks list):
   the base lays a tile out as a row, so a wide figure ("10,322") ran over its
   caption. They stack, as the Tasks reference tile was drawn.
   -------------------------------------------------------------------------- */
.mtcom-kpi-tile:has(> .mtcom-kpi-label) {
    flex-direction: column !important;
    align-items: flex-start !important;
    justify-content: center !important;
    gap: 2px !important;
}

/* --------------------------------------------------------------------------
   Dashboard launch cards. How many cards show depends on the person's rights;
   with the base auto-fit rule one or two cards stretched across the whole
   row. Each column is at least one sixth of the row (six = the most cards
   there can be), so a short row keeps normal-width cards and a full row of
   six is unchanged. The gap is a variable because the sixth depends on it.
   -------------------------------------------------------------------------- */
.cc-launch-grid.cc-launch-grid--six {
    --cc-launch-gap: 14px;
    --cc-launch-max: 6;
    gap: var(--cc-launch-gap);
    grid-template-columns: repeat(auto-fill, minmax(max(190px, calc((100% - (var(--cc-launch-max) - 1) * var(--cc-launch-gap)) / var(--cc-launch-max) - 1px)), 1fr));
}

/* --------------------------------------------------------------------------
   The old top bar (top navigation, "All Modules" launcher, Quick Actions)
   and its phone drawer were replaced in redesign phase 2 by the console
   shell - see "Console shell" in the SHARED BUILDING BLOCKS section below.
   The width tiers and the drawer-opacity repair that lived here targeted
   markup that no longer exists; the shell was built to the same checks
   (fits 320-1920px in both languages, drawer visible when open).
   -------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------
   Breadcrumbs: Soft-UI dims crumb links with .opacity-5, which halves the
   link token (2.7:1 light / 3.2:1 dark). Keep them quiet but readable.
   -------------------------------------------------------------------------- */
.breadcrumb .opacity-5,
.breadcrumb-item a.opacity-5 {
    opacity: .85 !important;
}

/* --------------------------------------------------------------------------
   Select2 (ticket create/edit, task form, rooms, departments, push
   notifications) in dark: the plugin paints white boxes and near-white
   chips with dark-on-dark text (1.1:1). Token colours, both states.
   -------------------------------------------------------------------------- */
[data-theme="dark"] .select2-container--default .select2-selection--single,
[data-theme="dark"] .select2-container--default .select2-selection--multiple {
    background: var(--bg-card-subtle) !important;
    border-color: var(--border-light) !important;
    color: var(--ink-primary) !important;
}
[data-theme="dark"] .select2-container--default .select2-selection--single .select2-selection__rendered,
[data-theme="dark"] .select2-container--default .select2-search--inline .select2-search__field {
    color: var(--ink-primary) !important;
}
[data-theme="dark"] .select2-container--default .select2-selection--multiple .select2-selection__choice {
    background: var(--brand-primary-tint) !important;
    border-color: var(--brand-primary-border) !important;
    color: var(--ink-primary) !important;
}
[data-theme="dark"] .select2-container--default .select2-selection--multiple .select2-selection__choice__remove {
    color: var(--ink-secondary) !important;
}
[data-theme="dark"] .select2-dropdown {
    background: var(--bg-card) !important;
    border-color: var(--border-light) !important;
    color: var(--ink-primary) !important;
}
[data-theme="dark"] .select2-container--default .select2-search--dropdown .select2-search__field {
    background: var(--bg-card-subtle) !important;
    border-color: var(--border-light) !important;
    color: var(--ink-primary) !important;
}
[data-theme="dark"] .select2-container--default .select2-results__option--highlighted,
[data-theme="dark"] .select2-container--default .select2-results__option--highlighted[aria-selected] {
    background: var(--brand-primary) !important;
    color: var(--on-brand, #fff) !important;
}
[data-theme="dark"] .select2-container--default .select2-results__option[aria-selected="true"],
[data-theme="dark"] .select2-container--default .select2-results__option--selected {
    background: var(--bg-card-active, #212C4A) !important;
    color: var(--ink-primary) !important;
}

/* ==========================================================================
   SHARED BUILDING BLOCKS (redesign phase 1) - the x-ui.* Blade components
   --------------------------------------------------------------------------
   resources/views/components/ui/*.blade.php draw these; the living sample is
   /admin/ui-kit; the rules are in docs/web-admin/ui-standard.md.
   - TOKENS ONLY below this line: no hex, no rgb() - light and dark come from
     the token sets above (a test fails the build if a literal colour appears).
   - Logical properties only (inline-start/end), so Arabic/Urdu mirror.
   - 44px targets for everything a finger taps; small buttons are 36px only
     where the pointer is a mouse.
   - Class prefix `ui-`: nothing older uses it, so nothing older is restyled.
   ========================================================================== */

/* ---- Layout helpers ---------------------------------------------------- */
.ui-stack { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.ui-inline { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; min-width: 0; }
.ui-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr)); gap: 12px; min-width: 0; }
.ui-tnum { font-variant-numeric: tabular-nums; }
.ui-text-danger { color: var(--danger-text); font-weight: 600; }
.ui-next-inline { font-size: 13px; font-weight: 600; color: var(--brand-link); }
.ui-icon { flex-shrink: 0; vertical-align: middle; }
[dir="rtl"] .ui-icon--flip { transform: scaleX(-1); }
html.ui-dialog-open { overflow: hidden; }
/* Text a person typed (dir="auto") keeps its own reading direction but lines
   up with the page: an English ticket title sits on the right in Arabic. */
:is(.ui-page-title, .ui-panel-title, .ui-review-title, .ui-facts dd, .ui-queue-title, .ui-list-title, .ui-list-sub)[dir="auto"] {
    text-align: -webkit-match-parent; /* Chrome, Edge, Safari */
    text-align: match-parent;         /* Firefox */
}

/* ---- Buttons and links ------------------------------------------------- */
.ui-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: 44px;
    padding: 0 16px;
    margin: 0;
    border-radius: 10px;
    border: 1px solid var(--border-strong);
    background: var(--bg-card);
    color: var(--ink-primary);
    font-size: 14px;
    font-weight: 600;
    line-height: 1.25;
    text-align: center;
    /* A long label wraps inside the button rather than pushing it past a
       320px screen; short labels stay on one line. */
    white-space: normal;
    overflow-wrap: break-word;
    max-width: 100%;
    text-decoration: none;
    text-transform: none;
    letter-spacing: normal;
    cursor: pointer;
    transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}
.ui-btn:hover { background: var(--bg-card-hover); color: var(--ink-primary); text-decoration: none; }
.ui-btn--primary { background: var(--brand-primary); border-color: var(--brand-primary); color: var(--on-brand); }
.ui-btn--primary:hover { background: var(--brand-primary-hover); border-color: var(--brand-primary-hover); color: var(--on-brand); }
.ui-btn--danger { background: var(--danger-fill); border-color: var(--danger-fill); color: var(--on-brand); }
.ui-btn--danger:hover { background: var(--danger-fill-hover); border-color: var(--danger-fill-hover); color: var(--on-brand); }
.ui-btn--ghost { background: transparent; border-color: transparent; color: var(--brand-link); }
.ui-btn--ghost:hover { background: var(--brand-primary-tint); color: var(--brand-link-hover); }
.ui-btn--sm { min-height: 36px; padding: 0 12px; font-size: 13px; border-radius: 8px; }
@media (pointer: coarse) { .ui-btn--sm { min-height: 44px; } }
/* Phase 10: the older Bootstrap fields inside console pages (the plan form's steps, create / edit
   forms not rebuilt yet) are 42px tall - one finger needs 44px on a touch screen. */
@media (pointer: coarse) {
    .mtcom-page :is(input.form-control, select.form-control, .form-select) { min-height: 44px; }
}
.ui-btn[disabled], .ui-btn[aria-disabled="true"] { opacity: .55; cursor: not-allowed; }
.ui-btn[disabled]:hover, .ui-btn[aria-disabled="true"]:hover { background: var(--bg-card); }
.ui-btn--primary[disabled]:hover { background: var(--brand-primary); }

.ui-icon-btn {
    display: inline-grid;
    place-items: center;
    width: 44px;
    height: 44px;
    flex-shrink: 0;
    margin: 0;
    padding: 0;
    border-radius: 10px;
    border: 1px solid var(--border-light);
    background: var(--bg-card);
    color: var(--ink-secondary);
    cursor: pointer;
}
.ui-icon-btn:hover { background: var(--bg-card-hover); color: var(--ink-primary); }

.ui-link {
    color: var(--brand-link);
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 2px;
    background: none;
    border: 0;
    padding: 0;
    cursor: pointer;
}
.ui-link:hover { color: var(--brand-link-hover); text-decoration-color: var(--brand-accent); }

/* Keyboard focus: the identity's saffron outline (global rule above) plus an
   indigo ring between it and the control, so the focus mark reaches 3:1
   against white and dark cards alike (saffron alone is about 2:1 on white). */
:is(.ui-btn, .ui-icon-btn, .ui-chip, .ui-metric, .ui-link, .ui-select, .ui-check input, .ui-search input):focus-visible {
    box-shadow: 0 0 0 2px var(--brand-link);
}

/* ---- Page header (x-ui.page-header) ------------------------------------ */
.ui-page-head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 16px;
    margin: 0 0 24px;
}
.ui-page-head-text { flex: 1 1 320px; min-width: 0; }
.ui-page-title {
    margin: 0;
    font-size: 28px;
    font-weight: 700;
    line-height: 1.3;
    letter-spacing: -.01em;
    color: var(--ink-primary);
    overflow-wrap: anywhere;
}
.ui-page-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 8px; }
.ui-page-sub { margin: 6px 0 0; max-width: 78ch; font-size: 14px; line-height: 1.5; color: var(--ink-muted); }
.ui-page-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }

/* ---- Card (x-ui.card) --------------------------------------------------- */
.ui-card {
    min-width: 0;
    background: var(--bg-card);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-md);
    color: var(--ink-primary);
}
.ui-card-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 8px 12px;
    padding: 14px 18px;
    border-bottom: 1px solid var(--border-light);
}
.ui-card-head-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ui-card-title { margin: 0; font-size: 18px; font-weight: 600; line-height: 1.3; color: var(--ink-primary); }
.ui-card-meta { font-size: 13px; color: var(--ink-muted); }
.ui-card-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
/* A text link in a card's head or foot ("All visits", "See all tickets") gets a
   44px hit area without making the head taller (it reaches into the padding). */
:is(.ui-card-actions, .ui-card-foot) > .ui-link { display: inline-flex; align-items: center; min-height: 44px; margin-block: -12px; }
.ui-card-body { padding: 16px 18px; }
.ui-card-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 12px;
    padding: 12px 18px;
    border-top: 1px solid var(--border-light);
    font-size: 13px;
    color: var(--ink-muted);
}

/* ---- Metric card (x-ui.metric) ----------------------------------------- */
.ui-metrics {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 150px), 1fr));
    gap: 12px;
    margin: 0;
}
.ui-metric {
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-width: 0;
    padding: 14px 16px;
    background: var(--bg-card);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-md);
    color: var(--ink-primary);
    text-align: start;
    text-decoration: none;
    transition: border-color .15s ease, box-shadow .15s ease;
}
a.ui-metric:hover { border-color: var(--border-strong); box-shadow: var(--shadow-md); color: var(--ink-primary); text-decoration: none; }
.ui-metric-label { display: flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 500; color: var(--ink-muted); }
.ui-metric-value { font-size: 30px; font-weight: 700; line-height: 1.1; color: var(--ink-primary); overflow-wrap: anywhere; }
.ui-metric-foot { font-size: 13px; line-height: 1.4; color: var(--ink-muted); }
.ui-metric-scope { display: flex; align-items: center; gap: 4px; font-size: 12px; color: var(--ink-muted); }
.ui-metric--danger { border-color: var(--danger-border); }
.ui-metric--danger .ui-metric-label,
.ui-metric--danger .ui-metric-value { color: var(--danger-text); }

/* ---- Pills (x-ui.status-pill, x-ui.priority-pill) ---------------------- */
.ui-pill {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 3px 10px;
    border-radius: 999px;
    border: 1px solid transparent;
    font-size: 12px;
    font-weight: 600;
    line-height: 1.4;
    white-space: nowrap;
    vertical-align: middle;
}
.ui-pill--neutral { background: var(--neutral-bg); border-color: var(--neutral-border); color: var(--neutral-text); }
.ui-pill--info    { background: var(--info-bg);    border-color: var(--info-border);    color: var(--info-text); }
.ui-pill--warning { background: var(--warning-bg); border-color: var(--warning-border); color: var(--warning-text); }
.ui-pill--success { background: var(--success-bg); border-color: var(--success-border); color: var(--success-text); }
.ui-pill--danger  { background: var(--danger-bg);  border-color: var(--danger-border);  color: var(--danger-text); }
.ui-pill--brand   { background: var(--brand-primary-tint); border-color: var(--brand-primary-border); color: var(--brand-link); }

/* ---- Saved views (x-ui.view-chips) ------------------------------------- */
.ui-views { display: flex; flex-wrap: wrap; gap: 8px; margin: 0; }
.ui-chip {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-height: 44px;
    margin: 0;
    padding: 0 16px;
    border-radius: 999px;
    border: 1px solid var(--border-strong);
    background: var(--bg-card);
    color: var(--ink-secondary);
    font-size: 14px;
    font-weight: 600;
    white-space: nowrap;
    max-width: 100%;
    cursor: pointer;
}
.ui-chip:hover { background: var(--bg-card-hover); color: var(--ink-primary); }
.ui-chip[aria-pressed="true"] { background: var(--brand-primary); border-color: var(--brand-primary); color: var(--on-brand); }
.ui-chip-count {
    min-width: 24px;
    padding: 1px 8px;
    border-radius: 999px;
    background: var(--neutral-bg);
    color: var(--neutral-text);
    font-size: 12px;
    font-weight: 600;
    text-align: center;
}
.ui-chip[aria-pressed="true"] .ui-chip-count { background: var(--brand-primary-dark); color: var(--on-brand); }

/* ---- Table toolbar and bulk bar ---------------------------------------- */
.ui-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin: 0;
    padding: 12px 18px;
    border-bottom: 1px solid var(--border-light);
}
.ui-search {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 1 1 240px;
    max-width: 360px;
    min-height: 44px;
    padding: 0 12px;
    border: 1px solid var(--border-strong);
    border-radius: 10px;
    background: var(--bg-card);
    color: var(--ink-muted);
}
.ui-search:focus-within { border-color: var(--brand-link); }
.ui-search input {
    flex: 1;
    min-width: 0;
    min-height: 42px;
    margin: 0;
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--ink-primary);
    font-size: 14px;
}
.ui-search input::placeholder { color: var(--ink-subtle); opacity: 1; }
.ui-select {
    flex: 0 1 auto;
    max-width: 100%;
    min-height: 44px;
    margin: 0;
    padding-block: 0;
    padding-inline: 12px 8px;
    border: 1px solid var(--border-strong);
    border-radius: 10px;
    background-color: var(--bg-card);
    color: var(--ink-primary);
    font-size: 14px;
}
[data-theme="dark"] :is(.ui-select, .ui-search input, .ui-check input) { color-scheme: dark; }

.ui-bulkbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 12px;
    padding: 8px 18px;
    background: var(--brand-primary-tint);
    border-bottom: 1px solid var(--border-light);
    color: var(--ink-primary);
    font-weight: 600;
}
.ui-bulkbar[hidden] { display: none !important; }
.ui-bulkbar-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }

.ui-check {
    display: inline-grid;
    place-items: center;
    min-width: 44px;
    min-height: 44px;
    margin: 0;
    cursor: pointer;
}
.ui-check input { width: 18px; height: 18px; margin: 0; accent-color: var(--brand-primary); cursor: pointer; }

/* ---- Table (x-ui.table): a table on wide screens, cards under 900px ---- */
.ui-table-wrap { overflow-x: auto; }
.ui-table { width: 100%; margin: 0; border-collapse: collapse; font-size: 14px; color: var(--ink-primary); }
.ui-table th {
    padding: 10px 14px;
    background: var(--bg-card-subtle);
    border-bottom: 1px solid var(--border-light);
    color: var(--ink-muted);
    font-size: 12px;
    font-weight: 600;
    text-align: start;
    white-space: nowrap;
}
.ui-table td { padding: 12px 14px; border-top: 1px solid var(--border-light); vertical-align: middle; color: var(--ink-primary); }
.ui-table tbody tr:first-child td { border-top: 0; }
.ui-table tbody tr:hover td { background: var(--bg-card-hover); }
.ui-table tbody tr.is-selected td { background: var(--brand-primary-tint); }
.ui-table .ui-td-select { width: 52px; padding-block: 0; padding-inline: 4px; }
.ui-td-primary { font-weight: 600; }
.ui-td-primary .ui-td-sub { display: block; font-size: 12px; font-weight: 400; color: var(--ink-muted); }
.ui-td-actions { text-align: end; white-space: nowrap; }
.ui-table-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 12px;
    padding: 12px 18px;
    border-top: 1px solid var(--border-light);
    font-size: 13px;
    color: var(--ink-muted);
}

@media (max-width: 899.98px) {
    .ui-table-wrap { overflow-x: visible; }
    .ui-table, .ui-table tbody { display: block; }
    .ui-table thead { display: none; }
    .ui-table tr {
        position: relative;
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        gap: 6px 12px;
        padding: 14px 16px;
        border-top: 1px solid var(--border-light);
    }
    .ui-table tbody tr:first-child { border-top: 0; }
    .ui-table-wrap--select .ui-table tr { padding-inline-start: 56px; }
    /* Each cell is a small flex row, so its "Label:" sits on the same line as
       a pill or a group of pills. */
    .ui-table td {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        gap: 4px 6px;
        padding: 0;
        border: 0;
        font-size: 13px;
        color: var(--ink-secondary);
    }
    .ui-table tbody tr:hover td { background: transparent; }
    .ui-table tbody tr.is-selected { background: var(--brand-primary-tint); }
    .ui-table tbody tr.is-selected td { background: transparent; }
    .ui-table td.ui-td-select { display: block; position: absolute; top: 4px; inset-inline-start: 6px; width: auto; padding: 0; }
    .ui-table td.ui-td-primary { display: block; flex: 1 0 100%; font-size: 14px; color: var(--ink-primary); }
    .ui-table td.ui-td-block { flex: 1 0 100%; }
    .ui-table td.ui-td-actions { flex: 1 0 100%; text-align: start; }
    .ui-table td.ui-td-hide-m { display: none; }
    .ui-table td[data-label]:not(.ui-td-primary):not(.ui-td-select)::before {
        content: attr(data-label) ": ";
        color: var(--ink-muted);
        font-weight: 500;
    }
}

/* ---- Empty / loading / error states ------------------------------------ */
.ui-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    padding: 40px 20px;
    text-align: center;
    color: var(--ink-muted);
}
.ui-state-icon { color: var(--ink-subtle); }
.ui-state--error .ui-state-icon { color: var(--danger-text); }
.ui-state-title { margin: 0; font-size: 18px; font-weight: 600; line-height: 1.3; color: var(--ink-primary); }
.ui-state-text { margin: 0; max-width: 52ch; font-size: 14px; line-height: 1.5; color: var(--ink-muted); }
.ui-state-action { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-top: 4px; }
.ui-spin { animation: uiSpin 1s linear infinite; }
@keyframes uiSpin { to { transform: rotate(360deg); } }

/* ---- Notes (next-action reason, review headings) ----------------------- */
.ui-note {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    padding: 10px 12px;
    border-radius: 10px;
    border: 1px solid transparent;
    font-size: 13px;
    line-height: 1.45;
}
.ui-note .ui-icon { margin-top: 1px; }
.ui-note--success { background: var(--success-bg); border-color: var(--success-border); color: var(--success-text); }
.ui-note--warning { background: var(--warning-bg); border-color: var(--warning-border); color: var(--warning-text); }
.ui-note--danger  { background: var(--danger-bg);  border-color: var(--danger-border);  color: var(--danger-text); }
.ui-note--info    { background: var(--info-bg);    border-color: var(--info-border);    color: var(--info-text); }

/* ---- Lifecycle strip (x-ui.lifecycle) ---------------------------------- */
.ui-lifecycle { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.ui-lifecycle > .ui-pill { align-self: flex-start; }
.ui-lifecycle-steps {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 4px;
    margin: 0;
    padding: 0;
    list-style: none;
}
.ui-lc-step { display: flex; flex-direction: column; gap: 6px; min-width: 0; font-size: 12px; font-weight: 500; color: var(--ink-muted); }
.ui-lc-bar { display: block; height: 6px; border-radius: 3px; background: var(--neutral-bg); border: 1px solid var(--neutral-border); }
.ui-lc-step.is-done .ui-lc-bar,
.ui-lc-step.is-current .ui-lc-bar { background: var(--brand-primary); border-color: var(--brand-primary); }
.ui-lc-step.is-current { color: var(--ink-primary); font-weight: 700; }
.ui-lc-step.is-current .ui-lc-bar { box-shadow: 0 0 0 2px var(--brand-accent); }
.ui-lc-label { overflow-wrap: anywhere; }

/* ---- Next action (x-ui.next-action) ------------------------------------ */
.ui-next {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 14px 16px;
    border: 1px solid var(--brand-primary-border);
    border-radius: var(--radius-md);
    background: var(--brand-primary-tint);
}
.ui-next-label { margin: 0; font-size: 12px; font-weight: 600; color: var(--brand-link); }
.ui-next-title { margin: 0; font-size: 16px; font-weight: 700; line-height: 1.35; color: var(--ink-primary); }
.ui-next-text { margin: 0; font-size: 14px; line-height: 1.5; color: var(--ink-secondary); }
.ui-next-actions { display: flex; flex-wrap: wrap; gap: 8px; }

/* ---- History note (x-ui.history-note) ---------------------------------- */
.ui-history-note {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px 8px;
    padding: 0 14px;
    border: 1px dashed var(--border-strong);
    border-radius: 10px;
    font-size: 13px;
    color: var(--ink-muted);
}
.ui-history-text { padding-block: 12px; flex: 0 1 auto; min-width: 0; }
.ui-history-note .ui-link { display: inline-flex; align-items: center; min-height: 44px; }

/* ---- Facts grid (a record's key facts, panel and page) ----------------- */
.ui-facts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 16px; margin: 0; }
.ui-facts dt { font-size: 12px; font-weight: 500; color: var(--ink-muted); }
.ui-facts dd { margin: 2px 0 0; font-weight: 600; color: var(--ink-primary); overflow-wrap: anywhere; }

/* ---- Dialogs: detail panel (drawer) and review modal ------------------- */
.ui-dialog {
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--ink-primary);
    max-width: none;
    max-height: none;
    overflow: visible;
}
.ui-dialog::backdrop { background: var(--bg-overlay); }
.ui-dialog-box {
    display: flex;
    flex-direction: column;
    background: var(--bg-card);
    color: var(--ink-primary);
    box-shadow: var(--shadow-xl);
}

.ui-panel {
    position: fixed;
    inset-block: 0;
    inset-inline-start: auto;
    inset-inline-end: 0;
    width: min(560px, 100%);
    height: 100%;
    height: 100dvh;
    margin: 0;
}
.ui-panel .ui-dialog-box { height: 100%; border-inline-start: 1px solid var(--border-light); --ui-slide: 100%; }
[dir="rtl"] .ui-panel .ui-dialog-box { --ui-slide: -100%; }
.ui-panel[open] .ui-dialog-box { animation: uiSlideIn .2s ease-out; }
@keyframes uiSlideIn { from { transform: translateX(var(--ui-slide)); } to { transform: none; } }
.ui-panel-head { display: flex; flex-direction: column; gap: 10px; padding: 16px 20px 14px; border-bottom: 1px solid var(--border-light); }
.ui-panel-top { display: flex; align-items: flex-start; gap: 12px; }
.ui-panel-title { flex: 1; min-width: 0; margin: 0; font-size: 21px; font-weight: 700; line-height: 1.3; color: var(--ink-primary); overflow-wrap: anywhere; }
.ui-panel-meta { display: flex; flex-direction: column; gap: 10px; }
.ui-panel-body { flex: 1; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: 18px; padding: 18px 20px 28px; }
.ui-panel-foot { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px; padding: 12px 20px; border-top: 1px solid var(--border-light); }

.ui-modal {
    width: min(640px, calc(100% - 32px));
    max-height: calc(100dvh - 32px);
    margin: auto;
}
.ui-modal .ui-dialog-box { max-height: calc(100dvh - 32px); border: 1px solid var(--border-light); border-radius: 14px; overflow: hidden; }
.ui-modal[open] .ui-dialog-box { animation: uiFadeIn .15s ease-out; }
@keyframes uiFadeIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.ui-modal-form { display: flex; flex-direction: column; min-height: 0; max-height: inherit; margin: 0; }
.ui-modal-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; padding: 16px 20px; border-bottom: 1px solid var(--border-light); }
.ui-modal-title { margin: 0; font-size: 19px; font-weight: 700; line-height: 1.3; color: var(--ink-primary); }
.ui-modal-body { flex: 1; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: 12px; padding: 18px 20px; }
.ui-modal-foot { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px; padding: 14px 20px; border-top: 1px solid var(--border-light); }
.ui-review-list { margin: 0; padding: 0; list-style: none; border: 1px solid var(--border-light); border-radius: 10px; }
.ui-review-list li { display: flex; flex-direction: column; gap: 2px; padding: 10px 14px; }
.ui-review-list li + li { border-top: 1px solid var(--border-light); }
.ui-review-title { font-weight: 600; color: var(--ink-primary); overflow-wrap: anywhere; }
.ui-review-meta { font-size: 13px; color: var(--ink-muted); }
.ui-review-reason { color: var(--warning-text); }
.ui-review-none { margin: 0; color: var(--ink-secondary); }

/* ---- Phones ------------------------------------------------------------ */
@media (max-width: 899.98px) {
    .ui-page-title { font-size: 24px; }
    .ui-facts { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 420px) {
    .ui-metric-value { font-size: 26px; }
    .ui-toolbar, .ui-card-head, .ui-card-body, .ui-card-foot, .ui-table-foot, .ui-bulkbar { padding-inline: 14px; }
    .ui-search { max-width: none; }
    .ui-select { flex: 1 1 100%; }
}

/* ---- Less motion when the person asked for it -------------------------- */
@media (prefers-reduced-motion: reduce) {
    .ui-spin,
    .ui-panel[open] .ui-dialog-box,
    .ui-modal[open] .ui-dialog-box { animation: none; }
    .ui-btn, .ui-chip, .ui-metric { transition: none; }
}
/* ---- Console shell: sidebar, header, drawer (redesign phase 2) --------- */
/* Drawn by admin/layout/app.blade.php + partials/shell-*.blade.php; what the
   sidebar lists comes from App\Support\Ui\Navigation. Sidebar 232px (72px
   folded to icons) on a desktop, a drawer from the start side under 900px;
   header 64px. Behaviour in mtcom-ui.js (initShell). */

/* The base gives <body> `overflow-x: hidden`, which turns it into a scroll box
   and stops a sticky header or sidebar from sticking. `clip` hides the same
   sideways spill without that side effect. */
body.app-body.ui-shell-body { overflow-x: clip !important; }

.ui-skip-link {
    position: absolute;
    top: -200px;
    inset-inline-start: 8px;
    z-index: 1100;
    padding: 10px 16px;
    border-radius: 10px;
    background: var(--brand-primary);
    color: var(--on-brand);
    font-weight: 600;
    text-decoration: none;
}
.ui-skip-link:focus { top: 8px; color: var(--on-brand); }

.ui-shell { display: flex; align-items: stretch; min-height: 100vh; min-height: 100dvh; }
.ui-shell-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.ui-shell-main > .main-content { flex: 1 0 auto; }
#main-content:focus { outline: none; }

/* Sidebar */
.ui-sidebar {
    --ui-nav-width: 232px;
    position: sticky;
    top: 0;
    z-index: 1015;
    flex: 0 0 var(--ui-nav-width);
    width: var(--ui-nav-width);
    height: 100vh;
    height: 100dvh;
    display: flex;
    flex-direction: column;
    overflow-y: auto;
    overscroll-behavior: contain;
    background: var(--bg-card);
    border-inline-end: 1px solid var(--border-light);
    color: var(--ink-primary);
}
.ui-sidebar-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    min-height: 64px;
    padding-block: 10px;
    padding-inline: 16px 12px;
    border-bottom: 1px solid var(--border-light);
}
.ui-brand {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    min-height: 44px;
    color: var(--ink-primary);
    font-size: 15px;
    font-weight: 700;
    letter-spacing: .08em;
    text-decoration: none;
}
.ui-brand:hover { color: var(--ink-primary); text-decoration: none; }
.ui-brand-mark {
    display: grid;
    place-items: center;
    flex: none;
    width: 32px;
    height: 32px;
    border-radius: 9px;
    background: var(--brand-primary);
    box-shadow: inset 0 -3px 0 var(--brand-accent);
    color: var(--on-brand);
    font-size: 15px;
    font-weight: 700;
    letter-spacing: 0;
}
.ui-sidebar-close { display: none; }

.ui-nav { flex: 1 0 auto; display: flex; flex-direction: column; gap: 14px; padding: 12px; }
.ui-nav-group { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ui-nav-label {
    margin: 0;
    padding: 0 10px 4px;
    color: var(--ink-muted);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .06em;
    line-height: 1.4;
    text-transform: uppercase;
}
[dir="rtl"] .ui-nav-label { font-size: 12px; letter-spacing: 0; text-transform: none; }
.ui-nav-list { display: flex; flex-direction: column; gap: 2px; margin: 0; padding: 0; list-style: none; }
.ui-nav-item {
    position: relative;
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 40px;
    padding: 8px 10px;
    border-radius: 8px;
    color: var(--ink-secondary);
    font-size: 14px;
    font-weight: 500;
    line-height: 1.3;
    text-decoration: none;
}
.ui-nav-item .ui-icon { color: var(--ink-muted); }
.ui-nav-item:hover { background: var(--bg-card-hover); color: var(--ink-primary); text-decoration: none; }
.ui-nav-item[aria-current="page"] { background: var(--brand-primary-tint); color: var(--brand-link); font-weight: 600; }
.ui-nav-item[aria-current="page"] .ui-icon { color: var(--brand-link); }
.ui-nav-item[aria-current="page"]::before {
    content: "";
    position: absolute;
    inset-block: 8px;
    inset-inline-start: 0;
    width: 3px;
    border-radius: 3px;
    background: var(--brand-accent);
}
.ui-nav-item--sub { min-height: 36px; padding-block: 6px; padding-inline: 38px 10px; font-size: 13px; }
.ui-nav-text { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.ui-nav-count {
    flex: none;
    min-width: 24px;
    padding: 1px 7px;
    border-radius: 999px;
    background: var(--neutral-bg);
    color: var(--neutral-text);
    font-size: 12px;
    font-weight: 600;
    line-height: 1.5;
    text-align: center;
    font-variant-numeric: tabular-nums;
}
.ui-nav-count--danger { background: var(--danger-bg); color: var(--danger-text); }

.ui-nav-more { margin: 0; }
.ui-nav-more > summary {
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 36px;
    padding: 6px 10px;
    border-radius: 8px;
    color: var(--ink-muted);
    font-size: 13px;
    font-weight: 600;
    list-style: none;
    cursor: pointer;
}
.ui-nav-more > summary::-webkit-details-marker { display: none; }
.ui-nav-more > summary::marker { content: ""; }
.ui-nav-more > summary:hover { background: var(--bg-card-hover); color: var(--ink-primary); }
.ui-nav-more-chevron { transition: transform .15s ease; }
.ui-nav-more[open] > summary .ui-nav-more-chevron { transform: rotate(180deg); }
:is(.ui-nav-item, .ui-nav-more > summary, .ui-campus-btn, .ui-topbar-btn, .ui-avatar-btn, .ui-popover-item, .ui-brand):focus-visible {
    outline: 2px solid var(--brand-accent);
    outline-offset: 2px;
    box-shadow: 0 0 0 2px var(--brand-link);
}

.ui-sidebar-foot {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 12px 22px 16px;
    border-top: 1px solid var(--border-light);
    color: var(--ink-muted);
    font-size: 12px;
    line-height: 1.45;
}
.ui-sidebar-foot-clock { display: inline-flex; align-items: center; gap: 6px; }
.ui-shell-clock { font-family: var(--font-mono); color: var(--ink-secondary); font-variant-numeric: tabular-nums; }
.ui-sidebar-foot-user { color: var(--ink-secondary); font-weight: 600; overflow-wrap: anywhere; }

/* Header */
.ui-topbar {
    position: sticky;
    top: 0;
    z-index: 1010;
    display: flex;
    align-items: center;
    gap: 8px;
    height: 64px;
    padding-inline: 24px;
    background: var(--bg-card);
    border-bottom: 1px solid var(--border-light);
    color: var(--ink-primary);
}
.ui-topbar-spacer { flex: 1 1 auto; min-width: 0; }

.ui-campus { position: relative; flex: 0 1 auto; min-width: 0; }
.ui-campus-btn,
.ui-campus--static {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    max-width: 100%;
    min-height: 44px;
    margin: 0;
    padding-inline: 12px 10px;
    border: 1px solid var(--border-strong);
    border-radius: 10px;
    background: var(--bg-card);
    color: var(--ink-primary);
    font-size: 14px;
    font-weight: 600;
    white-space: nowrap;
    cursor: pointer;
}
.ui-campus--static { border-color: var(--border-light); background: var(--bg-card-subtle); cursor: default; }
.ui-campus-btn:hover { background: var(--bg-card-hover); }
.ui-campus-btn .ui-icon,
.ui-campus--static .ui-icon { color: var(--ink-muted); }
.ui-campus-label { color: var(--ink-muted); font-size: 12px; font-weight: 500; }
.ui-campus-name { min-width: 0; max-width: 220px; overflow: hidden; text-overflow: ellipsis; }

.ui-topbar-search {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 1 1 320px;
    min-width: 0;
    max-width: 420px;
    min-height: 44px;
    margin: 0;
    padding-inline: 12px;
    border: 1px solid var(--border-light);
    border-radius: 10px;
    background: var(--bg-card-subtle);
    color: var(--ink-muted);
}
.ui-topbar-search:focus-within { border-color: var(--brand-link); background: var(--bg-card); }
.ui-topbar-search input {
    flex: 1;
    min-width: 0;
    min-height: 42px;
    margin: 0;
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--ink-primary);
    font-size: 14px;
}
.ui-topbar-search input::placeholder { color: var(--ink-subtle); opacity: 1; }
[data-theme="dark"] .ui-topbar-search input { color-scheme: dark; }
.ui-search-toggle { display: none; }

.ui-topbar-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    flex: none;
    min-width: 44px;
    min-height: 44px;
    margin: 0;
    padding-inline: 12px;
    border: 1px solid var(--border-light);
    border-radius: 10px;
    background: var(--bg-card);
    color: var(--ink-secondary);
    font-size: 13px;
    font-weight: 600;
    white-space: nowrap;
    text-decoration: none;
}
.ui-topbar-btn:hover { background: var(--bg-card-hover); color: var(--ink-primary); text-decoration: none; }

/* The theme switch shows what you would switch TO: a moon in light, a sun in dark. */
.ui-theme-icon-dark { display: none; }
[data-theme="dark"] .ui-theme-icon-light { display: none; }
[data-theme="dark"] .ui-theme-icon-dark { display: inline-block; }

.ui-menu-root { position: relative; flex: none; }
.ui-bell { position: relative; }
.ui-bell-dot {
    position: absolute;
    top: 9px;
    inset-inline-end: 10px;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: var(--danger-fill);
    box-shadow: 0 0 0 2px var(--bg-card);
}
.ui-avatar-btn {
    display: grid;
    place-items: center;
    width: 44px;
    height: 44px;
    margin: 0;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: var(--brand-primary-tint);
    color: var(--brand-link);
    font-size: 16px;
    font-weight: 700;
    cursor: pointer;
}
.ui-avatar-btn:hover { background: var(--bg-card-active); }

/* Header menus */
.ui-popover {
    position: absolute;
    top: calc(100% + 8px);
    inset-inline-end: 0;
    z-index: 1030;
    width: max-content;
    min-width: 240px;
    max-width: min(340px, calc(100vw - 24px));
    max-height: calc(100vh - 88px);
    max-height: calc(100dvh - 88px);
    overflow-y: auto;
    padding: 8px;
    background: var(--bg-card);
    border: 1px solid var(--border-light);
    border-radius: 12px;
    box-shadow: var(--shadow-lg);
    color: var(--ink-primary);
}
.ui-popover[hidden] { display: none; }
.ui-popover--start { inset-inline-end: auto; inset-inline-start: 0; }
.ui-popover-title { margin: 0; padding: 8px 10px 6px; color: var(--ink-muted); font-size: 12px; font-weight: 600; }
.ui-popover-list { display: flex; flex-direction: column; gap: 2px; margin: 0; padding: 0; list-style: none; }
.ui-popover-item {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    min-height: 44px;
    margin: 0;
    padding: 8px 10px;
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: var(--ink-primary);
    font-size: 14px;
    font-weight: 500;
    line-height: 1.35;
    text-align: start;
    text-decoration: none;
    cursor: pointer;
}
.ui-popover-item:hover { background: var(--bg-card-hover); color: var(--ink-primary); text-decoration: none; }
.ui-popover-item .ui-icon { color: var(--ink-muted); }
.ui-popover-item[aria-current="true"] { background: var(--brand-primary-tint); color: var(--brand-link); font-weight: 600; }
.ui-popover-item .ui-check-mark { visibility: hidden; color: var(--brand-link); }
.ui-popover-item[aria-current="true"] .ui-check-mark { visibility: visible; }
.ui-popover-item-text { flex: 1 1 auto; min-width: 0; }
.ui-popover-item--danger,
.ui-popover-item--danger .ui-icon { color: var(--danger-text); }
.ui-popover-item--danger:hover { background: var(--danger-bg); color: var(--danger-text); }
.ui-popover-empty { margin: 0; padding: 6px 10px 10px; color: var(--ink-muted); font-size: 14px; }
.ui-account-head {
    display: flex;
    flex-direction: column;
    gap: 2px;
    margin-bottom: 6px;
    padding: 8px 10px 10px;
    border-bottom: 1px solid var(--border-light);
}
.ui-account-name { color: var(--ink-primary); font-weight: 700; overflow-wrap: anywhere; }
.ui-account-role { color: var(--ink-muted); font-size: 13px; }
.ui-only-narrow { display: none; }

.ui-scrim { position: fixed; inset: 0; z-index: 1035; background: var(--bg-overlay); }
.ui-scrim[hidden] { display: none; }

/* Desktop: the sidebar folds to icons (the menu button; remembered per browser).
   Words hidden on screen below stay readable to a screen reader (clipped,
   not display:none), so every link and button keeps its name. */
@media (min-width: 900px) {
    html.ui-nav-collapsed .ui-sidebar { --ui-nav-width: 72px; }
    html.ui-nav-collapsed .ui-sidebar-head { justify-content: center; padding-inline: 8px; }
    html.ui-nav-collapsed :is(.ui-brand-name, .ui-nav-label, .ui-nav-text) {
        position: absolute !important;
        width: 1px !important;
        height: 1px !important;
        margin: -1px !important;
        padding: 0 !important;
        overflow: hidden !important;
        clip: rect(0 0 0 0) !important;
        white-space: nowrap !important;
        border: 0 !important;
    }
    html.ui-nav-collapsed .ui-nav { padding-inline: 10px; }
    html.ui-nav-collapsed .ui-nav-item { justify-content: center; padding-inline: 0; }
    html.ui-nav-collapsed .ui-nav-count {
        position: absolute;
        top: 1px;
        inset-inline-end: 2px;
        min-width: 18px;
        padding: 0 5px;
        font-size: 11px;
    }
    html.ui-nav-collapsed .ui-nav-more,
    html.ui-nav-collapsed .ui-sidebar-foot { display: none; }
}
@media (min-width: 900px) and (max-width: 1199.98px) {
    .ui-topbar { padding-inline: 16px; }
    .ui-campus-label {
        position: absolute !important;
        width: 1px !important;
        height: 1px !important;
        margin: -1px !important;
        padding: 0 !important;
        overflow: hidden !important;
        clip: rect(0 0 0 0) !important;
        white-space: nowrap !important;
        border: 0 !important;
    }
    .ui-campus-name { max-width: 150px; }
    .ui-topbar-search { flex-basis: 180px; }
}

/* Under 900px: the sidebar is a drawer from the start side (the right in
   Arabic/Urdu); the search opens as a row under the header. */
@media (max-width: 899.98px) {
    .ui-sidebar {
        position: fixed;
        inset-block: 0;
        inset-inline-start: 0;
        z-index: 1040;
        width: min(300px, 86vw);
        height: 100%;
        height: 100dvh;
        visibility: hidden;
        transform: translateX(var(--ui-nav-shift, -105%));
        box-shadow: var(--shadow-xl);
        transition: transform .2s ease, visibility 0s linear .2s;
    }
    [dir="rtl"] .ui-sidebar { --ui-nav-shift: 105%; }
    html.ui-nav-open .ui-sidebar { visibility: visible; transform: none; transition: transform .2s ease; }
    html.ui-nav-open { overflow: hidden; }
    .ui-sidebar-close { display: inline-grid; }
    .ui-nav-item, .ui-nav-more > summary { min-height: 44px; }

    .ui-topbar { gap: 6px; padding-inline: 12px; }
    .ui-topbar-search { display: none; }
    html.ui-search-open .ui-topbar-search {
        display: flex;
        position: absolute;
        top: 64px;
        inset-inline: 0;
        max-width: none;
        min-height: 60px;
        padding-inline: 16px;
        border-width: 0 0 1px;
        border-radius: 0;
        background: var(--bg-card);
        box-shadow: var(--shadow-md);
    }
    .ui-search-toggle { display: inline-grid; }
    .ui-campus-label {
        position: absolute !important;
        width: 1px !important;
        height: 1px !important;
        margin: -1px !important;
        padding: 0 !important;
        overflow: hidden !important;
        clip: rect(0 0 0 0) !important;
        white-space: nowrap !important;
        border: 0 !important;
    }
    .ui-campus-name { max-width: 36vw; }
    /* The base pads phone pages for a bottom bar this console no longer has. */
    body.app-body.ui-shell-body { padding-bottom: 0 !important; }
    .ui-shell .main-content { padding-bottom: 24px !important; }
}
@media (max-width: 575.98px) {
    /* Language and theme move into the account menu. */
    .ui-hide-narrow { display: none; }
    .ui-only-narrow { display: block; }
    .ui-campus--static { display: none; }
    .ui-campus-btn { padding-inline: 10px 8px; gap: 6px; }
    .ui-campus-btn .ui-campus-icon { display: none; }
    .ui-campus-name { max-width: 30vw; }
    /* Menus span the screen instead of hanging off a button near an edge. */
    .ui-popover,
    .ui-popover--start {
        position: fixed;
        top: 72px;
        inset-inline: 12px;
        width: auto;
        min-width: 0;
        max-width: none;
    }
}
@media (max-width: 360px) {
    .ui-topbar { gap: 4px; padding-inline: 8px; }
    /* The campus name gets the room; the button's border still says "tap me". */
    .ui-campus-btn .ui-campus-chevron { display: none; }
    .ui-campus-name { max-width: none; }
}
@media (pointer: coarse) {
    .ui-nav-item, .ui-nav-more > summary { min-height: 44px; }
}
@media (prefers-reduced-motion: reduce) {
    .ui-sidebar, html.ui-nav-open .ui-sidebar, .ui-nav-more-chevron { transition: none; }
}
@media print {
    .ui-sidebar, .ui-topbar, .ui-scrim, .ui-skip-link { display: none !important; }
}

/* ---- Campus in a form (x-ui.campus-field, redesign phase 3) ----------- */
/* The campus is picked once, in the header: a form shows it read-only, offers
   "keep / move to the top-bar campus" on an edit, or one "pick the campus"
   step while the header is on All campuses. */
.ui-campus-field { display: flex; flex-direction: column; gap: 8px; min-width: 0; margin-block-end: 16px; }
.ui-campus-line { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 0; font-size: 14px; color: var(--ink-primary); }
.ui-campus-line .ui-icon { color: var(--ink-muted); }
.ui-campus-hint { margin: 0; font-size: 13px; color: var(--ink-muted); }
.ui-campus-move { display: flex; flex-direction: column; gap: 4px; margin: 0; padding: 0; border: 0; min-width: 0; }
.ui-campus-move > legend { float: none; width: auto; margin-block-end: 4px; padding: 0; }
.ui-campus-choice { display: flex; align-items: center; gap: 10px; min-height: 44px; margin: 0; font-size: 14px; color: var(--ink-primary); cursor: pointer; }
.ui-campus-choice input { width: 18px; height: 18px; flex-shrink: 0; accent-color: var(--brand-primary); }
.ui-campus-pick {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 12px 14px;
    border: 1px solid var(--info-border);
    border-radius: var(--radius-md);
    background: var(--info-bg);
}
.ui-campus-pick-title { display: flex; align-items: center; gap: 8px; margin: 0; font-size: 15px; font-weight: 600; color: var(--info-text); }
.ui-field-error { margin: 0; font-size: 13px; font-weight: 600; color: var(--danger-text); }
/* The campus a list shows (x-ui.scope-line) - under the page title. */
.ui-scope-line { display: flex; align-items: center; gap: 6px; margin: 4px 0 0; font-size: 13px; color: var(--ink-muted); }
.ui-scope-line .ui-icon { color: var(--ink-subtle); }

/* ---- Live status line (Field tracking, redesign phase 3) --------------- */
/* A real state, never a fixed "Live" label: data-live-state is one of
   connecting | live | stale | offline | error, set by the page from the live
   connection and the age of the newest position. Icon + words, not colour
   alone. */
.ui-live { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; min-width: 0; font-size: 13px; color: var(--ink-primary); }
.ui-live-icons { display: inline-flex; align-items: center; }
.ui-live [data-live-icon] { display: none; }
.ui-live[data-live-state="connecting"] [data-live-icon="connecting"],
.ui-live[data-live-state="live"] [data-live-icon="live"],
.ui-live[data-live-state="stale"] [data-live-icon="stale"],
.ui-live[data-live-state="offline"] [data-live-icon="offline"],
.ui-live[data-live-state="error"] [data-live-icon="error"] { display: inline-block; }
.ui-live-text { font-weight: 600; }
.ui-live-time { color: var(--ink-muted); }
.ui-live[data-live-state="connecting"] .ui-live-icons { color: var(--ink-muted); }
.ui-live[data-live-state="live"] .ui-live-icons,
.ui-live[data-live-state="live"] .ui-live-text { color: var(--success-text); }
.ui-live[data-live-state="stale"] .ui-live-icons,
.ui-live[data-live-state="stale"] .ui-live-text,
.ui-live[data-live-state="offline"] .ui-live-icons,
.ui-live[data-live-state="offline"] .ui-live-text { color: var(--warning-text); }
.ui-live[data-live-state="error"] .ui-live-icons,
.ui-live[data-live-state="error"] .ui-live-text { color: var(--danger-text); }

/* ---- "This campus" or no campus (x-ui.campus-choice, redesign phase 3) - */
/* A spare part (this campus / shared store) or a blank asset label (this
   campus / no campus): two answers, the first showing the header campus. */
.ui-campus-choice-group { display: flex; flex-direction: column; gap: 4px; min-width: 0; margin: 0 0 16px; padding: 0; border: 0; }
.ui-campus-choice-group > legend { float: none; width: auto; margin-block-end: 4px; padding: 0; }
.ui-campus-choice-detail { padding-inline-start: 28px; }
.ui-campus-choice-detail .ui-campus-field { margin-block-end: 4px; }

/* ---- Overview (redesign phase 4): page rhythm and the two columns ------ */
/* /admin/dashboard: header, numbers, history note, then the work queue
   (wide) beside today's maintenance and stock exceptions; one column under
   1100px. A column with nothing allowed in it is not drawn, and the other
   then takes the full width. */
.ui-overview { display: flex; flex-direction: column; gap: 20px; min-width: 0; }
.ui-overview > .ui-page-head { margin: 0; }
.ui-overview-grid {
    display: grid;
    grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr);
    gap: 16px;
    align-items: start;
    min-width: 0;
}
.ui-overview-grid > :only-child { grid-column: 1 / -1; }
@media (max-width: 1099.98px) {
    .ui-overview-grid { grid-template-columns: minmax(0, 1fr); }
}

/* ---- Ranked work queue (x-ui.queue-item inside <ol class="ui-queue">) -- */
/* The whole row is the link to the ticket. Rank · title + facts · pill and
   the next action; under 600px the pill and next action wrap under the title. */
.ui-queue { margin: 0; padding: 0; list-style: none; }
.ui-queue > li + li { border-top: 1px solid var(--border-light); }
.ui-queue-row {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: center;
    gap: 12px;
    min-height: 44px;
    padding: 12px 18px;
    color: var(--ink-primary);
    text-decoration: none;
}
.ui-queue-row:hover { background: var(--bg-card-hover); color: var(--ink-primary); text-decoration: none; }
.ui-queue-row:focus-visible { box-shadow: inset 0 0 0 2px var(--brand-link); }
.ui-queue-rank {
    display: inline-grid;
    place-items: center;
    width: 28px;
    height: 28px;
    border-radius: 14px;
    background: var(--neutral-bg);
    color: var(--ink-secondary);
    font-size: 12px;
    font-weight: 700;
}
.ui-queue-rank--urgent { background: var(--danger-bg); color: var(--danger-text); }
.ui-queue-main { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.ui-queue-title {
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.ui-queue-meta { display: flex; flex-wrap: wrap; gap: 2px 10px; min-width: 0; font-size: 13px; color: var(--ink-muted); }
.ui-queue-meta > * { min-width: 0; overflow-wrap: anywhere; }
.ui-queue-side { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; min-width: 0; }
.ui-queue-next { font-size: 13px; font-weight: 600; line-height: 1.35; color: var(--brand-link); text-align: end; }
.ui-queue-next--waiting { font-weight: 500; color: var(--ink-muted); }
@media (max-width: 599.98px) {
    .ui-queue-row { grid-template-columns: auto minmax(0, 1fr); padding-inline: 14px; }
    .ui-queue-title { white-space: normal; overflow-wrap: anywhere; }
    .ui-queue-side { grid-column: 2; flex-direction: row; flex-wrap: wrap; align-items: center; }
    .ui-queue-next { text-align: start; }
}

/* ---- Simple list inside a card (visits, stock exceptions, activity) ---- */
/* <ul class="ui-list"><li><a class="ui-list-row">lead · main (title + sub) ·
   end</a></li></ul> - a row that opens something is one 44px link. */
.ui-list { margin: 0; padding: 0; list-style: none; }
.ui-list[hidden] { display: none; }
.ui-list > li + li { border-top: 1px solid var(--border-light); }
.ui-list-row {
    display: flex;
    align-items: center;
    gap: 12px;
    min-height: 44px;
    padding: 11px 18px;
    color: var(--ink-primary);
    text-decoration: none;
}
a.ui-list-row:hover { background: var(--bg-card-hover); color: var(--ink-primary); text-decoration: none; }
a.ui-list-row:focus-visible { box-shadow: inset 0 0 0 2px var(--brand-link); }
.ui-list-lead { flex: 0 0 auto; min-width: 52px; font-size: 13px; color: var(--ink-secondary); }
.ui-list-main { display: flex; flex-direction: column; gap: 2px; flex: 1 1 auto; min-width: 0; }
.ui-list-title { font-weight: 600; color: var(--ink-primary); overflow-wrap: anywhere; }
.ui-list-sub { font-size: 13px; line-height: 1.45; color: var(--ink-muted); overflow-wrap: anywhere; }
.ui-list-sub .ui-pill { vertical-align: middle; }
.ui-list-end { flex: 0 0 auto; }
.ui-list-empty { margin: 0; padding: 16px 18px; font-size: 14px; color: var(--ink-muted); }
.ui-list-empty[hidden] { display: none; }
@media (max-width: 420px) {
    .ui-list-row { gap: 10px; padding-inline: 14px; }
    .ui-list-lead { min-width: 44px; max-width: 64px; }
}

/* ---- Level bar: how full a shelf is against its reorder level --------- */
/* A native <progress> (the words beside it carry the numbers; the bar is
   aria-hidden). Indigo by default, red for a stock exception. */
.ui-bar {
    -webkit-appearance: none;
    appearance: none;
    display: block;
    flex: 0 0 auto;
    width: 72px;
    height: 6px;
    border: 0;
    border-radius: 3px;
    background: var(--neutral-bg);
    color: var(--brand-primary);
    overflow: hidden;
}
.ui-bar::-webkit-progress-bar { background: var(--neutral-bg); border-radius: 3px; }
.ui-bar::-webkit-progress-value { background: var(--brand-primary); border-radius: 3px; }
.ui-bar::-moz-progress-bar { background: var(--brand-primary); border-radius: 3px; }
.ui-bar--danger { color: var(--danger-fill); }
.ui-bar--danger::-webkit-progress-value { background: var(--danger-fill); }
.ui-bar--danger::-moz-progress-bar { background: var(--danger-fill); }

/* ---- Figures in a line (<dl class="ui-figures">) ----------------------- */
.ui-figures {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 20px;
    margin: 0;
    padding: 12px 18px;
    border-bottom: 1px solid var(--border-light);
    font-size: 13px;
    color: var(--ink-muted);
}
.ui-figures > div { display: flex; align-items: baseline; gap: 6px; }
.ui-figures dt { font-weight: 500; }
.ui-figures dd { margin: 0; font-weight: 700; color: var(--ink-primary); }
@media (max-width: 420px) {
    .ui-figures { padding-inline: 14px; }
}
@media (prefers-reduced-motion: reduce) {
    .ui-queue-row, .ui-list-row { transition: none; }
}

/* ---- Row "More" menu (x-ui.row-menu, redesign phase 5) ----------------- */
/* The row's less frequent actions (edit, certificate, delete…) behind one
   44px button. The list floats at a fixed spot next to its button, placed by
   mtcom-ui-components.js (below it, or above when there is no room), so a
   table that scrolls sideways never cuts it off. */
.ui-rowmenu { position: relative; display: inline-flex; }
.ui-rowmenu-panel {
    position: fixed;
    inset: auto;
    width: max-content;
    min-width: 220px;
    max-width: min(320px, calc(100vw - 16px));
}
.ui-table .ui-td-menu { width: 56px; padding-block: 0; padding-inline: 4px; text-align: end; }
@media (max-width: 899.98px) {
    /* On a phone card the menu sits in the top-end corner (the tick box has
       the top-start one), and the title keeps clear of it. */
    .ui-table-wrap--menu .ui-table tr { padding-inline-end: 56px; }
    .ui-table td.ui-td-menu { display: block; position: absolute; top: 4px; inset-inline-end: 6px; width: auto; padding: 0; }
}

/* ---- A row's own lines (title link, "#id · department", a second line) -- */
/* The title and a next-action link get a 44px hit area without making the row
   taller: they reach into the cell's padding (and still wrap cleanly). */
.ui-row-title { display: inline-block; padding-block: 12px; margin-block: -12px; }
a.ui-row-next { display: inline-block; padding-block: 14px; margin-block: -14px; }
.ui-row-title { color: var(--ink-primary); font-weight: 600; text-decoration: none; overflow-wrap: anywhere; }
.ui-row-title:hover { color: var(--brand-link); text-decoration: underline; text-underline-offset: 2px; }
.ui-row-title[dir="auto"] { text-align: -webkit-match-parent; text-align: match-parent; }
.ui-row-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; margin-top: 4px; font-size: 12px; font-weight: 400; color: var(--ink-muted); }
.ui-row-meta .ui-pill { padding: 1px 8px; font-size: 11px; }
.ui-table .ui-td-sub { display: block; font-size: 12px; font-weight: 400; color: var(--ink-muted); }
.ui-table .ui-td-nowrap { white-space: nowrap; }
.ui-row-next { font-size: 13px; font-weight: 600; line-height: 1.35; color: var(--brand-link); }
a.ui-row-next { text-decoration: underline; text-underline-offset: 2px; }
a.ui-row-next:hover { color: var(--brand-link-hover); }
.ui-row-next--waiting { font-weight: 500; color: var(--ink-muted); }
@media (max-width: 899.98px) {
    .ui-table td .ui-td-sub { display: inline; }
}

/* ---- Fields inside the building blocks (review steps, "More filters") -- */
/* The older stylesheet turns every <label> into a 12px bold capitalised caption
   (with !important). A label that IS one of these building blocks takes its own
   type back. */
:is(label.ui-field, label.ui-check-line, label.ui-check, label.ui-campus-choice) {
    margin-bottom: 0 !important;
    font-size: 14px !important;
    font-weight: 400 !important;
    letter-spacing: normal !important;
    text-transform: none !important;
    color: var(--ink-primary) !important;
}
.ui-field { display: flex; flex-direction: column; gap: 6px; min-width: 0; margin: 0; }
.ui-field-label { font-size: 13px; font-weight: 600; color: var(--ink-secondary); }
.ui-field-hint { margin: 0; font-size: 12px; color: var(--ink-muted); }
.ui-input {
    max-width: 100%;
    min-height: 44px;
    margin: 0;
    padding: 8px 12px;
    border: 1px solid var(--border-strong);
    border-radius: 10px;
    background-color: var(--bg-card);
    color: var(--ink-primary);
    font-size: 14px;
}
textarea.ui-input { min-height: 88px; resize: vertical; }
.ui-input:focus-visible { box-shadow: 0 0 0 2px var(--brand-link); }
[data-theme="dark"] .ui-input { color-scheme: dark; }
.ui-check-line { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; margin: 0; font-size: 14px; color: var(--ink-primary); cursor: pointer; }
.ui-check-line input { width: 18px; height: 18px; margin: 0; accent-color: var(--brand-primary); }

/* "More filters" inside a toolbar: a <details> that takes its own line when open. */
.ui-filter-more { flex: 0 0 auto; min-width: 0; }
.ui-filter-more[open] { flex: 1 0 100%; }
.ui-filter-more > summary {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-height: 44px;
    padding: 0 12px;
    border: 1px solid var(--border-strong);
    border-radius: 10px;
    background: var(--bg-card);
    color: var(--ink-secondary);
    font-size: 14px;
    font-weight: 600;
    list-style: none;
    cursor: pointer;
}
.ui-filter-more > summary::-webkit-details-marker { display: none; }
.ui-filter-more > summary:hover { background: var(--bg-card-hover); color: var(--ink-primary); }
.ui-filter-more > summary:focus-visible { box-shadow: 0 0 0 2px var(--brand-link); }
.ui-filter-more-body { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px; padding-top: 12px; }

/* Quiet lines between a list's toolbar and its rows ("Also filtered: …",
   "Searched every campus you are authorised for"). */
.ui-list-notes {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 10px 18px;
    border-bottom: 1px solid var(--border-light);
    font-size: 13px;
    color: var(--ink-muted);
}
.ui-list-notes p { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; margin: 0; }

/* A note that carries a short list (a bulk action's "these were not changed, because…"). */
.ui-note-body { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.ui-note-list { margin: 0; padding-inline-start: 18px; }
.ui-note-list li { overflow-wrap: anywhere; }

/* ---- Lifecycle step notes (when / by whom, redesign phase 6) ---------- */
.ui-lc-note { font-size: 12px; font-weight: 400; line-height: 1.35; color: var(--ink-muted); overflow-wrap: anywhere; }

/* ---- Tabs (x-ui.tabs + x-ui.tab-panel, redesign phase 6) --------------- */
/* Underlined tabs over a record's sections; the strip scrolls on its own
   (never the page) when four tabs do not fit a 320px phone. */
.ui-tabs {
    display: flex;
    flex-wrap: nowrap;
    gap: 4px 20px;
    margin: 0;
    padding: 0 2px;
    border-bottom: 1px solid var(--border-light);
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: thin;
}
.ui-tab {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    flex: 0 0 auto;
    min-height: 44px;
    margin: 0 0 -1px;
    padding: 0 2px;
    border: 0;
    border-bottom: 2px solid transparent;
    background: none;
    color: var(--ink-muted);
    font-size: 15px;
    font-weight: 600;
    white-space: nowrap;
    cursor: pointer;
}
.ui-tab:hover { color: var(--ink-primary); }
.ui-tab[aria-selected="true"] { color: var(--ink-primary); border-bottom-color: var(--brand-primary); }
.ui-tab:focus-visible { box-shadow: inset 0 0 0 2px var(--brand-link); border-radius: 6px; }
.ui-tab-count {
    min-width: 24px;
    padding: 1px 8px;
    border-radius: 999px;
    background: var(--neutral-bg);
    color: var(--neutral-text);
    font-size: 12px;
    font-weight: 600;
    text-align: center;
}
.ui-tab[aria-selected="true"] .ui-tab-count { background: var(--brand-primary-tint); color: var(--brand-link); }
.ui-tab-panel { min-width: 0; padding-top: 16px; }
.ui-tab-panel[hidden] { display: none !important; }
.ui-tab-panel:focus-visible { outline-offset: 4px; }

/* ---- A record's top: lifecycle, next action and key facts (phase 6) ---- */
/* The ticket page: page header (title, #code, pills, source), then one card
   with the lifecycle strip and, side by side, the next action and the facts
   (stacked under 900px). */
.ui-record { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.ui-record > .ui-page-head { margin: 0; }
.ui-record-top {
    display: flex;
    flex-direction: column;
    gap: 16px;
    min-width: 0;
    padding: 16px 18px;
    background: var(--bg-card);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-md);
}
.ui-record-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.35fr);
    gap: 16px 24px;
    align-items: start;
    min-width: 0;
}
.ui-facts--wide { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.ui-facts .ui-fact--danger dd { color: var(--danger-text); }
.ui-facts time { font-variant-numeric: tabular-nums; }
@media (max-width: 899.98px) {
    .ui-record-grid { grid-template-columns: minmax(0, 1fr); }
    .ui-facts--wide { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 380px) {
    .ui-record-top { padding: 14px; }
    .ui-facts--wide { grid-template-columns: minmax(0, 1fr); }
}

/* The record's code as a small button that copies it (44px tall to tap). */
.ui-code-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-height: 44px;
    margin: -6px 0;
    padding: 0 12px;
    border: 1px solid var(--border-strong);
    border-radius: 10px;
    background: var(--bg-card-subtle);
    color: var(--ink-primary);
    font-family: var(--font-mono, monospace);
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
}
.ui-code-chip:hover { background: var(--bg-card-hover); }
.ui-code-chip:focus-visible { box-shadow: 0 0 0 2px var(--brand-link); }
.ui-code-chip .ui-icon { color: var(--ink-muted); }

/* A record page's two columns inside a tab (main + side); one under 1100px. */
.ui-record-cols {
    display: grid;
    grid-template-columns: minmax(0, 1.8fr) minmax(0, 1fr);
    gap: 16px;
    align-items: start;
    min-width: 0;
}
.ui-record-cols > .ui-stack { min-width: 0; }
@media (max-width: 1099.98px) {
    .ui-record-cols { grid-template-columns: minmax(0, 1fr); }
}
.ui-text-block { margin: 0; font-size: 14px; line-height: 1.6; color: var(--ink-primary); white-space: pre-line; overflow-wrap: anywhere; }
.ui-text-muted { color: var(--ink-muted); }
.ui-subhead { margin: 0 0 4px; font-size: 12px; font-weight: 600; color: var(--ink-muted); }

/* A place's number. Neutral by default; `--coloured` wears the place's own
   colour, which the ticket page sets as --loc-color (the same eight as the
   field ticket page, each dark enough to carry white). */
.ui-loc-num {
    display: inline-grid;
    place-items: center;
    flex: 0 0 auto;
    min-width: 24px;
    height: 24px;
    padding: 0 6px;
    border: 1px solid var(--neutral-border);
    border-radius: 7px;
    background: var(--neutral-bg);
    color: var(--neutral-text);
    font-size: 12px;
    font-weight: 700;
    line-height: 1;
}
.ui-loc-num--coloured { background: var(--loc-color, var(--brand-primary)); border-color: var(--loc-color, var(--brand-primary)); color: var(--on-brand); }

/* Evidence place by place: number · place + status · "Evidence 2 of 3" + bar. */
.ui-evidence-row { display: flex; align-items: flex-start; gap: 12px; padding: 12px 18px; }
.ui-evidence-main { display: flex; flex-direction: column; gap: 4px; flex: 1 1 auto; min-width: 0; }
.ui-evidence-count { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; font-size: 13px; color: var(--ink-secondary); }
.ui-evidence-count .ui-bar { width: 96px; }
.ui-evidence-count--done { color: var(--success-text); font-weight: 600; }
/* A text link inside a row's lines gets a 44px hit area without making the row taller. */
:is(.ui-evidence-count, .ui-person-main) > .ui-link { display: inline-flex; align-items: center; min-height: 44px; margin-block: -12px; }
@media (max-width: 420px) {
    .ui-evidence-row { padding-inline: 14px; }
}

/* People on a record (technicians, the reporter) with their small actions. */
.ui-person { display: flex; align-items: center; gap: 12px; padding: 10px 18px; }
.ui-person + .ui-person { border-top: 1px solid var(--border-light); }
.ui-person-initial {
    display: inline-grid;
    place-items: center;
    flex: 0 0 auto;
    width: 40px;
    height: 40px;
    border-radius: 10px;
    background: var(--brand-primary-tint);
    color: var(--brand-link);
    font-weight: 700;
}
.ui-person-main { display: flex; flex-direction: column; gap: 2px; flex: 1 1 auto; min-width: 0; }
.ui-person-name { font-weight: 600; color: var(--ink-primary); overflow-wrap: anywhere; }
.ui-person-sub { font-size: 13px; color: var(--ink-muted); overflow-wrap: anywhere; }
.ui-person-actions { display: flex; flex-wrap: wrap; gap: 6px; }
@media (max-width: 420px) {
    .ui-person { padding-inline: 14px; }
}

/* One gallery, grouped by place (the ticket's Evidence tab). */
.ui-gallery-group + .ui-gallery-group { margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--border-light); }
.ui-gallery-group[hidden] { display: none; }
.ui-gallery-head { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; margin: 0 0 12px; font-size: 15px; font-weight: 600; color: var(--ink-primary); }
.ui-gallery-head .ui-card-meta { font-weight: 400; }
.ui-gallery-filters { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 16px; }

/* A next step this person cannot take ("Waiting for a supervisor to close") is
   information, not a call to act: a quieter box. A line under the buttons
   (why they cannot send the work back). */
.ui-next--waiting { border-color: var(--border-light); background: var(--bg-card-subtle); }
.ui-next--waiting .ui-next-title { color: var(--ink-secondary); }
.ui-next-after { display: flex; flex-direction: column; gap: 4px; }
.ui-next-after .ui-next-text { display: flex; align-items: flex-start; gap: 6px; font-size: 13px; }
.ui-next-after .ui-icon { margin-top: 2px; }
.ui-record-tabs { display: flex; flex-direction: column; min-width: 0; }

/* A QR code for opening the record on a phone. */
.ui-qr { display: flex; flex-direction: column; align-items: center; gap: 6px; margin: 0; padding: 12px; border: 1px solid var(--border-light); border-radius: 10px; background: var(--bg-card-subtle); }
.ui-qr img { display: block; width: 110px; height: 110px; border-radius: 6px; }
.ui-qr figcaption { font-size: 12px; color: var(--ink-muted); text-align: center; }

/* The quick panel's own head row: code and pills, "Open full ticket" at the end. */
.ui-peek-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; }
.ui-peek-section { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.ui-peek-section > .ui-list { border: 1px solid var(--border-light); border-radius: 12px; }
.ui-peek-section .ui-evidence-row,
.ui-peek-section .ui-list-row { padding-inline: 14px; }

/* ---- Planned maintenance (redesign phase 7) ---------------------------- */
/* Two views as a segmented control: <x-ui.view-chips class="ui-views--seg">
   (the same GET form and buttons, joined into one control). */
.ui-maint-switches { gap: 10px 16px; }
.ui-views--seg { gap: 0; flex-wrap: nowrap; max-width: 100%; }
.ui-views--seg .ui-chip { border-radius: 0; margin-inline-start: -1px; }
.ui-views--seg .ui-chip:first-of-type { margin-inline-start: 0; border-start-start-radius: 10px; border-end-start-radius: 10px; }
.ui-views--seg .ui-chip:last-of-type { border-start-end-radius: 10px; border-end-end-radius: 10px; }
.ui-views--seg .ui-chip[aria-pressed="true"] { position: relative; }
/* The seven days of "This week": quieter, smaller chips under the windows. */
.ui-views--days .ui-chip { min-height: 40px; padding: 0 12px; font-size: 13px; }
@media (pointer: coarse) { .ui-views--days .ui-chip { min-height: 44px; } }
@media (max-width: 420px) {
    .ui-views--seg { width: 100%; }
    .ui-views--seg .ui-chip { flex: 1 1 0; justify-content: center; white-space: normal; text-align: center; padding-inline: 10px; }
}

/* A visit's checklist: a short bar and "3/8" (the words for a screen reader beside it). */
.ui-checklist { display: inline-flex; align-items: center; gap: 8px; }
.ui-checklist .ui-bar { width: 64px; }
/* A plan's late visits (red: the one urgent thing on its row), and its Year view link
   with a 44px hit area that does not make the row taller. */
.ui-table .ui-plan-late { display: block; font-size: 12px; font-weight: 600; color: var(--danger-text); }
.ui-table a.ui-link.ui-td-sub { display: block; width: fit-content; padding-block: 12px; margin-block: -12px; }
@media (max-width: 899.98px) {
    .ui-table .ui-plan-late { display: inline; }
}

/* The plan form: its steps, the form beside the preview (stacked under 1100px). */
.ui-steps ol { display: flex; flex-wrap: wrap; gap: 8px; margin: 0; padding: 0; list-style: none; }
.ui-steps a {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-height: 44px;
    /* Logical sides: the number's side 8px, the words' end 14px - mirrored in right to left (review CGW-RTL-1). */
    padding-block: 0;
    padding-inline: 8px 14px;
    border: 1px solid var(--border-light);
    border-radius: 999px;
    background: var(--bg-card);
    color: var(--ink-secondary);
    font-size: 14px;
    font-weight: 600;
    text-decoration: none;
}
.ui-steps a:hover { background: var(--bg-card-hover); color: var(--ink-primary); text-decoration: none; }
.ui-steps a:focus-visible { box-shadow: 0 0 0 2px var(--brand-link); }
.ui-step-num {
    display: inline-grid;
    place-items: center;
    flex: 0 0 auto;
    width: 26px;
    height: 26px;
    border-radius: 999px;
    background: var(--brand-primary-tint);
    color: var(--brand-link);
    font-size: 13px;
    font-weight: 700;
}
.ui-card-title .ui-step-num { margin-inline-end: 10px; vertical-align: middle; }
.ui-plan-form { margin: 0; }
.ui-plan-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 360px);
    gap: 16px;
    align-items: start;
    margin-top: 16px;
    min-width: 0;
}
.ui-plan-step, .ui-plan-aside { scroll-margin-top: 80px; }
.ui-plan-aside { position: sticky; top: 80px; }
.ui-plan-subhead { margin: 16px 0 6px; font-size: 15px; font-weight: 600; color: var(--ink-primary); }
/* The form's older buttons inside the steps keep a finger-sized target. */
.ui-plan-step .remove-checklist-item { min-width: 44px; min-height: 44px; }
.ui-plan-hint { margin-top: 30px; }
.ui-plan-weekend { margin-top: 4px; }
.ui-plan-weekend .form-check-label { font-weight: 600; color: var(--ink-primary); }
.ui-plan-weekend-time { max-width: 260px; margin-top: 6px; }
.ui-plan-actions { justify-content: flex-end; }
@media (max-width: 1099.98px) {
    .ui-plan-grid { grid-template-columns: minmax(0, 1fr); }
    .ui-plan-aside { position: static; }
    .ui-plan-hint { margin-top: 0; }
}

/* The preview: a summary, the next visit dates, and notes (weekend days skipped…). */
.ui-preview { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.ui-preview[aria-busy="true"] { opacity: .6; }
.ui-preview-summary { margin: 0; font-size: 15px; font-weight: 600; line-height: 1.45; color: var(--ink-primary); overflow-wrap: anywhere; }
.ui-preview-sub { margin: 0; font-size: 13px; color: var(--ink-secondary); }
.ui-preview-hint { margin: 0; font-size: 14px; line-height: 1.5; color: var(--ink-muted); }
.ui-preview-dates { margin: 0; padding-inline-start: 22px; font-size: 14px; color: var(--ink-primary); font-variant-numeric: tabular-nums; }
.ui-preview-dates li { padding-block: 2px; }
.ui-preview-notes { display: flex; flex-direction: column; gap: 6px; margin: 0; padding: 0; list-style: none; font-size: 13px; line-height: 1.45; color: var(--ink-secondary); }
.ui-preview-notes li { padding-inline-start: 10px; border-inline-start: 3px solid var(--warning-border); }
@media (prefers-reduced-motion: reduce) {
    .ui-plan-step, .ui-plan-aside { scroll-behavior: auto; }
}

/* ---- Approvals queue (redesign phase 8) -------------------------------- */
/* <ol class="ui-approvals"><li class="ui-approval"> main (kind pill · waiting ·
   campus / what / facts / note) beside its actions; the actions wrap under the
   text below 720px. Every button is the door that already decides the thing. */
.ui-approvals { margin: 0; padding: 0; list-style: none; }
.ui-approvals > li + li { border-top: 1px solid var(--border-light); }
.ui-approval {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: 10px 16px;
    padding: 14px 18px;
}
.ui-approval-main { display: flex; flex-direction: column; gap: 4px; flex: 1 1 320px; min-width: 0; }
.ui-approval-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px 10px;
    margin: 0;
    font-size: 12px;
    color: var(--ink-muted);
}
.ui-approval-meta .ui-pill { padding: 1px 8px; font-size: 12px; }
.ui-approval-title {
    margin: 2px 0 0;
    font-size: 15px;
    font-weight: 600;
    line-height: 1.4;
    color: var(--ink-primary);
    overflow-wrap: anywhere;
}
.ui-approval-title[dir="auto"] { text-align: -webkit-match-parent; text-align: match-parent; }
.ui-approval-sub {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 2px 6px;
    margin: 0;
    font-size: 13px;
    line-height: 1.45;
    color: var(--ink-muted);
}
.ui-approval-sub > span { min-width: 0; overflow-wrap: anywhere; }
.ui-approval-sub > span + span::before { content: "·"; margin-inline-end: 6px; color: var(--ink-muted); }
.ui-approval-sub.ui-text-danger { color: var(--danger-text); }
.ui-approval-reason {
    display: flex;
    align-items: flex-start;
    gap: 6px;
    margin: 2px 0 0;
    font-size: 13px;
    font-weight: 600;
    color: var(--warning-text);
}
.ui-approval-reason .ui-icon { margin-top: 2px; flex: 0 0 auto; }
.ui-approval-note {
    margin: 4px 0 0;
    padding-inline-start: 10px;
    border-inline-start: 3px solid var(--border-strong);
    font-size: 13px;
    line-height: 1.5;
    color: var(--ink-secondary);
    overflow-wrap: anywhere;
    white-space: pre-line;
}
.ui-approval-actions { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 8px; flex: 0 1 auto; }
.ui-approval-ticket { font-size: 13px; }
span.ui-approval-ticket { display: inline-flex; align-items: center; min-height: 36px; color: var(--ink-muted); }
@media (max-width: 719.98px) {
    .ui-approval { padding-inline: 14px; }
    .ui-approval-actions { flex: 1 0 100%; justify-content: flex-start; }
}

/* ---- Stock exceptions: the available quantity above its level bar ------ */
.ui-stock-qty { display: block; font-weight: 700; }
.ui-table td .ui-bar { margin-top: 6px; }
@media (max-width: 899.98px) {
    .ui-stock-qty { display: inline; }
    .ui-table td .ui-bar { margin-top: 0; }
}

/* ---- Field tracking: the map under the list ---------------------------- */
/* Leaflet needs a box with its own height to draw into. */
.ui-map { display: block; width: 100%; height: 420px; border-end-start-radius: var(--radius-md); border-end-end-radius: var(--radius-md); }
.ui-map[hidden] { display: none; }
.ui-map--history { height: 320px; margin-bottom: 20px; border: 1px solid var(--border-light); border-radius: 12px; }
.ui-map-history-list { max-height: 250px; overflow-y: auto; }
.ui-map-note { margin: 12px 18px; }
@media (max-width: 599.98px) {
    .ui-map { height: 300px; }
    .ui-map--history { height: 240px; }
}

/* ---- Reports hub, saved reports, certificates (redesign phase 9) ------- */
/* Chips that are LINKS (two lists behind one page, quick periods): the chip look,
   the current one marked with aria-current instead of aria-pressed. */
.ui-views--links a.ui-chip { text-decoration: none; }
.ui-views--links a.ui-chip:hover { text-decoration: none; }
.ui-views--links a.ui-chip:focus-visible { box-shadow: 0 0 0 2px var(--brand-link); }
.ui-views--links a.ui-chip[aria-current] { background: var(--brand-primary); border-color: var(--brand-primary); color: var(--on-brand); }

/* Analytics hub: the period (chosen once), the "right now" numbers, the
   question cards and the totals. */
.ui-hub-note { margin-bottom: 12px; }
.ui-hub-presets { margin-bottom: 12px; }
.ui-hub-period { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px; margin: 0; }
.ui-hub-period .ui-field { flex: 0 1 200px; }
.ui-hub-section { gap: 8px; }
.ui-hub-heading { margin: 0; font-size: 18px; font-weight: 600; line-height: 1.3; color: var(--ink-primary); }
.ui-hub-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px; min-width: 0; }
@media (min-width: 1100px) {
    .ui-hub-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: start; }
}
.ui-hub-entry { display: flex; align-items: stretch; min-width: 0; }
.ui-hub-link {
    display: flex;
    align-items: center;
    gap: 12px;
    flex: 1 1 auto;
    min-width: 0;
    min-height: 44px;
    padding: 12px 18px;
    color: var(--ink-primary);
    text-decoration: none;
}
.ui-hub-link:hover { background: var(--bg-card-hover); color: var(--ink-primary); text-decoration: none; }
.ui-hub-link:hover .ui-list-title { color: var(--brand-link); text-decoration: underline; text-underline-offset: 2px; }
.ui-hub-link:focus-visible { outline: none; box-shadow: inset 0 0 0 2px var(--brand-link); }
.ui-hub-link .ui-list-title { display: inline-flex; align-items: center; gap: 6px; }
.ui-hub-go { flex: 0 0 auto; color: var(--ink-subtle); }
.ui-hub-covers { display: inline-flex; align-items: center; gap: 4px; margin-top: 2px; font-size: 12px; color: var(--ink-muted); }
.ui-hub-exports { display: flex; flex: 0 0 auto; align-items: center; gap: 6px; padding-inline-end: 12px; }
@media (max-width: 599.98px) {
    .ui-hub-entry { flex-wrap: wrap; }
    .ui-hub-link { flex-basis: 100%; }
    .ui-hub-exports { padding-inline: 18px; padding-bottom: 12px; }
}

/* A date inside a list's toolbar: its word beside the field. */
.ui-toolbar-date { display: inline-flex; align-items: center; gap: 6px; min-width: 0; margin: 0; font-size: 13px; color: var(--ink-secondary); }
label.ui-toolbar-date {
    margin-bottom: 0 !important;
    font-size: 13px !important;
    font-weight: 500 !important;
    letter-spacing: normal !important;
    text-transform: none !important;
    color: var(--ink-secondary) !important;
}
.ui-toolbar-date .ui-input { width: auto; min-width: 0; max-width: 170px; }

/* Certificates: the download (or why not yet) and the printable view. */
.ui-cert-buttons { display: inline-flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 6px; }
.ui-cert-reason { display: block; max-width: 30ch; margin-top: 4px; margin-inline-start: auto; font-size: 12px; line-height: 1.4; color: var(--ink-muted); white-space: normal; text-align: end; }
@media (max-width: 899.98px) {
    .ui-cert-buttons { justify-content: flex-start; }
    .ui-cert-reason { flex-basis: 100%; max-width: none; margin-inline-start: 0; text-align: start; }
}

/* Saved reports: progress beside its percentage, a menu item that is a form, the share dialog. */
.ui-saved-progress { display: flex; align-items: center; gap: 8px; margin-top: 4px; }
[data-saved-list] .ui-rowmenu-panel form { margin: 0; }
.ui-saved-share-name { margin: 0; font-weight: 600; color: var(--ink-primary); overflow-wrap: anywhere; }
/* (end of: reports, phase 9) */

/* ---- Settings in sections (redesign phase 9) --------------------------- */
/* /admin/settings: six tabs, each its own form - an intro line, cards of fields
   (the shared .ui-field / .ui-input / .ui-select / .ui-check-line), then a save
   bar that stays in reach while the section scrolls. */
.ui-settings [hidden] { display: none !important; }
.ui-settings-sections { min-width: 0; }
.ui-settings-form { display: flex; flex-direction: column; gap: 16px; min-width: 0; margin: 0; }
.ui-settings-intro { max-width: 72ch; margin: 0; font-size: 14px; line-height: 1.5; color: var(--ink-secondary); }
.ui-settings-fieldset,
.ui-settings-group { display: flex; flex-direction: column; min-width: 0; margin: 0; padding: 0; border: 0; }
.ui-settings-fieldset { gap: 16px; }
.ui-settings-group { gap: 8px; }
.ui-settings-group > legend {
    float: none;
    width: auto;
    margin: 0 0 2px;
    padding: 0;
    font-size: 13px;
    font-weight: 600;
    line-height: 1.4;
    color: var(--ink-secondary);
}
/* auto-fill: a card with one box keeps it box-sized instead of stretching it across. */
.ui-settings-grid { grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr)); gap: 16px; }
.ui-settings-item { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.ui-settings-item .ui-field-hint,
.ui-settings-group .ui-field-hint { line-height: 1.45; }
.ui-settings-control { width: 100%; }
.ui-settings .ui-input[aria-invalid="true"],
.ui-settings .ui-select[aria-invalid="true"] { border-color: var(--danger-border); }
.ui-settings-fieldset[disabled] :is(.ui-input, .ui-select) { background-color: var(--bg-card-subtle); color: var(--ink-muted); cursor: not-allowed; }
.ui-settings-fieldset[disabled] .ui-check-line { color: var(--ink-muted); cursor: not-allowed; }

/* On/off lines: the words beside the box, the hint under the words. */
.ui-settings-checks { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.ui-settings-checks--grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr)); gap: 4px 16px; }
.ui-settings-check { gap: 0; }
.ui-settings-check .ui-check-line { font-weight: 600; }
.ui-settings-check .ui-field-hint { padding-inline-start: 26px; }

/* The seven weekend days as finger-sized chips. */
.ui-settings-days { display: flex; flex-wrap: wrap; gap: 8px; }
.ui-settings-day { padding-inline: 12px; border: 1px solid var(--border-light); border-radius: 10px; background: var(--bg-card); }
.ui-settings-day:has(input:checked) { border-color: var(--brand-primary-border); background: var(--brand-primary-tint); }
.ui-settings-day:focus-within { box-shadow: 0 0 0 2px var(--brand-link); }

/* The report logo beside its upload box. */
.ui-settings-logo { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 16px; }
.ui-settings-logo > .ui-settings-item { flex: 1 1 280px; }
.ui-settings-logo-now { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; }
.ui-settings-logo-img {
    display: block;
    max-width: 220px;
    max-height: 80px;
    padding: 8px;
    border: 1px solid var(--border-light);
    border-radius: 10px;
    background: var(--bg-card);
    object-fit: contain;
}

.ui-settings-subhead {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin: 0;
    font-size: 14px;
    font-weight: 600;
    line-height: 1.4;
    color: var(--ink-primary);
}
.ui-settings .ui-field-label .ui-pill { margin-inline-start: 8px; }
.ui-settings-plan { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px; }
.ui-settings-plan > .ui-field { flex: 1 1 200px; }
.ui-settings-facts { display: flex; flex-direction: column; gap: 4px; margin: 0; padding: 0; list-style: none; font-size: 13px; line-height: 1.45; color: var(--ink-muted); }
.ui-settings-facts strong { font-weight: 600; color: var(--ink-primary); }

/* Voice notes: counts, the settings, then the tools and the health line. */
[data-settings-voice] > .ui-card-body { display: flex; flex-direction: column; gap: 16px; }
.ui-settings-voice-status,
.ui-settings-tools { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.ui-settings-tools { padding-top: 16px; border-top: 1px solid var(--border-light); }
.ui-settings-figures { padding: 0; border-bottom: 0; }

/* The save bar: what is unsaved, then the section's one Save button. */
.ui-settings-savebar {
    position: sticky;
    bottom: 0;
    z-index: 5;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: 8px 16px;
    padding: 12px 16px;
    border: 1px solid var(--border-light);
    border-radius: var(--radius-md);
    background: var(--bg-card);
}
.ui-settings-dirty { margin: 0; margin-inline-end: auto; font-size: 14px; font-weight: 600; color: var(--warning-text); }
.ui-settings-form[data-settings-dirty] .ui-settings-savebar { border-color: var(--warning-border); }
.ui-settings-tab-dirty {
    display: inline-block;
    flex: 0 0 auto;
    width: 8px;
    height: 8px;
    border-radius: 999px;
    background: var(--warning-text);
}
.ui-settings-leave-text { margin: 0; font-size: 15px; line-height: 1.5; color: var(--ink-primary); }
@media (max-width: 479.98px) {
    .ui-settings-savebar { padding-inline: 12px; }
    .ui-settings-savebar .ui-btn { flex: 1 1 100%; justify-content: center; }
    .ui-settings-check .ui-field-hint { padding-inline-start: 0; }
}
/* (end of: settings, phase 9) */

/* ---- Modules, messaging integrations, Telegram groups (phase 9) ------- */
/* A quiet line under a page's cards (what switching keeps, who sees what). */
.ui-int-note { margin: 0; font-size: 13px; line-height: 1.5; color: var(--ink-muted); overflow-wrap: anywhere; }

/* Modules: one item per part - icon, name + one sentence, state pill; the state
   in words; "Needs" / "Used by"; the actions (switch opens a review). */
.ui-module-list { margin: 0; padding: 0; list-style: none; }
.ui-module { display: flex; flex-direction: column; gap: 10px; padding-block: 16px; min-width: 0; }
.ui-module:first-child { padding-block-start: 0; }
.ui-module:last-child { padding-block-end: 0; }
.ui-module + .ui-module { border-top: 1px solid var(--border-light); }
.ui-module-head { display: flex; align-items: flex-start; gap: 12px; min-width: 0; }
.ui-module-icon {
    display: inline-grid;
    place-items: center;
    flex: 0 0 auto;
    width: 40px;
    height: 40px;
    border-radius: 10px;
    background: var(--brand-primary-tint);
    color: var(--brand-link);
}
.ui-module-main { display: flex; flex-direction: column; gap: 2px; flex: 1 1 auto; min-width: 0; }
.ui-module-name { margin: 0; font-size: 16px; font-weight: 600; line-height: 1.35; color: var(--ink-primary); }
.ui-module-about { margin: 0; font-size: 14px; line-height: 1.5; color: var(--ink-secondary); overflow-wrap: anywhere; }
.ui-module-head > .ui-pill { flex: 0 0 auto; }
.ui-module-line { margin: 0; font-size: 13px; line-height: 1.5; color: var(--ink-secondary); }
.ui-module-deps { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px 16px; margin: 0; }
.ui-module-deps dt { font-size: 12px; font-weight: 500; color: var(--ink-muted); }
.ui-module-deps dd { margin: 2px 0 0; font-size: 14px; font-weight: 600; color: var(--ink-primary); overflow-wrap: anywhere; }
.ui-module-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
/* What a switch will do, inside its review dialog. */
.ui-module-impact { display: flex; flex-direction: column; gap: 6px; margin: 12px 0 0; padding-inline-start: 20px; font-size: 14px; line-height: 1.5; color: var(--ink-primary); }
.ui-module-impact li { overflow-wrap: anywhere; }
@media (max-width: 599.98px) {
    .ui-module-head { flex-wrap: wrap; }
    .ui-module-head > .ui-pill { order: 3; margin-inline-start: 52px; }
    .ui-module-deps { grid-template-columns: minmax(0, 1fr); }
}

/* Messaging integrations: one card per connection (state pill in the head,
   the state in words, delivery health, who may be messaged, Open in the foot). */
.ui-figures.ui-conn-figures { padding: 0; border-bottom: 0; }
.ui-conn-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); gap: 16px; align-items: stretch; min-width: 0; }
.ui-conn { display: flex; flex-direction: column; min-width: 0; }
.ui-conn > .ui-card-body { flex: 1 1 auto; }
.ui-conn-body { gap: 12px; }
.ui-conn-line { margin: 0; font-size: 14px; line-height: 1.5; color: var(--ink-secondary); overflow-wrap: anywhere; }
.ui-conn-lists { margin: 0; font-size: 13px; line-height: 1.5; color: var(--ink-muted); }
.ui-conn-health { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.ui-conn-health .ui-facts dd { font-weight: 600; }
.ui-conn-form { min-width: 0; margin: 0; }
.ui-conn-label { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; }
.ui-conn-label .ui-pill { padding: 1px 8px; font-size: 11px; }
.ui-conn-cap { max-width: 12rem; }
.ui-conn-test { gap: 10px; padding-top: 12px; border-top: 1px solid var(--border-light); }
.ui-conn-test .ui-subhead { margin: 0; }

/* A connection's two number lists inside one card: each section has its head,
   its add form and its table. */
.ui-num-section + .ui-num-section { border-top: 1px solid var(--border-light); }
.ui-num-head { display: flex; flex-direction: column; gap: 4px; padding: 16px 18px 8px; }
.ui-num-title { display: flex; align-items: center; gap: 8px; margin: 0; font-size: 16px; font-weight: 600; color: var(--ink-primary); }
.ui-num-title .ui-icon { color: var(--ink-muted); }
.ui-num-add {
    display: grid;
    grid-template-columns: minmax(0, 1.2fr) minmax(0, 1.5fr) minmax(0, 1fr) auto;
    align-items: end;
    gap: 12px;
    margin: 0;
    padding: 8px 18px 16px;
}
.ui-num-add .ui-select { width: 100%; }
@media (max-width: 899.98px) {
    .ui-num-add { grid-template-columns: minmax(0, 1fr); }
    .ui-num-head, .ui-num-add { padding-inline: 14px; }
}

/* Telegram groups: the connection setup (the bot beside "how a group gets
   here"), a group's settings form, what it is told about, the chat commands,
   and the rights explainer. */
.ui-tg-setup { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px 24px; align-items: start; }
.ui-tg-setup .ui-subhead { margin: 0; }
.ui-facts .ui-tg-wide { grid-column: 1 / -1; }
.ui-facts .mono { overflow-wrap: anywhere; }
.ui-tg-steps { display: flex; flex-direction: column; gap: 6px; margin: 0; padding-inline-start: 20px; font-size: 14px; line-height: 1.5; color: var(--ink-primary); }
.ui-tg-form .ui-select, .ui-tg-form .ui-input { width: 100%; }
.ui-tg-pair { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 16px; }
.ui-tg-events { display: flex; flex-direction: column; gap: 6px; margin: 0 0 8px; padding: 0; list-style: none; }
.ui-tg-events li { display: flex; align-items: center; gap: 8px; min-height: 28px; font-size: 14px; color: var(--ink-primary); }
.ui-tg-events li[data-event-on="0"] { color: var(--ink-muted); }
.ui-tg-events li[data-event-on="1"] .ui-icon { color: var(--success-text); }
.ui-tg-event-state { margin-inline-start: auto; font-size: 12px; color: var(--ink-muted); }
.ui-tg-commands { display: flex; flex-direction: column; gap: 6px; margin: 0 0 8px; }
.ui-tg-commands > div { display: grid; grid-template-columns: minmax(7.5rem, auto) minmax(0, 1fr); gap: 8px; align-items: baseline; }
.ui-tg-commands dt { font-size: 13px; font-weight: 600; color: var(--ink-primary); }
.ui-tg-commands dd { margin: 0; font-size: 13px; color: var(--ink-secondary); }
.ui-tg-rights { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr)); gap: 12px 16px; margin: 0; }
.ui-tg-rights dt { display: flex; align-items: center; gap: 6px; font-size: 14px; font-weight: 600; color: var(--ink-primary); }
.ui-tg-rights dt .ui-icon { color: var(--brand-link); }
.ui-tg-rights dd { margin: 4px 0 0; font-size: 13px; line-height: 1.5; color: var(--ink-secondary); }
.ui-tg-rules { font-size: 13px; line-height: 1.5; color: var(--ink-muted); }
.ui-tg-rights-form { gap: 4px; }
.ui-tg-rights-form .ui-note { margin-top: 8px; }
@media (max-width: 899.98px) {
    .ui-tg-setup, .ui-tg-pair { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 420px) {
    .ui-tg-commands > div { grid-template-columns: minmax(0, 1fr); gap: 0; }
}
/* (end of: integrations, phase 9) */

/* ---- Guest reporters, ticket templates, push notifications (phase 9) -- */
/* Guest reporters: the limits card beside the states card (stacked under 1100px). */
.ui-guest-rules { display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px; min-width: 0; }
@media (min-width: 1100px) {
    .ui-guest-rules { grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: start; }
}
.ui-guest-limits dd.ui-guest-hint { margin-top: 2px; font-size: 12px; font-weight: 400; color: var(--ink-muted); }
@media (max-width: 599.98px) {
    .ui-guest-limits { grid-template-columns: minmax(0, 1fr); }
}
.ui-guest-foot-text { flex: 1 1 260px; min-width: 0; font-size: 13px; color: var(--ink-muted); }
.ui-guest-states { display: flex; flex-direction: column; gap: 10px; margin: 0; padding: 0; list-style: none; }
.ui-guest-states > li { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ui-guest-state-link {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    width: fit-content;
    max-width: 100%;
    min-height: 44px;
    padding-inline: 6px;
    border-radius: 10px;
    color: var(--ink-primary);
    text-decoration: none;
}
.ui-guest-state-link:hover { background: var(--bg-card-hover); color: var(--ink-primary); text-decoration: none; }
.ui-guest-state-link:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--brand-link); }
.ui-guest-state-link[aria-current="true"] { background: var(--brand-primary-tint); }
.ui-guest-state-count { font-size: 13px; font-weight: 600; color: var(--brand-link); }
.ui-guest-state-text { margin: 0; padding-inline-start: 6px; font-size: 13px; line-height: 1.45; color: var(--ink-secondary); }
.ui-guest-menu-form { display: block; margin: 0; }
.ui-guest-notes { margin-top: 16px; padding-top: 12px; border-top: 1px solid var(--border-light); }
.ui-guest-notes-title { margin: 0 0 4px; font-size: 13px; font-weight: 600; color: var(--ink-secondary); }
.ui-guest-notes p { margin: 0; white-space: pre-line; overflow-wrap: anywhere; color: var(--ink-primary); }
.ui-guest-form, .ui-template-form, .ui-push-form { margin: 0; }
:is(.ui-guest-form-actions, .ui-push-actions) { justify-content: flex-end; width: 100%; }

/* Ticket templates: the "possible duplicate" pill may carry a sentence - it wraps. */
.ui-template-dup { max-width: 100%; white-space: normal; overflow-wrap: anywhere; }
.ui-template-dup bdi { font-weight: 500; }

/* "How reporters see it": a phone-like frame per language with the row of one-tap chips. */
.ui-template-preview { min-width: 0; }
.ui-template-context { margin: 0; font-size: 13px; color: var(--ink-secondary); overflow-wrap: anywhere; }
.ui-template-context bdi { font-weight: 600; color: var(--ink-primary); }
.ui-template-phones { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr)); gap: 12px; min-width: 0; }
.ui-template-phones--stack { grid-template-columns: minmax(0, 1fr); }
.ui-template-phone-wrap { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.ui-template-phone-cap { margin: 0; font-size: 12px; font-weight: 600; color: var(--ink-muted); }
.ui-template-phone {
    display: flex;
    flex-direction: column;
    gap: 8px;
    min-width: 0;
    padding: 14px;
    border: 1px solid var(--border-strong);
    border-radius: 18px;
    background: var(--bg-page-subtle);
}
.ui-template-box { margin: 0; font-size: 12px; color: var(--ink-secondary); }
.ui-template-chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 0; padding: 0; list-style: none; }
.ui-template-chip {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    max-width: 100%;
    padding: 4px 12px;
    border: 1px solid var(--border-light);
    border-radius: 999px;
    background: var(--bg-card);
    color: var(--ink-primary);
    font-size: 13px;
    font-weight: 500;
    line-height: 1.4;
    overflow-wrap: anywhere;
}
.ui-template-chip--mine { padding: 3px 11px; border: 2px solid var(--brand-primary); background: var(--brand-primary-tint); color: var(--brand-link); font-weight: 700; }

/* New push notification: the recipient list (ticked boxes, built from the server's answer). */
.ui-push-people { min-width: 0; margin: 0; padding: 0; border: 0; }
.ui-push-people > legend { float: none; width: auto; margin: 0 0 6px; padding: 0; }
.ui-push-people-head { justify-content: space-between; margin-bottom: 8px; }
.ui-push-list {
    display: flex;
    flex-direction: column;
    max-height: 320px;
    overflow-y: auto;
    padding: 4px 12px;
    border: 1px solid var(--border-light);
    border-radius: 10px;
    background: var(--bg-card);
}
.ui-push-list:empty { display: none; }
.ui-push-list .ui-check-line { width: 100%; flex-wrap: wrap; }
.ui-push-phone { font-size: 12px; color: var(--ink-muted); }
[data-push-recipients][aria-busy="true"] .ui-push-list { opacity: .6; }
.ui-push-when { max-width: 320px; }
/* (end of: guests and templates, phase 9) */

/* ---- Team, roles & permissions, departments, professions (phase 9) ---- */
/* Lists: several short values in one cell (roles, campuses, managers), each on
   its own line; a quiet caption before a value ("Department:"). */
.ui-people-line { display: block; overflow-wrap: anywhere; }
.ui-people-line + .ui-people-line { margin-top: 2px; }
.ui-people-label { font-size: 12px; color: var(--ink-muted); }
@media (max-width: 899.98px) {
    .ui-table td .ui-people-line { display: inline; }
    .ui-table td .ui-people-line + .ui-people-line::before { content: " · "; color: var(--ink-muted); }
}
/* "12 of 180 rights" opens the role's rights: a link-looking button with a 44px hit area. */
.ui-people-link-btn { display: inline-block; padding-block: 12px; margin-block: -12px; font: inherit; font-weight: 600; text-align: start; }

/* Role form: name, "Start from an existing role", grouped rights, preview. */
.ui-people-name { width: 100%; max-width: 480px; }
.ui-people-template {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 8px 12px;
    padding-top: 16px;
    border-top: 1px solid var(--border-light);
}
.ui-people-template[hidden] { display: none; }
.ui-people-template .ui-field { flex: 1 1 240px; max-width: 360px; }
.ui-people-template .ui-select { width: 100%; }
.ui-people-template .ui-field-hint { flex: 1 0 100%; }
.ui-people-status:empty { display: none; }
.ui-people-status { color: var(--ink-secondary); font-weight: 600; }
/* In a vertical stack the toolbar's 240px flex basis would become a HEIGHT. */
.ui-people-search { max-width: 480px; flex: 0 0 auto; }
.ui-people-search[hidden] { display: none; }
.ui-people-none { margin: 0; color: var(--ink-secondary); }
.ui-people-groups {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr));
    gap: 16px;
    align-items: start;
}
.ui-people-group {
    min-width: 0;
    margin: 0;
    padding: 4px 14px 10px;
    border: 1px solid var(--border-light);
    border-radius: 12px;
    background: var(--bg-card);
}
.ui-people-group[hidden] { display: none; }
.ui-people-group-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0 12px;
    float: none;
    width: 100%;
    margin: 0;
    padding: 0;
    border-bottom: 1px solid var(--border-light);
    font-size: 15px;
    line-height: 1.3;
}
label.ui-people-group-name { flex: 1 1 auto; min-width: 0; font-weight: 600 !important; overflow-wrap: anywhere; }
.ui-people-group-count { flex: 0 0 auto; font-size: 12px; font-weight: 600; color: var(--ink-muted); }
.ui-people-rights { margin: 0; padding: 0; list-style: none; }
.ui-people-rights li[hidden] { display: none; }
label.ui-people-right { display: flex; align-items: flex-start; width: 100%; padding-block: 10px; }
label.ui-people-right input { flex: 0 0 auto; margin-top: 2px; }
.ui-people-right-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ui-people-code { font-size: 12px; color: var(--ink-muted); overflow-wrap: anywhere; }
.ui-people-preview { display: flex; flex-direction: column; gap: 10px; margin: 0; }
.ui-people-preview[hidden] { display: none; }
.ui-people-preview-row { display: grid; grid-template-columns: minmax(120px, 220px) 1fr; gap: 4px 16px; }
.ui-people-preview-row dt { margin: 0; font-weight: 600; color: var(--ink-primary); }
.ui-people-preview-row dd { margin: 0; color: var(--ink-secondary); overflow-wrap: anywhere; }
.ui-people-preview-empty { margin: 0; color: var(--ink-secondary); }
@media (max-width: 599.98px) {
    .ui-people-preview-row { grid-template-columns: 1fr; }
}
.ui-people-actions { justify-content: flex-end; }
/* (end of: people, phase 9) */

/* ---- Campuses & rooms explorer and its lists (redesign phase 9) ------- */
/* The tab strip across the Campuses & rooms pages: links styled as the ui-tabs,
   the page shown marked aria-current="page". The equipment lists add a second,
   smaller strip of link chips (types / categories). */
.ui-fac-tabs { min-width: 0; }
.ui-fac-tabs-list { list-style: none; }
.ui-fac-tabs-list > li { display: flex; flex: 0 0 auto; }
.ui-fac-tabs a.ui-tab, .ui-fac-tabs a.ui-tab:hover { text-decoration: none; }
.ui-fac-tabs a.ui-tab[aria-current="page"] { color: var(--ink-primary); border-bottom-color: var(--brand-primary); }
.ui-fac-sub-list { padding: 0; list-style: none; }
.ui-fac-sub-list > li { display: flex; }
.ui-fac-sub a.ui-chip, .ui-fac-sub a.ui-chip:hover { text-decoration: none; }
.ui-fac-sub a.ui-chip:focus-visible { box-shadow: 0 0 0 2px var(--brand-link); }
.ui-fac-sub a.ui-chip[aria-current="page"] { background: var(--brand-primary); border-color: var(--brand-primary); color: var(--on-brand); }

/* A row's counts ("3 buildings · 5 floors · 40 rooms"), a link beside a pill,
   the sentence inside a delete confirmation, quiet page text. */
.ui-fac-counts, .ui-tree-totals { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 6px; min-width: 0; }
.ui-fac-counts > span + span::before, .ui-tree-totals > span + span::before { content: "\00B7"; margin-inline-end: 6px; color: var(--ink-subtle); }
.ui-fac-action { margin-inline-start: 8px; font-size: 13px; }
.ui-fac-meta { font-size: 14px; color: var(--ink-muted); overflow-wrap: anywhere; }
.ui-fac-note { margin: 0 0 12px; font-size: 14px; line-height: 1.5; color: var(--ink-secondary); }
.ui-fac-text { margin: 0; font-size: 14px; line-height: 1.5; color: var(--ink-secondary); }
.ui-fac-subhead { margin: 0; font-size: 15px; font-weight: 600; line-height: 1.3; color: var(--ink-primary); }

/* The campus explorer: building -> floor -> rooms. Each head is one 44px toggle
   (aria-expanded) + its totals + its "More" menu; the body under it is hidden
   when closed. Without the script everything stays open. */
.ui-tree { margin: 0; padding: 0; list-style: none; min-width: 0; }
.ui-tree-node { min-width: 0; border-top: 1px solid var(--border-light); }
.ui-tree > .ui-tree-node:first-child { border-top: 0; }
.ui-tree-head { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px; min-width: 0; padding-block: 6px; padding-inline: 6px 8px; }
.ui-tree-toggle {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    flex: 1 1 260px;
    min-width: 0;
    min-height: 44px;
    margin: 0;
    padding: 0 10px;
    border: 0;
    border-radius: 8px;
    background: none;
    color: var(--ink-primary);
    font: inherit;
    text-align: start;
    cursor: pointer;
}
.ui-tree-toggle:hover { background: var(--bg-card-hover); }
.ui-tree-toggle:focus-visible { box-shadow: inset 0 0 0 2px var(--brand-link); }
.ui-tree-chevron { flex: 0 0 auto; color: var(--ink-muted); transition: transform 0.15s ease; }
.ui-tree-toggle[aria-expanded="false"] .ui-tree-chevron { transform: rotate(-90deg); }
[dir="rtl"] .ui-tree-toggle[aria-expanded="false"] .ui-tree-chevron { transform: rotate(90deg); }
.ui-tree-name { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; min-width: 0; }
.ui-tree-title { font-weight: 600; overflow-wrap: anywhere; }
.ui-tree-node--building > .ui-tree-head .ui-tree-title { font-size: 16px; }
.ui-tree-code { font-size: 12px; color: var(--ink-muted); }
.ui-tree-name .ui-pill { padding: 1px 8px; font-size: 11px; }
.ui-tree-totals { font-size: 13px; color: var(--ink-muted); }
.ui-tree-open { color: var(--ink-primary); font-weight: 600; }
.ui-tree-head .ui-rowmenu { margin-inline-start: auto; }
.ui-tree-body { min-width: 0; padding-block: 0 8px; padding-inline: 28px 12px; }
.ui-tree-body[hidden], [data-tree-all][hidden] { display: none !important; }
.ui-tree--floors { border: 1px solid var(--border-light); border-radius: 10px; background: var(--bg-card-subtle); }
.ui-tree-node--floor > .ui-tree-head { padding-block: 2px; }
.ui-tree-node--floor > .ui-tree-body { padding-inline: 12px; }
.ui-tree-rooms { border: 1px solid var(--border-light); border-radius: 10px; background: var(--bg-card); }
.ui-tree-empty { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; margin: 0; padding: 8px 12px 12px; font-size: 14px; color: var(--ink-muted); }
@media (max-width: 599.98px) {
    /* A phone: name and "More" on the first line, the totals under them. */
    .ui-tree-body { padding-inline: 8px 4px; }
    .ui-tree-node--floor > .ui-tree-body { padding-inline: 4px; }
    .ui-tree-toggle { flex-basis: 0; }
    .ui-tree-head .ui-rowmenu { order: 2; }
    .ui-tree-totals { order: 3; flex-basis: 100%; padding-inline-start: 36px; }
}
@media (prefers-reduced-motion: reduce) {
    .ui-tree-chevron { transition: none; }
}

/* The campus page's import & export tab: two small cards beside the import. */
.ui-fac-import { display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px; align-items: start; min-width: 0; }
.ui-fac-import-side { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
@media (min-width: 1100px) {
    .ui-fac-import { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
}
.ui-fac-import [hidden] { display: none !important; }
.ui-fac-sample { max-height: 320px; overflow-y: auto; border: 1px solid var(--border-light); border-radius: 10px; }
.ui-fac-errors { max-height: 180px; overflow-y: auto; }

/* Room QR codes: the label preview dialog. The label sits on the card colour
   with a frame; the image itself carries its own light background. */
[data-qr-part][hidden] { display: none !important; }
.ui-fac-qr-head { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.ui-fac-qr-name { margin: 0; font-size: 18px; font-weight: 600; line-height: 1.3; color: var(--ink-primary); overflow-wrap: anywhere; }
.ui-fac-qr-figure { display: flex; justify-content: center; margin: 0; padding: 12px; border: 1px solid var(--border-light); border-radius: 12px; background: var(--bg-card-subtle); }
.ui-fac-qr-figure img { display: block; width: 220px; max-width: 100%; height: auto; aspect-ratio: 1 / 1; border-radius: 6px; }
.ui-fac-qr-link { display: block; padding: 8px 10px; border: 1px solid var(--border-light); border-radius: 8px; background: var(--bg-card-subtle); font-size: 13px; color: var(--ink-primary); overflow-wrap: anywhere; text-align: start; }
/* (end of: campuses, phase 9) */

/* ---- Assets register (redesign phase 9) -------------------------------- */
/* The kinds of equipment as smaller chips (a register can hold twenty types). */
.ui-views--types .ui-chip { min-height: 40px; padding: 0 12px; font-size: 13px; }
@media (pointer: coarse) { .ui-views--types .ui-chip { min-height: 44px; } }
/* A name the console made up (the asset has none of its own yet) reads quieter. */
.ui-row-title.ui-asset-fallback { color: var(--ink-secondary); font-weight: 500; }
.ui-row-title.ui-asset-fallback:hover { color: var(--brand-link); }
/* Campus · building · floor · room: one line that wraps between its parts. */
.ui-asset-place { display: inline-flex; flex-wrap: wrap; align-items: baseline; gap: 0 6px; min-width: 0; overflow-wrap: anywhere; }
.ui-asset-place > [aria-hidden="true"] { color: var(--ink-muted); }
/* The asset page: its code under the title (read-only, left to right), quiet
   second lines inside a fact, the history numbers under the facts, the QR
   label at a size that still scans, the photo. */
.ui-asset-code {
    display: inline-flex;
    align-items: center;
    min-height: 28px;
    padding: 0 10px;
    border: 1px solid var(--border-strong);
    border-radius: 8px;
    background: var(--bg-card-subtle);
    color: var(--ink-primary);
    font-size: 13px;
    font-weight: 600;
}
.ui-asset-sub { display: block; margin-top: 2px; font-size: 12px; font-weight: 400; color: var(--ink-muted); overflow-wrap: anywhere; }
.ui-asset-figures { padding: 12px 0 0; border-bottom: 0; border-top: 1px solid var(--border-light); }
.ui-asset-notes-head { margin-top: 16px; }
.ui-asset-qr { display: flex; justify-content: center; margin: 0; }
.ui-asset-qr svg { display: block; width: 100%; max-width: 220px; height: auto; border-radius: 8px; }
.ui-asset-photo { display: block; max-width: 100%; height: auto; border-radius: 10px; }
/* (end of: assets, phase 9) */

/* ---- Quick periods (x-ui.period-chips, owner request 2026-09-24) ------- */
/* One row of one-click periods (Any time · Today · Last 2 days · This week ·
   This month · Custom range) above a list's status chips. The chips are the
   saved-view chips; "Custom range" is a <details> whose two date boxes and
   Apply sit under the row, full width, so a phone never scrolls sideways. */
.ui-period { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.ui-period-chips { align-items: center; }
.ui-period-caption { margin-inline-end: 4px; font-size: 13px; font-weight: 600; color: var(--ink-secondary); }
.ui-period-toggle { margin: 0; min-width: 0; }
.ui-period-toggle > summary { list-style: none; }
.ui-period-toggle > summary::-webkit-details-marker { display: none; }
.ui-period-toggle > summary::marker { content: ""; }
.ui-period-toggle > summary .ui-icon { transition: transform .15s ease; }
.ui-period-toggle[open] > summary .ui-icon { transform: rotate(180deg); }
.ui-period-toggle > summary[aria-current="true"] { background: var(--brand-primary); border-color: var(--brand-primary); color: var(--on-brand); }
.ui-period-custom {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 12px;
    margin: 0;
    padding: 12px;
    border: 1px solid var(--border-light);
    border-radius: 12px;
    background: var(--bg-card);
}
.ui-period-custom .ui-field { flex: 1 1 140px; max-width: 220px; }
.ui-period-custom .ui-input { width: 100%; min-width: 0; }
.ui-period-custom .ui-btn { flex: 0 0 auto; }
/* Closed "Custom range" hides the boxes; a browser without :has() keeps them showing. */
@supports selector(:has(*)) {
    .ui-period:not(:has(.ui-period-toggle[open])) .ui-period-custom { display: none; }
}
.ui-period-span,
.ui-period-note { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 0; font-size: 13px; line-height: 1.4; color: var(--ink-muted); }
.ui-period-note { color: var(--warning-text); }
@media (max-width: 420px) {
    .ui-period-custom .ui-field { max-width: none; }
    .ui-period-custom .ui-btn { flex: 1 1 100%; }
}
@media (prefers-reduced-motion: reduce) {
    .ui-period-toggle > summary .ui-icon { transition: none; }
}
/* "Download the reports for these dates" under a list's toolbar now shows for
   every chosen period: a 44px target on a touch screen. */
@media (pointer: coarse) {
    [data-range-reports] .ui-link { display: inline-flex; align-items: center; min-height: 44px; }
}
/* (end of: quick periods) */

/* ---- Page help (x-ui.page-help, owner request 2026-09-24) -------------- */
/* What the page is for, above every console page (the layout draws it, never
   a page): an info icon + one sentence always on screen, and "How to use this
   page" - a <details> that opens Who uses it / What you see / What you can do
   and the tip. Calm: an info tint, indigo-link text, no shadow. The toggle is
   a 44px target at the row's end; open, it takes the whole width so the panel
   is never squeezed. Hidden on paper. */
.ui-help {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0 16px;
    min-width: 0;
    margin: 0 0 16px;
    padding-block: 4px;
    padding-inline: 14px 6px;
    border: 1px solid var(--info-border);
    border-radius: 12px;
    background: var(--info-bg);
    color: var(--brand-link);
}
.ui-help-lead {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    flex: 1 1 320px;
    min-width: 0;
    padding-block: 8px;
}
.ui-help-icon { margin-top: 2px; color: var(--brand-link); }
.ui-help-summary {
    margin: 0;
    min-width: 0;
    font-size: 14px;
    font-weight: 600;
    line-height: 1.5;
    color: var(--brand-link);
    overflow-wrap: anywhere;
}
.ui-help-more { flex: 0 1 auto; min-width: 0; margin: 0; }
.ui-help-more[open] { flex-basis: 100%; }
.ui-help-toggle {
    display: flex;
    align-items: center;
    gap: 6px;
    width: fit-content;
    max-width: 100%;
    min-height: 44px;
    padding: 0 10px;
    border-radius: 10px;
    color: var(--brand-link);
    font-size: 13px;
    font-weight: 600;
    line-height: 1.3;
    text-decoration: underline;
    text-underline-offset: 2px;
    cursor: pointer;
    list-style: none;
    user-select: none;
}
.ui-help-toggle::-webkit-details-marker { display: none; }
.ui-help-toggle::marker { content: ""; }
.ui-help-toggle:hover { background: var(--brand-primary-tint); color: var(--brand-link-hover); text-decoration-color: var(--brand-accent); }
.ui-help-toggle:focus-visible { outline: 2px solid var(--brand-accent); outline-offset: 2px; box-shadow: 0 0 0 2px var(--brand-link); }
.ui-help-toggle .ui-icon { transition: transform .15s ease; }
.ui-help-more[open] > .ui-help-toggle { margin-inline-start: auto; }
.ui-help-more[open] > .ui-help-toggle .ui-icon { transform: rotate(180deg); }
.ui-help-panel {
    margin: 0 0 10px;
    margin-inline-end: 8px;
    padding: 14px 16px;
    border: 1px solid var(--border-light);
    border-radius: 10px;
    background: var(--bg-card);
    color: var(--ink-primary);
    font-size: 14px;
    line-height: 1.55;
}
.ui-help-facts {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr));
    gap: 14px 24px;
    margin: 0;
}
.ui-help-fact { min-width: 0; }
.ui-help-facts dt { margin: 0 0 4px; font-size: 12px; font-weight: 700; color: var(--ink-muted); }
.ui-help-facts dd { margin: 0; font-size: 14px; line-height: 1.55; color: var(--ink-primary); overflow-wrap: anywhere; }
.ui-help-actions { margin: 0; padding-inline-start: 18px; }
.ui-help-actions li + li { margin-top: 4px; }
.ui-help-tip {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    margin: 14px 0 0;
    padding-top: 12px;
    border-top: 1px solid var(--border-light);
    font-size: 14px;
    line-height: 1.55;
    color: var(--ink-secondary);
    overflow-wrap: anywhere;
}
.ui-help-tip .ui-icon { margin-top: 3px; color: var(--warning-icon); }
@media (max-width: 420px) {
    .ui-help { padding-inline: 12px 4px; }
    .ui-help-panel { margin-inline-end: 4px; padding: 12px; }
}
@media (prefers-reduced-motion: reduce) {
    .ui-help-toggle .ui-icon { transition: none; }
}
@media print {
    .ui-help { display: none !important; }
}
/* (end of: page help) */

/* ---- Checklist rows: a long answer wraps (owner request 2026-09-25) ----
   "Not answered · closed with the ticket" is far longer than "○ Pending": a
   badge that never wraps ran past a 390 px screen and pushed the delete
   button out of reach. The words wrap inside the row; the button never
   shrinks; on a phone the answer drops under the question when it must. */
.tkt-chk-row .tkt-chk-main { min-width: 0; }
.tkt-chk-row .tkt-chk-main .ticket-checklist-text { overflow-wrap: anywhere; }
.tkt-chk-row .tkt-chk-end { flex: 0 1 auto; min-width: 0; max-width: 60%; justify-content: flex-end; }
.tkt-chk-row .tkt-chk-end .delete-ticket-checklist-btn { flex-shrink: 0; }
.tkt-chk-badge,
.tkt-chk-row .tkt-chk-badge {
    white-space: normal;
    overflow-wrap: anywhere;
    text-align: start;
    line-height: 1.35;
    max-width: 100%;
}
@media (max-width: 480px) {
    .tkt-chk-row { flex-wrap: wrap; }
    .tkt-chk-row .tkt-chk-end { max-width: 100%; margin-inline-start: auto; }
}
/* (end of: checklist rows) */

/* ---- Timeline (Gantt) report (owner request 2026-09-25) ---------------- */
/* admin/reports/gantt.blade.php + partials/gantt-*.blade.php. One card per
   campus holding a chart that scrolls sideways INSIDE its own box (never the
   page): a sticky label column, the time scale, a background layer (column
   lines, weekend and today columns, the today line) and one 44px row per item.
   Bars, visit blocks and marks are placed by time with two custom properties
   the server writes - --s (start, % of the window) and --w (width, %) -
   through inset-inline-start / inline-size, so on an Arabic or Urdu page time
   runs from right to left by itself. A bar's colour is its StatusTone tone
   (--tone); "waiting" (neutral) is also hatched so it never relies on colour
   alone. The track's least width is --cols x --col-min, set on .ui-gantt by
   the page for the column unit (2 hours 36px, day 24px, week 48px, month
   60px: a month of days fits a 1280px screen), so a 390px phone scrolls the
   chart and not the page. */
.ui-gantt {
    --gantt-label: 240px;
    --gantt-row: 44px;
    --cols: 30;
    --col-min: 24px;
    min-width: 0;
}
.ui-gantt-scroll {
    overflow-x: auto;
    overscroll-behavior-inline: contain;
    container-type: inline-size;
    border-end-start-radius: var(--radius-md);
    border-end-end-radius: var(--radius-md);
}
.ui-gantt-scroll:focus-visible { outline: 2px solid var(--brand-accent); outline-offset: -3px; }
.ui-gantt-grid {
    position: relative;
    isolation: isolate;
    /* An open end that reaches the window's end is cut at the edge instead of
       widening the scroll (clip, unlike hidden, keeps the labels sticky). */
    overflow-x: clip;
    min-inline-size: calc(var(--gantt-label) + var(--cols) * var(--col-min));
    font-size: 13px;
    color: var(--ink-primary);
}
.ui-gantt-rows { margin: 0; padding: 0; list-style: none; }
.ui-gantt-row {
    display: grid;
    grid-template-columns: var(--gantt-label) minmax(0, 1fr);
    min-block-size: var(--gantt-row);
    margin: 0;
    border-block-end: 1px solid var(--border-subtle);
}
.ui-gantt-label {
    position: sticky;
    inset-inline-start: 0;
    z-index: 3;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 2px;
    min-inline-size: 0;
    margin: 0;
    padding-block: 4px;
    padding-inline: 14px 10px;
    border-inline-end: 1px solid var(--border-light);
    background: var(--bg-card);
    color: var(--ink-primary);
}
.ui-gantt-track { position: relative; min-inline-size: 0; }

/* The time scale */
.ui-gantt-row--scale { min-block-size: 46px; border-block-end-color: var(--border-light); }
.ui-gantt-row--scale > .ui-gantt-label,
.ui-gantt-row--scale > .ui-gantt-track { background: var(--bg-card-subtle); }
.ui-gantt-heading { font-size: 13px; font-weight: 600; line-height: 1.3; color: var(--ink-secondary); }
.ui-gantt-col {
    position: absolute;
    inset-block: 0;
    inset-inline-start: var(--s);
    inline-size: var(--w);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1px;
    border-inline-start: 1px solid var(--border-subtle);
    overflow: hidden;
    white-space: nowrap;
    line-height: 1.2;
    text-align: center;
}
.ui-gantt-col-label { font-size: 12px; font-weight: 600; color: var(--ink-secondary); }
.ui-gantt-col-sub { font-size: 11px; color: var(--ink-muted); }
.ui-gantt-col.is-weekend { background: var(--neutral-bg); }
.ui-gantt-col.is-today { background: var(--brand-accent-tint); }
.ui-gantt-col.is-today .ui-gantt-col-label { padding-inline: 5px; border-radius: 999px; background: var(--brand-link); color: var(--ink-inverse); }
/* Two-hour columns: the day's name under 00:00 runs on over the next columns. */
.ui-gantt[data-unit="hour"] .ui-gantt-col { align-items: flex-start; padding-inline-start: 4px; overflow: visible; }

/* The background layer: column lines, weekend and today columns, the today line */
.ui-gantt-body { position: relative; }
.ui-gantt-layer {
    position: absolute;
    inset-block: 0;
    inset-inline-start: var(--gantt-label);
    inset-inline-end: 0;
    pointer-events: none;
}
.ui-gantt-shade {
    position: absolute;
    inset-block: 0;
    inset-inline-start: var(--s);
    inline-size: var(--w);
    border-inline-start: 1px solid var(--border-subtle);
}
.ui-gantt-shade.is-weekend { background: var(--neutral-bg); }
.ui-gantt-shade.is-today { background: var(--brand-accent-tint); }
.ui-gantt-now {
    position: absolute;
    z-index: 2;
    inset-block: 0;
    inset-inline-start: var(--s);
    margin-inline-start: -1px;
    border-inline-start: 2px solid var(--brand-link);
}
.ui-gantt-row--now { min-block-size: 24px; }
.ui-gantt-flag {
    position: absolute;
    z-index: 2;
    inset-block-start: 3px;
    inset-inline-start: var(--s);
    margin-inline-start: -1px;
    padding-inline: 6px;
    border-radius: 4px;
    border-start-start-radius: 0;
    background: var(--brand-link);
    color: var(--ink-inverse);
    font-size: 11px;
    font-weight: 600;
    line-height: 18px;
    white-space: nowrap;
}
/* Near the end of the window the flag hangs back from the line. */
.ui-gantt-flag.is-end {
    inset-inline-start: auto;
    inset-inline-end: calc(100% - var(--s));
    margin-inline: 0 -1px;
    border-start-start-radius: 4px;
    border-start-end-radius: 0;
}

/* A group of rows (type, building or department) */
.ui-gantt-row--group { min-block-size: 36px; border-block-start: 1px solid var(--border-light); }
.ui-gantt-row--group > .ui-gantt-label {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    background: var(--bg-card-subtle);
    font-size: 13px;
    font-weight: 700;
    line-height: 1.3;
    color: var(--ink-secondary);
}
.ui-gantt-group-count { flex: 0 0 auto; font-weight: 600; color: var(--ink-muted); }

/* A row's label: number + title, then state + place · department · people */
.ui-gantt-line { display: flex; align-items: center; gap: 6px; min-inline-size: 0; }
.ui-gantt-code { flex: 0 0 auto; font-size: 11px; color: var(--ink-muted); }
.ui-gantt-title,
.ui-gantt-sub {
    min-inline-size: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.ui-gantt-title { font-size: 13px; font-weight: 600; line-height: 1.35; color: var(--ink-primary); text-decoration: none; }
a.ui-gantt-title:hover { color: var(--brand-link); text-decoration: underline; text-underline-offset: 2px; }
a.ui-gantt-title:focus-visible { outline: 2px solid var(--brand-accent); outline-offset: 1px; box-shadow: 0 0 0 2px var(--brand-link); }
.ui-gantt-sub { font-size: 12px; line-height: 1.35; color: var(--ink-muted); }
.ui-gantt-line .ui-pill { flex: 0 0 auto; gap: 3px; padding: 0 6px; font-size: 11px; }
.ui-gantt-late { flex: 0 0 auto; font-size: 11px; font-weight: 700; color: var(--danger-text); }
/* Where an item came from / what it led to (an escalation: its visit, its ticket),
   under the row's label and in the list's title cell. */
.ui-gantt-links { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 10px; min-inline-size: 0; }
.ui-gantt-link { font-size: 12px; font-weight: 600; line-height: 1.35; overflow-wrap: anywhere; color: var(--ink-muted); }
a.ui-gantt-link { color: var(--brand-link); text-decoration: underline; text-underline-offset: 2px; }
a.ui-gantt-link:hover { color: var(--brand-link-hover); text-decoration-color: var(--brand-accent); }
a.ui-gantt-link:focus-visible { outline: 2px solid var(--brand-accent); outline-offset: 1px; box-shadow: 0 0 0 2px var(--brand-link); }
.ui-td-primary > .ui-gantt-links { margin-block-start: 4px; }

/* Tones: the StatusTone colour of a bar, a block or a mark */
.ui-gantt-tone--neutral { --tone: var(--ink-subtle); }
.ui-gantt-tone--info    { --tone: var(--info-accent); }
.ui-gantt-tone--warning { --tone: var(--warning-icon); }
.ui-gantt-tone--success { --tone: var(--success-accent); }
.ui-gantt-tone--danger  { --tone: var(--danger-accent); }

/* Bars (a ticket's phases, a whole span), visit blocks, the "really ran" line */
.ui-gantt-bar {
    position: absolute;
    z-index: 1;
    box-sizing: border-box;
    inset-block-start: calc(50% - 7px);
    inset-inline-start: var(--s);
    inline-size: var(--w);
    min-inline-size: 4px;
    block-size: 14px;
    border-radius: 4px;
    background: var(--tone, var(--ink-subtle));
}
.ui-gantt-bar.ui-gantt-tone--neutral {
    border: 1px solid var(--tone);
    background: repeating-linear-gradient(-45deg, var(--tone) 0 2px, transparent 2px 5px);
}
.ui-gantt-bar--visit {
    inset-block-start: calc(50% - 6px);
    inline-size: calc(var(--w) - 2px);
    block-size: 12px;
    border-radius: 3px;
}
/* A late visit (red) is also struck through with a light slash, so it never
   differs from a done one (green) by colour alone. */
.ui-gantt-bar--visit.ui-gantt-tone--danger {
    background: linear-gradient(135deg,
        var(--tone) 0 calc(50% - 1.5px),
        var(--bg-card) calc(50% - 1.5px) calc(50% + 1.5px),
        var(--tone) calc(50% + 1.5px) 100%);
}
.ui-gantt-bar.ui-gantt-bar--actual {
    inset-block-start: calc(50% + 9px);
    block-size: 4px;
    border: 0;
    border-radius: 2px;
    background: var(--tone, var(--ink-subtle));
}
.ui-gantt-bar.is-cut-start { border-start-start-radius: 0; border-end-start-radius: 0; }
/* Still open: the bar runs on to today and ends in an arrow. */
.ui-gantt-bar.is-open-end { border-start-end-radius: 0; border-end-end-radius: 0; }
.ui-gantt-bar.is-open-end::after {
    content: "";
    position: absolute;
    inset-block-start: 50%;
    inset-inline-start: 100%;
    transform: translateY(-50%);
    border-block: 7px solid transparent;
    border-inline-start: 7px solid var(--tone, var(--ink-subtle));
}
a.ui-gantt-bar { cursor: pointer; }
/* A bar that is a link is a 44px target without making the row taller. */
a.ui-gantt-bar::before { content: ""; position: absolute; inset-block: -15px; inset-inline: 0; }
a.ui-gantt-bar:hover { box-shadow: 0 0 0 2px var(--brand-link); }
a.ui-gantt-bar:focus-visible { z-index: 2; outline: 2px solid var(--brand-accent); outline-offset: 2px; box-shadow: 0 0 0 2px var(--brand-link); }

/* A date to watch: a small diamond on the row */
.ui-gantt-mark {
    position: absolute;
    z-index: 2;
    box-sizing: border-box;
    inset-block-start: calc(50% - 6px);
    inset-inline-start: var(--s);
    inline-size: 12px;
    block-size: 12px;
    margin-inline-start: -6px;
    border: 2px solid var(--bg-card);
    border-radius: 2px;
    background: var(--tone, var(--ink-subtle));
    transform: rotate(45deg);
}

/* "N more rows are not drawn here" - kept inside the visible part of the scroller */
.ui-gantt-note {
    position: sticky;
    inset-inline-start: 0;
    z-index: 3;
    box-sizing: border-box;
    inline-size: 100%;
    max-inline-size: 100cqi;
    margin: 0;
    padding: 10px 14px;
    border-block-end: 1px solid var(--border-subtle);
    background: var(--bg-card);
    font-size: 13px;
    line-height: 1.45;
    color: var(--ink-muted);
}
.ui-gantt-empty { margin: 0; padding: 16px 18px; font-size: 14px; line-height: 1.5; color: var(--ink-muted); }

/* How to read the chart (a <details> with the ui-filter-more toggle) */
.ui-gantt-legend { align-self: flex-start; max-inline-size: 100%; }
.ui-gantt-legend[open] { align-self: stretch; }
.ui-gantt-legend-list {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr));
    gap: 10px 20px;
    margin: 0;
    padding: 12px 0 0;
    list-style: none;
}
.ui-gantt-legend-list li { display: flex; align-items: center; gap: 10px; min-inline-size: 0; font-size: 13px; line-height: 1.4; color: var(--ink-secondary); }
.ui-gantt-key { --s: 0%; --w: 100%; position: relative; flex: 0 0 auto; inline-size: 44px; block-size: 20px; }
.ui-gantt-key--open { --w: 70%; }
.ui-gantt-key--point { --s: 50%; }
/* One visit block, about as wide as a day's column. */
.ui-gantt-key--visit { --s: 25%; --w: 50%; }
.ui-gantt-key .ui-gantt-bar--actual { inset-block-start: calc(50% - 2px); }
.ui-gantt-key--weekend { border: 1px solid var(--border-light); border-radius: 3px; background: var(--neutral-bg); }
/* The visits' own key: a caption, then one block per state. */
.ui-gantt-legend-list > .ui-gantt-legend-group { grid-column: 1 / -1; flex-direction: column; align-items: flex-start; gap: 8px; }
.ui-gantt-legend-caption { font-weight: 600; color: var(--ink-secondary); }
.ui-gantt-legend-states { display: flex; flex-wrap: wrap; gap: 8px 20px; margin: 0; padding: 0; list-style: none; }

/* Chart options: kinds of item as tick chips, then the selects and Apply */
.ui-gantt-options { display: flex; flex-direction: column; gap: 14px; margin: 0; }
.ui-gantt-layers { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; min-inline-size: 0; margin: 0; padding: 0; border: 0; }
.ui-gantt-layers > legend {
    float: none;
    inline-size: 100%;
    margin: 0 0 2px;
    padding: 0;
    font-size: 13px;
    font-weight: 600;
    line-height: 1.4;
    color: var(--ink-secondary);
}
/* The older stylesheet turns every <label> into a 12px capitalised caption (!important). */
label.ui-gantt-toggle {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-block-size: 44px;
    margin: 0 !important;
    padding-inline: 12px 16px;
    border: 1px solid var(--border-strong);
    border-radius: 999px;
    background: var(--bg-card);
    color: var(--ink-secondary) !important;
    font-size: 14px !important;
    font-weight: 600 !important;
    letter-spacing: normal !important;
    text-transform: none !important;
    cursor: pointer;
}
label.ui-gantt-toggle:hover { background: var(--bg-card-hover); }
label.ui-gantt-toggle:has(input:checked) { border-color: var(--brand-primary-border); background: var(--brand-primary-tint); color: var(--brand-link) !important; }
label.ui-gantt-toggle:focus-within { box-shadow: 0 0 0 2px var(--brand-link); }
.ui-gantt-toggle input { inline-size: 18px; block-size: 18px; margin: 0; accent-color: var(--brand-primary); cursor: pointer; }
[data-theme="dark"] .ui-gantt-toggle input { color-scheme: dark; }
.ui-gantt-fields { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px; }
.ui-gantt-fields .ui-field { flex: 1 1 180px; max-inline-size: 260px; }
.ui-gantt-fields .ui-select { inline-size: 100%; }
.ui-gantt-fields .ui-btn { flex: 0 0 auto; }

/* Campus by campus, and the list view */
.ui-gantt-summary .ui-gantt-total td,
.ui-gantt-summary .ui-gantt-total th { font-weight: 700; background: var(--bg-card-subtle); }
.ui-gantt-list-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin: 0;
    padding: 12px 18px;
    border-block: 1px solid var(--border-light);
    background: var(--bg-card-subtle);
    font-size: 14px;
    font-weight: 700;
    line-height: 1.3;
    color: var(--ink-secondary);
}
.ui-gantt-list > .ui-gantt-list-head:first-child { border-block-start: 0; }
.ui-gantt-list-note { margin: 0; padding: 10px 18px; border-block-start: 1px solid var(--border-light); font-size: 13px; line-height: 1.45; color: var(--ink-muted); }
.ui-gantt-progress { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 2px 8px; }
.ui-gantt-progress .ui-bar { inline-size: 48px; }
/* A date breaks between its day and its time, never inside either. */
.ui-gantt-when > span { white-space: nowrap; }
/* The list's title keeps a readable width and wraps a long word; the other
   columns are a little tighter than a plain list (ten of them share the rest),
   their headings and a long status wrap, so a 1280px screen needs no sideways
   scroll. The campus table's headings wrap too (Arabic and Urdu run longer). */
.ui-gantt-list-title { overflow-wrap: anywhere; }
@media (min-width: 900px) {
    .ui-gantt-list .ui-table { font-size: 13px; }
    .ui-gantt-list .ui-table th,
    .ui-gantt-list .ui-table td { padding-inline: 6px; }
    .ui-gantt-list .ui-table th:first-child,
    .ui-gantt-list .ui-table td:first-child { padding-inline-start: 16px; }
    .ui-gantt-list .ui-table th,
    .ui-gantt-summary .ui-table th { white-space: normal; }
    .ui-gantt-list .ui-table td .ui-pill { white-space: normal; border-radius: 10px; }
    .ui-gantt-list .ui-table td.ui-gantt-list-title { min-inline-size: 14rem; }
    .ui-gantt-list .ui-table td.ui-gantt-list-place { min-inline-size: 6rem; }
    .ui-gantt-list .ui-table td .mono { font-size: 12px; }
}

@media (max-width: 600px) {
    .ui-gantt { --gantt-label: 150px; }
    .ui-gantt-row > .ui-gantt-label { padding-inline: 10px 8px; }
    /* The number on its own line, so the title has the whole label to itself. */
    .ui-gantt-line--head { flex-wrap: wrap; row-gap: 0; }
    .ui-gantt-line--head > .ui-gantt-code { flex: 0 0 100%; }
    .ui-gantt-fields .ui-field { max-inline-size: none; }
    .ui-gantt-fields .ui-btn { flex: 1 1 100%; }
}
@media print {
    .ui-gantt-scroll { overflow: visible; }
}

/* ---- Custom Gantts (owner request 2026-09-25) --------------------------- */
/* admin/reports/custom-gantt/*.blade.php. A custom Gantt is drawn by the
   Timeline's own chart and list (above); it adds:
   - the PLANNED stretch of a row (GanttGrid::PLANNED): an outlined, dashed
     bar in the upper part of the row, so the REAL bar of the same ticket or
     plan stays readable under it. Outline against solid, never colour alone;
     a row whose only bar is its plan (a removed item) has it in the middle;
   - the Edit / Remove menu at the end of a row's label (rows the viewer may
     change only);
   - the wizard (owner request 2026-09-26, decision CGM-6): its steps
     indicator, the Back / Next bar, the Events step's four ways to add, the
     event form's out source choice (one box shown per choice, with :has()),
     the searches whose lines each have their own "Add", and the "Who can see
     it" lists of people and roles. 44px targets, logical sides only, no
     colour without words. */
.ui-gantt-bar.ui-gantt-bar--planned {
    z-index: 0;
    inset-block-start: calc(50% - 15px);
    block-size: 10px;
    border: 2px dashed var(--brand-link);
    border-radius: 3px;
    background: var(--brand-primary-tint);
}
/* A row with a plan has two lanes: the plan above, the real bars and visit
   blocks a little lower and slimmer, so neither touches the row's edge. */
.ui-gantt-track:has(> .ui-gantt-bar--planned) > .ui-gantt-bar:not(.ui-gantt-bar--planned):not(.ui-gantt-bar--actual) {
    inset-block-start: calc(50% - 1px);
    block-size: 12px;
}
.ui-gantt-track:not(:has(.ui-gantt-bar:not(.ui-gantt-bar--planned))) > .ui-gantt-bar--planned {
    inset-block-start: calc(50% - 7px);
    block-size: 14px;
}
.ui-gantt-key .ui-gantt-bar.ui-gantt-bar--planned { inset-block-start: calc(50% - 6px); block-size: 12px; }

.ui-gantt-row > .ui-gantt-label.ui-gantt-label--tools { padding-inline-end: 50px; }
/* Centred by its own 44px height, never by a transform: a transform would make
   this box the frame of the menu's position:fixed panel, which then opened
   off its button and shut at once (review CG-UI-1). */
.ui-gantt-label > .ui-cg-rowtools {
    position: absolute;
    inset-block-start: calc(50% - 22px);
    inset-inline-end: 3px;
}
/* Each sticky label is a layer of its own, so the rows after an open menu
   would cover its panel and take the click meant for "Edit row": while a
   row's menu is open, that row (and its chart) is drawn above the rest. */
.ui-gantt-row > .ui-gantt-label:has(.ui-rowmenu-btn[aria-expanded="true"]) { z-index: 4; }
.ui-gantt-grid:has(.ui-rowmenu-btn[aria-expanded="true"]) { z-index: 1; }

/* The page: the Gantt's description and who made it, under its name */
.ui-cg-desc { flex: 1 0 100%; margin: 0; font-size: 14px; line-height: 1.5; color: var(--ink-secondary); white-space: pre-line; overflow-wrap: anywhere; }
.ui-cg-byline { font-size: 13px; color: var(--ink-muted); }
.ui-cg-period-line { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px; margin: -8px 0 0; font-size: 13px; color: var(--ink-muted); }
.ui-cg-period-line .ui-link { display: inline-flex; align-items: center; min-block-size: 44px; }
/* The options: the two views, the real-Timeline switch, then the selects */
.ui-cg-switches { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 24px; }
.ui-cg-switch { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; min-inline-size: 0; }
.ui-cg-switch-caption { font-size: 13px; font-weight: 600; color: var(--ink-secondary); }
.ui-cg-real-note { margin: 0; font-size: 13px; line-height: 1.45; color: var(--ink-muted); }
/* Between the Gantt's own rows and the campus's real Timeline */
.ui-cg-divider {
    display: flex;
    align-items: center;
    gap: 12px;
    margin: 8px 0 0;
    font-size: 15px;
    font-weight: 700;
    line-height: 1.35;
    color: var(--ink-secondary);
}
.ui-cg-divider::after { content: ""; flex: 1 1 24px; border-block-start: 1px dashed var(--border-strong); }

/* The wizard's steps (partials/steps): the plan form's .ui-steps pills; the
   step on screen is filled (aria-current="step"), a step not reachable yet is
   plain and muted, a step done carries a tick. */
.ui-cg-steps .ui-cg-step {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-height: 44px;
    padding-block: 0;
    padding-inline: 8px 14px;
    border: 1px solid var(--border-light);
    border-radius: 999px;
    background: var(--bg-card);
    color: var(--ink-muted);
    font-size: 14px;
    font-weight: 600;
}
/* Filled like every other brand-filled control: its text in --on-brand (white in both themes -
   the dark theme's --bg-card on --brand-primary read 2.8:1; review CGW-UI-1). */
.ui-cg-steps .ui-cg-step.is-current { border-color: var(--brand-primary); background: var(--brand-primary); color: var(--on-brand); }
.ui-cg-steps .ui-cg-step.is-current .ui-step-num { background: var(--on-brand); color: var(--brand-primary); }
.ui-cg-steps a.is-done .ui-step-num { background: var(--success-bg); color: var(--success-text); }
/* Back / Next (and Finish): at the end of the page, the forward button last. */
.ui-cg-wizard-actions { justify-content: flex-end; flex-wrap: wrap; gap: 10px; }
.ui-cg-wizard-actions .ui-btn { min-block-size: 44px; }
/* Step 2: the ways to add - three large links, then the less used fourth. */
.ui-cg-ways { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr)); gap: 12px; }
.ui-cg-way {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    min-block-size: 64px;
    padding: 14px;
    border: 1px solid var(--border-light);
    border-radius: 12px;
    background: var(--bg-card-subtle);
    color: var(--ink-primary);
    text-decoration: none;
}
.ui-cg-way:hover { border-color: var(--brand-primary-border); background: var(--brand-primary-tint); color: var(--ink-primary); text-decoration: none; }
.ui-cg-way:focus-visible { outline: 2px solid var(--brand-accent); outline-offset: 2px; }
.ui-cg-way > .ui-icon { flex: 0 0 auto; margin-block-start: 2px; color: var(--brand-link); }
.ui-cg-way-text { display: flex; flex-direction: column; gap: 4px; min-inline-size: 0; }
.ui-cg-way-title { font-size: 15px; font-weight: 700; line-height: 1.35; }
.ui-cg-way-hint { font-size: 13px; line-height: 1.45; color: var(--ink-secondary); }
.ui-cg-way-more { margin: 10px 0 0; font-size: 14px; }
.ui-cg-way-more .ui-link, .ui-link.ui-cg-continue { display: inline-flex; align-items: center; min-block-size: 44px; }
.ui-cg-event-actions { flex-wrap: wrap; gap: 6px; }
/* The event form: a linked event says what it shows; out source - one box per choice. */
.ui-cg-linked { margin: 0; padding: 10px 12px; border: 1px solid var(--border-light); border-radius: 10px; background: var(--bg-card-subtle); font-size: 14px; line-height: 1.45; color: var(--ink-primary); overflow-wrap: anywhere; }
.ui-cg-linked-caption { font-weight: 600; color: var(--ink-secondary); }
.ui-cg-dates { grid-template-columns: repeat(auto-fit, minmax(min(100%, 180px), 1fr)); }
.ui-cg-outsource { display: flex; flex-direction: column; gap: 10px; min-inline-size: 0; margin: 0; padding: 0; border: 0; }
.ui-cg-outsource > legend { margin-block-end: 6px; padding: 0; float: none; inline-size: auto; }
.ui-cg-outsource-choices { display: flex; flex-wrap: wrap; gap: 8px; }
.ui-cg-outsource .ui-select { inline-size: 100%; }
.ui-cg-outsource:has(input[data-cg-outsource-type][value="none"]:checked) [data-cg-outsource-box],
.ui-cg-outsource:has(input[data-cg-outsource-type][value="contractor"]:checked) [data-cg-outsource-box="company"],
.ui-cg-outsource:has(input[data-cg-outsource-type][value="company"]:checked) [data-cg-outsource-box="contractor"] { display: none; }
/* The searches (event-search): "Added so far", the lines, each with its own "Add". */
.ui-cg-so-far { margin: 0; padding: 10px 14px; border: 1px solid var(--border-light); border-radius: 10px; background: var(--bg-card-subtle); font-size: 14px; font-weight: 600; color: var(--ink-secondary); }
.ui-cg-search-period { padding-block: 12px 0; padding-inline: 16px; }
.ui-cg-search-count, .ui-cg-add-status { margin: 0; padding-block: 8px; padding-inline: 16px; font-size: 13px; color: var(--ink-muted); }
/* A live region stays in the page while empty (only its space folds), so its first message is
   announced (review CGW-A11Y-1) - never display: none on it. */
.ui-cg-add-status:empty { padding-block: 0; }
.ui-cg-results { margin: 0; padding: 0; list-style: none; border-block-start: 1px solid var(--border-subtle); }
.ui-cg-result {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 8px 14px;
    min-block-size: 56px;
    padding-block: 10px;
    padding-inline: 16px;
    border-block-end: 1px solid var(--border-subtle);
}
.ui-cg-result[data-cg-on-gantt] { background: var(--bg-card-subtle); }
.ui-cg-result-text { display: flex; flex: 1 1 260px; flex-direction: column; gap: 4px; min-inline-size: 0; }
.ui-cg-result-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 8px; min-inline-size: 0; }
.ui-cg-result-code { font-size: 13px; color: var(--ink-secondary); unicode-bidi: isolate; }
.ui-cg-result-title { font-size: 14px; font-weight: 600; color: var(--ink-primary); overflow-wrap: anywhere; }
.ui-cg-result-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; font-size: 12px; color: var(--ink-muted); }
.ui-cg-result-meta .ui-pill { padding: 1px 8px; font-size: 11px; }
.ui-cg-result-act { flex: 0 0 auto; }
.ui-cg-add-line { margin: 0; }
.ui-cg-add-line .ui-btn { min-block-size: 44px; }
.ui-cg-added { display: inline-flex; align-items: center; gap: 6px; min-block-size: 44px; padding-inline: 10px; font-size: 13px; font-weight: 700; color: var(--success-text); }
.ui-cg-added:focus-visible { outline: 2px solid var(--brand-accent); outline-offset: 2px; border-radius: 8px; }
.ui-cg-search-pages { padding-block: 10px 14px; padding-inline: 16px; gap: 8px; }
.ui-cg-search-pages .ui-btn { min-block-size: 44px; }
/* Step 3: the people (a search box narrows them) and the roles, one 44px line each. */
/* Its own height, never the column's share (a .ui-search grows in a row). */
.ui-cg-people-search { flex: 0 0 auto; max-inline-size: none; }
.ui-cg-people-search[hidden] { display: none; }
.ui-cg-pick-status { margin: 0; font-size: 12px; color: var(--ink-muted); }
.ui-cg-pick-status:empty { min-block-size: 0; }
.ui-cg-pick-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr));
    gap: 6px;
    max-block-size: 420px;
    margin: 0;
    padding: 0;
    overflow-y: auto;
    border: 0;
}
.ui-cg-pick-line {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    min-block-size: 44px;
    margin: 0;
    padding-block: 8px;
    padding-inline: 10px;
    border: 1px solid var(--border-light);
    border-radius: 10px;
    cursor: pointer;
}
.ui-cg-pick-line[hidden] { display: none; }
/* The older stylesheet turns every <label> into a bold capitalised caption (with
   !important); a line of the list takes its own type back, as the other
   building-block labels do ("Fields inside the building blocks"). */
label.ui-cg-pick-line {
    margin-bottom: 0 !important;
    font-size: 14px !important;
    font-weight: 400 !important;
    letter-spacing: normal !important;
    text-transform: none !important;
    color: var(--ink-primary) !important;
}
.ui-cg-pick-line:hover { background: var(--bg-card-hover); }
.ui-cg-pick-line:focus-within { box-shadow: inset 0 0 0 2px var(--brand-link); }
.ui-cg-pick-line:has(input:checked) { border-color: var(--brand-primary-border); background: var(--brand-primary-tint); }
.ui-cg-pick-line input { flex: 0 0 auto; inline-size: 18px; block-size: 18px; margin-block: 2px 0; margin-inline: 0; accent-color: var(--brand-primary); cursor: pointer; }
.ui-cg-pick-line-text { display: flex; flex-direction: column; gap: 2px; min-inline-size: 0; }
.ui-cg-pick-line-title { font-weight: 600; overflow-wrap: anywhere; }
.ui-cg-pick-line-meta { font-size: 12px; color: var(--ink-muted); }
@media (max-width: 420px) {
    .ui-cg-wizard-actions .ui-btn { flex: 1 1 auto; justify-content: center; }
    .ui-cg-result-act, .ui-cg-add-line, .ui-cg-add-line .ui-btn { inline-size: 100%; }
}
/* The list view's extra menu column: the title gives up a little of its least
   width, so eleven columns still fit a 1280px screen. */
@media (min-width: 900px) {
    .ui-gantt-list .ui-table-wrap--menu .ui-table td.ui-gantt-list-title { min-inline-size: 11rem; }
    .ui-gantt-list .ui-table-wrap--menu .ui-table td.ui-td-menu { width: 52px; padding-inline: 2px 6px; }
}
@media (max-width: 600px) {
    .ui-gantt-row > .ui-gantt-label.ui-gantt-label--tools { padding-inline-end: 48px; }
}
/* (end of: timeline) */

/* ---- Close popup (ticket page, owner request 2026-09-25) --------------- */
/* partials/modals.blade.php #completeModal: the photos a close will use, place
   by place (TicketCloseProof) - each kept, removed or replaced, new ones added
   - the note, and what the history line will say. The Close button stays off
   while the ticket has no photo at all. Wider than a plain dialog: a grid of
   photos needs the room; one column of two photos on a phone. */
.ui-modal--wide { width: min(820px, calc(100% - 32px)); }
.ui-close .ui-modal-body { gap: 16px; }
.ui-close[aria-busy="true"] .ui-modal-body { opacity: .7; pointer-events: none; }
.ui-close-ref { overflow-wrap: anywhere; }
.ui-close-places { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ui-close-places .ui-note { margin: 6px 0 0; }
.ui-close-pick { gap: 10px; min-width: 0; padding-block: 4px; }
.ui-close-pick input { flex-shrink: 0; }
/* The name, then its status pill - on the next line under the name (never under the box) when narrow. */
.ui-close-pick-text { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; min-width: 0; }
.ui-close-pick-text > span[dir="auto"] { min-width: 0; overflow-wrap: anywhere; }
.ui-close-photos { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.ui-close-heading { margin: 0; font-size: 15px; font-weight: 700; line-height: 1.35; color: var(--ink-primary); }
.ui-close-photos > .ui-note { margin: 0; }
.ui-close-none .ui-note-body { gap: 4px; }
.ui-close-none .ui-note-body strong { font-size: 14px; }
.ui-close-none .ui-btn { margin-top: 4px; }
.ui-close-place {
    display: flex;
    flex-direction: column;
    gap: 10px;
    min-width: 0;
    padding: 12px;
    border: 1px solid var(--border-light);
    border-radius: 12px;
    background: var(--bg-card-subtle);
}
.ui-close-place[hidden] { display: none; }
/* The work photos handed in for the whole ticket (several places): set apart from the places it serves. */
.ui-close-place--ticket { border-color: var(--brand-primary-border); background: var(--bg-card); }
.ui-close-source[hidden] { display: none; }
.ui-close-place-head { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; min-width: 0; }
.ui-close-place-name {
    flex: 1 1 220px;
    min-width: 0;
    margin: 0;
    font-size: 14px;
    font-weight: 700;
    line-height: 1.4;
    color: var(--ink-primary);
    text-align: start;
    overflow-wrap: anywhere;
}
.ui-close-count { font-size: 12px; font-weight: 600; color: var(--ink-muted); }
.ui-close-source { margin: 0; font-size: 13px; line-height: 1.45; color: var(--ink-secondary); }
.ui-close-place > .ui-note { margin: 0; }
.ui-close-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 170px), 1fr));
    gap: 10px;
    margin: 0;
    padding: 0;
    list-style: none;
}
.ui-close-grid:empty { display: none; }
.ui-close-photo {
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-width: 0;
    padding: 6px;
    border: 1px solid var(--border-light);
    border-radius: 10px;
    background: var(--bg-card);
}
.ui-close-photo--new { border-color: var(--brand-primary-border); background: var(--brand-primary-tint); }
.ui-close-photo.is-removed { border-style: dashed; border-color: var(--border-strong); background: var(--bg-card-subtle); }
.ui-close-thumb {
    display: block;
    width: 100%;
    aspect-ratio: 4 / 3;
    object-fit: cover;
    border-radius: 6px;
    background: var(--neutral-bg);
}
.ui-close-photo.is-removed .ui-close-thumb { opacity: .35; filter: grayscale(1); }
.ui-close-tag { align-self: flex-start; max-width: 100%; white-space: normal; }
.ui-close-taken { font-size: 12px; line-height: 1.35; color: var(--ink-muted); overflow-wrap: anywhere; }
.ui-close-actions { display: flex; flex-wrap: wrap; gap: 6px; margin-top: auto; }
.ui-close-actions .ui-btn { flex: 1 1 auto; padding-inline: 8px; }
.ui-close-add { display: flex; flex-wrap: wrap; gap: 8px; }
.ui-close-record {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 10px 12px;
    border: 1px dashed var(--border-strong);
    border-radius: 10px;
}
.ui-close-record-text { margin: 0; font-size: 14px; line-height: 1.5; color: var(--ink-primary); overflow-wrap: anywhere; text-align: start; }
.ui-close .ui-modal-foot .ui-btn[disabled] { opacity: .5; }
@media (max-width: 420px) {
    .ui-close .ui-modal-body { padding-inline: 14px; }
    .ui-close-place { padding: 10px; }
    .ui-close-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
    .ui-close .ui-modal-foot .ui-btn { flex: 1 1 auto; }
}
/* (end of: close popup) */

/* ---- Language menu (header + account menu, owner request 2026-09-26) ----
   Every language in its own name; the current one ticked (.ui-check-mark).
   On a phone the list sits in the account menu under a small heading. */
.ui-language-heading { display: flex; align-items: center; gap: 6px; }
.ui-popover-item [dir="rtl"] { unicode-bidi: isolate; }
/* (end of: language menu) */

/* ==== END OF SHARED BUILDING BLOCKS ==================================== */
