/* PRINT
   ===========================================================================
   Two consumers, one stylesheet.

   1. scripts/article_export.py renders src/_print.html through WeasyPrint
      with tokens.css and this file and nothing else, so everything the
      article needs on paper has to be declared here rather than inherited
      from style.css.
   2. _layout.html links it with media="print", so Ctrl-P in a browser gets
      the same treatment. That path *does* have style.css underneath it,
      which is why the chrome suppression below exists.

   Sizes are in pt, not the px type tokens: --text-md is 18px, which is
   13.5pt — around a third larger than anything you would set a page of A4
   in. Colour, typeface and spacing still come from the tokens.

   WeasyPrint 69 does not implement fill/stroke as CSS properties, so the
   diagram cannot be styled from here at all; article_export.py writes it out
   with presentation attributes instead.
   =========================================================================== */

@page {
  size: A4;
  margin: 20mm 30mm 18mm;

  /* The margin boxes in the top row share the full height of the top
     margin, so a border-bottom on both lands at the same y and reads as one
     continuous rule under the running header, not two floating labels. */
  @top-left {
    content: string(doctitle);
    font-family: var(--font-sans);
    font-size: 8pt;
    color: var(--color-muted);
    vertical-align: bottom;
    border-bottom: var(--border-1) var(--border-style) var(--color-hairline);
    padding-bottom: var(--space-1);
  }

  /* The mark itself is set in the print document: it is the committed white
     logo repainted in --color-ink, which only exists once the build has read
     the tokens. */
  @top-right {
    vertical-align: bottom;
    border-bottom: var(--border-1) var(--border-style) var(--color-hairline);
    padding-bottom: var(--space-1);
  }

  @bottom-left {
    content: "stardevs.gg";
    font-family: var(--font-sans);
    font-size: 8pt;
    color: var(--color-muted);
  }

  @bottom-right {
    content: counter(page) " / " counter(pages);
    font-family: var(--font-sans);
    font-size: 8pt;
    color: var(--color-muted);
  }
}

/* The cover carries the title already. */
@page :first {
  @top-left {
    content: none;
    border-bottom: none;
  }

  @top-right {
    content: none;
    border-bottom: none;
  }
}

@media print {
  /* Screen chrome, for the browser's own print path. */
  .header,
  .footer,
  .skip-link,
  .consent,
  .article-aside,
  .article-downloads,
  .article-end,
  .article-anchor {
    display: none !important;
  }

  /* The rail is gone, so the column reserved for it would otherwise hold the
     text at 980 of 1240 on the page. */
  .article-layout {
    display: block;
  }

  /* The hero is the article's <h1>; without it a printout has no title.
     Keep the heading, drop the photograph it sits on. */
  .blog-headline {
    background: none;
    margin: 0 0 8mm;
    padding: 0;
  }

  .blog-headline__title {
    background: none !important;
    padding: 0;
    margin: 0;
    max-width: none;
    color: var(--color-ink);
    font-size: 22pt;
    line-height: 1.2;
  }
}

html {
  font-family: var(--font-sans);
  font-size: 10.5pt;
  line-height: 1.45;
  color: var(--color-black);
  background: none;

  /* style.css sets these on body, which this document never loads, so every
     typographic guarantee the site makes stopped at the PDF boundary.
     font-synthesis is listed for completeness even though WeasyPrint 69 does
     not implement it — the italic is shipped now, so nothing needs faking. */
  font-kerning: normal;
  font-variant-ligatures: common-ligatures contextual;
  font-optical-sizing: auto;
  font-synthesis: none;
}

body {
  margin: 0;
}

/* -- the masthead -------------------------------------------------------- */

/* The site's own header, reproduced: the shipped logo is white, so it needs
   the ink ground to be visible at all. Negative margins bleed the band out to
   the page edges through the @page margin; the running header on later pages
   uses a recoloured copy instead, declared in the print document because the
   colour is resolved at build time. */
.masthead {
  display: flex;
  /* Not baseline: an image's baseline is its bottom margin edge, so aligning
     it to the label's text baseline pushes the wordmark out of the band. */
  align-items: center;
  justify-content: space-between;
  margin: -20mm -30mm var(--space-6);
  padding: 10mm 30mm;
  background-color: var(--color-ink);
  /* A brand accent at the foot of the band, not a contrast-bearing UI
     boundary: the band's own background already separates it from the cover
     below, so this is decorative emphasis rather than the edge itself. */
  border-bottom: var(--border-2) var(--border-style) var(--color-indigo);
}

.masthead__logo {
  width: 34mm;
  height: auto;
}

.masthead__kind {
  font-family: var(--font-sans);
  font-size: 8pt;
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--color-cyan);
}

/* -- the cover ----------------------------------------------------------- */

.cover {
  margin-bottom: var(--space-10);
  padding-bottom: var(--space-5);
  border-bottom: var(--border-2) var(--border-style) var(--color-ink);
}

