/* ─────────────────────────────────────────────────────────────
   Infragrit — low-tech visual system

   A printed page: warm paper, hairline rules, one typeface family
   (IBM Plex Mono, self-hosted) for everything that is machine-like,
   and the reader's own serif for prose. No JavaScript is required
   for anything on this page to work.

   Images are 1-bit dithered plates (see tools/dither.sh). They are
   black ink on white paper, so they are tinted here by laying them
   over a section colour with `mix-blend-mode: multiply` — a tint
   costs zero bytes.
   ───────────────────────────────────────────────────────────── */

/* ── typefaces ───────────────────────────────────────────────
   IBM Plex Mono 400 + 500, latin subset, SIL Open Font License.
   Two files, 29 kB, no third-party connection. The reader's own
   serif is used for prose: nothing to download. */

@font-face{
  font-family:"IBM Plex Mono";
  font-style:normal; font-weight:400;
  font-display:swap;
  src:url("../fonts/ibm-plex-mono-400-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;
}
@font-face{
  font-family:"IBM Plex Mono";
  font-style:normal; font-weight:500;
  font-display:swap;
  src:url("../fonts/ibm-plex-mono-500-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;
}

/* ── tokens ──────────────────────────────────────────────── */

:root{
  --paper:   #F4F0E5;
  --paper-2: #EAE4D3;
  --paper-3: #DED6C1;
  --ink:     #17160F;
  --ink-2:   #4C4838;
  --rule:    rgba(23,22,15,.16);
  --rule-2:  rgba(23,22,15,.34);
  --accent:  #8A5320;
  --tint:    #E9DFC6;

  --mono:  "IBM Plex Mono", ui-monospace, "SFMono-Regular", "SF Mono", Menlo, Consolas, monospace;
  --serif: ui-serif, "Iowan Old Style", "Palatino Linotype", Palatino, "Book Antiqua", Georgia, serif;

  --pad:   clamp(18px, 4.2vw, 44px);
  --maxw:  1120px;
  --prose: 34rem;
  --hair:  1px solid var(--rule);

  color-scheme: light;
  -webkit-text-size-adjust: 100%;
}

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

html{ scroll-behavior:smooth; }
@media (prefers-reduced-motion: reduce){ html{ scroll-behavior:auto; } }

body{
  margin:0;
  background:var(--paper);
  color:var(--ink);
  font-family:var(--serif);
  font-size:clamp(1.02rem, .55vw + .92rem, 1.14rem);
  line-height:1.62;
  text-rendering:optimizeLegibility;
}

.wrap{ width:100%; max-width:var(--maxw); margin-inline:auto; padding-inline:var(--pad); }
.prose{ max-width:var(--prose); }

a{ color:var(--accent); text-decoration:none; }
a:hover{ text-decoration:underline; text-underline-offset:.2em; }
a:focus-visible,
button:focus-visible,
summary:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; }

p{ margin:0 0 1.1em; }
ul,ol{ margin:0 0 1.1em; padding-left:1.3em; }
li{ margin-bottom:.35em; }
li:last-child{ margin-bottom:0; }

img{ max-width:100%; height:auto; display:block; }
hr{ border:0; border-top:var(--hair); margin:2.5rem 0; }

.skip{
  position:absolute; left:-9999px;
  background:var(--ink); color:var(--paper);
  padding:.6em 1em; font-family:var(--mono); font-size:.85rem; z-index:10;
}
.skip:focus{ left:.5rem; top:.5rem; }

/* ── small print: labels, meta, machine-ish text ─────────── */

.mono,.label,.meta,.tag,time,code,kbd,samp{
  font-family:var(--mono);
  font-size:.82rem;
  letter-spacing:.01em;
}
.label{
  display:inline-block;
  text-transform:uppercase;
  letter-spacing:.12em;
  color:var(--ink-2);
}
.meta{ color:var(--ink-2); }

/* ── masthead ────────────────────────────────────────────── */

.masthead{ border-bottom:1px solid var(--rule-2); background:var(--paper); }
/* On screens wider than a phone the masthead stays pinned while the guide
   scrolls, so the way back is always on screen. (On a phone the stacked
   header is too tall to pin; the footer's "Back to top ↑" covers that.) */
@media (min-width:621px){
  .masthead{ position:sticky; top:0; z-index:20; }
  /* Keep section targets from landing underneath the pinned header. */
  [id]{ scroll-margin-top:4.5rem; }
}
.masthead__inner{
  display:flex; flex-wrap:wrap; align-items:baseline; gap:1rem 2rem;
  padding-block:.9rem;
}
.mark{
  font-family:var(--mono); font-weight:500; font-size:1rem;
  letter-spacing:.14em; text-transform:uppercase; color:var(--ink);
  white-space:nowrap;
}
.mark:hover{ text-decoration:none; color:var(--accent); }
.mark__glyph{ color:var(--accent); }

/* Seven items: sized so that the masthead stays on one line at a 1280 laptop
   width, with the call-to-action still on the same row. */
.nav{ display:flex; flex-wrap:wrap; gap:.25rem 1rem; margin-inline:auto 0; }
.nav a{
  font-family:var(--mono); font-size:.8rem; letter-spacing:.04em;
  color:var(--ink-2); text-transform:lowercase;
}
.nav a::before{ content:"["; color:var(--rule-2); }
.nav a::after{ content:"]"; color:var(--rule-2); }
.nav a:hover, .nav a[aria-current]{ color:var(--ink); }

.masthead__end{ display:flex; align-items:baseline; gap:1.2rem; }

/* No hamburger and no menu script: the links are short enough to wrap onto
   two or three lines on a phone, which is cheaper than any menu. */
@media (max-width:620px){
  .masthead__inner{ flex-direction:column; align-items:flex-start; gap:.7rem; }
  .nav{ margin:0; gap:.2rem .9rem; }
  .nav a{ font-size:.76rem; }
  .masthead__end{ width:100%; }
}

/* ── buttons ─────────────────────────────────────────────── */

.btn{
  display:inline-block;
  font-family:var(--mono); font-size:.82rem; letter-spacing:.06em;
  padding:.65em 1.1em;
  border:1px solid var(--ink); color:var(--ink);
  background:transparent;
}
.btn:hover{ background:var(--ink); color:var(--paper); text-decoration:none; }
.btn--accent{ border-color:var(--accent); color:var(--accent); }
.btn--accent:hover{ background:var(--accent); border-color:var(--accent); color:var(--paper); }
.btn--on-ink{ border-color:var(--paper); color:var(--paper); }
.btn--on-ink:hover{ background:var(--paper); color:var(--ink); }

.link-more{
  font-family:var(--mono); font-size:.82rem; letter-spacing:.04em;
}
.link-more::after{ content:" →"; }

/* ── hero ────────────────────────────────────────────────── */

/* The ridge photograph is a background layer behind the hero copy, tinted
   by `multiply` like every other plate and veiled with a paper scrim that
   is solid under the text and lets the image show towards the right. */
.hero{
  position:relative; isolation:isolate; overflow:hidden;
  border-bottom:var(--hair);
  padding-block:clamp(2rem,5vw,3.6rem) clamp(2.4rem,6vw,4.2rem);
}
.hero__bg{
  position:absolute; z-index:-1; inset:0; margin:0;
  pointer-events:none;
}
.hero__bg img{
  width:100%; height:100%; object-fit:cover; object-position:center 42%;
  mix-blend-mode:multiply;
}
.hero__bg::after{
  content:""; position:absolute; inset:0;
  background:linear-gradient(90deg,
    var(--paper) 0%, var(--paper) 34%,
    rgba(244,240,229,.78) 56%, rgba(244,240,229,.18) 100%);
}
/* Narrow screens: the copy spans the whole width, so fade the image out
   vertically instead of sideways. */
@media (max-width:640px){
  .hero__bg img{ opacity:.24; }
  .hero__bg::after{
    background:linear-gradient(180deg,
      var(--paper) 0%, rgba(244,240,229,.42) 55%, rgba(244,240,229,.1) 100%);
  }
}
@media print{ .hero__bg{ display:none; } }

.hero__eyebrow{ margin-bottom:1.1rem; }
.hero h1{
  font-family:var(--serif); font-weight:400;
  font-size:clamp(2.05rem, 5.4vw, 3.5rem);
  line-height:1.08; letter-spacing:-.01em;
  margin:0 0 1.1rem;
}
.hero h1 em{ font-style:italic; }
.hero__lede{ font-size:1.06em; max-width:var(--prose); color:var(--ink); }
.hero__actions{ display:flex; flex-wrap:wrap; align-items:center; gap:1rem 1.4rem; margin-top:1.6rem; }


/* ── plates: 1-bit dithered images ───────────────────────── */

.plate{
  position:relative; margin:0;
  background:var(--tint);
  border:1px solid var(--rule);
}
.plate img{
  width:100%;
  mix-blend-mode:multiply;
  /* The dots are the image: keep them from being blurred into grey mush. */
  image-rendering:auto;
}
.plate figcaption{
  font-family:var(--mono); font-size:.76rem; line-height:1.5;
  color:var(--ink-2);
  padding:.55rem .7rem;
  border-top:1px solid var(--rule);
  background:var(--paper-2);
}
.plate--square{ max-width:280px; }
.plate--portrait img{ aspect-ratio:1/1; object-fit:cover; }

/* ── section furniture ───────────────────────────────────── */

.section{ padding-block:clamp(2.4rem,5vw,4rem); border-top:1px solid var(--rule); }
.section--tint{ background:var(--paper-2); --tint:#E3D8BC; }
.section--tint .plate figcaption{ background:var(--paper-3); }
.section__head{ display:grid; gap:.7rem; margin-bottom:clamp(1.4rem,3vw,2.2rem); }
.section__no{
  font-family:var(--mono); font-size:.78rem; letter-spacing:.16em;
  text-transform:uppercase; color:var(--accent); margin:0;
}
.section h2{
  font-family:var(--serif); font-weight:400;
  font-size:clamp(1.5rem,3.2vw,2.15rem);
  line-height:1.16;  letter-spacing:-.005em; margin:0;
  max-width:32ch;
}
.section__note{ max-width:var(--prose); color:var(--ink-2); margin:0; }

/* ── steps (roman numerals) ──────────────────────────────── */

.steps{ list-style:none; padding:0; margin:0; display:grid; gap:1.2rem; }
@media (min-width:760px){ .steps{ grid-template-columns:repeat(2,1fr); } .steps--3{ grid-template-columns:repeat(3,1fr); } }
.steps li{ margin:0; padding-top:.7rem; border-top:var(--hair); }
.step__no{
  display:block; font-family:var(--mono); font-size:.76rem;
  letter-spacing:.16em; color:var(--accent); margin-bottom:.35rem;
}
.steps h3{ font-family:var(--serif); font-weight:400; font-size:1.12rem; margin:0 0 .3rem; }
.steps p{ margin:0; color:var(--ink-2); font-size:.95em; }

/* ── ledger: services and posts ──────────────────────────── */

.ledger{ list-style:none; padding:0; margin:0; border-top:1px solid var(--rule-2); }
.row{
  display:grid; gap:.4rem 1.4rem;
  padding-block:1.1rem;
  border-bottom:var(--hair);
  margin:0;
}
@media (min-width:820px){
  .row{ grid-template-columns:3.2rem minmax(15rem,20rem) 1fr; align-items:baseline; }
}
.row__no{ font-family:var(--mono); font-size:.78rem; color:var(--ink-2); }
.row__title{ font-family:var(--serif); font-weight:400; font-size:1.15rem; margin:0; }
.row__title a{ color:var(--ink); }
.row__title a:hover{ color:var(--accent); }
.row__body{ margin:0; color:var(--ink-2); grid-column:3; }
@media (max-width:819px){ .row__body{ grid-column:1; } }
.row__tags{
  grid-column:3; list-style:none; display:flex; flex-wrap:wrap; gap:.4rem .5rem;
  padding:0; margin:.5rem 0 0;
}
@media (max-width:819px){ .row__tags{ grid-column:1; } }
.tag{ color:var(--ink-2); border:1px solid var(--rule); padding:.05em .45em; }

/* ── blog ────────────────────────────────────────────────── */

.post-list{ list-style:none; padding:0; margin:0; border-top:1px solid var(--rule-2); }
.post-list li{ border-bottom:var(--hair); margin:0; }
.post-list a{
  display:grid; gap:.2rem 1.4rem; padding-block:.95rem;
  grid-template-columns:1fr; color:var(--ink);
}
@media (min-width:700px){
  .post-list a{ grid-template-columns:7.5rem 1fr; align-items:baseline; }
}
.post-list a:hover{ text-decoration:none; }
.post-list a:hover .post-list__title{ color:var(--accent); text-decoration:underline; text-underline-offset:.2em; }
.post-list time{ color:var(--ink-2); }
.post-list__title{ font-family:var(--serif); font-size:1.08rem; }
.post-list__summary{ grid-column:2; color:var(--ink-2); font-size:.93em; }
@media (max-width:699px){ .post-list__summary{ grid-column:1; } }

/* ── long-form prose ─────────────────────────────────────── */

.post__head, .page__head{ padding-block:clamp(2rem,4.6vw,3.2rem) 1.2rem; }
.post__head h1, .page__head h1{
  font-family:var(--serif); font-weight:400;
  font-size:clamp(1.9rem,4.6vw,3rem); line-height:1.1; margin:.4rem 0 .8rem;
}
.post__meta{ color:var(--ink-2); display:flex; flex-wrap:wrap; gap:.4rem 1rem; }

.post__body{
  max-width:var(--prose); padding-bottom:clamp(2rem,4vw,3rem);
  /* Long identifiers, ARNs and reference URLs have no break opportunity of
     their own; without this they push the whole page sideways on a phone. */
  overflow-wrap:break-word;
}
.post__body h2{ font-size:1.5rem; margin:2.2em 0 .5em; }
.post__body h3{ font-size:1.2rem; margin:1.8em 0 .4em; }
.post__body h2,.post__body h3{ font-family:var(--serif); font-weight:400; }
.post__body ul,.post__body ol{ padding-left:1.4em; }
.post__body blockquote{
  margin:1.6em 0; padding-left:1em; border-left:2px solid var(--accent);
  color:var(--ink-2);
}
.post__body code{
  background:var(--paper-2); padding:.1em .35em; border:1px solid var(--rule);
}
.post__body pre{
  background:var(--paper-2); border:1px solid var(--rule);
  padding:.9rem 1rem; overflow-x:auto; font-size:.82rem; line-height:1.55;
  margin:1.6em 0;
}
.post__body pre code{ background:none; border:0; padding:0; }
.post__body table{ border-collapse:collapse; width:100%; font-size:.92em; margin:1.6em 0; }
.post__body th,.post__body td{ border-bottom:var(--hair); padding:.5em .6em; text-align:left; vertical-align:top; }
.post__body th{ font-family:var(--mono); font-size:.8rem; text-transform:uppercase; letter-spacing:.08em; }
.post__body hr{ margin:2.4em 0; }
.post__body figure{ margin:2em 0; }
.post__foot{ max-width:var(--prose); border-top:var(--hair); padding-top:1.2rem; padding-bottom:3rem; }

/* definition lists: facts, engagement terms */
.specs{ display:grid; gap:0; margin:1.4rem 0 0; max-width:var(--prose); }
.specs > div{ display:grid; gap:.1rem 1.2rem; padding-block:.6rem; border-top:var(--hair); }
@media (min-width:640px){ .specs > div{ grid-template-columns:8rem 1fr; } }
.specs dt{ font-family:var(--mono); font-size:.78rem; text-transform:uppercase; letter-spacing:.1em; color:var(--ink-2); }
.specs dd{ margin:0; font-size:.97em; }

/* table of contents */
.toc{
  display:grid; gap:.3rem 1.6rem; border-top:1px solid var(--rule-2);
  padding-top:1rem; margin-top:2rem; font-family:var(--mono); font-size:.82rem;
}
@media (min-width:700px){ .toc{ grid-template-columns:repeat(2,1fr); } }
.toc a{ display:flex; gap:.7rem; color:var(--ink-2); }
.toc a:hover{ color:var(--accent); }
.toc .toc__no{ color:var(--accent); }

/* ── contact band ────────────────────────────────────────── */

.contact{ background:var(--ink); color:var(--paper); --tint:#8A5320; }
.contact a{ color:var(--paper); }
.contact__inner{
  display:grid; gap:clamp(1.4rem,3vw,2.6rem); padding-block:clamp(2.4rem,5vw,3.6rem);
}
@media (min-width:900px){ .contact__inner{ grid-template-columns:1.4fr 1fr; } }
.contact h2{
  font-family:var(--serif); font-weight:400; color:var(--paper);
  font-size:clamp(1.6rem,3.4vw,2.3rem); line-height:1.14; margin:.5rem 0 1rem;
}
.contact .label{ color:rgba(244,240,229,.7); }
.contact__body{ color:rgba(244,240,229,.78); max-width:var(--prose); }
.contact__actions{ display:flex; flex-wrap:wrap; align-items:center; gap:1rem 1.4rem; margin-top:1.5rem; }
.contact__note{ margin:1.3rem 0 0; font-family:var(--mono); font-size:.78rem; color:rgba(244,240,229,.62); }

/* ── footer / colophon ──────────────────────────────────── */

.footer{ border-top:1px solid var(--rule-2); background:var(--paper); }
.footer__inner{
  display:grid; gap:1.6rem; padding-block:2rem;
}
@media (min-width:800px){ .footer__inner{ grid-template-columns:1.2fr 2fr; } }
.footer__cols{ display:grid; gap:1.4rem; grid-template-columns:repeat(auto-fit,minmax(10rem,1fr)); }
.footer__cols > div{ display:grid; gap:.35rem; align-content:start; }
.footer__h{ margin:0 0 .3rem; color:var(--ink-2); text-transform:uppercase; letter-spacing:.12em; font-size:.74rem; }
.footer a{ color:var(--ink); font-size:.9rem; }
.footer a:hover{ color:var(--accent); }
.footer__note{ font-size:.9rem; color:var(--ink-2); margin:0; }

.colophon{
  border-top:var(--hair); padding-block:1.2rem 2.6rem;
  font-family:var(--mono); font-size:.74rem; line-height:1.8; color:var(--ink-2);
  display:grid; gap:.9rem 2.4rem;
}
@media (min-width:820px){ .colophon{ grid-template-columns:minmax(0,1fr) minmax(0,1.15fr); } }
.colophon p{ margin:0 0 .35rem; }
.colophon__links{ display:flex; flex-wrap:wrap; gap:.2rem 1rem; }
.colophon a{ color:var(--ink-2); text-decoration:underline; text-underline-offset:.2em; }
.weight{ color:var(--accent); }

/* ── 404 ─────────────────────────────────────────────────── */

.blank{ padding-block:clamp(3rem,8vw,6rem); }
.blank pre{ font-family:var(--mono); font-size:.8rem; line-height:1.5; overflow-x:auto; margin:0 0 1.4rem; }

/* ── fit lines ───────────────────────────────────────────── */

.fit{ font-family:var(--mono); font-size:.82rem; color:var(--accent); margin:0 0 1.2rem; }
.fit::before{ content:"→ "; }

/* Prose inside a section is capped to a readable measure. Only bare
   paragraphs are touched, so ledgers, step grids and spec tables keep the
   full width. */
.section > .wrap > p{ max-width:var(--prose); }

/* ── about grid ──────────────────────────────────────────── */

.about{ display:grid; gap:clamp(1.6rem,3.4vw,2.6rem); align-items:start; }
@media (min-width:860px){ .about{ grid-template-columns:minmax(0,1fr) 280px; } }
.about__body p:last-child{ margin-bottom:0; }
.about__side{ display:grid; gap:1.2rem; }
.about__side .specs{ margin:0; }

/* ── specs on the dark contact band ──────────────────────── */

.specs--ink > div{ border-top-color:rgba(244,240,229,.22); }
.specs--ink dt{ color:rgba(244,240,229,.6); }
.specs--ink dd{ color:rgba(244,240,229,.88); }

/* ── guides ──────────────────────────────────────────────
   The 13-part series is wider than an essay because the guides carry config,
   tables and diagrams. Prose keeps the 46rem measure; the blocks that are
   genuinely wide — code, tables, rendered diagrams — get the full wrap and
   scroll inside their own box rather than pushing the page sideways. */

.guide__head, .toc--guide, .guide__nav{ max-width:46rem; }
.guide__body{ max-width:none; }
.guide__body > *{ max-width:46rem; }
.guide__body > pre,
.guide__body > table,
.guide__body > figure.diagram{ max-width:100%; }
.guide__head h1{ font-size:clamp(1.7rem,3.6vw,2.4rem); line-height:1.14; }

.toc--guide{ margin-top:0; margin-bottom:2rem; }
.toc--guide a{ font-size:.8rem; }

/* Wide Markdown tables scroll inside their own box rather than pushing the
   page sideways. */
.post__body table{ display:block; max-width:100%; overflow-x:auto; }

/* ── diagrams ────────────────────────────────────────────
   tools/diagrams.py renders each diagram to SVG at build time, so a diagram   here is one small cached image and no JavaScript. The SVG scales, but text
   below about 10px is not worth showing. Compact diagrams stay at their
   natural size and are centred; wide diagrams stop
   shrinking at 56rem and scroll inside their own frame on narrow screens.

   Do not set width:auto here. The shortcode carries the diagram's intrinsic
   size (data/diagrams.toml) as width/height attributes; width:auto discards
   them, so the lazy SVG has no box until it loads and every figure collapses
   to 0 and shoves the page down when it arrives. Leave width to the attribute
   and let max-width scale it; height:auto keeps the ratio while it does. */

.diagram{ margin:2em 0; }
.diagram__scroll{
  overflow-x:auto; padding:.7rem;
  background:var(--paper-2); border:1px solid var(--rule);
}
.diagram img{
  display:block; height:auto; max-width:max(100%, 56rem);
  margin-inline:auto;
}
@media (max-width:700px){
  .diagram__scroll{ padding:.45rem; }
}
.diagram figcaption{
  display:flex; flex-wrap:wrap; gap:.3rem 1rem; justify-content:space-between;
  margin-top:.55rem; padding-left:.7rem; border-left:2px solid var(--accent);
  font-family:var(--mono); font-size:.76rem; line-height:1.5; color:var(--ink-2);
}
.diagram__zoom{ flex:none; color:var(--accent); }

.guide__nav{
  display:flex; flex-wrap:wrap; justify-content:space-between; gap:.6rem 2rem;
  margin-top:.4rem; padding-top:1rem;
  border-top:1px solid var(--rule-2);
  font-family:var(--mono); font-size:.8rem;
}
.guide__nav a{ color:var(--ink-2); }
.guide__nav a:hover{ color:var(--accent); }
.guide__nav-next{ margin-left:auto; text-align:right; }

.row__no small{ display:block; margin-top:.15rem; color:var(--ink-2); font-size:.68rem; }
.ledger__foot{ margin-top:1.2rem; }

/* ── print ───────────────────────────────────────────────── */

@media print{
  .masthead,.contact__actions,.footer__cols{ display:none; }
  .diagram__scroll{ overflow:visible; }
  .diagram img{ max-width:100%; }
  body{ background:#fff; color:#000; font-size:11pt; }
  .plate{ background:#fff; }
  a::after{ content:" (" attr(href) ")"; font-size:.75em; color:#444; }
}
