/* Blog: the index (/blog/) and every post (/blog/<slug>/). Both pages are
   written by .claude/blog/build.py, so the markup below is the same on all
   33 pages. site.css is already linked by partials/head.html; this file
   only adds what the blog needs on top of its tokens, buttons, chips,
   hero ground (.section--hero) and band (.section--band).

   The parts, top to bottom:
     post hero      eyebrow, H1, author / date / reading time
     post layout    cover image + article prose, with a sticky aside
                    ("On this page" + a quote card) from 1080px up
     prose          everything the migrated post bodies emit
     post foot      venue tags, then the Related product card
     blog card      one card for the index grid and Related posts
     index          hero, venue filter, featured card, load more
     CTA band       the closing ask, shared by both pages */

/* =========================================================================
   POST HERO
   ========================================================================= */
.post-hero { padding-block: var(--sp-9) var(--sp-8); }
.post-hero .rail-wide > * { max-width: 920px; }
.post-hero__title {
  margin-top: var(--sp-4);
  font: var(--text-display-md); letter-spacing: var(--ls-display); text-wrap: balance;
}

.post-meta { display: flex; align-items: center; gap: var(--sp-4); margin-top: var(--sp-7); }
.post-meta__avatar {
  display: grid; place-items: center; flex: 0 0 auto;
  width: 44px; height: 44px; border-radius: 50%;
  background: var(--gradient-mark); color: var(--text-on-brand);
  font: var(--fw-bold) 15px/1 var(--font-sans); letter-spacing: .02em;
}
.post-meta__text b { display: block; font: var(--text-label); font-weight: var(--fw-semibold); color: var(--text-primary); }
.post-meta__text p { display: flex; flex-wrap: wrap; margin-top: 2px; font: var(--text-body-sm); color: var(--text-secondary); }
.post-meta__text p > * + *::before { content: "·"; margin-inline: var(--sp-2); color: var(--text-tertiary); }
/* On a phone the items wrap, so they drop the dots and take a gap instead:
   a dot at the start of a line reads as a stray mark. */
@media (max-width: 560px) {
  .post-meta { align-items: flex-start; }
  .post-meta__text p { column-gap: var(--sp-4); }
  .post-meta__text p > * + *::before { content: none; }
}

/* =========================================================================
   POST LAYOUT
   One column on phones and tablets; from 1080px the article gets a sticky
   aside on its right. The article column never runs wider than a
   comfortable line of text plus the cover image's width.
   ========================================================================= */
.post-layout {
  display: grid; grid-template-columns: minmax(0, 1fr);
  gap: var(--sp-10); padding-bottom: var(--section-y-tight);
}
.post-article { min-width: 0; max-width: var(--container-narrow); }

.post-cover { margin: 0; }
.post-cover img {
  display: block; width: 100%; height: auto;
  border-radius: var(--radius-lg); background: var(--surface-media);
  box-shadow: var(--shadow-md);
}

.post-aside { display: none; }

@media (min-width: 1080px) {
  .post-layout { grid-template-columns: minmax(0, 1fr) 288px; gap: clamp(48px, 5vw, 80px); }
  .post-aside {
    display: grid; gap: var(--sp-6); align-content: start; align-self: start;
    position: sticky; top: calc(var(--header-h) + 12px + var(--sp-6));
  }
}

/* ---------- On this page ------------------------------------------------ */
.post-toc__title {
  font: var(--text-overline); letter-spacing: var(--ls-overline); text-transform: uppercase;
  color: var(--text-tertiary);
}
.post-toc ol {
  margin-top: var(--sp-4); padding: 0; list-style: none;
  border-left: 1px solid var(--border-default);
  max-height: calc(100vh - var(--header-h) - 380px); overflow-y: auto; overscroll-behavior: contain;
  scrollbar-width: thin;
}
.post-toc a {
  display: block; margin-left: -1px; padding: 6px 0 6px var(--sp-4);
  border-left: 2px solid transparent;
  font: var(--text-body-sm); line-height: 1.4; color: var(--text-secondary); text-decoration: none;
  transition: var(--transition-control);
}
.post-toc a:hover { color: var(--text-primary); text-decoration: none; }
.post-toc a[aria-current="true"] { border-left-color: var(--text-brand); color: var(--text-primary); font-weight: var(--fw-semibold); }

