/*!
 * ============================================================================
 * Copyright (c) 2025 ATH SOLUTIONS (PTY) LTD. All rights reserved.
 * KwaZulu-Natal, Republic of South Africa.
 * ============================================================================
 *
 * @BEGIN Developer Log Header Block
 * @FILENAME: main.css
 * @TITLE: ATH Accounts - Main Stylesheet
 * @DESCRIPTION: Core component styles for the ATH Accounts application shell. Depends on design-tokens.css being loaded first. All values reference CSS custom properties from design-tokens.css.
 * @AUTHOR: Ary van der Pijl
 * @COMPANY: ATH SOLUTIONS (PTY) LTD
 * @WEBSITE: https://www.ath.solutions/
 * @EMAIL: info@ath.solutions
 * @COPYRIGHT: All Rights Reserved
 * @LICENSE: ATH SOLUTIONS - PROPRIETARY SOFTWARE LICENCE AGREEMENT (https://www.ath.solutions/documents/ath_solutions_software_licence_agreement.pdf)
 *
 * BEGIN CHANGELOG
 * @IMPORTANT NOTICE: Developers working on these files MUST update and maintain the Developers Change Log, failure to do is not an option:
 * !==================================================================================================================================================================
 * VERSION 1.3.0
 * - File Modified | Ary van der Pijl | 2026-10-23 | ATH-GAP-052 | Follow-up to 1.2.9: switching .info-block to display:flex dropped its implicit block-level width:100% fill of the .col-3 grid cell - flex items size to content by default unless a width is set, so it visibly lost its width against .dash-grid's siblings. Added width:100% + box-sizing:border-box (needed once width:100% is explicit, so the existing padding doesn't push it past the grid cell).
 * VERSION 1.2.9
 * - File Modified | Ary van der Pijl | 2026-10-23 | ATH-GAP-052 | Reported "cards too small for the data" on the System Monitoring page (screenshot: 3-line KPI content - uppercase label, value, delta/sub-line - visibly overflowing/cramped inside .kpi-tile) and the same complaint on the Books dashboard's .info-block tiles once their title-wrap bug (1.2.7/1.2.8) was fixed and real content started showing. .kpi-tile's min-height:104px was sized for its simplest 2-line case, never updated for pages like monitoring.php whose tiles pack a wrapping label + value + 2-part delta line; raised to 140px + height:100% so it also stretches to match a taller row sibling (e.g. monitoring.php's attack-trend row: col-8 chart panel next to a col-4 single kpi-tile). Also fixed .kpi-tile.accent-gold: it referenced --color-gold-700, a token that was removed from design-tokens.css in the MicroOffice rebrand (ATH-GAP-051) and never existed under that name again - the left accent stripe silently rendered as nothing on every accent-gold tile (confirmed live: "DB SIZE" tile in monitoring.php had no visible accent border next to its 3 siblings that did). Repointed to --color-blue-700, the same repoint --stat-gold-color already uses for this exact reason elsewhere in this file. Gave .info-block the same min-height treatment (170px, plus display:flex/flex-direction:column/justify-content:center so its content centers in the taller card instead of leaving dead space below) so its cards read at the same visual weight as the .panel.glass cards beside them in the same row.
 * VERSION 1.2.8
 * - File Modified | Ary van der Pijl | 2026-10-23 | ATH-GAP-052 | Follow-up to 1.2.7: .info-block-top .title had no flex-grow, so in the flex row it sized to auto with min-width:0 and no allocated space - rendered with zero visible width (title text invisible entirely, not just truncated) once white-space:nowrap/overflow:hidden were added. Added flex:1 1 auto so it actually claims the row's remaining space (icon stays flex-shrink:0 at its fixed size) before overflow/ellipsis kicks in.
 * VERSION 1.2.7
 * - File Modified | Ary van der Pijl | 2026-10-23 | ATH-GAP-052 | Fixed the Books financial-health dashboard's .info-block tiles on report of broken-looking layout (screenshot: "Cash on hand" wrapping to 3 lines, "R 0" splitting across two lines mid-string). Root cause: .info-block-top .title had no white-space handling at --text-xl (18px) in a col-3 (25%) card - icon + "Cash on hand" don't fit on one line at that size/width, so it wrapped at every word; .info-block-number had the same gap (a clamp() font-size up to 56px with no white-space:nowrap), so even the 2-character "R 0" string wrapped at its own space once the number ever rendered short/empty. Title now truncates with ellipsis instead of wrapping (lowered to --text-md/medium-weight, which also fits more comfortably); number gets white-space:nowrap and a lower clamp ceiling (was 3.2vw/text-6xl, now 2.6vw/kept text-6xl ceiling only at wide viewports) plus a .is-empty modifier for the "n/a"/zero placeholder states so they read as an intentional muted empty state rather than a broken huge-font glitch. Also added .info-block.glass/.panel.glass (translucent --glass-bg + backdrop-filter blur, opt-in per the Glassmorphism style - "modern SaaS, financial dashboards" is its own documented best-fit) and .dash-backdrop (a faint radial-gradient wrapper class so the glass surfaces have something to blur against) per an explicit ask to bring a glass accent to this dashboard. Deliberately scoped as opt-in modifier classes, not applied to every .panel/.info-block site-wide - backdrop-filter has a real paint cost and most of this app's pages (forms, tables, settings) don't want it.
 * VERSION 1.2.6
 * - File Modified | Ary van der Pijl | 2026-10-01 | ATH-GAP-051 | Applied DESIGN/index.html (Layout 1) on top of the re-tokenised palette: .panel-heading lost its bottom divider (opt back in with .panel-heading-bb) and gained a leading-icon slot (.panel-heading > i); .table th now uses --gradient-grey; added .greeting-field, .info-block (icon + title, large number, caption tile), .progress-lg with .progress-bar-gradient-primary/info/danger/alert, and a dark-theme .btn-primary text override. All token-driven.
 * VERSION 1.2.5
 * - File Modified | Ary van der Pijl | 2026-09-13 | ATH-GAP-045 | UX audit pass 2: added body{overflow-x:hidden} as a defensive safety net against any future fixed-width regression forcing a mobile horizontal scrollbar; added .form-control:disabled/.form-select:disabled/textarea:disabled styling (previously only .btn[disabled] had a distinct look - roles.js's read-only view-mode toggle left disabled inputs with only the browser's barely-visible default); added .search-results-dropdown (z-index: var(--z-dropdown), max-height/overflow-y) replacing two raw inline style="z-index:1000" literals in roles.php that duplicated the token's value instead of referencing it.
 * VERSION 1.2.4
 * - File Modified | Ary van der Pijl | 2026-09-13 | ATH-GAP-044 | .badge-success/.badge-warning/.badge-info text colors darkened (were the raw --color-success/-warning/-info semantic tokens at ~3.1-3.4:1 on their own pale -bg tint, short of WCAG 1.4.3's 4.5:1) - kept the base semantic tokens unchanged (still used correctly at full saturation for icons/borders elsewhere) and gave badges their own darker literal shade instead. .badge-danger left as-is (~4.4:1, already effectively passing).
 * VERSION 1.2.3
 * - File Modified | Ary van der Pijl | 2026-09-13 | ATH-GAP-044 | Platform-wide UX/accessibility audit fixes (touch targets): .header-btn 36->44px (mobile menu/language/theme/Admin toggles), .btn-icon 36->44px, .btn-icon.btn-sm 30->40px (every datatable row-action button - edit/delete/view icons across users/tenants/roles/cms/sso/finance/etc.), .toggle-icon (sidebar collapse) 32->40px. All below WCAG 2.5.5's 44x44 minimum target size; .presence-avatar/.presence-more deliberately left at 28px - a desktop-only (d-md-flex), intentionally-overlapping avatar cluster, not a touch-primary control.
 * VERSION 1.2.2
 * - File Modified | Ary van der Pijl | 2026-09-13 | ATH-GAP-043 | Added .admin-menu (max-height:70vh + scroll) for the new topbar Admin dropdown (header.php) - 15 items would run off-screen on short viewports otherwise.
 * VERSION 1.2.1
 * - File Modified | Ary van der Pijl | 2026-09-13 | ATH-GAP-042 | Added the .marketing-* section (nav, hero, feature grid, cta) for the new public marketing landing page (layouts/marketing.php, pages/landing.php) - all token-driven (navy hero background, --panel-* for feature cards, existing spacing/type scale), no new tokens invented.
 * VERSION 1.2.0
 * - File Modified | Ary van der Pijl | 2026-09-13 | ATH-GAP-040 | Added .panel-heading:has(.nav-tabs) (drops the heading's own padding-bottom/border-bottom in favour of the Bootstrap nav-tabs' own bottom border, and un-flexes it so the tab strip runs edge-to-edge) and .panel-heading .nav-tabs{margin-bottom:-1px} (sits the tab underline flush against the panel's border) for profile.php's 7-card-to-tabs conversion.
 * VERSION 1.1.9
 * - File Modified | Ary van der Pijl | 2026-09-13 | ATH-GAP-039 | .panel/.kpi-tile no longer carry an outer 1px border - DESIGN/index2.html's actual dependency (theme.css `#content .panel`) has none, only the flat box-shadow now correctly transcribed into --panel-shadow (see design-tokens.css changelog). --panel-border stays in use for the heading bottom-divider and footer top-divider, which are real, intentional dividers in both the reference and this codebase.
 * VERSION 1.1.8
 * - File Modified | Ary van der Pijl | 2026-09-13 | ATH-GAP-037 | .auth-page is now a flex column (was flex row-default with align-items+justify-content:center, which centred .auth-container and the auth-footer as equal siblings - the footer overlapped the login card instead of sitting below it). .auth-container now self-centres via margin:auto 0, .auth-footer pins to the bottom via margin-top:auto (same sticky-footer pattern as the authenticated shell below), width:100% + padding-top replacing the old fixed margin-top so it doesn't shrink-wrap off-centre in the column.
 * VERSION 1.1.7
 * - File Modified | Ary van der Pijl | 2026-09-13 | ATH-GAP-037 | .page-content is now a flex column with .page-content > .app-footer { margin-top: auto } - the standard sticky-footer pattern, since .page-wrapper already establishes the full-viewport-height flex column .page-content/.topbar sit in. Fixes the footer (copyright/legal links) floating up under short-content pages instead of staying pinned to the viewport bottom.
 * VERSION 1.1.6
 * - File Modified | Ary van der Pijl | 2026-09-13 | ATH-GAP-036 | .sidebar-logo-icon now sizes an <img> (32x32, object-fit:contain) instead of styling a Boxicons glyph (font-size/color) - sidebar.php now shows the actual ATH symbol image. Removed .auth-crest/.auth-crest:hover/.auth-crest i - the generic Boxicons-compass fallback they styled is gone now that auth.php's no-tenant-logo case also uses the ATH symbol image (.auth-crest-img handles both cases identically), leaving these rules dead.
 * VERSION 1.1.5
 * - File Modified | Ary van der Pijl | 2026-09-11 | ATH-GAP-017 | Added .auth-crest-img for the new tenant-logo-on-auth-pages feature (auth.php) - same footprint as the generic .auth-crest icon it replaces when a logo resolves.
 * VERSION 1.1.4
 * - File Modified | Ary van der Pijl | 2026-09-11 | ATH-GAP-015 | Added cursor:pointer + focus outline to .presence-avatar (now clickable, opens a view-profile modal) and .presence-avatar-lg for that modal's larger avatar display.
 * VERSION 1.1.3
 * - File Modified | Ary van der Pijl | 2026-09-11 | ATH-GAP-006 | Added .header-lang-flag sizing for the new flag-emoji language switcher (header.php).
 * VERSION 1.1.2
 * - File Modified | Ary van der Pijl | 2026-09-11 | ATH-GAP-003 | Added .app-footer/.app-footer-link (site-wide footer in the authenticated shell) and extended .auth-footer with .auth-footer-links for the same footer in the auth layout |
 * VERSION 1.1.1
 * - File Modified | Ary van der Pijl | 2026-09-10 | ATH-SKELETON-021 | Design sweep: added themed .alert/.alert-* (were undefined - pages fell through to Bootstrap), btn-outline-* /btn-success/btn-warning/btn-info, .badge-secondary; tightened .modal-content radius; converged .card-header/.card-body/.card-title/.card-footer onto the same --panel-* tokens so every .card page picks up the index2.html density with no markup change. |
 * VERSION 1.1.0
 * - File Modified | Ary van der Pijl | 2026-09-10 | ATH-SKELETON-021 | Design system rollout (index2.html look-and-feel): added .panel/.panel-heading/.panel-title/.panel-body/.panel-footer card idiom, .dash-grid + .chart-box + .kpi-tile dashboard primitives, .metric-list/.ageing-bar/.legend-dots helpers, .gauge-wrap. Tightened .card radius to --panel-radius. All token-driven. |
 * VERSION 1.0.9
 * - File Modified | Ary van der Pijl | 2026-08-16 | ATH-SKELETON-018 | Added .address-autocomplete/.address-autocomplete__list/.address-autocomplete__item for the new address-search dropdown on the Profile/Organisation address fields |
 * VERSION 1.0.8
 * - File Modified | Ary van der Pijl | 2026-08-16 | ATH-SKELETON-014 | Added .branding-preview for the new logo/favicon upload thumbnails on the Appearance page |
 * VERSION 1.0.7
 * - File Modified | Ary van der Pijl | 2026-08-16 | ATH-SKELETON-014 | Fixed .user-avatar img rendering at full natural size instead of the 32px circle: object-fit only affects replaced elements (img/video), not the .user-avatar div itself, so an inserted <img> child had no size constraint at all. Added a .user-avatar img rule and moved object-fit there. |
 * VERSION 1.0.6
 * - File Modified | Ary van der Pijl | 2026-07-23 | ATH-SKELETON-003 | Added .presence-stack/.presence-avatar/.presence-more (overlapping avatar stack for the "who's online" header widget) |
 * VERSION 1.0.5
 * - File Modified | Ary van der Pijl | 2026-07-23 | ATH-SKELETON-003 | Added object-fit:cover to .user-avatar so an <img> avatar fills the circle without distortion (previously only ever held text initials) |
 * VERSION 1.0.4
 * - File Modified | Ary van der Pijl | 2026-07-22 | ATH-SKELETON-012 | Added sortable-column-header styles (.th-sortable, .th-sort-icon, .th-sort-active) for the DataTable component |
 * VERSION 1.0.3
 * - File Modified | Ary van der Pijl | 2026-07-22 | ATH-SKELETON-011 | Dashtreme look-and-feel: rebuilt shell/sidebar/header onto wrapper/sidebar-wrapper/metismenu/topbar/page-wrapper structure; swapped material-icons-round selectors for Boxicons `i` tags; rounder card/modal/table radii |
 * VERSION 1.0.2
 * - File Modified | Ary van der Pijl | 2026-06-16 | ATH-COMPLIANCE-001 | Applied ATH Solutions 2026 standards: added ATH /*! file header per G-17 |
 * VERSION 1.0.1
 * - File Created | Ary van der Pijl | 2026-05-01 | ATH-SKELETON-001 | Initial file |
 * ==================================================================================================================================================================!
 * END CHANGELOG
 */

