/* Broadsheet — design-system tokens and component classes for the two
   plumbing demos. Sibling of ../../electrician/marek/nocturne.css and
   ../../electrician/vance/modernist.css, which do the same job for those.

   One thing is different about this file and it matters if you go looking:
   those two were LIFTED from design-canvas exports and carry "nothing below
   is ours to retune" at the top, because the canvas is where they are
   retuned. There is no canvas project behind this one. It was written here,
   on 2026-09-23, so here is where it is retuned — but retune it in BOTH
   copies (wexler/ and renner/), which are byte-identical on purpose, the way
   nocturne.css is across its three demos.

   Why a third system at all: Nocturne was on three of the four demos and
   Modernist on the fourth. Two more Nocturne pages would have made five of
   six read as one template, which is the opposite of what a page called
   /websites is trying to demonstrate.

   The idea is print. A local paper, not a magazine: everything sits on a
   rule, nothing floats. No rounded corners, no drop shadows, no cards
   lifting off the ground — those are the moves Nocturne makes, and doing
   them differently is not the same as not doing them. Rules do the
   separating, weight and size do the hierarchy, and figures are tabular so
   a column of prices lines up like a column of prices.

   Zilla Slab (SIL OFL 1.1) sets the headings; Libre Franklin (SIL OFL 1.1)
   sets everything else. Both are self-hosted below, latin and latin-ext
   only, addressed relative to THIS file so the URLs survive whatever the
   page's own URL does. Libre Franklin is a variable face and Google serves
   one file for every weight, so it is declared once per subset with a
   400-600 range rather than downloaded twice under two names. */

