/* ════════════════════════════════════════════════════════════════════
   PAGE — SHOP-JOURNAL (blog) · index + post template, ONE shared sheet.
   Lane: page-blog.html (index) + page-blog-post.html (post) sharing this
   css + js/pages/blog.js.

   Authority: picks.json page:blog ("G001 as-is"; optional graft = the
   related-resources sidebar from G003; truth hazard = invented author
   "Mike/Jason Schold" — REAL names only, Mark Seybold / Rachel Richardson)
   + WOW_CONTRACTS page:blog + DESIGN.md + the locked board slice
   (section-page-blog.jpg = the POST page).

   All selectors scoped under .blog-index / .blog-post (page-root classes on
   <main>) so nothing leaks into the shared shell. Palette from tokens.css ONLY:
     --base    #222222  Shop-Floor Charcoal (the field — quietest surface on site)
     --accent  #C2231B  Signal Red (the ONE red — dateline tick, reading gauge,
                        pull-quote glow, stripe under the head; NEVER a field)
     --breath  #E9E6E1  Primer Gray (body text on dark)
     --support #B7BCC1  Polished Steel (mono labels, hairlines, captions)
     --ink-deep #141414 (raised plates / seams)
   Radius 0 = machined edge everywhere (stamped-steel journal plates).
   ════════════════════════════════════════════════════════════════════ */

/* Page root: the dark charcoal field. The subpage <main> gets its own top pad
   to clear the fixed nav (the homepage hero handles this itself; subpages start
   with a real section, so they must offset --nav-h). */
.blog-index,
.blog-post {
  background: var(--ink-900);
  color: var(--text-on-dark);
  overflow: clip;
}

/* consistent one-grade photo look site-wide (DESIGN.md photography treatment:
   slight desat + warm lift — cohesion across era-variant shop photos). */
.blog-index img,
.blog-post img {
  filter: saturate(0.92) brightness(1.02) contrast(1.02);
}

/* ─────────────────────────────────────────────────────────────────────
   SHARED PRIMITIVES — the journal register (dateline eyebrow, steel plate,
   the machined red tick). Used by both index and post.
   ───────────────────────────────────────────────────────────────────── */

/* dateline eyebrow — Plex Mono caps + steel hairline lead-in (DESIGN.md
   text system: eyebrows are the engineering-datasheet register). */
.jrnl-eyebrow {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  font-family: var(--font-mono);
  font-size: var(--step--1);
  font-weight: 500;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--slate-400);
}
.jrnl-eyebrow__rule {
  display: inline-block;
  width: clamp(1.5rem, 3.5vw, 2.6rem);
  height: 1px;
  background: var(--slate-400);
  flex: none;
  opacity: 0.8;
}

/* ════════════════════════════════════════════════════════════════════
   INDEX — "SHOP-JOURNAL"
   A masthead + a grid of stamped journal-page date plates. Alive at t0 via a
   quiet tungsten ink-breath on each plate's dateline tick; plate-press hover.
   ════════════════════════════════════════════════════════════════════ */

/* ---- masthead ---- */
.blog-index__masthead {
  padding-block: calc(var(--nav-h) + var(--space-l)) var(--space-l);
  border-bottom: 1px solid var(--ink-700);
}
.blog-index__masthead-inner { max-width: 52rem; }

.blog-index__title {
  font-family: var(--font-display);
  font-weight: 800;
  text-transform: uppercase;
  font-size: var(--step-hero);
  line-height: 0.9;
  letter-spacing: 0.004em;
  color: var(--breath);
  margin-top: var(--space-s);
}
/* the one thin Signal-Red service-stripe regrip under the masthead head
   (DESIGN.md rhythm plan: red as thin stripe, never a field). */
.blog-index__stripe {
  display: block;
  width: clamp(3.5rem, 8vw, 5.5rem);
  height: 4px;
  margin-top: var(--space-m);
  background: var(--accent);
  border-radius: var(--radius);
}
.blog-index__lede {
  margin-top: var(--space-m);
  max-width: 42rem;
  font-size: var(--step-1);
  line-height: 1.55;
  color: var(--slate-300);
}

/* ---- the journal body: entries rail + related-resources sidebar (G003 graft,
   re-materialized in steel — never the cream/serif register of the mockup). ---- */
