@charset "UTF-8";
/* ============================================================================
   AptaOps theme layer — the "Aperture" design system
   ----------------------------------------------------------------------------
   Loads AFTER materia.custom.css and BEFORE the per-tenant
   wwwroot/company/{registrationId}/assets/css/default.css, so a customer's own
   brand colour and logo still win. Nothing here touches markup: it retargets
   the Bootstrap custom properties the Materia theme already reads, then adds
   component rules where the design differs from Materia's defaults.

   Source of truth: design_handoff_aptaops_identity/tokens/tokens.css and the
   component tables in that bundle's README.

   Two deliberate departures from the handoff, both because this is a dense
   operations portal rather than the marketing site:

   1. Base font size stays at Materia's 14px. The handoff's own product screens
      specify 14px names, 13px mono data and 15px card headers; its 16px body is
      for marketing prose. Raising the base would reflow all 125 views.
   2. The sidebar keeps Materia's icon rail plus fly-out rather than becoming
      the handoff's 232px labelled column. The design language is applied to the
      rail we have: primary-deep fill, copper active marker, mono group labels.
   ========================================================================== */

/* ---------------------------------------------------------------------------
   1. Tokens
   ------------------------------------------------------------------------- */
:root,
[data-bs-theme="light"] {
    /* Brand */
    --apta-primary: #0F4C4A;
    --apta-primary-deep: #0A3433;
    --apta-primary-hover: #0A3433;
    --apta-secondary: #2B3238;
    --apta-accent: #B4762F;
    --apta-accent-hover: #9C641F;
    --apta-accent-text: #8A5B1E;
    --apta-dark: #0B1417;

    /* Neutrals */
    --apta-bg: #F6F7F5;
    --apta-surface: #FFFFFF;
    --apta-surface-sunken: #EDEFEA;
    --apta-surface-sunken-hover: #E3E6E1;
    --apta-border: #D8DCD6;
    --apta-border-subtle: #EDEFEA;
    --apta-border-strong: #B9BFB7;

    /* Text */
    --apta-text: #101A1A;
    --apta-text-body: #3C4A48;
    --apta-text-muted: #5C6866;
    --apta-text-disabled: #9AA5A2;
    --apta-text-on-primary: #FFFFFF;

    /* Status */
    --apta-success: #157F4E;
    --apta-success-tint: #E6F2EB;
    --apta-success-text: #0E5B38;
    --apta-warning: #C9910B;
    --apta-warning-tint: #FBF2DC;
    --apta-warning-text: #7A5905;
    --apta-error: #B3261E;
    --apta-error-tint: #F9E7E5;
    --apta-error-text: #8C1D17;
    --apta-info: #1D6E77;
    --apta-info-tint: #E4EFF0;
    --apta-info-text: #134E55;

    /* Disabled control */
    --apta-disabled-bg: #F1F2EF;
    --apta-disabled-border: #E3E6E1;

    /* Type */
    --apta-font-sans: "IBM Plex Sans", "Segoe UI", system-ui, sans-serif;
    --apta-font-mono: "IBM Plex Mono", ui-monospace, "Cascadia Mono", Consolas, monospace;

    /* Radius — 2px controls and badges, 3px cards and panels. Nothing else. */
    --apta-radius-sm: 2px;
    --apta-radius-md: 3px;

    /* Spacing, 8px base */
    --apta-space-1: 4px;
    --apta-space-2: 8px;
    --apta-space-3: 12px;
    --apta-space-4: 16px;
    --apta-space-5: 24px;
    --apta-space-6: 32px;
    --apta-space-7: 44px;
    --apta-space-8: 64px;

    /* The only box-shadow in the system */
    --apta-focus-ring: 0 0 0 2px var(--apta-surface), 0 0 0 4px var(--apta-accent);

    /* Colour-only transitions. No motion on layout. */
    --apta-transition: 120ms ease-out;
}

[data-bs-theme="dark"] {
    --apta-bg: #0B1417;
    --apta-surface: #132125;
    --apta-surface-sunken: #0B1417;
    --apta-surface-sunken-hover: #1B2C31;
    --apta-border: #26383B;
    --apta-border-subtle: #1B2C31;
    --apta-border-strong: #354548;

    --apta-primary: #4FA39D;
    --apta-primary-deep: #0A3433;
    --apta-primary-hover: #6FB8B2;
    --apta-accent: #C98C3E;
    --apta-accent-hover: #D8A45C;
    --apta-accent-text: #D8A45C;

    --apta-text: #E8EDEB;
    --apta-text-body: #CFDCD9;
    --apta-text-muted: #9CB0AD;
    --apta-text-disabled: #6C807D;
    --apta-text-on-primary: #06201F;

    --apta-success: #34A56F;
    --apta-success-tint: #122A20;
    --apta-success-text: #7FD3A8;
    --apta-warning: #E0AE2E;
    --apta-warning-tint: #2C2410;
    --apta-warning-text: #EBC96E;
    --apta-error: #D6483F;
    --apta-error-tint: #2E1512;
    --apta-error-text: #EE8C85;
    --apta-info: #3A939C;
    --apta-info-tint: #12262A;
    --apta-info-text: #7FC3CA;

    --apta-disabled-bg: #17272B;
    --apta-disabled-border: #26383B;

    --apta-focus-ring: 0 0 0 2px var(--apta-bg), 0 0 0 4px var(--apta-accent);
}

