/* =========================================================
   CERTIFICATE IN MARKETING — design system
   Brand palette: deep teal (trust, growth, communication) with a
   warm gold accent shared with the certificate documents, on a
   clean warm-neutral background. Mobile-first, minimal dependency
   (no external UI framework) — this file is the whole system.
   ========================================================= */

:root {
    --brand: #0E5C52;
    --brand-dark: #083E37;
    --brand-light: #E4F1EE;
    --accent: #C9932E;
    --accent-light: #F8ECD6;
    --ink: #1B241F;
    --text: #2B332F;
    --muted: #6B776F;
    --border: #E1E6E2;
    --bg: #F7F8F6;
    --card: #FFFFFF;
    --success: #1F9D66;
    --success-bg: #E5F6ED;
    --warning: #B9791A;
    --warning-bg: #FCF1DE;
    --danger: #D6483F;
    --danger-bg: #FBE9E7;
    --info: #2A72B5;
    --info-bg: #E8F1FA;
    --radius: 12px;
    --radius-sm: 8px;
    --shadow: 0 2px 10px rgba(20, 40, 34, .06);
    --shadow-lg: 0 12px 34px rgba(20, 40, 34, .12);
    --font-body: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    --font-head: Georgia, 'Times New Roman', serif;
    --ease: cubic-bezier(.22, 1, .36, 1);
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
    margin: 0;
    font-family: var(--font-body);
    color: var(--text);
    background: var(--bg);
    -webkit-font-smoothing: antialiased;
    line-height: 1.55;
}
img { max-width: 100%; display: block; }
a { color: var(--brand); text-decoration: none; }
a:hover { text-decoration: underline; }
h1, h2, h3, h4 { font-family: var(--font-head); color: var(--ink); line-height: 1.2; margin: 0 0 .5em; }
h1 { font-size: clamp(1.8rem, 3vw, 2.6rem); }
h2 { font-size: clamp(1.4rem, 2.4vw, 1.9rem); }
h3 { font-size: 1.2rem; }
p { margin: 0 0 1em; }
.muted { color: var(--muted); }
.small { font-size: .85em; }
.text-danger { color: var(--danger); }
.text-success { color: var(--success); }
.center { text-align: center; }
code, kbd { font-family: 'SFMono-Regular', Consolas, monospace; background: var(--brand-light); padding: 2px 6px; border-radius: 4px; font-size: .9em; }

.container { max-width: 1160px; margin: 0 auto; padding: 0 20px; }
.container-narrow { max-width: 760px; margin: 0 auto; padding: 0 20px; }
.section { padding-top: 56px; padding-bottom: 56px; }
.section-tight { padding-top: 16px; padding-bottom: 16px; }

/* ---- Icons ----
   Base .icon sets a sane default size so an <svg class="icon"> never
   falls back to its unconstrained intrinsic size. Modifiers scale from
   there; more specific containers (sidebar, feature tiles) still win
   via selector specificity. */
.icon { width: 20px; height: 20px; flex: 0 0 auto; vertical-align: -4px; }
.icon-xs { width: 14px; height: 14px; }
.icon-sm { width: 16px; height: 16px; }
.icon-md { width: 24px; height: 24px; }
.icon-lg { width: 32px; height: 32px; }
.icon-xl { width: 48px; height: 48px; }

/* ---- Buttons ---- */
.btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 8px;
    padding: 11px 22px; border-radius: 999px; font-weight: 600; font-size: .95rem;
    border: 1px solid transparent; cursor: pointer; transition: transform .12s ease, box-shadow .12s ease, background .12s ease;
    text-decoration: none; line-height: 1.2;
}
.btn:hover { text-decoration: none; }
.btn-primary { background: var(--brand); color: #fff; }
.btn-primary:hover { background: var(--brand-dark); box-shadow: var(--shadow); }
.btn-accent { background: var(--accent); color: #fff; }
.btn-accent:hover { filter: brightness(.94); }
.btn-outline { background: transparent; color: var(--brand); border-color: var(--brand); }
.btn-outline:hover { background: var(--brand-light); }
.btn-outline-light { background: transparent; color: #fff; border-color: rgba(255,255,255,.6); }
.btn-outline-light:hover { background: rgba(255,255,255,.12); }
.btn-outline-danger { background: transparent; color: var(--danger); border-color: var(--danger); }
.btn-outline-danger:hover { background: var(--danger-bg); }
.btn-outline-success { background: transparent; color: var(--success); border-color: var(--success); }
.btn-outline-success:hover { background: var(--success-bg); }
.btn-danger { background: var(--danger); color: #fff; }
.btn-danger:hover { filter: brightness(.92); }
.btn-sm { padding: 7px 14px; font-size: .82rem; }
.btn-lg { padding: 14px 30px; font-size: 1.05rem; }
.btn-block { width: 100%; }
.btn[disabled], .btn.disabled { opacity: .55; cursor: not-allowed; pointer-events: none; }
.btn-group { display: flex; gap: 10px; flex-wrap: wrap; }

/* ---- Forms ---- */
label { display: block; font-weight: 600; font-size: .88rem; color: var(--ink); margin-bottom: 14px; }
input, select, textarea {
    width: 100%; margin-top: 6px; padding: 11px 13px; border: 1px solid var(--border); border-radius: var(--radius-sm);
    font-size: .95rem; font-family: inherit; background: #fff; color: var(--text);
}
/* Checkboxes and radios opt out of the width:100%/padding/border styling
   above — without this, a bare <input type="checkbox"> (e.g. every
   table's "select all" header checkbox and each row's [data-bulk-select]
   bulk-action checkbox) inherits a full-width, padded, bordered box
   instead of a normal small tickbox. Most harmless at typical desktop
   widths where a fixed column width constrains it, but once a table
   stacks below 960px (see "Responsive tables" below) its <td> becomes a
   full-width block and the checkbox stretched to match it — rendering
   as an oversized blank box rather than something recognisable to
   click, which is exactly what made bulk-select checkboxes on
   Programmes and Subjects look like they weren't there at all. */
input[type="checkbox"], input[type="radio"] { width: auto; margin-top: 0; padding: 0; border: 0; background: none; }
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-light); }
textarea { resize: vertical; min-height: 90px; }
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 18px; }
.form-grid .span-2 { grid-column: 1 / -1; }
@media (max-width: 640px) { .form-grid { grid-template-columns: 1fr; } }
.checkbox-row { display: flex; align-items: center; gap: 8px; font-weight: 500; }
.checkbox-row input { width: auto; margin-top: 0; }

/* Programme checkbox grid (superuser/subjects.php's Add/Edit "Programmes"
   picker) — a proper grid instead of inline-flex labels wrapping ad hoc,
   so columns line up and a checkbox stays pinned to the top of its label
   even when a long programme name wraps to two or three lines. */
.program-checkbox-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 12px 20px; margin-top: 10px; }
.program-checkbox-item { display: flex; align-items: flex-start; gap: 8px; font-weight: 400; margin-bottom: 0; line-height: 1.35; }
.program-checkbox-item input[type="checkbox"] { width: auto; margin-top: 3px; flex-shrink: 0; }
.field-hint { font-weight: 400; color: var(--muted); font-size: .85em; display: block; margin-top: 3px; }
fieldset { border: 1px solid var(--border); border-radius: var(--radius); padding: 16px; margin: 0 0 18px; }
legend { font-weight: 700; padding: 0 6px; color: var(--ink); }