.blog-index__body {
  display: grid;
  grid-template-columns: minmax(0, 1fr) clamp(16rem, 24vw, 20rem);
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: start;
  padding-block: var(--space-xl);
}

/* ════════════════════════════════════════════════════════════════════
   FEATURED entry — the flagship post, a wide steel journal plate with its
   own documentary photo. Sits above the grid. (T2.1/T2.5 — the most
   important entry reads biggest; content-fit sizing.)
   ════════════════════════════════════════════════════════════════════ */
.jrnl-feature {
  position: relative;
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  background: var(--ink-800);
  border: 1px solid var(--ink-700);
  border-radius: var(--radius);
  overflow: hidden;
  margin-bottom: var(--space-l);
  isolation: isolate;
  transition: border-color var(--dur-fast) var(--ease-out),
              transform 160ms var(--ease-out),
              box-shadow 160ms var(--ease-out);
}
.jrnl-feature__media {
  position: relative;
  min-height: 100%;
  overflow: hidden;
}
.jrnl-feature__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}
/* seam scrim: feathers the photo edge into the steel plate so there's no hard
   accidental line at the column join (T2.19). */
.jrnl-feature__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg,
    rgba(34,34,34,0) 55%, rgba(34,34,34,0.5) 82%, rgba(44,44,44,0.9) 100%);
  pointer-events: none;
}
.jrnl-feature__body {
  padding: clamp(1.6rem, 3.2vw, 2.8rem);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-s);
}
/* the machined red tick that opens the dateline — alive at rest via the
   tungsten ink-breath (compositor-cheap opacity, gated by motion). */
.jrnl-feature__flag {
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  font-family: var(--font-mono);
  font-size: 0.66rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
}
.jrnl-feature__flag::before {
  content: "";
  width: 0.62rem;
  height: 0.62rem;
  background: var(--accent);
  border-radius: var(--radius);
  flex: none;
}
.jrnl-feature__title {
  font-family: var(--font-display);
  font-weight: 800;
  text-transform: uppercase;
  font-size: var(--step-section);
  line-height: 0.92;
  letter-spacing: 0.004em;
  color: var(--breath);
}
.jrnl-feature__title .em { color: var(--accent); font-style: normal; }
.jrnl-feature__excerpt {
  font-size: var(--step-0);
  line-height: 1.58;
  color: var(--slate-300);
  max-width: 34rem;
}
.jrnl-feature__meta {
  margin-top: auto;
  padding-top: var(--space-s);
  display: flex;
  align-items: center;
  gap: 0.7rem;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--slate-400);
}
.jrnl-feature__meta-dot { color: var(--ink-700); }
.jrnl-feature__more {
  margin-top: var(--space-s);
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  font-family: var(--font-mono);
  font-size: 0.74rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--breath);
}
.jrnl-feature__more::after {
  content: "";
  width: 1.4em; height: 0.62em; flex: none;
  background: var(--accent);
  -webkit-mask: no-repeat center / contain
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 14'%3E%3Cpath d='M0 7h20M15 1l6 6-6 6' fill='none' stroke='%23000' stroke-width='2'/%3E%3C/svg%3E");
          mask: no-repeat center / contain
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 14'%3E%3Cpath d='M0 7h20M15 1l6 6-6 6' fill='none' stroke='%23000' stroke-width='2'/%3E%3C/svg%3E");
  transition: transform 160ms var(--ease-out);
}
@media (hover: hover) {
  .jrnl-feature:hover {
    transform: translateY(-3px);
    border-color: var(--slate-600);
    box-shadow: 0 22px 44px -30px rgba(0,0,0,0.7);
  }
  .jrnl-feature:hover .jrnl-feature__more::after { transform: translateX(4px); }
}

/* ════════════════════════════════════════════════════════════════════
   ENTRY GRID — the stamped journal-page date plates. Repeated units are
   identical by default (T2.2): same plate height via flex, same padding,
   aligned titles (T2.13 anti-step-ladder).
   ════════════════════════════════════════════════════════════════════ */
.jrnl-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-m);
}
.jrnl-card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--ink-850);
  border: 1px solid var(--ink-700);
  border-radius: var(--radius);
  overflow: hidden;
  isolation: isolate;
  transition: border-color var(--dur-fast) var(--ease-out),
              transform 160ms var(--ease-out),
              box-shadow 160ms var(--ease-out);
}
.jrnl-card__media {
  position: relative;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: var(--ink-deep);
}
.jrnl-card__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  transition: transform 500ms var(--ease-out);
}
/* the dateline plate stamped onto the photo corner — a real inspection tag.
   Anchored bottom-left where the shop photos are calmest (T2.8). */