/* ─── Base Reset ─────────────────────────────────────────────────────────── */

*, *::before, *::after {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

body {
  font-family: var(--font-sans);
  font-size: var(--text-base);
  font-weight: var(--fw-normal);
  line-height: var(--lh-normal);
  color: var(--color-text);
  background-color: var(--color-bg);
  margin: 0;
  -webkit-font-smoothing: antialiased;
  /* Defensive safety net - no component should currently force this, but a future fixed-width
     regression shouldn't be able to introduce a page-level horizontal scrollbar on mobile. */
  overflow-x: hidden;
}

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

a:hover {
  color: var(--color-primary-hover);
}

img, svg {
  vertical-align: middle;
}

/* ─── App Shell ──────────────────────────────────────────────────────────── */

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

/* ─── Sidebar ────────────────────────────────────────────────────────────── */

#sidebar {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  width: var(--sidebar-width);
  background: var(--sidebar-bg);
  display: flex;
  flex-direction: column;
  z-index: var(--z-fixed);
  transition: width var(--transition-slow);
  overflow-x: hidden;
}

.wrapper.toggled #sidebar {
  width: var(--sidebar-collapsed);
}

.sidebar-header {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-5) var(--space-5);
  height: var(--header-height);
  border-bottom: 1px solid var(--sidebar-border);
  overflow: hidden;
  white-space: nowrap;
}

