/* ─────────────────────────────────────────────────────────────────────────────
   CogniPage blog

   Loaded on top of brand.css + landing.css, so colours, fonts, buttons and the
   animated background all come from there; this file adds only the blog's own
   furniture — the index (hero, tag rail, lead card, grid), and the article
   (reading column, contents rail, and the typography the markdown renderer's
   output lands in).

   The section marked "Article body" is the one that matters most: every element
   under `.blog-body` is produced by app/services/markdown.py, so a selector
   here and a rule there are two halves of the same feature. Changing what the
   renderer emits means changing this block too.
   ───────────────────────────────────────────────────────────────────────── */

.blog-page {
  --blog-measure: 100%;
  --blog-toc: 220px;
  /* Clearance below the site's sticky navbar (~94px once it shrinks on scroll).
     Stated once because two separate things have to agree with it: where the
     contents rail pins, and where a heading lands when jumped to. If they
     disagree, clicking a contents link parks that heading under the navbar. */
  --blog-nav: 6.5rem;
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 3.5rem 1.5rem 5rem;
}

/* ── Index hero ──────────────────────────────────────────────────────────── */

.blog-hero { max-width: 720px; }
.blog-hero h1 {
  font-size: clamp(2.1rem, 4.5vw, 3.1rem);
  font-weight: 800;
  letter-spacing: -0.025em;
  margin: 0.85rem 0 0;
}
.blog-hero__lede {
  color: var(--muted);
  font-size: 1.08rem;
  line-height: 1.75;
  margin: 0.8rem 0 0;
}

.blog-search {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 1.6rem;
  max-width: 620px;
}
.blog-search svg {
  position: absolute;
  left: 1rem;
  top: 50%;
  transform: translateY(-50%);
  width: 18px;
  height: 18px;
  color: var(--muted);
  pointer-events: none;
}
.blog-search input {
  flex: 1;
  width: 100%;
  padding: 0.85rem 1rem 0.85rem 2.85rem;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface);
  color: var(--fg);
  font: inherit;
  font-size: 0.98rem;
}
.blog-search input:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 1px;
}
.blog-search .btn-sm { padding: 0.7rem 1.1rem; font-size: 0.92rem; }

/* ── Tag rail ────────────────────────────────────────────────────────────── */

.blog-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 2.2rem 0 0;
}
.blog-tag {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.42rem 0.85rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  color: var(--muted);
  font-size: 0.88rem;
  font-weight: 500;
  text-decoration: none;
  text-transform: capitalize;
  transition: border-color 0.15s, color 0.15s;
}
.blog-tag:hover { color: var(--fg); border-color: var(--primary); }
.blog-tag span {
  font-size: 0.78rem;
  color: var(--muted);
  opacity: 0.75;
}
.blog-tag.is-active {
  background: var(--primary);
  border-color: var(--primary);
  color: #fff;
}
.blog-tag.is-active span { color: #fff; }

/* ── Meta line (shared by cards and the article header) ──────────────────── */

.blog-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.45rem;
  margin: 0;
  color: var(--muted);
  font-size: 0.85rem;
}
.blog-meta__new {
  padding: 0.16rem 0.5rem;
  border-radius: 999px;
  background: color-mix(in srgb, var(--primary) 14%, transparent);
  color: var(--primary);
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.blog-byline { color: var(--fg); font-weight: 600; }

/* ── Lead card ───────────────────────────────────────────────────────────── */

.blog-lead {
  display: grid;
  grid-template-columns: 1.15fr 1fr;
  gap: 2.5rem;
  align-items: center;
  margin: 2.5rem 0 3.5rem;
  padding: 1.25rem;
  border: 1px solid var(--border);
  border-radius: 20px;
  background: var(--surface);
}
.blog-lead__media,
.blog-card__media {
  display: block;
  overflow: hidden;
  border-radius: 14px;
  background: color-mix(in srgb, var(--primary) 8%, var(--bg));
}
.blog-lead__media { aspect-ratio: 16 / 10; }
.blog-lead__media img,
.blog-card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 0.4s var(--ease, ease);
}
.blog-lead:hover .blog-lead__media img,
.blog-card:hover .blog-card__media img { transform: scale(1.03); }

/* A post with no cover gets a generated wash rather than a grey hole. */
.blog-lead__ph,
.blog-card__ph {
  display: block;
  width: 100%;
  height: 100%;
  background:
    radial-gradient(120% 90% at 15% 15%, color-mix(in srgb, var(--primary) 30%, transparent), transparent 60%),
    radial-gradient(110% 100% at 85% 80%, color-mix(in srgb, var(--secondary) 45%, transparent), transparent 62%);
}