.jrnl-card__date {
  position: absolute;
  left: 0; bottom: 0;
  z-index: 2;
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
  padding: 0.5rem 0.85rem;
  background: color-mix(in srgb, var(--ink-deep) 88%, transparent);
  -webkit-backdrop-filter: blur(3px);
  backdrop-filter: blur(3px);
  border-top: 2px solid var(--accent);   /* the machined red tick — the tell */
  font-family: var(--font-mono);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--breath);
}
.jrnl-card__date-day { font-size: 1.15rem; font-weight: 500; }
.jrnl-card__date-mo  { font-size: 0.7rem; color: var(--slate-400); }
.jrnl-card__date-yr  { font-size: 0.7rem; color: var(--slate-400); }

.jrnl-card__body {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  padding: clamp(1.15rem, 2.4vw, 1.6rem);
  flex: 1;                       /* content-fit + equal-height peers (T2.5) */
}
.jrnl-card__kicker {
  font-family: var(--font-mono);
  font-size: 0.64rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent);
}
.jrnl-card__title {
  font-family: var(--font-display);
  font-weight: 700;
  text-transform: uppercase;
  font-size: clamp(1.3rem, 2.3vw, 1.7rem);
  line-height: 0.98;
  letter-spacing: 0.008em;
  color: var(--breath);
}
.jrnl-card__excerpt {
  font-size: var(--step--1);
  line-height: 1.55;
  color: var(--slate-400);
}
.jrnl-card__foot {
  margin-top: auto;
  padding-top: var(--space-xs);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  font-family: var(--font-mono);
  font-size: 0.66rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--slate-500);
}
.jrnl-card__read {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  color: var(--slate-300);
}
.jrnl-card__read::after {
  content: "";
  width: 1.15em; height: 0.58em; flex: none;
  background: var(--accent);
  -webkit-mask: no-repeat center / contain
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 14'%3E%3Cpath d='M0 7h20M15 1l6 6-6 6' fill='none' stroke='%23000' stroke-width='2'/%3E%3C/svg%3E");
          mask: no-repeat center / contain
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 14'%3E%3Cpath d='M0 7h20M15 1l6 6-6 6' fill='none' stroke='%23000' stroke-width='2'/%3E%3C/svg%3E");
  transition: transform 160ms var(--ease-out);
}
/* plate-press hover — scale-not-shift feel, ≤160ms, hover-capable only (T2.27/T2.30) */
@media (hover: hover) {
  .jrnl-card:hover {
    transform: translateY(-3px);
    border-color: var(--slate-600);
    box-shadow: 0 20px 40px -28px rgba(0,0,0,0.7);
  }
  .jrnl-card:hover .jrnl-card__img { transform: scale(1.045); }
  .jrnl-card:hover .jrnl-card__read::after { transform: translateX(4px); }
}

/* ---- WHOLE-CARD hit target (T2.38 — "if a tile reads as a link the WHOLE tile
   is the hit target"). David clicked the bottom-right Read affordance and nothing
   fired; now the single semantic title anchor (.jrnl-stretch) spreads an invisible
   ::after over the whole card, so every pixel of the card navigates. One anchor
   per card = no nested-anchor a11y hazard; the link stays keyboard-focusable and
   its focus ring is restored below. Applies to the feature plate + the grid cards
   (the estimates/featured card included). ---- */
.jrnl-card,
.jrnl-feature { position: relative; }
.jrnl-stretch::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 3;            /* above media + body, so the whole plate is clickable */
}
/* keyboard: the stretched link is the real focus stop — ring the whole card so
   focus is legible (the invisible ::after can't show a ring itself). */