/* ---------- Quote card -------------------------------------------------- */
.post-quote {
  position: relative; overflow: hidden; display: grid; gap: var(--sp-3); justify-items: start;
  padding: var(--card-pad);
  border: 1px solid var(--border-subtle); border-radius: var(--radius-md);
  background: var(--surface-raised); box-shadow: var(--shadow-sm);
}
.post-quote::before {
  content: ""; position: absolute; inset-block-start: 0; inset-inline: 0; height: 3px;
  background: var(--motif-rule-accent);
}
.post-quote__title { font: var(--text-h4); color: var(--text-primary); }
.post-quote p:not([class]) { font: var(--text-body-sm); color: var(--text-secondary); }
.post-quote .btn { margin-top: var(--sp-2); width: 100%; }
.post-quote__call {
  display: inline-flex; align-items: center; gap: var(--sp-2); justify-self: center;
  font: var(--text-label); color: var(--text-primary); text-decoration: none;
}
.post-quote__call .i { color: var(--text-brand); }
.post-quote__call:hover { color: var(--text-brand); text-decoration: none; }

/* =========================================================================
   PROSE
   Everything the migrated post bodies emit: headings, paragraphs, lists,
   tables, blockquotes, inline images, and the FAQ block build.py wraps.
   The body steps up to the lead size on wide screens, where the column is
   wide enough to carry it.
   ========================================================================= */
.prose { margin-top: var(--sp-9); font-size: var(--fs-body); line-height: 1.7; color: var(--text-primary); }
@media (min-width: 900px) { .prose { font-size: var(--fs-body-lg); } }
.prose > :first-child { margin-top: 0; }

.prose h2, .prose h3, .prose h4 {
  scroll-margin-top: calc(var(--header-h) + 12px + var(--sp-6));
  color: var(--text-primary); text-wrap: balance; overflow-wrap: break-word;
}
.prose h2 { margin-top: var(--sp-10); font: var(--text-h2); letter-spacing: var(--ls-heading); }
.prose h3 { margin-top: var(--sp-8); font: var(--text-h3); letter-spacing: -.01em; }
.prose h4 { margin-top: var(--sp-7); font: var(--text-h4); }
.prose h2 + p, .prose h3 + p, .prose h4 + p,
.prose h2 + ul, .prose h3 + ul, .prose h4 + ul,
.prose h2 + ol, .prose h3 + ol, .prose h4 + ol { margin-top: var(--sp-4); }

.prose p { margin-top: var(--sp-5); text-wrap: pretty; overflow-wrap: break-word; }
.prose strong, .prose b { font-weight: var(--fw-semibold); color: var(--text-primary); }

.prose a {
  color: var(--text-brand); font-weight: var(--fw-medium);
  text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px;
  text-decoration-color: color-mix(in srgb, currentColor 40%, transparent);
  transition: text-decoration-color var(--dur-2) var(--ease-out);
}
.prose a:hover { text-decoration-color: currentColor; }

.prose ul, .prose ol { margin-top: var(--sp-5); padding-left: 1.4em; display: grid; gap: var(--sp-3); }
.prose li { padding-left: var(--sp-1); }
.prose li > ul, .prose li > ol { margin-top: var(--sp-3); }
.prose ul > li::marker { color: var(--text-brand); }
.prose ol > li::marker { color: var(--text-brand); font-weight: var(--fw-bold); }

.prose blockquote {
  margin: var(--sp-8) 0; padding: var(--sp-5) var(--sp-6);
  border-left: 3px solid var(--border-brand); border-radius: 0 var(--radius-md) var(--radius-md) 0;
  background: var(--surface-subtle);
  font: var(--text-lead); color: var(--text-primary);
}
.prose blockquote > :first-child { margin-top: 0; }

.prose img {
  display: block; max-width: 100%; height: auto; margin: var(--sp-8) auto;
  border-radius: var(--radius-md); border: 1px solid var(--border-subtle);
}

/* Tables scroll inside their own frame on a phone instead of widening
   the page (build.py wraps each one in .post-table). */
.post-table {
  margin-top: var(--sp-7); overflow-x: auto; overscroll-behavior-x: contain;
  border: 1px solid var(--border-default); border-radius: var(--radius-md);
  -webkit-overflow-scrolling: touch;
}
.post-table table { width: 100%; border-collapse: collapse; font: var(--text-body-sm); }
/* A floor per cell rather than per table: a two-column table fits a phone,
   a five-column one scrolls. */