.blog-lead__body h2 {
  font-size: clamp(1.5rem, 2.6vw, 2.1rem);
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.2;
  margin: 0.7rem 0 0;
}
.blog-lead__body h2 a,
.blog-card__body h3 a {
  color: inherit;
  text-decoration: none;
}
.blog-lead__body h2 a:hover,
.blog-card__body h3 a:hover { color: var(--primary); }
.blog-lead__excerpt {
  color: var(--muted);
  line-height: 1.7;
  margin: 0.7rem 0 0;
}
.blog-more {
  display: inline-block;
  margin-top: 1.1rem;
  color: var(--primary);
  font-weight: 600;
  text-decoration: none;
}
.blog-more:hover { text-decoration: underline; }

/* ── Card grid ───────────────────────────────────────────────────────────── */

.blog-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 1.75rem;
}
.blog-card {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border);
  border-radius: 18px;
  background: var(--surface);
  overflow: hidden;
  transition: transform 0.2s var(--ease, ease), border-color 0.2s;
}
.blog-card:hover { transform: translateY(-3px); border-color: var(--primary); }
.blog-card__media { aspect-ratio: 16 / 9; border-radius: 0; }
.blog-card__body { padding: 1.15rem 1.25rem 1.4rem; }
.blog-card__body h3 {
  font-size: 1.16rem;
  font-weight: 700;
  line-height: 1.35;
  letter-spacing: -0.01em;
  margin: 0.55rem 0 0;
}
.blog-card__excerpt {
  color: var(--muted);
  font-size: 0.94rem;
  line-height: 1.65;
  margin: 0.5rem 0 0;
  /* Three lines, so a long and a short excerpt still make level card bottoms. */
  display: -webkit-box;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.blog-card__tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin: 0.9rem 0 0;
}
.blog-card__tags span {
  padding: 0.2rem 0.55rem;
  border-radius: 999px;
  background: color-mix(in srgb, var(--primary) 10%, transparent);
  color: var(--primary);
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: capitalize;
}

.blog-empty {
  margin: 3rem 0;
  color: var(--muted);
  font-size: 1.05rem;
}

/* ── Pagination ──────────────────────────────────────────────────────────── */

.blog-pager {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 3rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--border);
}
.blog-pager__link {
  color: var(--primary);
  font-weight: 600;
  text-decoration: none;
}
.blog-pager__link:hover { text-decoration: underline; }
.blog-pager__count { color: var(--muted); font-size: 0.9rem; }

/* ── Article ─────────────────────────────────────────────────────────────── */

.blog-crumbs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  color: var(--muted);
  font-size: 0.86rem;
}
.blog-crumbs a { color: var(--muted); text-decoration: none; }
.blog-crumbs a:hover { color: var(--primary); }
.blog-crumbs span:last-child {
  color: var(--fg);
  max-width: 32ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.blog-post__head {
  max-width: var(--blog-measure);
  margin: 1.5rem 0 0;
}
.blog-post__tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.45rem;
  margin: 0 0 0.9rem;
}
.blog-post__tags a {
  padding: 0.28rem 0.7rem;
  border-radius: 999px;
  background: color-mix(in srgb, var(--primary) 12%, transparent);
  color: var(--primary);
  font-size: 0.8rem;
  font-weight: 600;
  text-decoration: none;
  text-transform: capitalize;
}
.blog-post__head h1 {
  font-size: clamp(2rem, 4.4vw, 3rem);
  font-weight: 800;
  letter-spacing: -0.028em;
  line-height: 1.14;
  margin: 0;
}
.blog-post__lede {
  color: var(--muted);
  font-size: 1.16rem;
  line-height: 1.7;
  margin: 1rem 0 0;
}
.blog-post__meta { margin-top: 1.2rem; }

.blog-post__cover {
  margin: 2.2rem 0 0;
  border-radius: 20px;
  overflow: hidden;
}
.blog-post__cover img {
  width: 100%;
  height: auto;
  display: block;
  max-height: 480px;
  object-fit: cover;
}
.blog-post__cover figcaption {
  margin-top: 0.6rem;
  color: var(--muted);
  font-size: 0.86rem;
}

/* Contents rail sits beside the column on wide screens and above it below. */
.blog-post__layout {
  display: grid;
  grid-template-columns: var(--blog-toc) minmax(0, 1fr);
  gap: 3rem;
  margin-top: 2.8rem;
  align-items: start;
}
.blog-post__layout:has(> .blog-body--wide) { grid-template-columns: minmax(0, 1fr); }

/* The rail pins to the *grid item*, not to the wrapper inside it.
   `align-items: start` above shrinks this column to its own content height, so
   a sticky element nested within it has nowhere to travel and scrolls straight
   off the top. A sticky grid item, by contrast, moves within its grid *area* —
   which spans the full height of the article beside it. */
