/* ==========================================================================
   Knight21-ERP - "Noble Tech" admin theme overlay
   --------------------------------------------------------------------------
   Loaded LAST so it layers on top of style.min.css / custom.css without
   modifying them. Purely presentational: no layout restructuring, no markup
   or behaviour changes (aside from the dashboard content itself, edited
   separately), so it can be disabled by removing the single <link> in
   resources/views/layouts/include.blade.php.

   This file previously implemented a light "glassmorphism" overlay. It has
   been rewritten in place to the "Noble Tech" design system (see
   C:\Users\tarun\office\stitch_website\DESIGN.md) - deep navy + teal,
   solid opaque surfaces for structural chrome (sidebar/navbar/cards), with
   glassmorphism blur reserved only for transient overlays (modals,
   dropdowns, SweetAlert2) per that spec.

   Colour policy: reuses the existing --theme-color (set from system
   settings, defaults to Noble Teal #14B8A6 already in include.blade.php) for
   every accent/active-state, so a school that customises its theme colour
   still gets a coherent result. Only the structural navy and neutrals below
   are new hardcoded values, taken directly from DESIGN.md's palette.
   ========================================================================== */

:root {
    --noble-navy: #0F2A3D;
    --noble-navy-deep: #001524;
    --noble-teal: var(--theme-color, #14B8A6);
    --noble-ice: #F8FAFC;
    --noble-serf-gray: #64748B;
    --noble-on-surface: #1A1C1D;
    --noble-surface-variant: #E3E2E4;

    --noble-radius-sm: 8px;
    --noble-radius: 16px;
    --noble-radius-lg: 24px;
    --noble-radius-pill: 9999px;

    --noble-shadow: 0 4px 20px -2px rgba(15, 42, 61, 0.08);
    --noble-shadow-hover: 0 10px 30px -4px rgba(15, 42, 61, 0.16);
    --noble-ease: cubic-bezier(0.22, 0.61, 0.36, 1);
    --noble-duration: 200ms;

    /* Kept for any markup still referencing the old variable names. */
    --glass-border: rgba(255, 255, 255, 0.55);
    --glass-blur: 16px;
}

/* --------------------------------------------------------------------------
   0. Typography
   Hanken Grotesk for headings (sharp, geometric, matches the landing page),
   Inter stays the base body font already set by the template.
   -------------------------------------------------------------------------- */
h1, h2, h3, h4, h5, h6,
.page-title,
.card-title,
.nav-profile-text p {
    font-family: 'Hanken Grotesk', 'Inter', sans-serif;
    font-weight: 700;
    color: var(--noble-navy);
}

/* --------------------------------------------------------------------------
   0b. Dashboard hero greeting
   -------------------------------------------------------------------------- */
.noble-hero-title {
    font-family: 'Hanken Grotesk', sans-serif;
    font-weight: 700;
    font-size: 1.75rem;
    color: var(--noble-navy);
    margin-bottom: 2px;
}

.noble-hero-subtitle {
    color: var(--noble-serf-gray);
    font-size: 0.95rem;
    margin-bottom: 0;
}

/* Stat cards on the dashboard (icon badge + label + value) */
.noble-stat-card {
    display: flex;
    align-items: center;
    gap: 14px;
}

.noble-stat-icon {
    width: 48px;
    height: 48px;
    min-width: 48px;
    border-radius: var(--noble-radius-sm);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.25rem;
}

.noble-stat-label {
    color: var(--noble-serf-gray);
    font-size: 0.8rem;
    font-weight: 500;
    margin-bottom: 2px;
}

.noble-stat-value {
    font-family: 'Hanken Grotesk', sans-serif;
    font-weight: 700;
    font-size: 1.5rem;
    color: var(--noble-navy);
    line-height: 1;
}

.noble-icon-teal {
    background: rgba(20, 184, 166, 0.1);
    color: var(--noble-teal);
}

.noble-icon-navy {
    background: rgba(15, 42, 61, 0.08);
    color: var(--noble-navy);
}

.noble-icon-amber {
    background: rgba(234, 190, 152, 0.35);
    color: #8a5a2d;
}

/* Accent-navy widget card (used for the attendance / engagement card) */
.noble-accent-card {
    background: var(--noble-navy) !important;
    border: none !important;
    color: #ffffff;
}

.noble-accent-card .card-title {
    color: #ffffff !important;
}

.noble-accent-card .noble-card-icon {
    background: var(--noble-teal);
    color: #ffffff;
}

/* Reusable small icon badge preceding a card title, matching the mockup's
   "icon in a colour-tinted square" header treatment. */
.noble-card-icon {
    width: 36px;
    height: 36px;
    min-width: 36px;
    border-radius: var(--noble-radius-sm);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: rgba(20, 184, 166, 0.1);
    color: var(--noble-teal);
    margin-right: 10px;
}

.noble-card-header {
    display: flex;
    align-items: center;
    margin-bottom: 4px;
}

.noble-card-header .card-title {
    margin-bottom: 0;
}

.alert {
    border-radius: var(--noble-radius-sm);
    border: none;
}

/* --------------------------------------------------------------------------
   1. Ambient background
   Flat "Ice White" per DESIGN.md - clean surface so cards read via shadow,
   not competing background colour.
   -------------------------------------------------------------------------- */
body {
    background-color: var(--noble-ice);
}

.container-scroller,
.main-panel,
.content-wrapper {
    background: transparent !important;
}

/* --------------------------------------------------------------------------
   2. Cards - the primary elevated surface
   Solid white + soft ambient shadow, not blurred - structural chrome stays
   crisp per DESIGN.md ("Elevated Card").
   -------------------------------------------------------------------------- */
.card {
    background: #ffffff !important;
    border: 1px solid rgba(15, 42, 61, 0.06) !important;
    border-radius: var(--noble-radius) !important;
    box-shadow: var(--noble-shadow) !important;
    transition: transform var(--noble-duration) var(--noble-ease),
                box-shadow var(--noble-duration) var(--noble-ease);
}

.card:hover {
    box-shadow: var(--noble-shadow-hover) !important;
    transform: translateY(-2px);
}

.card .card-title {
    letter-spacing: 0.01em;
}

.page-title-icon {
    border-radius: var(--noble-radius-sm) !important;
}

/* --------------------------------------------------------------------------
   3. Sidebar - solid Knight Navy, matching the mockup's unified dark sidebar
   -------------------------------------------------------------------------- */
.sidebar {
    background: var(--noble-navy) !important;
    border-right: none;
    box-shadow: 4px 0 24px rgba(15, 42, 61, 0.12);
}

.sidebar .nav .nav-item .nav-link {
    color: rgba(248, 250, 252, 0.7);
    border-radius: var(--noble-radius-sm);
    margin: 2px 10px;
    transition: background-color var(--noble-duration) var(--noble-ease),
                color var(--noble-duration) var(--noble-ease),
                transform 160ms var(--noble-ease);
}

.sidebar .nav .nav-item .nav-link .menu-icon,
.sidebar .nav .nav-item .nav-link .menu-arrow {
    color: inherit;
}

.sidebar .nav .nav-item .nav-link:hover {
    background-color: rgba(255, 255, 255, 0.08);
    color: #ffffff;
    transform: translateX(3px);
}

/* style.min.css sets .nav-item.active { background:#fff } on the outer <li>,
   and forces the inner .menu-title / icon color to var(--theme-color) (teal)
   with higher specificity than a plain color rule can beat - so on top of a
   teal active nav-link, that text/icon rendered teal-on-teal, invisible.
   Neutralise the white li background and force text/icon white explicitly. */
.sidebar .nav .nav-item.active {
    background-color: transparent !important;
}

.sidebar .nav .nav-item.active > .nav-link {
    background-color: var(--noble-teal);
    color: #ffffff;
    font-weight: 700;
    box-shadow: none;
}

.sidebar .nav .nav-item.active > .nav-link .menu-title,
.sidebar .nav .nav-item.active > .nav-link i {
    color: #ffffff !important;
}

/* The base template paints the expanded parent row (e.g. "Academics") and
   its submenu white once opened (.nav-item.active / [aria-expanded=true]
   background rules), while our submenu text was styled light-on-navy - on
   a white panel that made every item unreadable. Force every state in the
   sidebar back to solid navy/transparent so nothing ever shows white. */
.sidebar .nav .nav-item,
.sidebar .nav .nav-item .nav-link,
.sidebar .nav .nav-item .nav-link[aria-expanded="true"],
.sidebar .collapse,
.sidebar .nav.sub-menu,
.sidebar .nav.sub-menu .nav-item {
    background-color: transparent !important;
}

.sidebar .nav.sub-menu {
    background-color: rgba(0, 0, 0, 0.18) !important;
    border-radius: var(--noble-radius-sm);
    margin: 0 10px 10px;
    padding: 4px 0;
}

.sidebar .nav.sub-menu .nav-item .nav-link {
    color: rgba(248, 250, 252, 0.7) !important;
}

.sidebar .nav.sub-menu .nav-item .nav-link:before {
    color: var(--noble-teal) !important;
}

.sidebar .nav.sub-menu .nav-item .nav-link:hover,
.sidebar .nav.sub-menu .nav-item .nav-link.active {
    color: #ffffff !important;
    background-color: rgba(20, 184, 166, 0.18) !important;
}

.sidebar .nav .nav-item .nav-link[aria-expanded="true"] {
    color: var(--noble-teal) !important;
}

.sidebar .nav .nav-item .nav-link[aria-expanded="true"] .menu-title,
.sidebar .nav .nav-item .nav-link[aria-expanded="true"] i,
.sidebar .nav .nav-item .nav-link[aria-expanded="true"] .menu-arrow {
    color: var(--noble-teal) !important;
}

.sidebar-search .form-control {
    background: rgba(255, 255, 255, 0.06) !important;
    border: 1px solid rgba(255, 255, 255, 0.12) !important;
    color: #ffffff !important;
}

.sidebar-search .form-control::placeholder {
    color: rgba(248, 250, 252, 0.5);
}

/* Sidebar brand block (logo + school name), moved here from the header. */
.sidebar-brand {
    padding: 4px 22px 20px;
    margin-bottom: 6px;
    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

.sidebar-brand img {
    max-height: 40px;
    width: auto;
    object-fit: contain;
}

.sidebar-brand .sidebar-brand-name {
    color: var(--noble-ice);
    font-family: 'Hanken Grotesk', sans-serif;
    font-weight: 700;
    font-size: 1.05rem;
    line-height: 1.2;
    margin-top: 8px;
}

.sidebar-brand .sidebar-brand-subtitle {
    color: rgba(248, 250, 252, 0.55);
    font-size: 0.75rem;
    font-weight: 500;
}

/* The logo now lives in the sidebar brand block above, not the header, so
   the old header brand box is collapsed out of the layout (CSS-only, the
   markup stays in case this override is ever removed). Collapse the
   sidebar's own brand text in icon-only mode, matching how the template
   already hides .menu-title text in that state. */
.navbar-brand-wrapper {
    display: none !important;
}

.sidebar-icon-only .sidebar-brand {
    padding: 4px 0 20px;
    text-align: center;
}

.sidebar-icon-only .sidebar-brand .sidebar-brand-name,
.sidebar-icon-only .sidebar-brand .sidebar-brand-subtitle {
    display: none;
}

/* --------------------------------------------------------------------------
   4. Top navbar - light, sits beside the navy sidebar
   -------------------------------------------------------------------------- */
.navbar.default-layout-navbar {
    background: #ffffff !important;
    border-bottom: 1px solid rgba(15, 42, 61, 0.06);
    box-shadow: 0 2px 12px rgba(15, 42, 61, 0.04);
}

.navbar .navbar-menu-wrapper,
.navbar .navbar-brand-wrapper {
    background: transparent !important;
}

/* The legacy top bar (cache-clear button, school name, session-year label,
   language/profile dropdowns) had no consistent spacing once the separate
   brand-logo box was removed - everything sat flush against each other. */
.navbar-menu-wrapper {
    gap: 18px;
    padding: 0 12px;
}

.navbar-menu-wrapper .cache-clear {
    display: flex;
    align-items: center;
}

.navbar-menu-wrapper .cache-clear .btn {
    font-size: 0.75rem;
    padding: 5px 14px;
    border-radius: var(--noble-radius-pill);
}

.navbar-menu-wrapper .cache-clear span {
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--noble-navy);
    margin-left: 0 !important;
}

.navbar-nav-right {
    align-items: center;
    gap: 4px;
}

.navbar-nav-right .nav-item {
    display: flex;
    align-items: center;
}

/* --------------------------------------------------------------------------
   5. Buttons
   -------------------------------------------------------------------------- */
.btn {
    border-radius: var(--noble-radius-sm);
    font-weight: 600;
    transition: transform 140ms var(--noble-ease),
                box-shadow var(--noble-duration) var(--noble-ease),
                filter var(--noble-duration) var(--noble-ease);
}

.btn:hover {
    transform: translateY(-1px);
    box-shadow: 0 6px 18px rgba(15, 42, 61, 0.18);
}

.btn:active {
    transform: translateY(0) scale(0.985);
}

.btn-theme {
    box-shadow: 0 4px 14px rgba(15, 42, 61, 0.2);
}

/* --------------------------------------------------------------------------
   6. Forms - visible teal focus state, 8px radius per DESIGN.md core elements
   -------------------------------------------------------------------------- */
.form-control,
.select2-container--default .select2-selection--single,
.select2-container--default .select2-selection--multiple {
    border-radius: var(--noble-radius-sm) !important;
    transition: border-color 180ms var(--noble-ease),
                box-shadow 180ms var(--noble-ease);
}

.form-control:focus,
.select2-container--default.select2-container--focus .select2-selection--multiple,
.select2-container--default.select2-container--open .select2-selection--single {
    border-color: var(--noble-teal) !important;
    box-shadow: 0 0 0 3px rgba(20, 184, 166, 0.18) !important;
}

/* --------------------------------------------------------------------------
   7. Modals, dropdowns, bottom sheets
   Glassmorphism blur kept here deliberately (DESIGN.md: "Overlays... use a
   Glassmorphism backdrop blur to maintain context of the underlying data") -
   this is the one place blur still belongs in the Noble Tech system.
   -------------------------------------------------------------------------- */
.modal-content {
    background: rgba(255, 255, 255, 0.92) !important;
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
    border: 1px solid rgba(15, 42, 61, 0.08) !important;
    border-radius: var(--noble-radius) !important;
    box-shadow: 0 20px 60px rgba(15, 42, 61, 0.28) !important;
}

.modal-backdrop.show {
    opacity: 0.5;
}

.dropdown-menu {
    background: rgba(255, 255, 255, 0.92) !important;
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
    border: 1px solid rgba(15, 42, 61, 0.08) !important;
    border-radius: var(--noble-radius-sm) !important;
    box-shadow: 0 12px 34px rgba(15, 42, 61, 0.16) !important;
}

.dropdown-menu .dropdown-item {
    border-radius: 8px;
    color: var(--noble-navy) !important;
    transition: background-color 160ms var(--noble-ease);
}

.dropdown-menu .dropdown-item:hover,
.dropdown-menu .dropdown-item:active {
    background-color: rgba(20, 184, 166, 0.1);
    color: var(--noble-navy) !important;
}

/* select2 renders its own results panel outside .dropdown-menu entirely -
   force visible dark text there too so options never render blank. */
.select2-dropdown {
    border-radius: var(--noble-radius-sm) !important;
}

.select2-results__option {
    color: var(--noble-on-surface) !important;
}

.select2-results__option--highlighted {
    background-color: var(--noble-teal) !important;
    color: #ffffff !important;
}

/* SweetAlert2 confirmation dialogs */
.swal2-popup {
    border-radius: var(--noble-radius) !important;
    background: rgba(255, 255, 255, 0.92) !important;
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
    box-shadow: 0 20px 60px rgba(15, 42, 61, 0.3) !important;
}

.swal2-styled {
    border-radius: var(--noble-radius-sm) !important;
    transition: transform 140ms var(--noble-ease);
}

.swal2-styled:hover {
    transform: translateY(-1px);
}

/* --------------------------------------------------------------------------
   8. Tables
   Not blurred - this is a data-dense admin tool and legibility of tabular
   data outweighs any surface effect.
   -------------------------------------------------------------------------- */
.table thead th {
    background: rgba(15, 42, 61, 0.05);
    border-bottom: 1px solid rgba(15, 42, 61, 0.12) !important;
    color: var(--noble-navy);
    letter-spacing: 0.02em;
}

.table tbody tr {
    transition: background-color 160ms var(--noble-ease);
}

.table tbody tr:hover {
    background-color: rgba(20, 184, 166, 0.05) !important;
}

.fixed-table-container,
.bootstrap-table .fixed-table-container {
    border-radius: var(--noble-radius-sm);
}

/* --------------------------------------------------------------------------
   9. Chips & badges - rounded pill status labels per DESIGN.md
   -------------------------------------------------------------------------- */
.badge {
    border-radius: var(--noble-radius-pill);
    font-weight: 600;
    letter-spacing: 0.01em;
}

/* --------------------------------------------------------------------------
   10. Entrance motion
   One subtle fade+rise on page content. Kept short so navigation still feels
   immediate rather than animated-for-the-sake-of-it.
   -------------------------------------------------------------------------- */
@keyframes nobleFadeRise {
    from { opacity: 0; transform: translateY(10px); }
    to   { opacity: 1; transform: translateY(0); }
}

.content-wrapper > .row > [class*="col-"] > .card,
.content-wrapper > .card,
.content-wrapper > .row > .card {
    animation: nobleFadeRise 340ms var(--noble-ease) both;
}

/* --------------------------------------------------------------------------
   11. Accessibility - honour reduced-motion preferences
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.001ms !important;
        scroll-behavior: auto !important;
    }

    .card:hover,
    .btn:hover,
    .sidebar .nav .nav-item .nav-link:hover {
        transform: none !important;
    }
}

/* --------------------------------------------------------------------------
   12. Fallback for browsers without backdrop-filter support
   Without this the translucent overlay surfaces (modals/dropdowns/SweetAlert2
   only, in this version) would look washed out and text contrast would drop
   below AA.
   -------------------------------------------------------------------------- */
@supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
    .modal-content,
    .dropdown-menu,
    .swal2-popup {
        background: #ffffff !important;
    }
}

