/* EZO Labs Inc: the print composition
 *
 * A third composition, for paper and for "save as PDF": linked on every page as
 * <link rel="stylesheet" href="/assets/print.css" media="print" /> as the last line of
 * its <head>, after theme.js and after any page's own <style>, so a tie in the cascade
 * goes to paper without !important. The screen stylesheets gain no print branch;
 * a site test holds every page to that link and this file to its rules, and a local
 * print gate (it needs Chromium and poppler) prints the real pages to PDF with
 * backgrounds off and reads the ink back out of them.
 *
 * Paper is the ground and ink is the text. A printer drops backgrounds (Chromium's
 * default print-color-adjust: economy), so nothing here asks for them back and no
 * background may carry meaning: the blue field prints as white paper with a 1.5pt
 * rule in the field's blue, and the striped mark still rises from that rule, in ink.
 * The field's blue stays the one accent: rules, link underlines, the figures' own
 * strokes and the lead number (in its deeper tint, 6.9:1 on white).
 *
 * The token block out-specifies both schemes: :root:root (0,2,0) beats
 * html[data-theme="dark"] (0,1,1), and .ent.ent beats the .ent body's own dark set,
 * so a visitor who picked dark still prints light (the OS setting is never read: the
 * dark scheme comes only from that pick). It is the site's own hexes plus white paper,
 * re-declared, never !important.
 *
 * Kept: the article, its abstract, numbers and assumptions, tables, figures, endnotes,
 * the citation and the revisions, and the research index's lead figure, which the screen
 * draws only at desktop widths. Hidden: the nav, the scheme switch, the research
 * rail and chapter bar, copy buttons, the sim's step controls, footnote back links,
 * the follow band, a post's next list, the index's lead chart, the footer. A research
 * article's links print their address after the text, from the data-url the research
 * build stamps on each one, a figure's full-size link among them. The page itself carries
 * a running head and a folio in its margin boxes (Chromium; other engines print the
 * margins and the breaks without them). */

@page {
  margin: 20mm 17mm 24mm;
  /* The running head and the folio: the site's address over every sheet, the page
     number under it. A margin box reads the root's custom properties, so these are
     the paper block's ink and type below. */
  @top-right {
    content: "ezolabs.io";
    font: 500 var(--t-label)/1 var(--mono);
    letter-spacing: 0.08em;
    color: var(--ink);
    vertical-align: bottom;
    padding-bottom: 5mm;
  }
  @bottom-right {
    content: "page " counter(page) " of " counter(pages);
    font: 500 var(--t-label)/1 var(--mono);
    letter-spacing: 0.08em;
    color: var(--ink);
    vertical-align: top;
    padding-top: 6mm;
  }
}

