/* the Periodic (web) — layout and register.
 *
 * The geometry is A4 and the risky part; the faces are A0.3/A6. The
 * remaining A6 work is the finer typographic detail (old-style figures,
 * the band and slug devices from grid.tex), not the type itself.
 *
 * The rule this file exists to enforce: NOTHING SCALES AN IMAGE. Every
 * width and height arrives from the server as an explicit pixel value
 * computed in whole units. No percentages, no `max-width: 100%`, no
 * `object-fit`, no `width: auto` on a dithered <img> — each of those
 * would put a 1-bit pattern on a fractional box and average its dots to
 * grey. The field does not reflow; it snaps between unit steps and lets
 * the outer margins take the slack.
 */

:root {
  --paper: #e5e1d5;
  --ink: #1b1813;
  --red: #8c2f1f;
  --hair: #c9c3b4;
  /* --u and --measure are set per-response in an inline <style>: they
     depend on which step the viewport resolved to. */
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: 'EB Garamond', Georgia, 'Times New Roman', serif;
  /* Old-style figures, as the print system sets them. */
  font-variant-numeric: oldstyle-nums;
  /* The one horizontal rule: the field never scrolls sideways. If a row
     ever overflows the measure this clips it, and the smoke test that
     asserts documentElement.scrollWidth === clientWidth catches it. */
  overflow-x: hidden;
}

.tech {
  /* The technical register: labels, folios, figure numbers, vote
     controls. Jost* stands in for the print system's Futura. */
  font-family: 'Jost', 'Futura', 'Century Gothic', system-ui, sans-serif;
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--red);
}

/* ── chrome ──────────────────────────────────────────────────────── */

.head {
  margin: 0 auto;
  padding: 24px 0 8px;
}

.head h1 {
  /* The masthead. Bodoni Moda at 900 italic stands in for the cover's
     lead Bodoni Ultra Italic — the heaviest free face at this cut, and
     still lighter than the metal. */
  font-family: 'Bodoni Moda', 'Bodoni 72', Didot, serif;
  font-size: 34px;
  font-style: italic;
  font-weight: 900;
  letter-spacing: -0.01em;
  margin: 0 0 4px;
}

.head p {
  margin: 0 0 10px;
}

/* \gticks — one tick per unit, all 58. Absolutely positioned at exact
   unit multiples, so a misaligned ruler is a visible symptom of a
   miscomputed step rather than a silent one. */
.ticks {
  position: relative;
  border-bottom: 1px solid var(--hair);
  margin-bottom: 18px;
}

.ticks i {
  position: absolute;
  bottom: 0;
  width: 1px;
  height: 4px;
  background: var(--hair);
}

.ticks i:nth-child(10n + 1) {
  height: 100%;
  background: var(--red);
}

/* ── the field ───────────────────────────────────────────────────── */

.field {
  margin: 0 auto;
}

.row {
  display: flex;
  /* gap is emitted inline as exactly 2 × unit — the grid's gutter. */
  margin-bottom: calc(var(--u) * 2);
}

.cell {
  /* THE CLIP. A cell is a fixed pixel box and its image is taller than
     it; the overflow is the crop. This is the line that lets one render
     per (span, unit) serve every row height that span appears in. */
  overflow: hidden;
  position: relative;
  flex: 0 0 auto;
  display: block;
}

.cell.img img {
  display: block;
  /* Belt and braces: the server sets width/height attributes to the
     exact source box, and these stop any stylesheet or user zoom from
     resampling it. `pixelated` keeps integer upscaling on hi-DPI
     screens crisp instead of smoothing the dots. */
  image-rendering: pixelated;
  max-width: none;
  /* Drops the dither's pure white onto the newsprint ground, so the
     pattern sits on paper rather than in a white box. Exact for white,
     and it needs no change to the PNGs. */
  mix-blend-mode: multiply;
}

/* A4 placeholder: a labelled block standing in for a render that does
   not exist yet, so the layout is checkable before the bulk job runs. */
.cell.ph {
  border: 1px solid var(--hair);
  background: repeating-linear-gradient(
    45deg,
    transparent,
    transparent 6px,
    rgba(27, 24, 19, 0.05) 6px,
    rgba(27, 24, 19, 0.05) 12px
  );
  display: flex;
  align-items: center;
  justify-content: center;
}

.cell.txt {
  color: inherit;
  text-decoration: none;
  border-top: 1px solid var(--ink);
  padding-top: 6px;
}

.txt-inner {
  font-size: 15px;
  line-height: 1.45;
  /* Prose and captions are the reading face; headings would be Cormorant,
     which enters with the section devices in A6. */
  font-family: 'EB Garamond', Georgia, serif;
}

.cell.title .txt-inner {
  /* Title candidates are set as the masthead is — they are competing to
     BE one. */
  font-family: 'Bodoni Moda', 'Bodoni 72', Didot, serif;
  font-size: calc(var(--u) * 1.6);
  line-height: 1.05;
  font-style: italic;
  font-weight: 900;
}

.cell.short .txt-inner {
  font-size: 14px;
}

#sentinel {
  height: 1px;
}