/* ---------------------------------------------------------------------------
   2. Bootstrap remap
   ---------------------------------------------------------------------------
   Materia reads these throughout, so redefining them re-skins most of the app
   without a single markup change.
   ------------------------------------------------------------------------- */
:root,
[data-bs-theme="light"],
[data-bs-theme="dark"] {
    --bs-font-sans-serif: var(--apta-font-sans);
    --bs-font-monospace: var(--apta-font-mono);
    --bs-body-font-family: var(--apta-font-sans);

    --bs-primary: var(--apta-primary);
    --bs-secondary: var(--apta-secondary);
    --bs-success: var(--apta-success);
    --bs-warning: var(--apta-warning);
    --bs-danger: var(--apta-error);
    --bs-info: var(--apta-info);
    --bs-light: var(--apta-surface-sunken);
    --bs-dark: var(--apta-dark);

    --bs-body-bg: var(--apta-bg);
    --bs-body-color: var(--apta-text-body);
    --bs-emphasis-color: var(--apta-text);
    --bs-heading-color: var(--apta-text);
    --bs-secondary-color: var(--apta-text-muted);
    --bs-border-color: var(--apta-border);
    --bs-border-color-translucent: var(--apta-border);

    --bs-link-color: var(--apta-primary);
    --bs-link-hover-color: var(--apta-primary-hover);

    /* 3px is the largest radius in the system. Materia ships .5rem/.75rem. */
    --bs-border-radius: var(--apta-radius-md);
    --bs-border-radius-sm: var(--apta-radius-sm);
    --bs-border-radius-lg: var(--apta-radius-md);
    --bs-border-radius-xl: var(--apta-radius-md);
    --bs-border-radius-2xl: var(--apta-radius-md);

    /* Materia's own surface tokens */
    --bs-theme-component-bg: var(--apta-surface);
    --bs-theme-popup-bg: var(--apta-surface);
    --bs-theme-popup-hover-bg: var(--apta-surface-sunken);
    --bs-theme-list-hover-bg: var(--apta-bg);
    --bs-theme-body-highlight-bg: var(--apta-surface-sunken);
    --bs-secondary-bg: var(--apta-surface-sunken);
    --bs-tertiary-bg: var(--apta-bg);

    --bs-card-bg: var(--apta-surface);
    --bs-card-border-color: var(--apta-border);
    --bs-card-box-shadow: none;
}

:root,
[data-bs-theme="light"] {
    --bs-primary-rgb: 15, 76, 74;
    --bs-secondary-rgb: 43, 50, 56;
    --bs-success-rgb: 21, 127, 78;
    --bs-warning-rgb: 201, 145, 11;
    --bs-danger-rgb: 179, 38, 30;
    --bs-info-rgb: 29, 110, 119;
    --bs-body-bg-rgb: 246, 247, 245;
    --bs-body-color-rgb: 60, 74, 72;
}

[data-bs-theme="dark"] {
    --bs-primary-rgb: 79, 163, 157;
    --bs-success-rgb: 52, 165, 111;
    --bs-warning-rgb: 224, 174, 46;
    --bs-danger-rgb: 214, 72, 63;
    --bs-info-rgb: 58, 147, 156;
    --bs-body-bg-rgb: 11, 20, 23;
    --bs-body-color-rgb: 207, 220, 217;
}

/* Sidebar defaults. A tenant's own default.css loads after this file and
   overrides them, which is how customer branding survives the rebrand. */
:root {
    --cms-sidebar-bg: var(--apta-primary-deep);
    --cms-sidebar-fg: #A9C3C0;
    --cms-sidebar-fg-active: #FFFFFF;
    --cms-sidebar-highlight: rgba(255, 255, 255, .12);
    --cms-sidebar-sub-bg: #0F4C4A;
    --cms-sidebar-sub-fg: #E8EDEB;
}

/* ---------------------------------------------------------------------------
   3. Type
   ------------------------------------------------------------------------- */