.sidebar-logo {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  text-decoration: none;
  overflow: hidden;
}

.sidebar-logo-icon {
  width: 32px;
  height: 32px;
  object-fit: contain;
  flex-shrink: 0;
}

.sidebar-logo-text {
  font-size: var(--text-lg);
  font-weight: var(--fw-bold);
  color: #ffffff;
  overflow: hidden;
  text-overflow: ellipsis;
}

.toggle-icon {
  margin-left: auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: var(--radius-sm);
  color: var(--sidebar-text);
  cursor: pointer;
  transition: background var(--transition-base), transform var(--transition-slow);
  flex-shrink: 0;
}

.toggle-icon:hover {
  background: var(--sidebar-hover-bg);
  color: #fff;
}

.wrapper.toggled .toggle-icon {
  transform: rotate(180deg);
}

.wrapper.toggled .sidebar-header,
.wrapper.toggled .sidebar-logo-text,
.wrapper.toggled .menu-label,
.wrapper.toggled .menu-title {
  opacity: 0;
  pointer-events: none;
}

.metismenu {
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
  list-style: none;
  margin: 0;
  padding: var(--space-4) 0;
  scrollbar-width: thin;
  scrollbar-color: var(--sidebar-border) transparent;
}

.menu-label {
  font-size: var(--text-xs);
  font-weight: var(--fw-semibold);
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--sidebar-text);
  padding: var(--space-4) var(--space-5) var(--space-2);
  opacity: .6;
  white-space: nowrap;
  overflow: hidden;
  transition: opacity var(--transition-fast);
}

.nav-item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-4);
  margin: 2px var(--space-2);
  border-radius: var(--radius-sm);
  color: var(--sidebar-text);
  text-decoration: none;
  font-size: var(--text-sm);
  font-weight: var(--fw-medium);
  cursor: pointer;
  transition: all var(--transition-base);
  white-space: nowrap;
  overflow: hidden;
}

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

.nav-item.active {
  background: var(--sidebar-active-bg);
  color: var(--sidebar-active-text);
  border-left: 3px solid var(--sidebar-active-border);
  padding-left: calc(var(--space-4) - 3px);
}

.nav-item--disabled {
  opacity: var(--module-tile-disabled-opacity);
  cursor: not-allowed;
  pointer-events: none;
}

.nav-item i {
  font-size: 20px;
  flex-shrink: 0;
}

.nav-item .parent-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 20px;
}

.nav-item .menu-title,
.nav-item-label {
  overflow: hidden;
  text-overflow: ellipsis;
  transition: opacity var(--transition-fast);
}

.nav-badge {
  margin-left: auto;
  background: rgba(255, 255, 255, .15);
  color: #fff;
  font-size: 10px;
  font-weight: var(--fw-semibold);
  padding: 2px 6px;
  border-radius: var(--radius-full);
  flex-shrink: 0;
}

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

.page-wrapper {
  margin-left: var(--sidebar-width);
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  transition: margin-left var(--transition-slow);
}

.wrapper.toggled .page-wrapper {
  margin-left: var(--sidebar-collapsed);
}

/* ─── Header ─────────────────────────────────────────────────────────────── */

.topbar {
  position: sticky;
  top: 0;
  height: var(--header-height);
  background: var(--header-bg);
  border-bottom: 1px solid var(--header-border);
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: 0 var(--space-6);
  z-index: var(--z-sticky);
  box-shadow: var(--shadow-xs);
}

.header-breadcrumb {
  flex: 1;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

.header-breadcrumb .breadcrumb-item {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.header-breadcrumb .breadcrumb-item.active {
  color: var(--color-text);
  font-weight: var(--fw-medium);
}

.header-breadcrumb .separator {
  color: var(--color-text-subtle);
}

.header-actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.header-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: var(--radius-sm);
  background: transparent;
  border: 1px solid transparent;
  color: var(--color-text-muted);
  cursor: pointer;
  transition: all var(--transition-base);
  position: relative;
}

.header-btn:hover {
  background: var(--color-surface-2);
  color: var(--color-text);
  border-color: var(--color-border);
}

.header-btn i {
  font-size: 20px;
}

.header-lang-flag {
  font-size: 18px;
  line-height: 1;
}

.badge-dot {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 8px;
  height: 8px;
  background: var(--color-danger);
  border-radius: 50%;
  border: 2px solid var(--header-bg);
}

.user-menu-btn {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  background: transparent;
  border: 1px solid transparent;
  color: var(--color-text);
  cursor: pointer;
  transition: all var(--transition-base);
}

.user-menu-btn:hover {
  background: var(--color-surface-2);
  border-color: var(--color-border);
}

.user-avatar {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--color-primary);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--text-sm);
  font-weight: var(--fw-semibold);
  flex-shrink: 0;
  overflow: hidden;
}

.user-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.branding-preview {
  width: 100%;
  height: 100%;
  object-fit: contain;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface-2);
}

.address-autocomplete {
  position: relative;
}

.address-autocomplete__list {
  position: absolute;
  z-index: var(--z-dropdown, 1000);
  top: 100%;
  left: 0;
  right: 0;
  margin-top: 4px;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-md);
  max-height: 240px;
  overflow-y: auto;
}

.address-autocomplete__item {
  display: block;
  width: 100%;
  text-align: left;
  padding: var(--space-2, 8px) var(--space-3, 12px);
  background: none;
  border: none;
  border-bottom: 1px solid var(--color-border-light);
  color: var(--color-text);
  font-size: var(--text-sm);
  cursor: pointer;
}

/* Generic search-result dropdown positioned under a text input (e.g. roles.php's
   assign-user/override-user pickers) - was a raw inline style="z-index:1000" literal
   duplicating --z-dropdown's value instead of referencing the token. */
.search-results-dropdown {
  z-index: var(--z-dropdown, 1000);
  max-height: 240px;
  overflow-y: auto;
}

.address-autocomplete__item:last-child {
  border-bottom: none;
}

.address-autocomplete__item:hover,
.address-autocomplete__item:focus {
  background: var(--color-surface-2);
}

.presence-stack {
  align-items: center;
  margin-right: var(--space-2, 8px);
}

.presence-avatar,
.presence-more {
  width: 28px;
  height: 28px;
  font-size: 11px;
  margin-left: -8px;
  border: 2px solid var(--color-surface);
}

.presence-avatar {
  cursor: pointer;
}

.presence-avatar:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

.presence-avatar-lg {
  width: 64px;
  height: 64px;
  font-size: 24px;
}

.presence-stack> :first-child {
  margin-left: 0;
}

.presence-more {
  border-radius: 50%;
  background: var(--color-surface-2);
  color: var(--color-text-muted);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: var(--fw-semibold);
}

.user-name {
  font-size: var(--text-sm);
  font-weight: var(--fw-medium);
}

/* ─── Page Content ───────────────────────────────────────────────────────── */

.page-content {
  flex: 1;
  display: flex;
  flex-direction: column;
  padding: var(--space-6);
  max-width: 1400px;
  width: 100%;
}

.page-content>.app-footer {
  margin-top: auto;
}

/* ─── App Footer (authenticated shell) ──────────────────────────────────────── */

.app-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-8);
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-border-light);
  font-size: var(--text-xs);
  color: var(--color-text-subtle);
}

.app-footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
}

.app-footer-link {
  background: none;
  border: none;
  padding: 0;
  font-size: var(--text-xs);
  color: var(--color-text-subtle);
  text-decoration: none;
  cursor: pointer;
}

.app-footer-link:hover,
.app-footer-link:focus-visible {
  color: var(--color-text-muted);
  text-decoration: underline;
}

.page-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-6);
  flex-wrap: wrap;
}

.page-title {
  font-size: var(--text-2xl);
  font-weight: var(--fw-bold);
  color: var(--color-text);
  margin: 0;
  line-height: var(--lh-tight);
}