/* ==========================================================================
   Sidebar: keep hovered text white in every state
   --------------------------------------------------------------------------
   The base template and the browser's own a:active/a:focus styling can win
   over the hover rule above, so a hovered item could flash the default link
   blue and become hard to read on the navy panel. Pin hover/focus/active to
   white for the row and everything inside it.
   ========================================================================== */
.sidebar .nav .nav-item .nav-link:hover,
.sidebar .nav .nav-item .nav-link:focus,
.sidebar .nav .nav-item .nav-link:active,
.sidebar .nav .nav-item .nav-link:hover .menu-title,
.sidebar .nav .nav-item .nav-link:focus .menu-title,
.sidebar .nav .nav-item .nav-link:active .menu-title,
.sidebar .nav .nav-item .nav-link:hover i,
.sidebar .nav .nav-item .nav-link:focus i,
.sidebar .nav .nav-item .nav-link:active i {
    color: #ffffff !important;
}

/* Hovering the currently-selected (teal) row must also stay white, not shift
   toward the link colour. */
.sidebar .nav .nav-item.active > .nav-link:hover,
.sidebar .nav .nav-item.active > .nav-link:hover .menu-title,
.sidebar .nav .nav-item.active > .nav-link:hover i {
    color: #ffffff !important;
}

/* Same for submenu rows. */
.sidebar .nav.sub-menu .nav-item .nav-link:hover,
.sidebar .nav.sub-menu .nav-item .nav-link:focus,
.sidebar .nav.sub-menu .nav-item .nav-link:active {
    color: #ffffff !important;
}