.cover__title {
  string-set: doctitle content();
  margin: 0 0 var(--space-3);
  font-family: var(--font-serif);
  font-size: 27pt;
  font-weight: var(--weight-semibold);
  line-height: 1.1;
  color: var(--color-ink);
}

.cover__standfirst {
  font-family: var(--font-serif);
  margin: 0 0 var(--space-4);
  font-size: 12pt;
  line-height: 1.4;
  color: var(--color-ink);
}

.cover__byline {
  margin: 0;
  font-size: 9.5pt;
  color: var(--color-muted);
}

.cover__byline::before {
  content: "";
  display: block;
  width: 20mm;
  margin-bottom: var(--space-3);
  border-top: var(--border-1) var(--border-style) var(--color-indigo);
}

.cover__author {
  font-weight: var(--weight-semibold);
  color: var(--color-black);
}

/* -- the article --------------------------------------------------------- */

.article {
  display: block;
  max-width: none;
  font-family: var(--font-serif);
  /* Literata has a larger x-height than Inter, so the same point size reads
     noticeably bigger. Measured against the previous Inter setting rather
     than carried across, and paired with the wider page margins above to
     bring the line length back under 80 characters. */
  font-size: 11pt;
  hyphens: auto;
  hyphenate-limit-chars: 7 4 3;
}

.article-p {
  max-width: none;
  margin: 0 0 var(--space-3);
  orphans: 3;
  widows: 3;
}

.article-h2,
.article-h3 {
  font-family: var(--font-serif);
  font-weight: var(--weight-semibold);
  color: var(--color-ink);
  /* A heading at the foot of a page with its section overleaf is the most
     common way a generated PDF looks unedited. */
  break-after: avoid;
  break-inside: avoid;
}

.article-h2 {
  margin: var(--space-5) 0 var(--space-2);
  padding-bottom: var(--space-1);
  border-bottom: var(--border-1) var(--border-style) var(--color-hairline);
  font-size: 16pt;
  line-height: 1.25;
}

.article-h3 {
  margin: var(--space-4) 0 var(--space-1);
  font-size: 12.5pt;
  line-height: 1.3;
}

.article-list {
  max-width: none;
  margin: 0 0 var(--space-3) var(--space-4);
  padding: 0;
}

.article-list li {
  margin-bottom: var(--space-1);
  orphans: 3;
  widows: 3;
}

ol.article-list li {
  list-style: decimal;
}

.article-quote {
  margin: var(--space-3) 0 var(--space-3) var(--space-3);
  padding-left: var(--space-3);
  border-left: var(--border-2) var(--border-style) var(--color-indigo);
  font-size: 11pt;
  font-style: italic;
  color: var(--color-ink);
  break-inside: avoid;
}

.article-quote p {
  margin: 0;
}

.article code,
.article kbd,
.article samp {
  font-family: var(--font-mono);
  font-size: 0.9em;
  font-variant-ligatures: none;
}

/* A code block, which no article had until the exporter learnt to carry one.
   Wrapped rather than clipped: a page has no horizontal scroll, and a line of
   code cut at the margin is a line of code that is wrong. */
.article pre {
  font-family: var(--font-mono);
  font-size: 0.82em;
  line-height: var(--leading-snug);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  margin: 0 0 1em;
}

.article pre code {
  font-size: inherit;
}

.article-fnref {
  font-size: 0.7em;
  line-height: 0;
  vertical-align: super;
}

/* Page navigation, not prose: neither the PDF nor a printout can follow them. */
.article-fnback,
.article-figure__open {
  display: none;
}

/* -- tables -------------------------------------------------------------- */

.article-table-wrap,
.article-figure {
  /* A scroll container has no meaning on paper, and it clips. */
  overflow: visible;
  margin: 0 0 var(--space-5);
  break-inside: avoid;
}

.article-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 9pt;
  font-variant-numeric: tabular-nums slashed-zero;
}

/* Seven tables in one article: at least one will cross a page boundary, and
   a continuation without its header is unreadable. */
.article-table thead {
  display: table-header-group;
}

.article-table tr,
.article-table th,
.article-table td {
  break-inside: avoid;
}

.article-table th,
.article-table td {
  padding: var(--space-2) var(--space-3);
  border-bottom: var(--border-1) var(--border-style) var(--color-hairline);
  text-align: left;
  vertical-align: top;
}

.article-table th {
  font-weight: var(--weight-semibold);
  color: var(--color-ink);
  border-bottom-color: var(--color-ink);
}

/* A hairline between rows is not enough to track a line across eight or nine
   columns; banding does the rest without adding another rule weight. */
.article-table tbody tr:nth-child(even) {
  background-color: var(--color-surface);
}

/* -- the diagram --------------------------------------------------------- */

.article-diagram {
  display: block;
  width: 100%;
  height: auto;
  max-width: 100%;
}

/* Without an explicit width a raster renders at its intrinsic size: the
   1672px pipeline render is 17 inches at 96dpi and ran off the page. The
   diagram escaped this because .article-diagram already set width: 100%. */