.page-subtitle {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  margin: var(--space-1) 0 0;
}

.page-actions {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}

/* ─── Cards ──────────────────────────────────────────────────────────────── */

.card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--panel-radius);
  box-shadow: var(--shadow-sm);
}

.card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--panel-heading-pad);
  border-bottom: 1px solid var(--color-border);
  gap: var(--space-3);
}

.card-title {
  font-size: var(--panel-title-size);
  font-weight: var(--panel-title-weight);
  color: var(--color-text);
  margin: 0;
}

.card-body {
  padding: var(--panel-body-pad);
}

.card-footer {
  padding: var(--space-3) var(--space-5);
  border-top: 1px solid var(--color-border);
  background: var(--color-surface-2);
  border-radius: 0 0 var(--panel-radius) var(--panel-radius);
}

/* ─── Stat Cards ─────────────────────────────────────────────────────────── */

.stat-card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  box-shadow: var(--shadow-md);
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
}

.stat-icon {
  width: 48px;
  height: 48px;
  border-radius: var(--radius-lg);
  background: var(--color-primary-light);
  color: var(--color-primary);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.stat-icon i {
  font-size: 24px;
}

.stat-value {
  font-size: var(--text-3xl);
  font-weight: var(--fw-bold);
  color: var(--color-text);
  line-height: 1;
  margin: 0 0 var(--space-1);
}

.stat-label {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  margin: 0;
}

.stat-change {
  font-size: var(--text-xs);
  font-weight: var(--fw-medium);
  margin-top: var(--space-2);
  display: flex;
  align-items: center;
  gap: 2px;
}

.stat-change.up {
  color: var(--color-success);
}

.stat-change.down {
  color: var(--color-danger);
}

/* ─── Table ──────────────────────────────────────────────────────────────── */

.table-wrapper {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-md);
}

.table-toolbar {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--color-border);
  flex-wrap: wrap;
}

.table-toolbar-left {
  flex: 1;
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.table-toolbar-right {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.table {
  margin: 0;
}

.table th {
  font-size: var(--text-xs);
  font-weight: var(--fw-semibold);
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--color-text-muted);
  background: var(--gradient-grey);
  border-bottom: 1px solid var(--color-border);
  padding: var(--space-3) var(--space-4);
  white-space: nowrap;
}

.table th.th-sortable {
  cursor: pointer;
  user-select: none;
}

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

.th-sort-icon {
  font-size: 14px;
  margin-left: var(--space-1);
  vertical-align: middle;
  opacity: .5;
}

.table th.th-sort-active {
  color: var(--color-primary);
}

.table th.th-sort-active .th-sort-icon {
  opacity: 1;
}

.table td {
  font-size: var(--text-sm);
  color: var(--color-text);
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--color-border-light);
  vertical-align: middle;
}

.table tbody tr:last-child td {
  border-bottom: none;
}

.table tbody tr:hover td {
  background: var(--color-surface-2);
}

.table-pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-3) var(--space-5);
  border-top: 1px solid var(--color-border);
  flex-wrap: wrap;
  gap: var(--space-3);
}

.table-meta {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

/* ─── Buttons ────────────────────────────────────────────────────────────── */

.btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  font-weight: var(--fw-medium);
  line-height: 1;
  padding: var(--space-2) var(--space-4);
  height: 36px;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  cursor: pointer;
  transition: all var(--transition-base);
  text-decoration: none;
  white-space: nowrap;
}

.btn:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

.btn-primary {
  background: var(--color-primary);
  color: #fff;
  border-color: var(--color-primary);
}

.btn-primary:hover {
  background: var(--color-primary-hover);
  border-color: var(--color-primary-hover);
  color: #fff;
}

.btn-secondary {
  background: var(--color-surface);
  color: var(--color-text);
  border-color: var(--color-border);
}

.btn-secondary:hover {
  background: var(--color-surface-2);
  color: var(--color-text);
}

.btn-ghost {
  background: transparent;
  color: var(--color-text-muted);
  border-color: transparent;
}

.btn-ghost:hover {
  background: var(--color-surface-2);
  color: var(--color-text);
}

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

.btn-danger:hover {
  background: #b91c1c;
  border-color: #b91c1c;
  color: #fff;
}

.btn-success {
  background: var(--color-success);
  color: #fff;
  border-color: var(--color-success);
}

.btn-success:hover {
  background: #15803d;
  border-color: #15803d;
  color: #fff;
}

.btn-warning {
  background: var(--color-warning);
  color: #fff;
  border-color: var(--color-warning);
}

.btn-warning:hover {
  background: #b45309;
  border-color: #b45309;
  color: #fff;
}

.btn-info {
  background: var(--color-info);
  color: #fff;
  border-color: var(--color-info);
}

.btn-info:hover {
  background: #0369a1;
  border-color: #0369a1;
  color: #fff;
}

/* Outline variants (index2.html uses these heavily for secondary row actions). */
.btn-outline-primary {
  background: transparent;
  color: var(--color-primary);
  border-color: var(--color-primary);
}

.btn-outline-primary:hover {
  background: var(--color-primary);
  color: #fff;
}

.btn-outline-secondary {
  background: transparent;
  color: var(--color-text-muted);
  border-color: var(--color-border);
}

.btn-outline-secondary:hover {
  background: var(--color-surface-2);
  color: var(--color-text);
}

.btn-outline-danger {
  background: transparent;
  color: var(--color-danger);
  border-color: var(--color-danger);
}

.btn-outline-danger:hover {
  background: var(--color-danger);
  color: #fff;
}

.btn-sm {
  height: 30px;
  padding: var(--space-1) var(--space-3);
  font-size: var(--text-xs);
}

.btn-lg {
  height: 44px;
  padding: var(--space-3) var(--space-6);
  font-size: var(--text-md);
}

.btn i {
  font-size: 16px;
}

.btn-icon {
  width: 44px;
  height: 44px;
  padding: 0;
  justify-content: center;
}

/* Datatable row-action buttons (edit/delete/view icons) - was 30x30, well under the 44x44
   WCAG 2.5.5 minimum. Table rows tolerate 40px fine without visibly bloating; row-action
   groups use gap-2 (8px, design-tokens.css --space-2) which stays a real, non-overlapping
   gap at this size. */
.btn-icon.btn-sm {
  width: 40px;
  height: 40px;
}

.btn[disabled], .btn.disabled {
  opacity: .5;
  cursor: not-allowed;
}

/* Disabled form controls (e.g. roles.js's read-only view-mode toggle) previously fell back to
   the browser's own barely-visible default disabled styling - no rule here targeted them at all. */
.form-control:disabled, .form-select:disabled, textarea:disabled {
  opacity: .6;
  cursor: not-allowed;
  background-color: var(--color-surface-2);
}

.btn.loading .btn-text {
  opacity: 0;
}

/* ─── Forms ──────────────────────────────────────────────────────────────── */

.form-label {
  display: block;
  font-size: var(--text-sm);
  font-weight: var(--fw-medium);
  color: var(--color-text);
  margin-bottom: var(--space-2);
}

.form-control, .form-select {
  width: 100%;
  padding: var(--space-2) var(--space-3);
  height: 38px;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  color: var(--color-text);
  transition: border-color var(--transition-base), box-shadow var(--transition-base);
  outline: none;
}

.form-control:focus, .form-select:focus {
  border-color: var(--color-primary);
  outline: 2px solid var(--color-primary);
  outline-offset: 1px;
}

.form-control::placeholder {
  color: var(--color-text-subtle);
}

textarea.form-control {
  height: auto;
  min-height: 100px;
  resize: vertical;
  line-height: var(--lh-normal);
}

.form-control.is-invalid, .form-select.is-invalid {
  border-color: var(--color-danger);
}

.invalid-feedback {
  font-size: var(--text-xs);
  color: var(--color-danger);
  margin-top: var(--space-1);
}

.form-group {
  margin-bottom: var(--space-5);
}

/* ─── Password reveal toggle (injected by password-toggle.js) ─────────────── */

.password-field {
  position: relative;
  display: block;
}

.password-field .form-control {
  padding-right: calc(var(--space-3) + 28px);
}

