/* public/css/blog.css  (BLOG-01)
 *
 * The blog platform's design system. Loaded by views/layouts/main.ejs only for
 * `type` values 'blog' and 'blog-single', the same way the video player CSS is
 * loaded only for the portal pages — so no other page pays for it.
 *
 * Everything is scoped under `.blog-page` (index, category, tag and author
 * archives) or `.article-page` (a single post). Both classes are set on the
 * <body> of the blog templates, so none of this can leak into admin, landing
 * or product pages.
 *
 * Why hand-authored CSS and not Tailwind:
 * public/css/output.css is a committed build with no rebuild step in
 * `npm start`, so a newly-invented utility class would simply not exist at
 * runtime. This file is linked AFTER output.css, so it also wins cascade ties
 * without needing !important.
 *
 * ---------------------------------------------------------------------------
 * Design direction — "the record"
 *
 * Pooyesh sells systems that turn raw attendance, asset and cheque records into
 * structured reports, and its articles are long procedural guides. So the blog
 * is built like a well-kept register: article rows with aligned metadata under
 * hairline rules, and a spine running down the reading edge of an article with
 * a square marker at every section heading. In RTL that spine sits on the
 * right — the edge a Persian reader starts from. The spine is the one loud
 * idea on the page; everything around it stays deliberately quiet.
 *
 * Type personality comes from scale, weight and measure rather than from a
 * display face: global.css sets `* { font-family: 'IranSans' !important }`,
 * and shipping a second Persian webfont to fight it would cost more than it
 * returns.
 * ---------------------------------------------------------------------------
 */

.blog-page,
.article-page {
  --bl-ink: #18181B;
  --bl-body: #3F3F46;
  --bl-muted: #71717A;
  --bl-faint: #A1A1AA;
  --bl-rule: #E4E4E7;
  --bl-rule-soft: #F4F4F5;
  --bl-accent: #0C66E4;
  --bl-accent-dark: #0A56C4;
  --bl-tint: #EBF3FE;
  --bl-tint-line: #C7D9F7;
  --bl-surface: #FAFAFA;
  --bl-radius: 10px;
}

/* ================================================================== LAYOUT
 * The blog owns its own grid rather than borrowing Tailwind utilities.
 *
 * That is not a stylistic preference: the committed output.css does not
 * contain `space-y-6`, `sr-only`, `line-clamp-3` or `lg:sticky`, all of which
 * the previous blog markup referenced. Because there is no Tailwind rebuild at
 * runtime, those classes silently did nothing. Defining the layout here means
 * what the markup says is what the browser gets.
 * ========================================================================= */

.blog-shell { max-width: 1280px; margin-inline: auto; padding-inline: 1rem; }
@media (min-width: 768px)  { .blog-shell { padding-inline: 2rem; } }
@media (min-width: 1024px) { .blog-shell { padding-inline: 4rem; } }

.blog-layout { display: grid; grid-template-columns: 1fr; gap: 2.5rem; }
@media (min-width: 1024px) {
  .blog-layout { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); gap: 3rem; }
}
.blog-layout__main { min-width: 0; }
.blog-layout__rail { min-width: 0; }

/* The rail does NOT scroll on its own.
 *
 * It used to be `position: sticky` with `max-height: calc(100vh - 96px)` and
 * `overflow-y: auto`, which gave the sidebar its own scrollbar — a second
 * scrolling region inside a page that already scrolls. On a long article the
 * rail (contents + product + related + lead form) is taller than the viewport,
 * so the reader had to scroll the page to reach the article and a separate
 * inner track to reach the rest of the sidebar.
 *
 * Sticking the whole rail without that clamp is worse, not better: anything
 * past the fold becomes unreachable entirely, because a stuck element does not
 * move no matter how far the page scrolls.
 *
 * So the rail flows with the page — every panel reachable by scrolling
 * normally — and only the FIRST panel is sticky. That is the table of contents,
 * the one thing worth keeping in view while reading. It travels down inside the
 * rail's own box and stops naturally when the rail ends, which is roughly where
 * the article ends. No second scrollbar anywhere.
 */
@media (min-width: 1024px) {
  .blog-layout__rail { align-self: start; }
}

