/* POST NO BILLS — typographic baseline.
   Ink on warm paper, quiet green accents. No other colors, no
   border-radius decoration, no box shadows, no icons, no emoji.
   See AGENTS.md for the design charter this stylesheet serves. */

:root {
  /* paper tokens equal the measured means of the baked bill assets
     (scripts/texture/bake-bill.mjs prints them) — the flat color and the
     texture must agree or the tile edge shows (charter: blend modes and
     images are never load-bearing for base color) */
  --paper: #e9e3d4;
  --ink: #24211b;
  --ink-faded: #6f6a5e;
  --green: #2c4342;
  --paper-deep: #dcd5c3;
  --hairline: rgba(36, 33, 27, 0.18);
  /* type set directly on the wall — chalk, never pure white
     (reference/street-observations.md); dim tone holds ≥4.5:1 on the
     wall's measured field mean #273d38 */
  --chalk: #e9e6da;
  --chalk-dim: #a9b3a6;

  --font-serif: Charter, 'Iowan Old Style', Georgia, 'Times New Roman', serif;
  --font-mono: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
}

/* ------------------------------------------------------------------ */
/* Reset + base                                                       */
/* ------------------------------------------------------------------ */

* {
  box-sizing: border-box;
}

html {
  background: var(--paper);
}

body {
  margin: 0;
  font-family: var(--font-serif);
  font-size: 1.1875rem;
  line-height: 1.55;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: auto;
}

@media (max-width: 480px) {
  body {
    font-size: 1.0625rem;
  }
}

img {
  max-width: 100%;
  height: auto;
  display: block;
}

/* ------------------------------------------------------------------ */
/* Mono metadata style — dates, note labels, footer                    */
/* ------------------------------------------------------------------ */

.post-date,
.note-label,
.colophon,
th {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-faded);
}

/* ------------------------------------------------------------------ */
/* Links in prose                                                     */
/* ------------------------------------------------------------------ */

.post-body a,
.note a {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-color: var(--green);
  text-underline-offset: 2px;
  text-decoration-thickness: 1px;
}

.post-body a:hover,
.note a:hover {
  color: var(--green);
}

/* ------------------------------------------------------------------ */
/* Headings, dek/lede                                                 */
/* ------------------------------------------------------------------ */

.post-title {
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: clamp(1.9rem, 5.5vw, 2.4rem);
  line-height: 1.12;
  margin: 0.35em 0 0;
}

.post-dek {
  font-family: var(--font-serif);
  font-style: italic;
  color: var(--ink-faded);
}

.post-dek {
  font-size: 1.0625rem;
  margin: 1rem 0 0;
}

.post-body h2 {
  font-family: var(--font-serif);
  font-weight: 700;
  font-size: 1.35rem;
  margin-top: 2.2em;
  margin-bottom: 0.6em;
}

.post-body h3 {
  font-family: var(--font-serif);
  font-weight: 700;
  font-size: 1.05rem;
  margin-top: 1.8em;
  margin-bottom: 0.5em;
}

/* ------------------------------------------------------------------ */
/* Home — the empty wall                                               */
/* ------------------------------------------------------------------ */

/* The asset carries the true paint color (assets/PROVENANCE.md); the
   background-color underneath is its measured field mean, shown only
   while the image loads or if it ever fails. Tile at 1200 CSS px —
   inside the 1050–1400 range the master was baked for. */
.wall-page {
  background-color: #273d38;
  background-image: url('/assets/plywood-green.webp');
  background-size: 1200px auto;
  min-height: 100dvh;
}

/* The stencil is paint on the wall, not a logo floating over it:
   composited as-is (the asset's alpha carries all paint texture — no
   blend mode, per PROVENANCE), placed like someone sprayed it at eye
   height. Stacked lockup top-left on wide viewports; one-line strip on
   narrow ones. */