/* Remove the focus outline flash without losing keyboard accessibility -
   the background change already signals focus for pointer users. */
.sidebar .nav .nav-item .nav-link:focus-visible {
    outline: 2px solid var(--noble-teal);
    outline-offset: -2px;
}

/* ==========================================================================
   Modal close (x): make it visible and red
   --------------------------------------------------------------------------
   Bootstrap 4's .close is near-black at 0.5 opacity, which disappears against
   the dark modal headers in this theme. Bootstrap 5's .btn-close is included
   too so the rule survives an upgrade.
   ========================================================================== */
.modal .close,
.modal .btn-close,
.modal-header .close,
.modal-header .btn-close {
    color: #dc2626 !important;
    opacity: 1 !important;
    text-shadow: none;
    background-color: transparent;
    border: none;
    font-size: 1.6rem;
    line-height: 1;
    font-weight: 700;
    padding: 0 .35rem;
    border-radius: var(--noble-radius-sm);
    transition: color 140ms var(--noble-ease),
                background-color 140ms var(--noble-ease);
}

.modal .close span,
.modal-header .close span {
    color: #dc2626 !important;
    opacity: 1 !important;
}

.modal .close:hover,
.modal .btn-close:hover,
.modal-header .close:hover,
.modal-header .btn-close:hover {
    color: #b91c1c !important;
    background-color: rgba(220, 38, 38, 0.12);
}