.jrnl-card:focus-within,
.jrnl-feature:focus-within {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.jrnl-stretch:focus-visible { outline: none; }        /* card carries the ring */
/* the redundant in-body affordances (feature "Read the entry", card "Read")
   point to the same post; let the stretch overlay own the click, but keep the
   press-in cursor honest across the whole plate. */
.jrnl-card, .jrnl-feature { cursor: pointer; }
.jrnl-feature__more { position: relative; z-index: 2; }

/* ---- SIDEBAR — related resources (G003 graft, in steel) ---- */
.jrnl-aside {
  position: sticky;
  top: calc(var(--nav-h) + var(--space-m));
  display: flex;
  flex-direction: column;
  gap: var(--space-m);
}
.jrnl-panel {
  border: 1px solid var(--ink-700);
  border-radius: var(--radius);
  background: var(--ink-850);
  padding: clamp(1.15rem, 2.2vw, 1.5rem);
}
.jrnl-panel__head {
  font-family: var(--font-mono);
  font-size: 0.66rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--slate-400);
  padding-bottom: var(--space-xs);
  margin-bottom: var(--space-xs);
  border-bottom: 1px solid var(--ink-700);
}
.jrnl-panel__list { list-style: none; }
.jrnl-panel__list li + li { margin-top: 0.15rem; }
.jrnl-panel__link {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  padding-block: 0.55rem;
  font-family: var(--font-display);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  font-size: 1.02rem;
  color: var(--breath);
  border-bottom: 1px solid transparent;
  transition: color var(--dur-fast) var(--ease-out);
}
.jrnl-panel__link .jrnl-panel__tick {
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.1em;
  color: var(--accent);
  flex: none;
}
.jrnl-panel__list li + li .jrnl-panel__link,
.jrnl-panel__link { border-top: 1px solid var(--ink-700); }
.jrnl-panel__list li:first-child .jrnl-panel__link { border-top: none; }
@media (hover: hover) {
  .jrnl-panel__link:hover { color: var(--accent); }
}
/* the "watch the builds" CTA plate — red stamped-steel (matches nav/hero) */
.jrnl-panel--cta {
  background: var(--ink-800);
  text-align: left;
}
.jrnl-panel__cta-line {
  font-size: var(--step--1);
  line-height: 1.5;
  color: var(--slate-300);
  margin-bottom: var(--space-s);
}
.jrnl-cta-plate {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #fff;
  background: var(--accent);
  padding: 0.8rem 1.2rem;
  border-radius: var(--radius);
  box-shadow: 0 3px 0 var(--terracotta-deep);
  transition: transform 140ms var(--ease-out), box-shadow 140ms var(--ease-out);
}
@media (hover: hover) {
  .jrnl-cta-plate:hover { transform: translateY(2px); box-shadow: 0 1px 0 var(--terracotta-deep); }
}

/* ════════════════════════════════════════════════════════════════════
   POST — the documentary article. Faithful to the board slice
   (section-page-blog.jpg): dateline eyebrow → big condensed-caps head +
   red stripe → measured prose → full-bleed process photo → mono pull-quote
   (red-glow behind the quote) → closing prose → author card + MORE FROM
   THE JOURNAL. A thin red reading-progress gauge fills as you scroll (WOW).
   ════════════════════════════════════════════════════════════════════ */

/* the reading gauge — a thin Signal-Red stripe pinned under the nav, scaled by
   scroll progress (driven in blog.js). Alive at t0: a faint 2px hairline shows
   even before scroll so it's not a dead element (T2.24). */
.blog-post__gauge {
  position: fixed;
  left: 0; right: 0;
  top: var(--nav-h);
  height: 3px;
  z-index: 90;
  background: color-mix(in srgb, var(--ink-deep) 70%, transparent);
  pointer-events: none;
}
.blog-post__gauge-fill {
  height: 100%;
  width: 100%;
  background: var(--accent);
  transform-origin: left center;
  transform: scaleX(var(--read, 0));
  box-shadow: 0 0 10px -1px rgba(194,35,27,0.6);
}
/* motion off → the gauge is a static thin resting bar (no fixed-tracking), so
   nothing looks broken; keep it visible but at a settled low fill. */
html:not(.motion-ready) .blog-post__gauge-fill { transform: scaleX(0.001); }

/* article column — a real reading measure. Top nav-clearance now lives on the
   .blog-post__layout grid (so the article AND the sticky aside share one top
   line — the index pattern), leaving the article with only its own bottom pad. */
.blog-post__article {
  max-width: 52rem;
  margin-inline: auto;
  padding-bottom: var(--space-l);
}