.post-table th, .post-table td {
  min-width: 9em; padding: var(--sp-3) var(--sp-4); text-align: left; vertical-align: top;
  border-bottom: 1px solid var(--border-subtle);
}
.post-table thead th, .post-table tr:first-child > th {
  background: var(--surface-subtle); font: var(--text-label); font-weight: var(--fw-semibold);
  color: var(--text-primary);
}
.post-table tbody tr:nth-child(even) > td { background: color-mix(in srgb, var(--surface-subtle) 55%, transparent); }
.post-table tr:last-child > * { border-bottom: 0; }
.post-table td:first-child { font-weight: var(--fw-semibold); }
.post-table p { margin: 0; }

/* ---------- FAQ block ----------------------------------------------------
   build.py wraps a post's FAQ heading and its questions in .post-faq.
   Posts write a question either as an <h3> or as a bold lead-in at the
   start of a paragraph; both get the same treatment here. */
.post-faq {
  margin-top: var(--sp-10); padding: var(--sp-8) clamp(20px, 4vw, 40px) var(--sp-7);
  border: 1px solid var(--border-subtle); border-radius: var(--radius-lg);
  background: var(--surface-subtle);
}
.post-faq h2 { margin-top: 0; }
.post-faq h3, .post-faq h4 {
  margin-top: var(--sp-6); padding-top: var(--sp-6); border-top: 1px solid var(--border-default);
  font: var(--text-h4); letter-spacing: 0;
}
.post-faq h2 + h3, .post-faq h2 + h4 { border-top: 0; padding-top: 0; }
.post-faq h3 + p, .post-faq h4 + p { margin-top: var(--sp-2); }
.post-faq p { font-size: var(--fs-body); color: var(--text-secondary); }
.post-faq p > strong:first-child {
  display: block; margin-bottom: var(--sp-2);
  font: var(--text-h4); color: var(--text-primary);
}
.post-faq p > strong:first-child + br { display: none; }
.post-faq h2 + p:has(> strong:first-child) { margin-top: var(--sp-6); }
.post-faq p:has(> strong:first-child) ~ p:has(> strong:first-child) {
  margin-top: var(--sp-6); padding-top: var(--sp-6); border-top: 1px solid var(--border-default);
}

/* =========================================================================
   POST FOOT: venue tags, then the Related product card
   ========================================================================= */
.post-foot {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-3);
  margin-top: var(--sp-10); padding-top: var(--sp-6); border-top: 1px solid var(--border-default);
}
.post-foot__label { font: var(--text-label); color: var(--text-secondary); }
.tag-chips { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin: 0; padding: 0; list-style: none; }
.tag-chip {
  display: inline-flex; align-items: center; height: 28px; padding-inline: var(--sp-3);
  border: 1px solid var(--border-subtle); border-radius: var(--radius-pill); background: var(--surface-subtle);
  font: var(--text-caption); color: var(--text-secondary);
}
.tag-chip::first-letter { text-transform: uppercase; }

.related-products { margin-top: var(--sp-9); }
.product-card {
  position: relative; overflow: hidden; isolation: isolate;
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 200px); align-items: center;
  gap: var(--sp-6); padding: var(--card-pad-lg);
  border: 1px solid var(--border-subtle); border-radius: var(--radius-lg);
  background:
    radial-gradient(90% 120% at 100% 50%, var(--stage-bg-2) 0%, var(--stage-bg) 100%);
  box-shadow: var(--shadow-sm);
  transition: var(--transition-lift);
}
.product-card::before {
  content: ""; position: absolute; inset-block-start: 0; inset-inline: 0; height: 3px;
  background: var(--motif-rule-accent); z-index: 1;
}
.product-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg); }
.product-card__copy { display: grid; gap: var(--sp-3); justify-items: start; }
.product-card__name { font: var(--text-h2); letter-spacing: var(--ls-heading); color: var(--text-primary); }
.product-card__copy p:not([class]) { font: var(--text-body); color: var(--text-secondary); max-width: 46ch; }
.product-card__go {
  display: inline-flex; align-items: center; gap: var(--sp-2); margin-top: var(--sp-2);
  font: var(--text-button); color: var(--text-primary);
}
.product-card__go a { color: var(--text-brand); text-decoration: none; }
/* The keyword link covers the whole card, so the card is one target. */
.product-card__go a::after { content: ""; position: absolute; inset: 0; z-index: 2; }
.product-card__go .i { color: var(--text-brand); transition: transform var(--dur-2) var(--ease-out); }
.product-card:hover .product-card__go .i { transform: translateX(3px); }
.product-card__art { margin: calc(var(--sp-6) * -1) 0; }
.product-card__art img { display: block; width: 100%; height: auto; max-height: 260px; object-fit: contain; }
.product-card__art--icon { display: grid; place-items: center; margin: 0; }
.product-card__art--icon .icon-tile { width: 96px; height: 96px; border-radius: var(--radius-lg); }
.product-card__art--icon .icon-tile svg { width: 44px; height: 44px; }
.product-card:focus-within { outline: 2px solid var(--focus-ring); outline-offset: 3px; }
.product-card__go a:focus-visible { outline: none; }