/* Masthead band: the POST NO BILLS stencil plus the small stenciled
   wayfinding words (About / Archive / RSS) — all one authority's paint.
   The band owns the container geometry; the marks just hang on it. */
.wall-head {
  max-width: 50rem;
  margin-inline: auto;
  padding: 1.5rem 1.25rem 0;
}

.stencil {
  margin: 0;
  padding: 0;
}

.wall-ways {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  margin-top: 1.1rem;
}

.wall-ways a {
  display: inline-block;
}

.wall-ways img {
  height: 0.8125rem;
  width: auto;
  opacity: 0.72;
}

.wall-ways a:hover img,
.wall-ways a:focus-visible img {
  opacity: 0.95;
}

.wall-ways a:focus-visible {
  outline: 1px solid var(--chalk-dim);
  outline-offset: 4px;
}

.stencil img {
  display: block;
  width: min(50vw, 200px);
  height: auto;
  /* paint soaks into the wood: wall grain shows through the chalk-white
     (reference/street-observations.md — "never pure white"). Plain
     opacity, no blend mode, so nothing breaks if compositing degrades. */
  opacity: 0.78;
}

/* Someone tagged the wall below the postings. Decoration only: quieter
   than the dim text (0.4 opacity keeps it below reading salience), off
   the text grid on purpose — a hand, not a layout. Deterministic, one
   instance, never beside a title. */
.wall-tag {
  max-width: 50rem;
  margin: 1rem auto 0;
  padding: 0 1.25rem 3.5rem;
}

.wall-tag::after {
  content: '';
  display: block;
  /* capped at 28vw: at 42vw on phones the tag rivaled the masthead's
     footprint (2026-07-12 composition critique) */
  width: min(230px, 28vw);
  aspect-ratio: 800 / 482;
  margin-left: 58%;
  background: url('/assets/tag-bill.webp') no-repeat center / contain;
  opacity: 0.4;
  transform: rotate(-3deg);
}

/* Wide viewports with real margin room: the tag moves beside the column
   at hand height — visible in the first viewport at natural laptop
   heights instead of below a content-length-dependent fold (Bill,
   2026-07-13). Below 1360px there's no margin to hold it, so it stays
   in flow after the list. 1360 = container 50rem + 2×(tag 230px + gap). */
@media (min-width: 1360px) {
  .wall-tag {
    position: absolute;
    top: 30rem;
    left: calc(50% + 26rem);
    margin: 0;
    padding: 0;
    max-width: none;
  }

  .wall-tag::after {
    width: 230px;
    margin-left: 0;
  }
}

/* A buff patch on the left periphery: someone's tag got rolled over
   with a fresher batch of the same green (reference/street/fence-corner-
   buff-patch-diamond-porthole-fdny.jpg). The material is the real wall
   showing through a plain-alpha color veil — grain continuity is what
   makes a buff read as a buff; no blend mode (charter), no image seam.
   Square to the wall like roller work; a second offset pass above.
   Same width gate as the tag: it needs true margin room. */
@media (min-width: 1360px) {
  /* The veil is a generated roller-pass density map extracted to alpha
     (assets/PROVENANCE.md) — real streak texture, and the wall's grain
     reads through everywhere because nothing in it is opaque. */
  .wall-buff {
    position: absolute;
    top: 12rem;
    left: calc(50% - 39rem);
    width: 8.5rem;
    aspect-ratio: 560 / 1248;
    background: url('/assets/buff-veil.webp') no-repeat center / contain;
  }
}

@media print {
  .wall-tag,
  .wall-ways,
  .wall-buff {
    display: none;
  }
}

/* Wide viewports: masthead left, wayfinding words right, bottoms shared
   like signage painted along one line. The one-line lockup spans most of
   the title column: width carries masthead presence (2026-07-12
   critique) without the retired stacked form's vertical tax. */
