/* print.css: the printable lyric sheet («Imprimir letra»), loaded with media="print".

   Until 2026-11-07 this section was §35 of site.css. It moved here because site.css blocks the
   first paint of every page, and ~10 KB gzip of it was print layout no screen ever uses: the
   desktop LCP p75 sat ~100 ms from the 2.5 s line (docs/print-lyric-sheet.md §14). A stylesheet
   whose media does not match is fetched at the lowest priority and never blocks rendering.

   Linked from components/print_sheet_head.html, so only a page with a sheet requests it. The
   section below is byte-identical to the old §35: print_sheet.py pins its SHA-256 between the
   two marker comments, and the print metrics were measured against exactly these bytes.
   ────────────────────────────────────────────────────────────────── */

/* ── 35. Printable lyric sheet («Imprimir letra», @media print) ──────
   Ctrl+P on a lyric page prints ONE framable sheet: the author photo, the title, one credits
   line, the lyric body and a discreet foot. docs/print-lyric-sheet.md is the source of truth;
   read it before touching anything here.

   - Everything is inside `@media print`: not one rule reaches the screen.
   - Every rule is scoped to a page that carries `[data-print-sheet]` (the 31 lyrics whose body
     is prose, and every other page, print exactly as before) — including the page box, which
     is a named page for that reason.
   - Nothing is duplicated: the hero `<img>` and `.lyric-text` the screen already has are
     reused, and the head/foot are `hidden` components (components/print_sheet_*.html).
   - The server picks the fit (content_catalog/print_sheet.py) from per-glyph tables and head
     heights measured against THIS section. Changing it changes them:
     `.venv/bin/python scripts/build_print_metrics.py`, then
     `.venv/bin/python scripts/verify_print_sheet.py --corpus`. A test pins this section's hash.
   ────────────────────────────────────────────────────────────────── */

