/* Habitus Mind Blog — listing + post detail.
   Loads after /style.css (the marketing site's Mercury tokens/components:
   .card, .block, .btn-cta, .answer, header/footer/WhatsApp FAB are all
   already defined there and reused as-is). This file only adds what the
   blog needs on top: category pills, the post grid, article typography,
   and the author card.

   v1 ships text-only — no photography (see blog/build.mjs's comment and
   the chat decision: real licensed photos weren't sourced for six posts
   under this pass, and a generated/gradient stand-in was ruled out by
   this project's own imagery standard). Cards read as editorial text
   cards, not broken image placeholders. */

.kicker {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-accent-soft);
  margin-bottom: var(--space-16);
}

.blog-hero { border-top: none; padding-top: var(--space-56); }
.blog-hero h1 { max-width: 40rem; font-size: clamp(32px, 4.5vw, 56px); letter-spacing: -0.01em; }
.blog-hero .answer { max-width: 40rem; }

/* ---------- Category filter ---------- */
.filter-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-8);
  margin-bottom: var(--space-40);
}

/* Also reused, unmodified, as the post page's share buttons (.post-share
   a/button) — same pill, same states, one definition. */
.filter-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 36px;
  padding: 0 var(--space-16);
  border-radius: var(--radius-tags);
  border: 1px solid var(--color-line-strong);
  background: transparent;
  color: var(--color-ink-soft);
  font: 400 14px var(--font-body);
  white-space: nowrap;
  text-decoration: none;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.filter-pill:hover { background: rgba(255, 60, 74, 0.08); color: var(--color-ink); text-decoration: none; }
.filter-pill.is-active {
  background: var(--color-accent);
  border-color: var(--color-accent);
  color: var(--color-white);
}

/* ---------- Tag pill (category label on a card / post) ---------- */
.tag {
  display: inline-block;
  width: fit-content;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 4px 14px;
  border-radius: var(--radius-tags);
  border: 1px solid var(--color-line-strong);
  color: var(--color-ink);
}

/* ---------- Featured post ---------- */
.featured-post {
  display: flex;
  flex-direction: column;
  gap: var(--space-16);
  margin-bottom: var(--space-56);
  color: inherit;
}

/* With a cover, the featured card goes side-by-side — cover left, copy
   right — which is the proportion the v2 design gives it. Full-bleed
   would make a 16:10 cover ~740px tall on a desktop column and push the
   headline below the fold; inside a ~55% column it lands around 400px,
   which is what the design actually shows. */
.featured-post.has-cover {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  gap: var(--space-32);
  align-items: center;
}
.featured-post-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-16);
  min-width: 0;
}
@media (max-width: 800px) {
  .featured-post.has-cover { grid-template-columns: 1fr; gap: var(--space-20); }
}
.featured-post:hover { text-decoration: none; border-color: var(--color-accent); }
.featured-post h2 { font-size: clamp(24px, 3vw, 32px); }
.featured-post .excerpt { max-width: 52rem; }

/* ---------- Featured block (lead post + the stack beside it) ----------
   `featured` is a flag several posts may carry at once (see
   db/migrate_blog_scheduled.sql) — with 2+ of them, the newest leads in
   the wide column and the rest stack in a narrower one beside it
   (design/Habitusmind blog page_v2). With 0 or 1 featured post,
   renderListingPage() never builds this wrapper and .featured-post
   above renders alone, full width. */
.featured-block {
  display: grid;
  grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr);
  gap: var(--space-24);
  align-items: stretch;
  margin-bottom: var(--space-56);
}
.featured-block .featured-post { margin-bottom: 0; }
@media (max-width: 900px) {
  .featured-block { grid-template-columns: 1fr; }
}