/* Stacked on a phone, the product centred above the copy, as the product
   heroes do. */
@media (max-width: 560px) {
  .product-card { grid-template-columns: minmax(0, 1fr); padding: var(--card-pad); gap: var(--sp-4); }
  .product-card__art { order: -1; justify-self: center; width: 150px; margin: 0; }
  .product-card__art img { max-height: 190px; }
  .product-card__art--icon { justify-self: start; width: auto; }
  .product-card__art--icon .icon-tile { width: 64px; height: 64px; }
  .product-card__art--icon .icon-tile svg { width: 30px; height: 30px; }
  .product-card__name { font: var(--text-h3); }
}

/* =========================================================================
   BLOG CARD
   One card everywhere a post is listed: the index grid and each post's
   Related posts row. The card system's look (hairline, soft shadow, 12px
   corners, lift on hover); the title link stretches over the whole card.
   Post covers are 1200 x 630, so the image keeps that shape and nothing
   baked into it gets cropped.
   ========================================================================= */
.blog-card-grid {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--grid-gap); margin-top: var(--sp-8);
}
@media (max-width: 1000px) { .blog-card-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 640px)  { .blog-card-grid { grid-template-columns: minmax(0, 1fr); } }

.blog-card {
  position: relative; isolation: isolate; overflow: hidden;
  display: flex; flex-direction: column;
  border: 1px solid var(--border-subtle); border-radius: var(--radius-md);
  background: var(--surface-raised); box-shadow: var(--shadow-sm);
  transition: var(--transition-lift);
}
.blog-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-lg); }
.blog-card:focus-within { outline: 2px solid var(--focus-ring); outline-offset: 3px; }
.blog-card.is-hidden { display: none; }

.blog-card__media { overflow: hidden; background: var(--surface-media); border-bottom: 1px solid var(--border-subtle); }
.blog-card__media img {
  display: block; width: 100%; height: auto; aspect-ratio: 1200 / 630; object-fit: cover;
  transition: transform var(--dur-4, 480ms) var(--ease-out);
}
.blog-card:hover .blog-card__media img { transform: scale(1.03); }
/* A cover in another shape (build.py adds --fit): the whole picture, with a
   blurred copy of it filling the rest of the frame. */
.blog-card__media--fit { position: relative; isolation: isolate; }
.blog-card__media--fit::before {
  content: ""; position: absolute; inset: -24px; z-index: -1;
  background: var(--cover) center / cover no-repeat; filter: blur(18px) saturate(1.1); opacity: .85;
}
.blog-card__media--fit img { object-fit: contain; }

.blog-card__body { flex: 1; display: flex; flex-direction: column; align-items: flex-start; gap: var(--sp-3); padding: var(--sp-5) var(--sp-5) var(--sp-6); }
.blog-card__meta { display: flex; flex-wrap: wrap; font: var(--text-caption); color: var(--text-tertiary); }
.blog-card__meta > * + *::before { content: "·"; margin-inline: var(--sp-2); }
.blog-card__title { font: var(--text-h4); font-size: 19px; line-height: 1.3; letter-spacing: -.01em; text-wrap: balance; }
.blog-card__title a { color: var(--text-primary); text-decoration: none; }
.blog-card__title a::after { content: ""; position: absolute; inset: 0; z-index: 1; }
.blog-card__title a:focus-visible { outline: none; }
.blog-card:hover .blog-card__title a { color: var(--text-brand); }
.blog-card__excerpt {
  font: var(--text-body-sm); color: var(--text-secondary);
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; line-clamp: 3; overflow: hidden;
}
.blog-card__go {
  display: inline-flex; align-items: center; gap: 6px; margin-top: auto; padding-top: var(--sp-2);
  font: var(--text-button); color: var(--text-brand);
}
.blog-card__go .i { transition: transform var(--dur-2) var(--ease-out); }
.blog-card:hover .blog-card__go .i { transform: translateX(3px); }

