/*
 * ems-enterprise.css — the restraint layer.
 * ═════════════════════════════════════════════════════════════════════════════════════════════
 *
 * The brief: the product read as colourful rather than professional, and it is shown to
 * international clients who benchmark it against enterprise SaaS. This layer does not redesign
 * anything. It TAKES COLOUR AWAY and gives back consistency — one accent, one radius, one
 * shadow, one type scale, and figures in ink.
 *
 * The governing idea: in enterprise software colour is a SIGNAL, not decoration. If eight things
 * on a screen are coloured, none of them is telling you anything. So money is ink-black, the
 * accent is reserved for what you can act on (links, the active tab, the primary button), and
 * red and green appear only where over/under is the actual meaning.
 *
 * ─────────────────────────────────────────────────────────────────────────────────────────────
 * ⚠ FIVE RULES THIS FILE OBEYS, so that a platform-wide restyle cannot become a platform-wide
 * outage:
 *
 *  1. PRESENTATION ONLY. No layout is restructured, nothing is hidden, nothing moves. Every
 *     declaration is a colour, a border, a radius, a shadow, a weight or a spacing value. The
 *     worst case of a mistake in this file is that something looks wrong, never that it stops
 *     working.
 *
 *  2. ENTIRELY INSIDE @media screen. Not one declaration here is ever seen by a print
 *     stylesheet, so every printed voucher, mark sheet, salary slip and certificate is
 *     structurally unaffected rather than merely tested. That matters more than usual: printing
 *     is how this product's output actually leaves the building.
 *
 *  3. SCOPED TO body.ems-ent, which template/header.php sets for the staff chrome only. The
 *     parent/student portal has its own design language and its own redesign, and the Flutter
 *     apps are a separate codebase entirely.
 *
 *  4. THE ALREADY-APPROVED PANES ARE LEFT ALONE — Financial Summary, Balance Sheet by Class and
 *     by Student, the financial and attendance dashboards, and the six executive dashboards.
 *     Those were designed to a handoff and signed off, so this layer must lose to them.
 *
 *     Five of the six sheets are scoped by ID (#balance_sheet_summary, #balance_sheet_class_wise,
 *     #student_wise_balance_sheet, #bi_financial, #attendance_executive), and an ID selector
 *     beats this file's class selectors whichever loads last — they were protected for free.
 *
 *     ⚠ ems-bi-dash.css WAS NOT. It is scoped `.ems-bi.ems-bi`, whose doubled class is itself a
 *     specificity bump — but it TIED with this file's `body.ems-ent ...` selectors, and a tie is
 *     decided by load order, which this file wins by design. The six executive dashboards would
 *     silently have been restyled. Its scope was raised to `.ems-bi.ems-bi.ems-bi`: a pure
 *     specificity change, not one declaration altered, so the approved design renders exactly as
 *     before and now provably outranks this layer.
 *
 *     That protection only holds while this file stays off !important for the same properties,
 *     which is why !important below is confined to killing gradients and to Limitless's own
 *     !important utility classes.
 *
 *  5. ONE FILE, ONE <link>. Deleting that line reverts the entire look instantly, with no
 *     migration and no backend change to undo.
 */