.blog-grid { display: grid; grid-template-columns: 1fr; gap: 1.75rem; }
@media (min-width: 640px)  { .blog-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1024px) { .blog-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

.blog-stack > * + * { margin-top: 0; }

/* Visually hidden but available to screen readers. */
.blog-page .sr-only,
.article-page .sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* ============================================================ ARTICLE PROSE
 * Long-form typography.
 *
 * Deliberately separate from `.rich-content`, which styles short CMS snippets
 * inside landing accordions. Those need four rules; a 1 800-word Persian guide
 * needs a measure, a heading scale, anchor scroll offsets, table overflow and
 * list markers that survive Tailwind's Preflight reset.
 *
 * Persian specifics: taller leading than Latin prose, a slightly larger base
 * size, and start-alignment rather than justification — justified Persian
 * without hyphenation opens rivers of whitespace.
 * ========================================================================= */

.article-page .article-prose {
  color: var(--bl-body);
  font-size: 1.0625rem;
  line-height: 1.95;
  max-width: 68ch;
  overflow-wrap: break-word;
  text-align: start;
}

.article-page .article-prose > *:last-child { margin-block-end: 0; }

.article-page .article-prose h2,
.article-page .article-prose h3,
.article-page .article-prose h4 {
  color: var(--bl-ink);
  font-weight: 800;
  letter-spacing: -0.012em;
  line-height: 1.6;
  /* Table-of-contents jumps must not land under the sticky site header. */
  scroll-margin-top: 96px;
}

.article-page .article-prose h2 { font-size: 1.5rem;    margin: 2.2em 0 0.7em; }
.article-page .article-prose h3 { font-size: 1.1875rem; margin: 1.7em 0 0.55em; }
.article-page .article-prose h4 { font-size: 1.0625rem; margin: 1.4em 0 0.5em; }
.article-page .article-prose > h2:first-child,
.article-page .article-prose > h3:first-child { margin-top: 0; }

.article-page .article-prose p { margin: 0 0 1.15em; }

.article-page .article-prose strong,
.article-page .article-prose b { color: var(--bl-ink); font-weight: 700; }

.article-page .article-prose a {
  color: var(--bl-accent);
  text-decoration: underline;
  text-underline-offset: 4px;
  text-decoration-thickness: 1px;
}
.article-page .article-prose a:hover { text-decoration-thickness: 2px; }

/* Preflight zeroes list styling; long-form needs it back. */
.article-page .article-prose ul,
.article-page .article-prose ol {
  padding-inline-start: 1.4em;
  margin: 0 0 1.15em;
}
.article-page .article-prose ul { list-style: disc; }
.article-page .article-prose ol { list-style: decimal; }
.article-page .article-prose li { margin-bottom: 0.45em; padding-inline-start: 0.2em; }
.article-page .article-prose li::marker { color: var(--bl-accent); }
.article-page .article-prose li > ul,
.article-page .article-prose li > ol { margin: 0.45em 0 0; }

.article-page .article-prose blockquote {
  border-inline-start: 3px solid var(--bl-accent);
  background: var(--bl-tint);
  border-radius: 0 var(--bl-radius) var(--bl-radius) 0;
  padding: 1em 1.25em;
  margin: 1.6em 0;
  color: var(--bl-ink);
}
.article-page .article-prose blockquote p:last-child { margin-bottom: 0; }

.article-page .article-prose img {
  max-width: 100%;
  height: auto;
  border-radius: var(--bl-radius);
  display: block;
  margin: 1.6em auto;
}
.article-page .article-prose figure { margin: 1.6em 0; }
.article-page .article-prose figcaption {
  color: var(--bl-muted);
  font-size: 0.8125rem;
  text-align: center;
  margin-top: 0.6em;
}

.article-page .article-prose hr {
  border: 0;
  border-top: 1px solid var(--bl-rule);
  margin: 2.2em 0;
}

/* Code keeps a monospace face and LTR flow. The global
 * `* { font-family: 'IranSans' !important }` has to be overridden explicitly. */
.article-page .article-prose code,
/* Embedded media. Editors paste YouTube/Aparat iframes into article bodies and
   those carry hardcoded width/height attributes, so on a phone they pushed the
   whole page sideways. Nothing else in the prose had this problem because
   images were already constrained. */
.article-page .article-prose iframe,
.article-page .article-prose video,
.article-page .article-prose embed,
.article-page .article-prose object {
  display: block;
  width: 100%;
  max-width: 100%;
  aspect-ratio: 16 / 9;
  height: auto;
  border: 0;
  border-radius: var(--bl-radius);
  margin: 1.6em 0;
}

.article-page .article-prose pre {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace !important;
  direction: ltr;
  unicode-bidi: isolate;
}
.article-page .article-prose code {
  background: var(--bl-rule-soft);
  border: 1px solid var(--bl-rule);
  border-radius: 5px;
  padding: 0.12em 0.4em;
  font-size: 0.875em;
}
.article-page .article-prose pre {
  background: #18181B;
  color: #F4F4F5;
  border-radius: var(--bl-radius);
  padding: 1em 1.15em;
  overflow-x: auto;
  margin: 1.6em 0;
}
.article-page .article-prose pre code { background: none; border: 0; padding: 0; color: inherit; }

/* Tables. src/utils/articleContent.js wraps every <table> in `.article-scroll`
 * so a wide table scrolls inside its own box and the page never scrolls
 * sideways on mobile. */
.article-page .article-scroll {
  overflow-x: auto;
  margin: 1.6em 0;
  border: 1px solid var(--bl-rule);
  border-radius: var(--bl-radius);
  -webkit-overflow-scrolling: touch;
}
.article-page .article-prose table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9375rem;
}
.article-page .article-prose th,
.article-page .article-prose td {
  border-bottom: 1px solid var(--bl-rule);
  padding: 0.7em 0.9em;
  text-align: start;
  /* global.css sets `td, th { white-space: nowrap }` for admin data grids;
   * article tables must wrap. */
  white-space: normal;
}
.article-page .article-prose thead th {
  background: var(--bl-surface);
  color: var(--bl-ink);
  font-weight: 700;
}
.article-page .article-prose tbody tr:last-child td { border-bottom: 0; }