.secondary-featured-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-16);
}
.secondary-featured-card {
  display: flex;
  gap: var(--space-16);
  align-items: center;
  min-width: 0;
  flex: 1 1 0;
  color: inherit;
  background: var(--color-surface-2);
  border: 1px solid rgba(255, 60, 74, 0.22);
  border-radius: var(--radius-cards-inner);
  padding: var(--space-12);
}
.secondary-featured-card:hover { text-decoration: none; border-color: var(--color-accent); }
.secondary-featured-card .cover-media { flex: 0 0 40%; align-self: stretch; min-height: 96px; }
.secondary-featured-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
  min-width: 0;
}
.secondary-featured-body h3 { font-size: 16px; line-height: 1.32; letter-spacing: normal; }
.secondary-featured-body .meta-muted { font-size: 12px; }
.eyebrow {
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--color-accent-soft);
}

.excerpt { color: var(--color-ink-soft); font-size: 16px; line-height: 1.6; }

.post-meta { display: flex; align-items: center; gap: var(--space-8); flex-wrap: wrap; }
.post-meta .avatar-chip { width: 32px; height: 32px; font-size: 12px; }
.meta-name { font-size: 14px; color: var(--color-ink); }
.meta-muted { font-size: 14px; color: var(--color-ink-soft); }
.meta-dot { color: var(--color-ink-soft); }

.read-more { color: var(--color-accent); font: 400 15px var(--font-body); width: fit-content; }
.featured-post:hover .read-more { text-decoration: underline; text-underline-offset: 3px; }

/* ---------- Post grid ---------- */
.latest-heading { margin-bottom: var(--space-24); }

.post-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-24);
}
@media (max-width: 900px) { .post-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 620px) { .post-grid { grid-template-columns: 1fr; } }

.post-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-12);
  color: inherit;
  height: 100%;
}
.post-card:hover { text-decoration: none; border-color: var(--color-accent); }
.post-card h3 { font-size: 20px; letter-spacing: normal; }
.post-card .excerpt {
  font-size: 14px;
  /* Clamp to 3 lines so cards stay level regardless of excerpt length —
     intrinsic sizing everywhere else, but a grid of cards needs this one
     explicit bound to avoid a ragged row. */
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.post-card .post-meta { margin-top: auto; padding-top: var(--space-4); }

.post-grid[hidden],
.post-card[hidden] { display: none; }

.empty-state {
  color: var(--color-ink-soft);
  text-align: center;
  padding: var(--space-56) 0;
}

/* ---------- Post detail ----------
   .post-detail is a full-width .block — only the header text and the
   article column below get their own max-width, so the hero image can
   run the full block width while the prose stays a readable measure
   (design/Habitusmind blog page_v2). */

.breadcrumb {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-8);
  font-size: 14px;
  color: var(--color-ink-soft);
  margin-bottom: var(--space-24);
}
.breadcrumb a { color: var(--color-ink-soft); }
.breadcrumb a:hover { color: var(--color-ink); }
.breadcrumb [aria-current="page"] { color: var(--color-ink); }

.post-header { max-width: 46rem; }

.post-header h1 {
  margin-top: var(--space-16);
  font-size: clamp(32px, 5vw, 48px);
}

.post-meta-lg { margin-top: var(--space-20); }
.post-meta-lg .avatar-chip { width: 36px; height: 36px; }

.post-share {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-8);
  margin-left: var(--space-16);
}
@media (max-width: 560px) { .post-share { margin-left: 0; } }

/* ---------- Article + "On this page" sidebar ---------- */
.post-layout {
  display: flex;
  align-items: flex-start;
  gap: var(--space-40);
  flex-wrap: wrap;
  margin-top: var(--space-32);
}
.post-article { flex: 3 1 500px; min-width: 0; max-width: 46rem; }

.post-toc {
  flex: 1 1 200px;
  min-width: 200px;
  position: sticky;
  top: 96px;
}
.post-toc-label {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-ink-soft);
  margin-bottom: var(--space-12);
}
.post-toc nav {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
  border-left: 2px solid var(--color-line-strong);
  padding-left: var(--space-16);
}
.post-toc a { font-size: 14px; color: var(--color-ink-soft); line-height: 1.4; }
.post-toc a:hover { color: var(--color-ink); }
@media (max-width: 900px) {
  .post-toc { position: static; }
}