.password-field .password-toggle {
  position: absolute;
  top: 0;
  right: 0;
  height: 38px;
  width: calc(var(--space-3) + 28px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  background: none;
  border: none;
  color: var(--color-text-muted);
  font-size: 18px;
  cursor: pointer;
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
}

.password-field .password-toggle:hover {
  color: var(--color-text);
}

.password-field .password-toggle:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: -2px;
}

.input-group {
  display: flex;
}

.input-group .form-control {
  flex: 1;
  border-radius: var(--radius-sm) 0 0 var(--radius-sm);
}

.input-group .btn {
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
}

.input-prefix, .input-suffix {
  display: flex;
  align-items: center;
  padding: 0 var(--space-3);
  background: var(--color-surface-2);
  border: 1px solid var(--color-border);
  color: var(--color-text-muted);
  font-size: var(--text-sm);
}

.input-prefix {
  border-right: none;
  border-radius: var(--radius-sm) 0 0 var(--radius-sm);
}

.input-suffix {
  border-left: none;
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
}

.input-group .form-control:not(:first-child):not(:last-child) {
  border-radius: 0;
}

/* ─── Alerts (index2.html: tinted fill, coloured left accent, small radius) ── */

.alert {
  padding: var(--space-3) var(--space-4);
  border: 1px solid transparent;
  border-left-width: 3px;
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  line-height: var(--lh-normal);
  margin-bottom: var(--space-4);
}

.alert-success {
  background: var(--color-success-bg);
  border-color: var(--color-success);
  color: var(--color-success);
}

.alert-warning {
  background: var(--color-warning-bg);
  border-color: var(--color-warning);
  color: var(--color-warning);
}

.alert-danger {
  background: var(--color-danger-bg);
  border-color: var(--color-danger);
  color: var(--color-danger);
}

.alert-info {
  background: var(--color-info-bg);
  border-color: var(--color-info);
  color: var(--color-info);
}

.alert strong, .alert b {
  font-weight: var(--fw-semibold);
}

/* ─── Badges / Status ────────────────────────────────────────────────────── */

.badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px var(--space-2);
  font-size: var(--text-xs);
  font-weight: var(--fw-semibold);
  border-radius: var(--radius-full);
  line-height: 1;
}

/* Badge text uses a darker shade than the base semantic color (--color-success/-warning/etc,
   tuned for icons/borders elsewhere) - the base tones read at ~3.1-3.2:1 on their own pale
   -bg tint, short of WCAG 1.4.3's 4.5:1 for normal-size badge text. */
.badge-success {
  background: var(--color-success-bg);
  color: #0f7a37;
}

.badge-warning {
  background: var(--color-warning-bg);
  color: #a35a05;
}

.badge-danger {
  background: var(--color-danger-bg);
  color: var(--color-danger);
}

.badge-info {
  background: var(--color-info-bg);
  color: #026aa8;
}

.badge-muted {
  background: var(--color-surface-2);
  color: var(--color-text-muted);
  border: 1px solid var(--color-border);
}

.badge-primary {
  background: var(--color-primary-light);
  color: var(--color-primary);
}

.badge-secondary {
  background: var(--color-surface-2);
  color: var(--color-text-muted);
  border: 1px solid var(--color-border);
}

.status-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  display: inline-block;
  flex-shrink: 0;
}

.status-dot.active {
  background: var(--color-success);
}

.status-dot.pending {
  background: var(--color-warning);
}

.status-dot.suspended {
  background: var(--color-danger);
}

.status-dot.draft {
  background: var(--color-text-subtle);
}

/* ─── Modals ─────────────────────────────────────────────────────────────── */

.modal-content {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
}

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

.modal-title {
  font-size: var(--text-lg);
  font-weight: var(--fw-semibold);
  color: var(--color-text);
  margin: 0;
}

.modal-body {
  padding: var(--space-6);
}

.modal-footer {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-6);
  border-top: 1px solid var(--color-border);
}

/* ─── Toast Notifications ────────────────────────────────────────────────── */

#toast-container {
  position: fixed;
  bottom: var(--space-6);
  right: var(--space-6);
  z-index: var(--z-toast);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  pointer-events: none;
}

.toast-item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  min-width: 300px;
  max-width: 420px;
  pointer-events: all;
  animation: toastIn .2s ease;
}

.toast-item.hide {
  animation: toastOut .2s ease forwards;
}

@keyframes toastIn {
  from {
    opacity: 0;
    transform: translateY(12px);
  }
}

@keyframes toastOut {
  to {
    opacity: 0;
    transform: translateY(12px);
  }
}

.toast-icon i {
  font-size: 20px;
}

.toast-success .toast-icon {
  color: var(--color-success);
}

.toast-error .toast-icon {
  color: var(--color-danger);
}

.toast-warning .toast-icon {
  color: var(--color-warning);
}

.toast-info .toast-icon {
  color: var(--color-info);
}

.toast-body {
  flex: 1;
}

.toast-title {
  font-size: var(--text-sm);
  font-weight: var(--fw-semibold);
  color: var(--color-text);
  margin: 0;
}

.toast-message {
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  margin: 2px 0 0;
}

.toast-close {
  background: none;
  border: none;
  cursor: pointer;
  color: var(--color-text-subtle);
  padding: 2px;
  border-radius: var(--radius-sm);
  display: flex;
  align-items: center;
}

.toast-close:hover {
  color: var(--color-text);
  background: var(--color-surface-2);
}

/* ─── Auth Pages ─────────────────────────────────────────────────────────── */

.auth-page {
  min-height: 100vh;
  background: var(--auth-page-bg);
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: var(--space-6);
}

.auth-container {
  width: 100%;
  max-width: 440px;
  padding: var(--space-8) var(--space-4);
  margin: auto 0;
}

/* Brand crest + name lockup above the auth card */
.auth-logo {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-decoration: none;
  margin-bottom: var(--space-8);
}

.auth-crest-img {
  width: var(--auth-crest-size);
  max-height: var(--auth-crest-size);
  object-fit: contain;
  margin-bottom: var(--space-3);
}

.auth-brand-name {
  color: var(--auth-brand-color);
  font-size: var(--text-xl);
  font-weight: var(--fw-bold);
  letter-spacing: 0.05em;
  text-align: center;
}

.auth-brand-sub {
  color: var(--auth-sub-color);
  font-size: var(--text-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-align: center;
  margin-top: 2px;
}

.auth-card {
  background: var(--auth-card-bg);
  border-radius: var(--auth-card-radius);
  padding: var(--space-8);
  box-shadow: var(--auth-card-shadow);
}

.auth-heading {
  font-size: var(--text-2xl);
  font-weight: var(--fw-bold);
  color: var(--color-primary);
  margin: 0 0 var(--space-2);
}

.auth-subtext {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  margin: 0 0 var(--space-6);
}

/* Override Bootstrap btn-primary to use brand navy in auth context */
.auth-card .btn-primary {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: #ffffff;
}

.auth-card .btn-primary:hover {
  background: var(--color-primary-hover);
  border-color: var(--color-primary-hover);
}

.auth-card .text-primary {
  color: var(--color-accent-text-on-light) !important;
}

.auth-card a.text-primary:hover {
  color: var(--color-accent) !important;
}

.auth-divider {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin: var(--space-5) 0;
  color: var(--color-text-subtle);
  font-size: var(--text-xs);
}

.auth-divider::before, .auth-divider::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--color-border);
}

.auth-footer {
  width: 100%;
  text-align: center;
  margin-top: auto;
  padding-top: var(--space-5);
  font-size: var(--text-sm);
  color: var(--auth-footer-color);
}

.auth-footer a {
  color: var(--auth-footer-link);
  text-decoration: none;
  font-weight: var(--fw-semibold);
}

.auth-footer a:hover {
  text-decoration: underline;
}

.auth-footer-links {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin-top: var(--space-6);
}

.auth-footer-links .app-footer-link {
  color: var(--auth-footer-color);
}

.auth-footer-links .app-footer-link:hover,
.auth-footer-links .app-footer-link:focus-visible {
  color: var(--auth-footer-link);
}

/* ─── Empty State ────────────────────────────────────────────────────────── */

.empty-state {
  text-align: center;
  padding: var(--space-16) var(--space-8);
  color: var(--color-text-muted);
}