@media (min-width: 640px) {
  .wall-head {
    padding: 2.5rem 1.25rem 0;
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 2rem;
  }

  .wall-ways {
    margin-top: 0;
    padding-bottom: 0.2rem;
  }

  .stencil img {
    /* trimmed from 30vw/460 once the wayfinding words joined the band —
       the line reads as one piece of signage now, and the masthead was
       shouting over it (Bill, 2026-07-13) */
    width: clamp(280px, 24vw, 380px);
  }
}

/* The index is type on the paint — no paper, no container. One register
   per entry, one text size (hierarchy by face/color/position only, per
   the Armin Ronacher index this is calibrated against: title = body
   size, dates as marginalia in a left gutter, one line-height between
   entries, measure ~67ch, column centered). Texture stays legible-quiet
   behind it: display type only, never body text (charter). */
.wall-index {
  max-width: 50rem;
  margin-inline: auto;
  padding: 2.5rem 1.25rem 4rem;
}

.wall-index ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

.wall-index li + li {
  margin-top: 1.5rem;
}

.wall-index time {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  line-height: 1.6;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--chalk-dim);
  margin-bottom: 0.2rem;
}

.wall-index .index-line {
  margin: 0;
  line-height: 1.5;
}

.wall-index a {
  color: var(--chalk);
  text-decoration: none;
}

