/* Blog: /blog (index) and /blog/<slug>/ (post)
   The shared chrome, type scale and colour tokens all come from styles.css.
   Both views are server-rendered from /data/blog.json; nothing here assumes a
   fixed number of posts or a fixed post shape.

   Index rows are stamped with the post's date rather than numbered. A serial
   number would only be counting; the date is the one ordering a reader of a
   blog actually uses. */

/* ===========================================================================
   INDEX (/blog)
   ========================================================================= */

.blog-head { padding-bottom: 0; }

.blog-meta {
  margin-top: 1.4rem;
  font-family: var(--font-mono);
  font-size: .8rem;
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.blog-list { padding-top: 2.6rem; }

.post-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1.4rem;
  align-items: start;
  padding-block: clamp(2rem, 4vw, 2.8rem);
  border-top: 1px solid var(--line-2);
}
.post-row:first-child { border-top: 0; padding-top: 0; }

/* A post with a cover gets a second column once there is room for one. Without
   :has support the thumbnail simply stacks under the text, which still reads. */
@media (min-width: 720px) {
  .post-row:has(.post-row-cover) { grid-template-columns: minmax(0, 1fr) 210px; gap: 2.2rem; }
}

.post-row-text { min-width: 0; }

.post-row-stamp {
  display: flex; align-items: center; gap: .55rem;
  margin-bottom: .85rem;
  font-family: var(--font-mono);
  font-size: .74rem; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--ink-3);
}
.post-row-dot { color: var(--accent); }

.post-row-title {
  font-family: var(--font-display); font-weight: 440;
  font-size: clamp(1.5rem, 3vw, 2.05rem);
  line-height: 1.12; letter-spacing: -.02em;
  max-width: 24ch;
  transition: color .25s var(--ease);
}
.post-row:hover .post-row-title,
.post-row:focus-visible .post-row-title { color: var(--accent); }

.post-row-summary {
  margin-top: .75rem;
  font-family: var(--font-sans); font-size: 1.02rem; line-height: 1.6;
  color: var(--ink-2); max-width: 58ch;
}

.post-row-tags { margin-top: 1rem; display: flex; flex-wrap: wrap; gap: .45rem; }
.post-row-tags .tag { font-size: .72rem; padding: .3em .6em; }

.post-row-more { margin-top: 1.1rem; }
.post-row:hover .post-row-more { color: var(--accent); }
.post-row:hover .post-row-more .tip { transform: translateX(.3em); }

.post-row-cover {
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--bg-2); overflow: hidden; aspect-ratio: 4 / 3;
}
.post-row-cover img {
  width: 100%; height: 100%; object-fit: cover;
  transition: transform .5s var(--ease);
}
.post-row:hover .post-row-cover img { transform: scale(1.04); }

@media (prefers-reduced-motion: reduce) {
  .post-row-cover img, .post-row-more .tip { transition: none; }
  .post-row:hover .post-row-cover img { transform: none; }
}

/* ===========================================================================
   POST (/blog/<slug>/)
   ========================================================================= */

/* Wider than the reading measure on purpose. Body text is capped at
   var(--measure) further down, so line length is unaffected; the extra width
   exists for tables and code blocks, which are scanned rather than read and
   suffer badly when squeezed to 68ch. */
.post-wrap { max-width: 900px; }

.post-topbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap;
  margin-bottom: clamp(1.8rem, 5vw, 3rem);
}

.post-head { margin-bottom: clamp(1.6rem, 4vw, 2.4rem); }

.post-stamp {
  display: flex; align-items: center; gap: .55rem;
  margin-bottom: 1.1rem;
  font-family: var(--font-mono);
  font-size: .76rem; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--ink-3);
}

.post-title {
  font-family: var(--font-display); font-weight: 430;
  font-size: clamp(2rem, 5vw, 3.3rem);
  line-height: 1.05; letter-spacing: -.028em;
  font-optical-sizing: auto;
  max-width: 22ch; margin-bottom: 1.2rem;
}