/* --- the spine ------------------------------------------------------------
 * A hairline down the reading edge with a square marker at each H2. Squares
 * rather than dots: this is a register of sections, not a timeline. Hidden
 * below `lg`, where the column is too narrow to spare the indent. */
@media (min-width: 1024px) {
  .article-page .article-prose--spine {
    border-inline-start: 1px solid var(--bl-rule);
    padding-inline-start: 1.75rem;
  }
  .article-page .article-prose--spine h2 { position: relative; }
  .article-page .article-prose--spine h2::before {
    content: "";
    position: absolute;
    inset-inline-start: -2.1rem;
    top: 0.72em;
    width: 9px;
    height: 9px;
    background: var(--bl-accent);
    border-radius: 2px;
  }
}

/* =================================================================== CARD
 * ONE card component for every blog surface. `variant` in
 * views/partials/blog/card.ejs picks a modifier. There is deliberately no
 * second copy of this markup in JavaScript — the previous implementation had
 * the card in both EJS and a template string in blog.js, and the two had
 * already drifted apart.
 * ========================================================================= */

.blog-card {
  position: relative;
  border-radius: var(--bl-radius);
}
.blog-card:focus-within { outline: 2px solid var(--bl-accent); outline-offset: 4px; }

/* Stretched link keeps the whole card clickable while the byline and category
 * links inside it stay independently focusable (they sit at a higher z-index). */
.blog-card__link { position: absolute; inset: 0; z-index: 5; }