body {
    font-family: var(--apta-font-sans);
    color: var(--apta-text-body);
    background-color: var(--apta-bg);
    -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, h5, h6,
.h1, .h2, .h3, .h4, .h5, .h6 {
    font-family: var(--apta-font-sans);
    color: var(--apta-text);
    font-weight: 600;
}

h1, .h1 { font-size: 40px; line-height: 1.05; letter-spacing: -.025em; }
h2, .h2 { font-size: 28px; line-height: 1.2;  letter-spacing: -.02em; }
h3, .h3 { font-size: 20px; line-height: 1.3;  letter-spacing: -.01em; }
h4, .h4 { font-size: 17px; line-height: 1.35; letter-spacing: -.01em; }
h5, .h5 { font-size: 15px; line-height: 1.4; }
h6, .h6 { font-size: 14px; line-height: 1.4; }

/* Display, for the few marketing-weight headings inside the portal */
.apta-display {
    font-size: 56px;
    line-height: 1;
    letter-spacing: -.03em;
    font-weight: 600;
    color: var(--apta-text);
}

/* Mono is for identifiers, references, dates, currency and table data.
   Never for running prose. */
.apta-mono,
.data-mono {
    font-family: var(--apta-font-mono);
    font-size: 13px;
    line-height: 1.45;
    font-variant-numeric: tabular-nums;
    color: var(--apta-text-body);
}

.apta-overline {
    font-family: var(--apta-font-mono);
    font-size: 11px;
    line-height: 1.3;
    letter-spacing: .14em;
    text-transform: uppercase;
    font-weight: 500;
    color: var(--apta-text-muted);
}

/* Numbers line up in every table, always. */
table td,
table th,
.gridjs-table td,
.gridjs-table th {
    font-variant-numeric: tabular-nums;
}

.text-muted,
.text-body-secondary {
    color: var(--apta-text-muted) !important;
}

.text-body-emphasis {
    color: var(--apta-text) !important;
}

/* Copper never carries text at its surface value: 3.1:1. This is the 5.2:1
   text variant from the handoff's accessibility rules. */
.text-accent {
    color: var(--apta-accent-text) !important;
}

/* ---------------------------------------------------------------------------
   4. Focus
   ---------------------------------------------------------------------------
   One ring, everywhere, always visible. It is the only box-shadow in the
   system, so it never competes with elevation.
   ------------------------------------------------------------------------- */
:where(a, button, input, select, textarea, [tabindex], .btn, .form-control, .form-select, .form-check-input, .choices__inner):focus-visible {
    outline: none;
    box-shadow: var(--apta-focus-ring);
}

.btn:focus,
.btn:focus-visible,
.form-control:focus,
.form-select:focus,
.form-check-input:focus,
.choices.is-focused .choices__inner {
    box-shadow: var(--apta-focus-ring);
    border-color: var(--apta-primary);
}

/* ---------------------------------------------------------------------------
   5. Elevation
   ---------------------------------------------------------------------------
   No drop shadows anywhere. Hairlines and whitespace do the separating.
   Overlays keep a shadow only because they float over arbitrary content and a
   1px hairline is not enough to detach them.
   ------------------------------------------------------------------------- */
.card,
.card-body,
.accordion-item,
.list-group,
.alert,
.nav-tabs,
.table-responsive,
.btn,
.form-control,
.form-select,
.badge,
.progress {
    box-shadow: none !important;
}

.card,
.accordion-item,
.list-group,
.alert {
    border: 1px solid var(--apta-border);
    border-radius: var(--apta-radius-md);
}

/* ---------------------------------------------------------------------------
   6. Buttons
   ------------------------------------------------------------------------- */
.btn {
    --bs-btn-border-radius: var(--apta-radius-sm);
    font-family: var(--apta-font-sans);
    font-size: 14px;
    font-weight: 600;
    letter-spacing: .01em;
    line-height: 1;
    padding: 11px 18px;
    border-radius: var(--apta-radius-sm);
    /* Written as the shorthand rather than leaning on Materia's
       --bs-btn-border-width: var(--bs-border-width). If that variable is ever
       undefined the whole shorthand is invalid at computed-value time and the
       border silently disappears, which is exactly how the secondary button
       loses its outline. */
    --bs-btn-border-width: 1px;
    border: 1px solid var(--bs-btn-border-color, transparent);
    transition: background-color var(--apta-transition), color var(--apta-transition), border-color var(--apta-transition);
}

.btn-sm {
    font-size: 13px;
    font-weight: 500;
    padding: 8px 14px;
}

.btn-lg {
    font-size: 15px;
    padding: 14px 22px;
}

.btn-primary {
    --bs-btn-bg: var(--apta-primary);
    --bs-btn-border-color: var(--apta-primary);
    --bs-btn-color: var(--apta-text-on-primary);
    --bs-btn-hover-bg: var(--apta-primary-hover);
    --bs-btn-hover-border-color: var(--apta-primary-hover);
    --bs-btn-hover-color: var(--apta-text-on-primary);
    --bs-btn-active-bg: var(--apta-primary-hover);
    --bs-btn-active-border-color: var(--apta-primary-hover);
    --bs-btn-disabled-bg: var(--apta-disabled-bg);
    --bs-btn-disabled-border-color: var(--apta-disabled-border);
    --bs-btn-disabled-color: var(--apta-text-disabled);
}

.btn-outline-primary,
.btn-secondary {
    --bs-btn-bg: var(--apta-surface);
    --bs-btn-border-color: var(--apta-primary);
    --bs-btn-color: var(--apta-primary);
    --bs-btn-hover-bg: var(--apta-surface-sunken);
    --bs-btn-hover-border-color: var(--apta-primary);
    --bs-btn-hover-color: var(--apta-primary);
    --bs-btn-active-bg: var(--apta-surface-sunken);
    --bs-btn-active-color: var(--apta-primary);
    --bs-btn-active-border-color: var(--apta-primary);
}

/* Ghost — Materia's light/secondary buttons land here */
.btn-light,
.btn-outline-light,
.btn-outline-secondary {
    --bs-btn-bg: var(--apta-surface-sunken);
    --bs-btn-border-color: var(--apta-surface-sunken);
    --bs-btn-color: var(--apta-secondary);
    --bs-btn-hover-bg: var(--apta-surface-sunken-hover);
    --bs-btn-hover-border-color: var(--apta-surface-sunken-hover);
    --bs-btn-hover-color: var(--apta-secondary);
    --bs-btn-active-bg: var(--apta-surface-sunken-hover);
    --bs-btn-active-color: var(--apta-secondary);
}

.btn-link {
    --bs-btn-color: var(--apta-primary);
    --bs-btn-hover-color: var(--apta-primary-hover);
    text-decoration: none;
    padding: 11px 0;
}

.btn-link:hover {
    text-decoration: underline;
}

/* Accent. The handoff allows copper once per view, for the single most
   consequential action. Use .btn-accent deliberately, not as a default. */
.btn-accent {
    --bs-btn-bg: var(--apta-accent);
    --bs-btn-border-color: var(--apta-accent);
    --bs-btn-color: #FFFFFF;
    --bs-btn-hover-bg: var(--apta-accent-hover);
    --bs-btn-hover-border-color: var(--apta-accent-hover);
    --bs-btn-hover-color: #FFFFFF;
    --bs-btn-active-bg: var(--apta-accent-hover);
    --bs-btn-active-color: #FFFFFF;
    background-color: var(--apta-accent);
    border-color: var(--apta-accent);
    color: #FFFFFF;
}

.btn-success { --bs-btn-bg: var(--apta-success); --bs-btn-border-color: var(--apta-success); --bs-btn-hover-bg: var(--apta-success-text); --bs-btn-hover-border-color: var(--apta-success-text); }
.btn-danger  { --bs-btn-bg: var(--apta-error);   --bs-btn-border-color: var(--apta-error);   --bs-btn-hover-bg: var(--apta-error-text);   --bs-btn-hover-border-color: var(--apta-error-text); }
.btn-warning { --bs-btn-bg: var(--apta-warning); --bs-btn-border-color: var(--apta-warning); --bs-btn-color: #101A1A; }
.btn-info    { --bs-btn-bg: var(--apta-info);    --bs-btn-border-color: var(--apta-info);    --bs-btn-color: #FFFFFF; }

.btn:disabled,
.btn.disabled {
    background-color: var(--apta-disabled-bg);
    border-color: var(--apta-disabled-border);
    color: var(--apta-text-disabled);
    opacity: 1;
}

/* ---------------------------------------------------------------------------
   7. Badges
   ------------------------------------------------------------------------- */
.badge {
    font-family: var(--apta-font-sans);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .02em;
    text-transform: uppercase;
    padding: 5px 10px;
    border-radius: var(--apta-radius-sm);
    line-height: 1.2;
}

/* Inside a table the badge sits in a 15px row, so it steps down a size. */
table .badge,
.gridjs-table .badge {
    font-size: 11px;
    padding: 4px 8px;
}

/* Status colour is never the only carrier of meaning — every badge keeps its
   text label. These are the tint/text pairs from the handoff. */
.badge.bg-success, .badge.badge-soft-success { background-color: var(--apta-success-tint) !important; color: var(--apta-success-text) !important; }
.badge.bg-warning, .badge.badge-soft-warning { background-color: var(--apta-warning-tint) !important; color: var(--apta-warning-text) !important; }
.badge.bg-danger,  .badge.badge-soft-danger  { background-color: var(--apta-error-tint)   !important; color: var(--apta-error-text)   !important; }
.badge.bg-info,    .badge.badge-soft-info    { background-color: var(--apta-info-tint)    !important; color: var(--apta-info-text)    !important; }
.badge.bg-primary, .badge.badge-soft-primary { background-color: var(--apta-primary)      !important; color: #FFFFFF !important; }
.badge.bg-secondary, .badge.badge-soft-secondary,
.badge.bg-light, .badge.badge-soft-light     { background-color: var(--apta-surface-sunken) !important; color: var(--apta-text-body) !important; }

/* Provisional, per the handoff's badge list */
.badge-provisional {
    background-color: var(--apta-surface-sunken) !important;
    color: var(--apta-text-body) !important;
}

/* ---------------------------------------------------------------------------
   8. Cards
   ------------------------------------------------------------------------- */
.card {
    background-color: var(--apta-surface);
    border: 1px solid var(--apta-border);
    border-radius: var(--apta-radius-md);
}

.card-header {
    background-color: transparent;
    border-bottom: 1px solid var(--apta-border-subtle);
    padding: 16px 20px;
    font-size: 15px;
    font-weight: 600;
    color: var(--apta-text);
}

/* The mono meta line that sits under a card title */
.card-header .card-meta {
    display: block;
    margin-top: 4px;
    font-family: var(--apta-font-mono);
    font-size: 12px;
    font-weight: 400;
    letter-spacing: 0;
    text-transform: none;
    color: var(--apta-text-muted);
}

.card-body {
    padding: 18px 20px;
}

.card-footer {
    background-color: transparent;
    border-top: 1px solid var(--apta-border-subtle);
    padding: 14px 20px;
}

/* Marks the focus item in a list of cards. One per view. */
.card-focus {
    border-top: 3px solid var(--apta-accent);
}

/* No nested cards inside cards — whitespace separates instead. */
.card .card {
    border: 0;
    background-color: transparent;
}

/* ---------------------------------------------------------------------------
   9. Tables
   ------------------------------------------------------------------------- */
.table,
.gridjs-table {
    --bs-table-bg: var(--apta-surface);
    --bs-table-color: var(--apta-text-body);
    --bs-table-border-color: var(--apta-border-subtle);
    --bs-table-hover-bg: var(--apta-bg);
    --bs-table-striped-bg: var(--apta-bg);
    font-size: 14px;
    color: var(--apta-text-body);
}

.table > thead th,
.gridjs-table th.gridjs-th {
    background-color: var(--apta-surface-sunken);
    color: var(--apta-text-body);
    font-family: var(--apta-font-mono);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: .1em;
    text-transform: uppercase;
    padding: 11px 22px;
    border-bottom: 1px solid var(--apta-border);
    border-top: 0;
}

.table > tbody > tr > td,
.gridjs-table td.gridjs-td {
    padding: 15px 22px;
    border-bottom: 1px solid var(--apta-border-subtle);
    border-top: 0;
    vertical-align: middle;
}

.table > tbody > tr:hover > td,
.gridjs-table tr:hover td.gridjs-td {
    background-color: var(--apta-bg);
    transition: background-color var(--apta-transition);
}

/* The primary cell: a 14/500 name over a mono uppercase sub-line naming the
   customer company. */
.cell-primary {
    font-size: 14px;
    font-weight: 500;
    color: var(--apta-text);
}

.cell-sub {
    display: block;
    margin-top: 3px;
    font-family: var(--apta-font-mono);
    font-size: 11px;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--apta-text-muted);
}

/* Dates, references, currency */
.cell-data {
    font-family: var(--apta-font-mono);
    font-size: 13px;
    font-variant-numeric: tabular-nums;
    color: var(--apta-text-body);
}

/* An unassigned or unresolved value asks to be looked at, so it takes the
   copper text colour rather than reading as ordinary muted content. */
.cell-unassigned {
    color: var(--apta-accent-text);
    font-weight: 500;
}

/* ---------------------------------------------------------------------------
   10. Tabs and pills
   ------------------------------------------------------------------------- */
.nav-tabs {
    border-bottom: 1px solid var(--apta-border);
}

.nav-tabs .nav-link {
    padding: 10px 14px;
    font-size: 14px;
    font-weight: 500;
    color: var(--apta-text-muted);
    border: 0;
    border-bottom: 2px solid transparent;
    border-radius: 0;
    transition: color var(--apta-transition), border-color var(--apta-transition);
}

.nav-tabs .nav-link:hover {
    color: var(--apta-text-body);
    border-bottom-color: var(--apta-border-strong);
}

.nav-tabs .nav-link.active {
    color: var(--apta-primary);
    font-weight: 600;
    background-color: transparent;
    border-bottom-color: var(--apta-primary);
}

.nav-pills .nav-link {
    border-radius: var(--apta-radius-sm);
    font-size: 14px;
    font-weight: 500;
    color: var(--apta-text-body);
}

.nav-pills .nav-link.active {
    background-color: var(--apta-primary);
    color: var(--apta-text-on-primary);
}

/* ---------------------------------------------------------------------------
   11. Forms
   ------------------------------------------------------------------------- */
.form-control,
.form-select,
.choices__inner {
    background-color: var(--apta-surface);
    border: 1px solid var(--apta-border-strong);
    border-radius: var(--apta-radius-sm);
    color: var(--apta-text);
    font-family: var(--apta-font-sans);
    font-size: 14px;
    transition: border-color var(--apta-transition), box-shadow var(--apta-transition);
}

.form-control::placeholder {
    color: var(--apta-text-disabled);
}

.form-control:disabled,
.form-select:disabled {
    background-color: var(--apta-disabled-bg);
    border-color: var(--apta-disabled-border);
    color: var(--apta-text-disabled);
}

.form-label,
.col-form-label {
    font-size: 13px;
    font-weight: 500;
    letter-spacing: .01em;
    line-height: 1.3;
    color: var(--apta-text-body);
}

.form-check-input {
    border-color: var(--apta-border-strong);
    border-radius: var(--apta-radius-sm);
}

.form-check-input:checked {
    background-color: var(--apta-primary);
    border-color: var(--apta-primary);
}

.form-switch .form-check-input {
    border-radius: 2em;
}

.input-group-text {
    background-color: var(--apta-surface-sunken);
    border: 1px solid var(--apta-border-strong);
    border-radius: var(--apta-radius-sm);
    color: var(--apta-text-body);
    font-size: 13px;
}

.invalid-feedback { color: var(--apta-error-text); }
.was-validated .form-control:invalid,
.form-control.is-invalid { border-color: var(--apta-error); }

/* ---------------------------------------------------------------------------
   12. Alerts
   ------------------------------------------------------------------------- */
.alert { border-radius: var(--apta-radius-md); padding: 14px 18px; font-size: 14px; }
.alert-success { background-color: var(--apta-success-tint); border-color: var(--apta-success); color: var(--apta-success-text); }
.alert-warning { background-color: var(--apta-warning-tint); border-color: var(--apta-warning); color: var(--apta-warning-text); }
.alert-danger  { background-color: var(--apta-error-tint);   border-color: var(--apta-error);   color: var(--apta-error-text); }
.alert-info    { background-color: var(--apta-info-tint);    border-color: var(--apta-info);    color: var(--apta-info-text); }

/* ---------------------------------------------------------------------------
   13. Chrome — topbar, sidebar rail, dropdowns, modals
   ------------------------------------------------------------------------- */
.navbar,
#header,
.app-header {
    background-color: var(--apta-surface);
    border-bottom: 1px solid var(--apta-border);
    box-shadow: none;
}

/* Group labels on the rail take the mono overline treatment. */
#sidebar .menu > li > div > span,
#sidebar .menu > li > a > span {
    font-family: var(--apta-font-mono);
    font-size: 10px;
    letter-spacing: .14em;
    text-transform: uppercase;
    font-weight: 500;
}

/* The copper marker on the active rail item. 5x5px at the right edge, the one
   place copper appears in the navigation. */
#sidebar .menu > li:has(a.active) > a,
#sidebar .menu > li:has(a.active) > div {
    position: relative;
}

#sidebar .menu > li:has(a.active) > a::after,
#sidebar .menu > li:has(a.active) > div::after {
    content: "";
    position: absolute;
    right: 6px;
    top: 50%;
    width: 5px;
    height: 5px;
    margin-top: -2.5px;
    background-color: var(--apta-accent);
}