.post-head .lede { max-width: 46ch; }
.post-head-tags { margin-top: 1.5rem; }

/* Height is capped so a portrait photo cannot push the article three screens
   down. A landscape image still runs the full column; only a tall one shrinks,
   keeping the crop the author chose rather than cropping it again. */
.post-cover {
  margin-block: clamp(1.6rem, 4vw, 2.6rem);
  width: fit-content; max-width: 100%; margin-inline: auto;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--bg-2); overflow: hidden;
}
.post-cover img { width: auto; max-width: 100%; max-height: 70vh; height: auto; }

/* ---- Body -----------------------------------------------------------------
   .prose (styles.css) already sets the reading face, size, measure and the
   p + p rhythm. Everything below is the block furniture markdown can produce
   on top of that. */

/* .prose caps the whole block at the reading measure, which is right for text
   and wrong for a wide table or a code block. Move the cap onto the text
   children instead: prose keeps its 68ch line length, tables/code/figures run
   the full column, and everything still shares one left edge. */
.post-body { max-width: none; }
.post-body > p,
.post-body > h2,
.post-body > h3,
.post-body > h4,
.post-body > ul,
.post-body > ol,
.post-body > blockquote,
.post-body > hr { max-width: var(--measure); }

.post-body h2, .post-body h3, .post-body h4 {
  letter-spacing: -.015em; line-height: 1.16;
  scroll-margin-top: 5.5rem;   /* clears the sticky nav on a #heading deep link */
}

.post-body h2 {
  font-family: var(--font-display); font-weight: 460;
  font-size: clamp(1.55rem, 3.4vw, 2rem);
  margin: 2.8rem 0 1rem;
}

/* The one flourish on this page: section headings carry the same mono marker
   the case studies use for their section labels, so an article reads as part
   of the same system rather than as a generic post template. */
.post-body h2::before {
  content: "//";
  font-family: var(--font-mono); font-size: .58em; font-weight: 500;
  letter-spacing: 0; color: var(--accent);
  margin-right: .6em; vertical-align: .14em;
}

.post-body h3 {
  font-family: var(--font-display); font-weight: 470;
  font-size: clamp(1.22rem, 2.6vw, 1.45rem);
  margin: 2.2rem 0 .75rem;
}

.post-body h4 {
  font-family: var(--font-sans); font-weight: 600; letter-spacing: 0;
  font-size: 1.08rem;
  margin: 1.9rem 0 .6rem;
}

.post-body > :first-child { margin-top: 0; }

.post-body hr { margin: 2.6rem 0; border: 0; border-top: 1px solid var(--line); }

.post-list { margin: 1.3rem 0; padding-left: 1.5rem; }
.post-list li { position: relative; }
.post-list li + li { margin-top: .6rem; }

ul.post-list li::before {
  content: ""; position: absolute; left: -1.15rem; top: .68em;
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--accent); opacity: .8;
}

ol.post-list { counter-reset: post-ol; }
ol.post-list li::before {
  counter-increment: post-ol; content: counter(post-ol) ".";
  position: absolute; left: -1.5rem; top: .18em;
  font-family: var(--font-mono); font-size: .76em; color: var(--accent);
}

.post-quote {
  margin: 1.9rem 0; padding-left: 1.3rem;
  border-left: 2px solid var(--accent);
  color: var(--ink-2); font-style: italic;
}
.post-quote p + p { margin-top: 1rem; }

.post-code {
  position: relative;
  margin: 1.7rem 0; padding: 1.15rem 1.2rem;
  background: var(--bg-2); border: 1px solid var(--line-2);
  border-radius: var(--radius-sm);
  overflow-x: auto;
}
/* Reset the inline-code chrome .prose code applies: inside a block it would
   draw a second border around every line. */
.post-code code {
  display: block; white-space: pre;
  font-family: var(--font-mono); font-size: .82rem; line-height: 1.65;
  color: var(--ink); background: none; border: 0; border-radius: 0; padding: 0;
}
.post-code[data-lang]::before {
  content: attr(data-lang);
  position: absolute; top: .55rem; right: .75rem;
  font-family: var(--font-mono); font-size: .62rem;
  letter-spacing: .14em; text-transform: uppercase; color: var(--ink-3);
}