.post-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-20);
}
.post-body h2 { font-size: 26px; margin-top: var(--space-16); }
.post-body p { color: var(--color-ink-soft); font-size: 17px; line-height: 1.7; max-width: 100%; }
.post-body ul { margin: 0; padding-left: 1.25em; color: var(--color-ink-soft); font-size: 17px; line-height: 1.7; }
.post-body li { margin-bottom: var(--space-8); }
.post-body li::marker { color: var(--color-accent); }

.post-tags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-8);
  margin-top: var(--space-40);
  padding-top: var(--space-24);
  border-top: 1px solid rgba(255, 60, 74, 0.12);
}
.post-tag {
  font-size: 13px;
  color: var(--color-ink-soft);
  border: 1px solid var(--color-line-strong);
  border-radius: var(--radius-tags);
  padding: var(--space-4) var(--space-12);
}

.author-card {
  display: flex;
  gap: var(--space-16);
  align-items: flex-start;
  margin-top: var(--space-40);
}
.avatar-chip-lg { width: 48px; height: 48px; font-size: 15px; flex-shrink: 0; }
.author-name { font: 480 16px var(--font-display); }
.author-role { font-size: 13px; color: var(--color-accent-soft); margin-top: 2px; }
.author-bio { font-size: 14px; color: var(--color-ink-soft); line-height: 1.6; margin-top: var(--space-8); }

.related-posts h2 { margin-bottom: var(--space-24); }

/* ---------- Rich content (WYSIWYG editor output) ----------
   The editor can now emit headings, ordered lists, quotes, code, rules,
   links, and images/figures — everything functions/_lib/blog-sanitize.js
   allows. These rules cover the tags the earlier markdown-only version
   never produced, so a post written in the visual editor renders as
   deliberately as the hand-written ones did. */

.post-body h3 { font-size: 21px; margin-top: var(--space-16); letter-spacing: normal; }
.post-body h4 { font-size: 18px; margin-top: var(--space-16); letter-spacing: normal; }

.post-body ol {
  margin: 0;
  padding-left: 1.25em;
  color: var(--color-ink-soft);
  font-size: 17px;
  line-height: 1.7;
}
.post-body ol li { margin-bottom: var(--space-8); }
.post-body ol li::marker { color: var(--color-accent); }

