:root {
    --osmis-primary: #0d6efd;
    --osmis-sidebar-bg: #2b3138;       /* gray */
    --osmis-sidebar-hover: #373e47;
    --osmis-sidebar-text: #c2c8d0;
    --osmis-sidebar-w: 250px;
    --osmis-topbar-h: 62px;
    --osmis-bg: #f5f6fa;
}

/* ---- Admission wizard ---- */
.wiz-steps { display: flex; gap: 0; margin-bottom: 1.75rem; position: relative; }
.wiz-step { flex: 1; text-align: center; position: relative; }
.wiz-step::before { content: ""; position: absolute; top: 19px; left: -50%; width: 100%; height: 3px; background: #e4e7ef; z-index: 0; }
.wiz-step:first-child::before { display: none; }
.wiz-step.done::before, .wiz-step.active::before { background: #0d6efd; }
.wiz-step .wiz-dot { width: 40px; height: 40px; border-radius: 50%; background: #e4e7ef; color: #8a93a8; display: inline-flex; align-items: center; justify-content: center; font-weight: 700; position: relative; z-index: 1; border: 3px solid #fff; }
.wiz-step.active .wiz-dot { background: #0d6efd; color: #fff; box-shadow: 0 0 0 4px rgba(13,110,253,.15); }
.wiz-step.done .wiz-dot { background: #1cab8b; color: #fff; }
.wiz-step .wiz-label { display: block; margin-top: .4rem; font-size: .8rem; color: #59617a; font-weight: 600; }
.wiz-step.active .wiz-label { color: #0d6efd; }
.wiz-panel { display: none; }
.wiz-panel.active { display: block; animation: wizfade .25s ease; }
@@keyframes wizfade { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
.wiz-review dt { color: #8a93a8; font-weight: 500; font-size: .8rem; }
.wiz-review dd { font-weight: 600; margin-bottom: .5rem; }

/* Preskool template owns the global body/layout styling; keep only small additions here. */
.osmis-logo { font-size: 1.4rem; font-weight: 800; color: #0d6efd; letter-spacing: .02em; }
.osmis-logo-sm { font-size: 1.4rem; font-weight: 800; color: #0d6efd; }

/* ---- Responsive tables -> cards on mobile & tablet ----
   The global labeler (in _Layout) copies each column header into every cell's data-label; below 992px
   this collapses table rows into stacked "label: value" cards. Opt a table out with class "no-cards". */
@media (max-width: 991.98px) {
    /* Kill page-level sideways scroll on mobile/tablet (e.g. Bootstrap .row negative margins in unpadded
       containers). Inner .table-responsive grids keep their own horizontal scroll. */
    body, .pc-container, .pc-content { overflow-x: hidden; max-width: 100%; }
    /* .dashlite hosts top-level .row elements directly; give it the gutter padding a Bootstrap container
       would provide, so the rows' -0.75rem margins are offset instead of pushing content off-screen. */
    .dashlite { padding-left: .75rem; padding-right: .75rem; }
    /* Flex/grid children (Bootstrap columns, card bodies) must be allowed to shrink below their content
       width — the default min-width:auto lets wide content (charts, long headings) blow out the layout and
       clip on the right. */
    .dashlite [class*="col-"], .dashlite .card, .dashlite .card-body, .dashlite .row { min-width: 0; }
    .dashlite [id^="chart"], .dashlite .apexcharts-canvas, .dashlite svg { max-width: 100%; }
    table.table-cards { border: 0; }
    table.table-cards > thead { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); border: 0; }
    table.table-cards > tbody > tr {
        display: block; margin-bottom: .75rem; padding: .15rem .1rem;
        border: 1px solid #e6e9f2; border-radius: .6rem; background: #fff;
        box-shadow: 0 1px 2px rgba(54,74,99,.05);
    }
    table.table-cards > tbody > tr > td {
        display: flex; justify-content: space-between; align-items: center; gap: 1rem;
        text-align: right; border: 0; border-bottom: 1px solid #f1f3f9; padding: .5rem .75rem; min-height: 2.4rem;
    }
    table.table-cards > tbody > tr > td:last-child { border-bottom: 0; }
    table.table-cards > tbody > tr > td::before {
        content: attr(data-label); font-weight: 600; color: #6b7280; text-align: left;
        white-space: nowrap; font-size: .8rem;
    }
    table.table-cards > tbody > tr > td:not([data-label])::before,
    table.table-cards > tbody > tr > td[data-label=""]::before { content: none; }
    /* Full-width cells (empty states, spanning rows) render as a plain centred block, not label:value. */
    table.table-cards > tbody > tr > td[colspan] { display: block; text-align: center; }
    table.table-cards > tbody > tr > td[colspan]::before { content: none; }
    table.table-cards > tbody > tr > td .btn { flex: 0 0 auto; }
    /* The wrapper no longer needs to scroll horizontally once rows are cards. */
    .table-responsive:has(table.table-cards) { overflow-x: visible; }
    /* Fallback for browsers without :has() — the labeler adds this class to the wrapper directly. */
    .table-responsive-cards { overflow-x: visible !important; }
    /* Let long values wrap inside a card cell instead of forcing width (which brings back the scrollbar). */
    table.table-cards > tbody > tr > td { overflow-wrap: anywhere; min-width: 0; }
}

/* ---- Shell ---- */
.osmis-shell { display: flex; min-height: 100vh; }
.osmis-main { flex: 1; margin-left: var(--osmis-sidebar-w); display: flex; flex-direction: column; min-width: 0; transition: margin-left .2s; }
.osmis-shell.collapsed .osmis-sidebar { transform: translateX(-100%); }
.osmis-shell.collapsed .osmis-main { margin-left: 0; }

/* ---- Sidebar ---- */
.osmis-sidebar {
    position: fixed; top: 0; left: 0; bottom: 0; width: var(--osmis-sidebar-w);
    background: var(--osmis-sidebar-bg); color: var(--osmis-sidebar-text);
    overflow-y: auto; transition: transform .2s; z-index: 1030;
}
.osmis-sidebar::-webkit-scrollbar { width: 6px; }
.osmis-sidebar::-webkit-scrollbar-thumb { background: #ffffff22; border-radius: 3px; }
.osmis-brand {
    height: var(--osmis-topbar-h); display: flex; align-items: center; gap: .55rem;
    padding: 0 1.25rem; font-size: 1.35rem; font-weight: 700; color: #fff;
    border-bottom: 1px solid #ffffff14; position: sticky; top: 0; background: var(--osmis-sidebar-bg);
}
.osmis-brand .bi { color: var(--osmis-primary); }
.osmis-menu { padding: .5rem 0 2rem; }
.osmis-menu-head {
    padding: 1rem 1.25rem .35rem; font-size: .68rem; text-transform: uppercase;
    letter-spacing: .08em; color: #ffffff66; font-weight: 600;
}
.osmis-menu a {
    display: flex; align-items: center; gap: .7rem; padding: .6rem 1.25rem;
    color: var(--osmis-sidebar-text); text-decoration: none; font-size: .92rem; border-left: 3px solid transparent;
}
.osmis-menu a .bi { font-size: 1.05rem; width: 1.2rem; text-align: center; }
.osmis-menu a:hover { background: var(--osmis-sidebar-hover); color: #fff; }
.osmis-menu a.active { background: var(--osmis-sidebar-hover); color: #fff; border-left-color: var(--osmis-primary); }

/* ---- Topbar ---- */
.osmis-topbar {
    height: var(--osmis-topbar-h); background: #fff; display: flex; align-items: center;
    gap: 1rem; padding: 0 1.25rem; position: sticky; top: 0; z-index: 1020;
    box-shadow: 0 1px 8px rgba(0,0,0,.06);
}
.osmis-toggle { border: none; background: transparent; font-size: 1.4rem; color: #25324b; padding: .1rem .4rem; }
.osmis-search { position: relative; }
.osmis-search .bi { position: absolute; left: .75rem; top: 50%; transform: translateY(-50%); color: #9aa3b8; }
.osmis-search input { border: 1px solid #e4e7ef; background: #f7f8fb; border-radius: 8px; padding: .45rem .75rem .45rem 2.1rem; width: 320px; outline: none; }
.osmis-search input:focus { border-color: var(--osmis-primary); }
.osmis-user { display: flex; align-items: center; gap: .55rem; text-decoration: none; color: #25324b; }
.osmis-avatar { width: 38px; height: 38px; border-radius: 50%; background: var(--osmis-primary); color: #fff; display: inline-flex; align-items: center; justify-content: center; font-weight: 600; }
.osmis-user-name { font-weight: 600; font-size: .9rem; }
.osmis-user-role { color: #8a93a8; font-size: .72rem; }

/* ---- Content ---- */
.osmis-content { padding: 1.5rem; flex: 1; }
.page-title { font-size: 1.4rem; font-weight: 700; margin: 0; }
.page-sub { color: #8a93a8; font-size: .85rem; }

/* ---- Cards / KPI ---- */
.card { border: none; border-radius: 12px; box-shadow: 0 2px 10px rgba(20,30,60,.05); }
.kpi { display: flex; align-items: center; gap: 1rem; }
.kpi-icon { width: 54px; height: 54px; border-radius: 12px; display: inline-flex; align-items: center; justify-content: center; font-size: 1.5rem; color: #fff; }
.kpi-value { font-size: 1.6rem; font-weight: 700; line-height: 1; }
.kpi-label { color: #8a93a8; font-size: .82rem; }
.bg-grad-blue { background: linear-gradient(135deg,#0d6efd,#3d8bff); }
.bg-grad-green { background: linear-gradient(135deg,#1cab8b,#46d3ad); }
.bg-grad-amber { background: linear-gradient(135deg,#f5803e,#ffb066); }
.bg-grad-purple { background: linear-gradient(135deg,#6f42c1,#9a6be0); }
.bg-grad-teal { background: linear-gradient(135deg,#0a9aa6,#2cc6d2); }
.bg-grad-pink { background: linear-gradient(135deg,#e8388a,#ff6fb0); }

/* table */
.table thead th { background: #f7f8fb; color: #59617a; font-size: .78rem; text-transform: uppercase; letter-spacing: .03em; border-bottom: 1px solid #eef0f5; }
/* A header row that explicitly asks for .table-primary means "brand-blue header": honour it with WHITE text.
   The generic rule above was flattening those to grey-on-grey, so the class looked like it did nothing.
   .table-light headers deliberately stay muted. */
.table thead.table-primary th,
.table > thead.table-primary > tr > th {
    background: linear-gradient(135deg, #4680ff, #0d6efd);
    color: #fff;
    border-bottom-color: #0d6efd;
}
.table thead.table-primary th .small,
.table thead.table-primary th small,
.table thead.table-primary th .fw-normal { color: rgba(255, 255, 255, .85); }
.table td { vertical-align: middle; }

/* ---- Login (AdminDek login-v1 mapping, floating labels) ---- */
.login-wrap {
    min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 1.5rem;
    background: #f3f5f9;
    background-image:
        radial-gradient(circle at 12% 18%, rgba(70,128,255,.10), transparent 42%),
        radial-gradient(circle at 88% 82%, rgba(70,128,255,.12), transparent 42%);
}
.login-card {
    background: #fff; border: 1px solid #eaecf1; border-radius: 12px;
    box-shadow: 0 8px 24px rgba(27,46,94,.10);
    width: 100%; max-width: 460px; padding: 2.5rem 2.25rem;
}
.login-brand { text-align: center; font-size: 1.65rem; font-weight: 700; color: #1b2850; margin-bottom: .25rem; }
.login-brand .bi { color: #4680ff; }
.login-card .form-floating > .form-control { height: calc(3.4rem + 2px); border-radius: 8px; border-color: #dbe0e5; }
.login-card .form-floating > .form-control:focus { border-color: #4680ff; box-shadow: 0 0 0 .15rem rgba(70,128,255,.18); }
.login-card .form-floating > label { color: #8996a4; }
.login-card .form-check-input:checked { background-color: #4680ff; border-color: #4680ff; }
.login-card .btn-auth { background: #4680ff; border: 1px solid #4680ff; color: #fff; font-weight: 500; padding: .7rem 1rem; border-radius: 8px; }
.login-card .btn-auth:hover { background: #3866cc; border-color: #3866cc; color: #fff; }
.login-card .link-auth { color: #4680ff; text-decoration: none; font-size: .875rem; }
.login-card .link-auth:hover { text-decoration: underline; }
.login-card .pw-field { position: relative; }
.login-card .pw-field > .form-control { padding-right: 3rem; }
.login-card .pw-toggle { position: absolute; top: 0; right: 0; height: 100%; width: 3rem; display: flex; align-items: center; justify-content: center; background: transparent; border: 0; padding: 0; color: #8996a4; cursor: pointer; z-index: 5; }
.login-card .pw-toggle:hover { color: #4680ff; }

/* Required-field marker. Put class="required" on a <label> and it gains a red asterisk; the label TEXT
   still comes from the model's [Display(Name = …)], so the wording stays in one place. Shared here rather
   than inlined per page — sign-up and the payment page both use it. Pair with aria-required="true" on the
   input so the cue is not colour/vision-only. */
label.required::after { content: " *"; color: #dc3545; font-weight: 700; }
.form-floating > label.required::after { margin-left: .1rem; }

/* ===== Staged owner sign-up ===================================================================
   Progress rail shared by every stage (_RegisterSteps.cshtml) plus the package cards on stage 2.
   Colours track the .login-card palette above so the wizard reads as one piece with the auth pages. */
.reg-steps { font-size: .8rem; }
.reg-step { display: flex; align-items: center; gap: .5rem; padding: .35rem .75rem .35rem .35rem;
            border: 1px solid #e6e9ef; border-radius: 999px; background: #fff; color: #8996a4; }
.reg-step-dot { width: 1.75rem; height: 1.75rem; border-radius: 50%; flex: 0 0 auto;
                display: flex; align-items: center; justify-content: center;
                background: #eef1f6; color: #8996a4; font-size: .8rem; }
.reg-step-text { display: flex; flex-direction: column; line-height: 1.1; }
.reg-step-no { font-size: .65rem; text-transform: uppercase; letter-spacing: .04em; opacity: .75; }
.reg-step-title { font-weight: 600; white-space: nowrap; }
.reg-step.now { border-color: #4680ff; color: #1b2850; box-shadow: 0 0 0 .15rem rgba(70,128,255,.14); }
.reg-step.now .reg-step-dot { background: #4680ff; color: #fff; }
.reg-step.done { border-color: #b7e4c7; color: #1b7a45; }
.reg-step.done .reg-step-dot { background: #198754; color: #fff; }
@media (max-width: 575.98px) {
    /* On a phone the five pills wrap into an unreadable block — keep the dots, drop the wording
       for every step except the one the applicant is actually on. */
    .reg-step:not(.now) .reg-step-text { display: none; }
    .reg-step:not(.now) { padding: .35rem; }
}

/* M-Pesa "how to pay" steps (_MpesaHowToPay.cshtml). Numbered circles rather than plain <ol> markers,
   because this is read off a phone screen mid-transaction and the step you're on has to be obvious. */
.mpesa-steps { list-style: none; counter-reset: mpesa; padding-left: 0; margin-bottom: 0; }
.mpesa-steps > li { counter-increment: mpesa; position: relative; padding-left: 2.25rem;
                    margin-bottom: .55rem; font-size: .9rem; line-height: 1.45; }
.mpesa-steps > li::before {
    content: counter(mpesa);
    position: absolute; left: 0; top: -.1rem;
    width: 1.6rem; height: 1.6rem; border-radius: 50%;
    background: #4680ff; color: #fff;
    display: flex; align-items: center; justify-content: center;
    font-size: .8rem; font-weight: 700;
}
.mpesa-pay .fs-3 { letter-spacing: .02em; }

/* Package cards (stage 2). The whole card is the label for its radio, so the click target is the
   card and not a 16px dot; .is-picked is toggled by the page script on change. */
.pkg-card { border: 1px solid #e6e9ef; border-radius: 12px; background: #fff; height: 100%;
            cursor: pointer; transition: border-color .15s, box-shadow .15s, transform .15s; }
.pkg-card:hover { border-color: #bcd0ff; transform: translateY(-2px); }
.pkg-card.is-picked { border-color: #4680ff; box-shadow: 0 0 0 .15rem rgba(70,128,255,.18); }
.pkg-card .pkg-price { font-size: 1.5rem; font-weight: 700; color: #1b2850; }
.pkg-card .pkg-feature { font-size: .82rem; }
.pkg-ribbon { position: absolute; top: -.65rem; right: .85rem; font-size: .68rem; letter-spacing: .03em; }
.addon-card { border: 1px solid #e6e9ef; border-radius: 10px; background: #fff; cursor: pointer;
              transition: border-color .15s, background .15s; }
.addon-card:hover { border-color: #bcd0ff; }
.addon-card.is-picked { border-color: #4680ff; background: #f5f8ff; }

/* ===== DashLite-inspired dashboard skin (scoped to .dashlite so other pages are untouched) ===== */
.dashlite { --dl-primary:#6576ff; --dl-success:#1ee0ac; --dl-danger:#e85347; --dl-warning:#f4bd0e; --dl-info:#09c2de; --dl-head:#364a63; --dl-muted:#8094ae; --dl-border:#e5e9f2; }
.dashlite .card { border:1px solid var(--dl-border); border-radius:8px; box-shadow:0 1px 3px rgba(54,74,99,.04); }
.dashlite .card-header { background:transparent; border-bottom:1px solid var(--dl-border); }
.dashlite h1,.dashlite h4,.dashlite h5,.dashlite h6,.dashlite .fw-bold,.dashlite .fw-semibold { color:var(--dl-head); }
.dashlite .page-title { font-size:1.35rem; font-weight:700; color:var(--dl-head); }
.dashlite .text-muted,.dashlite .page-sub { color:var(--dl-muted) !important; }
.dashlite .card-title-group { display:flex; align-items:flex-start; justify-content:space-between; gap:1rem; }
.dashlite .card-title .title { font-size:.95rem; font-weight:700; color:var(--dl-head); }
.dashlite .card-title .sub-text { font-size:.78rem; color:var(--dl-muted); }
.dashlite .link-primary { color:var(--dl-primary); font-weight:500; }
.dashlite a.text-decoration-none { color:var(--dl-primary); }
.dashlite .btn-primary { background:var(--dl-primary); border-color:var(--dl-primary); }
.dashlite .btn-outline-primary { color:var(--dl-primary); border-color:var(--dl-primary); }
.dashlite .btn-outline-primary:hover { background:var(--dl-primary); border-color:var(--dl-primary); }
.dashlite .table > thead > tr > th { color:var(--dl-muted); font-weight:600; text-transform:uppercase; font-size:.72rem; letter-spacing:.04em; }
.dashlite .badge.bg-success-subtle { background:rgba(30,224,172,.15) !important; color:#0f9c79 !important; }
.dashlite .badge.bg-danger-subtle { background:rgba(232,83,71,.14) !important; color:#d33724 !important; }
.dashlite .badge.bg-secondary-subtle { background:#f0f3f8 !important; color:var(--dl-muted) !important; }
/* Keep the colored KPI hero cards vivid but slightly flatter to match DashLite tiles. */
.dashlite .card.bg-primary,.dashlite .card.bg-success,.dashlite .card.bg-danger,.dashlite .card.bg-info,.dashlite .card.bg-warning,.dashlite .card.bg-secondary,.dashlite .card.bg-dark { border:0; box-shadow:0 2px 8px rgba(54,74,99,.12); }

/* ===== Smart, professional polish for the global dashboard (scoped to .dashlite) ===== */
.dashlite .card { border:1px solid #e9edf5; border-radius:12px; box-shadow:0 1px 2px rgba(54,74,99,.05); transition:transform .18s ease, box-shadow .18s ease; }
.dashlite .card:hover { transform:translateY(-2px); box-shadow:0 10px 26px rgba(54,74,99,.10); }
.dashlite .card .card-body { padding:1.15rem 1.25rem; }
.dashlite .card h6 { font-size:.9rem; font-weight:700; letter-spacing:.2px; }
.dashlite .kpi-icon { box-shadow:0 6px 14px rgba(101,118,255,.25); }
.dashlite .kpi-value { font-size:1.7rem; letter-spacing:-.5px; }
.dashlite .page-title { font-size:1.55rem; font-weight:800; letter-spacing:-.4px; }
.dashlite .page-sub { font-size:.88rem; }
.dashlite .table-hover > tbody > tr:hover { background:#f5f7fc; }
.dashlite .table > tbody > tr { transition:background .12s ease; }
/* Refined hero: icon chip + soft gradient panel */
.dashlite .dash-hero { background:linear-gradient(100deg,#ffffff 0%,#f3f6ff 100%); border:1px solid #e9edf5; border-radius:14px; box-shadow:0 1px 2px rgba(54,74,99,.05); padding:1rem 1.25rem; }
.dashlite .dash-hero-icon { width:48px; height:48px; border-radius:12px; display:inline-flex; align-items:center; justify-content:center; color:#fff; font-size:1.5rem; background:linear-gradient(135deg,#6576ff,#3b4ce0); box-shadow:0 6px 14px rgba(101,118,255,.30); }

/* App-wide convention: every modal header uses the primary background with white text. */
.modal-header { background-color: #0d6efd !important; color: #fff !important; border-bottom: 0; }
.modal-header .modal-title,
.modal-header .h5 { color: #fff !important; }
.modal-header .btn-close { filter: brightness(0) invert(1); opacity: .85; }

/* ===== Sidebar menu scrolling =================================================================
   The menu is long — every module, each with sub-items — and on a laptop it runs well past the fold.
   The theme relies on a JS scrollbar plugin here, so when that doesn't initialise the overflow is
   simply clipped and the lower half of the menu becomes unreachable with no visible cue.
   This makes it a plain CSS scroll region instead, which cannot fail to initialise:

     navbar-wrapper  -> full-height flex column
     m-header (brand)-> fixed, never scrolls away
     navbar-content  -> takes the remaining height and scrolls

   Sized with flex rather than calc(100vh - 74px) on purpose: a hardcoded header height silently
   breaks the moment the brand row changes. overscroll-behavior stops a flick at the end of the menu
   from carrying on and scrolling the page behind it.

   NOTE the collapsed icon-rail below deliberately re-sets overflow:visible so submenus can fly out;
   its selector is more specific, so it still wins. */
.pc-sidebar .navbar-wrapper { display: flex; flex-direction: column; height: 100vh; }
.pc-sidebar .navbar-wrapper > .m-header { flex: 0 0 auto; }
.pc-sidebar .navbar-content {
    flex: 1 1 auto;
    min-height: 0;              /* without this a flex child refuses to shrink and never scrolls */
    overflow-y: auto;
    overflow-x: hidden;
    overscroll-behavior: contain;
    scrollbar-width: thin;      /* Firefox */
}
/* A slim scrollbar that only shows up when there is something to scroll, so it doesn't sit as a
   permanent stripe down the menu. */
.pc-sidebar .navbar-content::-webkit-scrollbar { width: 7px; }
.pc-sidebar .navbar-content::-webkit-scrollbar-track { background: transparent; }
.pc-sidebar .navbar-content::-webkit-scrollbar-thumb { background: #00000026; border-radius: 4px; }
.pc-sidebar .navbar-content:hover::-webkit-scrollbar-thumb { background: #00000040; }

/* ===== Collapsed sidebar = icon-only mini bar (large screens), with smooth transitions ===== */
.pc-sidebar, .pc-sidebar .navbar-wrapper { transition: width .25s ease; }
.pc-header, .pc-container, .pc-footer { transition: margin-left .25s ease, left .25s ease; }

@media (min-width: 1025px) {
    /* Instead of fully hiding (width:0), shrink to an icon rail. */
    .pc-sidebar.pc-sidebar-hide { width: 74px !important; --pc-sidebar-border: 1px solid #e5e9f2; }
    .pc-sidebar.pc-sidebar-hide .navbar-wrapper { width: 74px !important; }
    .pc-sidebar.pc-sidebar-hide ~ .pc-header { left: 74px !important; }
    .pc-sidebar.pc-sidebar-hide ~ .pc-container,
    .pc-sidebar.pc-sidebar-hide ~ .pc-footer { margin-left: 74px !important; }

    /* Show icons, hide text / captions / arrows. */
    .pc-sidebar.pc-sidebar-hide .pc-mtext,
    .pc-sidebar.pc-sidebar-hide .pc-arrow,
    .pc-sidebar.pc-sidebar-hide .pc-caption label { display: none !important; }
    .pc-sidebar.pc-sidebar-hide .pc-caption { text-align: center; padding-left: 0; padding-right: 0; }
    .pc-sidebar.pc-sidebar-hide .pc-link { justify-content: center; padding-left: 0; padding-right: 0; text-align: center; }
    .pc-sidebar.pc-sidebar-hide .pc-micon { margin-right: 0 !important; }

    /* Brand: keep the icon, hide the wordmark. */
    .pc-sidebar.pc-sidebar-hide .m-header { justify-content: center; }
    .pc-sidebar.pc-sidebar-hide .osmis-brand { font-size: 0; }
    .pc-sidebar.pc-sidebar-hide .osmis-brand i { font-size: 1.35rem; }

    /* Submenus fly out to the right on hover. */
    .pc-sidebar.pc-sidebar-hide .navbar-content { overflow: visible; }
    .pc-sidebar.pc-sidebar-hide .pc-item.pc-hasmenu { position: relative; }
    .pc-sidebar.pc-sidebar-hide .pc-submenu { display: none !important; }
    .pc-sidebar.pc-sidebar-hide .pc-item.pc-hasmenu:hover > .pc-submenu {
        display: block !important;
        position: absolute; left: 74px; top: 0; min-width: 210px;
        background: #fff; border: 1px solid #e5e9f2; border-radius: 8px;
        box-shadow: 0 6px 18px rgba(54,74,99,.18); padding: 6px 0; z-index: 1035;
    }
    .pc-sidebar.pc-sidebar-hide .pc-item.pc-hasmenu:hover > .pc-submenu .pc-link { justify-content: flex-start; padding-left: 16px; text-align: left; }
}

/* School switcher in the top bar: show the active school name in full (no clipping). */
.osmis-school-switch .pc-head-link { white-space: nowrap; max-width: none !important; width: auto !important; }
.osmis-school-switch .pc-head-link > span { display: inline-block; vertical-align: middle; max-width: none !important; overflow: visible !important; }
.osmis-school-switch .pc-h-dropdown { min-width: 280px; }
/* Keep the switcher fully visible on hover/focus (theme hover styles / ::before overlay can wash it out). */
.osmis-school-switch .pc-head-link::before { display: none !important; }
.osmis-school-switch .pc-head-link:hover,
.osmis-school-switch .pc-head-link:focus,
.osmis-school-switch .pc-head-link:active,
.osmis-school-switch.show .pc-head-link { opacity: 1 !important; visibility: visible !important; background: transparent !important; }
.osmis-school-switch .pc-head-link:hover > span,
.osmis-school-switch .pc-head-link:focus > span { color: #364a63 !important; opacity: 1 !important; visibility: visible !important; }
.osmis-school-switch .pc-head-link:hover > i,
.osmis-school-switch .pc-head-link:focus > i { opacity: 1 !important; visibility: visible !important; }
.osmis-school-switch .pc-head-link:hover > i.text-primary { color: var(--bs-primary, #0d6efd) !important; }

/* Breathing room on the left of the auto-generated table search box. */
.osmis-livesearch { margin-left: .5rem; }

/* ===== Broadsheet / cross-tab results (subjects as columns, frozen Rank+Student) ===== */
.broadsheet { border-collapse: separate; border-spacing: 0; }
.broadsheet td, .broadsheet th { border: 1px solid #e5e9f2; white-space: nowrap; }
.broadsheet thead th { background: #cfe2ff; color: #084298; font-weight: 600; }
.broadsheet .freeze1 { position: sticky; left: 0; z-index: 2; min-width: 44px; text-align: center; }
.broadsheet .freeze2 { position: sticky; left: 44px; z-index: 2; min-width: 170px; box-shadow: 3px 0 5px -3px rgba(0,0,0,.18); }
.broadsheet tbody .freeze1, .broadsheet tbody .freeze2 { background: #fff; }
.broadsheet thead .freeze1, .broadsheet thead .freeze2 { z-index: 3; background: #cfe2ff; }
.broadsheet tbody tr:hover .freeze1, .broadsheet tbody tr:hover .freeze2 { background: #f5f7fc; }

/* The pupil's place IN ONE SUBJECT, riding on the mark rather than taking a column of its own — a
   broadsheet already carries a score and a grade per subject, and a third column each would make nine
   subjects unreadable. Small enough to read past when you only want the score, findable when you want
   the placing. Shared by the internal and external results tables AND by the legend that explains them,
   so the key can never render differently from the table. */
.subj-pos {
    display: inline-block; min-width: 1.15rem; margin-left: .15rem;
    padding: 0 .2rem; border: 1px solid #d8dee9; border-radius: .35rem;
    background: #fff; color: #6b7a90;
    font-size: .62rem; font-weight: 600; line-height: 1.25; vertical-align: super;
}
/* Legend swatches — the same four bands the cells use. */
.band-key { display: inline-flex; align-items: center; gap: .3rem; font-size: .78rem; color: #5b6b82 }
.band-key i { width: .85rem; height: .85rem; border-radius: .25rem; display: inline-block; border: 1px solid rgba(0,0,0,.06) }

/* Global ✕ clear button for live-search boxes (added by JS in _Layout). */
.osmis-clear-wrap { position: relative; display: block; }
.osmis-clear-host { position: relative; }
.osmis-clear-x {
    position: absolute; top: 50%; right: 6px; transform: translateY(-50%);
    border: 0; background: transparent; color: #8094ae; font-size: 1.25rem;
    line-height: 1; cursor: pointer; padding: 0 4px; z-index: 5;
}
.osmis-clear-x:hover { color: #e03131; }

/* Cleaner pill-style tabs (Classes & Streams etc.) */
.osmis-tabs { flex-wrap: wrap; }
.osmis-tabs .nav-link { color: #5b6b82; border-radius: 8px; padding: .4rem .9rem; font-weight: 500; transition: background .15s ease, color .15s ease; }
.osmis-tabs .nav-link:hover { background: #eef1f6; color: #364a63; }
.osmis-tabs .nav-link.active { background: #6576ff; color: #fff; box-shadow: 0 2px 6px rgba(101,118,255,.35); }

/* Long names (user / school) wrap instead of overflowing, especially on mobile. */
.osmis-name { overflow-wrap: anywhere; word-break: break-word; }
.min-w-0 { min-width: 0; }

/* ---- AdminDek sidebar brand ---- */
.m-header .osmis-brand { font-weight: 700; font-size: 1.35rem; color: #4680ff; white-space: nowrap; letter-spacing: .5px; }
.m-header .osmis-brand .ti { vertical-align: -2px; }

/* ---- Tables: AdminDek list-page (membership-list) look, applied app-wide ---- */
/* Scoped to tables inside cards / responsive wrappers — where all data/list tables live. */
.card .table,
.table-responsive > .table { margin-bottom: 0; }
/* Responsive: horizontal scroll with momentum on touch devices. */
.table-responsive { overflow-x: auto; -webkit-overflow-scrolling: touch; }
/* Mobile: convert tagged data tables into stacked cards (one card per row). */
@media (max-width: 767.98px) {
    table.osmis-cardize > thead { display: none; }
    table.osmis-cardize,
    table.osmis-cardize > tbody,
    table.osmis-cardize > tbody > tr,
    table.osmis-cardize > tbody > tr > td { display: block; width: 100%; }
    table.osmis-cardize > tbody > tr {
        border: 1px solid #e9edf2; border-radius: .6rem; margin-bottom: .75rem;
        padding: .35rem .85rem; background: #fff; box-shadow: 0 1px 3px rgba(27, 46, 94, .06);
    }
    table.osmis-cardize > tbody > tr > td {
        border: 0 !important; padding: .45rem 0; display: flex; align-items: center;
        justify-content: space-between; gap: 1rem; text-align: right;
        overflow-wrap: anywhere; word-break: break-word; min-width: 0; flex-wrap: wrap;
    }
    /* Long values (e.g. subject name) wrap onto their own full-width line inside the card cell. */
    table.osmis-cardize > tbody > tr > td > * { min-width: 0; overflow-wrap: anywhere; word-break: break-word; max-width: 100%; }
    table.osmis-cardize > tbody > tr > td::before {
        content: attr(data-label); font-weight: 600; color: #5b6b79; text-align: left; margin-right: auto;
    }
    table.osmis-cardize > tbody > tr > td:not([data-label])::before { content: ""; margin: 0; }
    /* Cardized cells always wrap (override any inline white-space:nowrap on the table). */
    table.osmis-cardize, table.osmis-cardize > tbody > tr > td { white-space: normal !important; }

    /* ---- Complex grids that OPT OUT of cards (broadsheet, Payslips/Debtors grouped grids) ----
       They stay a horizontally-scrollable table on mobile. Drop the sticky/frozen columns so the
       scroll is clean, and let the responsive wrapper provide the swipe. */
    .broadsheet .freeze1, .broadsheet .freeze2 { position: static !important; left: auto !important; box-shadow: none !important; z-index: auto !important; }
    .table-responsive { -webkit-overflow-scrolling: touch; }
}
.card .table > thead > tr > th,
.table-responsive > .table > thead > tr > th {
    background: transparent;
    color: #1d2630;
    font-weight: 600;
    white-space: nowrap;
    border-bottom: 1px solid #e9edf2;
    padding: .9rem .75rem;
}
.card .table > tbody > tr > td,
.card .table > tbody > tr > th,
.table-responsive > .table > tbody > tr > td,
.table-responsive > .table > tbody > tr > th {
    vertical-align: middle;
    border-bottom: 1px solid #f1f3f6;
    padding: .9rem .75rem;
}
/* Hover highlight on every data table (even those without the table-hover class). */
.card .table > tbody > tr:hover > *,
.table-responsive > .table > tbody > tr:hover > * { background-color: rgba(70, 128, 255, .04); }
/* Compact, consistent action-column buttons. */
.card .table .btn-sm,
.table-responsive > .table .btn-sm { --bs-btn-padding-y: .2rem; --bs-btn-padding-x: .5rem; }
/* Rounded top corners to match the card edge. */
.card > .table-responsive:first-child > .table > thead > tr > th:first-child,
.card > .card-body:first-child .table > thead > tr > th:first-child { border-top-left-radius: .25rem; }
.card > .table-responsive:first-child > .table > thead > tr > th:last-child,
.card > .card-body:first-child .table > thead > tr > th:last-child { border-top-right-radius: .25rem; }

@@media (max-width: 991px) {
    .osmis-main { margin-left: 0; }
    .osmis-sidebar { transform: translateX(-100%); }
    .osmis-shell.collapsed .osmis-sidebar { transform: translateX(0); }
}

/* ===== Mobile sidebar safety-net (AdminDek pc-sidebar) =====
   On phones/tablets the theme slides the sidebar in via .mob-sidebar-active (left:-264px → 0).
   These rules harden that so the open menu is PINNED and scrolls on its own instead of
   "rolling" with the page or scrolling off-screen. We deliberately do NOT touch `left`
   (the theme animates it) — only position/height/scroll/stacking + a backdrop + body lock. */
@media (max-width: 1024px) {
    /* Pin the drawer to the viewport and give it its own scroll area. */
    .pc-sidebar {
        position: fixed !important;
        top: 0 !important;
        height: 100vh !important;
        height: 100dvh !important;          /* dynamic viewport height: accounts for mobile URL bar */
        z-index: 1045 !important;            /* above the page + header */
        overflow: hidden !important;         /* the inner scroller handles scrolling */
        -webkit-overflow-scrolling: touch;
    }
    /* The actual scroll container (works with OR without SimpleBar). */
    .pc-sidebar .navbar-content {
        height: calc(100vh - 74px) !important;
        height: calc(100dvh - 74px) !important;
        overflow-y: auto !important;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior: contain;        /* don't chain the scroll to the page behind it */
    }
    /* Dim backdrop behind the open drawer (the theme injects .pc-menu-overlay on open). */
    .pc-sidebar .pc-menu-overlay {
        position: fixed; inset: 0; left: 264px;   /* sit to the right of the open 264px drawer */
        background: rgba(15, 23, 42, .45);
        z-index: -1;                              /* behind the drawer, above the page */
    }
    /* While the drawer is open, stop the page body behind it from scrolling. */
    body.osmis-drawer-open { overflow: hidden !important; }
}

/* ===================================================================================
   PROFESSIONAL POLISH LAYER (2026) — additive, app-wide.
   Deliberately conservative: only low-collision refinements (transitions, focus rings,
   radii, shadows, alert accents, a reusable page header) so the Able Pro theme and the
   140+ existing pages are lifted, not disturbed.
   =================================================================================== */

/* Buttons: tactile press + soft hover shadow on solid variants. */
.btn { transition: transform .12s ease, box-shadow .12s ease, filter .12s ease; }
.btn:active { transform: translateY(1px); }
.btn-primary:hover, .btn-success:hover, .btn-danger:hover, .btn-info:hover, .btn-warning:hover { box-shadow: 0 4px 12px rgba(13,110,253,.20); }

/* Consistent brand focus ring across all inputs. */
.form-control:focus, .form-select:focus, .form-check-input:focus {
    border-color: #86b7fe; box-shadow: 0 0 0 .2rem rgba(13,110,253,.15);
}
.form-control, .form-select { border-radius: 8px; }

/* Cards: consistent radius + a gentle lift for clickable ones (opt-in via .card-hover). */
.card { border-radius: 12px; }
.card-hover { transition: transform .18s ease, box-shadow .18s ease; }
.card-hover:hover { transform: translateY(-2px); box-shadow: 0 12px 28px rgba(20,30,60,.10); }

/* Alerts: softer, with a left accent bar. */
.alert { border-radius: 10px; border-left-width: 4px; }

/* Badges: a touch more weight. */
.badge { font-weight: 600; }

/* Reusable professional page header. Adopt with:
   <div class="page-head"><span class="page-head-icon"><i class="ti ti-..."></i></span>
     <div><h4>Title</h4><div class="text-muted small">subtitle</div></div></div>  */
.page-head {
    display: flex; align-items: center; gap: 1rem; flex-wrap: wrap;
    background: linear-gradient(100deg,#ffffff,#eef3fe); border: 1px solid #dde6f7;
    border-radius: 14px; padding: 1rem 1.25rem; margin-bottom: 1.25rem;
    box-shadow: 0 1px 2px rgba(54,74,99,.05);
}
.page-head .page-head-icon {
    width: 52px; height: 52px; border-radius: 12px; display: inline-flex; align-items: center;
    justify-content: center; color: #fff; font-size: 1.5rem;
    background: linear-gradient(135deg,#4680ff,#0d6efd); box-shadow: 0 6px 16px rgba(13,110,253,.30);
}
.page-head h1, .page-head h2, .page-head h3, .page-head h4 { margin: 0; font-weight: 700; color: #0d6efd; }

/* Modals: softer corners + deeper shadow (header colour rule already app-wide above). */
.modal-content { border: 0; border-radius: 14px; box-shadow: 0 20px 60px rgba(15,23,42,.25); }

/* Refined app-wide scrollbars (WebKit). */
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-thumb { background: #c7d0e0; border-radius: 6px; border: 2px solid transparent; background-clip: content-box; }
*::-webkit-scrollbar-thumb:hover { background: #aab6cc; }

/* ---- Assessment/page-design system, ported from v2 (2026-08-06) ---- */
/* The title block takes the slack so an action cluster sits hard right at any width. */
.page-head > .page-head-body { flex: 1 1 18rem; min-width: 0; }
.page-head .page-head-sub { color: #6c757d; font-size: .82rem; margin-top: .15rem; }
/* Context chips (school, term, scope) — one wrapping row that never pushes the title around. */
.page-head .page-head-meta { display: flex; flex-wrap: wrap; gap: .35rem; align-items: center; margin-top: .4rem; }
.page-head .page-head-meta .badge { background: #fff; border: 1px solid #dde6f7; color: #364a63; font-weight: 600; }
.page-head .page-head-actions { display: flex; flex-wrap: wrap; gap: .5rem; margin-left: auto; }

/* Accent variants. One page = one accent, so a module reads as a set while each screen stays
   recognisable. Tint, border, title colour and icon move together; a page states only its accent. */
.page-head.accent-teal { background: linear-gradient(100deg,#ffffff,#e9fbfe); border-color: #cdeef5; }
.page-head.accent-teal .page-head-icon { background: linear-gradient(135deg,#09c2de,#0a8aa0); box-shadow: 0 6px 16px rgba(9,194,222,.30); }
.page-head.accent-teal h1, .page-head.accent-teal h2, .page-head.accent-teal h3, .page-head.accent-teal h4 { color: #0a8aa0; }
.page-head.accent-amber { background: linear-gradient(100deg,#ffffff,#fff7f3); border-color: #f1e4dc; }
.page-head.accent-amber .page-head-icon { background: linear-gradient(135deg,#e0824b,#c0562a); box-shadow: 0 6px 16px rgba(192,86,42,.30); }
.page-head.accent-amber h1, .page-head.accent-amber h2, .page-head.accent-amber h3, .page-head.accent-amber h4 { color: #c0562a; }
.page-head.accent-green { background: linear-gradient(100deg,#ffffff,#eafaf2); border-color: #cfeddf; }
.page-head.accent-green .page-head-icon { background: linear-gradient(135deg,#2dce89,#12905c); box-shadow: 0 6px 16px rgba(45,206,137,.30); }
.page-head.accent-green h1, .page-head.accent-green h2, .page-head.accent-green h3, .page-head.accent-green h4 { color: #12905c; }
.page-head.accent-violet { background: linear-gradient(100deg,#ffffff,#f3f2ff); border-color: #e2dffb; }
.page-head.accent-violet .page-head-icon { background: linear-gradient(135deg,#8b7bff,#5b46e5); box-shadow: 0 6px 16px rgba(101,118,255,.30); }
.page-head.accent-violet h1, .page-head.accent-violet h2, .page-head.accent-violet h3, .page-head.accent-violet h4 { color: #5b46e5; }

/* Filter bar — the "choose class / stream / term" panel that opens nearly every screen. Its own
   surface, so it reads as controls rather than as the first block of content. */
.filter-card { border: 1px solid #e5eaf3; border-top: 3px solid #0d6efd; border-radius: 12px;
    background: #fbfdff; box-shadow: 0 1px 2px rgba(54,74,99,.05); margin-bottom: 1rem; }
.filter-card > .card-body { padding: .9rem 1rem; }
.filter-card .filter-legend { font-size: .78rem; font-weight: 700; letter-spacing: .02em;
    text-transform: uppercase; color: #0d6efd; margin-bottom: .6rem; }

/* Section card — the standard content block, so a page of four panels doesn't show four different
   corner radii and three different header treatments. */
.section-card { border: 1px solid #e5eaf3; border-radius: 12px; box-shadow: 0 1px 3px rgba(54,74,99,.06); margin-bottom: 1rem; }
.section-card > .card-header { background: #fff; border-bottom: 1px solid #eef2f8; border-radius: 12px 12px 0 0;
    padding: .75rem 1rem; font-weight: 700; color: #364a63; display: flex; align-items: center;
    justify-content: space-between; gap: .75rem; flex-wrap: wrap; }
.section-card > .card-header .sc-title { display: flex; align-items: center; gap: .45rem; }

/* Stat tiles — the count strip above a table (compiled / excluded / sheets attached …). */
.stat-row { display: grid; grid-template-columns: repeat(auto-fit,minmax(9.5rem,1fr)); gap: .75rem; margin-bottom: 1rem; }
.stat-tile { border: 1px solid #e5eaf3; border-radius: 12px; background: #fff; padding: .7rem .9rem;
    box-shadow: 0 1px 2px rgba(54,74,99,.05); }
.stat-tile .stat-label { font-size: .72rem; text-transform: uppercase; letter-spacing: .03em; color: #8094ae; font-weight: 700; }
.stat-tile .stat-value { font-size: 1.35rem; font-weight: 700; color: #364a63; line-height: 1.2; }
.stat-tile.is-good .stat-value { color: #12905c; }
.stat-tile.is-warn .stat-value { color: #c0562a; }
.stat-tile.is-bad  .stat-value { color: #d92d20; }

/* Data tables: quieter header, roomier rows, optional sticky head for a long stream. */
.table-clean thead th { background: #f6f9fe; color: #52627a; font-size: .75rem; text-transform: uppercase;
    letter-spacing: .03em; font-weight: 700; border-bottom: 1px solid #e3eaf5; white-space: nowrap; }
.table-clean tbody td { vertical-align: middle; }
.table-clean tbody tr:hover > * { background: #f8fbff; }
.table-sticky thead th { position: sticky; top: 0; z-index: 2; }