@media print {
  /* ---------- the paper token block ----------
     The root, /enterprise's body (which carries the dark set in both schemes) and
     research's paper grid (which re-derives its tints): each out-specifies the block it
     overrides, so the paper wins whatever data-theme says. */
  :root:root, .ent.ent, .paper.paper {
    color-scheme: light;
    --ground: #ffffff;
    --text: #05070f;
    --ink: #05070f;
    --field: #3b6ef6;
    --field-on-ground: #1551c8;
    --muted: #5f646d;
    /* opaque tints of the ink: a printer lays solid ink, never a translucent one */
    --text-2: color-mix(in srgb, var(--ink) 80%, var(--ground));    /* 11.6:1 on white */
    --text-3: color-mix(in srgb, var(--ink) 52%, var(--ground));    /* 4.1:1, strokes and frames */
    --hairline: color-mix(in srgb, var(--ink) 26%, var(--ground));  /* 1.9:1, a rule that survives the printer */
    --tint: transparent;
    --surface: var(--ground);
    /* research's paper grid is ruled in ink, as in light (a dark pick rules it in the muted grey) */
    --paper-rule: var(--ink);
    /* nothing is filled on paper, so text "on ink" is ink */
    --on-ink: var(--ink);
    /* the geometry: the sheet's margins are the gutter, and nothing bleeds */
    --page-zoom: 1;
    --gutter: 0px;
    --edge: 0px;
    --edge-r: 0px;
    --inset-l: 0px;
    --inset-r: 0px;
    --maxw: none;
    /* the type ramp in points, nothing under 9pt (12px) */
    --t-label: 9pt;
    --t-small: 9.5pt;
    --t-nav: 9pt;
    --t-body: 10.5pt;
    --t-lead: 12pt;
    --t-h3: 12.5pt;
  }

  html { zoom: 1; }
  body { background: none; font-size: var(--t-body); line-height: 1.5; }
  /* a sheet has no motion: every entrance prints at its end state. This rule only
     switches motion off, so it needs no prefers-reduced-motion guard of its own. */
  *, *::before, *::after { animation: none !important; transition: none !important; }
  /* The hero's copy prints whole whatever its entrance did. Until main.js marks the copy
     .ready, the screen holds the headline and the kicker at opacity 0 (`.hero-copy:not(.ready)
     .t`, three classes' weight) for a keyframe to lift, and paper has no keyframes (above): a
     sheet printed before the entrance runs (scripts blocked, or not yet run) would carry no
     headline. The :not(.ready) arms carry that hold's weight and, later in the cascade, win. */
  .hero-copy .t, .hero-copy .kicker,
  .hero-copy:not(.ready) .t, .hero-copy:not(.ready) .kicker,
  .w-ground { opacity: 1; transform: none; }

  /* ---------- the screen's furniture ---------- */
  .site-header, .site-footer, .defs, .cf,
  [role="switch"], button, input, select, textarea, form, .pv-label,
  .hero-btn, .world-steps, .status-dot,
  .post__rail, .chapter, .cite__actions, .post__more, .revisions__chev,
  .segments, .counts__feed, .empty__action, .section-head__slot,
  .follow, .post__next,
  a[data-footnote-backref] { display: none; }
  /* The index's lead chart shows only where the lead cell is 1126px wide or more, and a sheet
     lays out under 700 (688 on Letter): the chart prints with its post, whatever window printed it. */
  .lead__figure { display: none; }
  /* A figure's full-size link, a phone's on screen, is its file's address on paper (the
     data-url rule below): every figure prints where its drawing can be fetched. */
  .figure__full { display: revert; }

  /* ---------- the field, on paper ----------
     White paper over a rule in the field's blue, and the mark rising from that rule in
     ink, as it rises from the field's bottom edge on screen. */
  .hero {
    height: auto;
    min-height: 0;
    display: flow-root;
    overflow: hidden;
    padding: 0 0 52mm;
    background: none;
    border-bottom: 1.5pt solid var(--field);
    --mark: 64mm;
  }
  .hero-mark {
    position: absolute;
    z-index: auto;
    right: 0;
    bottom: calc(var(--mark) * -0.367);
    width: var(--mark);
    height: var(--mark);
    margin: 0;
    fill: var(--ink);
  }
  .hero-copy { position: relative; padding: 0; margin: 0; }
  .hero .kicker { margin-bottom: 6mm; }
  .hero h1 { font-size: 34pt; line-height: 1; }
  .hero h1 .l { white-space: normal; }
  /* the section head (research's list pages, /security, the archive): the ink band on paper,
     as the hero is. The lockup, the page's h1, in ink on white, no fill, closed by the
     field's blue rule; the sheet's top margin is its top pad. Its name slot is the paper's
     solid grey (on screen a tint of the off-white over ink); its slot (research's topics,
     security's report pill and count) is screen furniture, hidden above. */
  .section-head {
    display: block;
    padding: 0 0 8mm;
    background: none;
    color: var(--ink);
    border-bottom: 1.5pt solid var(--field);
  }
  .section-head__kind { color: var(--text-2); }
  .section-head__rule { background: none; border-left: 1px solid var(--text-3); opacity: 1; }
  /* The archive prints under the name it carried until 2026-10-28, "ezo labs | disclosures": its
     screen h1 names the record ("dependency remediation"), and the sheet keeps the page's own
     name, as the head's name slot did before the relabel. The head's parts join one row — the
     lockup's flex is what the row is — and the paper name takes the h1's place after the rule,
     in the kind's own voice. The page's <style> hides that name on screen, so the visitor only
     ever sees the record's name. No other page carries the span, so only the archive changes. */
  .section-head:has(> .se-print-kind) {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-start;
    gap: var(--head-lockup-gap);
  }
  .section-head:has(> .se-print-kind) .section-head__lockup { display: contents; }
  .section-head:has(> .se-print-kind) .section-head__lockup > h1.section-head__kind { display: none; }
  .section-head:has(> .se-print-kind) .se-print-kind {
    display: block;
    font-size: var(--head-kind);
    font-weight: 400;
    line-height: 1;
    letter-spacing: -0.03em;
    color: var(--text-2);
  }
  /* the other fields (the superbot band, /security's report band and research's chip): ink
     on paper between field rules, never a fill a printer would drop */
  .sb-band, .se-report, .verdict, .sb-btn { background: none; color: var(--ink); }
  .sb-band, .se-report { padding: 8mm 0; border-block: 1.5pt solid var(--field); }
  .sb-btn { border: 1px solid var(--ink); }

  /* ---------- research's index ----------
     The lead prints with its figure. The screen draws the figure from 901px only, where the
     lead cell is wide enough for the chart's labels; a sheet is about 690px, so there the lead
     takes the sheet's width and the figure all of it, and the side column (the next posts and
     the topics) follows as one row. The grid's rules are its ground showing through 1px gaps,
     which no printer lays: on paper they are hairlines, between the lead and the row and
     between the row's cells. */
  .index-grid { grid-template-columns: minmax(0, 1fr); }
  .lead-cell { padding-right: 0; }
  .lead__figure { display: block; max-width: none; margin-top: 6mm; color: var(--ink); }
  .index-side { display: flex; flex-direction: row; border-top: 1px solid var(--hairline); }
  .index-side > * { flex: 1 1 0; min-width: 0; padding-left: var(--s5); padding-right: var(--s5); }
  .index-side > * + * { border-left: 1px solid var(--hairline); }
  .index-side > :first-child { padding-left: 0; }
  .index-side > :last-child { padding-right: 0; }

  /* ---------- breaks ----------
     A heading stays with what follows it, a figure or a citation is never cut, and a
     long table breaks between rows with its header repeated on the next sheet. The home
     page's what we do is one beat: a sheet carries its label, statement and line together. */
  h1, h2, h3, h4, caption, figcaption, .label { break-after: avoid; }
  figure, .figure, caption, .cite, .katex-display, blockquote, pre,
  .numbers__list li, .assumptions, .world, .status-row, .sb-band, .section-head, .contact-row, .what-we-do,
  .lead__figure, .index-side,
  .se-disc > li, .se-proof__list, .se-report,
  .ab-omni, .ab-faq > div { break-inside: avoid; }
  p, li, dd { orphans: 3; widows: 3; }
  thead { display: table-header-group; }
  tr, td, th { break-inside: avoid; }
  .table-wrap, .figure__art, .cite__bib { overflow: visible; }
  /* a table's caption is pinned left on screen so a wide table scrolls under it; a sheet does
     not scroll, and a pinned box would ride every sheet */
  .post__body caption { position: static; }
  /* the home page's about sections are grids on screen; a grid row would not keep a heading
     with its content across a sheet, a block does */
  .ab-sec, .ab-faq { display: block; }
  .ab-sec > * + *, .ab-faq > * + * { margin-top: var(--s6); }
  /* its folds (closed on screen by default) print open, their matter under the heading and the
     chevron left on the screen: here where the browser has ::details-content, and main.js opens
     them on beforeprint where it has not */
  .ab-det::details-content { content-visibility: visible; display: contents; }
  .ab-body { display: block; padding-bottom: var(--s5); }
  .ab-body > * + * { margin-top: var(--s5); }
  .ab-chev { display: none; }

  /* ---------- a link cannot be clicked: its address prints after it ---------- */
  a[data-url]::after {
    content: " (" attr(data-url) ")";
    font: 400 var(--t-label)/1.4 var(--mono);
    letter-spacing: 0;
    color: var(--text-2);
    overflow-wrap: anywhere;
  }

  /* the revisions fold open on paper, where it cannot be clicked */
  .revisions::details-content { content-visibility: visible; display: contents; }
}