.modal .close:hover span,
.modal-header .close:hover span {
    color: #b91c1c !important;
}

.modal .close:focus-visible,
.modal .btn-close:focus-visible {
    outline: 2px solid #dc2626;
    outline-offset: 2px;
}

/* Bootstrap 5 draws its x as a background SVG rather than a glyph, so recolour
   the asset itself; the color property alone would have no effect there. */
.modal .btn-close {
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23dc2626'%3e%3cpath d='M.293.293a1 1 0 011.414 0L8 6.586 14.293.293a1 1 0 111.414 1.414L9.414 8l6.293 6.293a1 1 0 01-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 01-1.414-1.414L6.586 8 .293 1.707a1 1 0 010-1.414z'/%3e%3c/svg%3e");
    background-repeat: no-repeat;
    background-position: center;
    background-size: 1em;
}

/* --------------------------------------------------------------------------
   The base theme applies its hover colour via the <li>, not the <a>:

     .sidebar .nav:not(.sub-menu)>.nav-item:hover:not(.nav-category)
       :not(.nav-profile)>.nav-link { color: #29323d; }

   #29323d is dark slate, intended for the light sidebar. On this navy panel it
   renders the hovered row nearly invisible. The template's own .sidebar-dark
   override would fix it, but <body> does not carry that class here. Match the
   same selector shape so the row and its children stay white on hover.
   -------------------------------------------------------------------------- */