/* ---- header ---- */
.blog-post__header { margin-bottom: var(--space-l); }
.blog-post__title {
  font-family: var(--font-display);
  font-weight: 800;
  text-transform: uppercase;
  font-size: clamp(2.6rem, 6.5vw, 5rem);
  line-height: 0.88;
  letter-spacing: 0.002em;
  color: var(--breath);
  margin-top: var(--space-s);
}
.blog-post__title .em { color: var(--accent); font-style: normal; }
/* the machined red stripe directly under the head — verbatim from the board */
.blog-post__stripe {
  display: block;
  width: clamp(4rem, 9vw, 6rem);
  height: 4px;
  margin-top: var(--space-m);
  background: var(--accent);
  border-radius: var(--radius);
}

/* ---- prose ---- */
.blog-post__prose > p {
  font-size: var(--step-1);
  line-height: 1.62;
  color: var(--slate-300);
}
.blog-post__prose > p + p { margin-top: var(--space-m); }
.blog-post__prose strong { color: var(--breath); font-weight: 600; }
.blog-post__lede-first {
  color: var(--breath) !important;
}

/* ---- full-bleed process photo (the board's silver-body chrome shot) ---- */
.blog-post__figure {
  margin-block: var(--space-l);
}
.blog-post__figure img {
  width: 100%;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  object-position: center;
  border-radius: var(--radius);
  border: 1px solid var(--ink-700);
}
.blog-post__figcaption {
  margin-top: var(--space-xs);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  /* Polished Steel (--slate-400 #B7BCC1) — the token the journal designates for
     captions. On the #222 field this computes 8.3:1, clearing WCAG AA (4.5:1);
     --slate-500 #6f6f6f was 3.2:1 and failed at this small size. */
  color: var(--slate-400);
}

/* ---- pull-quote — mono datasheet register, ruled top+bottom (board slice),
   the KEPT red glow behind the red quote words (pre-rendered opacity, never
   an animated blur — T2.22). Alive-at-t0-safe: the glow is static. ---- */
.blog-post__pull {
  position: relative;
  margin-block: var(--space-l);
  padding-block: var(--space-m);
  border-top: 1px solid var(--ink-700);
  border-bottom: 1px solid var(--ink-700);
  isolation: isolate;
}
.blog-post__pull blockquote {
  font-family: var(--font-mono);
  font-size: clamp(1rem, 1.9vw, 1.28rem);
  line-height: 1.5;
  letter-spacing: 0.01em;
  text-transform: uppercase;
  color: var(--breath);
  max-width: 40rem;
}
.blog-post__pull .em {
  position: relative;
  color: var(--accent);
  font-style: normal;
}
/* the red glow bloom behind the accented quote words — static ::after opacity,
   pre-rendered, NEVER animated blur (motion-must-feel-tight). */
.blog-post__pull .em::after {
  content: "";
  position: absolute;
  inset: -0.5em -0.4em;
  z-index: -1;
  background: radial-gradient(60% 120% at 50% 50%,
    rgba(194,35,27,0.28) 0%, rgba(194,35,27,0.08) 55%, rgba(194,35,27,0) 80%);
  pointer-events: none;
}
.blog-post__pull cite {
  display: block;
  margin-top: var(--space-s);
  font-family: var(--font-mono);
  font-size: 0.76rem;
  font-style: normal;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--slate-400);
}

/* ---- author card — steel plate, portrait + role + bio + "MORE FROM THE
   JOURNAL" plate (verbatim from board, REAL author only). ---- */