#sidebar .menu > li > ul > li > a {
    border-radius: var(--apta-radius-sm);
    font-size: 14px;
    font-weight: 500;
}

.dropdown-menu {
    background-color: var(--apta-surface);
    border: 1px solid var(--apta-border);
    border-radius: var(--apta-radius-md);
    box-shadow: none;
    font-size: 14px;
}

.dropdown-item {
    border-radius: var(--apta-radius-sm);
    color: var(--apta-text-body);
}

.dropdown-item:hover,
.dropdown-item:focus {
    background-color: var(--apta-surface-sunken);
    color: var(--apta-text);
}

.dropdown-item.active,
.dropdown-item:active {
    background-color: var(--apta-primary);
    color: var(--apta-text-on-primary);
}

/* Overlays keep an elevation shadow: they float over arbitrary content, where
   a hairline alone does not detach them. Everything else in the system does not. */
.modal-content,
.offcanvas {
    background-color: var(--apta-surface);
    border: 1px solid var(--apta-border);
    border-radius: var(--apta-radius-md);
}

.modal-header,
.offcanvas-header {
    border-bottom: 1px solid var(--apta-border-subtle);
    padding: 16px 20px;
}

.modal-footer {
    border-top: 1px solid var(--apta-border-subtle);
    padding: 14px 20px;
}