.blog-toc {
  position: sticky;
  top: var(--blog-nav);
  align-self: start;
  /* Below the navbar's z-index, so a long rail slides under it, not over it. */
  z-index: 1;
}
.blog-toc__inner {
  /* A contents list taller than the screen scrolls on its own rather than
     forcing the reader back to the top of the article to reach the last entry. */
  max-height: calc(100vh - var(--blog-nav) - 2rem);
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
  /* Room for the active marker, which sits in the negative margin below. */
  padding-left: 0.7rem;
  margin-left: -0.7rem;
}
.blog-toc__title {
  margin: 0 0 0.7rem;
  color: var(--muted);
  font-size: 0.76rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
/* A continuous hairline the active marker slides along, so the highlight reads
   as "you are here in the article" rather than as a detached accent. */
.blog-toc ul {
  list-style: none;
  margin: 0;
  padding: 0 0 0 0.7rem;
  border-left: 2px solid var(--border);
}
.blog-toc li { margin: 0 0 0.5rem; }
.blog-toc__l3 { padding-left: 0.85rem; }
.blog-toc a {
  display: block;
  color: var(--muted);
  font-size: 0.9rem;
  line-height: 1.45;
  text-decoration: none;
  /* Pulls the marker onto the rail drawn by the list's border. */
  border-left: 2px solid transparent;
  padding-left: 0.7rem;
  margin-left: calc(-0.7rem - 2px);
  transition: color 0.18s, border-color 0.18s;
}
.blog-toc a:hover { color: var(--fg); border-left-color: var(--muted); }
.blog-toc a:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.blog-toc a.is-current {
  color: var(--primary);
  font-weight: 600;
  border-left-color: var(--primary);
}

/* ── Article body ────────────────────────────────────────────────────────────
   Everything below styles output from app/services/markdown.py. Nothing else
   writes these elements, so the two files change together.
   ───────────────────────────────────────────────────────────────────────── */

.blog-body {
  max-width: var(--blog-measure);
  color: var(--fg);
  font-size: 1.09rem;
  line-height: 1.78;
}
.blog-body--wide { margin: 0 auto; }

.blog-body > p { margin: 0 0 1.35rem; }
.blog-body > p:first-child { margin-top: 0; }

.blog-body h2,
.blog-body h3,
.blog-body h4 {
  position: relative;
  font-weight: 700;
  letter-spacing: -0.018em;
  line-height: 1.3;
  /* Anchored headings must clear the sticky navbar when jumped to, by the same
     amount the contents rail pins below it. */
  scroll-margin-top: var(--blog-nav);
}
.blog-body h2 { font-size: 1.65rem; margin: 2.8rem 0 0.9rem; }
.blog-body h3 { font-size: 1.28rem; margin: 2.2rem 0 0.7rem; }
.blog-body h4 { font-size: 1.08rem; margin: 1.8rem 0 0.6rem; }

/* The heading link is present for anyone who wants to copy it, and out of the
   way (and out of the accessibility tree's reading order) until hovered. */
.blog-anchor {
  position: absolute;
  left: -1.1rem;
  color: var(--primary);
  font-weight: 500;
  text-decoration: none;
  opacity: 0;
  transition: opacity 0.15s;
}
.blog-body h2:hover .blog-anchor,
.blog-body h3:hover .blog-anchor,
.blog-body h4:hover .blog-anchor,
.blog-anchor:focus-visible { opacity: 1; }

.blog-body a {
  color: var(--primary);
  text-decoration: underline;
  text-underline-offset: 2px;
  text-decoration-thickness: 1px;
}
.blog-body a:hover { text-decoration-thickness: 2px; }

.blog-body strong { font-weight: 700; }
.blog-body mark {
  background: color-mix(in srgb, var(--secondary) 55%, transparent);
  color: inherit;
  padding: 0.05em 0.2em;
  border-radius: 3px;
}

.blog-body ul,
.blog-body ol { margin: 0 0 1.35rem; padding-left: 1.4rem; }
.blog-body li { margin: 0 0 0.5rem; }
.blog-body li > ul,
.blog-body li > ol { margin: 0.5rem 0 0; }

.blog-body blockquote {
  margin: 1.8rem 0;
  padding: 0.2rem 0 0.2rem 1.4rem;
  border-left: 3px solid var(--primary);
  color: var(--muted);
  font-size: 1.1rem;
  font-style: italic;
}
.blog-body blockquote p:last-child { margin-bottom: 0; }

.blog-body code {
  padding: 0.15em 0.4em;
  border-radius: 5px;
  background: color-mix(in srgb, var(--primary) 12%, transparent);
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
  font-size: 0.88em;
}
.blog-body pre {
  margin: 1.6rem 0;
  padding: 1.1rem 1.25rem;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface);
  overflow-x: auto;
}
.blog-body pre code { padding: 0; background: none; font-size: 0.88rem; line-height: 1.6; }

