/* SpaceCamp print styles.
 *
 * Everything here is inside one @media print block, and nothing in it affects
 * the screen — which is the whole reason it is its own file rather than a
 * section of app.css: a screen rule that lands in here does nothing, and a
 * print rule that lands in app.css is invisible until someone prints.
 *
 * It is loaded after sc-tokens.css and app.css (see assets/app.js), so where a
 * rule below matches an existing one at equal specificity, the later one wins.
 * The selectors that have to beat a [data-bs-theme="dark"] rule carry an `html`
 * prefix so they do not depend on that ordering.
 *
 * Written for the two reports in this app people actually print:
 * /report/job-finances, a copy of which is filed at month end because the
 * figures keep moving afterwards, and /report/expenses, which is checked off
 * line by line against Reckon. The chrome-off and force-light sections apply
 * everywhere; the table layout is scoped to `.sc-print-report`, and the column
 * widths, which differ per report, to a second class beside it
 * (`.sc-print-expenses`).
 */

@media print {

    /* ─── The A4 page itself ─────────────────────────────────────────────── */
    /*
     * Portrait, not landscape: the report is a long list of jobs, and portrait
     * fits about half again as many rows per sheet. The name column takes the
     * slack instead (see `table-layout: fixed` below).
     */
    @page {
        size: A4 portrait;
        margin: 12mm 10mm;
    }

    /*
     * A print media query is evaluated against the *page* box, and A4 portrait
     * inside those margins is ~718 CSS px — under Bootstrap's 767.98px `md`
     * breakpoint. So every `@media (max-width: 767.98px)` rule in app.css fires
     * when printing, and one of them is what broke this page: it restores
     * `overflow-x: auto` on `.table-responsive.sticky-head`, making the wrapper
     * a scroll container, so everything past ~718px was simply cut off the
     * sheet. Anything below that fights a mobile rule is fighting that.
     */

    /* ─── The app's voice stays on screen ────────────────────────────────── */
    /*
     * A subheading or a moment is company for the person at the desk, not part
     * of a record anyone files. See "Voice" in CLAUDE.md.
     */
    .sc-voice,
    .sc-moment {
        display: none !important;
    }

    /* ─── Force the light palette ────────────────────────────────────────── */
    /*
     * The theme is whatever the user last chose in localStorage, so a dark-mode
     * user prints near-white text — and backgrounds are dropped by the print
     * dialogue's default settings, so the page comes out blank. Every dark rule
     * in app.css paints from a --bs-* variable, so flipping the variables here
     * converts the lot; only the hard-coded hexes below need naming.
     */
    html[data-bs-theme="dark"] {
        color-scheme: light;
        --bs-body-bg: #fff;
        --bs-body-color: #000;
        --bs-emphasis-color: #000;
        --bs-secondary-color: #555;
        --bs-secondary-bg: transparent;
        --bs-tertiary-bg: transparent;
        --bs-border-color: #999;
        --bs-border-subtle: #ddd;
        --bs-table-color: #000;
        --bs-table-bg: transparent;
        --bs-link-color: #000;
        --bs-code-color: #000;
    }

    html, body {
        background: #fff !important;
        color: #000 !important;
    }

    /* The four finance colours are literal hexes with a dark-mode pair, and the
       dark pair is pale on paper. `html[data-bs-theme]` outruns
       `[data-bs-theme="dark"]` whichever order the sheets load in. */
    html[data-bs-theme] .fin-inc-tbc { color: #8f8a4d !important; }
    html[data-bs-theme] .fin-exp-tbc { color: #7a1f1f !important; }
    html[data-bs-theme] .fin-income  { color: #2f7d32 !important; }
    html[data-bs-theme] .fin-expense { color: #d32f2f !important; }

    /* ─── Chrome off ─────────────────────────────────────────────────────── */
    /* `.d-print-none` is Bootstrap's and covers the page's own controls; the
       navbar is on every page and is nobody's idea of evidence. */
    nav.navbar {
        display: none !important;
    }

    /* The page container is a screen constraint — on paper the margin box is
       already the margin. `padding: 0` also drops base.html.twig's `pb-5`. */
    body > .container,
    body > .container-fluid {
        max-width: none !important;
        width: auto !important;
        padding: 0 !important;
    }

    /* ─── A printed report's heading ─────────────────────────────────────── */
    .sc-print-report h1 {
        font-size: 14pt !important;
        margin: 0;
    }

    .sc-print-report .page-header-toolbar {
        display: block;
        margin: 0 0 6pt !important;
    }

    /* When and by whom this copy was taken. The point of printing the report is
       to have the month's figures as they stood, so a copy that does not say
       when it was taken is not evidence of anything. */
    .sc-print-provenance {
        font-size: 7.5pt;
        color: #555;
        margin-top: 1pt;
    }

    /* ─── The report table ───────────────────────────────────────────────── */
    /* The card is a screen surface; on paper the table is the document. */
    .sc-print-report .card,
    .sc-print-report .card:has(.table-data),
    .sc-print-report .card-body {
        border: 0 !important;
        border-radius: 0 !important;
        box-shadow: none !important;
        padding: 0 !important;
        background: transparent !important;
    }

    /* See the breakpoint note above: this is the rule that makes the table fit
       the sheet rather than being clipped at the wrapper's width. */
    .sc-print-report .table-responsive,
    .sc-print-report .table-responsive.sticky-head {
        overflow: visible !important;
    }

    /*
     * `table-layout: fixed` is what stops the six columns being sized by their
     * content: the money columns get a fixed share and a long job name wraps
     * into what is left, rather than shouldering the figures off the sheet.
     *
     * 13.5% of the 190mm text block is 25.6mm, which at 8pt holds the widest
     * figure this report can print — a YTD grand total run negative,
     * -$12,345,678.90, about 22mm plus the cell padding. `nowrap` is what makes
     * that the constraint: the alternative failure is a total breaking after
     * "$1,810,699.5", which is not a number anyone should have to reassemble.
     * Right-aligned, an overflowing figure spills left into the neighbouring
     * column's padding and stays whole and legible.
     */
    .sc-print-report .table-data {
        table-layout: fixed;
        width: 100% !important;
        font-size: 8pt;
        line-height: 1.25;    /* Bootstrap's 1.5 costs a row every ten */
        font-variant-numeric: tabular-nums;
    }

    /* The job-finances shape. /report/expenses restates all seven of its own
       further down — see the note there. */
    .sc-print-report .table-data thead th:nth-child(1) { width: 9%; }
    .sc-print-report .table-data thead th:nth-child(2) { width: 37%; }
    .sc-print-report .table-data thead th:nth-child(n+3) { width: 13.5%; }

    /*
     * The finance "compared with" view adds a seventh column, Net change, so
     * the widths are restated for it (the six above would come to 113.5%).
     * The change figures print in black: the arrow already carries the
     * direction, and a coloured figure is a grey one on most office printers.
     */
    .sc-print-report.sc-print-fin-changes .table-data thead th:nth-child(1) { width: 9%; }
    .sc-print-report.sc-print-fin-changes .table-data thead th:nth-child(2) { width: 31%; }
    .sc-print-report.sc-print-fin-changes .table-data thead th:nth-child(n+3) { width: 12%; }

    .sc-print-report .sc-fin-delta,
    .sc-print-report .sc-fin-chip {
        color: #000 !important;
    }

    .sc-print-report .sc-fin-chip {
        border-color: #000 !important;
        font-size: 6.5pt;
    }

    .sc-print-report .table-data tr.sc-fin-changed > td:first-child {
        box-shadow: inset 1.5pt 0 0 #000;
    }

    .sc-print-report .sc-fin-changes .stat-card {
        border: 0.5pt solid #999 !important;
        background: transparent !important;
    }

    .sc-print-report .sc-fin-changes {
        break-inside: avoid;
        margin-bottom: 6mm !important;
    }

    .sc-print-report .sc-fin-changes .stat-number.sc-fin-stat {
        font-size: 12pt;
    }

    /* A4 is under Bootstrap's md breakpoint, so the panel's columns would
       stack one per line and push the table onto page two. */
    .sc-print-report .sc-fin-changes .stat-row-4 > [class*="col-"] {
        flex: 0 0 25%;
        max-width: 25%;
    }

    .sc-print-report .sc-fin-changes .row.g-4 > [class*="col-"] {
        flex: 0 0 50%;
        max-width: 50%;
    }

    .sc-print-report .sc-fin-changes .stat-card .card-body {
        padding: 3pt 5pt;
    }

    .sc-print-report .sc-fin-movers li {
        font-size: 8pt;
        padding: 1pt 0;
    }

    .sc-print-report .table-data tbody td.text-end,
    .sc-print-report .table-data tfoot td.text-end {
        white-space: nowrap;
    }

    /* A sticky header does not repeat on the next sheet — a table header group
       does, so every page carries its column headings. */
    .sc-print-report .table-data thead {
        display: table-header-group;
    }

    html .sc-print-report .table-responsive.sticky-head thead th,
    html .sc-print-report .table-data thead th {
        position: static !important;
        background: transparent !important;
        color: #000;
        font-size: 7pt;
        white-space: normal;      /* nowrap headings would outgrow the widths above */
        padding: 2pt 4pt;
        border-bottom: 0.75pt solid #000 !important;
    }

    /*
     * `tfoot` repeats on every printed page by default, which for a five-row
     * grand-total-and-target block is both wrong and a waste of a third of each
     * sheet. As a row group it flows once, at the end, where it belongs.
     */
    .sc-print-report .table-data tfoot {
        display: table-row-group;
        break-inside: avoid;
    }

    html .sc-print-report .table-data tbody td {
        padding: 1.5pt 4pt;
        border-color: #e0e0e0 !important;
        background: transparent !important;
    }

    /*
     * No background fills anywhere on this page. Chrome and Safari drop
     * background colours unless the user ticks "Background graphics", so a
     * table whose structure is carried by grey bands loses its structure for
     * most people; rules and weight are how a printed ledger has always done
     * it, and they come out the same on every printer.
     */
    /* `fs-5` and `py-2` are Bootstrap utilities on this cell, so both of the
       declarations they collide with have to be !important to land. */
    html .sc-print-report .table-data .row-group-header > td {
        background: transparent !important;
        color: #000;
        font-size: 8pt !important;
        padding: 5pt 4pt 1.5pt !important;
        border-top: 0.75pt solid #000 !important;
        border-bottom: 0.25pt solid #bbb;
    }

    html .sc-print-report .table-data .row-subtotal > td {
        background: transparent !important;
        border-top: 0.25pt solid #999 !important;
    }

    html .sc-print-report .table-data tfoot.table-totals td {
        background: transparent !important;
        color: #000;
        padding: 2pt 4pt;
        border-top: 0.75pt solid #000 !important;
    }

    /* ─── Where the page may break ───────────────────────────────────────── */
    .sc-print-report .table-data tr {
        break-inside: avoid;
    }

    /* A client's name alone at the foot of a sheet, or its sub-total alone at
       the head of the next one, both read as a missing group. */
    .sc-print-report .table-data .row-group-header {
        break-after: avoid;
    }

    .sc-print-report .table-data .row-subtotal {
        break-before: avoid;
    }

    /* ─── Ink-saving details ─────────────────────────────────────────────── */
    /*
     * Links are navigation; on paper a job name is just a job name, and blue
     * ink for something nobody can click is waste. app.css paints every link in
     * a table cell `#0d6efd !important` (and a dark-theme pair on top of that)
     * from `.table td a:not([class*="btn"])`, so this has to out-specify a
     * selector that already carries !important — hence the full shape.
     */
    html[data-bs-theme] .sc-print-report .table-data td a:not([class*="btn"]),
    html[data-bs-theme] .sc-print-report .table-data th a:not([class*="btn"]) {
        color: inherit !important;
        text-decoration: none !important;
    }

    .sc-print-report .table-data code {
        color: inherit !important;
        font-size: inherit;
    }

    /*
     * The Global Target cell is rendered by `inline_edit_controller`, which puts
     * a "✏ Edit" affordance in it when no target has been set. Printed, that
     * reads as a broken cell rather than as an unset figure, so it becomes the
     * dash this report already uses for "nothing here".
     */
    .sc-print-report .inline-edit-placeholder {
        display: none !important;
    }

    .sc-print-report .inline-edit-cell:has(.inline-edit-placeholder)::after {
        content: "-";
    }

    .sc-print-report .inline-edit-display {
        padding: 0;
    }

    /* ─── The expense reconciliation report (/report/expenses) ───────────── */
    /*
     * Seven columns rather than the finance report's six, so every width above
     * has to be restated: `nth-child(n+3)` at 13.5% would otherwise put this
     * table at 113.5% of the sheet. Scoped to `.sc-print-expenses`, which the
     * page sets alongside `.sc-print-report`.
     *
     * A copy is still printed and filed — that is the whole history of this
     * report — so the tick column prints as a real box: empty where a line has
     * not been found in Reckon yet, ticked where it has. Which means a paper
     * copy can be worked on exactly as the old PDF was, and starts out already
     * showing whatever has been ticked on screen.
     */
    .sc-print-report.sc-print-expenses .table-data thead th:nth-child(1) { width: 5%; }
    .sc-print-report.sc-print-expenses .table-data thead th:nth-child(2) { width: 10%; }
    .sc-print-report.sc-print-expenses .table-data thead th:nth-child(3) { width: 11%; }
    .sc-print-report.sc-print-expenses .table-data thead th:nth-child(4) { width: 12%; }
    .sc-print-report.sc-print-expenses .table-data thead th:nth-child(5) { width: 15%; }
    .sc-print-report.sc-print-expenses .table-data thead th:nth-child(6) { width: 34%; }
    .sc-print-report.sc-print-expenses .table-data thead th:nth-child(7) { width: 13%; }

    /*
     * The description cell carries a screen font size in `rem`, which is
     * *smaller* than the body on screen (0.85rem against 1rem) and bigger than
     * this table on paper: 0.85rem is 13.6px is ~10.2pt against the 8pt every
     * other cell prints at. So the description printed a quarter larger than
     * every figure beside it — and its `min-width: 16rem` is 256px, which is
     * ~36% of the 718px sheet against the 34% the column is dealt, so the
     * cell pushed its column wider and the width came out of PO # and
     * Invoice #, which then wrapped `13000-001` onto two lines.
     *
     * `inherit` is deliberate rather than a restated 8pt: whatever this table
     * prints at, the description prints at the same. The two widths go for the
     * same reason — a min-width in `rem` has no business in a table whose
     * columns are dealt out as percentages of the sheet.
     */
    .sc-print-report .sc-recon-desc {
        font-size: inherit;
        min-width: 0;
        max-width: none;
    }

    /*
     * The date is a fixed eleven characters and reads as one thing, so it is
     * held on one line. PO and invoice numbers deliberately are *not*: the
     * column holds the common `12046-100` shape comfortably, but production
     * carries PO numbers up to 25 characters and invoice numbers up to 53,
     * with 7% of them over 14 — `invoice_number` is free text and finance do
     * put several numbers in one. Held on one line, those would run straight
     * through the Supplier column; allowed to wrap they break at a hyphen or a
     * slash, which is where they read as breaking anyway.
     */
    .sc-print-report.sc-print-expenses .table-data tbody td:nth-child(2) {
        white-space: nowrap;
    }

    /* An unticked line's date caption is empty, and on paper nothing is being
       clicked, so the line it reserves on screen (which is what stops the
       column jogging as boxes are ticked) is a wasted row-height on every
       line of the report. */
    .sc-print-report .sc-recon-meta:empty {
        display: none;
    }

    /* A checkbox input is not reliably printed at all (and its tick is a
       background in some browsers), so it is replaced by a drawn box —
       borders and a text glyph, which come out the same on every printer and
       need no "Background graphics". */
    .sc-print-report .sc-recon-box {
        display: none !important;
    }

    .sc-print-report .sc-recon-cell::before {
        content: "";
        display: inline-block;
        box-sizing: border-box;
        width: 8pt;
        height: 8pt;
        line-height: 7pt;
        text-align: center;
        font-size: 7pt;
        border: 0.75pt solid #000;
    }

    html .sc-print-report .table-data tr.is-reconciled .sc-recon-cell::before {
        content: "\2713";
    }

    /* No fills on paper (see above), so a checked row is carried by the ticked
       box alone; the screen tint would either vanish or print as a grey band
       over half the sheet. The muting goes too — printed, everything on the
       page is equally worth reading. */
    html .sc-print-report .table-data tr.is-reconciled > td {
        background: transparent !important;
        color: #000;
        box-shadow: none !important;
    }

    html .sc-print-report .table-data .row-job-header > td {
        background: transparent !important;
        color: #000;
        padding: 3pt 4pt 1.5pt !important;
        border-top: 0.25pt solid #999 !important;
    }

    html .sc-print-report .table-data .row-job-total > td {
        background: transparent !important;
        color: #000;
        font-size: 7.5pt;
        padding: 0 4pt 2pt !important;
        border-top: 0 !important;
    }

    /* How far through the month the checking has got is worth having on a filed
       copy; the bar itself is a background fill, which is not. */
    .sc-print-report .sc-recon-bar {
        display: none !important;
    }

    .sc-print-report .sc-recon-progress-label {
        font-size: 7.5pt;
        margin: 0;
    }

    .sc-print-report .sc-recon-meta {
        font-size: 6pt;
        color: #555;
        min-height: 0;
    }

    /* A job's lines belong with the job's heading, and its total with its
       lines — the same reason the client group header and sub-total above
       avoid a break. */
    .sc-print-report .table-data .row-job-header {
        break-after: avoid;
    }

    .sc-print-report .table-data .row-job-total {
        break-before: avoid;
    }

    /* ── The job Project page (job/project.html.twig) ── */

    /* The picture *is* the fills: force them, since Chrome and Safari drop
       backgrounds unless the reader ticks "Background graphics". */
    .sc-print-project .sc-proj-bar,
    .sc-print-project .sc-proj-fill,
    .sc-print-project .sc-proj-track,
    .sc-print-project .sc-proj-today-tag,
    .sc-print-project .sc-proj-legend i {
        -webkit-print-color-adjust: exact;
        print-color-adjust: exact;
    }

    .sc-print-project .sc-proj-gantt {
        --proj-label-w: 150px;
        --proj-row-h: 26px;
        font-size: 8.5pt;
    }

    /* The meters, the timeline and each bar section stay whole on a sheet. */
    .sc-print-project #project-headline,
    .sc-print-project #project-timeline,
    .sc-print-project #project-hours,
    .sc-print-project #project-budget {
        break-inside: avoid;
    }

    .sc-print-project .sc-proj-row-caption { font-size: 8.5pt; }
    .sc-print-project .sc-proj-verdict { font-size: 10pt; }
    .sc-print-project .sc-proj-bar:hover { background: inherit; }
}