.article-figure img {
  display: block;
  width: 100%;
  height: auto;
  max-width: 100%;

  /* Not for looks: WeasyPrint derives the PDF /Interpolate flag from this
     property (`interpolate = image_rendering == 'auto'`), and PDF/A forbids
     /Interpolate true — ISO 19005-3 clause 6.2.8. Leaving it at auto made
     veraPDF reject both image-bearing PDFs.

     crisp-edges rather than smooth because WeasyPrint's validator accepts
     only auto, crisp-edges and pixelated; smooth is dropped and falls back
     to auto. The visual cost here is nil: /Interpolate governs smoothing on
     upscale, and every one of these images is placed smaller than its
     intrinsic size. */
  image-rendering: crisp-edges;
}

/* Square and portrait art would otherwise be taller than the text block and
   push a page break in front of itself. */
.article-figure--inset img {
  max-width: 95mm;
  margin-inline: auto;
}

.article-figure--poster img {
  max-width: 105mm;
  margin-inline: auto;
  border: var(--border-1) var(--border-style) var(--color-hairline);
}

.article-caption {
  max-width: none;
  margin-top: var(--space-2);
  font-size: 8pt;
  line-height: 1.4;
  color: var(--color-muted);
  break-before: avoid;
}

/* -- links --------------------------------------------------------------- */

.article a {
  color: var(--color-indigo);
  text-decoration: underline;
}

/* Paper has no hover and no address bar, so an unprinted URL is simply lost.
   Footnote marks are excluded or all thirteen print as "1 (#fn-1)". */
.article a[href^="http"]::after {
  content: " (" attr(href) ")";
  font-size: 0.82em;
  color: var(--color-muted);
  word-break: break-all;
}

/* Except a file in a table of files: the diagram kit's table links each of
   its glyphs twice, and 62 printed addresses buried the table under them.
   The article names the folder they are all in. Same specificity as the rule
   above, and later, so it wins. */
.article a.article-file::after {
  content: none;
}

.article a[href^="#"]::after {
  content: none;
}

/* -- the colophon -------------------------------------------------------- */

.colophon {
  margin-top: var(--space-6);
  padding-top: var(--space-3);
  border-top: var(--border-1) var(--border-style) var(--color-hairline);
  font-size: 8pt;
  line-height: 1.5;
  color: var(--color-muted);
  break-inside: avoid;
}

.colophon a {
  color: var(--color-muted);
}

/* -- service pages ------------------------------------------------------- */

/* .services is a dark gradient band carrying blush text, and .headline--band
   is the same gradient behind white. Browsers drop backgrounds when printing,
   so every service page printed pale text on white — effectively a blank
   sheet. That was survivable while the pages were 200 words of filler; they
   are now the case for an engagement someone will want to hand to a
   colleague. */
.services,
.headline--band {
  background: none;
  color: var(--color-ink);
}

.headline__kicker,
.headline__fact dt,
.services-stage__span,
.services-stage__output,
.services-caption {
  color: var(--color-muted);
}

.headline__facts,
.headline__title,
.services-title,
.services-stage__name,
.services-evidence__link {
  color: var(--color-ink);
}

.headline__button {
  background: none;
  color: var(--color-ink);
  border: var(--border-1) var(--border-style) var(--color-ink);
}

/* The screen layout puts the controls in a three-column panel grid, the
   stages in a 2×2, and the diagram beside the lede. On a sheet the grids
   would run 13px copy in 60mm cells, and the panel grounds are dropped with
   every other background — so flow everything as one column and keep a
   hairline where a ground used to mark the edge. */
.services-lede,
.services-list--panels,
.services-list--ruled,
.services-stages,
.services-cta {
  display: block;
}

.services-lede .services-figure {
  margin: var(--space-8) 0;
}

/* background: none, not just left to the browser: with "background graphics"
   switched on, the navy-soft panel would print under ink text. */
.services-list--panels .services-list__item,
.services-cta {
  background: none;
  border: var(--border-1) var(--border-style) var(--color-hairline);
  margin-bottom: var(--space-3);
}

.services-list--panels .services-list__item > strong {
  color: var(--color-ink);
}

.services-list--ruled .services-list__item,
.services-stage {
  border-top-color: var(--color-hairline);
  margin-bottom: var(--space-3);
}

/* The diagram brings its own dark panel as an element background, which is
   dropped for the same reason — leaving cyan and mint strokes on white at
   1.7:1 and 1.2:1. Restate the whole drawing in ink. WeasyPrint cannot style
   inline SVG at all (see the note at the top of this file), so this governs
   browser printing only; the PDF path is untouched because service pages are
   not exported. */
.article-diagram--panel {
  background: none;
}

.diagram-box rect,
.diagram-box path,
.diagram-line path {
  stroke: var(--color-ink);
}

.diagram-head path,
.diagram-label text {
  fill: var(--color-ink);
}

/* The diagram kit, restated for paper the same way, with the star in indigo:
   white on white is no star at all. Same specificity as style.css's rules so
   the later sheet wins. */
.diagram-glyph {
  stroke: var(--color-ink);
}

.diagram-star {
  fill: var(--color-indigo);
}
