/* Long-form typography for /blog. Loaded only by blog pages, after site.css —
   it inherits every colour token, font stack and hairline from there and adds
   nothing global. The landing page never downloads it.

   Everything here is scoped to .prose, .post-head or .post-list so it cannot
   reach back into index.html. See AGENTS.md → "Blog". The nav above a post is
   .sitenav and lives in site.css, because the landing page uses it too.

   Rendered posts are written by hand (well — by an LLM; see the publish-post
   skill). There is no build step and no markdown parser at runtime, so this
   file is the contract: the converter emits the elements styled below and
   nothing else. A post needing a new element needs a new rule here first. */

/* ---------- post header ---------- */

.post-head {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 20px;
  padding: clamp(44px, 8vh, 80px) 0 clamp(40px, 6vh, 60px);
  max-width: var(--measure);
}

.post-head h1 {
  font-family: var(--font-display);
  font-size: clamp(2rem, 4.6vw, 2.9rem);
  line-height: 1.1;
  font-weight: 600;
  letter-spacing: -0.015em;
  text-wrap: balance;
}

/* the standfirst — one sentence on why this is worth ten minutes */
.post-head .deck {
  font-size: 1.16rem;
  line-height: 1.5;
  color: var(--ink-soft);
}

/* Same mono-caps-behind-a-tick treatment as .label on the landing page, so a
   post reads as part of the same document set rather than a bolted-on blog. */
.post-meta {
  display: flex;
  align-items: center;
  gap: 12px;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.post-meta::before {
  content: "";
  width: 20px;
  height: 2px;
  background: var(--signal);
  flex: none;
}
.post-meta .dim { color: var(--rule); }

/* ---------- prose ---------- */

.prose {
  max-width: var(--measure);
  padding: clamp(36px, 5vh, 48px) 0 0;
  border-top: 1px solid var(--rule-soft);
  color: var(--ink-soft);
  font-size: 1.075rem;
  line-height: 1.68;
}

/* One rhythm rule for the whole flow. Elements needing more air override it
   below, rather than every element declaring its own top and bottom margin. */
.prose > * + * { margin-top: 1.15em; }

.prose h2 {
  font-family: var(--font-display);
  font-size: clamp(1.45rem, 2.8vw, 1.75rem);
  line-height: 1.2;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink);
  text-wrap: balance;
  /* site.css gives h2 a 22px margin-bottom for the landing page's bands; in a
     prose flow the following paragraph sets its own top margin instead */
  margin: 2.2em 0 0;
}
.prose h2 + * { margin-top: 0.75em; }

.prose h3 {
  font-family: var(--font-display);
  font-size: 1.25rem;
  line-height: 1.3;
  font-weight: 600;
  color: var(--ink);
  text-wrap: balance;
  margin: 1.9em 0 0;
}
.prose h3 + * { margin-top: 0.6em; }

.prose strong { color: var(--ink); font-weight: 600; }

/* Body links are underlined, not colour-only: against --ink-soft body text the
   accent alone is not a reliable signal for everyone. */
.prose a {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 0.18em;
  text-decoration-thickness: 1px;
  text-decoration-color: color-mix(in srgb, var(--accent) 40%, transparent);
}
.prose a:hover { text-decoration-color: var(--accent); }

/* ---------- lists ---------- */

/* Hanging markers, so the text block keeps the page's single left edge — the
   same construction as .symptoms and .steps on the landing page. */
.prose ul,
.prose ol { padding-left: 0; list-style: none; }
.prose li { position: relative; padding-left: 24px; }
.prose li + li { margin-top: 0.6em; }

.prose ul > li::before {
  content: "";
  position: absolute;
  left: 2px;
  top: 0.8em;
  width: 8px;
  height: 1px;
  background: var(--signal);
}

.prose ol { counter-reset: prose-ol; }
.prose ol > li { counter-increment: prose-ol; }
.prose ol > li::before {
  content: counter(prose-ol) ".";
  position: absolute;
  left: 0;
  top: 0;
  font-family: var(--font-mono);
  font-size: 0.82em;
  line-height: 2;
  color: var(--signal);
}

.prose li > ul,
.prose li > ol { margin-top: 0.6em; }

/* ---------- code ---------- */

/* site.css already styles inline `code`; this adds only the tint that would be
   wrong on the landing page's dense mono labels. */
.prose :not(pre) > code {
  background: var(--surface);
  border: 1px solid var(--rule-soft);
  border-radius: 3px;
  padding: 0.1em 0.34em;
}

.prose pre {
  margin: 1.7em 0;
  padding: 18px 20px;
  background: var(--surface);
  border: 1px solid var(--rule-soft);
  border-left: 2px solid var(--rule);
  overflow-x: auto;          /* never let a long line widen the page */
  -webkit-overflow-scrolling: touch;
}
.prose pre code {
  font-family: var(--font-mono);
  font-size: 0.845rem;
  line-height: 1.65;
  color: var(--ink);
  white-space: pre;
  background: none;
  border: 0;
  padding: 0;
}

/* ---------- figures ---------- */