/* The newest post on the index: the full row, picture beside the copy. */
.blog-card--featured { grid-column: 1 / -1; }
/* Side by side only where the copy is short enough to sit beside the
   picture without cropping it by more than a sliver; stacked below that. */
@media (min-width: 1180px) {
  .blog-card--featured { display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); }
  .blog-card--featured .blog-card__media { border-bottom: 0; border-right: 1px solid var(--border-subtle); }
  .blog-card--featured .blog-card__media img { height: 100%; }
  .blog-card--featured .blog-card__body { justify-content: center; gap: var(--sp-3); padding: clamp(20px, 2.6vw, 40px); }
  .blog-card--featured .blog-card__title { font: var(--text-h1); letter-spacing: var(--ls-heading); }
  .blog-card--featured .blog-card__excerpt { -webkit-line-clamp: 3; line-clamp: 3; }
  .blog-card--featured .blog-card__go { margin-top: var(--sp-2); }
}
@media (min-width: 761px) and (max-width: 1179px) {
  .blog-card--featured .blog-card__body { padding: var(--sp-6) var(--sp-7) var(--sp-7); }
  .blog-card--featured .blog-card__title { font: var(--text-h1); letter-spacing: var(--ls-heading); }
}

@media (prefers-reduced-motion: reduce) {
  .blog-card, .blog-card__media img, .product-card, .blog-card__go .i, .product-card__go .i { transition: none; }
  .blog-card:hover, .product-card:hover { transform: none; }
  .blog-card:hover .blog-card__media img { transform: none; }
}

/* ---------- Related posts row on a post --------------------------------- */
.related-posts .section-head { align-items: flex-end; }
.related-posts .section-head h2 { font: var(--text-display-md); letter-spacing: var(--ls-display); }

/* =========================================================================
   INDEX
   ========================================================================= */
.blog-hero { padding-block: var(--sp-10) var(--sp-9); }
.blog-hero .lead { max-width: 60ch; }
.blog-hero .lead a { color: var(--text-brand); }
.blog-list { padding-top: 0; }

.venue-filter { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); }
.venue-filter__label { margin-right: var(--sp-2); font: var(--text-label); color: var(--text-secondary); }
.venue-chip {
  display: inline-flex; align-items: center; gap: var(--sp-2); height: 36px; padding-inline: var(--sp-4) var(--sp-3);
  border: 1px solid var(--border-default); border-radius: var(--radius-pill);
  background: var(--surface-raised); font: var(--text-label); color: var(--text-primary);
  white-space: nowrap; cursor: pointer; transition: var(--transition-control);
}
.venue-chip:hover { border-color: var(--border-strong); background: var(--surface-subtle); }
.venue-chip:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.venue-chip__count {
  display: inline-grid; place-items: center; min-width: 22px; height: 20px; padding-inline: 6px;
  border-radius: var(--radius-pill); background: var(--surface-sunken);
  font: var(--text-caption); font-variant-numeric: tabular-nums; color: var(--text-secondary);
}
.venue-chip.is-active { background: var(--n-900); border-color: var(--n-900); color: var(--text-on-dark); }
.venue-chip.is-active .venue-chip__count { background: rgba(255,255,255,.16); color: var(--text-on-dark); }
@media (prefers-reduced-motion: reduce) { .venue-chip { transition: none; } }

/* On a phone the chips stay on one line and scroll sideways. */
@media (max-width: 640px) {
  .venue-filter {
    flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none;
    margin-inline: calc(var(--gutter) * -1); padding-inline: var(--gutter); padding-block: 2px;
  }
  .venue-filter::-webkit-scrollbar { display: none; }
  .venue-filter__label { display: none; }
}

.blog-more { display: flex; justify-content: center; margin-top: var(--sp-9); }

/* =========================================================================
   CTA BAND (both pages)
   ========================================================================= */
.blog-cta__inner { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--sp-8); }
.blog-cta__copy { max-width: 640px; }
.blog-cta__copy h2 { margin-top: var(--sp-3); }
.blog-cta__copy .lead { margin-top: var(--sp-4); }
.blog-cta__actions { display: flex; flex-wrap: wrap; gap: var(--sp-3); }
