// ui_kits/website/PostPage.jsx
//
// Full article page (the replacement for the lightweight PostModal).
// Layout (chosen: option 1):
//   ┌────────────────────────────────────────────────┐
//   │           HERO IMAGE (full-bleed)              │
//   │   pill · meta · TITLE · italic dek             │
//   ├──────────────┬─────────────────────────────────┤
//   │   ARTICLE    │       sticky right rail         │
//   │   body       │   - share buttons                │
//   │              │   - reading time                 │
//   │              │   - "next article" card          │
//   │              │   - newsletter inline cta        │
//   ├──────────────┴─────────────────────────────────┤
//   │            medical disclaimer                   │
//   │            author bio                           │
//   │            related (3 from same section)        │
//   └────────────────────────────────────────────────┘
//
// When Ghost is wired up, `post.bodyHtml` becomes the html field from
// the Ghost Content API. Right now it falls back to a small sample
// rendering so the layout reads correctly.

const postPageStyles = {
  // ---- Hero -------------------------------------------------------
  hero: {
    position: 'relative',
    minHeight: 520,
    display: 'flex', alignItems: 'flex-end',
    overflow: 'hidden',
    color: '#fff',
  },
  heroBg: {
    position: 'absolute', inset: 0,
    backgroundSize: 'cover', backgroundPosition: 'center',
    zIndex: 0,
  },
  heroScrim: {
    position: 'absolute', inset: 0, zIndex: 1,
    background: 'linear-gradient(180deg, rgba(15,15,15,0.0) 30%, rgba(15,15,15,0.65) 100%)',
  },
  heroInner: {
    position: 'relative', zIndex: 2,
    maxWidth: 1100, margin: '0 auto', padding: '80px 32px 56px',
    width: '100%', boxSizing: 'border-box',
  },
  breadcrumb: {
    display: 'flex', alignItems: 'center', gap: 8,
    fontFamily: 'var(--font-sans)', fontSize: 12, fontWeight: 600,
    letterSpacing: '0.14em', textTransform: 'uppercase',
    color: 'rgba(255,255,255,0.85)',
    marginBottom: 26,
  },
  breadcrumbLink: { color: 'inherit', textDecoration: 'none', cursor: 'pointer' },
  pillRow: { display: 'flex', alignItems: 'center', gap: 12, marginBottom: 16 },
  pill: {
    padding: '4px 12px', borderRadius: 9999,
    background: 'rgba(255,255,255,0.18)',
    border: '1px solid rgba(255,255,255,0.4)',
    color: '#fff',
    fontFamily: 'var(--font-sans)', fontSize: 11, fontWeight: 700,
    letterSpacing: '0.14em', textTransform: 'uppercase',
  },
  heroMeta: {
    fontFamily: 'var(--font-sans)', fontSize: 12, fontWeight: 600,
    letterSpacing: '0.14em', textTransform: 'uppercase',
    color: 'rgba(255,255,255,0.85)',
  },
  title: {
    fontFamily: 'var(--font-serif)', fontWeight: 700,
    fontSize: 56, lineHeight: 1.05, letterSpacing: '-0.02em',
    margin: '8px 0 0', color: '#fff', maxWidth: '20ch',
    textShadow: '0 2px 18px rgba(0,0,0,0.35)',
    textWrap: 'balance',
  },
  dek: {
    fontFamily: 'var(--font-serif)', fontStyle: 'italic',
    fontSize: 22, lineHeight: 1.45, color: 'rgba(255,255,255,0.95)',
    marginTop: 22, maxWidth: '54ch',
    textWrap: 'pretty',
  },

  // ---- Byline strip -----------------------------------------------
  byline: {
    background: '#fff', borderBottom: '1px solid var(--color-divider)',
  },
  bylineInner: {
    maxWidth: 1100, margin: '0 auto', padding: '20px 32px',
    display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 24,
  },
  bylineLeft: { display: 'flex', alignItems: 'center', gap: 12 },
  bylineAv: {
    width: 36, height: 36, borderRadius: '50%',
    background: 'var(--brand-leaf)', color: '#fff',
    display: 'flex', alignItems: 'center', justifyContent: 'center',
    fontFamily: 'var(--font-serif)', fontWeight: 700, fontSize: 15,
  },
  bylineWho: { fontFamily: 'var(--font-sans)', fontSize: 14, color: 'var(--color-fg)' },
  bylineRole: { fontFamily: 'var(--font-sans)', fontSize: 12, color: 'var(--color-fg-muted)', marginTop: 2 },
  bylineRight: {
    display: 'flex', alignItems: 'center', gap: 18,
    fontFamily: 'var(--font-sans)', fontSize: 12, fontWeight: 600,
    letterSpacing: '0.06em', textTransform: 'uppercase',
    color: 'var(--color-fg-muted)',
  },

  // ---- Body + rail -----------------------------------------------
  bodyWrap: { background: '#fff', padding: '56px 0 80px' },
  bodyInner: {
    maxWidth: 1100, margin: '0 auto', padding: '0 32px',
    display: 'grid', gridTemplateColumns: 'minmax(0, 1fr) 280px', gap: 80, alignItems: 'flex-start',
  },
  article: {
    fontFamily: 'var(--font-sans)', fontSize: 18, lineHeight: 1.75,
    color: 'var(--color-fg)',
  },
  rail: { position: 'sticky', top: 32 },

  railBlock: {
    border: '1px solid var(--color-divider)',
    borderRadius: 12,
    padding: '18px 18px 20px',
    marginBottom: 18, background: '#fff',
  },
  railLabel: {
    fontFamily: 'var(--font-sans)', fontSize: 10.5, fontWeight: 700,
    letterSpacing: '0.18em', textTransform: 'uppercase',
    color: 'var(--color-fg-muted)', margin: '0 0 12px',
  },
  shareRow: { display: 'flex', gap: 8 },
  shareBtn: {
    width: 36, height: 36, borderRadius: 8,
    background: 'var(--brand-cream)',
    border: '1px solid var(--color-divider)',
    display: 'flex', alignItems: 'center', justifyContent: 'center',
    color: 'var(--color-fg)', cursor: 'pointer',
    transition: 'all 180ms var(--ease-out)',
  },
  copyMsg: {
    fontFamily: 'var(--font-sans)', fontSize: 12, color: 'var(--brand-leaf)',
    marginTop: 10,
  },
  readTimeRow: { display: 'flex', alignItems: 'center', gap: 8, fontFamily: 'var(--font-sans)', fontSize: 13, color: 'var(--color-fg)' },

  // ---- Below-article sections ------------------------------------
  disclaimerWrap: { background: 'var(--brand-cream)', padding: '40px 0 32px' },
  disclaimer: {
    maxWidth: 760, margin: '0 auto', padding: '20px 32px',
    fontFamily: 'var(--font-serif)', fontStyle: 'italic',
    fontSize: 15.5, lineHeight: 1.6, color: 'var(--color-fg-muted)',
    borderLeft: '2px solid var(--brand-leaf)',
    paddingLeft: 24,
  },

  authorWrap: { background: 'var(--brand-cream)', paddingBottom: 64 },
  authorCard: {
    maxWidth: 820, margin: '0 auto', padding: '32px',
    background: '#fff', border: '1px solid var(--color-divider)',
    borderRadius: 14,
    display: 'grid', gridTemplateColumns: '96px 1fr', gap: 24, alignItems: 'center',
  },
  authorPortrait: {
    width: 96, height: 96, borderRadius: '50%',
    background: 'linear-gradient(135deg, #8FCFAE, #2E6F5A)',
    color: '#fff', fontFamily: 'var(--font-serif)', fontWeight: 700, fontSize: 40,
    display: 'flex', alignItems: 'center', justifyContent: 'center',
  },
  authorName: { fontFamily: 'var(--font-serif)', fontWeight: 700, fontSize: 22, color: 'var(--color-fg-strong)', margin: 0 },
  authorRole: { fontFamily: 'var(--font-sans)', fontSize: 13, color: 'var(--color-fg-muted)', marginTop: 4, letterSpacing: '0.06em', textTransform: 'uppercase' },
  authorBody: { fontFamily: 'var(--font-sans)', fontSize: 15, lineHeight: 1.6, color: 'var(--color-fg)', marginTop: 10 },

  relatedWrap: { background: '#fff', padding: '72px 0 96px', borderTop: '1px solid var(--color-divider)' },
  relatedInner: { maxWidth: 1100, margin: '0 auto', padding: '0 32px' },
  relatedHead: {
    display: 'flex', alignItems: 'baseline', justifyContent: 'space-between',
    marginBottom: 36, gap: 24,
  },
  relatedTitle: { fontFamily: 'var(--font-serif)', fontSize: 32, fontWeight: 700, margin: 0, color: 'var(--color-fg-strong)' },
  relatedGrid: { display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 28 },
};

