/* Print stylesheet — the entire report "generation engine".
 *
 * There is no PDF library in this project and there is not going to be one. A
 * report is html, the browser already paginates html, and `window.print()` is
 * the whole mechanism. What that buys: no dependency to audit on a machine
 * holding treatment records, no change to the Content-Security-Policy in
 * index.html, no network, and a printout that looks like whatever the operating
 * system's print dialog says it looks like. What it costs is this file.
 *
 * TWO RULES FOR ANYONE EDITING IT:
 *
 *   1. EVERYTHING GOES INSIDE @media print, except the one rule that hides
 *      #print-root on screen. print.css must be invisible to the running app —
 *      loading it changes nothing a user sees until they press Ctrl+P.
 *      test/dom/print.contract.test.js fails the build if a rule leaks out.
 *
 *   2. THE PALETTE OVERRIDE MUST NAME THE THEME CLASSES. styles.css declares
 *      every colour token on `body.dark-theme` / `body.light-theme`, so a bare
 *      `body { --text-primary: #111 }` here loses the cascade at equal
 *      specificity minus a class, and a dark-mode user prints white on white.
 *      That is also why index.html loads this file AFTER styles.css: the
 *      override wins on order, and only on order.
 *
 * WHAT THIS FILE CANNOT PROMISE. jsdom has no layout, so the contract test
 * asserts the rules, not the result. Whether the margins suit a Letter sheet,
 * whether a long narrative breaks where it should, and whether page numbers
 * appear at all are print-preview questions for a human in a real browser.
 */

/* The only on-screen rule in this file. #print-root holds a client's clinical
 * narrative between injection and afterprint, so it is hidden rather than
 * merely empty. */
#print-root {
  display: none;
}