@media print {
    /* The browser's header and footer (URL, date) are drawn in the page margin; with no margin
       there is no room for them, so the sheet carries its margins inside. */
    @page lyric-sheet {
        size: auto;
        margin: 0;
    }

    :root:has([data-print-sheet]) {
        --ps-ink: #1b1512;
        --ps-soft: #4a3d36;
        --ps-rule: #9c8670;
        --ps-column-rule: #cbbca9;
        --ps-paper: #ffffff;
        /* Design area = A4 ∩ Letter = 210 × 279.4 mm. The sheet fills the real page; only the
           lyric row grows, so A4's extra 17.6 mm becomes air around the verses. */
        --ps-side: 17mm;
        --ps-bleed: 7mm;
        --ps-top: 12mm;
        --ps-bottom: 9mm;
        color-scheme: light;
        print-color-adjust: exact;
        -webkit-print-color-adjust: exact;
        background: var(--ps-paper) !important;
        /* The page box reaches the sheet as a percentage down this chain: `100vh` is the page in
           Chrome but the SCREEN in WebKit, where a sheet that tall let the verses spill over the
           photo and the title (an iPhone print, 2026-10-13). */
        height: 100%;
    }

    :root:has([data-print-sheet]) body {
        page: lyric-sheet;
        margin: 0 !important;
        padding: 0 !important;
        background: var(--ps-paper) !important;
        color: var(--ps-ink) !important;
        min-height: 0 !important;
        height: 100% !important;
    }

    /* 1. Keep only the path down to the sheet. */
    :root:has([data-print-sheet]) body > :not(.site-shell),
    :root:has([data-print-sheet]) .site-shell > :not(#site-main),
    :root:has([data-print-sheet]) #site-main > :not(.lyric-detail-section),
    :root:has([data-print-sheet]) [data-print-sheet] > :not(.lyric-hero):not(.lyric-reader-grid),
    :root:has([data-print-sheet]) .lyric-reader-grid > :not(.lyric-sheet),
    :root:has([data-print-sheet]) .lyric-sheet > :not(.ps-head):not(.ps-photo):not(.lyric-text):not(.ps-foot),
    :root:has([data-print-sheet]) .lyric-hero > :not(.lyric-hero-media),
    :root:has([data-print-sheet]) [data-print-photo="own"] .lyric-hero,
    :root:has([data-print-sheet]) [data-print-photo="none"] .lyric-hero {
        display: none !important;
    }

    :root:has([data-print-sheet]) .site-shell,
    :root:has([data-print-sheet]) #site-main,
    :root:has([data-print-sheet]) .lyric-detail-section {
        display: block !important;
        margin: 0 !important;
        padding: 0 !important;
        border: 0 !important;
        background: none !important;
        box-shadow: none !important;
        min-height: 0 !important;
        height: 100% !important;
        max-width: none !important;
        width: auto !important;
        overflow: visible !important;
    }

    /* Their backdrops (gradients, grain, scrims) are pseudo-elements, and a `display: contents`
       box still generates its ::before/::after: they would paint the screen backdrop on paper. */
    :root:has([data-print-sheet]) .site-shell::before,
    :root:has([data-print-sheet]) .site-shell::after,
    :root:has([data-print-sheet]) #site-main::before,
    :root:has([data-print-sheet]) #site-main::after,
    :root:has([data-print-sheet]) .lyric-detail-section::before,
    :root:has([data-print-sheet]) .lyric-detail-section::after,
    :root:has([data-print-sheet]) [data-print-sheet]::before,
    :root:has([data-print-sheet]) [data-print-sheet]::after,
    :root:has([data-print-sheet]) .lyric-hero::before,
    :root:has([data-print-sheet]) .lyric-hero::after,
    :root:has([data-print-sheet]) .lyric-reader-grid::before,
    :root:has([data-print-sheet]) .lyric-reader-grid::after,
    :root:has([data-print-sheet]) .lyric-sheet::before,
    :root:has([data-print-sheet]) .lyric-sheet::after {
        content: none !important;
        display: none !important;
    }

    /* The hero header, the reader grid and the article dissolve: their surviving children
       become items of ONE grid, so the reused hero <img> and the reused .lyric-text are laid
       out together although they live in different subtrees. */
    :root:has([data-print-sheet]) .lyric-hero,
    :root:has([data-print-sheet]) .lyric-reader-grid,
    :root:has([data-print-sheet]) .lyric-sheet {
        display: contents !important;
    }

    /* 2. The sheet. */
    :root:has([data-print-sheet]) [data-print-sheet] {
        display: grid !important;
        box-sizing: border-box;
        width: auto !important;
        max-width: none !important;
        /* At least the page, never less than its content: a sheet held to the page height lays
           an overflowing lyric over the head (its row shrinks to nothing and the verses, centred
           on it, spill both ways). Grown, it overflows onto a visible second page instead. */
        height: auto;
        min-height: 100%;
        margin: 0 !important;
        padding: var(--ps-top) 0 var(--ps-bottom) !important;
        /* `.lyric-detail-layout` has a gap on screen; inherited here it narrowed the text column
           from 176 to 165 mm behind the server's back. */
        gap: 0 !important;
        grid-template-columns: var(--ps-side) minmax(0, 1fr) var(--ps-side);
        grid-template-rows: auto auto minmax(0, 1fr) auto;
        grid-template-areas:
            ". photo ."
            ". head  ."
            ". lyric ."
            ". foot  .";
        align-items: start;
        /* Never `hidden`: if a browser's metrics ever beat the server's estimate, a second page
           is a visible, reportable failure; clipped verses would be a silent one. */
        overflow: visible;
        background: var(--ps-paper) !important;
        color: var(--ps-ink);
        font-synthesis: none;
    }

    /* 3. Photo: the reused screen hero, or the print-only one. */
    :root:has([data-print-sheet]) .lyric-hero-media,
    :root:has([data-print-sheet]) .ps-photo {
        grid-area: photo;
        position: relative !important;
        inset: auto !important;
        display: block !important;
        margin: 0 auto !important;
        padding: 0 !important;
        overflow: hidden !important;
        opacity: 1 !important;
        transform: none !important;
        background: none !important;
        z-index: auto !important;
    }

    :root:has([data-print-sheet]) .lyric-hero-media::before,
    :root:has([data-print-sheet]) .lyric-hero-media::after {
        content: none !important;
        display: none !important;
    }

    /* A warm black and white that survives a mono printer, cropped on the face the screen hero
       was tuned for (`--ps-photo-position`, from the stored image_position). */
    :root:has([data-print-sheet]) .lyric-hero-media img,
    :root:has([data-print-sheet]) .ps-photo img {
        display: block !important;
        position: static !important;
        width: 100% !important;
        height: 100% !important;
        max-width: none !important;
        object-fit: cover !important;
        object-position: var(--ps-photo-position, 50% 22%) !important;
        opacity: 1 !important;
        transform: none !important;
        mask-image: none !important;
        -webkit-mask-image: none !important;
        filter: grayscale(1) sepia(0.14) contrast(1.06) brightness(1.02) !important;
    }

    /* Bleed (≥ 900 px): a band across the printable width, wider than the text column. */
    :root:has([data-print-layout="bleed"]) .lyric-hero-media,
    :root:has([data-print-layout="bleed"]) .ps-photo {
        grid-column: 1 / -1 !important;
        width: calc(100% - 2 * var(--ps-bleed)) !important;
        height: var(--ps-bleed-h, 92mm) !important;
        margin-top: calc(var(--ps-bleed) - var(--ps-top)) !important;
    }

    /* Portrait (177–899 px): a small art-deco arched frame, never a pixelated bleed. */
    :root:has([data-print-layout="portrait"]) .lyric-hero-media,
    :root:has([data-print-layout="portrait"]) .ps-photo {
        width: var(--ps-portrait-w, 46mm) !important;
        height: calc(var(--ps-portrait-w, 46mm) * 1.28) !important;
        border-radius: 50% 50% 0 0 / 36% 36% 0 0 !important;
        outline: 0.5pt solid var(--ps-rule);
        outline-offset: 1.6mm;
        margin-top: 3mm !important;
    }

    :root:has([data-print-layout="portrait"]) .lyric-hero-media img,
    :root:has([data-print-layout="portrait"]) .ps-photo img {
        border-radius: inherit !important;
    }

    /* 4. Head: ornament, title, credits. */
    :root:has([data-print-sheet]) .ps-head {
        grid-area: head;
        display: block !important;
        text-align: center;
        padding-top: 6mm;
    }

    :root:has([data-print-sheet]) .ps-rule {
        display: flex;
        align-items: center;
        gap: 2.6mm;
        margin: 0 auto;
        width: 62mm;
    }

    :root:has([data-print-sheet]) .ps-rule::before,
    :root:has([data-print-sheet]) .ps-rule::after {
        content: "";
        flex: 1;
        border-top: 0.5pt solid var(--ps-rule);
        border-bottom: 0.25pt solid var(--ps-rule);
        height: 0.7mm;
    }

    :root:has([data-print-sheet]) .ps-rule i {
        width: 1.7mm;
        height: 1.7mm;
        border: 0.5pt solid var(--ps-rule);
        transform: rotate(45deg);
    }

    :root:has([data-print-sheet]) .ps-title {
        margin: 4.2mm 0 0 !important;
        font-family: var(--font-display) !important;
        font-weight: 600;
        font-size: var(--ps-title-size, 27pt);
        line-height: 1.1;
        letter-spacing: 0.2em;
        /* Tracking adds trailing space after the last letter; pull it back so the title centers. */
        margin-right: -0.2em !important;
        text-transform: uppercase;
        color: var(--ps-ink) !important;
        text-wrap: balance;
        /* Optical size pinned, like the lyric's below: the server's glyph table is one cut. */
        font-optical-sizing: none;
        font-variation-settings: "opsz" 28;
    }

    :root:has([data-print-sheet]) .ps-credits {
        margin: 3.4mm 0 4.6mm !important;
        font-family: var(--font-reading) !important;
        font-size: var(--ps-credits-size, 10.5pt);
        line-height: 1.3;
        color: var(--ps-soft) !important;
        text-wrap: balance;
        font-optical-sizing: none;
        font-variation-settings: "opsz" 12;
    }

    :root:has([data-print-sheet]) .ps-credits:empty {
        display: none !important;
    }

    :root:has([data-print-sheet]) .ps-credits b {
        font-family: var(--font-ui);
        font-weight: 600;
        font-size: 0.61em;
        letter-spacing: 0.22em;
        text-transform: uppercase;
        color: var(--ps-rule);
        margin-right: 0.35em;
        vertical-align: 0.12em;
    }

    :root:has([data-print-sheet]) .ps-credits .ps-sep {
        margin: 0 0.7em;
        color: var(--ps-rule);
    }

    /* The typographic version: the title is the image. */
    :root:has([data-print-layout="type"]) .ps-head {
        padding-top: 14mm;
    }

    :root:has([data-print-layout="type"]) .ps-title {
        margin-top: 9mm !important;
        margin-bottom: 1mm !important;
    }

    :root:has([data-print-layout="type"]) .ps-rule {
        width: 96mm;
    }

    :root:has([data-print-layout="type"]) .ps-credits {
        margin-top: 5mm !important;
        margin-bottom: 8mm !important;
    }

    /* 5. The lyric: the page's own .lyric-text, restyled. */
    :root:has([data-print-sheet]) .lyric-text {
        grid-area: lyric;
        align-self: center;
        justify-self: center;
        width: auto !important;
        max-width: 100% !important;
        margin: 0 !important;
        padding: 7mm 0 3mm !important;
        font-family: var(--font-reading) !important;
        font-size: var(--ps-lyric-size, 12pt) !important;
        line-height: var(--ps-leading, 1.36) !important;
        /* Optical size pinned: with `auto` Newsreader is 13% wider at 9 pt than at 14 pt, which
           the server-side fit would have to model per size and per browser. */
        font-optical-sizing: none !important;
        font-variation-settings: "opsz" 12 !important;
        letter-spacing: 0 !important;
        color: var(--ps-ink) !important;
        text-wrap: wrap;
        columns: var(--ps-cols, 1);
        column-gap: 11mm;
        column-rule: 0.4pt solid var(--ps-column-rule);
        column-fill: balance;
        orphans: 1;
        widows: 1;
    }

    :root:has([data-print-sheet]) .lyric-text p {
        margin: 0 0 0.85em !important;
        padding: 0 !important;
        /* A verse too long for the column wraps under a hanging indent, so the reader still sees
           where each verse starts. `each-line` restarts the count after every <br>. */
        text-indent: 0 !important;
        text-indent: 1.1em hanging each-line !important;
        break-inside: avoid;
        color: inherit !important;
    }

    :root:has([data-print-sheet]) .lyric-text p:last-child {
        margin-bottom: 0 !important;
    }

    /* The screen turns <br> into a spaced block; on paper it is a plain break. Never write
       `br + br` here: text nodes are not siblings, so it matches every <br> after the first. */
    :root:has([data-print-sheet]) .lyric-text br {
        display: inline !important;
        content: normal !important;
        margin: 0 !important;
    }

    :root:has([data-print-sheet]) .lyric-text > p:first-of-type::first-letter {
        all: unset;
    }

    :root:has([data-print-sheet]) .lyric-text a {
        color: inherit !important;
        text-decoration: none !important;
    }

    /* «Frases» highlights and any other inline decoration print as plain text. */
    :root:has([data-print-sheet]) .lyric-text mark,
    :root:has([data-print-sheet]) .lyric-text [class] {
        background: none !important;
        color: inherit !important;
        box-shadow: none !important;
        text-decoration: none !important;
    }

    /* Several columns: the block is as wide as its verses need (`--ps-measure`, set by the
       server from the longest verse), so the poem sits centered instead of hugging the left. */
    :root:has([data-print-cols="2"]) .lyric-text,
    :root:has([data-print-cols="3"]) .lyric-text {
        width: min(100%, calc(var(--ps-cols) * var(--ps-measure, 100%) + (var(--ps-cols) - 1) * 11mm)) !important;
    }

    /* CSS Custom Highlights (text_actions.js) touch no DOM, so the rule above cannot reach them.
       lt-anchored paints the verse in --marker-ink, which is light in the dark theme: on white
       paper those verses vanished (cambalache, 2026-10-12 prototype). Paper carries no layers. */
    :root:has([data-print-sheet]) ::highlight(lt-anchored),
    :root:has([data-print-sheet]) ::highlight(lt-phrase-own),
    :root:has([data-print-sheet]) ::highlight(lt-phrase-flash),
    :root:has([data-print-sheet]) ::highlight(lt-hint),
    :root:has([data-print-sheet]) ::highlight(lt-hint-1),
    :root:has([data-print-sheet]) ::highlight(lt-hint-2),
    :root:has([data-print-sheet]) ::highlight(lt-hint-3),
    :root:has([data-print-sheet]) ::highlight(lt-hint-4),
    :root:has([data-print-sheet]) ::highlight(lt-hint-5),
    :root:has([data-print-sheet]) ::highlight(lt-comment-draft) {
        color: var(--ps-ink);
        background-color: transparent;
        text-decoration: none;
    }

    /* 6. Foot: «LETRASTANGO.COM», and the photo credit when the photo prints. */
    :root:has([data-print-sheet]) .ps-foot {
        grid-area: foot;
        display: flex !important;
        justify-content: center;
        align-items: center;
        gap: 2.4mm;
        padding-top: 5mm;
        font-family: var(--font-ui) !important;
        font-size: 6.6pt;
        letter-spacing: 0.24em;
        text-transform: uppercase;
        color: var(--ps-rule) !important;
    }

    :root:has([data-print-sheet]) .ps-foot .ps-credit {
        letter-spacing: 0.06em;
        text-transform: none;
    }

    :root:has([data-print-sheet]) .ps-foot i {
        width: 1.1mm;
        height: 1.1mm;
        border: 0.4pt solid var(--ps-rule);
        transform: rotate(45deg);
    }

    /* 7. Compact head: the long lyrics take the room the head gives up. */
    :root:has([data-print-head="compact"]) {
        --ps-bleed-h: 64mm;
        --ps-portrait-w: 30mm;
        --ps-leading: 1.3;
    }

    :root:has([data-print-head="compact"]) .ps-head {
        padding-top: 3.5mm;
    }

    :root:has([data-print-head="compact"]) .ps-title {
        margin-top: 3mm !important;
    }

    :root:has([data-print-head="compact"]) .ps-credits {
        margin: 2.4mm 0 3mm !important;
    }

    :root:has([data-print-head="compact"]) .lyric-text {
        padding-top: 5mm !important;
    }

    :root:has([data-print-layout="type"][data-print-head="compact"]) .ps-head {
        padding-top: 6mm;
    }

    :root:has([data-print-layout="type"][data-print-head="compact"]) .ps-title {
        margin-top: 5mm !important;
    }

    :root:has([data-print-layout="type"][data-print-head="compact"]) .ps-credits {
        margin: 3.5mm 0 4mm !important;
    }

    /* 8. Mini head: the last resort for the few lyrics that fit nowhere else
       (fabula-para-gardel, 133 lines). The photo yields its room; the title stays, smaller. */
    :root:has([data-print-head="mini"]) {
        --ps-leading: 1.26;
    }

    :root:has([data-print-head="mini"]) .lyric-hero-media,
    :root:has([data-print-head="mini"]) .ps-photo {
        display: none !important;
    }

    :root:has([data-print-head="mini"]) .ps-head {
        padding-top: 1mm !important;
    }

    :root:has([data-print-head="mini"]) .ps-title {
        margin-top: 2.4mm !important;
    }

    :root:has([data-print-head="mini"]) .ps-credits {
        margin: 1.8mm 0 2.4mm !important;
    }

    :root:has([data-print-head="mini"]) .lyric-text {
        padding-top: 4mm !important;
    }

    :root:has([data-print-head="mini"]) .lyric-text p {
        margin-bottom: 0.6em !important;
    }

    /* 9. No photo on paper → no photo box and no photo credit. Covers the typographic layout the
       server chose, the mini head, and the beforeprint fallback when a print-only photo has not
       arrived (Safari never loads a lazy image for print: WebKit bug 224547). */
    :root:has([data-print-layout="type"]) .lyric-hero-media,
    :root:has([data-print-layout="type"]) .ps-photo,
    :root:has([data-print-layout="type"]) .ps-foot .ps-credit,
    :root:has([data-print-layout="type"]) .ps-foot i,
    :root:has([data-print-head="mini"]) .ps-foot .ps-credit,
    :root:has([data-print-head="mini"]) .ps-foot i {
        display: none !important;
    }

    /* 10. WebKit: Safari, and every iOS browser (Chrome included), flagged on <html> by
       base_interactions.js. Its real print pipeline (measured through WKWebView, 2026-10-13)
       differs from Chrome's in ways the screen-media emulation never showed:
       - It lays the page out at 1.25 CSS px per point (Chrome: 1.333), inside margins it picks
         itself: `@page { margin }` is ignored (iOS keeps ~12 pt). The page is narrower than the
         design area in CSS terms. A sheet wider than any of its pages makes WebKit shrink the
         whole sheet to the printable width, whatever those margins are. At 216 mm the 279.4 mm
         design height still fits once shrunk: Letter's height/width (279.4 / 215.9) is just
         above the sheet's (279.4 / 216), A4's is far above, and margins only raise a ratio.
       - A multi-column box that only exists in print is never balanced: every verse lands in
         the first column, and a forced break opens a column one whole box-width away. Flex
         columns wrapped at the server's tallest column (`--ps-col-h`) do the same job. */
    :root[data-print-engine="webkit"]:has([data-print-sheet]) {
        --ps-side: 20mm; /* (216 - 176) / 2: the text column stays the server's 176 mm */
    }

    :root[data-print-engine="webkit"]:has([data-print-sheet]) [data-print-sheet] {
        width: 216mm !important;
    }

    :root[data-print-engine="webkit"]:has([data-print-cols="2"]) .lyric-text,
    :root[data-print-engine="webkit"]:has([data-print-cols="3"]) .lyric-text {
        display: flex !important;
        flex-flow: column wrap;
        align-content: flex-start;
        position: relative;
        box-sizing: content-box;
        /* One line of slack, so a verse that wraps here and not in the estimate cannot push its
           stanza into a column past the last one. */
        max-height: calc(var(--ps-col-h) + 1.4em);
        row-gap: 0.85em;
        column-gap: 11mm;
        columns: auto;
    }

    :root[data-print-engine="webkit"]:has([data-print-cols="2"]) .lyric-text p,
    :root[data-print-engine="webkit"]:has([data-print-cols="3"]) .lyric-text p {
        flex: none;
        width: calc((100% - (var(--ps-cols) - 1) * 11mm) / var(--ps-cols));
        /* The stanza gap is the flex row gap: a margin would follow the last stanza of every
           column too, and the server's column height does not count it. */
        margin: 0 !important;
    }

    :root[data-print-engine="webkit"]:has([data-print-head="mini"]) .lyric-text {
        row-gap: 0.6em;
    }

    /* The column rules, in the middle of each gap, over the verses only (not the padding). */
    :root[data-print-engine="webkit"]:has([data-print-cols="2"]) .lyric-text::before,
    :root[data-print-engine="webkit"]:has([data-print-cols="3"]) .lyric-text::before,
    :root[data-print-engine="webkit"]:has([data-print-cols="3"]) .lyric-text::after {
        content: "";
        position: absolute;
        top: 7mm;
        bottom: 3mm;
        left: calc((100% - (var(--ps-cols) - 1) * 11mm) / var(--ps-cols) + 5.5mm);
        border-left: 0.4pt solid var(--ps-column-rule);
    }

    :root[data-print-engine="webkit"]:has([data-print-cols="3"]) .lyric-text::after {
        left: calc(2 * (100% - 2 * 11mm) / 3 + 16.5mm);
    }

    :root[data-print-engine="webkit"]:has([data-print-head="compact"]) .lyric-text::before,
    :root[data-print-engine="webkit"]:has([data-print-head="compact"]) .lyric-text::after {
        top: 5mm;
    }

    :root[data-print-engine="webkit"]:has([data-print-head="mini"]) .lyric-text::before,
    :root[data-print-engine="webkit"]:has([data-print-head="mini"]) .lyric-text::after {
        top: 4mm;
    }
}
/* ── end of 35. Printable lyric sheet ── */