.blog-card__media {
  position: relative;
  overflow: hidden;
  border-radius: var(--bl-radius);
  background: var(--bl-rule-soft);
  flex-shrink: 0;
}
.blog-card__media img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 0.4s ease;
}
.blog-card:hover .blog-card__media img { transform: scale(1.04); }
.blog-card__placeholder {
  width: 100%; height: 100%;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, #EBF3FE 0%, #F4F4F5 100%);
  color: var(--bl-tint-line);
}
.blog-card__title {
  color: var(--bl-ink);
  font-weight: 700;
  line-height: 1.65;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  transition: color 0.15s ease;
}
.blog-card:hover .blog-card__title { color: var(--bl-accent); }
.blog-card__excerpt {
  color: var(--bl-muted);
  font-size: 0.875rem;
  line-height: 1.9;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.blog-card__meta {
  display: flex; align-items: center; flex-wrap: wrap;
  gap: 0.4rem 0.7rem;
  color: var(--bl-faint);
  font-size: 0.75rem;
}
.blog-card__meta a { position: relative; z-index: 10; color: inherit; }
.blog-card__meta a:hover { color: var(--bl-accent); }
.blog-card__dot { width: 3px; height: 3px; border-radius: 50%; background: currentColor; opacity: 0.55; }

/* Row variant — the register row. Thumbnail, then an aligned column of
 * title / excerpt / metadata, separated by a hairline rather than a border. */
.blog-card--row {
  display: flex; gap: 1.25rem;
  padding: 1.5rem 0;
  border-bottom: 1px solid var(--bl-rule);
}
.blog-card--row .blog-card__media { width: 200px; aspect-ratio: 4 / 3; }
.blog-card--row .blog-card__body { min-width: 0; display: flex; flex-direction: column; flex: 1; }
.blog-card--row .blog-card__title { font-size: 1.0625rem; margin: 0.5rem 0 0.45rem; }
.blog-card--row .blog-card__meta { margin-top: auto; padding-top: 0.75rem; }

/* Lead variant — the newest article, given real weight so a slow-publishing
 * B2B blog does not read as abandoned. */
.blog-card--lead { padding-bottom: 1.75rem; border-bottom: 1px solid var(--bl-rule); }
.blog-card--lead .blog-card__media { aspect-ratio: 16 / 8; margin-bottom: 1.25rem; }
.blog-card--lead .blog-card__title {
  font-size: 1.5rem; line-height: 1.55; -webkit-line-clamp: 3;
  letter-spacing: -0.01em; margin-bottom: 0.6rem;
}
.blog-card--lead .blog-card__excerpt { -webkit-line-clamp: 3; font-size: 0.9375rem; }
.blog-card--lead .blog-card__meta { margin-top: 1rem; }

/* Grid variant — related posts and taxonomy archives. */
.blog-card--grid { display: flex; flex-direction: column; height: 100%; }
.blog-card--grid .blog-card__media { aspect-ratio: 16 / 9; margin-bottom: 0.9rem; }
.blog-card--grid .blog-card__title { font-size: 0.9375rem; margin-bottom: 0.5rem; }
.blog-card--grid .blog-card__meta { margin-top: auto; padding-top: 0.75rem; }

/* Compact variant — sidebar lists. Numbered, because ranking by readership is
 * a genuine ordering and the number carries information the reader uses. */
.blog-card--compact { display: flex; gap: 0.75rem; padding: 0.85rem 0; border-bottom: 1px solid var(--bl-rule-soft); }
.blog-card--compact:last-child { border-bottom: 0; }
.blog-card--compact .blog-card__rank {
  color: #fff;
  font-size: 1.375rem; font-weight: 800; line-height: 1.3;
  flex-shrink: 0; min-width: 1.4rem;
  -webkit-text-stroke: 1px var(--bl-tint-line);
}
.blog-card--compact .blog-card__title { font-size: 0.8125rem; line-height: 1.8; }
.blog-card--compact .blog-card__meta { margin-top: 0.35rem; font-size: 0.6875rem; }

@media (max-width: 640px) {
  .blog-card--row { gap: 0.9rem; padding: 1.15rem 0; }
  .blog-card--row .blog-card__media { width: 108px; aspect-ratio: 1 / 1; }
  .blog-card--row .blog-card__title { font-size: 0.9375rem; margin-top: 0.35rem; }
  .blog-card--row .blog-card__excerpt { display: none; }
  .blog-card--lead .blog-card__title { font-size: 1.1875rem; }
  .blog-card--lead .blog-card__media { aspect-ratio: 16 / 9; }
}

/* =================================================================== CHIPS
 * Category and tag pills. Real <a> elements: the old JS-only filter buttons
 * gave crawlers no path to a category and gave users no shareable URL.
 * ========================================================================= */

.blog-chips { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.blog-chips--scroll { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; padding-bottom: 0.25rem; }
.blog-chips--scroll::-webkit-scrollbar { display: none; }

.blog-chip {
  display: inline-flex; align-items: center; gap: 0.375rem;
  padding: 0.3rem 0.85rem;
  border-radius: 999px;
  border: 1px solid var(--bl-rule);
  background: #fff;
  color: var(--bl-body);
  font-size: 0.8125rem;
  line-height: 1.9;
  white-space: nowrap;
  transition: all 0.15s ease;
}
.blog-chip:hover { border-color: var(--bl-accent); color: var(--bl-accent); }
.blog-chip[aria-current="page"] {
  background: var(--bl-tint);
  border-color: transparent;
  color: var(--bl-accent);
  font-weight: 700;
}
.blog-chip__count { color: var(--bl-faint); font-size: 0.6875rem; }
.blog-chip[aria-current="page"] .blog-chip__count { color: var(--bl-accent); opacity: 0.7; }

/* Badge form — sits on a card, so it must not look pressable. */
.blog-badge {
  display: inline-flex; align-items: center;
  padding: 0.15rem 0.6rem;
  border-radius: 999px;
  background: var(--bl-tint);
  color: var(--bl-accent);
  font-size: 0.6875rem; font-weight: 700;
  position: relative; z-index: 10;
}

/* ===================================================== TABLE OF CONTENTS
 * Rendered only when the article has three or more headings — a two-item TOC
 * is decoration, not navigation.
 * ========================================================================= */

.blog-toc { position: sticky; top: 88px; }
.blog-toc__title {
  font-size: 0.8125rem; font-weight: 800; color: var(--bl-ink);
  margin-bottom: 0.85rem;
  display: flex; align-items: center; gap: 0.5rem;
}
.blog-toc__list { max-height: 58vh; overflow-y: auto; scrollbar-width: thin; }
.blog-toc__link {
  display: block;
  border-inline-start: 2px solid var(--bl-rule);
  padding: 0.4rem 0.85rem;
  color: var(--bl-muted);
  font-size: 0.8125rem; line-height: 1.75;
  transition: all 0.15s ease;
}
.blog-toc__link:hover { color: var(--bl-accent); border-inline-start-color: var(--bl-tint-line); }
.blog-toc__link--sub { padding-inline-start: 1.6rem; font-size: 0.75rem; }
.blog-toc__link.is-active {
  color: var(--bl-accent);
  border-inline-start-color: var(--bl-accent);
  font-weight: 700;
  background: linear-gradient(to left, transparent, var(--bl-tint));
}

/* ================================================================= PRODUCT
 * The article → product bridge: commercially, the reason the blog exists.
 * ========================================================================= */

.blog-prod {
  border: 1px solid var(--bl-rule);
  border-radius: 14px;
  background: #fff;
  overflow: hidden;
}
.blog-prod__label {
  display: flex; align-items: center; gap: 0.4rem;
  background: var(--bl-tint);
  color: var(--bl-accent);
  font-size: 0.6875rem; font-weight: 700;
  padding: 0.5rem 1rem;
}
.blog-prod__body { padding: 1rem; display: flex; gap: 1rem; align-items: flex-start; }
.blog-prod__media {
  width: 76px; height: 76px; flex-shrink: 0;
  border-radius: 10px; overflow: hidden;
  background: var(--bl-rule-soft);
  display: flex; align-items: center; justify-content: center;
  color: var(--bl-tint-line);
}
.blog-prod__media img { width: 100%; height: 100%; object-fit: cover; }
.blog-prod__name { color: var(--bl-ink); font-weight: 700; font-size: 0.9375rem; line-height: 1.7; }
.blog-prod__desc {
  color: var(--bl-muted); font-size: 0.8125rem; line-height: 1.85; margin-top: 0.3rem;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.blog-prod__actions { display: flex; flex-wrap: wrap; gap: 0.5rem; padding: 0 1rem 1rem; }

/* Inline variant — sits inside the reading flow, so it is quieter than the
 * end-of-article block and never wider than the text measure. */
.blog-prod--inline { margin: 2.25rem 0; max-width: 68ch; }

/* Sidebar variant — stacked and narrower. */
.blog-prod--aside .blog-prod__body { flex-direction: column; gap: 0.75rem; }
.blog-prod--aside .blog-prod__media { width: 100%; height: 116px; border-radius: 8px; }
.blog-prod--aside .blog-prod__actions { padding-top: 0; }

/* ================================================================= BUTTONS */

.blog-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.4rem;
  padding: 0.55rem 1rem;
  border-radius: 8px;
  font-size: 0.8125rem; font-weight: 700;
  transition: all 0.15s ease;
  border: 1px solid transparent;
  position: relative; z-index: 10;
  cursor: pointer;
}
.blog-btn--primary { background: var(--bl-accent); color: #fff; }
.blog-btn--primary:hover { background: var(--bl-accent-dark); color: #fff; }
.blog-btn--ghost { border-color: var(--bl-rule); color: var(--bl-body); background: #fff; }
.blog-btn--ghost:hover { border-color: var(--bl-accent); color: var(--bl-accent); }
.blog-btn:focus-visible { outline: 2px solid var(--bl-accent); outline-offset: 2px; }
.blog-btn[disabled] { opacity: 0.6; pointer-events: none; }

/* ===================================================================== CTA
 * End-of-article conversion block: one per page, immediately after the last
 * paragraph, where a reader who finished the guide decides what to do next.
 * ========================================================================= */

.blog-cta {
  border-radius: 16px;
  background: var(--bl-tint);
  padding: 1.75rem;
  margin: 2.5rem 0;
  max-width: 68ch;
}
.blog-cta__eyebrow { color: var(--bl-accent); font-size: 0.75rem; font-weight: 700; }
.blog-cta__title { color: var(--bl-ink); font-size: 1.1875rem; font-weight: 800; line-height: 1.7; margin: 0.5rem 0 0.6rem; }
.blog-cta__text { color: var(--bl-body); font-size: 0.875rem; line-height: 1.95; margin-bottom: 1.25rem; }
.blog-cta__actions { display: flex; flex-wrap: wrap; gap: 0.6rem; }

/* Lead strip — the only conversion surface on listing pages. */
.blog-lead {
  border: 1px solid var(--bl-rule);
  border-radius: 14px;
  background: #fff;
  padding: 1.25rem;
}
.blog-lead__title { color: var(--bl-ink); font-size: 0.9375rem; font-weight: 700; line-height: 1.7; }
.blog-lead__text { color: var(--bl-muted); font-size: 0.8125rem; line-height: 1.9; margin: 0.4rem 0 0.9rem; }
.blog-lead__form { display: flex; gap: 0.5rem; }
.blog-lead__input {
  flex: 1; min-width: 0;
  height: 42px; padding-inline: 0.85rem;
  border: 1px solid var(--bl-rule); border-radius: 8px;
  font-size: 0.8125rem; color: var(--bl-ink);
  background: #fff;
}
.blog-lead__input:focus { outline: none; border-color: var(--bl-accent); }
.blog-lead__msg { font-size: 0.75rem; line-height: 1.85; margin-top: 0.6rem; }
.blog-lead__msg--ok { color: #15803D; }
.blog-lead__msg--err { color: #B91C1C; }

/* ================================================================= SIDEBAR
 * Panels share one shell so the rail reads as a single column rather than
 * five unrelated widgets.
 * ========================================================================= */

.blog-panel { padding: 1.5rem 0; border-bottom: 1px solid var(--bl-rule); }
.blog-panel:first-child { padding-top: 0; }
.blog-panel:last-child { border-bottom: 0; }
.blog-panel__title {
  color: var(--bl-ink); font-size: 0.9375rem; font-weight: 800;
  margin-bottom: 0.85rem;
  display: flex; align-items: center; justify-content: space-between; gap: 0.5rem;
}
.blog-panel__more { color: var(--bl-accent); font-size: 0.75rem; font-weight: 400; }

/* ============================================================== PAGINATION */

.blog-pager { display: flex; align-items: center; justify-content: center; gap: 0.4rem; flex-wrap: wrap; }
.blog-pager a,
.blog-pager span {
  min-width: 38px; height: 38px;
  display: inline-flex; align-items: center; justify-content: center;
  padding-inline: 0.6rem;
  border-radius: 8px;
  border: 1px solid var(--bl-rule);
  color: var(--bl-body);
  font-size: 0.8125rem;
}
.blog-pager a:hover { border-color: var(--bl-accent); color: var(--bl-accent); }
.blog-pager [aria-current="page"] { background: var(--bl-accent); border-color: var(--bl-accent); color: #fff; font-weight: 700; }
.blog-pager .is-disabled { opacity: 0.4; pointer-events: none; }
.blog-pager .blog-pager__gap { border: 0; min-width: 1.25rem; color: var(--bl-faint); }

/* ============================================================= EMPTY STATE
 * An empty screen is an invitation to act, so every one of these carries a
 * next step rather than an apology.
 * ========================================================================= */

.blog-empty { text-align: center; padding: 3.5rem 1rem; }
.blog-empty__title { color: var(--bl-ink); font-size: 1rem; font-weight: 700; margin-bottom: 0.4rem; }
.blog-empty__text { color: var(--bl-muted); font-size: 0.875rem; line-height: 1.95; }
.blog-empty__actions { display: flex; flex-wrap: wrap; gap: 0.5rem; justify-content: center; margin-top: 1.25rem; }

/* ================================================================= ARTICLE
 * Header block, byline and author card.
 * ========================================================================= */

.article-page .article-head { max-width: 68ch; }
.article-page .article-title {
  color: var(--bl-ink);
  font-size: clamp(1.5rem, 1.05rem + 1.9vw, 2.25rem);
  font-weight: 800;
  line-height: 1.6;
  letter-spacing: -0.015em;
  margin: 0.9rem 0 0.85rem;
}
.article-page .article-standfirst {
  color: var(--bl-body);
  font-size: 1.0625rem;
  line-height: 1.95;
  padding-inline-start: 0.9rem;
  border-inline-start: 3px solid var(--bl-tint);
}
.article-page .article-byline {
  display: flex; align-items: center; flex-wrap: wrap; gap: 0.75rem;
  color: var(--bl-muted); font-size: 0.8125rem;
  padding: 1.1rem 0;
  border-top: 1px solid var(--bl-rule);
  border-bottom: 1px solid var(--bl-rule);
  margin: 1.5rem 0;
}
.article-page .article-byline a { color: var(--bl-ink); font-weight: 700; }
.article-page .article-byline a:hover { color: var(--bl-accent); }
.article-page .article-byline__avatar {
  width: 32px; height: 32px; border-radius: 50%; overflow: hidden;
  background: var(--bl-rule-soft);
  display: flex; align-items: center; justify-content: center;
  color: var(--bl-faint); flex-shrink: 0;
}
.article-page .article-byline__avatar img { width: 100%; height: 100%; object-fit: cover; }

.article-page .article-hero {
  border-radius: 14px; overflow: hidden;
  aspect-ratio: 16 / 8; background: var(--bl-rule-soft);
  margin-bottom: 2rem;
}
/* 16:8 is a 195px-tall letterbox on a 390px phone. A little taller reads as an
   image rather than a banner. */
@media (max-width: 640px) {
  .article-page .article-hero { aspect-ratio: 16 / 10; margin-bottom: 1.5rem; }
}
.article-page .article-hero img { width: 100%; height: 100%; object-fit: cover; display: block; }

.article-author {
  display: flex; gap: 1rem;
  border: 1px solid var(--bl-rule); border-radius: 14px;
  padding: 1.25rem;
  margin: 2.5rem 0;
  max-width: 68ch;
}
.article-author__avatar {
  width: 56px; height: 56px; flex-shrink: 0;
  border-radius: 50%; overflow: hidden;
  background: var(--bl-rule-soft);
  display: flex; align-items: center; justify-content: center;
  color: var(--bl-faint);
}
.article-author__avatar img { width: 100%; height: 100%; object-fit: cover; }
.article-author__name { color: var(--bl-ink); font-weight: 700; font-size: 0.9375rem; }
.article-author__role { color: var(--bl-accent); font-size: 0.75rem; margin-top: 0.15rem; }
.article-author__bio { color: var(--bl-muted); font-size: 0.8125rem; line-height: 1.95; margin-top: 0.5rem; }
.article-author__link { display: inline-block; color: var(--bl-accent); font-size: 0.8125rem; margin-top: 0.6rem; }

/* Breadcrumb — mirrors the BreadcrumbList trail exactly. */
.blog-crumbs { display: flex; align-items: center; flex-wrap: wrap; gap: 0.4rem; color: var(--bl-faint); font-size: 0.75rem; }
.blog-crumbs a { color: var(--bl-muted); }
.blog-crumbs a:hover { color: var(--bl-accent); }
.blog-crumbs__sep { opacity: 0.5; }
.blog-crumbs__current {
  color: var(--bl-body);
  max-width: 22rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ================================================================ MASTHEAD
 * Listing-page header. Reuses the existing `.blog-section` artwork.
 * ========================================================================= */

/* Masthead padding lived in three inline `style` attributes with two
   different values, so it could not respond to viewport at all. */
.blog-masthead { padding: 5.25rem 1rem 2.75rem; }
@media (min-width: 768px)  { .blog-masthead { padding: 6rem 1rem 3.5rem; } }
@media (min-width: 1024px) { .blog-masthead { padding: 6.5rem 1rem 4rem; } }

.blog-masthead__eyebrow {
  display: inline-flex; align-items: center;
  background: rgba(255, 255, 255, 0.16);
  border: 1px solid rgba(255, 255, 255, 0.22);
  color: #fff; border-radius: 999px;
  padding: 0.25rem 0.85rem; font-size: 0.6875rem;
}
.blog-masthead__title {
  color: #fff;
  font-size: clamp(1.375rem, 1rem + 1.6vw, 2rem);
  font-weight: 800; line-height: 1.6; letter-spacing: -0.015em;
}
.blog-masthead__text { color: rgba(255, 255, 255, 0.72); font-size: 0.875rem; line-height: 1.95; }

/* ==================================================================== MISC */

.blog-share { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.blog-share__btn {
  width: 38px; height: 38px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--bl-rule); border-radius: 8px;
  color: var(--bl-muted); background: #fff;
  transition: all 0.15s ease; cursor: pointer;
}
.blog-share__btn:hover { border-color: var(--bl-accent); color: var(--bl-accent); }

/* Reading progress — a hairline at the top of the viewport. Ties back to the
 * spine idea without adding another visible widget. */
.article-progress {
  position: fixed; top: 0; left: 0; right: 0;
  height: 2px; z-index: 60;
  background: var(--bl-accent);
  transform-origin: right center;
  transform: scaleX(0);
  transition: transform 0.1s linear;
}

@media (prefers-reduced-motion: reduce) {
  .blog-card__media img,
  .blog-card__title,
  .blog-chip,
  .blog-btn,
  .blog-toc__link,
  .article-progress { transition: none !important; }
  .blog-card:hover .blog-card__media img { transform: none; }
}

/* ============================================================ REPORT MODAL
 * Moved out of a <style> block that lived inside views/blog-single.ejs's
 * second (nested) <head>. Browsers hoisted it, but it was invalid markup and
 * unreachable from any other page.
 * ========================================================================= */

.report-modal-overlay {
  position: fixed; inset: 0;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex; align-items: center; justify-content: center;
  z-index: 1000;
  opacity: 0; visibility: hidden;
  transition: all 0.3s ease;
}
.report-modal-overlay.active { opacity: 1; visibility: visible; }
.report-modal-container {
  background: #fff; border-radius: 20px;
  width: 90%; max-width: 500px; max-height: 85vh;
  display: flex; flex-direction: column; overflow: hidden;
}
.report-modal-body { overflow-y: auto; flex-grow: 1; padding: 20px; }
.report-modal-body::-webkit-scrollbar { width: 6px; }
.report-modal-body::-webkit-scrollbar-track { background: transparent; }
.report-modal-body::-webkit-scrollbar-thumb { background-color: #cbd5e1; border-radius: 20px; }
.report-modal-header {
  flex-shrink: 0; border-bottom: 1px solid #e4e4e7;
  padding: 16px 20px;
  display: flex; justify-content: space-between; align-items: center;
}
.report-modal-footer {
  flex-shrink: 0; border-top: 1px solid #e4e4e7;
  padding: 16px 20px; display: flex; gap: 12px;
}
.report-option-item { transition: background-color 0.2s ease; }
.report-option-item.selected { background-color: #e8f0fe; border-right: 3px solid #3C83F5; }
.report-reason-badge { transition: all 0.2s ease; }
.report-reason-badge:hover { transform: translateY(-2px); }