.blog-post__author {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: clamp(1rem, 3vw, 2rem);
  align-items: center;
  margin-top: var(--space-xl);
  padding: clamp(1.2rem, 2.6vw, 1.8rem);
  border: 1px solid var(--ink-700);
  border-radius: var(--radius);
  background: var(--ink-850);
}
.blog-post__author-portrait {
  width: clamp(4rem, 9vw, 5.5rem);
  height: clamp(4rem, 9vw, 5.5rem);
  flex: none;
  /* Real shop photo (P0518): Mark stands at the far RIGHT and his face brushes
     the TOP edge, so a plain object-fit:cover square reads as "a car in a shop."
     We ZOOM into the man (background-size >100% + a pan to his face) so the
     PERSON is unmistakably the subject — an honest, tighter crop of the same
     real photo of the same real person (T2.18 / T2.8, crop where the subject
     is). Kept as a background so we get zoom + pan an <img> can't give here;
     accessible name lives on role="img"/aria-label in the markup. */
  background-image: url("../../assets/people-story/P0518.webp");
  background-repeat: no-repeat;
  background-size: 250%;
  background-position: 82% 8%;
  border-radius: var(--radius);
  border: 1px solid var(--ink-700);
  filter: saturate(0.92) brightness(1.05) contrast(1.02);
}
.blog-post__author-name {
  font-family: var(--font-display);
  font-weight: 700;
  text-transform: uppercase;
  font-size: clamp(1.2rem, 2.2vw, 1.5rem);
  line-height: 1;
  letter-spacing: 0.02em;
  color: var(--breath);
}
.blog-post__author-role {
  margin-top: 0.4rem;
  font-family: var(--font-mono);
  font-size: 0.66rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
}
.blog-post__author-bio {
  margin-top: 0.55rem;
  font-size: var(--step--1);
  line-height: 1.5;
  color: var(--slate-400);
  max-width: 34rem;
}
.blog-post__author-more {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.1rem;
  text-align: center;
  min-width: clamp(7rem, 14vw, 9rem);
  padding: 0.9rem 1.1rem;
  border: 1px solid var(--slate-600);
  border-radius: var(--radius);
  box-shadow: inset 0 0 0 3px rgba(255,255,255,0.03);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--breath);
  transition: color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out);
}
/* corner rivets — the stamped-plate tell (matches the board's bracketed plate) */
.blog-post__author-more::before,
.blog-post__author-more::after {
  content: "";
  position: absolute;
}
.blog-post__author-more { position: relative; }
@media (hover: hover) {
  .blog-post__author-more:hover { color: var(--accent); border-color: var(--accent); }
}

/* ---- POST-FOOT nav: prev / index / next (the board's "SEE THE NEXT" logic) ---- */
.blog-post__nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-m);
  flex-wrap: wrap;
  margin-top: var(--space-l);
  padding-top: var(--space-m);
  border-top: 1px solid var(--ink-700);
  font-family: var(--font-mono);
  font-size: 0.74rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.blog-post__nav a {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  color: var(--slate-300);
  transition: color var(--dur-fast) var(--ease-out);
}
@media (hover: hover) {
  .blog-post__nav a:hover { color: var(--accent); }
}
.blog-post__nav-index { color: var(--slate-500) !important; }

/* ---- POST-page related-resources sidebar (G003 graft, in steel) — on the post
   it floats to the right on wide screens, stacks under on narrow. We keep the
   article single-column-centered and hang the aside as a right rail only ≥1180px
   so the reading measure is never compromised.

   STICKY CHOREOGRAPHY PARITY (T2.33 · David LOVES the index behavior): the post
   aside must feel EXACTLY like the index .jrnl-aside — grid `align-items:start`
   so the aside track starts at the article top, one `top` offset identical to the
   index (nav-h + space-m), and NO internal top pad. On the index the aside is
   `position:sticky`: it pins under the nav on scroll-down and rides down the tall
   entries column; at the page bottom it seats above the grid's symmetric bottom
   breath, JUST clear of the footer. On the post the article is the tall column,
   so the SAME sticky aside rides all the way down and seats the same way — the
   ONLY thing that was missing was the breath: the layout had `padding-bottom:0`
   and ran straight into the footer, so the seated aside kissed the footer. Fix
   (row 20): give `.blog-post__layout` the index's symmetric `padding-bottom:
   var(--space-xl)` so both the article column AND the ridden-down sticky aside
   end with the loved composed breath before the footer. ---- */