.modal-title {
    font-size: 17px;
    font-weight: 600;
    color: var(--apta-text);
}

/* ---------------------------------------------------------------------------
   14. Misc surfaces
   ------------------------------------------------------------------------- */
.progress {
    background-color: var(--apta-surface-sunken);
    border-radius: var(--apta-radius-sm);
}

.progress-bar {
    background-color: var(--apta-primary);
}

.list-group-item {
    background-color: var(--apta-surface);
    border-color: var(--apta-border-subtle);
    color: var(--apta-text-body);
    font-size: 14px;
}

.list-group-item.active {
    background-color: var(--apta-primary);
    border-color: var(--apta-primary);
    color: var(--apta-text-on-primary);
}

.page-link {
    color: var(--apta-primary);
    border-color: var(--apta-border);
    border-radius: var(--apta-radius-sm);
    font-size: 13px;
}

.page-item.active .page-link {
    background-color: var(--apta-primary);
    border-color: var(--apta-primary);
    color: var(--apta-text-on-primary);
}

hr {
    border-color: var(--apta-border);
    opacity: 1;
}

code, kbd, pre, samp {
    font-family: var(--apta-font-mono);
}

::selection {
    background-color: var(--apta-primary);
    color: #FFFFFF;
}

/* No gradients, no glassmorphism. Strip Materia's decorative gradient fills. */
.bg-gradient {
    background-image: none !important;
}