@media print {

  @page {
    margin: 0.6in 0.55in;
  }

  /* ------------------------------------------------------------------ */
  /* Palette — ink on paper, whichever theme the screen was showing      */
  /* ------------------------------------------------------------------ */
  /* One palette for both theme classes on purpose: two people printing the
   * same client-week must produce the same document, and which of them had
   * dark mode on is not a property of the record. */
  body,
  body.dark-theme,
  body.light-theme {
    --bg-app: #ffffff;
    --bg-sidebar: #ffffff;
    --bg-card: #ffffff;
    --bg-card-hover: #ffffff;
    --bg-input: #ffffff;
    --bg-overlay: #ffffff;

    --text-primary: #111111;
    --text-secondary: #333333;
    --text-muted: #555555;
    --sidebar-text: #111111;
    --sidebar-text-muted: #555555;

    --border-color: #999999;
    --border-color-light: #cccccc;
    --sidebar-border: #cccccc;

    --color-brand: #1a1a1a;
    --color-brand-hover: #1a1a1a;
    --color-brand-glow: transparent;
    /* The foreground ON a brand fill. Brand is near-black on paper, so this is
     * the one place the answer inverts from the dark theme's near-black. */
    --color-brand-fg: #ffffff;

    /* Status as TEXT. Same three hues as the compliance bands below and at the
     * same ink density — the screen tints are tuned for a dark card and print
     * as pastel mush, exactly as the *-rgb triples do. */
    --text-success: #047857;
    --text-warning: #a64f03;
    --text-danger: #b01037;

    /* The compliance bands are the one piece of colour that carries meaning.
     * Screen values are tuned for a dark background and print as pastel mush;
     * these are the same three hues at ink density. */
    --compliant-rgb: 4, 120, 87;
    --marginal-rgb: 166, 79, 3;
    --non-compliant-rgb: 176, 16, 55;

    /* Glass and shadow are screen affordances. On paper a blur is a grey
     * smear and a shadow is a wasted band of toner. Neutralised at the token
     * so every existing `var(--shadow-md)` in styles.css evaluates to none. */
    --glass-blur: none;
    --glass-border: 1px solid #cccccc;
    --shadow-sm: none;
    --shadow-md: none;
    --shadow-lg: none;
    --shadow-glow: none;

    background: #ffffff;
    color: #111111;
    print-color-adjust: exact;
  }

  /* ------------------------------------------------------------------ */
  /* Unlock the shell                                                    */
  /* ------------------------------------------------------------------ */
  /* styles.css pins `body { height: 100vh; overflow: hidden }` and gives
   * .app-layout a 100vh grid. Left alone, a printout is exactly one screenful
   * and the rest of the report silently does not exist — the failure mode is a
   * report that looks complete and is not. */
  html,
  body {
    overflow: visible !important;
    height: auto !important;
    width: auto !important;
    background: #ffffff !important;
  }

  .app-layout {
    display: none !important;
    overflow: visible !important;
    height: auto !important;
  }

  /* Transient chrome. A modal open behind the print dialog must not paginate
   * itself onto the paper.
   *
   * THE GUIDE BELONGS IN THIS LIST, and not hypothetically. Its panel and its
   * spotlight ring are appended to <body>, OUTSIDE .app-layout — they have to
   * be, so the ring can sit over the app rather than inside the subtree it
   * points at — which means the `.app-layout { display: none }` rule above does
   * not reach them. And the guide ships an answer whose whole purpose is to
   * walk somebody to Print Summary, so "the guide is open at the moment of
   * printing" is the EXPECTED state, not an unlucky one. Without these two
   * selectors a clinical disclosure record prints with a help panel and a
   * highlight ring across it. */
  .modal-backdrop,
  .toast-notification,
  #guide-panel,
  #guide-spotlight {
    display: none !important;
  }

  #print-root {
    display: block !important;
    overflow: visible !important;
    height: auto !important;
    counter-reset: page 1;
  }

  /* ------------------------------------------------------------------ */
  /* Nothing on paper carries a screen effect                            */
  /* ------------------------------------------------------------------ */
  #print-root * {
    box-shadow: none !important;
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
    text-shadow: none !important;
  }

  /* ------------------------------------------------------------------ */
  /* The document                                                        */
  /* ------------------------------------------------------------------ */
  /* ------------------------------------------------------------------ */
  /* BROADSHEET redesign — a newsprint serif on white paper. The system  */
  /* is: one serif family throughout, hairline rules instead of boxes,   */
  /* whitespace for hierarchy. The three compliance hues (green/amber/   */
  /* red) are kept — they carry meaning — and applied to status TEXT via */
  /* the [data-status] hooks below. Source Serif 4 (the design's face)   */
  /* is not bundled; Georgia is the closest system newsprint serif.      */
  /* ------------------------------------------------------------------ */
  .report-document {
    font-family: Georgia, "Times New Roman", "Times", serif;
    font-size: 11.5pt;
    line-height: 1.45;
    color: #201e1d;
  }

  .report-header {
    border-bottom: 2px solid #201e1d;
    padding-bottom: 10pt;
    margin-bottom: 14pt;
  }

  .report-header-facility {
    font-size: 10pt;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: #605d5d;
  }

  .report-header-title {
    font-size: 24pt;
    font-weight: 600;
    letter-spacing: -0.005em;
    margin: 4pt 0 10pt 0;
  }

  .report-header-identity {
    display: grid;
    grid-template-columns: max-content 1fr;
    column-gap: 12pt;
    row-gap: 3pt;
    margin: 0;
    font-size: 11pt;
    color: #444141;
  }

  .report-header-identity dt {
    font-weight: 600;
    color: #605d5d;
  }

  .report-header-identity dd {
    margin: 0;
  }

  .report-header-client {
    font-weight: 700;
  }

  .report-header-week {
    color: #555555;
  }

  /* The 42 CFR §2.32 statement. Boxed, kept whole, and never allowed to be the
   * thing that gets squeezed off the bottom of a page. */
  /* The 42 CFR §2.32 notices — the ONE exception to "no boxes": compliance-
   * mandated, so they stay visually bounded. Enlarged to 11pt so a legal notice
   * is actually readable, and never split across a page. */
  .report-notice {
    border: 1pt solid #201e1d;
    padding: 10pt 12pt;
    margin-bottom: 12pt;
    font-size: 11pt;
    line-height: 1.5;
    break-inside: avoid;
    page-break-inside: avoid;
  }

  .report-notice-title {
    display: block;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-size: 10.5pt;
    margin-bottom: 5pt;
  }

  .report-notice-body {
    margin: 0;
    color: #444141;
  }

  /* The §2.32(b) consent scope. This block IS the "clear explanation of the
   * scope of that consent" the paragraph requires, so it is set as a labelled
   * field list rather than prose — a reader checking one element (who may
   * receive this, for what purpose, until when) finds it by its label. Kept
   * whole with the notice around it; a consent scope split across a page break
   * is an explanation the reader has to reassemble. */
  .report-consent-scope {
    margin-top: 8pt;
    border-top: 0.5pt solid #a09b9b;
    padding-top: 6pt;
    break-inside: avoid;
    page-break-inside: avoid;
  }

  .report-consent-row {
    display: grid;
    grid-template-columns: 1.6in 1fr;
    column-gap: 8pt;
    padding: 1pt 0;
    break-inside: avoid;
    page-break-inside: avoid;
  }

  .report-consent-label {
    font-weight: 600;
    color: #605d5d;
  }

  .report-consent-text {
    white-space: pre-wrap;
  }

  /* A revoked or expired consent on file, on the fallback path. Bold because it
   * is the one line on the page that tells the reader the authority for this
   * disclosure needs checking before the paper leaves the building. */
  .report-consent-warning {
    margin: 6pt 0 0;
    font-weight: 700;
  }

  /* De-boxed: the score is a figure set off by a hairline, not a bordered card. */
  .report-score-panel {
    display: flex;
    align-items: baseline;
    gap: 12pt;
    border-top: 1pt solid #d7d3d3;
    padding: 8pt 0;
    margin-bottom: 14pt;
    break-inside: avoid;
    page-break-inside: avoid;
  }

  /* The facility roster's figures: each is "16 Active residents", wrapping to a
   * second line on a narrow page rather than running into the next one. */
  .report-roster-rollup {
    flex-wrap: wrap;
    gap: 4pt 18pt;
  }

  .report-roster-stat {
    display: flex;
    align-items: baseline;
    gap: 4pt;
  }

  .report-roster-stat-value {
    font-size: 16pt;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
  }

  /* The roster is many residents long: it flows across pages (each resident row
   * still stays whole) instead of jumping to a fresh page and leaving the one
   * before it nearly blank. */
  .report-section-card[data-section="roster"] {
    break-inside: auto;
    page-break-inside: auto;
  }

  .report-score-value {
    font-size: 24pt;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
  }

  .report-score-label {
    font-size: 11.5pt;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
  }

  .report-score-detail {
    font-size: 10pt;
    color: #605d5d;
  }

  .report-narrative-missing {
    font-style: italic;
    color: #605d5d;
    margin-bottom: 8pt;
  }

  /* ------------------------------------------------------------------ */
  /* Sections and rows — the units that must not be cut in half          */
  /* ------------------------------------------------------------------ */
  .report-section-card,
  .report-requirement-row {
    break-inside: avoid;
    page-break-inside: avoid;
  }

  .report-section-card {
    border-top: 1pt solid #d7d3d3;
    padding-top: 8pt;
    margin-bottom: 20pt;
  }

  .report-section-title {
    font-family: Georgia, "Times New Roman", "Times", serif;
    font-size: 13pt;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    margin: 0 0 10pt 0;
    break-after: avoid;
    page-break-after: avoid;
  }

  /* ------------------------------------------------------------------ */
  /* A section the governing consent does not cover (chrome.js)          */
  /* ------------------------------------------------------------------ */
  /* IT KEEPS ITS TITLE. That is the whole point of the block: a section that
   * simply vanished would be indistinguishable on paper from a resident who
   * takes no medication, and a reader would draw a clinical conclusion from an
   * access-control decision. So nothing here dims or shrinks the heading — the
   * only thing that changes is that the body is one italic sentence saying why
   * the contents are not there.
   *
   * Addressed by BOTH the class and the attribute: the class is what chrome.js
   * writes, the attribute is the machine-readable half that tests key on, and a
   * printed page must not depend on which of the two survives a refactor.
   *
   * NO COLOUR THAT DEPENDS ON INK. The note carries meaning, and this page is
   * printed on whatever the facility has — a mono laser, a cartridge three
   * months past its life. So the signal is a hairline box, italics and the
   * words themselves, in the same black as the rest of the document. A grey or
   * amber "omitted" note is one economy-mode print away from being invisible. */
  .report-section-omitted,
  [data-section-omitted="true"] {
    break-inside: avoid;
    page-break-inside: avoid;
  }

  .report-omitted-note {
    margin: 0;
    padding: 6pt 9pt;
    border: 0.5pt solid #605d5d;
    font-style: italic;
    font-size: 10.5pt;
    line-height: 1.45;
    color: #111111;
    break-inside: avoid;
    page-break-inside: avoid;
  }

  /* De-boxed: a requirement block is separated from the next by a top hairline
   * only — no left rule, no shading. (In the Client Summary these blocks lay out
   * two-across via .report-req-grid below; elsewhere they stack full width.) */
  .report-requirement-row {
    border-top: 1pt solid #d7d3d3;
    padding: 8pt 0 0 0;
    margin-bottom: 6pt;
  }

  .report-requirement-head {
    display: flex;
    align-items: baseline;
    gap: 8pt;
    flex-wrap: wrap;
  }

  .report-requirement-name {
    font-weight: 600;
    font-size: 12.5pt;
  }

  .report-requirement-count,
  .report-requirement-percent {
    font-variant-numeric: tabular-nums;
    font-size: 11pt;
    color: #605d5d;
  }

  .report-requirement-uncounted {
    font-size: 10pt;
    font-style: italic;
    color: #605d5d;
  }

  .report-daily-grid {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 3pt;
    margin: 4pt 0;
    max-width: 4.2in;
  }

  /* Day/work cells stay hairline-ruled: they are a data matrix, where the grid
   * itself is the information — not the decorative card chrome "no boxes" bans. */
  .report-day {
    border: 0.75pt solid #bab6b6;
    padding: 2pt;
    text-align: center;
    font-size: 9pt;
  }

  .report-day-label {
    display: block;
    font-weight: 700;
  }

  .report-day-mark {
    display: block;
  }

  .report-job-list {
    margin: 4pt 0 0 14pt;
    padding: 0;
  }

  .report-job {
    margin-bottom: 2pt;
    break-inside: avoid;
    page-break-inside: avoid;
  }

  .report-job span + span::before {
    content: " · ";
    color: #555555;
  }

  .report-op-list {
    margin: 0 0 0 14pt;
    padding: 0;
  }

  .report-op-group {
    break-inside: avoid;
    page-break-inside: avoid;
  }

  .report-op-group span + span::before {
    content: " · ";
    color: #555555;
  }

  /* ------------------------------------------------------------------ */
  /* Fields                                                              */
  /* ------------------------------------------------------------------ */
  .report-field {
    display: grid;
    grid-template-columns: 1.6in 1fr;
    column-gap: 8pt;
    padding: 1pt 0;
    break-inside: avoid;
    page-break-inside: avoid;
  }

  .report-field-label {
    font-weight: 600;
    color: #605d5d;
  }

  .report-field-value {
    white-space: pre-wrap;
  }

  /* An unfilled field is stated, not left blank: a reader must be able to tell
   * "nobody wrote this down" from "the printer dropped a line". */
  .report-empty {
    color: #555555;
    font-style: italic;
  }

  .report-work-grid {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 3pt;
  }

  .report-work-day {
    border: 0.75pt solid #bab6b6;
    padding: 2pt;
    font-size: 9pt;
    text-align: center;
  }

  .report-work-day-label {
    display: block;
    font-weight: 700;
  }

  .report-work-total {
    margin-top: 3pt;
    font-weight: 700;
  }

  /* ------------------------------------------------------------------ */
  /* Footer and page numbering                                           */
  /* ------------------------------------------------------------------ */
  .report-footer {
    border-top: 1pt solid #d7d3d3;
    margin-top: 14pt;
    padding-top: 5pt;
    display: flex;
    justify-content: space-between;
    gap: 10pt;
    font-size: 9pt;
    color: #605d5d;
    break-inside: avoid;
    page-break-inside: avoid;
  }

  /* ------------------------------------------------------------------ */
  /* Client Summary "specimen grid" — tracking requirements two-across   */
  /* ------------------------------------------------------------------ */
  /* Only the Client Summary requirements section wraps its blocks in this
   * grid; every other use of .report-requirement-row (weekly rows carry a
   * 7-day grid and notes, roster client rows, requirement history) stays full
   * width. Each block keeps its own top hairline + break-inside:avoid. */
  .report-req-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0 24pt;
  }

  /* Inside the specimen grid a block reads name → meta LINE (stacked), not a
   * name butted against its target on one run. */
  .report-req-grid .report-requirement-name {
    display: block;
  }

  .report-req-grid .report-requirement-count {
    display: block;
    margin-top: 2pt;
  }

  /* Requirement-history week rows: keep the week, the count and the percent from
   * butting together (these spans were previously unstyled on paper). */
  .report-req-week-label,
  .report-req-week-count {
    margin-right: 12pt;
  }

  /* Roster requirements: name, then count, then a clear gap before the next
   * requirement (these spans were unstyled and ran together on paper). */
  .report-roster-req {
    display: inline-block;
    margin-right: 12pt;
  }

  .report-roster-req[hidden] {
    display: none;
  }

  .report-roster-req-name {
    margin-right: 6pt;
  }

  .report-roster-req-uncounted {
    margin-left: 6pt;
  }

  /* Vehicle cost table: header and body cells take the padding the restock
   * and curfew tables use, so neighbouring headers never touch. */
  .report-vehicle-cost-table th,
  .report-vehicle-cost-table td {
    padding: 4pt 6pt;
  }

  /* ------------------------------------------------------------------ */
  /* Compliance status colour — green / amber / red at ink density       */
  /* ------------------------------------------------------------------ */
  /* The three bands are the one piece of colour on the page, so they are
   * applied to the status TEXT via each report's [data-status] hook. The
   * band tokens are the print-ink values set in the palette block above. */
  .report-trend-row[data-status="compliant"] .report-trend-status,
  .report-score-panel[data-status="compliant"] .report-score-label,
  .report-roster-row[data-status="compliant"] .report-roster-status {
    color: rgb(var(--compliant-rgb));
    font-weight: 600;
  }

  .report-trend-row[data-status="marginal"] .report-trend-status,
  .report-score-panel[data-status="marginal"] .report-score-label,
  .report-roster-row[data-status="marginal"] .report-roster-status {
    color: rgb(var(--marginal-rgb));
    font-weight: 600;
  }

  .report-trend-row[data-status="non-compliant"] .report-trend-status,
  .report-score-panel[data-status="non-compliant"] .report-score-label,
  .report-roster-row[data-status="non-compliant"] .report-roster-status {
    color: rgb(var(--non-compliant-rgb));
    font-weight: 700;
  }

  /* MAR matrix: only the EXCEPTIONS take colour, so they stand out of an
   * otherwise ink grid — a wall of green "taken" cells would carry no signal. */
  .report-mar-cell[data-state="undocumented"] {
    color: rgb(var(--marginal-rgb));
    font-weight: 600;
  }

  .report-mar-cell[data-state="missed"] {
    color: rgb(var(--non-compliant-rgb));
    font-weight: 700;
  }

  /* A documented missed dose and an as-needed dose are one line of parts (the
   * day, the reason or time, who logged it, the note): spaced apart like the
   * job and vehicle lines, or they print run together. */
  /* MAR LAYOUT. render() in medicationAdministration.js emits every part of the
   * record as bare <span>s, so without rules here the parts print run together
   * ("Metformin500mgDaily", "0%0 of 6 scheduled doses given"). Each group below
   * is a flex row that wraps, or a table, so a part cannot collide with the next.
   * The day grid is a 31-column table that has to fit the page: fixed layout,
   * one narrow column per day, and a first column for the dose label. */
  /* The scheduled-medication section holds one block per medication and can run
   * to several pages; each .report-mar-med still stays whole, but the section may
   * break between them instead of jumping to a fresh page and leaving the one
   * before it blank (the roster section does the same). */
  .report-section-card[data-section="scheduled"] {
    break-inside: auto;
    page-break-inside: auto;
  }

  .report-mar-adherence {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 2pt 12pt;
    margin: 0 0 4pt 0;
  }

  .report-mar-adherence-value {
    font-size: 24pt;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
  }

  .report-mar-adherence-detail {
    font-size: 11pt;
  }

  .report-mar-adherence-days {
    font-size: 10pt;
    color: #605d5d;
  }

  .report-mar-caveat,
  .report-mar-prn-caveat {
    margin: 4pt 0 0 0;
    font-size: 10pt;
    line-height: 1.4;
    color: #605d5d;
  }

  .report-mar-summary-line,
  .report-mar-count-summary-line {
    display: block;
    margin: 0 0 6pt 0;
    font-size: 11pt;
  }

  .report-mar-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 2pt 14pt;
    margin: 0 0 10pt 0;
    font-size: 9.5pt;
    color: #333333;
  }

  .report-mar-legend-item {
    display: inline-flex;
    align-items: baseline;
    gap: 3pt;
  }

  .report-mar-legend-mark {
    font-weight: 700;
  }

  .report-mar-med {
    margin: 0 0 14pt 0;
    padding-top: 8pt;
    border-top: 0.75pt solid #d7d3d3;
    break-inside: avoid;
    page-break-inside: avoid;
  }

  .report-mar-med-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 1pt 10pt;
    margin: 0 0 6pt 0;
  }

  .report-mar-med-name {
    font-size: 12.5pt;
    font-weight: 600;
  }

  .report-mar-med-dosage {
    font-size: 11pt;
  }

  .report-mar-med-schedule,
  .report-mar-med-prescriber,
  .report-mar-med-range,
  .report-mar-med-location,
  .report-mar-med-inventory {
    font-size: 10pt;
    color: #605d5d;
  }

  /* The first line is the medication; where it is kept and how much is left each
   * take their own line beneath, so a long locker label does not push the
   * prescriber off the row. */
  .report-mar-med-location,
  .report-mar-med-inventory {
    flex-basis: 100%;
  }

  .report-mar-dose-totals {
    display: flex;
    flex-wrap: wrap;
    gap: 2pt 14pt;
    margin: 0 0 5pt 0;
    font-size: 10pt;
  }

  .report-mar-dose {
    display: inline-flex;
    align-items: baseline;
    gap: 4pt;
  }

  .report-mar-dose-label {
    font-weight: 600;
  }

  .report-mar-grid-scroll {
    overflow: visible;
    margin: 0 0 6pt 0;
  }

  .report-mar-grid {
    width: 100%;
    table-layout: fixed;
    border-collapse: collapse;
    font-size: 7.5pt;
    font-variant-numeric: tabular-nums;
  }

  .report-mar-grid th,
  .report-mar-grid td {
    border: 0.5pt solid #bab6b6;
    padding: 1.5pt 0;
    text-align: center;
    overflow: hidden;
  }

  .report-mar-grid th.report-mar-rowlabel {
    width: 0.9in;
    padding: 1.5pt 3pt;
    text-align: left;
    font-size: 8pt;
    font-weight: 600;
    overflow-wrap: anywhere;
  }

  .report-mar-daynum-n,
  .report-mar-daynum-dow {
    display: block;
  }

  .report-mar-daynum-n {
    font-weight: 700;
  }

  .report-mar-daynum-dow {
    font-size: 6.5pt;
    font-weight: 400;
    color: #605d5d;
  }

  .report-mar-missed,
  .report-mar-notes,
  .report-mar-prn-list,
  .report-mar-count-list {
    list-style: none;
    margin: 4pt 0 0 0;
    padding: 0;
  }

  .report-mar-missed-row,
  .report-mar-note,
  .report-mar-prn,
  .report-mar-count {
    margin: 0 0 2pt 0;
    font-size: 10pt;
    line-height: 1.35;
    break-inside: avoid;
    page-break-inside: avoid;
  }

  .report-mar-missed-none {
    margin: 4pt 0 0 0;
    font-size: 10pt;
    color: #605d5d;
  }

  .report-mar-missed-when,
  .report-mar-note-when,
  .report-mar-prn-when,
  .report-mar-count-when {
    font-weight: 600;
  }

  .report-mar-note span + span::before {
    content: " · ";
    color: #555555;
  }

  /* A pill count is one line of parts; they wrap as a group rather than butting
   * together, and the verdict (short or over) is the only part that is bold. */
  .report-mar-count {
    display: flex;
    flex-wrap: wrap;
    gap: 1pt 10pt;
    padding: 3pt 0;
    border-top: 0.5pt solid #e5e2e2;
  }

  .report-mar-count-med {
    font-weight: 600;
  }

  .report-mar-count-discrepancy {
    font-weight: 700;
  }

  .report-mar-count-discrepancy:empty {
    display: none;
  }

  .report-mar-missed-row span + span::before,
  .report-mar-prn span + span::before {
    content: " · ";
    color: #555555;
  }

  /* ------------------------------------------------------------------ */
  /* Tables (compliance trend, accounting) — serif header, hairline rows */
  /* ------------------------------------------------------------------ */
  /* Plain rows: serif upper-case header bottom-ruled at neutral-400, body
   * rows ruled at neutral-200. No zebra, no cell fills. */
  .report-trend-table,
  .report-accounting-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 11pt;
    margin-top: 4pt;
  }

  .report-trend-table th,
  .report-accounting-table th {
    text-align: left;
    font-family: Georgia, "Times New Roman", "Times", serif;
    font-weight: 600;
    text-transform: uppercase;
    font-size: 9.5pt;
    letter-spacing: 0.05em;
    color: #605d5d;
    border-bottom: 1pt solid #bab6b6;
    padding: 5pt 8pt 6pt 0;
  }

  .report-trend-table td,
  .report-accounting-table td {
    padding: 5pt 8pt 5pt 0;
    border-bottom: 1pt solid #eae7e7;
    vertical-align: top;
  }

  .report-trend-score {
    font-variant-numeric: tabular-nums;
  }

  .report-accounting-when {
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
  }

  /* The accounting integrity line + scope note (previously unstyled on paper). */
  .report-accounting-integrity {
    font-size: 10.5pt;
    color: #605d5d;
    margin: 0 0 8pt 0;
  }

  .report-accounting-integrity[data-chain-ok="false"] {
    color: rgb(var(--non-compliant-rgb));
    font-weight: 700;
  }

  .report-accounting-scope-note {
    font-size: 10pt;
    color: #605d5d;
    font-style: italic;
    margin: 0 0 10pt 0;
  }

  .report-accounting-empty {
    font-style: italic;
    color: #605d5d;
  }

  /* ------------------------------------------------------------------ */
  /* The two documents that are not a disclosure (phase 2 §2i)           */
  /* ------------------------------------------------------------------ */
  /* chrome.js prints three documents. `phi` is the one every rule above  */
  /* was written for and it carries NO data-report-mode at all, so        */
  /* nothing in this section can reach it. The other two drop the §2.32   */
  /* notices, which leaves a visual gap the reader would otherwise have   */
  /* to interpret — these rules say what the page is instead.             */

  /* The patient's own copy. Set as a rule under the header rather than   */
  /* as a box: a boxed notice on this page would read as the compliance   */
  /* block that was deliberately removed, which is the one thing it must  */
  /* not be mistaken for. Kept with the header it belongs to.             */
  .report-copy-line {
    font-size: 10.5pt;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: #201e1d;
    border-bottom: 1pt solid #201e1d;
    padding-bottom: 6pt;
    margin: 0 0 14pt 0;
    break-inside: avoid;
    page-break-inside: avoid;
  }

  /* A facility-scoped page has no patient, so the header's identity list  */
  /* is two rows rather than three and the heavy rule under it is more    */
  /* weight than it now carries.                                          */
  [data-report-mode="no-phi"] .report-header {
    border-bottom-width: 1pt;
  }

  /* Neither document is a release, and neither should look like a form   */
  /* that is missing its notice: the footer line stays (it is house-      */
  /* keeping, not a legal statement) and is set quieter than on a         */
  /* disclosure, where it sits under two boxed notices and needs weight.  */
  [data-report-mode="patient-copy"] .report-footer,
  [data-report-mode="no-phi"] .report-footer {
    font-size: 9pt;
    color: #605d5d;
  }

  /* ------------------------------------------------------------------ */
  /* A captured signature (src/js/strokesToSvg.js)                       */
  /* ------------------------------------------------------------------ */
  /* The svg carries its own viewBox and `vector-effect`, so the only    */
  /* thing paper has to decide is how big the box is. Sized in mm        */
  /* because this is a physical signature line, and `height: auto` would */
  /* let a tall pad push a table onto a second page.                     */
  .report-signature {
    display: block;
    width: 52mm;
    height: 16mm;
    color: #201e1d;
    break-inside: avoid;
    page-break-inside: avoid;
  }

  /* Belt and braces with the presentation attributes the renderer emits: */
  /* a stylesheet rule beats an attribute, so if anything above ever sets */
  /* a fill on svg children, a signature would flood as a filled blob.    */
  .report-signature path {
    fill: none;
    stroke: currentColor;
  }

  /* ------------------------------------------------------------------ */
  /* Rent statement and receipt (phase 7 step 7a)                        */
  /* ------------------------------------------------------------------ */
  /* Money in tabular figures, right-aligned, so a column of balances    */
  /* lines up. A ledger can run past a page, so its card may break       */
  /* between rows; a row never splits.                                   */
  .report-rent-balances {
    margin: 0;
  }

  .report-rent-balances > div {
    display: flex;
    justify-content: space-between;
    gap: 12pt;
    padding: 4pt 0;
    border-bottom: 1pt solid #eae7e7;
  }

  .report-rent-balances dd {
    margin: 0;
    font-variant-numeric: tabular-nums;
  }

  .report-rent-ledger {
    width: 100%;
    border-collapse: collapse;
    font-size: 10.5pt;
    margin-top: 4pt;
  }

  .report-rent-ledger th {
    text-align: left;
    font-weight: 600;
    text-transform: uppercase;
    font-size: 9pt;
    letter-spacing: 0.05em;
    color: #605d5d;
    border-bottom: 1pt solid #bab6b6;
    padding: 4pt 8pt 5pt 0;
  }

  .report-rent-ledger td {
    padding: 4pt 8pt 4pt 0;
    border-bottom: 1pt solid #eae7e7;
    vertical-align: top;
  }

  .report-rent-ledger tr {
    break-inside: avoid;
    page-break-inside: avoid;
  }

  .report-nowrap {
    white-space: nowrap;
  }

  .report-rent-ledger .report-num {
    text-align: right;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
  }

  .report-section-card[data-section="rent-ledger"] {
    break-inside: auto;
    page-break-inside: auto;
  }

  .report-muted {
    color: #605d5d;
  }

  .report-receipt-flag {
    font-size: 11pt;
    margin: 0 0 8pt 0;
  }

  /* A promissory note (step 7c): the text keeps the line breaks the      */
  /* resident read, and can run past a page; the digests are long hex.   */
  .report-note-text {
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    font-size: 10.5pt;
    line-height: 1.5;
    margin: 4pt 0 8pt 0;
  }

  .report-section-card[data-section="rent-note-text"] {
    break-inside: auto;
    page-break-inside: auto;
  }

  .report-note-signature {
    margin: 8pt 0;
    border-bottom: 1pt solid #201e1d;
    width: 52mm;
  }

  .report-note-digests dd {
    font-size: 8.5pt;
    overflow-wrap: anywhere;
  }

  /* The restock sheet (phase 6 step 7): one row per item, the figures     */
  /* right-aligned so a column of numbers reads down.                     */
  .report-restock-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 11pt;
  }

  .report-restock-table th,
  .report-restock-table td {
    border-bottom: 0.5pt solid #bdb8b5;
    padding: 4pt 6pt;
    text-align: left;
  }

  .report-restock-table td:not(:first-child),
  .report-restock-table th:not(:first-child) {
    text-align: right;
  }

  .report-restock-note {
    font-size: 9.5pt;
    margin: 6pt 0 0 0;
  }

  /* The setup summary (setup wizard W2): one row per step, figures right. */
  .report-setup-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 11pt;
  }

  .report-setup-table th,
  .report-setup-table td {
    border-bottom: 0.5pt solid #bdb8b5;
    padding: 4pt 6pt;
    text-align: left;
  }

  .report-setup-table td:not(:first-child),
  .report-setup-table th:not(:first-child) {
    text-align: right;
  }

  .report-setup-note {
    font-size: 9.5pt;
    margin: 6pt 0 0 0;
  }

  /* The curfew report (phase 8 §7): one row per missed or excused night.  */
  .report-curfew-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 10.5pt;
  }

  .report-curfew-table th,
  .report-curfew-table td {
    border-bottom: 0.5pt solid #bdb8b5;
    padding: 4pt 6pt;
    text-align: left;
    vertical-align: top;
  }

  .report-curfew-summary {
    font-size: 10.5pt;
    margin: 6pt 0;
  }

  .report-state-title {
    font-size: 11pt;
    margin: 6pt 0 0;
  }

  /* ------------------------------------------------------------------ */
  /* Behavioural contract and discipline history (phase 13 phase 6)      */
  /* ------------------------------------------------------------------ */
  /* The contract is one page with room for two signature lines at the    */
  /* foot; the history is a list of write-ups that may run onto more.     */
  .report-contract-facts {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 12pt;
    margin: 0 0 10pt 0;
  }

  .report-contract-fact {
    display: flex;
    flex-direction: column;
    gap: 2pt;
  }

  .report-contract-label {
    font-size: 8.5pt;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: #605d5d;
  }

  .report-contract-lines {
    margin: 0;
    padding-left: 18pt;
    display: flex;
    flex-direction: column;
    gap: 5pt;
    line-height: 1.45;
  }

  .report-contract-rules {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 12pt;
    line-height: 1.4;
  }

  .report-contract-understanding {
    margin: 0;
    line-height: 1.45;
  }

  .report-section-card[data-section="contract-signatures"] {
    break-inside: avoid;
    page-break-inside: avoid;
  }

  .report-contract-signs {
    display: flex;
    gap: 24pt;
    margin-top: 6pt;
  }

  .report-contract-sign {
    flex: 1 1 0;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 3pt;
  }

  .report-contract-sign-line {
    display: flex;
    align-items: flex-end;
    height: 18mm;
    border-bottom: 1pt solid #201e1d;
  }

  .report-contract-sign-caption {
    font-size: 9.5pt;
    color: #605d5d;
  }

  .report-section-card[data-section="history-incidents"],
  .report-section-card[data-section="history-contracts"] {
    break-inside: auto;
    page-break-inside: auto;
  }

  .report-history-item {
    padding: 6pt 0;
    border-bottom: 1pt solid #eae7e7;
    break-inside: avoid;
    page-break-inside: avoid;
  }

  .report-history-head {
    display: flex;
    flex-wrap: wrap;
    gap: 4pt 12pt;
    margin-bottom: 3pt;
  }

  .report-history-when {
    font-weight: 600;
    white-space: nowrap;
  }

  .report-history-category,
  .report-history-outcome,
  .report-history-status {
    color: #605d5d;
  }

  .report-history-line {
    margin: 2pt 0;
    font-size: 10.5pt;
    line-height: 1.45;
    overflow-wrap: anywhere;
  }

  /* A receipt is one short page: narrower margins, printed on its own. */
  @page receipt {
    margin: 0.5in;
  }

  [data-report="rent-receipt"] {
    page: receipt;
  }

  /* The page-number hook the report chrome emits, filled from the CSS page
   * counter rather than from JavaScript — only the paginating engine knows how
   * many pages there are, and it does not tell the DOM.
   *
   * HONESTY NOTE: Chromium (and therefore Electron) does not currently
   * implement `counter(page)` outside @page margin boxes, which it also does
   * not implement. On this host the span stays empty and the operating
   * system's own print dialog supplies headers and footers. The declaration is
   * kept because it is correct CSS, it costs nothing, and it is what makes the
   * hook meaningful on any engine that does honour Paged Media. */
  [data-page-number]::after {
    content: counter(page);
  }
}
