/*
 * ems-report-print.css — the approved report look, on the NATIVE print path, for every report.
 * ═════════════════════════════════════════════════════════════════════════════════════════════
 *
 * The design was proven on Search Vouchers and lived inside that one view's <style media="print">
 * block, so every other report in the product still printed plain. This is the same design,
 * expressed once.
 *
 * ─────────────────────────────────────────────────────────────────────────────────────────────
 * ⚠ HOW IT KNOWS WHAT IS A REPORT — and why this cannot reach a fee voucher or a result card.
 *
 * Everything is scoped to `body:has(.ems-print-head)`. That element is emitted by
 * layout/admin_print_template.php, the shared letterhead partial that report views include and
 * that designed documents do not. So a page carrying the report letterhead gets the report look,
 * and a fee voucher, ID card, certificate or result card — each measured to its own sheet — is
 * untouched by every rule below.
 *
 * :has() is the only way to say "a page that contains this" in CSS. Chrome and Edge have
 * supported it since 105; where it is not supported nothing matches and reports simply print as
 * they did before, which is a safe way to be wrong.
 *
 * ⚠ AND IT IS THE NATIVE PATH ONLY. The Export PDF button renders server-side through
 * Report_pdf, which builds its own document and never sees this file. The two paths are separate
 * renderers by design; this is what stops them looking like two different products.
 */

/*
 * ⚠ THE LETTERHEAD IS FOR PAPER ONLY.
 *
 * Checked on the live accounts report after adding it: it rendered ON SCREEN, above the report,
 * because whatever hides `.print-only` elsewhere does not reach this page — so the school block
 * appeared twice to anyone simply looking at the report.
 *
 * Stated here rather than assumed, because this file is the one that puts the letterhead to
 * work; a hook it introduces should not depend on another stylesheet remembering to hide it.
 */
@media screen {
    .print-only { display: none !important; }

    /*
     * The report toolbar, grouped.
     *
     * The buttons do three different kinds of work — act on selected rows, export the data,
     * produce the report — and were laid out as one undifferentiated row, so a destructive
     * action sat a pixel from a harmless one. A gap between groups is all that is needed for the
     * row to read as three ideas rather than seven buttons; the grouping itself is in the
     * markup, and this only keeps each group from breaking across a line.
     */
    .ems-btn-group {
        display: inline-flex;
        align-items: center;
        white-space: nowrap;
    }

    /* An empty group must not leave a gap of its own — the selection buttons are hidden until
       something is actually ticked. */
    .ems-btn-group:empty { display: none; }
}

/*
 * ⚠ THE SHEET'S OWN MARGIN, set once and small.
 *
 * Left to the browser this is around 10mm a side plus the shell's padding, which is what put an
 * inch of nothing down both edges of a wide accounting grid. 8mm clears every printer's
 * unprintable border with room to spare while giving the report the page.
 *
 * Deliberately NOT declaring `size`. Naming a size here would pin the paper and, in Chrome and
 * Edge, take Orientation out of the print dialogue — and both the orientation control and the
 * Scale control have to keep working. The user picks the paper; this only sets the margin.
 */
@page {
    margin: 8mm;
}