// Base prose styles applied to the article body. Targets the Ghost-style
// HTML output (h2/h3, p, blockquote, ul/ol, img/figure, hr).
const articleProseCss = `
.article-prose h2 {
  font-family: var(--font-serif); font-weight: 700;
  font-size: 32px; line-height: 1.2; letter-spacing: -0.01em;
  color: var(--color-fg-strong);
  margin: 56px 0 16px;
}
.article-prose h3 {
  font-family: var(--font-serif); font-weight: 600;
  font-size: 22px; line-height: 1.3;
  color: var(--color-fg-strong);
  margin: 40px 0 12px;
}
.article-prose p {
  font-family: var(--font-sans); font-size: 18px; line-height: 1.75;
  color: var(--color-fg); margin: 0 0 22px;
  text-wrap: pretty;
}
.article-prose p.lead {
  font-family: var(--font-serif); font-style: italic;
  font-size: 22px; line-height: 1.5;
  color: var(--color-fg-strong);
  margin: 0 0 32px;
  padding-left: 20px; border-left: 2px solid var(--brand-leaf);
}
.article-prose blockquote {
  font-family: var(--font-serif); font-style: italic;
  font-size: 24px; line-height: 1.45;
  color: var(--brand-leaf-deep);
  margin: 36px 0;
  padding-left: 28px; border-left: 3px solid var(--brand-mint);
}
.article-prose ul, .article-prose ol {
  font-family: var(--font-sans); font-size: 17px; line-height: 1.75;
  color: var(--color-fg); margin: 0 0 22px;
  padding-left: 24px;
}
.article-prose li { margin: 6px 0; }
.article-prose img,
.article-prose figure img { width: 100%; height: auto; border-radius: 10px; margin: 28px 0; }
.article-prose figcaption {
  font-family: var(--font-sans); font-size: 13px; color: var(--color-fg-muted);
  font-style: italic; text-align: center; margin: -12px 0 28px;
}
.article-prose hr {
  border: none; height: 1px; background: var(--color-divider);
  margin: 56px 0; max-width: 80px;
}
.article-prose a {
  color: var(--brand-leaf); text-decoration: none;
  border-bottom: 1px solid var(--brand-mint);
  transition: color 180ms var(--ease-out), border-color 180ms var(--ease-out);
}
.article-prose a:hover { color: var(--brand-leaf-deep); border-bottom-color: var(--brand-leaf); }
.article-prose strong { color: var(--color-fg-strong); }
.article-prose p.lead {
  font-family: var(--font-serif);
  font-size: 22px; line-height: 1.45;
  color: var(--color-fg-strong); font-weight: 500;
  margin: 0 0 32px; padding-bottom: 28px;
  border-bottom: 1px solid var(--color-divider);
}
.article-prose sup.ref {
  font-family: var(--font-mono); font-size: 0.7em; font-weight: 600;
  color: var(--brand-leaf-deep); margin: 0 1px; letter-spacing: 0;
}
.article-prose table.md-table {
  width: 100%; border-collapse: collapse; margin: 28px 0; font-size: 15px;
  font-family: var(--font-sans);
}
.article-prose table.md-table th,
.article-prose table.md-table td {
  text-align: left; padding: 10px 14px;
  border-bottom: 1px solid var(--color-divider);
}
.article-prose table.md-table th {
  font-weight: 700; color: var(--color-fg-strong);
  background: var(--brand-cream);
  text-transform: uppercase; letter-spacing: 0.08em; font-size: 12px;
}
.article-prose ol.references {
  font-family: var(--font-sans); font-size: 14px; line-height: 1.55;
  color: var(--color-fg-muted); padding-left: 0; list-style: none;
  margin-top: 32px; padding-top: 28px;
  border-top: 1px solid var(--color-divider);
}
.article-prose ol.references li { margin-bottom: 10px; }
.article-prose ol.references .ref-num {
  font-family: var(--font-mono); font-weight: 700;
  color: var(--brand-leaf-deep); margin-right: 8px;
}
.article-prose ol.references a {
  color: var(--color-fg); border-bottom: 1px solid var(--color-divider);
}
`;