.empty-state i {
  font-size: 48px;
  color: var(--color-text-subtle);
  margin-bottom: var(--space-4);
}

.empty-state-title {
  font-size: var(--text-lg);
  font-weight: var(--fw-semibold);
  color: var(--color-text);
  margin: 0 0 var(--space-2);
}

.empty-state-text {
  font-size: var(--text-sm);
  margin: 0 0 var(--space-6);
}

/* ─── Loading ────────────────────────────────────────────────────────────── */

.skeleton {
  background: linear-gradient(90deg, var(--color-border) 25%, var(--color-surface-2) 50%, var(--color-border) 75%);
  background-size: 200% 100%;
  animation: skeleton-shimmer 1.5s infinite;
  border-radius: var(--radius-sm);
}

@keyframes skeleton-shimmer {
  to {
    background-position: -200% 0;
  }
}

.spinner-sm {
  width: 16px;
  height: 16px;
  border: 2px solid var(--color-border);
  border-top-color: var(--color-primary);
  border-radius: 50%;
  animation: spin .6s linear infinite;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

/* ─── Dropdown ───────────────────────────────────────────────────────────── */

.dropdown-menu {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: var(--space-2);
  min-width: 180px;
}

.dropdown-item {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  color: var(--color-text);
  cursor: pointer;
  transition: background var(--transition-base);
  text-decoration: none;
  border: none;
  background: none;
  width: 100%;
}

.dropdown-item:hover {
  background: var(--color-surface-2);
  text-decoration: none;
  color: var(--color-text);
}

.dropdown-item.danger {
  color: var(--color-danger);
}

.dropdown-item.danger:hover {
  background: var(--color-danger-bg);
}

.dropdown-divider {
  height: 1px;
  background: var(--color-border);
  margin: var(--space-2) 0;
}

.dropdown-item i {
  font-size: 16px;
  color: var(--color-text-muted);
}

/* Admin topbar menu - 15 items is too tall for very short viewports without a scroll cap. */
.admin-menu {
  max-height: 70vh;
  overflow-y: auto;
}

/* ─── Code Editor ────────────────────────────────────────────────────────── */

.code-editor {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  background: #0f172a;
  color: #e2e8f0;
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border);
  padding: var(--space-4);
  resize: vertical;
  min-height: 200px;
}

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

@media (max-width: 768px) {
  #sidebar {
    transform: translateX(-100%);
    transition: transform var(--transition-slow);
  }

  #sidebar.mobile-open {
    transform: translateX(0);
  }

  .page-wrapper {
    margin-left: 0;
  }

  .page-content {
    padding: var(--space-4);
  }

  .page-header {
    flex-direction: column;
  }
}

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

.text-muted {
  color: var(--color-text-muted) !important;
}

.text-subtle {
  color: var(--color-text-subtle) !important;
}

.text-primary {
  color: var(--color-primary) !important;
}

.text-success {
  color: var(--color-success) !important;
}

.text-danger {
  color: var(--color-danger) !important;
}

.text-warning {
  color: var(--color-warning) !important;
}

.fw-medium {
  font-weight: var(--fw-medium);
}

.fw-semibold {
  font-weight: var(--fw-semibold);
}

.fw-bold {
  font-weight: var(--fw-bold);
}

.truncate {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.divider {
  height: 1px;
  background: var(--color-border);
  margin: var(--space-5) 0;
}

.overlay-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, .5);
  z-index: calc(var(--z-modal) - 1);
}

.overlay-backdrop.hidden {
  display: none;
}

/* ─── Header Utility Classes ─────────────────────────────────────────────── */

.icon-xs {
  font-size: 14px;
}

.icon-sm {
  font-size: 16px;
}

.icon-md {
  font-size: 20px;
}

.icon-lg {
  font-size: 32px;
}

.icon-2xl {
  font-size: 48px;
}

.icon-3xl {
  font-size: 64px;
}

.icon-xl {
  font-size: 72px;
}

/* ─── Stat Card Colour Variants ──────────────────────────────────────────── */

.stat-icon--navy {
  background: var(--stat-navy-bg);
  color: var(--stat-navy-color);
}

.stat-icon--gold {
  background: var(--stat-gold-bg);
  color: var(--stat-gold-color);
}

.stat-icon--red {
  background: var(--stat-red-bg);
  color: var(--stat-red-color);
}

.stat-icon--green {
  background: var(--stat-green-bg);
  color: var(--stat-green-color);
}

.stat-icon--blue {
  background: var(--stat-blue-bg);
  color: var(--stat-blue-color);
}

.stat-icon--amber {
  background: var(--stat-amber-bg);
  color: var(--stat-amber-color);
}

/* ─── Module Shortcut Tiles ──────────────────────────────────────────────── */

.module-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3);
  border-radius: var(--radius-md);
  text-decoration: none;
  transition: all var(--transition-base);
}

.module-tile:hover {
  text-decoration: none;
  filter: brightness(0.95);
}

.module-tile--navy {
  background: var(--module-tile-bg);
}

.module-tile--gold {
  background: var(--module-tile-bg-gold);
}

.module-tile--green {
  background: var(--module-tile-bg-green);
}

.module-tile--blue {
  background: var(--module-tile-bg-blue);
}

.module-tile--disabled {
  opacity: var(--module-tile-disabled-opacity);
  pointer-events: none;
  cursor: not-allowed;
}

.module-tile__icon {
  font-size: 32px;
}

.module-tile__icon--navy {
  color: var(--color-navy-700);
}

.module-tile__icon--gold {
  color: var(--color-gold-700);
}

.module-tile__icon--green {
  color: var(--color-success);
}

.module-tile__icon--blue {
  color: var(--color-info);
}

.module-tile__label {
  font-size: var(--text-sm);
  font-weight: var(--fw-semibold);
}

.module-tile__label--navy {
  color: var(--color-navy-700);
}

.module-tile__label--gold {
  color: var(--color-gold-700);
}

.module-tile__label--green {
  color: var(--color-success);
}

.module-tile__label--blue {
  color: var(--color-info);
}

/* ─── Quick Action Nav Items ─────────────────────────────────────────────── */

.quick-action-nav {
  color: var(--color-text);
}

.quick-action-icon--navy {
  color: var(--color-navy-700);
}

.quick-action-icon--gold {
  color: var(--color-gold-700);
}

.quick-action-icon--red {
  color: var(--color-danger);
}

/* ─── Dashboard Phase Badge ──────────────────────────────────────────────── */

.badge-navy {
  background: var(--color-navy-700);
  color: #ffffff;
  font-size: var(--text-xs);
}

/* ─── Skin Selector ──────────────────────────────────────────────────────── */

.skin-option {
  cursor: pointer;
  padding: var(--space-3);
  border: 2px solid var(--color-border);
  border-radius: var(--radius-md);
  text-align: center;
  transition: border-color var(--transition-fast);
}

.skin-option.selected,
.skin-option--selected {
  border-color: var(--color-primary);
}

.skin-option__swatch {
  width: 40px;
  height: 40px;
  border-radius: var(--radius-sm);
  margin: 0 auto var(--space-2);
  background: var(--swatch-color, var(--color-primary));
}

.skin-option__label {
  font-size: 0.75rem;
  font-weight: 500;
}

/* ─── Filter Toolbar ─────────────────────────────────────────────────────── */

.filter-toolbar__input {
  max-width: 260px;
}

.filter-toolbar__input--sm {
  max-width: 200px;
}

.filter-toolbar__select {
  max-width: 160px;
}

.filter-toolbar__select--sm {
  max-width: 140px;
}

.filter-toolbar__date {
  max-width: 160px;
}

/* ─── Theme Selector ─────────────────────────────────────────────────────── */

.theme-option {
  cursor: pointer;
  border-radius: var(--radius-md) !important;
}

.theme-option--selected {
  border-color: var(--color-primary) !important;
}

.theme-option__icon--warning {
  color: var(--color-warning);
}

/* ─── Permissions List ───────────────────────────────────────────────────── */

.permissions-list {
  max-height: 360px;
  overflow-y: auto;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  padding: var(--space-4);
}

/* ─── Avatar Placeholder ─────────────────────────────────────────────────── */

