@media print {
    /* Global
  /* ------------------------------------------------------------------------ */

    :root {
        --color-ink: black;
        --color-canvas: white;
        --border-dark: 1px solid var(--color-ink);
        --border-light: 1px solid color-mix(in oklch, var(--color-ink), transparent 75%);
        --font-sans: "Adwaita Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Hiragino Sans GB", "Hiragino Sans", "Apple SD Gothic Neo", "Microsoft YaHei", "Meiryo", "Malgun Gothic";
    }

    @page {
        margin: 0.5in;
    }

    /* Keep every colour on paper (status, avatars, thermograms) — the */
    /* browser's "Background graphics" toggle otherwise strips them.  */
    html {
        font-size: 10pt;
        -webkit-print-color-adjust: exact;
        print-color-adjust: exact;
    }

    a {
        color: inherit;
        text-decoration: none;
    }

    /* Controls never print (Basecamp pattern); `print--show` opts back in. */
    /* The datasheet's check label is a <button> — it's content, keep it. */
    button:not(.datasheet__link, .print--show),
    .btn:not(.print--show),
    .btn--subtle:not(.print--show),
    input:not([type="checkbox"], [type="radio"], .print--show),
    select:not(.print--show),
    textarea:not(.print--show) {
        display: none !important;
    }

    main {
        inline-size: unset;
        margin: 0;
        orphans: 3;
        padding: 0;
        widows: 2;
    }

    /* Browsers usually disable backgrounds on print, so this ensures icons
    (which use BG masks) will show up. */
    .icon {
        -webkit-print-color-adjust: exact;
        color-adjust: exact;
        print-color-adjust: exact;
    }

    .nav__menu,
    .nav__trigger,
    .header__actions {
        display: none;
    }

    .header {
        padding: 0;
    }

    /* Cards
  /* -------------------------------------------------------------------------- */

    .card {
        --card-color: var(--color-ink) !important;

        background: var(--color-canvas);
        border: var(--border-light);
        box-shadow: none;
        break-inside: avoid;
        color: var(--color-ink);
    }

    .card {
        .card__board {
            background: var(--color-canvas);
            border-block-end: var(--border-light);
            border-inline-end: var(--border-light);
            color: var(--color-ink);
        }
    }

    /* Events
  /* ------------------------------------------------------------------------ */

    .event {
        --card-color: var(--color-ink) !important;

        background: var(--color-canvas);
        border: var(--border-light);
        box-shadow: none;
        break-inside: avoid;
        color: var(--color-ink);

        .avatar {
            --avatar-size: 2lh;
        }
    }

    /* Card perma
  /* ------------------------------------------------------------------------ */

    .comment--new,
    .steps>.step:last-child {
        display: none;
    }

    .comments {
        --row-gap: 0;
        --comment-padding-inline: 1.4lh;

        padding-inline: 0;
    }

    .comment {
        --comment-max: none;

        border-block-end: var(--border-light);
    }

    .comment__content {
        background: none;
    }

    .comment__avatar {
        --btn-size: 2lh;

        margin-inline-start: 0;
    }

    .comment__author h3 {
        margin-inline: 0;
    }

    .comment__body {
        text-align: start;
    }

    /* Routes & Execution reports
  /* ------------------------------------------------------------------------ */

    .header {
        padding-block-start: 1em;
    }

    /* Execution detail (datasheet report)                                      */
    /* The on-screen datasheet IS the printed report: strip screen chrome,      */
    /* keep status colour (print-color-adjust: exact), repeat the table header   */
    /* on every page, and keep zone groups + rows from breaking mid-block.       */

    /* Flatten the screen hero into a plain report title block. */
    .form-hero {
        background: none;
        border: none;
        box-shadow: none;
        padding: 0 0 0.6em;
        margin: 0 0 0.8em;
        border-block-end: 1pt solid var(--color-ink);
        break-after: avoid;
    }
    .form-hero__side {
        display: none;
    }
    .form-hero__title {
        font-size: 18pt;
        font-weight: 700;
    }
    .form-hero__description {
        font-size: 9.5pt;
        color: var(--color-ink);
    }
    .form-hero__meta {
        font-size: 8.5pt;
    }

    .section-head {
        break-after: avoid;
    }

    /* Report header: breadcrumb sits small above the title, left-aligned. */
    .header {
        border: none;
        display: block;
        padding: 0 0 0.3em;
    }
    .header .breadcrumb {
        color: var(--color-ink);
        font-size: 7.5pt;
        justify-content: flex-start;
        justify-self: start; /* screen pins it right; Chrome honours this in block flow too */
    }
    .form-sheet {
        padding-inline: 0; /* align the report with the breadcrumb edge */
    }
    .section-head__meta {
        display: none; /* duplicates the hero's CHECKS · STOPS line */
    }

    /* Datasheet: hairline row rules, no cell grid (Basecamp-style list);   */
    /* status colours kept; header repeated on every page.                  */
    .datasheet {
        border: none;
        border-collapse: collapse;
        font-size: 8.5pt;
        inline-size: 100%;
        -webkit-print-color-adjust: exact;
        print-color-adjust: exact;
    }
    .datasheet thead {
        display: table-header-group; /* repeat column headers on each page */
    }
    .datasheet thead th {
        background: var(--color-canvas);
        border-block-end: 1pt solid var(--color-ink);
        box-shadow: none;
        position: static; /* drop sticky for print */
    }
    .datasheet th,
    .datasheet td {
        border: none;
        border-block-end: var(--border-light);
        padding: 0.35em 0.45em;
        vertical-align: top;
    }
    .datasheet thead th:first-child,
    .datasheet td[data-col="ref"] {
        padding-inline-start: 1.1rem; /* keep the state-triangle gutter */
    }
    .datasheet__ref {
        background: none;
        border: none;
        padding: 0;
    }

    /* Zone group: ink pill with a rule running out to the right. */
    .datasheet__group-head {
        break-after: avoid;
    }
    .datasheet__group-head th {
        background: linear-gradient(var(--color-ink), var(--color-ink)) no-repeat left 1.5em / 100% 1pt;
        border: none;
        padding: 1.1em 0 0.3em;
    }
    .datasheet__group-marker {
        background: var(--color-ink);
        border-radius: 0.2em;
        color: var(--color-canvas);
        padding: 0.25em 0.6em;
    }
    .datasheet__group-meta {
        background: var(--color-canvas);
        color: var(--color-ink);
        display: inline;
        margin: 0;
        padding-inline: 0.5em;
    }

    /* Asset sub-header: plain bold ink line, no box. */
    .datasheet__subgroup-head {
        break-after: avoid;
    }
    .datasheet__subgroup-head th {
        background: none;
        border: none;
        border-block-end: var(--border-light);
        padding: 0.7em 0.45em 0.2em;
    }
    .datasheet__subgroup-marker {
        color: var(--color-ink);
        font-size: 8.5pt;
        font-weight: 700;
    }
    .datasheet tbody tr {
        break-inside: avoid;
    }
    .datasheet tr[data-state] td,
    .datasheet tr[data-state] th {
        -webkit-print-color-adjust: exact;
        print-color-adjust: exact;
    }

    /* Report detail: expand every check's write-up regardless of screen
       collapse state. The lazy reading frame and the check link are screen
       affordances. Each check is its own <tbody>; keep a result with its
       detail on one page (Chromium ignores breaks on a <tr>). */
    /* utilities.css hides [hidden] with a layered !important, which beats
       any unlayered rule; inside the same layer, specificity wins. */
    @layer utilities {
        .datasheet__detail-row[hidden] {
            display: table-row !important;
        }
    }
    .datasheet__detail-row > td {
        background: none;
    }
    .datasheet__detail-row > td > turbo-frame,
    .datasheet__detail-link {
        display: none !important;
    }
    .datasheet__check {
        break-inside: avoid;
    }
    .report-detail {
        gap: 0.4em;
        padding: 0.4em 0.6em;
    }
    /* The trend chart is a screen affordance: Plotly renders it at zero width
       inside collapsed rows and only re-fits on the (screen-only) expand
       nudge, so on paper it would print blank. Hide it and let the numeric
       previous→current + breakdown carry the trend on the printed report. */
    .report-detail__chart {
        display: none;
    }
    .report-detail__stats {
        gap: 0.8em;
    }

    /* Media thumbnails: small, wrapped, colours kept (thermograms). */
    .datasheet__media {
        gap: 0.2em;
    }
    .datasheet__media-thumb,
    .datasheet__media-thumb img,
    .datasheet__media-thumb .attachment__thumb {
        block-size: 1.2cm;
        inline-size: auto;
    }
    .thermography-hotspot {
        -webkit-print-color-adjust: exact;
        print-color-adjust: exact;
    }

    /* Notes line: readable on paper. */
    .datasheet__sub {
        color: var(--color-ink);
        display: block;
        font-size: 7.5pt;
    }

    /* ---- Shared screen-only chrome (suppressed on every printed page) -----
       These classes live in shared partials / controllers (thermography
       overlays, native <dialog> modals) and the route capture page — they
       are NOT execution-specific, so they stay in their own group to survive
       future section edits. */
    .thermography-tooltip {
        display: none !important;
    }
    dialog,
    #lightbox-dialog {
        display: none !important;
    }
    .routes {
        padding: 0;
    }
}
