/* 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;
  }

  .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;
  }

  /* 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;
  }

  /* ------------------------------------------------------------------ */
  /* 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;
  }

  /* ------------------------------------------------------------------ */
  /* 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 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);
  }
}