/* ---------------------------------------------------------------------------
   15. Plugin skins
   ---------------------------------------------------------------------------
   Grid.js (mermaid theme), Choices and AlertifyJS ship their own greys and,
   in alertify's case, a blue accent. Their stylesheets load before this one,
   so a handful of rules is enough to bring them onto the palette. Structure
   and class names are untouched.
   ------------------------------------------------------------------------- */

/* --- Grid.js -------------------------------------------------------------- */
.gridjs-container {
    color: var(--apta-text-body);
    font-family: var(--apta-font-sans);
}

.gridjs-wrapper,
.gridjs-footer,
.gridjs-head {
    border-color: var(--apta-border);
    box-shadow: none;
    border-radius: var(--apta-radius-md);
    background-color: var(--apta-surface);
}

input.gridjs-input,
.gridjs-search-input {
    background-color: var(--apta-surface);
    border: 1px solid var(--apta-border-strong);
    border-radius: var(--apta-radius-sm);
    color: var(--apta-text);
    font-family: var(--apta-font-sans);
    font-size: 14px;
}

input.gridjs-input:focus,
.gridjs-search-input:focus {
    border-color: var(--apta-primary);
    box-shadow: var(--apta-focus-ring);
    outline: none;
}

.gridjs-th-content {
    font-family: var(--apta-font-mono);
    font-size: 11px;
    letter-spacing: .1em;
    text-transform: uppercase;
}

.gridjs-summary {
    font-family: var(--apta-font-mono);
    font-size: 12px;
    color: var(--apta-text-muted);
}

.gridjs-pagination .gridjs-pages button {
    background-color: var(--apta-surface);
    border: 1px solid var(--apta-border);
    border-radius: var(--apta-radius-sm);
    color: var(--apta-text-body);
    font-size: 13px;
}