// Sample article body — used when a post has no real body. Mirrors what
// Ghost will deliver (HTML string from the Content API).
function sampleBody(post, lang) {
  if (lang === 'es') {
    return `
      <p class="lead">${post.excerpt || 'Una nota breve y basada en evidencia sobre algo pequeño que puedes hacer esta semana.'}</p>
      <p>Hay protocolos que pertenecen al folklore, otros al laboratorio, y unos pocos a ambos. Este es uno de esos pocos — simple, antiguo, y con suficiente investigación moderna detrás como para que valga la pena mirarlo seriamente.</p>
      <h2>¿De dónde viene la idea?</h2>
      <p>La práctica tradicional ya describía el patrón hace siglos. Lo curioso es que la fisiología moderna lo está alcanzando — no derrumbando, alcanzando. Los estudios pequeños son consistentes; los grandes no se han hecho aún.</p>
      <blockquote>"Lo simple no es lo mismo que lo trivial. A veces es lo único que funciona a largo plazo."</blockquote>
      <h2>El protocolo, paso a paso</h2>
      <ol>
        <li>Encuentra un momento del día que ya tienes — no inventes uno nuevo.</li>
        <li>Empieza con dos minutos. No tres, no cinco. Dos.</li>
        <li>Hazlo siete días seguidos antes de decidir si funciona.</li>
        <li>Mide algo concreto al final de la semana. Energía, sueño, ánimo.</li>
      </ol>
      <h3>Lo que dice la evidencia</h3>
      <p>Hay tres estudios que vale la pena conocer. El primero, publicado en 2019, mostró un efecto modesto pero consistente; los autores fueron cautos en su lenguaje. El segundo, de 2022, replicó parcialmente los resultados. El tercero — y este es el más útil — observó que el efecto desaparece cuando se intenta hacer "más rápido".</p>
      <p>La conclusión práctica: la cantidad no es el cuello de botella. La consistencia sí. Empieza pequeño, hazlo todos los días, deja que el tiempo trabaje.</p>
      <hr/>
      <p><strong>¿Quieres probarlo?</strong> Empieza esta semana. Cuéntame cómo te fue — respondo todos los correos.</p>
    `;
  }
  return `
    <p class="lead">${post.excerpt || 'A short, evidence-led look at one small thing you can do this week.'}</p>
    <p>Some protocols belong to folklore, others to the lab, and a few to both. This one is in that small "both" set — simple, ancient, with enough modern research behind it that it's worth a careful look.</p>
    <h2>Where the idea comes from</h2>
    <p>Traditional practice described the pattern centuries ago. What's curious is that modern physiology is catching up — not overturning, catching up. The small studies are consistent; the big ones haven't been run yet.</p>
    <blockquote>"Simple isn't the same as trivial. Sometimes it's the only thing that holds up over years."</blockquote>
    <h2>The protocol, step by step</h2>
    <ol>
      <li>Find a moment in your day you already have — don't invent a new one.</li>
      <li>Start with two minutes. Not three, not five. Two.</li>
      <li>Do it seven days in a row before deciding whether it works.</li>
      <li>Measure something concrete at the end of the week. Energy, sleep, mood.</li>
    </ol>
    <h3>What the evidence says</h3>
    <p>Three studies are worth knowing. The first, from 2019, showed a modest but consistent effect; the authors were careful with their language. The second, from 2022, partially replicated the results. The third — the most useful — found that the effect disappears when people try to do it "faster."</p>
    <p>The practical takeaway: amount isn't the bottleneck. Consistency is. Start small, do it every day, let time do the work.</p>
    <hr/>
    <p><strong>Want to try it?</strong> Start this week. Tell me how it goes — I answer every email.</p>
  `;
}