.blog-post__layout {
  display: grid;
  grid-template-columns: minmax(0, 52rem);
  justify-content: center;
  gap: clamp(2rem, 4vw, 4rem);
  align-items: start;
  /* nav-clearance for BOTH columns lives here (the index grid does the same via
     .blog-index__body padding) so the article header and the sticky aside share
     one top line and the aside can anchor-top exactly like the index. */
  padding-top: calc(var(--nav-h) + var(--space-l));
  /* composed breath before the footer — the index grid ends with a symmetric
     var(--space-xl) bottom pad (.blog-index__body padding-block); the post ran
     content straight into the footer (padding-bottom:0). Match the index so the
     column bottom leaves the same breath and the sticky aside rides down to
     seat above it, not touching the footer (row 20 · T2.33 choreography parity). */
  padding-bottom: var(--space-xl);
}
@media (min-width: 1180px) {
  .blog-post__layout {
    grid-template-columns: minmax(0, 52rem) clamp(15rem, 20vw, 18rem);
    justify-content: center;
    align-items: start;
  }
  .blog-post__aside {
    /* identical anchor to .jrnl-aside (the loved index sidebar): sticks under the
       nav on scroll-down, then rides the article-column bottom on release.
       The article column carries the nav-clearing top pad; the aside gets the
       SAME nav offset via its sticky `top` (nav-h + space-m) and NO internal
       top pad — so once stuck it seats just under the nav exactly like the index
       (the old rule ADDED a nav-h+space-l `padding-block` on TOP of a nav-sized
       `top`, doubling the offset → panels floated low = the bottom-align feel). */
    position: sticky;
    top: calc(var(--nav-h) + var(--space-m));
  }
}
.blog-post__aside {
  display: flex;
  flex-direction: column;
  gap: var(--space-m);
}
@media (max-width: 1179px) {
  /* stacked under the article; the layout's own padding-bottom: var(--space-xl)
     now supplies the breath before the footer (row 20), so no local bottom pad
     here or the stacked breath would double. */
  .blog-post__aside { max-width: 52rem; margin-inline: auto; }
}

/* ════════════════════════════════════════════════════════════════════
   ALIVE AT t0 (inviolable) — every content element is fully visible with NO
   JS / reduced-motion / ?solo. Any reveal choreography is ADDITIVE and only
   engages under .jrnl-ready (set by blog.js when GSAP+ScrollTrigger are live).
   Absent that class, the reveal targets are fully painted — no gating.
   ════════════════════════════════════════════════════════════════════ */
html.jrnl-ready .blog-index [data-jrnl-reveal],
html.jrnl-ready .blog-post [data-jrnl-reveal] {
  opacity: 0;
  transform: translateY(18px);
  will-change: opacity, transform;
}
html.jrnl-ready .blog-index [data-jrnl-reveal].is-in,
html.jrnl-ready .blog-post [data-jrnl-reveal].is-in {
  opacity: 1;
  transform: none;
  will-change: auto;
}

/* the dateline tungsten ink-breath — a faint red pulse on the machined tick so
   the plates are alive at rest without moving (T2.33). Opacity only, gated by
   motion, quiet register (this is the quietest surface on the site). */
.jrnl-card__date { position: absolute; }
.jrnl-card__date::before {
  content: "";
  position: absolute;
  left: 0; top: -2px;
  width: 100%; height: 2px;
  background: var(--accent);
  opacity: 0;
}
.motion-ready .jrnl-card__date::before {
  animation: tungsten-idle 8.6s ease-in-out infinite;
  opacity: 0.7;
}
.motion-ready .jrnl-feature__flag::before {
  animation: tungsten-idle 8.6s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
  .motion-ready .jrnl-card__date::before,
  .motion-ready .jrnl-feature__flag::before { animation: none; opacity: 0; }
}

/* ════════════════════════════════════════════════════════════════════
   RESPONSIVE — mobile is desktop RECOMPOSED, not squished (T2.31).
   ════════════════════════════════════════════════════════════════════ */
@media (max-width: 1024px) {
  .blog-index__body {
    grid-template-columns: 1fr;
    gap: var(--space-l);
  }
  .jrnl-aside {
    position: static;
    flex-direction: row;
    flex-wrap: wrap;
  }
  .jrnl-aside .jrnl-panel { flex: 1 1 16rem; }
}
@media (max-width: 720px) {
  .jrnl-feature { grid-template-columns: 1fr; }
  .jrnl-feature__media { aspect-ratio: 16 / 9; min-height: 0; }
  .jrnl-feature__media::after {
    background: linear-gradient(180deg,
      rgba(34,34,34,0) 55%, rgba(44,44,44,0.85) 100%);
  }
  .jrnl-grid { grid-template-columns: 1fr; }
  .jrnl-aside { flex-direction: column; }
  .blog-post__author {
    grid-template-columns: auto 1fr;
    row-gap: var(--space-m);
  }
  .blog-post__author-more { grid-column: 1 / -1; justify-self: start; }
  .blog-post__nav { font-size: 0.68rem; gap: var(--space-s); }
}