.wall-index a:hover {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

.wall-index .index-dek {
  color: var(--chalk-dim);
}

/* The exit to the archive, in the dates' register — apparatus, not an
   entry. Aligned with the titles on wide viewports. */
.index-more {
  margin: 2.5rem 0 0;
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.index-more a {
  color: var(--chalk-dim);
  text-decoration: none;
}

.index-more a:hover {
  color: var(--chalk);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

.stencil a {
  display: inline-block;
}

/* Wide viewports: dates move to a marginalia gutter so titles align
   flush and the reading column carries only one voice. */
@media (min-width: 640px) {
  .wall-index {
    padding-block: 3rem 4rem;
  }

  .wall-index li {
    display: grid;
    grid-template-columns: 8.5rem 1fr;
    column-gap: 1.5rem;
  }

  .wall-index time {
    text-align: right;
    margin-bottom: 0;
    /* mono cap-height sits high; nudge to share the title's baseline */
    padding-top: 0.4rem;
  }

  .index-more {
    /* flush with the titles: gutter + gap */
    margin-left: 10rem;
  }
}

@media print {
  .wall-page {
    background: #fff;
  }

  .stencil img {
    /* chalk-white ink vanishes on paper; let alt text carry it */
    display: none;
  }

  .stencil::after {
    content: 'POST NO BILLS';
    font-family: var(--font-mono);
    letter-spacing: 0.35em;
    color: #000;
  }

  /* chalk tones vanish on white paper; the index prints as ink */
  .wall-index a {
    color: #000;
  }

  .wall-index time,
  .wall-index .index-dek {
    color: #444;
  }
}

/* ------------------------------------------------------------------ */
/* The posted bill — the article is a sheet wheatpasted to the wall    */
/* (AGENTS.md, "The Posted BILL"). The sheet is a machine-cut          */
/* rectangle: no shadow, no curl, no border — the paper meets the      */
/* paint directly and the tonal step is the edge. Texture lives at     */
/* the perimeter (paste bands baked from the master, alpha-fading      */
/* into the field); the central reading field is the near-flat tile.   */
/* ------------------------------------------------------------------ */

.bill-street {
  padding: 0 1.1rem 4.5rem;
}

.bill {
  position: relative;
  max-width: 46rem;
  margin: 2.75rem auto 0;
  padding: clamp(1.7rem, 6vw, 3rem) clamp(1.3rem, 5.5vw, 3.4rem) clamp(1.3rem, 5vw, 2.4rem);
  color: var(--ink);
  background-color: var(--paper);
  background-image:
    url('/assets/bill-edge-top.webp'),
    url('/assets/bill-edge-bottom.webp'),
    url('/assets/bill-paper.webp');
  background-repeat: no-repeat, no-repeat, repeat;
  background-position: top center, bottom center, 0 0;
  /* tile at 360 CSS px = the 720px asset at 2x; bands span the sheet */
  background-size: 100% auto, 100% auto, 360px 360px;
}

/* Edge events — local interruptions of the machine cut (masters and
   extraction: bake-bill.mjs). Which events a bill carries and where is
   seeded per slug by build.mjs, which emits one span per event — every
   bill keeps its own wear, forever. Decal cut lines sit at fixed
   fractions, so the negative offsets hang each exactly over the sheet
   boundary. The nick's bite is pre-filled with the shipped wall tile
   (both modes) — no CSS masking. */
.bill-wear {
  position: absolute;
  pointer-events: none;
  background-repeat: no-repeat;
  background-position: center;
  background-size: 100% 100%;
}

.wear-crinkle-r {
  right: -25px;
  width: 100px;
  height: 80px;
  background-image: url('/assets/bill-crinkle.webp');
}

.wear-crinkle-l {
  left: -25px;
  width: 100px;
  height: 80px;
  background-image: url('/assets/bill-crinkle-left.webp');
}

.wear-fray {
  bottom: -30px;
  width: 160px;
  height: 60px;
  background-image: url('/assets/bill-fray.webp');
}

.wear-nick {
  top: -15px;
  right: -15px;
  width: 110px;
  height: 110px;
  background-image: url('/assets/bill-nick.webp');
}

/* The bill hangs slightly off plumb-center — deterministic per slug
   (--bill-drift is baked into the HTML by build.mjs). Only where the
   wall has real margin room; on narrow viewports the sheet needs every
   pixel of measure. */
@media (min-width: 900px) {
  .bill {
    transform: translateX(var(--bill-drift, 0px));
  }
}

/* Drop cap — typographic and restrained (AGENTS.md), only in engines
   with real initial-letter support (WebKit prefixed, Chromium plain);
   elsewhere the paragraph simply opens. Uses the wall's green: painted
   display ink, one letter's worth. */
@supports (initial-letter: 3) or (-webkit-initial-letter: 3) {
  .post-body > p:first-of-type::first-letter {
    -webkit-initial-letter: 3;
    initial-letter: 3;
    margin-right: 0.45em;
    color: var(--green);
  }

  @media (max-width: 480px) {
    .post-body > p:first-of-type::first-letter {
      -webkit-initial-letter: 2;
      initial-letter: 2;
      margin-right: 0.35em;
    }
  }
}

/* Dark mode: the same bill under less light (AGENTS.md) — near-black
   hunter-green wall, muted warm putty paper, dark charcoal ink. The
   wall dims through a plain alpha veil (no blend modes); the paper
   swaps to the dark bake, whose measured mean is the --paper value. */
@media (prefers-color-scheme: dark) {
  .post-page {
    --paper: #a8a193;
    --paper-deep: #98917e;
    --ink: #26221b;
    --ink-faded: #3d382d;
    --hairline: rgba(30, 26, 20, 0.34);
    background-color: #142019;
    background-image:
      linear-gradient(rgba(6, 13, 11, 0.55), rgba(6, 13, 11, 0.55)),
      url('/assets/plywood-green.webp');
  }

  .post-page .bill {
    background-image:
      url('/assets/bill-edge-top-dark.webp'),
      url('/assets/bill-edge-bottom-dark.webp'),
      url('/assets/bill-paper-dark.webp');
  }

  .post-page .wear-crinkle-r {
    background-image: url('/assets/bill-crinkle-dark.webp');
  }

  .post-page .wear-crinkle-l {
    background-image: url('/assets/bill-crinkle-left-dark.webp');
  }

  .post-page .wear-fray {
    background-image: url('/assets/bill-fray-dark.webp');
  }

  .post-page .wear-nick {
    background-image: url('/assets/bill-nick-dark.webp');
  }
}

.post-body p {
  margin: 1.1em 0;
}

.post-body ul,
.post-body ol {
  margin: 1.1em 0;
  padding-left: 1.4em;
}

.post-body li + li {
  margin-top: 0.35em;
}

.post-body blockquote {
  margin: 1.6em 0;
  margin-left: 0;
  padding-left: 1rem;
  border-left: 2px solid var(--green);
  font-style: normal;
  color: var(--ink-faded);
}

.post-body blockquote p {
  margin: 0.4em 0;
}

.post-body code {
  font-family: var(--font-mono);
  font-size: 0.85em;
  background: var(--paper-deep);
  padding: 0.08em 0.3em;
}

.post-body pre {
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  line-height: 1.5;
  background: var(--paper-deep);
  padding: 0.9rem 1rem;
  overflow-x: auto;
  border: 1px solid var(--hairline);
  margin: 1.6em 0;
}

.post-body pre code {
  background: none;
  padding: 0;
  font-size: 1em;
}

.table-wrap {
  overflow-x: auto;
  margin: 1.6em 0;
}

.post-body table {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--font-serif);
  font-size: 0.9375rem;
}

.post-body th,
.post-body td {
  text-align: left;
  padding: 0.5em 0.8em 0.5em 0;
  vertical-align: top;
}

.post-body thead th {
  border-top: 1px solid var(--hairline);
  border-bottom: 1px solid var(--hairline);
}

.post-body tbody tr:last-child td {
  border-bottom: 1px solid var(--hairline);
}

.post-body aside.note {
  background: var(--paper-deep);
  border: 1px solid var(--hairline);
  padding: 1rem 1.15rem;
  margin-block: 1.8rem;
  font-size: 0.9375rem;
}

.post-body aside.note p {
  margin: 0.6em 0;
}

.post-body aside.note p:first-child {
  margin-top: 0;
}

.post-body aside.note p:last-child {
  margin-bottom: 0;
}

.post-body .note-label {
  margin: 0 0 0.6em;
}

.post-body figure {
  margin: 1.8em 0;
}

.post-body figcaption {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  text-transform: none;
  letter-spacing: 0.08em;
  color: var(--ink-faded);
  margin-top: 0.5rem;
}

.post-body hr {
  border: none;
  border-top: 1px solid var(--hairline);
  max-width: 8rem;
  margin: 2.5rem auto;
}

/* Footnotes (emitted by marked-footnote) */

.post-body .footnotes {
  margin-top: 2.5rem;
  padding-top: 1.2rem;
  border-top: 1px solid var(--hairline);
  font-size: 0.875rem;
  color: var(--ink-faded);
}

.post-body .footnotes ol {
  padding-left: 1.2em;
}

.post-body .footnotes li {
  margin: 0.6em 0;
}

.post-body .footnotes p {
  margin: 0;
}

.post-body [data-footnote-ref] {
  font-family: var(--font-mono);
  font-size: 0.7em;
  color: var(--green);
  text-decoration: none;
}

.post-body [data-footnote-backref] {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  color: var(--ink-faded);
  text-decoration: none;
}

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

/* ------------------------------------------------------------------ */
/* Footer                                                              */
/* ------------------------------------------------------------------ */

.post-footer {
  margin-top: 3rem;
  padding-top: 1.2rem;
  border-top: 1px solid var(--hairline);
}

.post-footer .colophon {
  margin: 0;
}

/* ------------------------------------------------------------------ */
/* Print                                                               */
/* ------------------------------------------------------------------ */

@media print {
  html,
  body {
    background: #fff;
    color: #000;
  }

  /* the bill prints as a clean document: no wall, no paper texture */
  .post-page {
    --paper: #fff;
    --ink: #000;
    --ink-faded: #444;
  }

  .bill {
    background: #fff;
    padding: 0;
    max-width: none;
    transform: none;
  }

  .bill-wear {
    display: none;
  }

  .bill-street {
    padding: 0;
  }

  .post-body pre,
  .post-body aside.note {
    background: #fff;
  }
}