.blog-body hr {
  margin: 2.5rem 0;
  border: none;
  border-top: 1px solid var(--border);
}

.blog-figure { margin: 2rem 0; }
.blog-figure img {
  width: 100%;
  height: auto;
  display: block;
  border-radius: 14px;
}
.blog-figure figcaption {
  margin-top: 0.65rem;
  color: var(--muted);
  font-size: 0.88rem;
  line-height: 1.6;
  text-align: center;
}

/* A 16:9 box the iframe fills, so the video reserves its space before it
   loads rather than shoving the rest of the article down when it arrives. */
.blog-embed--video {
  position: relative;
  aspect-ratio: 16 / 9;
  border-radius: 14px;
  overflow: hidden;
  background: #000;
  margin: 2rem 0;
}
.blog-figure .blog-embed--video { margin: 0; }
.blog-embed--video iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

/* Wide tables scroll inside their own box; the article never scrolls sideways. */
.blog-table {
  margin: 1.8rem 0;
  overflow-x: auto;
  border: 1px solid var(--border);
  border-radius: 12px;
}
.blog-table table { width: 100%; border-collapse: collapse; font-size: 0.95rem; }
.blog-table th,
.blog-table td {
  padding: 0.7rem 0.9rem;
  text-align: left;
  border-bottom: 1px solid var(--border);
}
.blog-table th {
  background: color-mix(in srgb, var(--primary) 7%, transparent);
  font-weight: 700;
}
.blog-table tr:last-child td { border-bottom: none; }

/* ── Article footer ──────────────────────────────────────────────────────── */

.blog-post__foot {
  margin-top: 3rem;
  padding-top: 1.8rem;
  border-top: 1px solid var(--border);
}
.blog-author__name { margin: 0; font-weight: 700; }
.blog-author__bio { margin: 0.35rem 0 0; color: var(--muted); line-height: 1.7; }

.blog-share {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.7rem;
  margin-top: 1.6rem;
}
.blog-share span { color: var(--muted); font-size: 0.88rem; }
.blog-share a {
  padding: 0.35rem 0.8rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--muted);
  font-size: 0.85rem;
  font-weight: 600;
  text-decoration: none;
}
.blog-share a:hover { color: var(--primary); border-color: var(--primary); }

/* ── Closing call to action ──────────────────────────────────────────────── */

.blog-cta {
  margin-top: 4rem;
  padding: 2.75rem 2rem;
  border: 1px solid var(--border);
  border-radius: 20px;
  background:
    radial-gradient(90% 140% at 12% 0%, color-mix(in srgb, var(--primary) 12%, transparent), transparent 65%),
    var(--surface);
  text-align: center;
}
.blog-cta h2 {
  font-size: clamp(1.4rem, 2.6vw, 1.9rem);
  font-weight: 800;
  letter-spacing: -0.02em;
  margin: 0;
}
.blog-cta p {
  max-width: 46rem;
  margin: 0.8rem auto 1.6rem;
  color: var(--muted);
  line-height: 1.7;
}
.blog-cta__alt {
  display: inline-block;
  margin-left: 1rem;
  color: var(--primary);
  font-weight: 600;
  text-decoration: none;
}
.blog-cta__alt:hover { text-decoration: underline; }

.blog-related { margin-top: 4rem; }
.blog-related h2 {
  font-size: 1.5rem;
  font-weight: 800;
  letter-spacing: -0.02em;
  margin: 0 0 1.5rem;
}

/* ── Responsive ──────────────────────────────────────────────────────────── */

@media (max-width: 980px) {
  .blog-post__layout { grid-template-columns: minmax(0, 1fr); gap: 1.8rem; }
  /* Stacked above the article, the rail is a normal block: pinning it here
     would cost a phone a third of its screen for the whole read. */
  .blog-toc { position: static; }
  .blog-toc__inner {
    max-height: none;
    overflow: visible;
    margin-left: 0;
    padding: 1rem 1.15rem;
    border: 1px solid var(--border);
    border-radius: 14px;
    background: var(--surface);
  }
  .blog-lead { grid-template-columns: 1fr; gap: 1.4rem; }
}

@media (max-width: 620px) {
  .blog-page { padding: 2.5rem 1.1rem 3.5rem; }
  .blog-search { flex-wrap: wrap; }
  .blog-search input { min-width: 0; }
  .blog-body { font-size: 1.04rem; }
  .blog-anchor { display: none; }
  .blog-cta { padding: 2rem 1.25rem; }
  .blog-cta__alt { display: block; margin: 1rem 0 0; }
}

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