.avatar-placeholder {
  width: 80px;
  height: 80px;
  font-size: 32px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--color-surface);
  color: var(--color-text-muted);
}

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

.text-xs {
  font-size: 0.75rem;
}

/* ─── Panels (index2.html card idiom) ───────────────────────────────────── */
/* A lighter-weight sibling of .card: square-ish corners, hairline border,
   subtle shadow, an optional heading bar. Used across every re-skinned page. */

.panel {
  background: var(--panel-bg);
  border-radius: var(--panel-radius);
  box-shadow: var(--panel-shadow);
  margin-bottom: var(--space-5);
}

/* Subtle glass treatment - opt in with .panel.glass (see .info-block.glass). */
.panel.glass {
  background: var(--glass-bg);
  border: 1px solid var(--glass-border);
  box-shadow: var(--glass-shadow);
  -webkit-backdrop-filter: blur(var(--glass-blur));
  backdrop-filter: blur(var(--glass-blur));
}

/* Wraps a page's content to give .glass panels/info-blocks something to blur
   against - a flat single-color background behind backdrop-filter just looks
   like a tinted solid, not glass. Scoped per-page (not body-wide) so pages
   that don't opt in pay no extra paint cost. */
.dash-backdrop {
  background-image: var(--dash-backdrop);
  background-attachment: fixed;
}

.panel-heading {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--panel-heading-pad);
  background: var(--panel-heading-bg);
  border-radius: var(--panel-radius) var(--panel-radius) 0 0;
}

.panel-heading.panel-heading-bb {
  border-bottom: 1px solid var(--panel-border);
  padding-bottom: var(--space-4);
}

/* Optional leading icon, as in DESIGN/index.html's `.panel-heading > i`. */
.panel-heading > i {
  font-size: 25px;
  line-height: 1;
  color: var(--info-block-icon-color);
  flex: none;
}

/* A panel-heading that hosts a tab strip instead of a title (e.g. profile.php's
   7-card-to-tabs conversion) - the tab list's own bottom border replaces the
   heading's, and it needs to run edge-to-edge rather than sit flex-centred. */
.panel-heading:has(.nav-tabs) {
  padding-bottom: 0;
  border-bottom: none;
  display: block;
}

.panel-heading .nav-tabs {
  margin-bottom: -1px;
}

.panel-title {
  font-size: var(--panel-title-size);
  font-weight: var(--panel-title-weight);
  color: var(--color-text);
  margin: 0;
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.panel-title .panel-subtitle {
  font-size: var(--text-xs);
  font-weight: var(--fw-normal);
  color: var(--color-text-muted);
}

.panel-heading-actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.panel-body {
  padding: var(--panel-body-pad);
}

.panel-body.pn {
  padding: 0;
}

.panel-body.tight {
  padding: var(--space-3) var(--space-4);
}

.panel-footer {
  padding: var(--space-3) var(--space-5);
  border-top: 1px solid var(--panel-border);
  background: var(--color-surface-2);
  border-radius: 0 0 var(--panel-radius) var(--panel-radius);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

/* A panel that wraps a table edge-to-edge (no body padding, rounded clip). */
.panel.panel-table {
  overflow: hidden;
}

.panel.panel-table .table {
  margin: 0;
}

/* ─── Dashboard Grid & Primitives ───────────────────────────────────────── */

.dash-grid {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: var(--space-5);
  align-items: start;
}

.dash-grid>.col-3 {
  grid-column: span 3;
}

.dash-grid>.col-4 {
  grid-column: span 4;
}

.dash-grid>.col-5 {
  grid-column: span 5;
}

.dash-grid>.col-6 {
  grid-column: span 6;
}

.dash-grid>.col-7 {
  grid-column: span 7;
}

.dash-grid>.col-8 {
  grid-column: span 8;
}

.dash-grid>.col-9 {
  grid-column: span 9;
}

.dash-grid>.col-12 {
  grid-column: span 12;
}

@media (max-width: 1200px) {
  .dash-grid>.col-3, .dash-grid>.col-4, .dash-grid>.col-5 {
    grid-column: span 6;
  }
}

@media (max-width: 768px) {
  .dash-grid {
    gap: var(--space-4);
  }

  .dash-grid>* {
    grid-column: span 12 !important;
  }
}

/* KPI tile: label, big value, delta, optional mini spark row. */
.kpi-tile {
  background: var(--panel-bg);
  border-radius: var(--panel-radius);
  box-shadow: var(--panel-shadow);
  padding: var(--space-4) var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-height: 140px;
  height: 100%;
}

.kpi-tile .kpi-label {
  font-size: var(--text-xs);
  font-weight: var(--fw-semibold);
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--color-text-muted);
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.kpi-tile .kpi-label i {
  font-size: 15px;
  color: var(--color-accent);
}

.kpi-tile .kpi-value {
  font-size: var(--text-3xl);
  font-weight: var(--fw-bold);
  color: var(--color-text);
  line-height: 1.1;
}

.kpi-tile .kpi-value.sm {
  font-size: var(--text-2xl);
}

.kpi-tile .kpi-delta {
  font-size: var(--text-xs);
  font-weight: var(--fw-medium);
  display: flex;
  align-items: center;
  gap: 3px;
}

.kpi-tile .kpi-delta.up {
  color: var(--color-success);
}

.kpi-tile .kpi-delta.down {
  color: var(--color-danger);
}

.kpi-tile .kpi-delta.flat {
  color: var(--color-text-subtle);
}

/* Accent stripe variants (left border). */
.kpi-tile.accent-navy {
  border-left: 3px solid var(--color-navy-700);
}

.kpi-tile.accent-gold {
  border-left: 3px solid var(--color-blue-700);
}

.kpi-tile.accent-green {
  border-left: 3px solid var(--color-success);
}

.kpi-tile.accent-red {
  border-left: 3px solid var(--color-danger);
}

.kpi-tile.accent-blue {
  border-left: 3px solid var(--color-info);
}

.kpi-tile.accent-amber {
  border-left: 3px solid var(--color-warning);
}

/* Chart container: fixed responsive height, canvas fills it. */
.chart-box {
  position: relative;
  width: 100%;
}

.chart-box.h-sm {
  height: 180px;
}

.chart-box.h-md {
  height: 260px;
}

.chart-box.h-lg {
  height: 340px;
}

.chart-box>canvas {
  position: absolute;
  inset: 0;
}

/* Gauge wrapper with a centred value overlay. */
.gauge-wrap {
  position: relative;
  width: 100%;
  height: 200px;
}

.gauge-wrap .gauge-center {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 28%;
  text-align: center;
}

.gauge-wrap .gauge-center .gauge-value {
  font-size: var(--text-3xl);
  font-weight: var(--fw-bold);
  color: var(--color-text);
  line-height: 1;
}

.gauge-wrap .gauge-center .gauge-unit {
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  text-transform: uppercase;
  letter-spacing: .05em;
}

/* Metric list: label / value rows inside a panel body. */
.metric-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.metric-list .metric-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  font-size: var(--text-sm);
}

.metric-list .metric-row .metric-name {
  color: var(--color-text-muted);
}

.metric-list .metric-row .metric-num {
  font-weight: var(--fw-semibold);
  color: var(--color-text);
  font-variant-numeric: tabular-nums;
}

.metric-list .metric-row .metric-num.pos {
  color: var(--color-success);
}

.metric-list .metric-row .metric-num.neg {
  color: var(--color-danger);
}

/* AR-ageing horizontal stacked bar (pure CSS, no chart). */
.ageing-bar {
  display: flex;
  height: 12px;
  border-radius: var(--radius-full);
  overflow: hidden;
  background: var(--color-border-light);
}

.ageing-bar>span {
  display: block;
  height: 100%;
}

.ageing-bar>.b-current {
  background: var(--color-success);
}

.ageing-bar>.b-30 {
  background: var(--color-warning);
}

.ageing-bar>.b-60 {
  background: var(--color-gold-700);
}

.ageing-bar>.b-90 {
  background: var(--color-danger);
}

.legend-dots {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-3);
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}