/* Tables. The wrapper is the scroller, so a wide table scrolls inside its own
   box and the page body never scrolls sideways on a phone. Set in the UI face
   rather than the reading face: a table is scanned, not read. */
.post-table-wrap {
  margin: 1.8rem 0;
  overflow-x: auto;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface);
}
.post-table {
  width: 100%; border-collapse: collapse;
  font-family: var(--font-sans);
  font-size: .93rem; line-height: 1.5;
}
.post-table th, .post-table td {
  padding: .7rem .85rem;
  text-align: left; vertical-align: top;
  border-bottom: 1px solid var(--line-2);
}
.post-table th {
  font-family: var(--font-mono);
  font-size: .7rem; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-3); white-space: nowrap;
  background: var(--bg-2);
  border-bottom-color: var(--line);
}
.post-table tbody tr:last-child td { border-bottom: 0; }
.post-table td { color: var(--ink-2); }
.post-table td strong { color: var(--ink); }
.post-table code { font-size: .8em; }

.post-figure { margin: 2.1rem 0; }
.post-figure img {
  width: auto; max-width: 100%; max-height: 70vh; height: auto;
  margin-inline: auto;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--bg-2);
}
.post-figure figcaption {
  margin-top: .7rem;
  font-family: var(--font-sans); font-size: .86rem; line-height: 1.5;
  color: var(--ink-3);
}

/* ---- Foot: who wrote this, and where else to read ------------------------- */

.post-foot {
  margin-top: clamp(2.4rem, 6vw, 3.4rem);
  padding-top: clamp(1.8rem, 4vw, 2.4rem);
  border-top: 1px solid var(--line);
}
.post-foot-note {
  max-width: 48ch; margin-bottom: 1.3rem;
  font-family: var(--font-sans); font-size: 1rem; line-height: 1.6;
  color: var(--ink-2);
}
.post-foot .hero-cta { display: flex; flex-wrap: wrap; gap: .85rem; }

.post-pager {
  margin-top: 2.4rem;
  display: grid; gap: 1rem; grid-template-columns: minmax(0, 1fr);
}
@media (min-width: 640px) {
  .post-pager { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* A newest post has no newer neighbour, so the lone Older link would sit in
     the right-hand column with a gap beside it. Put a lone Newer link there
     instead and let Older keep the left. */
  .post-pager-link.is-next:only-child { grid-column: 2; }
}

.post-pager-link {
  border: 1px solid var(--line); border-radius: var(--radius);
  padding: 1rem 1.15rem; background: var(--surface);
  transition: border-color .25s var(--ease), transform .25s var(--ease),
              box-shadow .25s var(--ease);
}
.post-pager-link:hover {
  border-color: var(--accent); transform: translateY(-2px);
  box-shadow: var(--shadow);
}
.post-pager-link.is-next { text-align: right; }

.post-pager-dir {
  display: block; margin-bottom: .45rem;
  font-family: var(--font-mono); font-size: .7rem;
  letter-spacing: .14em; text-transform: uppercase; color: var(--accent);
}
.post-pager-title {
  font-family: var(--font-display); font-weight: 450;
  font-size: 1.05rem; line-height: 1.25; color: var(--ink);
}

@media (prefers-reduced-motion: reduce) {
  .post-pager-link { transition: none; }
  .post-pager-link:hover { transform: none; }
}

@media (max-width: 760px) {
  .post-body h2 { margin-top: 2.3rem; }
  .post-code { padding: .95rem 1rem; }
}

/* A four-column table on a phone is cramped whatever you do; tightening the
   type and padding fits one more column before the scroll starts. */
@media (max-width: 560px) {
  .post-table { font-size: .85rem; }
  .post-table th, .post-table td { padding: .55rem .6rem; }
  .post-table th { font-size: .64rem; letter-spacing: .08em; }
}