.sidebar .nav:not(.sub-menu) > .nav-item:hover > .nav-link,
.sidebar .nav:not(.sub-menu) > .nav-item:hover > .nav-link .menu-title,
.sidebar .nav:not(.sub-menu) > .nav-item:hover > .nav-link .menu-arrow,
.sidebar .nav:not(.sub-menu) > .nav-item:hover > .nav-link i {
    color: #ffffff !important;
}

/* Submenu rows use their own hover colour (#555555 / #b3b3b3), equally dark. */
.sidebar .nav.sub-menu > .nav-item:hover > .nav-link,
.sidebar .nav.sub-menu > .nav-item:hover > .nav-link .menu-title,
.sidebar .nav.sub-menu > .nav-item:hover > .nav-link i {
    color: #ffffff !important;
}

/* Keep the hovered row's background readable rather than the theme's light
   wash, which would otherwise flash pale behind white text. */
.sidebar .nav:not(.sub-menu) > .nav-item:hover > .nav-link {
    background-color: rgba(255, 255, 255, 0.08) !important;
}

/* --------------------------------------------------------------------------
   School registration lifecycle
   Explains, on Manage Schools, what has to happen before a school can sign in.
   Numbered steps connected by a rule; stacks to a vertical list on narrow
   screens so the notes stay readable rather than squeezing to two words wide.
   -------------------------------------------------------------------------- */