.gridjs-pagination .gridjs-pages button:hover:not(:disabled) {
    background-color: var(--apta-surface-sunken);
}

.gridjs-pagination .gridjs-pages button.gridjs-currentPage,
.gridjs-pagination .gridjs-pages button:disabled.gridjs-currentPage {
    background-color: var(--apta-primary);
    border-color: var(--apta-primary);
    color: var(--apta-text-on-primary);
    font-weight: 600;
}

.gridjs-loading-bar {
    background-color: var(--apta-surface-sunken);
}

/* --- Choices -------------------------------------------------------------- */
.choices__list--dropdown,
.choices__list[aria-expanded] {
    background-color: var(--apta-surface);
    border: 1px solid var(--apta-border);
    border-radius: var(--apta-radius-sm);
    box-shadow: none;
}

.choices__list--dropdown .choices__item--selectable.is-highlighted,
.choices__list[aria-expanded] .choices__item--selectable.is-highlighted {
    background-color: var(--apta-surface-sunken);
    color: var(--apta-text);
}

.choices__list--multiple .choices__item {
    background-color: var(--apta-primary);
    border-color: var(--apta-primary);
    border-radius: var(--apta-radius-sm);
    color: var(--apta-text-on-primary);
    font-size: 13px;
}

/* --- AlertifyJS ----------------------------------------------------------- */
.ajs-dialog,
.ajs-message {
    background-color: var(--apta-surface);
    border: 1px solid var(--apta-border);
    border-radius: var(--apta-radius-md);
    color: var(--apta-text-body);
    font-family: var(--apta-font-sans);
}

.ajs-header {
    background-color: transparent;
    border-bottom: 1px solid var(--apta-border-subtle);
    color: var(--apta-text);
    font-weight: 600;
}

.ajs-footer {
    background-color: transparent;
    border-top: 1px solid var(--apta-border-subtle);
}

/* The footer buttons are bare <button>s in alertify: no padding, no border, and
   the ok button's blue is set from `.alertify .ajs-footer ...` in both alertify's
   default theme and app.min.css. Those five-class selectors outrank a shorter one
   here, so the ok label kept its blue on top of our fill. Everything below is
   prefixed with .alertify to win, and shaped to match .btn-primary and .btn-light
   so the confirm dialogs read like the rest of the portal. */
.alertify .ajs-footer {
    padding: var(--apta-space-3) var(--apta-space-5);
}

.alertify .ajs-footer .ajs-buttons .ajs-button {
    min-width: 0;
    min-height: 0;
    margin: 0 0 0 var(--apta-space-2);
    padding: 11px 18px;
    background-color: var(--apta-surface-sunken);
    border: 1px solid var(--apta-surface-sunken);
    border-radius: var(--apta-radius-sm);
    color: var(--apta-secondary);
    font-family: var(--apta-font-sans);
    font-size: 14px;
    font-weight: 600;
    letter-spacing: .01em;
    line-height: 1;
    text-transform: none;
    transition: background-color var(--apta-transition), color var(--apta-transition), border-color var(--apta-transition);
}

.alertify .ajs-footer .ajs-buttons .ajs-button:hover {
    background-color: var(--apta-surface-sunken-hover);
    border-color: var(--apta-surface-sunken-hover);
    color: var(--apta-secondary);
}

.alertify .ajs-footer .ajs-buttons .ajs-button.ajs-ok {
    background-color: var(--apta-primary);
    border-color: var(--apta-primary);
    color: var(--apta-text-on-primary);
}

.alertify .ajs-footer .ajs-buttons .ajs-button.ajs-ok:hover {
    background-color: var(--apta-primary-hover);
    border-color: var(--apta-primary-hover);
    color: var(--apta-text-on-primary);
}

.alertify .ajs-footer .ajs-buttons .ajs-button:focus-visible {
    box-shadow: var(--apta-focus-ring);
    outline: none;
}

.ajs-message.ajs-success { background-color: var(--apta-success-tint); color: var(--apta-success-text); border-color: var(--apta-success); }
.ajs-message.ajs-warning { background-color: var(--apta-warning-tint); color: var(--apta-warning-text); border-color: var(--apta-warning); }
.ajs-message.ajs-error   { background-color: var(--apta-error-tint);   color: var(--apta-error-text);   border-color: var(--apta-error); }

/* --- FullCalendar --------------------------------------------------------- */
.calendar.fc {
    --fc-border-color: var(--apta-border);
    --fc-today-bg-color: var(--apta-surface-sunken);
    --fc-event-bg-color: var(--apta-primary);
    --fc-event-border-color: var(--apta-primary);
    /* Dark, not white. diary/calendar.init.js paints every event as a 30%-alpha tint of
       its status colour with a solid left border, so the fill is always pale and white
       text disappears on it. The JS sets a dark colour inline on the event element, but
       FullCalendar applies this variable to the inner content of multi-day block events,
       where it wins. A course sitting on the Completed yellow was unreadable. */
    --fc-event-text-color: var(--apta-text);
    font-family: var(--apta-font-sans);
}

.calendar.fc .fc-col-header-cell-cushion,
.calendar.fc .fc-daygrid-day-number {
    font-family: var(--apta-font-mono);
    font-size: 12px;
    color: var(--apta-text-muted);
    text-decoration: none;
}