/* ---- Alerts / badges ---- */
.alert { padding: 13px 16px; border-radius: var(--radius-sm); margin-bottom: 18px; font-size: .92rem; border: 1px solid transparent; }
.alert-success { background: var(--success-bg); color: #14603F; border-color: #bfe6d1; }
.alert-danger { background: var(--danger-bg); color: #8C2A24; border-color: #f0c6c2; }
.alert-warning { background: var(--warning-bg); color: #7A4E0D; border-color: #f0dcb1; }
.alert-info { background: var(--info-bg); color: #1B4E7D; border-color: #c3dcf1; }
.badge { display: inline-block; padding: 3px 10px; border-radius: 999px; font-size: .74rem; font-weight: 700; letter-spacing: .02em; }
.badge-active, .badge-confirmed, .badge-approved, .badge-completed { background: var(--success-bg); color: #14603F; }
.badge-pending, .badge-warning { background: var(--warning-bg); color: #7A4E0D; }
.badge-suspended, .badge-rejected, .badge-danger { background: var(--danger-bg); color: #8C2A24; }
.badge-info { background: var(--info-bg); color: #1B4E7D; }
.badge-neutral { background: #EEF0EC; color: var(--muted); }
.sidebar-count-badge { display:inline-block; margin-left:6px; padding:1px 7px; border-radius:999px; font-size:.7rem; font-weight:700; background: var(--warning-bg); color:#7A4E0D; line-height:1.5; }

/* ---- Cards ---- */
.card { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow); margin-bottom: 22px; overflow: hidden; }
.card-body { padding: 22px; }
.card-header { padding: 16px 22px; border-bottom: 1px solid var(--border); font-weight: 700; font-family: var(--font-head); font-size: 1.05rem; display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.card > form, .card > .form-grid { padding: 22px; }
.card > .table-wrap { padding: 0; }
.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 16px; margin-bottom: 24px; }
.stat-tile { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); padding: 18px 20px; box-shadow: var(--shadow); }
.stat-tile .stat-label { font-size: .78rem; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); font-weight: 700; }
.stat-tile .stat-value { font-family: var(--font-head); font-size: 1.9rem; color: var(--ink); font-weight: 700; margin-top: 4px; }
.stat-tile .stat-sub { font-size: .82rem; color: var(--muted); margin-top: 2px; }
.stat-tile-warn { border-color: var(--warning); }
.stat-tile-warn .stat-value { color: var(--warning); }

/* ---- Tabs (e.g. Settings) ---- */
.tabs-nav { display: flex; gap: 4px; flex-wrap: wrap; border-bottom: 1px solid var(--border); margin-bottom: 22px; }
.tabs-nav button { background: none; border: none; border-bottom: 3px solid transparent; padding: 11px 16px; font-family: var(--font-head); font-weight: 700; font-size: .92rem; color: var(--muted); cursor: pointer; display: inline-flex; align-items: center; gap: 7px; transition: color .12s ease, border-color .12s ease; }
.tabs-nav button:hover { color: var(--ink); }
.tabs-nav button.active { color: var(--brand); border-bottom-color: var(--brand); }

/* ---- Tables ---- */
.table-wrap { overflow-x: auto; }
.table { width: 100%; border-collapse: collapse; font-size: .92rem; }
.table th, .table td { padding: 12px 16px; text-align: left; border-bottom: 1px solid var(--border); white-space: nowrap; }
.table th { background: #F1F3F0; color: var(--ink); font-weight: 700; font-size: .78rem; text-transform: uppercase; letter-spacing: .04em; }
.table tbody tr:hover { background: #FAFBF9; }
.actions a { margin-right: 12px; font-weight: 600; font-size: .88rem; }

/* =========================================================
   PUBLIC SITE
   ========================================================= */
.public-nav {
    display: flex; align-items: center; justify-content: space-between; gap: 20px;
    padding: 14px 26px; background: #fff; border-bottom: 1px solid var(--border);
    position: sticky; top: 0; z-index: 40;
}
.public-brand { display: flex; align-items: center; gap: 10px; font-family: var(--font-head); font-weight: 700; font-size: 1.15rem; color: var(--ink); }

.promo-banner { background: var(--accent); color: #fff; }
.promo-banner-inner { max-width: 1160px; margin: 0 auto; padding: 10px 20px; display: flex; align-items: center; justify-content: center; gap: 10px; flex-wrap: wrap; text-align: center; font-size: .88rem; }
.promo-banner-inner .icon { flex: 0 0 auto; }
.promo-banner-link { color: #fff; font-weight: 700; text-decoration: underline; white-space: nowrap; }
.public-brand img { height: 36px; width: 36px; border-radius: 8px; object-fit: cover; }
.nav-toggle {
    display: none;
    flex-direction: column; align-items: center; justify-content: center; gap: 5px;
    width: 42px; height: 42px;
    border-radius: 10px;
    border: 1px solid var(--border);
    background: #fff;
    cursor: pointer;
    transition: background .15s var(--ease), border-color .15s var(--ease);
}
.nav-toggle:hover, .nav-toggle:focus-visible { background: var(--bg); border-color: var(--brand); outline: none; }
/* Classic three-bar icon that morphs into an X when open — real <span>s
   (see includes/header_public.php), not a ☰/✕ character swap, so it
   animates smoothly regardless of font glyph support. 7px = the line's
   own 2px height plus the 5px gap between lines (adjacent block-margins
   collapse to 5px, not 10) — the exact pitch between line centers. */
.nav-toggle span { display: block; width: 20px; height: 2px; background: var(--text); border-radius: 2px; transition: transform .2s var(--ease), opacity .2s var(--ease); }
.nav-toggle.open span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle.open span:nth-child(2) { opacity: 0; }
.nav-toggle.open span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }
.public-nav-links { display: flex; align-items: center; gap: 22px; flex-wrap: wrap; }
.public-nav-links > a, .nav-dropdown-toggle { font-weight: 600; color: var(--text); font-size: .93rem; background: none; border: none; cursor: pointer; font-family: inherit; display: flex; align-items: center; gap: 4px; }
.public-nav-links > a:hover, .nav-dropdown-toggle:hover { color: var(--brand); text-decoration: none; }
.nav-dropdown { position: relative; }
.nav-dropdown-menu { display: none; position: absolute; top: calc(100% + 12px); left: 0; background: #fff; border: 1px solid var(--border); border-radius: var(--radius-sm); box-shadow: var(--shadow-lg); min-width: 220px; padding: 8px; z-index: 50; }
.nav-dropdown-menu a { display: block; padding: 9px 12px; border-radius: 6px; font-size: .9rem; color: var(--text); font-weight: 500; }
.nav-dropdown-menu a:hover { background: var(--brand-light); text-decoration: none; }
.nav-dropdown.open .nav-dropdown-menu { display: block; }
/* Programmes dropdown ("mega menu") — as the programme list grows past
   5, this wraps into a new column to the right instead of one long
   scroll of links. grid-auto-flow:column + a fixed row count is what
   does it: the first 5 items fill column 1 top-to-bottom, the 6th
   starts column 2, etc. With 5 or fewer programmes it renders exactly
   like the plain single-column dropdown above. */
.nav-dropdown-menu-mega { grid-template-rows: repeat(5, auto); grid-auto-flow: column; grid-auto-columns: 220px; column-gap: 4px; min-width: 260px; }
.nav-dropdown.open .nav-dropdown-menu-mega { display: grid; }
.nav-dropdown-toggle .icon { transition: transform .2s var(--ease); }
.nav-dropdown.open .nav-dropdown-toggle .icon { transform: rotate(180deg); }

/* "Professional, distinctive" pass on the public nav dropdowns: icons per
   link, a top accent bar, small section eyebrows, and a hover slide-in
   accent instead of a flat background swap. */
.nav-dropdown-menu-fancy { padding-top: 10px; border-top: 3px solid var(--brand); }
.nav-dropdown-menu-fancy a { display: flex; align-items: center; gap: 9px; position: relative; padding-left: 14px; }
.nav-dropdown-menu-fancy a .icon { width: 15px; height: 15px; color: var(--accent); flex: none; }
.nav-dropdown-menu-fancy a::before { content: ''; position: absolute; left: 0; top: 50%; transform: translateY(-50%) scaleY(0); width: 3px; height: 60%; background: var(--accent); border-radius: 2px; transition: transform .15s var(--ease); }
.nav-dropdown-menu-fancy a:hover::before { transform: translateY(-50%) scaleY(1); }
.nav-dropdown-menu-fancy a.nav-dropdown-all { font-weight: 700; color: var(--brand-dark); border-bottom: 1px solid var(--border); border-radius: 0; padding-bottom: 11px; margin-bottom: 4px; }
.nav-dropdown-eyebrow { display: block; font-size: .68rem; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); padding: 6px 12px 4px; }
.nav-dropdown-divider { display: block; height: 1px; background: var(--border); margin: 6px 4px; }
.nav-account { display: flex; align-items: center; gap: 12px; }
/* Login and Apply Now are ordinary items in nav_menu_items now (see
   superuser/nav_menu.php) — the superuser can drag them anywhere among
   Programmes/Subjects/etc., so their "looks like a button" treatment is
   given by an explicit .nav-cta / .nav-cta-toggle class directly on the
   element rather than by an ancestor wrapper (which only worked while
   they were guaranteed to sit in one fixed spot at the end of the menu).
   Login keeps its outline-button look from the site-wide .btn/.btn-outline
   classes already on its <a> — those two classes together already outrank
   the flat ".public-nav-links > a" reset above on specificity alone, this
   comment is just the paper trail. The Apply Now toggle needs its own
   rule: .nav-dropdown-toggle's flat styling has equal specificity and
   comes first in the file, so without a scoped override here it would
   win and the button would look like a plain link — .nav-cta-toggle
   below is that override, kept separate from the plain Programmes/
   Certificates dropdown toggles so only Apply Now gets the solid look. */
.nav-dropdown-toggle.nav-cta-toggle { background: var(--brand); border: 1px solid transparent; color: #fff; font-size: .95rem; gap: 8px; }
.nav-dropdown-toggle.nav-cta-toggle.btn-sm { font-size: .82rem; }
.nav-dropdown-toggle.nav-cta-toggle:hover { background: var(--brand-dark); color: #fff; }

/* ---- Mobile nav: off-canvas drawer sliding in from the left, matching
   Quiz_Platform_4's includes/header_public.php + assets/css/style.css
   pattern (same off-canvas approach as the mobile-nav-drawer skill,
   which that project's own CSS comments cite directly) rather than a
   dropdown-below-header panel. Three things dodge its classic traps:
   longhand top/left/bottom below (never the `inset` shorthand, which has
   inconsistent support and can silently fail to apply fixed
   positioning); no backdrop-filter/filter/transform on any ancestor the
   drawer sits inside, so its fixed positioning resolves against the
   viewport instead of collapsing into a tiny box sized by that ancestor;
   and .public-nav gets z-index:2001 below — permanently while this media
   query is active, not just while the drawer is open — because that
   header is itself position:sticky with its own z-index, making it a
   stacking context whose z-index (not the drawer's, nested inside it) is
   what counts when compared against .nav-overlay, a separate element
   appended straight to <body> (see site.js) rather than written here as
   a pseudo-element, so it's an actual click target. ---- */
@media (max-width: 900px) {
    .nav-toggle { display: inline-flex; }
    .public-nav { z-index: 2001; }

    .public-nav-links {
        position: fixed; top: 0; left: 0; bottom: 0; right: auto;
        width: 82%; max-width: 320px;
        /* Subtle brand-tinted wash instead of flat white, plus a thin
           two-tone top edge so the drawer reads as a designed surface. */
        background: linear-gradient(180deg, #ffffff 0%, var(--accent-light) 100%);
        display: flex; flex-direction: column; flex-wrap: nowrap; align-items: flex-start;
        padding: 84px 18px 20px; gap: 3px;
        transform: translateX(-100%);
        transition: transform .3s var(--ease);
        box-shadow: var(--shadow-lg);
        z-index: 2000; overflow-y: auto; overflow-x: hidden;
    }
    .public-nav-links::before {
        content: ''; position: absolute; top: 0; left: 0; right: 0; height: 4px;
        background: linear-gradient(90deg, var(--brand), var(--accent));
    }
    .public-nav-links.open { transform: translateX(0); }

    /* Each row reads as a soft "pill" — a colored accent bar grows in on
       hover/tap on the left edge, with a gentle tinted background so the
       tap target itself is visually obvious. Login and Apply Now are
       ordinary draggable items in this same list now (see
       superuser/nav_menu.php), so this rule reaches them too by default —
       the .nav-cta override just below restores their button look. */
    .public-nav-links > a {
        display: flex; align-items: center; width: 100%;
        padding: 13px 14px; margin: 0; border-radius: 12px;
        font-weight: 600; color: var(--text); position: relative;
        transition: background .15s var(--ease), color .15s var(--ease), padding-left .15s var(--ease);
    }
    .public-nav-links > a::before {
        content: ''; position: absolute; left: 0; top: 50%; transform: translateY(-50%);
        width: 3px; height: 0; border-radius: 3px; background: var(--accent);
        transition: height .15s var(--ease);
    }
    .public-nav-links > a:hover, .public-nav-links > a:active {
        background: rgba(14, 92, 82, .08); color: var(--brand-dark);
        padding-left: 18px; text-decoration: none;
    }
    .public-nav-links > a:hover::before, .public-nav-links > a:active::before { height: 20px; }

    /* Login keeps a full-width, centered "button row" layout wherever it's
       dragged to — its actual colors/border come from the site-wide
       .btn.btn-outline classes on the element itself, which already win
       over the plain .public-nav-links > a rule above on specificity
       alone (two classes beats one class + element), same reasoning as
       the desktop stylesheet. This class only carries the layout part. */
    .public-nav-links > a.nav-cta {
        justify-content: center; text-align: center; margin-top: 4px;
    }
    .public-nav-links > a.nav-cta::before { display: none; }

    .nav-dropdown { width: 100%; }
    .nav-dropdown-toggle {
        display: flex; align-items: center; justify-content: space-between;
        width: 100%; padding: 13px 14px; margin: 0; border-radius: 12px;
        background: none; border: none; font: inherit; font-weight: 600;
        text-align: left; color: var(--text); cursor: pointer;
        transition: background .15s var(--ease), color .15s var(--ease);
    }
    .nav-dropdown-toggle:hover, .nav-dropdown.open .nav-dropdown-toggle { background: rgba(14, 92, 82, .08); color: var(--brand-dark); }
    .nav-dropdown.open .nav-dropdown-toggle .icon { transform: rotate(180deg); color: var(--accent); }
    /* Apply Now keeps its solid CTA look wherever it's dragged to — same
       reasoning as the desktop .nav-dropdown-toggle.nav-cta-toggle rule
       near the top of this file, needed again here because the flat
       .nav-dropdown-toggle rule just above would otherwise win by being
       an ordinary item in this list now instead of living inside
       .nav-account. */
    .nav-dropdown-toggle.nav-cta-toggle {
        background: var(--brand); color: #fff; justify-content: center;
        margin-top: 4px; border-radius: 999px;
    }
    .nav-dropdown-toggle.nav-cta-toggle:hover,
    .nav-dropdown.open .nav-dropdown-toggle.nav-cta-toggle { background: var(--brand-dark); color: #fff; }
    .nav-dropdown-toggle.nav-cta-toggle .icon { margin-left: 2px; }
    /* Collapsed by default — a tap on the toggle above adds .open (see
       site.js), the same "tap to reveal" pattern as every other
       collapsible list on this platform, instead of dumping every
       submenu open at once. */
    .nav-dropdown-menu {
        position: static; display: none; box-shadow: none; border: none; background: transparent;
        padding: 4px 0 6px 20px; margin: 2px 0 4px; min-width: 0;
        border-left: 2px solid rgba(14, 92, 82, .25);
    }
    .nav-dropdown.open .nav-dropdown-menu { display: block; }
    .nav-dropdown-menu a { color: var(--muted); padding: 9px 10px; border-radius: 9px; font-weight: 500; }
    .nav-dropdown-menu a:hover { background: rgba(14, 92, 82, .08); color: var(--brand-dark); }
    .nav-dropdown-menu-mega { grid-template-rows: none; grid-auto-flow: row; grid-auto-columns: auto; column-gap: 0; min-width: 0; }
    .nav-dropdown.open .nav-dropdown-menu-mega { display: block; }

    /* Account actions (Portal / Log out once signed in) sit visually apart
       from the primary nav — a top divider plus margin-top:auto pins the
       group toward the bottom of the drawer when there's spare height, the
       pattern most people recognise from native app menus. Login and
       Apply Now are ordinary draggable items now (see
       superuser/nav_menu.php) and no longer live in here — their CTA look
       is handled by the .nav-cta / .nav-cta-toggle rules above instead. */
    .nav-account {
        width: 100%; margin-top: auto; padding-top: 14px;
        border-top: 1px solid var(--border);
        display: flex; flex-direction: column; gap: 3px;
    }
    .nav-account a.btn { width: 100%; padding: 13px 14px; justify-content: center; margin-top: 4px; font-size: 1em; }

    /* Dim backdrop behind the open drawer — injected by site.js. Faded in
       via opacity rather than an abrupt display swap so opening the menu
       feels like one smooth motion; still a real element the whole time
       (not display:none while "hidden"), so it can never end up
       intercepting clicks meant for the drawer above it. */
    .nav-overlay {
        position: fixed; top: 0; right: 0; bottom: 0; left: 0;
        background: rgba(15, 23, 42, .5);
        -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px);
        z-index: 1999; opacity: 0; visibility: hidden; pointer-events: none;
        transition: opacity .25s var(--ease), visibility 0s linear .25s;
    }
    .nav-overlay.open {
        opacity: 1; visibility: visible; pointer-events: auto;
        transition: opacity .25s var(--ease), visibility 0s linear 0s;
    }
}

.public-main { min-height: 60vh; }

.hero {
    background: linear-gradient(155deg, var(--brand) 0%, var(--brand-dark) 100%);
    color: #fff; padding: 72px 25px 84px; text-align: center;
}
.hero-badge { display: inline-flex; align-items: center; gap: 6px; background: rgba(255,255,255,.14); padding: 6px 16px; border-radius: 999px; font-size: .82rem; font-weight: 700; letter-spacing: .03em; margin-bottom: 18px; }
.hero h1 { color: #fff; max-width: 780px; margin: 0 auto .4em; }
.hero p { max-width: 620px; margin: 0 auto 28px; color: rgba(255,255,255,.88); font-size: 1.08rem; }
.hero .btn-group { justify-content: center; }
.hero-stats { display: flex; gap: 34px; justify-content: center; margin-top: 40px; flex-wrap: wrap; }
.hero-stat-value { font-family: var(--font-head); font-size: 1.8rem; font-weight: 700; }
.hero-stat-label { font-size: .8rem; color: rgba(255,255,255,.75); text-transform: uppercase; letter-spacing: .04em; }

.section-head { text-align: center; max-width: 640px; margin: 0 auto 40px; }
.section-eyebrow { color: var(--accent); font-weight: 800; letter-spacing: .08em; text-transform: uppercase; font-size: .78rem; }

/* margin-bottom matches p's own rhythm (margin:0 0 1em) — headings carry
   no margin-top of their own (h1-h4 { margin: 0 0 .5em }), so any content
   that follows a grid relies entirely on the grid's bottom margin for
   spacing. A CSS grid never lets a child's margin collapse through it,
   so without this a heading placed right after a grid (e.g. "Lessons"
   after programme.php's subjects grid) sits noticeably tighter than the
   same heading would after a plain paragraph. Sibling block margins
   collapse as normal, so this never doubles up with a following
   element's own margin-top. */
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; margin-bottom: 1em; }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; margin-bottom: 1em; }
.grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; margin-bottom: 1em; }
/* CSS Grid tracks default to min-width:auto, so a child with a long unbroken string (a title, a URL) can force the whole grid wider than its container and cause page-level horizontal scroll — allow tracks to shrink below content size instead. */
.grid-3 > *, .grid-2 > *, .grid-4 > * { min-width: 0; }
@media (max-width: 900px) { .grid-3, .grid-4 { grid-template-columns: 1fr 1fr; } }
@media (max-width: 640px) { .grid-3, .grid-2, .grid-4 { grid-template-columns: 1fr; } }

.feature-card { background: #fff; border: 1px solid var(--border); border-radius: var(--radius); padding: 26px; box-shadow: var(--shadow); transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease; }
.feature-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg); border-color: var(--brand); }
.feature-icon { width: 46px; height: 46px; border-radius: 12px; background: var(--brand-light); color: var(--brand); display: flex; align-items: center; justify-content: center; margin-bottom: 14px; }
.feature-icon .icon { width: 24px; height: 24px; }
.link-arrow { display: inline-block; margin-top: 10px; font-weight: 700; color: var(--brand); text-decoration: none; font-size: .92rem; }
.link-arrow:hover { text-decoration: underline; }
.subject-locked-out { opacity: .4; filter: grayscale(.4); }
.subject-locked-out:hover { border-color: var(--border); }

/* Live-search match highlighting — used sitewide wherever a data-live-search or data-live-search-cards input is present. */
mark.js-hl { background: #FFE8A3; color: inherit; padding: 0 1px; border-radius: 2px; }

.subject-card {
    background: #fff; border: 1px solid var(--border); border-radius: var(--radius); padding: 24px;
    box-shadow: var(--shadow); display: flex; flex-direction: column; gap: 10px; transition: transform .15s ease, box-shadow .15s ease;
}
.subject-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg); }
.subject-card .subject-number { font-family: var(--font-head); color: var(--accent); font-weight: 700; font-size: .85rem; letter-spacing: .06em; }
.subject-card h3 { margin-bottom: 4px; }
.subject-card .subject-price { font-weight: 800; color: var(--brand); font-size: 1.15rem; margin-top: auto; }

/* ---- programme.php: subjects rendered as cards (linked whole-card), with a
   richer hover treatment than the plain .subject-card — an accent top bar
   that slides in, the title tinting brand-green, and the CTA arrow nudging
   right, on top of the usual lift + shadow. ---- */
.programme-subjects-grid { grid-template-columns: repeat(2, 1fr); }
@media (max-width: 640px) { .programme-subjects-grid { grid-template-columns: 1fr; } }
.programme-subject-card {
    position: relative; text-decoration: none; color: inherit; cursor: pointer;
    border-top: 3px solid transparent; transition: transform .18s var(--ease, ease), box-shadow .18s var(--ease, ease), border-color .18s var(--ease, ease);
}
.programme-subject-card:hover { border-top-color: var(--accent); text-decoration: none; }
.programme-subject-card:hover h3 { color: var(--brand); }
.programme-subject-card h3 { transition: color .15s ease; }
.programme-subject-card-cta { align-self: flex-start; pointer-events: none; transition: gap .15s ease, background .15s ease, color .15s ease; }
.programme-subject-card-cta .icon { transition: transform .18s ease; }
.programme-subject-card:hover .programme-subject-card-cta { background: var(--brand); color: #fff; border-color: var(--brand); }
.programme-subject-card:hover .programme-subject-card-cta .icon { transform: translateX(4px); }
.lesson-sponsor-line { display: flex; align-items: center; gap: 6px; }
.sponsor-card .card-header { display: flex; align-items: center; gap: 8px; }
.lesson-sponsor-line { border-top: 1px dashed var(--border); margin-top: 18px; padding-top: 14px; }
.subject-card { overflow: hidden; }
.sponsor-banner {
    background: var(--brand); color: #fff; font-weight: 700; font-size: .92rem;
    padding: 10px 24px; display: flex; align-items: center; gap: 8px;
    margin: 0 -24px; width: calc(100% + 48px);
    cursor: pointer; transition: background .12s ease; border: none;
}
.sponsor-banner:hover, .sponsor-banner:focus-visible { background: var(--brand-dark); outline: none; }
.sponsor-banner .icon { flex: 0 0 auto; }
.sponsor-card .card-header[role="button"] { cursor: pointer; }
.sponsor-card .card-header[role="button"]:hover { background: var(--brand-light); }

.subject-pager { display: flex; align-items: stretch; justify-content: space-between; gap: 14px; margin-top: 36px; padding-top: 26px; border-top: 1px solid var(--border); flex-wrap: wrap; }
.subject-pager a { display: flex; align-items: center; gap: 8px; text-align: left; }
.subject-pager-prev .icon { transform: scaleX(-1); }
.subject-pager-prev, .subject-pager-next { max-width: 300px; }
.subject-pager-next { margin-left: auto; text-align: right; }
.subject-pager-next span { text-align: right; }
@media (max-width: 720px) { .subject-pager { flex-direction: column; } .subject-pager-next { margin-left: 0; } }

.cv-video-card { background: #fff; border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; box-shadow: var(--shadow); transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease; }
.cv-video-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg); border-color: var(--brand); }
.cv-video-card h4 { margin: 14px 16px 4px; }
.cv-video-card p { margin: 0 16px 16px; }
.video-embed { position: relative; width: 100%; padding-top: 56.25%; background: #000; }
.video-embed iframe { position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: 0; }

.guide-card { background: #fff; border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; box-shadow: var(--shadow); display: flex; flex-direction: column; transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease; }
.guide-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg); border-color: var(--brand); }
.guide-card-image { position: relative; width: 100%; padding-top: 70%; background: var(--brand-light); }
.guide-card-image img { position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; }
.guide-card-badge { position: absolute; top: 10px; left: 10px; }
.guide-card-body { padding: 16px 18px 18px; display: flex; flex-direction: column; flex: 1; gap: 6px; }
.guide-card-body, .guide-card-body * { overflow-wrap: break-word; }
.guide-card-body h4 { margin: 0; }
.subject-select-card { border: 2px solid var(--border); border-radius: var(--radius); padding: 18px 20px; display: flex; align-items: flex-start; gap: 14px; cursor: pointer; background: #fff; transition: border-color .12s ease, background .12s ease; }
.subject-select-card:hover { border-color: var(--accent); }
.subject-select-card:has(input:checked) { border-color: var(--brand); background: var(--brand-light); }
.subject-select-card:has(input:checked):hover { border-color: var(--brand); }
.subject-select-card input { width: auto; margin: 3px 0 0; }
.subject-select-card .subject-select-title { font-weight: 700; color: var(--ink); }
.subject-select-card .subject-select-price { color: var(--brand); font-weight: 700; }
.career-service-card input[type="checkbox"] { width: auto; margin: 0; }

/* Apply Now, step 2 — "Pick subjects individually" vs "Pay for a whole
   programme" segmented toggle (see apply.php). Two equal-width pill
   buttons in a rounded track, matching the site's radius/shadow tokens
   rather than reusing .tabs-nav (which only styles <button>, not the
   radio+label pair this needs so a native radiogroup stays keyboard-
   and screen-reader-friendly). */
.enrollment-toggle { display: flex; background: var(--bg); border: 1px solid var(--border); border-radius: 999px; padding: 4px; gap: 4px; margin-bottom: 18px; max-width: 480px; }
.enrollment-toggle label { flex: 1; display: flex; align-items: center; justify-content: center; text-align: center; gap: 6px; padding: 10px 16px; margin-bottom: 0; border-radius: 999px; font-family: var(--font-head); font-weight: 700; font-size: .92rem; line-height: 1.25; color: var(--muted); cursor: pointer; transition: background .12s ease, color .12s ease, box-shadow .12s ease; }
.enrollment-toggle input { position: absolute; opacity: 0; width: 1px; height: 1px; pointer-events: none; }
.enrollment-toggle label:has(input:checked) { background: var(--brand); color: #fff; box-shadow: var(--shadow); }
.enrollment-toggle label:hover:not(:has(input:checked)) { color: var(--ink); }
@media (max-width: 560px) { .enrollment-toggle { flex-direction: column; border-radius: var(--radius-sm); max-width: none; } .enrollment-toggle label { border-radius: 6px; } }

/* Whole-programme picker — a plain <select> (apply.php) instead of a
   long list of radio cards, so a platform with many programmes doesn't
   push the fee card off screen; .whole-program-summary echoes the
   picked option's price/promo once chosen, reusing the same visual
   language as .subject-select-card so it doesn't look like a second,
   unrelated component. */
.whole-program-picker { max-width: 480px; }
.whole-program-summary { border: 2px solid var(--brand); border-radius: var(--radius); padding: 18px 20px; display: flex; align-items: flex-start; gap: 14px; background: var(--brand-light); margin-top: 14px; }
.whole-program-summary .subject-select-title { font-weight: 700; color: var(--ink); }
.whole-program-summary .subject-select-price { color: var(--brand); font-weight: 700; white-space: nowrap; }

/* Apply Now, "Pick subjects individually" — one accordion row per
   subject rather than one wide flex card. A long title or summary used
   to sit inline in a single row and could force the whole page to
   scroll sideways on a narrow phone; now the row itself only ever
   holds a checkbox, a short title and a price, and the summary lives
   in a collapsed panel underneath. Only one row's panel is open at a
   time — see [data-subject-pick-accordion] in apply.php. */
.subject-pick-item { border: 2px solid var(--border); border-radius: var(--radius); background: #fff; overflow: hidden; transition: border-color .12s ease, background .12s ease; }
.subject-pick-item:has(.subject-pick-check input:checked) { border-color: var(--brand); background: var(--brand-light); }
.subject-pick-row { display: flex; align-items: center; gap: 10px; padding: 14px 16px; min-width: 0; }
.subject-pick-check { display: flex; align-items: center; gap: 8px; flex: 1 1 auto; min-width: 0; margin-bottom: 0; font-weight: 400; cursor: pointer; }
.subject-pick-check input { width: auto; margin: 0; flex-shrink: 0; }
.subject-pick-title { font-weight: 700; color: var(--ink); overflow-wrap: anywhere; }
.subject-pick-price { flex-shrink: 0; color: var(--brand); font-weight: 700; white-space: nowrap; }
.subject-pick-expand { flex-shrink: 0; width: 30px; height: 30px; display: flex; align-items: center; justify-content: center; border: 1px solid var(--border); border-radius: 50%; background: none; cursor: pointer; color: var(--muted); transition: transform .15s ease, background .12s ease, color .12s ease; }
.subject-pick-expand:hover { background: var(--brand-light); color: var(--brand); }
.subject-pick-item.open .subject-pick-expand { transform: rotate(180deg); color: var(--brand); }
.subject-pick-panel { padding: 0 16px 16px; border-top: 1px solid var(--border); }
.subject-pick-panel p { margin: 12px 0 0; }
@media (max-width: 480px) {
    .subject-pick-row { flex-wrap: wrap; }
    .subject-pick-price { margin-left: 38px; }
}

/* Subject-selection accordion (e.g. superuser/sponsors.php's "sponsored
   subjects" picker) — categorises a long list of subject checkboxes
   under a per-programme accordion. Unlike the sidebar's accordion,
   multiple groups can be open at once here, since choosing subjects
   often spans programmes. See [data-subject-accordion] in site.js. */
.subject-accordion { display: flex; flex-direction: column; gap: 6px; }
.subject-accordion-group { border: 2px solid var(--border); border-radius: var(--radius); overflow: hidden; background: #fff; }
.subject-accordion-group-needscontent { border-color: #8C2A24; }
.subject-accordion-group-needscontent > .subject-accordion-toggle { background: var(--danger-bg); }
.subject-accordion-toggle { width: 100%; display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 14px 18px; background: var(--brand-light, #F7F8FA); border: 0; cursor: pointer; font-weight: 700; color: var(--ink); text-align: left; font-size: .96rem; }
.subject-accordion-toggle:hover { background: var(--accent-light, var(--brand-light)); }
.subject-accordion-group.open > .subject-accordion-toggle { color: var(--brand); }
.subject-accordion-group.open > .subject-accordion-toggle .sidebar-accordion-caret { transform: rotate(180deg); }
.subject-accordion-title { display: flex; align-items: center; gap: 8px; }
.subject-accordion-count { font-size: .78rem; font-weight: 600; color: var(--muted); white-space: nowrap; margin-left: auto; }
.subject-accordion-panel { display: none; flex-direction: column; gap: 10px; padding: 16px 18px; border-top: 1px solid var(--border); }
.subject-accordion-group.open .subject-accordion-panel { display: flex; }
/* A bulk-select checkbox rendered as a sibling of .subject-accordion-toggle
   (never nested inside it — a <button> can't validly contain another
   interactive control) but visually pinned to its top-left corner, so a
   row can be selected for bulk action without expanding it. Fixed top
   offset rather than centering: the group's own box height grows once
   its panel opens, so a vertically-centered position would drift down. */
.subject-accordion-group.has-select-checkbox { position: relative; }
.subject-accordion-group.has-select-checkbox > .subject-accordion-toggle { padding-left: 44px; }
.subject-accordion-group .group-select-checkbox { position: absolute; left: 16px; top: 16px; z-index: 2; width: auto; margin: 0; }
/* Compact key/value facts shown inside an accordion panel (used by the
   redesigned superuser/programmes.php so a programme's detail fields
   don't need a full table row each). */
.accordion-fact-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 10px 18px; margin-bottom: 4px; }
.accordion-fact-grid .fact-label { font-size: .74rem; font-weight: 600; text-transform: uppercase; letter-spacing: .02em; color: var(--muted); display: block; }
.accordion-fact-grid .fact-value { font-size: .92rem; }
@media (max-width: 640px) {
    .subject-accordion-toggle { flex-wrap: wrap; padding: 12px 14px; }
    .subject-accordion-count { margin-left: 0; }
}

/* Responsive tables — below 960px every table.table stacks each row into
   label/value blocks instead of needing horizontal scroll (site-wide "no
   horizontal scrolling" requirement; the .card-body { overflow-x: auto }
   rule elsewhere is a safety net for anything this doesn't catch, not the
   primary fix for our own tables). Labels are injected automatically onto
   each <td data-label> by site.js from the table's own <thead> — no
   per-page template changes needed anywhere this class is used. Raised
   from 700px to 960px because wider admin tables (Fees Summary, Training
   Programs — many columns / button-heavy action cells) were still
   overflowing their card and triggering the .card-body scroll fallback
   on tablet and narrow-laptop widths, which is exactly the horizontal
   scrolling this rule exists to avoid. */
@media (max-width: 960px) {
    table.table thead { display: block; position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; padding: 0; margin: -1px; }
    table.table, table.table tbody, table.table tr, table.table td { display: block; width: 100%; box-sizing: border-box; max-width: 100%; }
    table.table tr { border: 1px solid var(--border); border-radius: var(--radius); margin-bottom: 12px; padding: 10px 14px; background: #fff; }
    /* Label above value (not side-by-side) — robust against rich cell
       content (chips, badges, multi-line text) that would otherwise fight
       a flex row for width and re-introduce horizontal overflow. */
    table.table td { border: none !important; border-bottom: 1px solid var(--border); padding: 8px 0 !important; white-space: normal !important; overflow-wrap: anywhere; }
    table.table td * { max-width: 100% !important; white-space: normal !important; }
    table.table td:last-child { border-bottom: none; }
    table.table td[data-label]:before { content: attr(data-label); display: block; font-size: .72rem; text-transform: uppercase; letter-spacing: .03em; color: var(--muted); font-weight: 700; margin-bottom: 4px; }
    table.table td:not([data-label]) { text-align: center; }
    table.table td.bulk-select-col { text-align: left; }
}

/* Accordion rows — for tables too column-dense to ever fit without a
   sideways scroll, at any normal screen width (Payments, Revision
   Guides, Registration Report detailed roster). Each row is a native
   <details>: collapsed by default it shows only the key identifying
   fields (and, where the row has actions like Confirm/Reject or
   Edit/Delete, those stay visible too so nothing requires expanding
   just to act on it); expanded, the rest of the row's fields list
   below as stacked label/value pairs. Content only ever grows
   downward, so this never needs — and never gets — a horizontal
   scrollbar, unlike the plain .table-wrap overflow-x fallback. */
.acc-list { display: flex; flex-direction: column; }
.acc-item { border-bottom: 1px solid var(--border); }
.acc-item:last-child { border-bottom: none; }
.acc-item > summary { list-style: none; cursor: pointer; padding: 14px 22px; display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.acc-item > summary::-webkit-details-marker { display: none; }
.acc-summary-main { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; min-width: 0; flex: 1 1 260px; }
.acc-summary-main strong { overflow-wrap: anywhere; }
.acc-summary-side { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.acc-caret { color: var(--muted); font-size: .8em; transition: transform .15s; flex-shrink: 0; }
.acc-item[open] .acc-caret { transform: rotate(180deg); }
.acc-body { padding: 12px 22px 16px; display: flex; flex-direction: column; gap: 10px; border-top: 1px solid var(--border); margin: 0 22px; }
.acc-field { display: flex; flex-direction: column; gap: 2px; }
.acc-field-label { font-size: .72rem; text-transform: uppercase; letter-spacing: .03em; color: var(--muted); font-weight: 700; }
.acc-field-value { overflow-wrap: anywhere; }
.acc-thumb { width: 40px; height: 40px; object-fit: cover; border-radius: 6px; border: 1px solid var(--border); flex-shrink: 0; }

/* Fees Summary and Training Programs: above the 960px stacking breakpoint
   these still overflowed on ordinary desktop widths, because their many
   text-heavy columns (subject/title, programme list, discount note,
   button-heavy action cell) have no natural width limit and just keep
   growing until the row is wider than the card, re-triggering the
   .card-body horizontal-scroll fallback — raising the stacking breakpoint
   alone doesn't fix a table that's simply too wide at full size. Giving
   these two tables a fixed layout with percentage column widths forces
   long content to wrap within its column instead of stretching the
   table, so they fit the card at any desktop width without scrolling. */
@media (min-width: 961px) {
    /* Generic fallback for every other admin table on the site: fixed
       layout with evenly-distributed, wrapping columns so a table with
       many columns (or one long value) can't force itself wider than
       its card and re-trigger the .card-body overflow-x fallback at
       ordinary desktop widths. Tables with more specific needs (Fees
       Summary, Training, Ads, Programmes below) get hand-tuned
       percentage/pixel column widths instead — those ID selectors win
       over this element selector regardless of source order. */
    .card-body table.table { table-layout: fixed; }
    .card-body table.table th, .card-body table.table td { overflow-wrap: break-word; white-space: normal; }

    #feesTable, #trainingTable, #adsTable, #programmesTable { table-layout: fixed; }
    #feesTable th, #feesTable td, #trainingTable th, #trainingTable td, #adsTable th, #adsTable td, #programmesTable th, #programmesTable td { overflow-wrap: break-word; white-space: normal; }
    #feesTable .bulk-select-col { width: 34px; }
    #feesTable th:nth-child(2), #feesTable td:nth-child(2) { width: 10%; }
    #feesTable th:nth-child(3), #feesTable td:nth-child(3) { width: 26%; }
    #feesTable th:nth-child(4), #feesTable td:nth-child(4) { width: 17%; }
    #feesTable th:nth-child(5), #feesTable td:nth-child(5) { width: 10%; }
    #feesTable th:nth-child(6), #feesTable td:nth-child(6) { width: 24%; }
    #feesTable th:nth-child(7), #feesTable td:nth-child(7) { width: 70px; }
    #trainingTable .bulk-select-col { width: 34px; }
    #trainingTable th:nth-child(2), #trainingTable td:nth-child(2) { width: 38%; }
    #trainingTable th:nth-child(3), #trainingTable td:nth-child(3) { width: 12%; }
    #trainingTable th:nth-child(4), #trainingTable td:nth-child(4) { width: 30%; }
    #trainingTable th:nth-child(5), #trainingTable td:nth-child(5) { width: 10%; }
    #trainingTable th:nth-child(6), #trainingTable td:nth-child(6) { width: 150px; }
    #adsTable .bulk-select-col { width: 34px; }
    #adsTable th:nth-child(2), #adsTable td:nth-child(2) { width: 24%; }
    #adsTable th:nth-child(3), #adsTable td:nth-child(3) { width: 15%; }
    #adsTable th:nth-child(4), #adsTable td:nth-child(4) { width: 12%; }
    #adsTable th:nth-child(5), #adsTable td:nth-child(5) { width: 16%; }
    #adsTable th:nth-child(6), #adsTable td:nth-child(6) { width: 8%; }
    #adsTable th:nth-child(7), #adsTable td:nth-child(7) { width: 7%; }
    #adsTable th:nth-child(8), #adsTable td:nth-child(8) { width: 9%; }
    #adsTable th:nth-child(9), #adsTable td:nth-child(9) { width: 150px; }
    /* Programmes: same fixed-layout treatment — the actions column used
       to hold four icon+text buttons with no width limit (see
       superuser/programmes.php), which alone was wide enough to force
       the whole table past the card on ordinary desktop widths. Now
       paired with icon-only action buttons there so a real 150px column
       comfortably fits all four, wrapping to a second line if it ever
       needs to rather than stretching the table. */
    #programmesTable .bulk-select-col { width: 34px; }
    #programmesTable th:nth-child(2), #programmesTable td:nth-child(2) { width: 28%; }
    #programmesTable th:nth-child(3), #programmesTable td:nth-child(3) { width: 9%; }
    #programmesTable th:nth-child(4), #programmesTable td:nth-child(4) { width: 9%; }
    #programmesTable th:nth-child(5), #programmesTable td:nth-child(5) { width: 9%; }
    #programmesTable th:nth-child(6), #programmesTable td:nth-child(6) { width: 17%; }
    #programmesTable th:nth-child(7), #programmesTable td:nth-child(7) { width: 9%; }
    #programmesTable th:nth-child(8), #programmesTable td:nth-child(8) { width: 150px; }

    /* Promotions: same fixed-layout treatment -- the actions column (edit
       icon, Activate/Deactivate text button, delete icon) has no width
       limit under the generic fallback above, so it was the widest thing
       in the row and pushed the whole table past the card, triggering
       the .card-body horizontal-scroll fallback. A dedicated 150px column
       (matching the other hand-tuned tables) fits all three controls,
       wrapping to a second line via the td's flex-wrap if it ever needs to. */
    #promotionsTable th:nth-child(1), #promotionsTable td:nth-child(1) { width: 14%; }
    #promotionsTable th:nth-child(2), #promotionsTable td:nth-child(2) { width: 26%; }
    #promotionsTable th:nth-child(3), #promotionsTable td:nth-child(3) { width: 13%; }
    #promotionsTable th:nth-child(4), #promotionsTable td:nth-child(4) { width: 15%; }
    #promotionsTable th:nth-child(5), #promotionsTable td:nth-child(5) { width: 15%; }
    #promotionsTable th:nth-child(6), #promotionsTable td:nth-child(6) { width: 10%; }
    #promotionsTable th:nth-child(7), #promotionsTable td:nth-child(7) { width: 150px; }
}

/* superuser/subjects.php redesign: collapsible "Add a new subject" panel,
   table search box, programme chips, subject title/summary cell, and a
   tidier wrapping action-button row for each subject. */
.panel-toggle-caret { transition: transform .2s ease; font-size: .85em; }
[data-panel-toggle].open .panel-toggle-caret,
[data-panel-toggle].open [data-panel-toggle-caret] { transform: rotate(180deg); }
.panel-toggle-body { border-top: 1px solid var(--border); }

.table-search-wrap { position: relative; max-width: 380px; }
.table-search-wrap .table-search-icon { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); color: var(--muted); display: flex; }
.table-search-wrap .table-search-icon svg { width: 16px; height: 16px; }
.table-search { width: 100%; padding: 9px 12px 9px 34px; border: 1px solid var(--border); border-radius: var(--radius); font-size: .92rem; background: #fff; }
.table-search:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-light); }

.subject-cell-title { font-weight: 700; color: var(--ink); }
.subject-cell-summary { margin-top: 2px; max-width: 280px; }

.programme-chip-list { display: flex; flex-wrap: wrap; gap: 5px; max-width: 220px; }
.programme-chip { display: inline-block; background: var(--brand-light); color: var(--brand); font-size: .74rem; font-weight: 700; padding: 3px 9px; border-radius: 999px; white-space: nowrap; }

.row-actions { display: flex; gap: 6px; flex-wrap: wrap; }
.row-actions form { display: inline-flex; }

/* superuser/subjects.php accordion rows — a flex/wrap row instead of a
   table, so a subject with many columns of info (fee, content status,
   actions…) never needs horizontal scroll: it just wraps onto more
   lines on a narrow screen. */
.subject-row { display: flex; align-items: flex-start; gap: 14px; flex-wrap: wrap; padding: 12px 0; border-bottom: 1px solid var(--border); }
.subject-row:last-child { border-bottom: 0; }
.subject-row-nocontent { background: var(--danger-bg); border-left: 3px solid #8C2A24; padding-left: 11px; margin-left: -14px; border-radius: 0 var(--radius) var(--radius) 0; }
.subject-row-partial { background: var(--warning-bg); border-left: 3px solid #7A4E0D; padding-left: 11px; margin-left: -14px; border-radius: 0 var(--radius) var(--radius) 0; }
.acc-item-nocontent { background: var(--danger-bg); border-left: 3px solid #8C2A24; }
.acc-item-partial { background: var(--warning-bg); border-left: 3px solid #7A4E0D; }
.subject-row > input[type="checkbox"] { margin-top: 4px; flex-shrink: 0; }
.subject-row-main { flex: 1 1 220px; min-width: 180px; }
.subject-row-meta { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; flex: 0 1 auto; font-size: .88rem; }
@media (max-width: 480px) {
    .subject-row-meta { width: 100%; padding-left: 30px; }
}

/* portal/consolidate.php: "consolidate a complete programme" shortcut rows */
.programme-consolidate-row { display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap; padding: 12px 0; border-top: 1px solid var(--border); }
.programme-consolidate-row:first-of-type { border-top: 0; padding-top: 4px; }

.pricing-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 22px; }
.pricing-card { background: #fff; border: 1px solid var(--border); border-radius: var(--radius); padding: 26px; box-shadow: var(--shadow); display: flex; flex-direction: column; transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease; }
.pricing-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg); border-color: var(--brand); }
.pricing-name { font-weight: 700; font-family: var(--font-head); font-size: 1.1rem; }
.pricing-price { font-size: 1.7rem; font-weight: 800; color: var(--brand); margin: 6px 0; }
.pricing-desc { color: var(--muted); font-size: .92rem; }
.pricing-features { list-style: none; padding: 0; margin: 10px 0 18px; font-size: .9rem; }
.pricing-features li { padding: 6px 0 6px 24px; position: relative; border-bottom: 1px dashed var(--border); }
.pricing-features li::before { content: "✓"; position: absolute; left: 0; color: var(--success); font-weight: 700; }

.cta-band { background: var(--accent-light); border-radius: var(--radius); padding: 40px 30px; text-align: center; margin: 20px auto; }
.cta-band h2 { margin-bottom: 8px; }

.faq-item { border-bottom: 1px solid var(--border); padding: 16px 0; }
.faq-item summary { cursor: pointer; font-weight: 700; color: var(--ink); list-style: none; display: flex; justify-content: space-between; align-items: center; }
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after { content: "+"; font-size: 1.3rem; color: var(--brand); }
.faq-item[open] summary::after { content: "–"; }
.faq-item p { margin-top: 10px; color: var(--muted); }

.faq-cat-nav { display: flex; flex-wrap: wrap; gap: 10px; margin: 0 0 30px; }
.faq-cat-nav a { display: inline-flex; align-items: center; gap: 6px; padding: 8px 16px; border: 1px solid var(--border); border-radius: 999px; font-size: .88rem; font-weight: 600; color: var(--ink); background: #fff; text-decoration: none; transition: border-color .15s ease, color .15s ease; }
.faq-cat-nav a:hover { border-color: var(--brand); color: var(--brand); }
.faq-cat-nav .icon-sm { width: 15px; height: 15px; }
.faq-cat-card { scroll-margin-top: 90px; margin-bottom: 30px; }
.faq-cat-card .card-header { display: flex; align-items: center; gap: 10px; font-size: 1.15rem; background: var(--brand-light); }
.faq-cat-card .card-header .icon { color: var(--brand); }
.faq-cat-card .card-body { padding: 6px 22px 10px; }
.faq-cat-card .faq-item:last-child { border-bottom: 0; }

.public-footer, .site-footer {
    background: var(--brand-dark); color: rgba(255,255,255,.82); padding: 48px 26px 24px; margin-top: 40px;
}
.footer-grid { display: grid; grid-template-columns: 2fr 1fr 1fr 1fr; gap: 28px; max-width: 1160px; margin: 0 auto; }
.footer-col h4 { color: #fff; font-size: .85rem; text-transform: uppercase; letter-spacing: .05em; margin-bottom: 12px; }
.footer-col a { display: block; color: rgba(255,255,255,.75); padding: 4px 0; font-size: .9rem; }
.footer-col a:hover { color: #fff; }
.footer-brand { display: flex; align-items: center; gap: 10px; color: #fff; font-family: var(--font-head); font-weight: 700; font-size: 1.1rem; margin-bottom: 10px; }
.footer-brand img { height: 32px; width: 32px; border-radius: 6px; }
.footer-blurb { color: rgba(255,255,255,.65); font-size: .88rem; max-width: 320px; }
.footer-bottom { max-width: 1160px; margin: 30px auto 0; padding-top: 18px; border-top: 1px solid rgba(255,255,255,.14); font-size: .82rem; color: rgba(255,255,255,.6); display: flex; justify-content: space-between; flex-wrap: wrap; gap: 10px; }
.footer-credit-link { background: none; border: none; padding: 0; font: inherit; color: rgba(255,255,255,.85); text-decoration: underline; cursor: pointer; }
.footer-credit-link:hover { color: #fff; }
@media (max-width: 800px) { .footer-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 500px) { .footer-grid { grid-template-columns: 1fr; } }

.auth-wrap { display: flex; align-items: center; justify-content: center; min-height: 70vh; padding: 40px 20px; }
.auth-card { background: #fff; border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow-lg); padding: 34px; max-width: 440px; width: 100%; }
.auth-card h1 { text-align: center; }

.whatsapp-btn { background: #25D366; color: #fff; }
.whatsapp-btn:hover { background: #1DA851; }

/* ---- Follow-up / status lookup ---- */
.status-timeline { list-style: none; margin: 20px 0; padding: 0; }
.status-timeline li { padding: 10px 0 10px 30px; position: relative; border-left: 2px solid var(--border); margin-left: 10px; }
.status-timeline li:last-child { border-color: transparent; }
.status-timeline li::before { content: ""; position: absolute; left: -7px; top: 12px; width: 12px; height: 12px; border-radius: 50%; background: var(--border); }
.status-timeline li.done::before { background: var(--success); }
.status-timeline li.current::before { background: var(--accent); box-shadow: 0 0 0 4px var(--accent-light); }

/* =========================================================
   PORTAL (Superuser / Admin / Participant) — app shell
   ========================================================= */
.app-body { background: var(--bg); }
.topbar {
    display: flex; align-items: center; justify-content: space-between; gap: 16px;
    padding: 12px 22px; background: var(--brand-dark); color: #fff; position: sticky; top: 0; z-index: 60;
}
.topbar-user { display: flex; align-items: center; gap: 14px; }
.topbar-brand { display: flex; align-items: center; gap: 10px; font-family: var(--font-head); font-weight: 700; }
.topbar-brand img { height: 30px; width: 30px; border-radius: 6px; }
.sidebar-toggle { display: none; background: none; border: none; color: #fff; cursor: pointer; }
.topbar-role { background: rgba(255,255,255,.15); padding: 3px 12px; border-radius: 999px; font-size: .76rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; }
.topbar .btn-outline { border-color: rgba(255,255,255,.5); color: #fff; }
.topbar .btn-outline:hover { background: rgba(255,255,255,.12); }

.app-shell { display: flex; min-height: calc(100vh - 58px); }
.sidebar { width: 250px; flex: 0 0 250px; background: #fff; border-right: 1px solid var(--border); padding: 18px 12px; }
.sidebar nav a { display: flex; align-items: center; gap: 10px; padding: 10px 14px; border-radius: var(--radius-sm); color: var(--text); font-weight: 600; font-size: .9rem; margin-bottom: 2px; }
.sidebar nav a:hover { background: var(--brand-light); text-decoration: none; }
.sidebar nav a.active { background: var(--brand); color: #fff; }
.sidebar-icon .icon, .sidebar nav a .icon { width: 18px; height: 18px; flex: 0 0 auto; }
.sidebar-group-label { font-size: .72rem; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); font-weight: 700; margin: 16px 0 6px; padding: 0 14px; }
.sidebar-group:first-child .sidebar-group-label { margin-top: 4px; }

/* ---- Staff/superuser sidebar: live search + collapsible accordion groups.
   Modeled on Quiz_Platform_4's sidebar_superuser.php pattern (search box,
   one-open-at-a-time accordion, separated Danger zone) but kept in this
   site's own light theme/brand colors rather than importing that project's
   dark-navy reskin. The participant sidebar (below, in the else branch)
   still uses plain <div class="sidebar-group-label"> dividers, so that
   generic selector above stays untouched — everything here is scoped to
   the <button> version the staff nav renders instead. ---- */
.sidebar-search-wrap { position: relative; margin: 2px 2px 14px; }
.sidebar-search-icon { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); color: var(--muted); pointer-events: none; display: flex; }
.sidebar-search-icon .icon { width: 14px; height: 14px; }
.sidebar-search { width: 100%; padding: 9px 34px; border-radius: var(--radius-sm); border: 1px solid var(--border); background: #fff; font-size: .85rem; font-family: inherit; }
.sidebar-search::placeholder { color: var(--muted); }
.sidebar-search:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-light); }
.sidebar-search-kbd { position: absolute; right: 8px; top: 50%; transform: translateY(-50%); font-size: .68rem; color: var(--muted); border: 1px solid var(--border); border-radius: 5px; padding: 1px 6px; font-family: inherit; pointer-events: none; background: var(--brand-light); }
.sidebar-search:focus ~ .sidebar-search-kbd { display: none; }

button.sidebar-group-label {
    display: flex; align-items: center; justify-content: space-between; width: 100%;
    margin: 0; padding: 10px 14px; background: none; border: none; font-family: inherit; cursor: pointer;
    border-radius: var(--radius-sm); transition: background .15s ease, color .15s ease;
}
button.sidebar-group-label:hover { background: var(--brand-light); }
.sidebar-group.open > button.sidebar-group-label { color: var(--brand); }
.sidebar-accordion-caret { font-size: .8em; transition: transform .2s ease; flex: 0 0 auto; }
.sidebar-group.open .sidebar-accordion-caret { transform: rotate(180deg); }
/* Collapsed by default — JS toggles .open; while searching,
   #sidebarNav.searching forces every matching group's links visible
   regardless of .open so results across sections stay reachable without
   extra clicks. */
.sidebar-group-links { display: none; flex-direction: column; gap: 1px; }
.sidebar-group.open .sidebar-group-links,
#sidebarNav.searching .sidebar-group-links { display: flex; }
.sidebar-group[data-no-filter] .sidebar-group-links { display: flex; }

.sidebar-group-danger > button.sidebar-group-label { color: var(--danger); }
.sidebar-group-danger a { color: var(--danger); }
.sidebar-group-danger a:hover { background: rgba(214,72,63,.08); }
.sidebar-no-results { padding: 8px 14px; color: var(--muted); font-size: .85rem; font-style: italic; }

.main-content { flex: 1; padding: 26px 30px 60px; min-width: 0; }
.page-title { margin-bottom: 4px; }
.page-sub { color: var(--muted); margin-bottom: 24px; }

.impersonation-banner { background: var(--warning-bg); color: #7A4E0D; padding: 10px 22px; display: flex; align-items: center; gap: 10px; font-size: .9rem; font-weight: 600; flex-wrap: wrap; }

@media (max-width: 960px) {
    .sidebar-toggle { display: block; }
    .app-shell { position: relative; }
    .sidebar { position: fixed; left: -270px; top: 58px; bottom: 0; z-index: 55; transition: left .2s ease; box-shadow: var(--shadow-lg); overflow-y: auto; }
    .sidebar.open { left: 0; }
    .main-content { padding: 20px 16px 50px; }
}

/* ---- Lesson reader ---- */
.lesson-layout { display: grid; grid-template-columns: 260px 1fr; gap: 26px; align-items: start; }
@media (max-width: 900px) { .lesson-layout { grid-template-columns: 1fr; } }
.lesson-toc { background: #fff; border: 1px solid var(--border); border-radius: var(--radius); padding: 8px; position: sticky; top: 76px; }
.lesson-toc a { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border-radius: var(--radius-sm); font-size: .88rem; font-weight: 600; color: var(--text); }
.lesson-toc a.active { background: var(--brand-light); color: var(--brand-dark); }
.lesson-toc a.locked { color: var(--muted); pointer-events: none; }
.lesson-toc a.completed .lesson-toc-check { color: var(--success); }
.lesson-toc-check { width: 16px; height: 16px; flex: 0 0 auto; }
.lesson-content { background: #fff; border: 1px solid var(--border); border-radius: var(--radius); padding: 32px; box-shadow: var(--shadow); }
.lesson-content h2, .lesson-content h3 { margin-top: 1.2em; }
.lesson-content ul, .lesson-content ol { padding-left: 1.4em; }
.lesson-content table { width: 100%; border-collapse: collapse; margin: 1em 0; }
.lesson-content table th, .lesson-content table td { border: 1px solid var(--border); padding: 8px 10px; text-align: left; }
.lesson-nav { display: flex; justify-content: space-between; align-items: center; margin-top: 28px; padding-top: 20px; border-top: 1px solid var(--border); gap: 12px; flex-wrap: wrap; }

.progress-bar { height: 8px; background: var(--border); border-radius: 999px; overflow: hidden; }
.progress-bar-fill { height: 100%; background: var(--brand); border-radius: 999px; transition: width .3s ease; }
.progress-label { display: flex; justify-content: space-between; font-size: .82rem; color: var(--muted); margin-bottom: 6px; }

/* ---- Assessment (MCQ) ---- */
.quiz-question { margin-bottom: 22px; }
.quiz-question-text { font-weight: 700; margin-bottom: 12px; }
.quiz-options { list-style: none; padding: 0; margin: 0; display: grid; gap: 10px; }
.quiz-option { border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 12px 14px; display: flex; align-items: center; gap: 10px; cursor: pointer; }
.quiz-option:has(input:checked) { border-color: var(--brand); background: var(--brand-light); }
.quiz-option input { width: auto; margin: 0; }
.quiz-result-hero { text-align: center; padding: 30px 20px; }
.quiz-score-circle {
    width: 130px; height: 130px; border-radius: 50%; display: flex; align-items: center; justify-content: center; flex-direction: column;
    margin: 0 auto 16px; border: 8px solid var(--brand-light);
}
.quiz-score-circle.passed { border-color: var(--success); }
.quiz-score-circle.failed { border-color: var(--danger); }
.quiz-score-circle .score-value { font-size: 1.7rem; font-weight: 800; font-family: var(--font-head); }

/* ---- Notification bell (staff) ---- */
.notif-bell-wrap { position: relative; }
.notif-bell-btn { background: none; border: none; color: #fff; cursor: pointer; position: relative; padding: 6px; }
.notif-bell-badge { position: absolute; top: 0; right: 0; background: var(--danger); color: #fff; font-size: .65rem; font-weight: 800; border-radius: 999px; padding: 1px 5px; }
.notif-bell-dropdown { position: absolute; right: 0; top: calc(100% + 8px); background: #fff; border: 1px solid var(--border); border-radius: var(--radius-sm); box-shadow: var(--shadow-lg); min-width: 260px; max-width: calc(100vw - 24px); z-index: 70; }
.notif-bell-item { display: flex; justify-content: space-between; padding: 10px 14px; color: var(--text); font-size: .88rem; font-weight: 600; border-bottom: 1px solid var(--border); }
.notif-bell-item:last-child { border-bottom: none; }
.notif-bell-empty { padding: 16px; color: var(--muted); font-size: .88rem; text-align: center; }

/* On very narrow phones the right-hand topbar group (notif bell + role
   badge + name + logout) can wrap or overflow next to the sidebar
   toggle/brand on the left. Drop the role badge and let the name shrink
   so the row always fits on one line without horizontal scroll. */
@media (max-width: 480px) {
    .topbar { padding: 10px 12px; gap: 8px; }
    .topbar-brand span, .topbar-brand { font-size: .92rem; }
    .topbar-role { display: none; }
    .topbar-user span:not(.notif-bell-badge) { max-width: 90px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}

/* ---- Floating contact button (public site) ---- */
.contact-fab-wrap { position: fixed; right: 20px; bottom: 20px; z-index: 65; }
.contact-fab {
    width: 56px; height: 56px; border-radius: 50%; border: none; cursor: pointer;
    background: var(--brand); color: #fff; box-shadow: var(--shadow-lg);
    display: flex; align-items: center; justify-content: center; transition: transform .15s ease, background .15s ease;
}
.contact-fab:hover, .contact-fab:focus-visible { background: var(--brand-dark); transform: scale(1.05); outline: none; }
.contact-fab .icon { width: 24px; height: 24px; }
.contact-fab-menu {
    display: none; position: absolute; right: 0; bottom: calc(100% + 14px); width: 240px;
    background: #fff; border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow-lg);
    padding: 10px; flex-direction: column; gap: 4px;
}
.contact-fab-menu.open { display: flex; }
.contact-fab-menu-title { font-weight: 700; color: var(--ink); font-size: .88rem; padding: 6px 8px 10px; }
.contact-fab-menu-link { display: flex; align-items: center; gap: 8px; padding: 10px 8px; border-radius: var(--radius-sm); font-weight: 600; font-size: .9rem; color: var(--text); }
.contact-fab-menu-link:hover { background: var(--brand-light); text-decoration: none; }
.contact-fab-menu-link .icon { width: 16px; height: 16px; flex: 0 0 auto; }
.contact-fab-menu-wa { color: #1DA851; }
@media (max-width: 480px) {
    .contact-fab-wrap { right: 14px; bottom: 14px; }
    .contact-fab { width: 50px; height: 50px; }
    .contact-fab-menu { width: min(240px, calc(100vw - 28px)); }
}

/* ---- Misc utility ---- */
.reveal { opacity: 1; }
.no-print { }
@media print { .no-print { display: none !important; } }

/* ---- Staff portal print treatment — shared by every superuser/staff
   report page's "Download PDF" button (window.print(), same convention
   as superuser/assessment_review.php's own inline version of this block
   before it moved here). Strips the chrome (topbar/sidebar/banners) so
   what prints is just the report content, full width. Browsers' own
   "Save as PDF" print destination is the actual download mechanism —
   no PDF library needed for this. */
@media print {
    .topbar, .sidebar, .impersonation-banner, .tabs-nav { display: none !important; }
    .app-shell, .main-content { display: block !important; margin: 0 !important; padding: 0 !important; }
}

/* ---- Print treatment for the public, token-based cohort pages
   (company_manage.php, company_report.php) — administrators reach these
   by link, not login, and need a clean printable/PDF-able roster. The
   letterhead markup itself lives in includes/_cohort_print.php (it needs
   $cohort/$conn data); this is the print stylesheet for it — a letterhead
   block that only shows when printing, plus a forced classic table layout
   (the mobile "stack into cards" rule above is a bare
   @media (max-width:960px), not scoped to screen, so it would otherwise
   still apply to a printed page too). */
.print-letterhead { display: none; }
@media print {
    .public-nav, .promo-banner, .scroll-top-btn, .contact-fab-wrap, .ad-section, .no-print, footer.public-footer { display: none !important; }
    body { background: #fff !important; }

    .print-letterhead { display: flex !important; align-items: center; gap: 14px; padding: 0 0 14px; margin: 0 0 18px; border-bottom: 3px solid #0E5C52; }
    .print-letterhead img { width: 46px; height: 46px; }
    .print-letterhead-academy { font-family: Georgia, 'Times New Roman', serif; font-size: 16pt; font-weight: 700; color: #0E5C52; }
    .print-letterhead-meta { font-size: 9.5pt; color: #444; margin-top: 2px; }

    /* The coloured hero keeps its text content (cohort name, subjects,
       access window) but loses the ink-heavy dark background and
       centered marketing-page treatment. */
    section.hero { background: #fff !important; color: #1B241F !important; padding: 0 0 16px !important; text-align: left !important; margin-bottom: 16px; }
    section.hero * { color: #1B241F !important; text-shadow: none !important; }
    section.hero .hero-badge { display: none !important; }
    section.hero h1 { font-size: 20pt; margin: 0 0 4px; max-width: none; }
    section.hero p { font-size: 10pt; max-width: none; margin: 0; }

    section.section, .container, .container-narrow { max-width: none !important; padding: 0 !important; }
    .card { box-shadow: none !important; border: 1px solid #ccc !important; break-inside: avoid; margin-bottom: 14px !important; }
    .card-header { background: #f2f2f2 !important; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
    .stat-tile { box-shadow: none !important; border: 1px solid #ccc !important; }
    .grid-3 { display: grid !important; grid-template-columns: repeat(3, 1fr) !important; }

    /* Force the classic table layout, overriding the mobile card-stack
       rule so a printed page reads as a proper roster grid rather than
       one card per row per person. */
    table.table thead { display: table-header-group !important; position: static !important; width: auto !important; height: auto !important; overflow: visible !important; clip: auto !important; white-space: normal !important; }
    table.table, table.table tbody, table.table tr, table.table td, table.table th { display: revert !important; width: auto !important; }
    table.table tr { break-inside: avoid; border: none !important; }
    table.table td, table.table th { border: none !important; border-bottom: 1px solid #ddd !important; padding: 6px 8px !important; text-align: left !important; }
    table.table td:before { content: none !important; }
    table.table { font-size: 9.5pt; border-collapse: collapse; width: 100%; }

    /* Nothing to click on once it's on paper. */
    table.table td.actions, table.table th:last-child, table.table .actions-col { display: none !important; }
}

hr { border: none; border-top: 1px solid var(--border); margin: 24px 0; }
.divider-text { display: flex; align-items: center; gap: 12px; color: var(--muted); font-size: .82rem; margin: 18px 0; }
.divider-text::before, .divider-text::after { content: ""; flex: 1; height: 1px; background: var(--border); }

/* ---- Superuser: navigation menu drag-to-reorder editor ---- */
.nav-menu-editor { list-style: none; margin: 0; padding: 10px; display: grid; gap: 8px; }
.nav-menu-editor-row {
    display: flex; align-items: center; gap: 12px; padding: 12px 14px; border: 1px solid var(--border);
    border-radius: var(--radius-sm); background: #fff; cursor: grab; user-select: none;
}
.nav-menu-editor-row.is-hidden { opacity: .55; background: var(--bg-soft, #f7f7f7); }
.nav-menu-editor-row.dragging { opacity: .4; border-style: dashed; }
.nav-menu-editor-handle { color: var(--muted); display: flex; }
.nav-menu-editor-label { font-weight: 700; }
.nav-menu-editor-url { flex: 1; }

/* ---- Mobile number field (country code + number) ---- */
.phone-input-group { display: flex; gap: 8px; }
.phone-input-group select { flex: 0 0 auto; max-width: 210px; }
.phone-input-group input { flex: 1; min-width: 0; }
@media (max-width: 480px) {
    .phone-input-group { flex-wrap: wrap; }
    .phone-input-group select, .phone-input-group input { flex: 1 1 100%; max-width: 100%; }
}

/* ---- Bulk-action tables ---- */
.table .bulk-select-col { width: 34px; text-align: center; }
.bulk-action-bar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 14px 22px; border-top: 1px solid var(--border); background: #fafbfb; }
.bulk-action-bar select { max-width: 220px; }
.bulk-action-bar [data-bulk-count] { color: var(--muted); font-size: .85rem; }
.bulk-action-bar button[disabled] { opacity: .5; cursor: not-allowed; }

/* ---- Sponsor / advertiser logo thumbnails ---- */
.logo-thumb { width: 48px; height: 48px; object-fit: contain; border-radius: 6px; border: 1px solid var(--border); background: #fff; padding: 3px; }
.logo-upload-preview { display: flex; align-items: center; gap: 12px; }

/* ---- Advertising banners ----
   A placement (see includes/ad_helper.php's adsRenderPlacement()) renders
   as a labeled "Sponsored" section — eyebrow label, then one card per
   active advert with a hover-lift and an advertiser-name caption, rather
   than a bare image dropped between sections. */
.ad-section { padding: 36px 20px; background: var(--bg-alt, #F6F8F7); border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); }
.ad-section-inner { max-width: 1160px; margin: 0 auto; }
.ad-section-label { display: flex; align-items: center; justify-content: center; gap: 6px; font-size: .74rem; font-weight: 700; text-transform: uppercase; letter-spacing: .08em; color: var(--muted); margin: 0 0 18px; }
.ad-section-label .icon { color: var(--muted); }
.ad-slot { display: flex; flex-wrap: wrap; justify-content: center; gap: 20px; }
.ad-banner { display: flex; flex-direction: column; max-width: 100%; background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; box-shadow: var(--shadow); transition: transform .18s var(--ease), box-shadow .18s var(--ease); text-decoration: none; }
.ad-banner:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg); }
.ad-banner-frame { display: block; line-height: 0; }
.ad-banner img { display: block; max-width: 100%; height: auto; }
.ad-banner-caption { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 10px 14px; font-size: .8rem; font-weight: 600; color: var(--text); border-top: 1px solid var(--border); }
.ad-banner-caption .icon { width: 14px; height: 14px; color: var(--muted); flex-shrink: 0; }

/* ---- Structured payment channels (MTN / Airtel / Bank) ----
   Grid, not a plain flex column: .payment-channel is display:contents
   so its label/value spans become direct grid children, which is what
   lets every value line up in the same column no matter how long its
   label is ("MTN Mobile Money:" vs "Airtel Money:"). The free-text
   note still spans both columns. */
.payment-channels { display: grid; grid-template-columns: max-content 1fr; column-gap: 16px; row-gap: 10px; align-items: baseline; }
.payment-channel { display: contents; }
.payment-channel-label { display: flex; align-items: center; gap: 8px; font-weight: 700; white-space: nowrap; }
.payment-channel-icon { display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px; border-radius: 50%; flex-shrink: 0; color: #fff; background: var(--muted); }
.payment-channel-icon .icon { width: 12px; height: 12px; }
.payment-channel--mtn .payment-channel-icon { background: var(--accent); }
.payment-channel--airtel .payment-channel-icon { background: var(--danger); }
.payment-channel--bank .payment-channel-icon { background: var(--brand); }
.payment-channel-value { font-variant-numeric: tabular-nums; letter-spacing: .3px; word-break: break-word; align-self: center; }
.payment-channel-note { grid-column: 1 / -1; margin-top: 6px; padding-top: 10px; border-top: 1px solid rgba(0,0,0,0.08); }
@media (max-width: 480px) {
    .payment-channels { grid-template-columns: 1fr; }
    .payment-channel-value { padding-left: 30px; }
}

/* ---- Live search box on the public Subjects page ---- */
.subjects-live-search { position: relative; max-width: 420px; margin: 22px auto 0; }
.subjects-live-search input { width: 100%; padding: 12px 16px 12px 42px; border-radius: 999px; border: 1px solid var(--border); font-size: .95rem; background: #fff; }
.subjects-live-search input:focus { border-color: var(--brand); outline: none; box-shadow: 0 0 0 3px var(--brand-light); }
.subjects-live-search-icon { position: absolute; left: 16px; top: 50%; transform: translateY(-50%); color: var(--muted); display: flex; }

/* ---- Scroll-to-top button (public site, staff portal, participant portal) ---- */
.scroll-top-btn {
    position: fixed; right: 22px; bottom: 22px; z-index: 900;
    width: 44px; height: 44px; border-radius: 50%; border: none;
    background: var(--brand); color: #fff; box-shadow: var(--shadow-lg);
    display: flex; align-items: center; justify-content: center; cursor: pointer;
    transition: background .15s ease, transform .15s ease, opacity .15s ease;
}
.scroll-top-btn:hover, .scroll-top-btn:focus-visible { background: var(--brand-dark); transform: translateY(-2px); outline: none; }
.scroll-top-btn[hidden] { display: none; }
@media (max-width: 640px) { .scroll-top-btn { right: 16px; bottom: 16px; width: 40px; height: 40px; } }

/* ---- No-horizontal-scroll safety net ----
   The page itself never scrolls sideways; anything genuinely too wide
   for its column (a data table, a long code/pre block) scrolls within
   its own box instead, so no content is ever silently clipped. */

/* Click-to-reveal contact details (contact.php) — styled to look like a
   plain inline link before it's revealed, so it doesn't read as a random
   button in the middle of a sentence. */
.reveal-contact-btn { background: none; border: none; padding: 0; margin: 0; font: inherit; color: var(--brand); text-decoration: underline; cursor: pointer; }
.reveal-contact-btn:hover { color: var(--brand-dark); }

html { overflow-x: hidden; }
body { max-width: 100%; overflow-x: hidden; }
img, video, iframe { max-width: 100%; }
pre, code { max-width: 100%; overflow-x: auto; }
.card-body { overflow-x: auto; }
.table-wrap, table.table { max-width: 100%; }

/* Fee-discounting promotions — inline badges on subject fee displays
   (apply.php, add_subject.php, pay_course.php, subjects.php). See
   subjectEffectivePrice() in includes/promotion_helper.php. */
.price-was {
    text-decoration: line-through;
    color: var(--muted, #888);
    font-size: 0.85em;
    margin-right: 4px;
}
.promo-tag {
    display: inline-block;
    background: #ffedd5;
    color: #9a3412;
    border-radius: 4px;
    padding: 1px 7px;
    font-size: 0.72em;
    font-weight: 600;
    margin-left: 4px;
    white-space: nowrap;
}

/* ---- Generic info modal (SweetAlert2 — footer "maintained by" credit, etc.) ---- */
.info-modal-popup { border-radius: var(--radius) !important; padding-top: 28px !important; }
.info-modal-avatar {
    width: 72px; height: 72px; margin: 0 auto 14px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    background: linear-gradient(135deg, var(--brand), var(--accent));
    color: #fff; font-family: var(--font-head); font-weight: 800; font-size: 1.6rem;
    box-shadow: var(--shadow-lg);
}
.info-modal-title { font-family: var(--font-head); color: var(--brand-dark); margin: 0 0 10px; }
.info-modal-body { text-align: left; color: var(--text); line-height: 1.55; }
.info-modal-body p:last-child { margin-bottom: 0; }