.legend-dots>span {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.legend-dots>span::before {
  content: "";
  width: 10px;
  height: 10px;
  border-radius: 3px;
  background: currentColor;
}

.legend-dots .d-current::before {
  background: var(--color-success);
}

.legend-dots .d-30::before {
  background: var(--color-warning);
}

.legend-dots .d-60::before {
  background: var(--color-gold-700);
}

.legend-dots .d-90::before {
  background: var(--color-danger);
}

/* Compliance / statutory calendar rows. */
.due-list {
  display: flex;
  flex-direction: column;
}

.due-list .due-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--color-border-light);
  font-size: var(--text-sm);
}

.due-list .due-row:last-child {
  border-bottom: none;
}

.due-list .due-row .due-tag {
  font-size: var(--text-xs);
  font-weight: var(--fw-bold);
  padding: 2px var(--space-2);
  border-radius: var(--radius-sm);
  background: var(--color-primary-light);
  color: var(--color-primary);
  min-width: 56px;
  text-align: center;
}

.due-list .due-row .due-when {
  margin-left: auto;
  color: var(--color-text-muted);
  font-variant-numeric: tabular-nums;
}

.due-list .due-row.is-soon .due-when {
  color: var(--color-warning);
  font-weight: var(--fw-semibold);
}

.due-list .due-row.is-overdue .due-when {
  color: var(--color-danger);
  font-weight: var(--fw-semibold);
}

/* ─── Print Styles ───────────────────────────────────────────────────────── */

@media print {
  #sidebar, .topbar, #toast-container, .no-print {
    display: none !important;
  }

  .page-wrapper {
    margin-left: 0 !important;
  }

  body {
    font-size: 11pt;
    color: #000;
    background: #fff;
  }

  .card, .panel {
    border: 1px solid #ccc;
    page-break-inside: avoid;
  }

  a[href]::after {
    content: " ("attr(href) ")";
  }

  h1, h2, h3 {
    page-break-after: avoid;
  }
}

/* ─── Marketing Landing Page ─────────────────────────────────────────────── */

.marketing-page {
  background: var(--color-surface);
}

.marketing-container {
  max-width: 1140px;
  margin: 0 auto;
  padding: 0 var(--space-5);
}

.marketing-nav {
  border-bottom: 1px solid var(--color-border);
  background: var(--color-surface);
}

.marketing-nav-inner {
  max-width: 1140px;
  margin: 0 auto;
  padding: var(--space-4) var(--space-5);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
}

.marketing-nav-logo {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  text-decoration: none;
  font-weight: var(--fw-bold);
  font-size: var(--text-lg);
  color: var(--color-text);
}

.marketing-nav-logo img {
  width: 32px;
  height: 32px;
  object-fit: contain;
}

.marketing-nav-actions {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.marketing-hero {
  background: var(--color-navy-800);
  padding: var(--space-8) 0;
  text-align: center;
}

.marketing-hero h1 {
  color: #ffffff;
  font-size: var(--text-4xl);
  font-weight: var(--fw-bold);
  max-width: 780px;
  margin: 0 auto var(--space-4);
}

.marketing-hero-subtitle {
  color: rgba(255, 255, 255, 0.75);
  font-size: var(--text-lg);
  max-width: 640px;
  margin: 0 auto var(--space-6);
}

.marketing-hero-actions {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.marketing-features {
  padding: var(--space-8) 0;
}

.marketing-features h2,
.marketing-cta h2 {
  text-align: center;
  font-size: var(--text-2xl);
  font-weight: var(--fw-bold);
  color: var(--color-text);
  margin-bottom: var(--space-3);
}

.marketing-section-subtitle {
  text-align: center;
  color: var(--color-text-muted);
  max-width: 640px;
  margin: 0 auto var(--space-6);
}

.marketing-feature-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-5);
}

@media (max-width: 900px) {
  .marketing-feature-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 600px) {
  .marketing-feature-grid {
    grid-template-columns: 1fr;
  }

  .marketing-hero h1 {
    font-size: var(--text-2xl);
  }
}

.marketing-feature-card {
  background: var(--panel-bg);
  border-radius: var(--panel-radius);
  box-shadow: var(--panel-shadow);
  padding: var(--space-5);
}

.marketing-feature-icon {
  font-size: 2rem;
  color: var(--color-blue-600);
  margin-bottom: var(--space-3);
  display: block;
}

.marketing-feature-card h3 {
  font-size: var(--text-md);
  font-weight: var(--fw-semibold);
  color: var(--color-text);
  margin-bottom: var(--space-2);
}

.marketing-feature-card p {
  color: var(--color-text-muted);
  font-size: var(--text-sm);
  margin: 0;
}

.marketing-cta {
  background: var(--color-bg);
  padding: var(--space-8) 0;
  text-align: center;
  border-top: 1px solid var(--color-border);
}

.marketing-cta p {
  color: var(--color-text-muted);
  max-width: 560px;
  margin: 0 auto var(--space-6);
}

/* ─── Layout 1 dashboard (DESIGN/index.html) ────────────────────────────── */

.greeting-field {
  font-size: var(--greeting-size);
  font-weight: var(--greeting-weight);
  line-height: var(--lh-tight);
  letter-spacing: .01em;
  color: var(--greeting-color);
  margin: 0 0 var(--space-5);
}

.greeting-field span {
  color: var(--color-text);
  font-weight: var(--fw-normal);
}

/* Icon + title row, oversized number, caption. */
.info-block {
  background: var(--panel-bg);
  border-radius: var(--panel-radius);
  box-shadow: var(--panel-shadow);
  padding: var(--space-5) var(--space-6) var(--space-6);
  text-align: center;
  width: 100%;
  height: 100%;
  min-height: 170px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  transition: box-shadow var(--transition-base), transform var(--transition-base);
  box-sizing: border-box;
}

/* Subtle glass treatment - opt in with .info-block.glass. Needs --dash-backdrop
   (or any non-flat background) behind it to actually read as glass; on a flat
   --color-bg page it just looks like a slightly lighter panel, which is fine. */
.info-block.glass {
  background: var(--glass-bg);
  border: 1px solid var(--glass-border);
  box-shadow: var(--glass-shadow);
  -webkit-backdrop-filter: blur(var(--glass-blur));
  backdrop-filter: blur(var(--glass-blur));
}

@media (hover: hover) {
  .info-block.glass:hover {
    box-shadow: var(--shadow-lg);
    transform: translateY(-2px);
  }
}

.info-block .info-block-top {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  text-align: left;
  min-width: 0;
}

.info-block .info-block-top i {
  font-size: 28px;
  line-height: 1;
  color: var(--info-block-icon-color);
  flex-shrink: 0;
}

.info-block .info-block-top .title {
  flex: 1 1 auto;
  font-size: var(--text-md);
  font-weight: var(--fw-medium);
  color: var(--color-text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}

.info-block .info-block-number {
  font-size: clamp(var(--text-3xl), 2.6vw, var(--info-block-number-size));
  font-weight: var(--fw-light);
  line-height: 1.1;
  color: var(--info-block-number-color);
  margin: var(--space-4) 0 0;
  white-space: nowrap;
}

.info-block .info-block-number.is-empty {
  color: var(--color-text-subtle);
  font-size: var(--text-3xl);
}

.info-block .info-block-caption {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  margin: var(--space-1) 0 0;
}

/* Large rounded progress bar with the template's gradient fills. */
.progress-lg {
  height: var(--progress-lg-height);
  border-radius: var(--radius-full);
  background: var(--color-surface-2);
  overflow: hidden;
  margin-bottom: var(--space-4);
}

.progress-lg .progress-bar {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  padding: 0 var(--space-3);
  font-size: var(--text-sm);
  font-weight: var(--fw-bold);
  color: var(--color-navy-900);
  white-space: nowrap;
}

.progress-bar-gradient-primary {
  background: var(--gradient-primary);
}

.progress-bar-gradient-info {
  background: var(--gradient-info);
}

.progress-bar-gradient-danger {
  background: var(--gradient-danger);
}

.progress-bar-gradient-alert {
  background: var(--gradient-alert);
}

/* Dark surfaces: white on the bright teal fill is only 2.9:1, so flip to the ink colour. */
[data-theme="dark"] .btn-primary {
  color: var(--color-navy-900);
}

[data-theme="dark"] .btn-primary:hover {
  color: var(--color-navy-900);
}