// ----- Sub-components ------------------------------------------------------

function ShareRail({ title }) {
  const tr = useT();
  const [copied, setCopied] = React.useState(false);

  const copy = async () => {
    try {
      await navigator.clipboard.writeText(window.location.href);
      setCopied(true);
      setTimeout(() => setCopied(false), 2400);
    } catch (e) {}
  };
  const mailHref = `mailto:?subject=${encodeURIComponent(title)}&body=${encodeURIComponent(window.location.href)}`;
  const whatsHref = `https://wa.me/?text=${encodeURIComponent(title + ' — ' + window.location.href)}`;

  return (
    <div style={postPageStyles.railBlock}>
      <h6 style={postPageStyles.railLabel}>{tr('article.share')}</h6>
      <div style={postPageStyles.shareRow}>
        <button style={postPageStyles.shareBtn} onClick={copy} title={tr('article.shareCopy')} aria-label={tr('article.shareCopy')}>
          <BookmarkIcon size={16}/>
        </button>
        <a style={postPageStyles.shareBtn} href={mailHref} title={tr('article.shareEmail')} aria-label={tr('article.shareEmail')}>
          <MailIcon size={16}/>
        </a>
        <a style={postPageStyles.shareBtn} href={whatsHref} target="_blank" rel="noopener" title={tr('article.shareWhats')} aria-label={tr('article.shareWhats')}>
          <Globe size={16}/>
        </a>
      </div>
      {copied && <div style={postPageStyles.copyMsg}>{tr('article.shareCopied')}</div>}
    </div>
  );
}