@media screen {

    /* ═══════════════════════════════════════════════════════════════════════════════════════
       TOKENS
       ───────────────────────────────────────────────────────────────────────────────────────
       Neutrals carry a slight blue bias (note the greys are not pure grey — 0b1220 rather than
       111111). Against a warm-white surface that reads as considered; a pure neutral grey reads
       as a default nobody chose.
       ═══════════════════════════════════════════════════════════════════════════════════════ */

    body.ems-ent {
        --e-ground: #f6f7f9;
        --e-surface: #ffffff;
        --e-raised: #fbfcfd;

        --e-ink: #0b1220;
        --e-body: #414b5a;
        --e-muted: #68717f;
        --e-faint: #98a1ad;

        --e-line: #e5e8ed;
        --e-line-soft: #eff1f5;

        /* ONE accent. Deep enough to sit against white without shouting — the brighter blue this
           product used reads as a consumer app. */
        --e-accent: #1d4ed8;
        --e-accent-hover: #1a3fb0;
        --e-accent-wash: #eef3ff;
        --e-accent-line: #d3e0fb;

        /* Semantics, deliberately desaturated. These are for STATE — paid/unpaid, present/absent,
           approved/rejected — and nothing else. They are never used to make a number look
           interesting. */
        --e-pos: #0f6b4a;
        --e-pos-wash: #e9f4ef;
        --e-pos-line: #cbe5da;
        --e-warn: #8a5a00;
        --e-warn-wash: #fdf5e6;
        --e-warn-line: #f0dfb8;
        --e-crit: #9f2f26;
        --e-crit-wash: #fbeeed;
        --e-crit-line: #f0cfcc;

        --e-radius: 10px;
        --e-radius-sm: 7px;
        /* ONE shadow. The template stacks several, which at card size reads as heavy rather than
           as lifted. */
        --e-shadow: 0 1px 2px rgba(11, 18, 32, .04), 0 6px 16px -10px rgba(11, 18, 32, .14);
    }

    body.ems-ent {
        background: var(--e-ground);
        color: var(--e-body);
        /* Inter is already linked by head.php. Named here so this layer does not depend on
           whichever stack happens to win further up. */
        font-family: Inter, "Segoe UI", Roboto, system-ui, -apple-system, sans-serif;
        -webkit-font-smoothing: antialiased;
    }

    /* Every figure in this product is read in a column against another figure. Lining figures are
       the single cheapest thing that makes a table look engineered. */
    body.ems-ent table,
    body.ems-ent .card-body,
    body.ems-ent input,
    body.ems-ent select { font-variant-numeric: tabular-nums; }

    /* ═══════════════════════════════════════════════════════════════════════════════════════
       NO GRADIENTS, NO TEXTURES
       ───────────────────────────────────────────────────────────────────────────────────────
       Limitless paints tiled PNGs behind panel headers and gradients behind buttons and tiles.
       Both are the strongest single signal of a 2014 admin template. This is the one place
       !important is unavoidable: the gradients are set by the vendor's own !important utilities.

       Deliberately NOT `background: none`, which would also strip a colour that a rule below
       intends to keep. Only the image layer goes.
       ═══════════════════════════════════════════════════════════════════════════════════════ */

    body.ems-ent .card,
    body.ems-ent .card-header,
    body.ems-ent .card-img-top,
    body.ems-ent .panel,
    body.ems-ent .panel-heading,
    body.ems-ent .page-header,
    body.ems-ent .navbar,
    body.ems-ent .btn,
    body.ems-ent .bg-light,
    body.ems-ent .bg-white { background-image: none !important; }

    /* ═══════════════════════════════════════════════════════════════════════════════════════
       CHROME — the two bars above every page
       ═══════════════════════════════════════════════════════════════════════════════════════ */

    body.ems-ent .navbar {
        background: var(--e-surface);
        border-bottom: 1px solid var(--e-line);
        box-shadow: none;
    }

    /* The school's own name. It was a saturated link-blue, which made the most permanent thing on
       screen look like something to click. */
    body.ems-ent .navbar-brand,
    body.ems-ent .navbar-brand a {
        color: var(--e-ink) !important;
        font-weight: 650;
        letter-spacing: -.01em;
    }

    body.ems-ent .navbar-brand small,
    body.ems-ent .navbar-brand .text-muted { color: var(--e-faint) !important; font-weight: 400; }

    /*
     * ⚠ The academic session was rendered in ALARM RED (.text-danger, #ef5350).
     *
     * "2026-27" is not a warning — it is the single most permanent fact on the screen, and it was
     * the loudest thing in the chrome. Red here also devalues red everywhere else: if the year is
     * red, an actually overdue figure has nothing left to say. It becomes quiet ink with the
     * accent reserved for interaction.
     *
     * Restricted to the navbar so .text-danger keeps meaning "danger" in page content.
     */
    body.ems-ent .navbar .navbar-nav-link.text-danger,
    body.ems-ent .navbar .text-danger {
        color: var(--e-ink) !important;
        font-weight: 600;
    }

    /*
     * The menu type. Inter at 12.75px / 500 with the tracking pulled in slightly — at this size
     * a default tracking makes eleven menu items look loose and consumer-ish, and negative
     * tracking is what makes a nav bar read as considered rather than as a list of links.
     */
    body.ems-ent .navbar-nav-link {
        color: var(--e-body);
        font-size: 12.75px;
        font-weight: 500;
        letter-spacing: -.012em;
    }

    body.ems-ent .navbar-nav-link:hover {
        color: var(--e-ink);
        background: var(--e-raised);
    }

    /* The dropdown caret is punctuation, not content. */
    body.ems-ent .navbar-nav-link.dropdown-toggle::after,
    body.ems-ent .navbar-nav-link > .caret { opacity: .45; }

    /*
     * ⚠ THE ACTIVE ITEM'S UNDERLINE CURVED UP AT BOTH ENDS INTO A SMILE.
     *
     * It was drawn with `box-shadow: inset 0 -2px 0`, which looks like an underline on a square
     * element — but another sheet in the stack puts `border-radius: 9px` on these links, and an
     * inset shadow FOLLOWS the border radius. So the bar bent around both bottom corners and read
     * as a stray blue outline rather than as an indicator.
     *
     * A pseudo-element instead: genuinely straight, and inset to the link's own horizontal
     * padding so it sits under the LABEL rather than spanning the whole padded box — which is
     * what makes it look drawn rather than leaked.
     *
     * The label itself goes to ink at a heavier weight and the accent is left to the bar alone.
     * Colouring both said the same thing twice, and this bar is the one piece of accent in the
     * chrome, so it should not have to compete with the word above it.
     */
    body.ems-ent .navbar .nav-item > .navbar-nav-link.active,
    body.ems-ent .navbar .nav-item.active > .navbar-nav-link {
        position: relative;
        color: var(--e-ink);
        font-weight: 600;
        background: transparent;
        box-shadow: none;
    }

    body.ems-ent .navbar .nav-item > .navbar-nav-link.active::before,
    body.ems-ent .navbar .nav-item.active > .navbar-nav-link::before {
        content: "";
        position: absolute;
        left: 11px;
        right: 11px;
        bottom: 0;
        height: 2px;
        background: var(--e-accent);
        /* Square. The radius on the parent is what caused the problem being fixed here. */
        border-radius: 0;
    }

    /* ═══════════════════════════════════════════════════════════════════════════════════════
       SURFACES
       ═══════════════════════════════════════════════════════════════════════════════════════ */

    body.ems-ent .card,
    body.ems-ent .panel {
        background: var(--e-surface);
        border: 1px solid var(--e-line);
        border-radius: var(--e-radius);
        box-shadow: var(--e-shadow);
        margin-bottom: 14px;
    }

    body.ems-ent .card-header,
    body.ems-ent .panel-heading {
        background: var(--e-surface);
        border-bottom: 1px solid var(--e-line-soft);
        padding: 11px 16px;
    }

    body.ems-ent .card-title,
    body.ems-ent .panel-title {
        font-size: 14px;
        font-weight: 650;
        color: var(--e-ink);
        letter-spacing: -.01em;
        margin: 0;
    }

    body.ems-ent .card-body { padding: 16px; }

    /*
     * ⚠ The page gutter, which is most of the wasted space on a dense screen.
     *
     * Limitless pads .content generously on all four sides, and on a 1366px laptop — which is
     * what school offices actually run — that is a visible strip of nothing down both edges
     * before any data starts. Trimmed rather than removed: the page should still not look
     * welded to the browser frame.
     */
    body.ems-ent .content { padding: 12px 14px; }
    body.ems-ent .content-wrapper > .content:first-child { padding-top: 10px; }

    /* Limitless's tinted panel variants. Enterprise surfaces are white; the tint was doing the
       job a heading should do. */
    body.ems-ent .card.bg-light,
    body.ems-ent .card-header.bg-light,
    body.ems-ent .bg-light { background-color: var(--e-raised) !important; color: var(--e-body); }

    /* ═══════════════════════════════════════════════════════════════════════════════════════
       TYPE
       ───────────────────────────────────────────────────────────────────────────────────────
       A tight scale. The product had headings at half a dozen sizes with no relationship between
       them, which is most of why dense screens read as busy.
       ═══════════════════════════════════════════════════════════════════════════════════════ */

    body.ems-ent h1, body.ems-ent h2, body.ems-ent h3,
    body.ems-ent h4, body.ems-ent h5, body.ems-ent h6 {
        color: var(--e-ink);
        letter-spacing: -.015em;
        font-weight: 650;
    }

    body.ems-ent .page-title h4,
    body.ems-ent .page-header h4 { font-size: 19px; }

    /* Section headings inside a card. Micro-caps rather than another near-title: it separates
       without adding a third level of shouting. */
    body.ems-ent .element-header,
    body.ems-ent .pagetitleh2 {
        font-size: 11px;
        font-weight: 700;
        letter-spacing: .08em;
        text-transform: uppercase;
        color: var(--e-muted);
        margin: 18px 0 10px;
        padding-bottom: 7px;
        border-bottom: 1px solid var(--e-line-soft);
    }

    body.ems-ent a { color: var(--e-accent); }
    body.ems-ent a:hover { color: var(--e-accent-hover); }

    body.ems-ent .text-muted { color: var(--e-muted) !important; }

    /* ═══════════════════════════════════════════════════════════════════════════════════════
       TABLES — the largest surface in the product
       ═══════════════════════════════════════════════════════════════════════════════════════ */

    body.ems-ent .table,
    body.ems-ent table.dataTable {
        border-collapse: separate;
        border-spacing: 0;
        font-size: 13px;
        color: var(--e-body);
    }

    /*
     * A micro-label header. Uppercase at 10px carries the same information as 13px bold while
     * taking up less of the eye's attention, which is the point: the DATA is the content.
     *
     * ⚠ DENSITY. 7px/11px padding puts a row at roughly 34px rather than 51px, so a screen shows
     * around fifteen rows instead of ten. That is the difference between reading a class list and
     * scrolling one, and on the grids this product is mostly made of it is worth more than the
     * extra air. The row RULE does the separating, so the whitespace is not load-bearing.
     */
    body.ems-ent .table thead th,
    body.ems-ent table.dataTable thead th,
    body.ems-ent .panel table thead th {
        background: var(--e-raised);
        color: var(--e-muted);
        font-size: 10px;
        font-weight: 700;
        letter-spacing: .07em;
        text-transform: uppercase;
        padding: 8px 11px;
        border: 0;
        border-bottom: 1px solid var(--e-line);
        white-space: nowrap;
        vertical-align: middle;
    }

    body.ems-ent .table tbody td,
    body.ems-ent table.dataTable tbody td {
        padding: 7px 11px;
        border: 0;
        border-bottom: 1px solid var(--e-line-soft);
        vertical-align: middle;
        line-height: 1.45;
    }

    /* The vendor's own "condensed" variants tighten further still; keep them meaningfully
       denser than the new default rather than letting the two converge. */
    body.ems-ent .table-sm td,
    body.ems-ent .table-sm th,
    body.ems-ent .table-condensed td,
    body.ems-ent .table-condensed th { padding: 5px 9px; }

    body.ems-ent .table tbody tr:hover > td,
    body.ems-ent table.dataTable tbody tr:hover > td { background: var(--e-accent-wash); }

    /*
     * ⚠ ZEBRA STRIPING OFF.
     *
     * table-striped paints every other row grey. With a hover state and hairline row rules it is
     * redundant, and two competing background treatments is what makes a long grid feel noisy.
     * The hairline does the same job with a twentieth of the ink.
     */
    body.ems-ent .table-striped tbody tr:nth-of-type(odd) { background-color: transparent; }

    body.ems-ent .table-bordered,
    body.ems-ent .table-bordered td,
    body.ems-ent .table-bordered th { border-color: var(--e-line-soft); }

    /* ── DataTables chrome ────────────────────────────────────────────────────────────────── */

    body.ems-ent .dataTables_wrapper .dataTables_length select,
    body.ems-ent .dataTables_wrapper .dataTables_filter input {
        border: 1px solid var(--e-line);
        border-radius: var(--e-radius-sm);
        padding: 4px 9px;
        font-size: 12px;
        min-height: 30px;
        background: var(--e-surface);
        color: var(--e-ink);
    }

    body.ems-ent .dataTables_wrapper .dataTables_info,
    body.ems-ent .dataTables_wrapper .dataTables_length,
    body.ems-ent .dataTables_wrapper .dataTables_filter {
        font-size: 12.5px;
        color: var(--e-muted);
    }

    body.ems-ent .dataTables_wrapper .dataTables_paginate .paginate_button {
        border-radius: var(--e-radius-sm) !important;
        border: 1px solid transparent !important;
        background: transparent !important;
        color: var(--e-muted) !important;
        padding: 3px 9px !important;
        margin: 0 1px;
        font-size: 12px;
    }

    body.ems-ent .dataTables_wrapper .dataTables_paginate .paginate_button:hover {
        background: var(--e-accent-wash) !important;
        border-color: var(--e-line) !important;
        color: var(--e-ink) !important;
    }

    body.ems-ent .dataTables_wrapper .dataTables_paginate .paginate_button.current {
        background: var(--e-accent) !important;
        border-color: var(--e-accent) !important;
        color: #fff !important;
        font-weight: 600;
    }

    /* Export buttons read as secondary, because they are. */
    body.ems-ent .dt-buttons .dt-button {
        border-radius: var(--e-radius-sm) !important;
        border: 1px solid var(--e-line) !important;
        background: var(--e-surface) !important;
        color: var(--e-body) !important;
        font-size: 12px;
        font-weight: 600;
        padding: 4px 10px !important;
        margin-right: 4px;
    }

    body.ems-ent .dt-buttons .dt-button:hover {
        background: var(--e-accent-wash) !important;
        border-color: var(--e-accent-line) !important;
        color: var(--e-accent-hover) !important;
    }

    /* ═══════════════════════════════════════════════════════════════════════════════════════
       FORMS
       ═══════════════════════════════════════════════════════════════════════════════════════ */

    body.ems-ent label {
        font-size: 11.5px;
        font-weight: 600;
        color: var(--e-muted);
        margin-bottom: 4px;
    }

    /* A form row's own gap, which on the long staff and admission forms compounds over forty
       fields into a page and a half of scrolling. */
    body.ems-ent .form-group { margin-bottom: 12px; }

    body.ems-ent .form-control,
    body.ems-ent .custom-select,
    body.ems-ent select.form-control {
        border: 1px solid var(--e-line);
        border-radius: var(--e-radius-sm);
        font-size: 12.5px;
        min-height: 34px;
        height: auto;
        padding: 6px 10px;
        color: var(--e-ink);
        background-color: var(--e-surface);
        box-shadow: none;
        transition: border-color .12s ease, box-shadow .12s ease;
    }

    body.ems-ent .form-control:hover { border-color: #ced4dd; }

    body.ems-ent .form-control:focus,
    body.ems-ent .custom-select:focus {
        border-color: var(--e-accent);
        box-shadow: 0 0 0 3px rgba(29, 78, 216, .11);
        outline: 0;
    }

    body.ems-ent .form-control::placeholder { color: var(--e-faint); }

    body.ems-ent .form-control:disabled,
    body.ems-ent .form-control[readonly] { background: var(--e-raised); color: var(--e-muted); }

    body.ems-ent .select2-container--default .select2-selection--single,
    body.ems-ent .select2-container--default .select2-selection--multiple {
        border: 1px solid var(--e-line) !important;
        border-radius: var(--e-radius-sm) !important;
        min-height: 38px;
    }

    /* ═══════════════════════════════════════════════════════════════════════════════════════
       BUTTONS
       ───────────────────────────────────────────────────────────────────────────────────────
       ⚠ ONE primary per screen is the intent. The product paints btn-primary, bg-blue, btn-info,
       btn-success and btn-warning as equally loud filled blocks, so a screen with six buttons has
       six primaries and the eye has nowhere to land. Everything that is not the primary action
       becomes a quiet outline; the colour stays available for the one button that matters.
       ═══════════════════════════════════════════════════════════════════════════════════════ */

    body.ems-ent .btn {
        border-radius: var(--e-radius-sm);
        font-size: 13px;
        font-weight: 600;
        padding: 6px 13px;
        letter-spacing: 0;
        text-transform: none;
        box-shadow: none;
        transition: background-color .12s ease, border-color .12s ease, color .12s ease;
    }

    body.ems-ent .btn-sm { padding: 4px 10px; font-size: 12px; }
    body.ems-ent .btn-lg { padding: 9px 18px; font-size: 13.5px; }

    body.ems-ent .btn-primary,
    body.ems-ent .bg-blue {
        background-color: var(--e-accent);
        border-color: var(--e-accent);
        color: #fff;
    }

    body.ems-ent .btn-primary:hover,
    body.ems-ent .btn-primary:focus {
        background-color: var(--e-accent-hover);
        border-color: var(--e-accent-hover);
        color: #fff;
    }

    /* Secondary intents, quietened. They keep their meaning on hover and in their icon; what they
       lose is the right to shout on arrival. */
    body.ems-ent .btn-info,
    body.ems-ent .btn-secondary,
    body.ems-ent .btn-default,
    body.ems-ent .btn-warning,
    body.ems-ent .btn-success {
        background-color: var(--e-surface);
        border-color: var(--e-line);
        color: var(--e-body);
    }

    body.ems-ent .btn-info:hover,
    body.ems-ent .btn-secondary:hover,
    body.ems-ent .btn-default:hover,
    body.ems-ent .btn-warning:hover,
    body.ems-ent .btn-success:hover {
        background-color: var(--e-accent-wash);
        border-color: var(--e-accent-line);
        color: var(--e-accent-hover);
    }

    /* Destructive keeps its colour, because that one IS a signal — but as an outline until the
       pointer is on it, so a grid of delete buttons is not a wall of red. */
    body.ems-ent .btn-danger {
        background-color: var(--e-surface);
        border-color: var(--e-crit-line);
        color: var(--e-crit);
    }

    body.ems-ent .btn-danger:hover {
        background-color: var(--e-crit);
        border-color: var(--e-crit);
        color: #fff;
    }

    /*
     * ⚠ THE ACTION CELL MUST NOT WRAP — tightening the grid made it wrap and cost more height
     * than the tightening saved.
     *
     * Narrower cell padding let DataTables give the Action column less width, so its three icon
     * buttons broke onto a second line and every row grew from ~34px to ~78px. Pinning the cell
     * to nowrap makes the column claim exactly the width its buttons need, which is what it was
     * getting implicitly before.
     *
     * :has() rather than :last-child, because the action column is not last on every grid — on
     * several it sits mid-table with totals after it.
     */
    body.ems-ent .table td:has(> .btn),
    body.ems-ent .table td:has(> a.btn),
    body.ems-ent table.dataTable td:has(> .btn) { white-space: nowrap; }

    /* Row action icons. A hundred rows × three filled buttons was the loudest thing in the app. */
    body.ems-ent .table td .btn {
        background: var(--e-raised);
        border: 1px solid var(--e-line);
        color: var(--e-muted);
        padding: 3px 7px;
        margin-right: 2px;
    }

    body.ems-ent .table td .btn:hover {
        background: var(--e-accent-wash);
        border-color: var(--e-accent-line);
        color: var(--e-accent-hover);
    }

    /* ═══════════════════════════════════════════════════════════════════════════════════════
       STATUS — the one place colour still speaks
       ───────────────────────────────────────────────────────────────────────────────────────
       Soft fill, matching hairline, dark text. A grid can carry two hundred of these; two hundred
       saturated chips is a stained-glass window, and none of them reads as urgent.
       ═══════════════════════════════════════════════════════════════════════════════════════ */

    body.ems-ent .badge,
    body.ems-ent .label {
        border-radius: 999px;
        padding: 2px 8px;
        font-size: 10.5px;
        font-weight: 650;
        letter-spacing: .01em;
        border: 1px solid transparent;
        box-shadow: none;
    }

    body.ems-ent .badge-success, body.ems-ent .label-success, body.ems-ent .badge.bg-success {
        background-color: var(--e-pos-wash) !important;
        color: var(--e-pos) !important;
        border-color: var(--e-pos-line);
    }

    body.ems-ent .badge-warning, body.ems-ent .label-warning, body.ems-ent .badge.bg-warning {
        background-color: var(--e-warn-wash) !important;
        color: var(--e-warn) !important;
        border-color: var(--e-warn-line);
    }

    body.ems-ent .badge-danger, body.ems-ent .label-danger, body.ems-ent .badge.bg-danger {
        background-color: var(--e-crit-wash) !important;
        color: var(--e-crit) !important;
        border-color: var(--e-crit-line);
    }

    body.ems-ent .badge-info, body.ems-ent .label-info, body.ems-ent .badge.bg-info,
    body.ems-ent .badge-primary, body.ems-ent .badge.bg-primary {
        background-color: var(--e-accent-wash) !important;
        color: var(--e-accent-hover) !important;
        border-color: var(--e-accent-line);
    }

    body.ems-ent .badge-secondary, body.ems-ent .label-default, body.ems-ent .badge.bg-secondary {
        background-color: var(--e-raised) !important;
        color: var(--e-muted) !important;
        border-color: var(--e-line);
    }

    /* ═══════════════════════════════════════════════════════════════════════════════════════
       KPI TILES
       ───────────────────────────────────────────────────────────────────────────────────────
       ⚠ THE FIGURE GOES BACK TO INK.
       Dashboards rendered their headline numbers in saturated red, green and blue. A number is
       not good or bad on its own — 33,454,951 receivable is simply the fact — and colouring all
       of them means the one figure that IS in trouble has no way left to say so. Caption muted,
       number ink, supporting line small. Where a tile genuinely encodes state it can still opt in
       via a badge, which is what badges are for.
       ═══════════════════════════════════════════════════════════════════════════════════════ */

    body.ems-ent .small-box,
    body.ems-ent .info-box,
    body.ems-ent .kpi,
    body.ems-ent .ep-kpi,
    body.ems-ent .spf-kpi {
        background: var(--e-surface) !important;
        border: 1px solid var(--e-line);
        border-radius: var(--e-radius);
        box-shadow: var(--e-shadow);
        color: var(--e-body) !important;
    }

    body.ems-ent .small-box h3,
    body.ems-ent .info-box-number,
    body.ems-ent .kpi-value {
        color: var(--e-ink) !important;
        font-weight: 700;
        letter-spacing: -.02em;
        font-variant-numeric: tabular-nums;
    }

    body.ems-ent .small-box p,
    body.ems-ent .info-box-text,
    body.ems-ent .kpi-label {
        color: var(--e-muted) !important;
        font-size: 11px;
        font-weight: 650;
        letter-spacing: .07em;
        text-transform: uppercase;
    }

    /* The vendor's saturated tile fills. */
    body.ems-ent .small-box.bg-aqua, body.ems-ent .small-box.bg-green,
    body.ems-ent .small-box.bg-yellow, body.ems-ent .small-box.bg-red,
    body.ems-ent .small-box.bg-blue, body.ems-ent .small-box.bg-teal,
    body.ems-ent .small-box.bg-purple, body.ems-ent .small-box.bg-orange {
        background: var(--e-surface) !important;
    }

    /* Their decorative watermark icon, at a fifth of its old presence. */
    body.ems-ent .small-box .icon { color: var(--e-line); opacity: .55; }

    /* ═══════════════════════════════════════════════════════════════════════════════════════
       NOTICES
       ═══════════════════════════════════════════════════════════════════════════════════════ */

    body.ems-ent .alert {
        border-radius: var(--e-radius-sm);
        border: 1px solid var(--e-line);
        background: var(--e-raised);
        color: var(--e-body);
        font-size: 12.5px;
        padding: 9px 13px;
        box-shadow: none;
    }

    body.ems-ent .alert-info {
        background: var(--e-accent-wash);
        border-color: var(--e-accent-line);
        color: #1a3a8f;
    }

    body.ems-ent .alert-success {
        background: var(--e-pos-wash);
        border-color: var(--e-pos-line);
        color: var(--e-pos);
    }

    body.ems-ent .alert-warning {
        background: var(--e-warn-wash);
        border-color: var(--e-warn-line);
        color: var(--e-warn);
    }

    body.ems-ent .alert-danger {
        background: var(--e-crit-wash);
        border-color: var(--e-crit-line);
        color: var(--e-crit);
    }

    /* ═══════════════════════════════════════════════════════════════════════════════════════
       TABS, MODALS, DROPDOWNS
       ═══════════════════════════════════════════════════════════════════════════════════════ */

    body.ems-ent .nav-tabs { border-bottom: 1px solid var(--e-line); gap: 2px; }

    body.ems-ent .nav-tabs .nav-link {
        border: 0 !important;
        border-bottom: 2px solid transparent !important;
        border-radius: 0;
        padding: 9px 12px;
        font-size: 12.5px;
        font-weight: 600;
        color: var(--e-muted);
        background: transparent !important;
        text-transform: none;
    }

    body.ems-ent .nav-tabs .nav-link:hover { color: var(--e-ink); border-bottom-color: var(--e-line); }

    body.ems-ent .nav-tabs .nav-link.active {
        color: var(--e-accent);
        border-bottom-color: var(--e-accent) !important;
    }

    /*
     * ⚠ LIMITLESS PAINTS A SECOND, PINK INDICATOR — and it is where the odd colour came from.
     *
     * .nav-tabs-highlight / -top / -bottom each get a `::before` bar pinned across the top of the
     * active tab, filled #f35c86. So a tab carried TWO indicators in two unrelated colours: the
     * vendor's pink bar above and the accent underline below. On the staff list that read as a
     * violet smear over "List view" with a blue line under it.
     *
     * The vendor bar goes rather than being recoloured. Recolouring would leave a tab underlined
     * at BOTH edges, which is a heavier thing than an active tab needs — one indicator, one
     * colour, at the bottom, matching every other tab strip in the product.
     */
    body.ems-ent .nav-tabs-highlight .nav-link::before,
    body.ems-ent .nav-tabs-top .nav-link::before,
    body.ems-ent .nav-tabs-bottom .nav-link::before { background-color: transparent !important; }

    body.ems-ent .modal-content {
        border: 0;
        border-radius: var(--e-radius);
        box-shadow: 0 24px 60px -20px rgba(11, 18, 32, .35);
    }

    body.ems-ent .modal-header { border-bottom: 1px solid var(--e-line-soft); padding: 13px 16px; }
    body.ems-ent .modal-title { font-size: 15px; font-weight: 650; color: var(--e-ink); }
    body.ems-ent .modal-footer { border-top: 1px solid var(--e-line-soft); padding: 11px 16px; }

    body.ems-ent .dropdown-menu {
        border: 1px solid var(--e-line);
        border-radius: var(--e-radius-sm);
        box-shadow: 0 12px 32px -12px rgba(11, 18, 32, .22);
        padding: 6px;
        font-size: 13px;
    }

    body.ems-ent .dropdown-item {
        border-radius: 5px;
        padding: 6px 9px;
        color: var(--e-body);
    }

    body.ems-ent .dropdown-item:hover {
        background: var(--e-accent-wash);
        color: var(--e-accent-hover);
    }

    /* ═══════════════════════════════════════════════════════════════════════════════════════
       CONSISTENCY SWEEP — what a walk through the admin actually turned up
       ═══════════════════════════════════════════════════════════════════════════════════════ */

    /*
     * ⚠ EVERY REQUIRED FIELD IN THE PRODUCT SHOWED TWO ASTERISKS: "Title * *".
     *
     * The markup writes its own — `<small class="req"> *</small>` — and ems-modern.css then adds
     * `.ems-ui .req::after { content: " *" }` on top of it. Visible on the admission form, the
     * staff search, the compose screens; anywhere with a required field, which is most of the app.
     *
     * The pseudo-element is the duplicate, so it is the one that goes. Checked before removing
     * rather than assumed: of 505 `.req` elements in the views, 505 already contain an asterisk
     * and NONE is empty, so nothing depends on the generated one.
     */
    body.ems-ent .req::after { content: none !important; }

    /*
     * ⚠ FOUR DIFFERENT SECTION HEADINGS ON ONE FORM.
     *
     * The admission form alone carries `h4.text-danger` (alarm red) for "Required",
     * `h4.text-primary` (bright blue) for "Sibling", a bare `h4` in ink for "Fee Starting", and
     * a micro-caps header for "Optional" — four styles for four headings doing the identical job
     * of dividing one form. That, more than any single colour, is what reads as unprofessional:
     * the page looks assembled by different hands.
     *
     * They all become the one section-heading treatment already used by .element-header and by
     * the accounts reports, so a section header looks the same everywhere in the product.
     */
    body.ems-ent .card-body h4,
    body.ems-ent .panel-body h4 {
        font-size: 12px;
        font-weight: 700;
        letter-spacing: .07em;
        text-transform: uppercase;
        color: var(--e-muted);
        margin: 20px 0 12px;
        padding-bottom: 8px;
        border-bottom: 1px solid var(--e-line-soft);
    }

    body.ems-ent .card-body > h4:first-child,
    body.ems-ent .card-body > .row:first-child h4,
    body.ems-ent .panel-body > h4:first-child { margin-top: 0; }

    /*
     * ⚠ COLOUR CLASSES ON HEADINGS, not on messages.
     *
     * Neutralised only where they sit ON a heading. A heading is not a warning: "Required" in
     * #ef5350 is the same red an overdue balance uses, and "Sibling" in link-blue looks clickable.
     * Left alone everywhere else, so a genuine validation message, an overdue figure or an error
     * banner keeps its colour — that is the whole point of reserving these colours.
     */
    body.ems-ent .card-body h1.text-danger, body.ems-ent .card-body h2.text-danger,
    body.ems-ent .card-body h3.text-danger, body.ems-ent .card-body h4.text-danger,
    body.ems-ent .card-body h5.text-danger, body.ems-ent .card-body h6.text-danger,
    body.ems-ent .card-body h4.text-primary, body.ems-ent .card-body h5.text-primary,
    body.ems-ent .card-body h4.text-info, body.ems-ent .card-body h4.text-success,
    body.ems-ent .card-body h4.text-warning { color: var(--e-muted) !important; }

    /*
     * …and the colour classes NESTED INSIDE a heading, which is how the admission form's
     * "Last Admission No : 2608157, Last Reg# : 1585" stayed alarm-red after the heading itself
     * had been quietened: the h4 is neutral, its child spans were not. A heading is one thing and
     * should be one colour; anything worth flagging inside it belongs in a badge.
     */
    body.ems-ent .card-body h4 .text-danger,
    body.ems-ent .card-body h4 .text-primary,
    body.ems-ent .card-body h4 .text-info,
    body.ems-ent .card-body h4 .text-success,
    body.ems-ent .card-body h4 .text-warning,
    body.ems-ent .card-body h4 b,
    body.ems-ent .card-body h4 strong { color: inherit !important; font-weight: inherit; }

    /*
     * Controls that never got .form-control — the Concession picker on the admission form is one.
     * They render at the browser's default height and border, half a centimetre shorter than the
     * field beside them, which is the sort of thing that reads as unfinished without anyone being
     * able to say why.
     */
    body.ems-ent .card-body select:not(.form-control):not(.custom-select):not([multiple]),
    body.ems-ent .card-body input[type="text"]:not(.form-control),
    body.ems-ent .card-body input[type="number"]:not(.form-control),
    body.ems-ent .card-body input[type="email"]:not(.form-control),
    body.ems-ent .card-body input[type="date"]:not(.form-control) {
        border: 1px solid var(--e-line);
        border-radius: var(--e-radius-sm);
        min-height: 34px;
        padding: 6px 10px;
        font-size: 12.5px;
        color: var(--e-ink);
        background-color: var(--e-surface);
        width: 100%;
    }

    /* ═══════════════════════════════════════════════════════════════════════════════════════
       ACCOUNTS ACTIVITY REPORTS — one document, not a stack of boxes
       ───────────────────────────────────────────────────────────────────────────────────────
       Cash Activity, Bank Activity and General Activity each present two halves — receipts and
       payments, withdrawals and deposits. They are ALREADY inside a single .panel (checked in the
       DOM: one panel, two <h4>, two tables), but they do not read as one: each half carries a
       fully bordered table, its own filter row and its own "Showing n of m" line, so the eye
       counts two or three separate objects and the report looks assembled rather than issued.

       Nothing is restructured — no PHP touched. The two halves are made to read as sections of
       one statement: a ruled heading, hairline rows instead of a boxed grid, and a single
       surface underneath.
       ═══════════════════════════════════════════════════════════════════════════════════════ */

    body.ems-ent #printArea .panel {
        box-shadow: var(--e-shadow);
        border: 1px solid var(--e-line);
        border-radius: var(--e-radius);
    }

    /* The halves. A rule under the heading is what turns "another box" into "next section". */
    body.ems-ent #printArea h4 {
        font-size: 12px;
        font-weight: 700;
        letter-spacing: .07em;
        text-transform: uppercase;
        color: var(--e-muted);
        margin: 22px 0 10px;
        padding-bottom: 8px;
        border-bottom: 1px solid var(--e-line);
    }

    body.ems-ent #printArea > div:first-child h4,
    body.ems-ent #printArea .panel-body > .row:first-child h4 { margin-top: 0; }

    /* The "(detailed)" / "(head-wise)" qualifier is a note, not part of the heading. */
    body.ems-ent #printArea h4 small {
        text-transform: none;
        letter-spacing: 0;
        font-weight: 500;
        color: var(--e-faint);
    }

    /*
     * ⚠ The boxed grid is most of why each half looked like its own card.
     *
     * table-bordered draws a rule on all four sides of every cell, which frames the table as an
     * object sitting ON the card rather than as content OF it. Horizontal hairlines alone
     * separate the rows just as well — that is what every printed ledger does.
     */
    body.ems-ent #printArea .table-bordered,
    body.ems-ent #printArea .table-bordered td,
    body.ems-ent #printArea .table-bordered th { border-left: 0; border-right: 0; }

    body.ems-ent #printArea .table-bordered { border-top: 0; border-bottom: 0; }

    /* The totals line is the one row worth weighting. */
    body.ems-ent #printArea .table tfoot td,
    body.ems-ent #printArea .table tr:last-child td strong,
    body.ems-ent #printArea .table td strong {
        color: var(--e-ink);
        font-weight: 700;
    }

    /* The filter and Show controls belong to the grid, not to the report; quieten them so they
       sit beside the section heading rather than competing with it. */
    body.ems-ent #printArea .dataTables_filter,
    body.ems-ent #printArea .dataTables_length,
    body.ems-ent #printArea .dataTables_info { font-size: 11.5px; color: var(--e-faint); }

    /* The Print button sat alone on its own line above the report, right-aligned against
       nothing. Pulled tight to the card it acts on. */
    body.ems-ent #print { margin-bottom: 6px !important; }

    /* ═══════════════════════════════════════════════════════════════════════════════════════
       ACCESSIBILITY
       ═══════════════════════════════════════════════════════════════════════════════════════ */

    body.ems-ent :focus-visible {
        outline: 2px solid var(--e-accent);
        outline-offset: 1px;
    }

    @media (prefers-reduced-motion: reduce) {
        body.ems-ent * { transition: none !important; animation: none !important; }
    }
}