.post-body a {
  color: var(--color-accent);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.post-body a:hover { color: var(--color-ink); }

.post-body strong { color: var(--color-ink); font-weight: 530; }
.post-body em { font-style: italic; }
.post-body u { text-underline-offset: 2px; }
.post-body s { opacity: 0.7; }

.post-body blockquote {
  margin: 0;
  padding: var(--space-4) 0 var(--space-4) var(--space-24);
  border-left: 2px solid var(--color-accent);
  color: var(--color-ink);
  font-size: 19px;
  line-height: 1.6;
  font-style: italic;
}

/* A TL;DR / key-takeaways callout is the same blockquote markup (a
   bold lead-in line + a bullet list) rather than a new tag — nothing
   outside the allowlist in functions/_lib/blog-sanitize.js. The quote's
   italic is right for a pulled sentence but wrong for a scannable list,
   so it's turned off just for the list inside one. This is also the
   shape answer engines and featured snippets tend to lift directly
   (GEO/AEO): a short labelled list right under the opening claim. */
.post-body blockquote p { font-style: normal; margin: 0 0 var(--space-8); }
.post-body blockquote ul,
.post-body blockquote ol {
  font-style: normal;
  margin: 0;
}
.post-body blockquote li { margin-bottom: var(--space-4); }

.post-body code {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  font-size: 0.88em;
  padding: 0.12em 0.4em;
  border-radius: var(--radius-default);
  background: var(--color-surface-2);
  color: var(--color-ink);
}

.post-body pre {
  margin: 0;
  padding: var(--space-20);
  border-radius: var(--radius-cards-inner);
  border: 1px solid var(--color-line-strong);
  background: var(--color-card);
  /* Wide code scrolls inside its own box — the page body must never
     scroll horizontally (see DESIGN.md's layout guidelines). */
  overflow-x: auto;
  font-size: 14px;
  line-height: 1.6;
}
.post-body pre code { background: none; padding: 0; font-size: inherit; }

.post-body hr {
  border: none;
  border-top: 1px solid var(--color-line-strong);
  margin: var(--space-16) 0;
}

/* Images. width is set inline as a percentage by the editor's resize
   control; max-width keeps that honest on narrow screens, and height:auto
   preserves the aspect ratio so nothing is squashed. */
.post-body img {
  max-width: 100%;
  height: auto;
  border-radius: var(--radius-cards-inner);
  display: inline-block;
  vertical-align: middle;
}

.post-body figure { margin: var(--space-8) 0; }

.post-body figcaption {
  margin-top: var(--space-12);
  font-size: 14px;
  line-height: 1.5;
  color: var(--color-ink-soft);
}

/* An image alone in a paragraph shouldn't inherit the body copy's
   bottom spacing twice over. */
.post-body p:has(> img:only-child) { line-height: 0; }

/* ---------- Cover images (design/Habitusmind blog page_v2) ----------
   ONE uploaded image per post, reused at four crops. The box sets the
   aspect ratio and the <img> is object-fit:cover'd into it, so the
   centre of the image survives everywhere and an author uploads once
   instead of four times. aspect-ratio also reserves the space before
   the image loads, so there's no layout shift (DESIGN.md's performance
   rule) without hardcoding pixel heights. */

.cover-media {
  position: relative;
  width: 100%;
  overflow: hidden;
  border-radius: var(--radius-cards-inner);
  background: var(--color-surface-2);
}

.cover-media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* The post header banner is wider than any card and sits full-column. */
.post-hero {
  margin: var(--space-32) 0 var(--space-40);
  border-radius: var(--radius-cards);
}

/* Brand lockup, bottom-right of a cover — the v2 design's own device
   for making a shared or screenshotted card still read as ours. */
.cover-brand {
  position: absolute;
  right: 12px;
  bottom: 12px;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: var(--space-8);
  padding: 6px 13px 6px 8px;
  border-radius: var(--radius-tags);
  background: rgba(5, 4, 4, 0.58);
  border: 1px solid rgba(244, 236, 236, 0.14);
  backdrop-filter: blur(6px);
  pointer-events: none;
  font: 500 11px/1 var(--font-body);
  letter-spacing: 0.06em;
  color: var(--color-ink);
  white-space: nowrap;
}
.cover-brand img { position: static; width: 18px; height: 18px; border-radius: 5px; flex: none; }

/* Small cards get the mark alone — the wordmark is unreadable at card
   scale and just becomes noise over the image. */
.cover-brand-mark {
  right: 8px;
  bottom: 8px;
  padding: 5px;
  gap: 0;
}
.cover-brand-mark img { width: 14px; height: 14px; border-radius: 4px; }

.cover-pill {
  position: absolute;
  left: 14px;
  top: 14px;
  z-index: 2;
  font: 500 10px/1 var(--font-body);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 6px 12px;
  border-radius: var(--radius-tags);
  background: var(--color-accent);
  color: var(--color-white);
  white-space: nowrap;
}

/* With a cover present the card's own top padding would double the gap
   under the image, so the media sits flush to the card's inner edge. */
.post-card.has-cover .cover-media { margin-bottom: var(--space-4); }

@media (max-width: 760px) {
  /* 21:8 is a letterbox on a phone — barely 50px tall at 375px wide.
     The banner relaxes toward the card ratio so it still reads as an
     image rather than a stripe. */
  .post-hero { aspect-ratio: 3 / 2 !important; }
  .cover-brand { right: 8px; bottom: 8px; padding: 5px 10px 5px 6px; font-size: 10px; }
  .cover-brand img { width: 14px; height: 14px; }
}