.school-lifecycle {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: 1.25rem;
    list-style: none;
    margin: 0;
    padding: 0;
    counter-reset: lifecycle;
}

.school-lifecycle > li {
    position: relative;
    padding-top: 0.25rem;
}

/* The connecting rule sits behind the numbers and stops before the last step. */
.school-lifecycle > li:not(:last-child)::after {
    content: "";
    position: absolute;
    top: 16px;
    left: 34px;
    right: -1.25rem;
    height: 2px;
    background: var(--noble-surface-variant);
    z-index: 0;
}

.school-lifecycle .lifecycle-step {
    position: relative;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: var(--noble-radius-pill);
    background: var(--noble-navy);
    color: #ffffff;
    font-weight: 600;
    font-size: 0.85rem;
}

.school-lifecycle .lifecycle-title {
    display: block;
    margin-top: 0.6rem;
    font-weight: 600;
    color: var(--noble-on-surface);
}

.school-lifecycle .lifecycle-note {
    display: block;
    margin-top: 0.25rem;
    font-size: 0.8rem;
    line-height: 1.5;
    color: var(--noble-serf-gray);
}

@media (max-width: 991px) {
    .school-lifecycle {
        grid-template-columns: 1fr;
        gap: 1rem;
    }

    /* Vertical layout: run the rule down the left gutter instead of across. */
    .school-lifecycle > li:not(:last-child)::after {
        top: 36px;
        bottom: -1rem;
        left: 15px;
        right: auto;
        width: 2px;
        height: auto;
    }

    .school-lifecycle > li {
        display: grid;
        grid-template-columns: 32px 1fr;
        column-gap: 0.9rem;
    }

    .school-lifecycle .lifecycle-step {
        grid-row: 1 / span 2;
    }

    .school-lifecycle .lifecycle-title {
        margin-top: 0.35rem;
    }
}

/* The Status cell's "Setting up..." state - the loader alone gave no clue what
   the animation meant or how long it was expected to last. */
.school-setup-pending .bar-loader {
    width: auto;
    height: 22px;
    margin: 0;
}

.school-setup-pending .bar-loader span {
    height: 18px;
    background-color: var(--noble-teal);
}

.school-setup-pending small {
    font-size: 0.72rem;
    margin-top: 0.15rem;
}