function NextArticleCard({ post, onOpenPost }) {
  const tr = useT();
  if (!post) return null;
  return (
    <div style={{ ...postPageStyles.railBlock, padding: 0, overflow: 'hidden', cursor: 'pointer' }}
         onClick={() => onOpenPost && onOpenPost(post)}>
      <div style={{ aspectRatio: '16 / 9', overflow: 'hidden' }}>
        {post.image
          ? <img src={post.image} alt="" style={{ width: '100%', height: '100%', objectFit: 'cover' }}/>
          : <CategoryThumb category={post.category} label={post.categoryLabel}/>}
      </div>
      <div style={{ padding: '16px 18px 20px' }}>
        <h6 style={{ ...postPageStyles.railLabel, marginBottom: 8 }}>{tr('section.featured')}</h6>
        <h4 style={{
          fontFamily: 'var(--font-serif)', fontWeight: 600,
          fontSize: 17, lineHeight: 1.3, color: 'var(--color-fg-strong)',
          margin: 0,
        }}>{post.title}</h4>
        <div style={{
          fontFamily: 'var(--font-sans)', fontSize: 11, fontWeight: 700,
          letterSpacing: '0.14em', textTransform: 'uppercase',
          color: 'var(--color-fg-muted)', marginTop: 8,
        }}>{post.categoryLabel} · {post.readMinutes} min</div>
      </div>
    </div>
  );
}

function InlineNewsletterRail() {
  const tr = useT();
  return (
    <div style={{ ...postPageStyles.railBlock, background: 'var(--brand-cream)' }}>
      <h6 style={postPageStyles.railLabel}>{tr('news.eyebrow')}</h6>
      <p style={{
        fontFamily: 'var(--font-serif)', fontStyle: 'italic',
        fontSize: 15.5, lineHeight: 1.5, color: 'var(--color-fg)', margin: '0 0 14px',
      }}>{tr('article.newsletterCta')}</p>
      <button className="btn btn--primary" style={{ width: '100%', justifyContent: 'center' }}>
        {tr('news.submit')}
      </button>
    </div>
  );
}

function AuthorBio() {
  const tr = useT();
  const lang = React.useContext(LangContext);
  return (
    <div style={postPageStyles.authorWrap}>
      <div style={postPageStyles.authorCard}>
        <div style={postPageStyles.authorPortrait}>P</div>
        <div>
          <h4 style={postPageStyles.authorName}>Paola D.</h4>
          <div style={postPageStyles.authorRole}>{tr('post.author.role')}</div>
          <p style={postPageStyles.authorBody}>
            {lang === 'es'
              ? 'Quince años cubriendo salud para revistas — y los últimos cinco probando todo lo que leo antes de escribir sobre ello. Vivo en Los Ángeles. Respondo todos los correos.'
              : 'Fifteen years covering health for magazines — and the last five trying everything I read about before writing about it. Based in Los Angeles. I answer every email.'}
          </p>
        </div>
      </div>
    </div>
  );
}

// ----- Main page ----------------------------------------------------------