/* latin */
@font-face {
  font-family: 'Zilla Slab';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("fonts/zilla-slab-latin.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
  font-family: 'Zilla Slab';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("fonts/zilla-slab-latin-ext.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Libre Franklin';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("fonts/libre-franklin-latin.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
  font-family: 'Libre Franklin';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("fonts/libre-franklin-latin-ext.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  /* Ground. Warm, slightly off-white: newsprint, not paper-white, so a
     photograph laid on it does not look like it is on a lightbox. */
  --color-bg: #f7f5ef;
  --color-surface: #fffefb;
  --color-sunk: #ece8de;          /* the shade a boxed-out panel takes */
  --color-text: #15171a;
  --color-accent: #0f6b62;        /* each demo overrides this in page.css */
  --color-accent-ink: #ffffff;    /* what sits ON the accent */

  /* One warm neutral ramp, even steps, so any two roles at the same step
     read as the same value. Hue held at ~40, chroma falling to nothing at
     the light end the way ink on paper does. */
  --color-neutral-100: #faf8f4;
  --color-neutral-200: #eeeae1;
  --color-neutral-300: #ddd7ca;
  --color-neutral-400: #b9b1a0;
  --color-neutral-500: #8e8676;
  --color-neutral-600: #6b6456;
  --color-neutral-700: #4e483d;
  --color-neutral-800: #332f28;
  --color-neutral-900: #1f1c18;

  --color-divider: #cdc6b7;
  --color-rule: #15171a;          /* the heavy rules are ink, not grey */

  --font-heading: 'Zilla Slab', Georgia, 'Times New Roman', serif;
  --font-heading-weight: 600;
  --font-body: 'Libre Franklin', system-ui, -apple-system, sans-serif;

  /* Print has no corner radius and no elevation. Both tokens exist because
     the component classes below reference them; both are flat on purpose,
     and a demo that wants a rounded corner should think again rather than
     override these. */
  --radius-sm: 0;
  --radius-md: 0;
  --radius-lg: 0;
  --shadow-sm: none;
  --shadow-md: none;

  --rule-hair: 1px;
  --rule-bold: 3px;

  --measure: 62ch;
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.6;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* height: auto is not decoration. Every <img> here carries real width/height
   attributes, which arrive as presentational hints -- and aspect-ratio only
   gets to compute a dimension when the other one is auto. Without this line
   a 1100x825 file in a 288px column renders 288 wide and 825 tall, and
   object-fit quietly crops it to a portrait. */
img { max-width: 100%; height: auto; }

a { color: inherit; }

:where(a, button, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 3px;
}

/* ------------------------------------------------------------ measure --- */
/* .wrap is on the SECTIONS, not on a single main element, so any one of them
   can run full width without fighting a parent. Same arrangement as the
   other demos. */
.wrap { max-width: 1240px; margin-inline: auto; }
.pad  { padding-inline: clamp(18px, 4.5vw, 56px); }

/* ---------------------------------------------------------------- type --- */
.h1 {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: clamp(38px, 6.4vw, 82px);
  line-height: 1.02;
  letter-spacing: -0.02em;
  margin: 0;
}
.h2 {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: clamp(26px, 3.2vw, 40px);
  line-height: 1.12;
  letter-spacing: -0.014em;
  margin: 0;
}
.h3 {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: clamp(19px, 1.7vw, 23px);
  line-height: 1.2;
  letter-spacing: -0.008em;
  margin: 0;
}

/* The standfirst: the paragraph directly under a headline, set larger than
   body and shorter in measure. A newspaper calls it a deck. */
.deck {
  font-size: clamp(17px, 1.5vw, 20px);
  line-height: 1.5;
  color: var(--color-neutral-700);
  max-width: 54ch;
  margin: 0;
}
.body { font-size: 16px; line-height: 1.65; color: var(--color-neutral-700); max-width: var(--measure); margin: 0 0 14px; }
.body:last-child { margin-bottom: 0; }
.fine { font-size: 13.5px; line-height: 1.5; color: var(--color-neutral-600); margin: 0; }

/* Small caps-ish label. Every section and every panel gets one -- it is how
   a ruled page tells you what you are looking at without a heading. */
.label {
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--color-neutral-600);
  margin: 0;
}
.label--accent { color: var(--color-accent); }

/* Figures line up in a column. Prices, phone numbers, dates, counts. */
.tnum { font-variant-numeric: tabular-nums; font-feature-settings: 'tnum' 1; }

/* ---------------------------------------------------------------- rule --- */
.rule      { border: 0; border-top: var(--rule-hair) solid var(--color-divider); margin: 0; }
.rule--ink { border-top: var(--rule-bold) solid var(--color-rule); }

/* --------------------------------------------------------------- button --- */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: 8px;
  font: inherit; font-weight: 600; font-size: 15px;
  letter-spacing: 0.01em;
  padding: 13px 22px;
  border: var(--rule-hair) solid var(--color-rule);
  border-radius: var(--radius-md);
  background: transparent; color: var(--color-text);
  text-decoration: none; cursor: pointer;
  transition: background 0.18s linear, color 0.18s linear;
}
.btn-primary {
  background: var(--color-accent);
  border-color: var(--color-accent);
  color: var(--color-accent-ink);
}
.btn-primary:hover { background: var(--color-text); border-color: var(--color-text); }
.btn-ghost:hover { background: var(--color-text); color: var(--color-bg); }
.actions { display: flex; flex-wrap: wrap; gap: 10px; }

/* A tag is a boxed word: an area served, a certification. Square, ruled. */
.tag {
  display: inline-block;
  font-size: 13px; line-height: 1.2;
  padding: 7px 11px;
  border: var(--rule-hair) solid var(--color-divider);
  color: var(--color-neutral-700);
  background: var(--color-surface);
}

/* ---------------------------------------------------------- the grid ---- */
/* Ruled cells. The workhorse of the whole system: a row of facts, prices or
   figures, divided by hairlines rather than gaps, with a heavy rule above.
   Used for the credentials strip, the figures strip and the hours. */
.cells {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  border-top: var(--rule-bold) solid var(--color-rule);
}
.cell {
  padding: 16px clamp(14px, 2vw, 26px) 18px 0;
  border-right: var(--rule-hair) solid var(--color-divider);
}
.cell:last-child { border-right: 0; }
.cell__k { margin: 0 0 6px; }
.cell__v { margin: 0; font-family: var(--font-heading); font-weight: 600; font-size: 19px; line-height: 1.25; }

/* ---------------------------------------------------------- the band ---- */
/* A photograph the full width of the page with a caption ruled under it.
   This is where pictures live in Broadsheet -- NOT behind the headline. The
   other four demos all put a photograph under their opening copy; the point
   of this one is that the first screen is type. */
/* margin: 0 is load-bearing -- <figure> carries a 40px UA inline margin and
   without this the band sits narrower than the ruled cells above it, which
   on a page made of aligned rules is the one thing you notice. */
.band { position: relative; margin: 0; }
.band__img { display: block; width: 100%; height: clamp(230px, 34vw, 420px); object-fit: cover; }
.band__cap {
  display: flex; flex-wrap: wrap; gap: 4px 18px; justify-content: space-between;
  padding: 10px 0 0;
  border-top: var(--rule-hair) solid var(--color-divider);
}

/* --------------------------------------------------------------- misc --- */
.skip {
  position: absolute; left: -9999px;
  background: var(--color-text); color: var(--color-bg);
  padding: 10px 16px; z-index: 50;
}
.skip:focus { left: 12px; top: 12px; }

.u-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    transition-duration: 0.001ms !important;
  }
}