@media print {

    /* ── The letterhead ─────────────────────────────────────────────────────────────────────
     * Sizing lives with the markup in admin_print_template.php. What is here is the report
     * TREATMENT: the rule under the band, and the school name at document weight.
     */
    body:has(.ems-print-head) .ems-print-head {
        align-items: center;
        padding-bottom: 6px;
        border-bottom: 2px solid #0f1b3d;
    }

    body:has(.ems-print-head) .ems-print-head h2 {
        font-size: 16pt !important;
        text-transform: uppercase;
        letter-spacing: .01em;
        color: #0f1b3d;
    }

    body:has(.ems-print-head) .ems-print-head h4,
    body:has(.ems-print-head) .ems-print-head h5 { font-size: 9pt !important; color: #333; }

    /*
     * ⚠ THE SCREEN'S CARD HEADING DOES NOT PRINT.
     *
     * A report's card header repeats its own title and, on several, a "Figures as at …" stamp.
     * Both orient someone looking at the SCREEN — the stamp exists so two screens can be
     * compared for drift. On paper the letterhead already names the report and the filter block
     * already says when it was produced, so printing them again is a duplicate title and a
     * second timestamp saying the same thing.
     *
     * Hidden, not removed: both do real work on screen and only on screen.
     */
    body:has(.ems-print-head) .card-header { display: none !important; }

    /*
     * ⚠ THE APPLICATION'S NAVIGATION MUST NEVER REACH THE PAPER.
     *
     * The accounts reports are a tab hub: Voucher Report, Expense Book, Income Book, Cash Book,
     * Bank Book, General Ledger, Trial Balance … nineteen links rendered above the report. They
     * were printing, so a financial statement opened with the application's menu system before
     * it said anything about money — the single most "this is a web page someone printed" thing
     * a report can do.
     *
     * Hidden for print, untouched on screen: the tabs are how the reports are reached.
     *
     * .nav is deliberately broad — tabs, pills and the module strips are all built on it, and a
     * printed report has no use for any of them. The report's own content never lives inside a
     * .nav; the panes it switches between are .tab-pane, which is not matched here.
     */
    body:has(.ems-print-head) .nav,
    body:has(.ems-print-head) .nav-tabs,
    body:has(.ems-print-head) .nav-pills,
    body:has(.ems-print-head) .navbar,
    body:has(.ems-print-head) .breadcrumb,
    body:has(.ems-print-head) .page-header:not(.ems-print-head) { display: none !important; }

    /* An inactive tab pane holds another report entirely — the hub keeps them all in the
       document. Only what is on screen may print. */
    body:has(.ems-print-head) .tab-pane:not(.active) { display: none !important; }

    /*
     * ── The letterhead, identical on accounts and billing ───────────────────────────────────
     *
     * ⚠ THE REPORT NAME WAS NEVER ACTUALLY CENTRED. admin_print_template.php styles .eph-title
     * with a size, a margin and letter-spacing under a comment reading "The report's name,
     * centred under the institution" — but sets no text-align, so it inherited left and sat
     * under the address rather than under the institution. Both areas share that template, so
     * fixing it here brings the accounts reports and the billing reports to the same header
     * without touching the approved markup.
     */
    body:has(.ems-print-head) .ems-print-head .eph-title {
        text-align: center;
        width: 100%;
    }

    /* ── The application, as opposed to the report ──────────────────────────────────────────
     *
     * ⚠ THIS IS WHAT WAS PRINTING THE WHOLE WEB PAGE.
     *
     * The rules above take out the tabs, the navbars and the card headers, which is most of the
     * furniture — but not the application shell around it. Measured on the live Bank Activity
     * page: .main-header, .fixed-top and .content-wrapper are all present and none was matched,
     * so Chrome's preview opened with the masthead, the menu strip and the dashboards row above
     * the report, exactly as on screen.
     *
     * The shell IS handled in ems-print.css — but only under a `.ems-print-compact` body class
     * that these report pages never carry, so those rules sat inert. Hidden here instead, under
     * the same hook as everything else, so one scope governs the whole printed document.
     *
     * .fixed-top matters twice over: it is the sticky menu and dashboards container, so left
     * alone it does not merely print, it prints ON TOP of the report on the first page.
     */
    body:has(.ems-print-head) .main-header,
    body:has(.ems-print-head) .fixed-top,
    body:has(.ems-print-head) .main-sidebar,
    body:has(.ems-print-head) .left-side,
    body:has(.ems-print-head) .sidebar,
    body:has(.ems-print-head) .main-footer,
    body:has(.ems-print-head) .btn-to-top,
    body:has(.ems-print-head) .jGrowl,
    /* A drill-down dialog is a click target, not report content, and it sits in the page
       carrying a "Loading…" placeholder until someone opens it. Bootstrap hides it on screen;
       said here too so no report can print it as a section that failed to load. */
    body:has(.ems-print-head) .modal,
    body:has(.ems-print-head) .modal-backdrop { display: none !important; }

    /*
     * The filter form is a control, not a report. What was searched belongs on the paper, and it
     * IS on the paper — the letterhead states the range, the branch and the session as static
     * text — so printing the dropdowns that produced it says the same thing twice, once in a
     * form nobody can use.
     *
     * Scoped to the block that carries the Search and Print buttons rather than to `form`
     * outright: several reports draw their content inside a form so that rows can be selected,
     * and a blanket rule on `form` would take the report with it.
     */
    body:has(.ems-print-head) #print,
    body:has(.ems-print-head) .ems-report-filters,
    body:has(.ems-print-head) .report-search-form,
    /*
     * ⚠ SELECT2 REPLACES THE ELEMENT IT IS ATTACHED TO, so hiding `select` misses it entirely.
     *
     * This is why the "Detailed" and "All Activity" dropdowns kept printing through two rounds
     * of fixes: select2 marks the real <select> `select2-hidden-accessible` — already invisible,
     * so the rule below had nothing to do — and paints its own <span class="select2-container">
     * beside it. That span is what appears on paper. Confirmed in the live DOM rather than
     * guessed: the elements reading "Detailed" are OPTIONs inside a
     * SELECT.form-control.select2-hidden-accessible.
     *
     * Hidden by the widget's own container class, so every select2 on every report goes with it.
     */
    body:has(.ems-print-head) .select2,
    body:has(.ems-print-head) .select2-container,
    body:has(.ems-print-head) .select2-dropdown,
    body:has(.ems-print-head) .picker,
    body:has(.ems-print-head) button:not(table *),
    body:has(.ems-print-head) .btn:not(table *),
    /* ⚠ EVERY select, with no table guard — unlike the rest of this list.
       The "Detailed" and "All Activity" dropdowns kept printing on the activity reports. They
       are injected into the RESULT when a report runs, not present in the page the guarded rule
       was checked against, so whether they sit inside a table was never something this
       stylesheet could rely on. Dropping the guard settles it either way: a <select> is never
       report data, it is a control, and its value is already stated in the letterhead's filter
       block. The guard exists to protect figures in cells, and there are none in a dropdown. */
    body:has(.ems-print-head) select,
    body:has(.ems-print-head) textarea:not(table *),
    body:has(.ems-print-head) input:not(table *),
    body:has(.ems-print-head) label:not(table *) { display: none !important; }

    /*
     * ⚠ `:not(table *)` on every one of those, and it is not defensive habit.
     *
     * Checked on Bank Activity: the seven controls in the report pane are the two date pickers'
     * Today/Clear buttons, Search, Print and Export PDF — all furniture, none of it data. But
     * this stylesheet governs nineteen accounting reports and the fee reports too, and some of
     * those draw a status pill or a drill-down link as a .btn inside a cell, and the voucher
     * search puts a checkbox in every row. A blanket rule would delete report content from the
     * paper and leave a plausible-looking report with a column quietly missing — the worst
     * failure available here, because nothing about the output would look wrong.
     *
     * Nothing inside a table is furniture: the tables ARE the report.
     */

    /* The shell reserves room for a masthead and a sidebar that are no longer there; without
       this the report starts a third of the way down the first sheet. */
    body:has(.ems-print-head) .content-wrapper,
    body:has(.ems-print-head) .page-content,
    body:has(.ems-print-head) .content {
        margin: 0 !important;
        padding: 0 !important;
        min-height: 0 !important;
    }

    /*
     * ── The full printable width ────────────────────────────────────────────────────────────
     *
     * ⚠ THE WHITE BAND DOWN BOTH SIDES IS THE APPLICATION'S LAYOUT, NOT THE PAGE MARGIN.
     *
     * The report sits inside the shell's containers and cards, each contributing padding and in
     * places a max-width meant for a desktop viewport. On paper that reads as a narrow report
     * floating in the middle of the sheet with an inch of nothing either side, and on a wide
     * accounting grid it costs columns.
     *
     * Released rather than overridden with a width: the padding is what creates the band, so
     * removing it lets the table occupy the sheet without anything being forced.
     *
     * ⚠ NO transform: scale() AND NO zoom. Either would make this screenshot look better and
     * then clip columns, invent pages and shrink type unpredictably per browser — and both take
     * the native Scale control out of the user's hands. The layout is corrected instead, so the
     * print dialogue's Scale, Orientation and Margins all keep working.
     */
    body:has(.ems-print-head) .container,
    body:has(.ems-print-head) .container-fluid,
    body:has(.ems-print-head) .card,
    body:has(.ems-print-head) .card-body,
    body:has(.ems-print-head) .tab-content,
    body:has(.ems-print-head) .tab-pane,
    body:has(.ems-print-head) [class^="col-"],
    body:has(.ems-print-head) [class*=" col-"],
    body:has(.ems-print-head) .row {
        max-width: none !important;
        width: auto !important;
        margin-left: 0 !important;
        margin-right: 0 !important;
        padding-left: 0 !important;
        padding-right: 0 !important;
        border: 0 !important;
        box-shadow: none !important;
    }

    /* The report's own tables take the released width. */
    body:has(.ems-print-head) table {
        width: 100% !important;
        max-width: 100% !important;
    }

    /*
     * An empty card is a screen device — a panel that held controls now hidden — and prints as a
     * blank ruled box above the report. Only ones with no table inside them, so a section that
     * legitimately wraps a table is untouched.
     */
    body:has(.ems-print-head) .card:not(:has(table)):not(:has(.ems-print-head)) {
        display: none !important;
    }

    /*
     * ⚠ AND THE ROW THAT HELD THEM. Hiding a control does not reclaim the space its container
     * reserved: the filter row keeps its height, padding and border and prints as an empty ruled
     * band between the letterhead and the first section — which is the blank box left after the
     * select2 widgets went.
     *
     * Same test as the card above: a row with no table in it is screen layout, because on these
     * reports the tables ARE the report. The letterhead is excluded explicitly since it is
     * itself laid out as a row in some templates.
     */
    body:has(.ems-print-head) .tab-pane.active .row:not(:has(table)):not(:has(.ems-print-head)),
    body:has(.ems-print-head) .card-body > .row:not(:has(table)):not(:has(.ems-print-head)) {
        display: none !important;
    }

    /* ── The grid ───────────────────────────────────────────────────────────────────────────
     *
     * ⚠ print-color-adjust is what makes the dark band survive. Browsers drop background
     * colours when printing unless a page asks for them explicitly, which is exactly why a
     * header that is dark on screen comes out white on paper.
     */
    body:has(.ems-print-head) table thead th {
        background: #16255c !important;
        color: #fff !important;
        border-color: #24356e !important;
        -webkit-print-color-adjust: exact !important;
        print-color-adjust: exact !important;
    }

    /* The totals line is what people look for first. */
    body:has(.ems-print-head) table tfoot td,
    body:has(.ems-print-head) table tr.total-row td,
    body:has(.ems-print-head) table td strong {
        font-weight: 700 !important;
        color: #0f1b3d !important;
    }

    /* Group bands — a class row, a month row — read as a break rather than another record. */
    body:has(.ems-print-head) table tbody tr td[colspan] {
        background: #eef1f7 !important;
        font-weight: 700 !important;
        -webkit-print-color-adjust: exact !important;
        print-color-adjust: exact !important;
    }

    /*
     * ⚠ VERTICAL PAGINATION, on every report rather than the one this was proven on.
     *
     * The heading row repeats at the top of each page, so page three carries the same columns
     * as page one; rows are never sliced through the middle; totals follow their figures.
     */
    body:has(.ems-print-head) table thead { display: table-header-group; }
    body:has(.ems-print-head) table tfoot { display: table-footer-group; }
    body:has(.ems-print-head) table tbody { display: table-row-group; }
    body:has(.ems-print-head) table tr { page-break-inside: avoid; break-inside: avoid; }

    /*
     * ⚠ THE WRAPPER CHAIN, released to the printable width.
     *
     * Bootstrap ships `@media print { body { min-width: 992px } .container { min-width: 992px } }`
     * on every admin page. That floor puts the layout in the ≥992px breakpoint where .container
     * is capped at 960px, leaving a band of nothing down the right of a landscape sheet — and in
     * portrait it is wider than the paper, so the right-hand columns fall off it.
     *
     * The admin's own chain adds to that: .page-content is a flex row with the sidebar as a
     * sibling, and .content carries 1.25rem of padding each side.
     */
    body:has(.ems-print-head),
    body:has(.ems-print-head) .container,
    body:has(.ems-print-head) .container-fluid {
        min-width: 0 !important;
        max-width: none !important;
        width: 100% !important;
    }

    body:has(.ems-print-head) .page-content,
    body:has(.ems-print-head) .content-wrapper,
    body:has(.ems-print-head) .content-inner,
    body:has(.ems-print-head) .content {
        display: block !important;
        width: 100% !important;
        max-width: none !important;
        min-width: 0 !important;
        margin: 0 !important;
        padding: 0 !important;
    }

    /* A sidebar that is merely invisible still takes part in a flex row's width negotiation. */
    body:has(.ems-print-head) .sidebar,
    body:has(.ems-print-head) .sidebar-main,
    body:has(.ems-print-head) .sidebar-secondary { display: none !important; }

    /* A .table-responsive clips overflow, which on paper means the right-hand columns simply
       are not drawn. */
    body:has(.ems-print-head) .table-responsive {
        overflow: visible !important;
        width: 100% !important;
        max-width: none !important;
    }

    /* Card chrome is screen furniture; on paper it spends margin and prints as grey boxes. */
    body:has(.ems-print-head) .card,
    body:has(.ems-print-head) .card-body {
        border: 0 !important;
        box-shadow: none !important;
        padding: 4px 0 !important;
    }
}