/* ---------------------------------------------------------------------------
   16. Signature components
   ---------------------------------------------------------------------------
   The three pieces the handoff calls the product's own: the qualification
   match meter, occupancy bars, and the registration-bracket frame. Bar radius
   is 1px here, which is the one exception to the 2px/3px rule — these are
   graphical marks, not controls, and 2px on an 8px bar reads as a lozenge.
   ------------------------------------------------------------------------- */

/* --- Match meter ---------------------------------------------------------
   One bar per qualification the course type requires, then a mono label
   reading "n / total · STATE". The state word matters as much as the colour:
   status is never carried by colour alone. */
.match-meter {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    white-space: nowrap;
}

.match-meter__bars {
    display: inline-flex;
    gap: 3px;
}

.match-meter__bar {
    display: block;
    width: 22px;
    height: 8px;
    border-radius: 1px;
    background-color: var(--apta-disabled-border);
}

.match-meter__label {
    font-family: var(--apta-font-mono);
    font-size: 12px;
    font-variant-numeric: tabular-nums;
    letter-spacing: .04em;
    color: var(--apta-text-muted);
}

.match-meter--ready .match-meter__bar--met { background-color: var(--apta-success); }
.match-meter--ready .match-meter__label { color: var(--apta-success-text); }

.match-meter--review .match-meter__bar--met { background-color: var(--apta-warning); }
.match-meter--review .match-meter__label { color: var(--apta-warning-text); }

.match-meter--blocked .match-meter__bar--met { background-color: var(--apta-error); }
.match-meter--blocked .match-meter__label { color: var(--apta-error-text); }

/* Nothing assessed: every bar stays unfilled and the label stays muted. */
.match-meter--none .match-meter__label { color: var(--apta-text-muted); }

/* Table variant — the row is 15px tall, so the bars step down with it. */
table .match-meter,
.gridjs-table .match-meter,
.match-meter--sm {
    gap: 6px;
}

table .match-meter__bar,
.gridjs-table .match-meter__bar,
.match-meter--sm .match-meter__bar {
    width: 14px;
    height: 7px;
}

table .match-meter__label,
.gridjs-table .match-meter__label,
.match-meter--sm .match-meter__label {
    font-size: 11px;
}

/* --- Occupancy bars ------------------------------------------------------
   The scheduling grid abstracted to flat blocks. Never a gradient, never 3D. */
.occupancy {
    display: flex;
    align-items: center;
    gap: 12px;
}

.occupancy__name {
    flex: 0 0 112px;
    font-size: 13px;
    color: var(--apta-text-body);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.occupancy__track {
    display: flex;
    flex: 1 1 auto;
    gap: 3px;
    min-width: 0;
}

.occupancy__block {
    flex: 1 1 0;
    height: 14px;
    border-radius: 1px;
    background-color: var(--apta-surface-sunken);
}

.occupancy__block--booked { background-color: var(--apta-primary); }
.occupancy__block--holiday { background-color: var(--apta-info-tint); }

/* The taller variant from the handoff, for a standalone scheduling strip. */
.occupancy--lg .occupancy__track { gap: 4px; }
.occupancy--lg .occupancy__block { height: 22px; }

.occupancy-legend {
    display: flex;
    gap: 16px;
    align-items: center;
    padding-top: 12px;
    margin-top: 12px;
    border-top: 1px solid var(--apta-border-subtle);
}

.occupancy-legend__item {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-family: var(--apta-font-mono);
    font-size: 11px;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--apta-text-muted);
}

.occupancy-legend__swatch {
    width: 10px;
    height: 10px;
    border-radius: 1px;
    background-color: var(--apta-surface-sunken);
}

.occupancy-legend__swatch--booked { background-color: var(--apta-primary); }
.occupancy-legend__swatch--holiday { background-color: var(--apta-info-tint); }

/* --- Registration brackets -----------------------------------------------
   The mark's two corners lifted out to frame a figure, a pull quote or an
   empty state. Opposite corners only, never all four. */
.apta-brackets {
    position: relative;
    padding: 22px 26px;
}

.apta-brackets::before,
.apta-brackets::after {
    content: "";
    position: absolute;
    width: 22px;
    height: 22px;
    border: 3px solid var(--apta-primary);
    pointer-events: none;
}

.apta-brackets::before {
    top: 0;
    left: 0;
    border-right: 0;
    border-bottom: 0;
}

.apta-brackets::after {
    right: 0;
    bottom: 0;
    border-left: 0;
    border-top: 0;
}

.apta-brackets--accent::before,
.apta-brackets--accent::after {
    border-color: var(--apta-accent);
}

.apta-brackets--muted::before,
.apta-brackets--muted::after {
    border-color: var(--apta-border-strong);
}

/* --- Empty state ---------------------------------------------------------- */
.empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 6px;
    margin: 24px auto;
    max-width: 420px;
}

.empty-state__title {
    font-size: 15px;
    font-weight: 600;
    color: var(--apta-text);
}

.empty-state__body {
    font-size: 14px;
    color: var(--apta-text-muted);
}

.empty-state__action {
    margin-top: 10px;
}

/* Grid.js writes its own "No matching records found" into .gridjs-message. */
.gridjs-td.gridjs-message {
    padding: 30px 22px;
    font-size: 14px;
    color: var(--apta-text-muted);
    text-align: center;
}