/* Diagrams are pre-rendered once per colour scheme by diagrams/compile.sh and
   picked with <picture>; both files are transparent so --ground shows through.

   That swap keys off prefers-color-scheme, which today is the only thing that
   decides the palette — site.css also defines :root[data-theme="..."] blocks,
   but nothing sets the attribute. If a theme toggle is ever added, <picture>
   will not follow it: the diagram would stay on the OS scheme while the rest
   of the page flipped. Swap to two <img>s toggled by CSS at that point. */
/* Diagrams read better wider than the text column, so a figure breaks out of
   --measure and runs toward the .wrap gutter instead. .prose is left-aligned
   inside .wrap, so the extra width spills to the right; the max-width keeps
   that spill inside the gutter at every viewport rather than scrolling the
   page sideways.

   The subtraction is .wrap's own padding (32px a side here, 22px below 720px)
   plus, on desktop, ~18px of slack: 100vw includes the classic scrollbar on
   platforms that have one, so without the slack a mid-width Windows window
   gets a diagram a scrollbar wider than the page. Phones use overlay
   scrollbars, so the narrow rule subtracts the padding alone. */
.prose figure {
  margin: 2.4em 0;
  width: 56rem;
  max-width: calc(100vw - 82px);
}
.prose figure img,
.prose figure svg {
  display: block;
  width: 100%;
  height: auto;
}
.prose figcaption {
  margin-top: 12px;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  line-height: 1.55;
  letter-spacing: 0.04em;
  color: var(--ink-faint);
}

/* ---------- quotes, rules, tables ---------- */

.prose blockquote {
  margin: 1.7em 0;
  padding-left: 22px;
  border-left: 2px solid var(--signal);
  font-family: var(--font-display);
  font-size: 1.14rem;
  line-height: 1.45;
  color: var(--ink);
}
.prose blockquote p + p { margin-top: 0.7em; }

.prose hr {
  margin: 2.6em 0;
  border: 0;
  border-top: 1px solid var(--rule-soft);
}

.prose table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.95rem;
}
.prose thead th {
  text-align: left;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  font-weight: 500;
  color: var(--ink);
  padding: 0 16px 10px 0;
  border-bottom: 1px solid var(--rule);
}
.prose tbody td {
  padding: 11px 16px 11px 0;
  border-bottom: 1px solid var(--rule-soft);
  vertical-align: top;
}
.prose tbody tr:last-child td { border-bottom: 0; }

/* A table is the one thing in a post likely to refuse to fit. Wrap it in
   <div class="scroll-x"> and it scrolls instead of the page doing so. */
.scroll-x { overflow-x: auto; -webkit-overflow-scrolling: touch; }

/* ---------- end of post ---------- */

/* A strip between the article and the CTA: a hairline above, the section's own
   heavier --ink rule below. The bottom margin is what keeps the link off that
   second rule — without it the two collide and the link looks underlined twice.
   Full width, like every other rule on the site; only text is measured. */
.post-end {
  margin: clamp(44px, 6vh, 64px) 0 clamp(36px, 5vh, 48px);
  padding-top: 22px;
  border-top: 1px solid var(--rule-soft);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
}
.post-end a {
  color: var(--ink-soft);
  text-decoration: none;
  border-bottom: 1px solid var(--rule);
  padding-bottom: 2px;
}
.post-end a:hover { color: var(--accent); border-color: var(--accent); }

/* ---------- index listing ---------- */

.post-list {
  display: flex;
  flex-direction: column;
  border-top: 1px solid var(--rule-soft);
}

/* One hairline-separated row per post, the same construction as .work on the
   landing page. Only the title is a link — a full-row hit target would swallow
   text selection. */
/* The rule spans the page and the text stays measured, matching how every
   .band on the landing page is drawn — so the cap goes on the children, not
   on the <article>, or the bottom rule would stop short of the top one. */
.post-list article {
  padding: 30px 0;
  border-bottom: 1px solid var(--rule-soft);
}
.post-list article > * { max-width: var(--measure); }
.post-list .when {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: 10px;
}
.post-list h2 {
  font-size: clamp(1.35rem, 2.6vw, 1.65rem);
  margin-bottom: 10px;
}
.post-list h2 a {
  color: var(--ink);
  text-decoration: none;
  background-image: linear-gradient(var(--accent), var(--accent));
  background-size: 0 1px;
  background-repeat: no-repeat;
  background-position: 0 100%;
  transition: background-size 0.22s ease;
}
.post-list h2 a:hover { color: var(--accent); background-size: 100% 1px; }
.post-list p { color: var(--ink-soft); }

.post-list .empty {
  padding: 30px 0;
  color: var(--ink-faint);
}

@media (prefers-reduced-motion: reduce) {
  .post-list h2 a { transition: none; }
}

/* ---------- responsive ---------- */

@media (max-width: 720px) {
  .prose { font-size: 1.0125rem; }
  .prose figure { max-width: calc(100vw - 44px); }
  .prose pre { padding: 14px 16px; }
  .prose pre code { font-size: 0.8rem; }
  .post-head { gap: 16px; }
  .post-list article { padding: 24px 0; }
}