function PostPage({ post, onClose, onOpenPost }) {
  const tr = useT();
  const lang = React.useContext(LangContext);
  if (!post) return null;

  // Scroll to top on mount + when a new post is opened.
  React.useEffect(() => {
    window.scrollTo({ top: 0, behavior: 'instant' in window ? 'instant' : 'auto' });
  }, [post.id]);

  React.useEffect(() => {
    const h = (e) => { if (e.key === 'Escape' && onClose) onClose(); };
    window.addEventListener('keydown', h);
    return () => window.removeEventListener('keydown', h);
  }, [onClose]);

  const palette = (window.SECTION_PALETTE || {})[post.category] || { strong: '#1F4F40', accent: '#6FA98C' };

  // Hero background — feature_image when Ghost provides one, else the
  // category gradient.
  const heroBg = post.image
    ? { backgroundImage: `url('${post.image}')` }
    : { background: `linear-gradient(135deg, ${palette.accent}, ${palette.strong})` };

  // If this post has a slug, try to load real body from blog-feed.js.
  // Falls back to post.bodyHtml or sampleBody() if no feed available.
  const [realPost, setRealPost] = React.useState(null);
  React.useEffect(() => {
    let cancelled = false;
    if (post.slug && window.BlogFeed) {
      window.BlogFeed.loadPost(post.slug, lang).then(p => {
        if (!cancelled && p) setRealPost(p);
      });
    } else {
      setRealPost(null);
    }
    return () => { cancelled = true; };
  }, [post.id, post.slug, lang]);

  // Body — real post from feed > Ghost-style html > sample copy.
  const bodyHtml = (realPost && realPost._bodyHtml && realPost._bodyHtml[lang])
    || post.bodyHtml
    || sampleBody(post, lang);

  // Related: 3 other posts in the same section.
  const related = (window.SAMPLE_POSTS || [])
    .filter(p => p.category === post.category && p.id !== post.id)
    .slice(0, 3)
    .map(p => resolvePost(p, lang));

  // "Next article" rail = the freshest other post in the same section.
  const next = related[0];

  return (
    <div>
      <style>{articleProseCss}</style>

      {/* HERO */}
      <section style={postPageStyles.hero}>
        <div style={{ ...postPageStyles.heroBg, ...heroBg }}/>
        <div style={postPageStyles.heroScrim}/>
        <div style={postPageStyles.heroInner}>
          <div style={postPageStyles.breadcrumb}>
            <a style={postPageStyles.breadcrumbLink} onClick={onClose}>{tr('section.back')}</a>
            <span style={{ opacity: 0.5 }}>/</span>
            <a style={postPageStyles.breadcrumbLink}
               onClick={() => window.dispatchEvent(new CustomEvent('app:navigate', { detail: { view: 'section', section: post.category } }))}>
              {post.categoryLabel}
            </a>
          </div>
          <div style={postPageStyles.pillRow}>
            <span style={postPageStyles.pill}>{post.categoryLabel}</span>
            <span style={postPageStyles.heroMeta}>{post.date} · {post.readMinutes} {tr('article.readTime')}</span>
          </div>
          <h1 style={postPageStyles.title}>{post.title}</h1>
          {post.excerpt && <p style={postPageStyles.dek}>{post.excerpt}</p>}
        </div>
      </section>

      {/* BYLINE */}
      <section style={postPageStyles.byline}>
        <div style={postPageStyles.bylineInner}>
          <div style={postPageStyles.bylineLeft}>
            <div style={postPageStyles.bylineAv}>P</div>
            <div>
              <div style={postPageStyles.bylineWho}>{post.author}</div>
              <div style={postPageStyles.bylineRole}>{tr('post.author.role')}</div>
            </div>
          </div>
          <div style={postPageStyles.bylineRight}>
            <span>{tr('article.published')} {post.date}</span>
            <span>·</span>
            <span>{post.readMinutes} {tr('article.readTime')}</span>
          </div>
        </div>
      </section>

      {/* BODY + RAIL */}
      <section style={postPageStyles.bodyWrap}>
        <div style={postPageStyles.bodyInner}>
          <article style={postPageStyles.article}
                   className="article-prose"
                   dangerouslySetInnerHTML={{ __html: bodyHtml }}/>
          <aside style={postPageStyles.rail}>
            <ShareRail title={post.title}/>
            <NextArticleCard post={next} onOpenPost={onOpenPost}/>
            <InlineNewsletterRail/>
          </aside>
        </div>
      </section>

      {/* DISCLAIMER */}
      <section style={postPageStyles.disclaimerWrap}>
        <div style={postPageStyles.disclaimer}>{tr('post.disclaimer')}</div>
      </section>

      {/* RELATED */}
      {related.length > 0 && (
        <section style={postPageStyles.relatedWrap}>
          <div style={postPageStyles.relatedInner}>
            <div style={postPageStyles.relatedHead}>
              <h3 style={postPageStyles.relatedTitle}>{tr('article.related')}</h3>
              <button className="btn btn--secondary"
                onClick={() => window.dispatchEvent(new CustomEvent('app:navigate', { detail: { view: 'section', section: post.category } }))}>
                {post.categoryLabel} <ArrowRight size={14}/>
              </button>
            </div>
            <div style={postPageStyles.relatedGrid}>
              {related.map(p => (
                <BlogCard key={p.id} post={p} onClick={() => onOpenPost && onOpenPost(p)}/>
              ))}
            </div>
          </div>
        </section>
      )}
    </div>
  );
}

window.PostPage = PostPage;
