function BlogSection({ onOpenArticle }) {
  const articles = [
    { series: 'Arquitetura', title: 'Filas e consistência eventual em sistemas distribuídos', excerpt: 'Um framework para decidir entre consistência forte e eventual em arquiteturas de grande escala.', readTime: '9 min', tone: 'accent', highlight: 'consistência eventual' },
    { series: 'Liderança técnica', title: 'Como conduzir um RFC que sobrevive à revisão', excerpt: 'Estrutura, tom e evidências que fazem uma proposta técnica ser aprovada por comitês de arquitetura.', readTime: '6 min', tone: 'success', highlight: 'RFC' },
    { series: 'Escalabilidade', title: 'Particionamento de dados: o que aprendi migrando um monólito', excerpt: 'Decisões de sharding, trade-offs de latência e o custo real de refatorar em produção.', readTime: '11 min', tone: 'warning', highlight: 'monólito' },
  ];
  return (
    <section style={{ padding: 'var(--space-8) var(--space-7)', background: 'var(--surface-sunken)' }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 'var(--space-6)' }}>
        <h2 style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 'var(--text-2xl)', color: 'var(--text-primary)', margin: 0 }}>Do blog</h2>
        <span style={{ fontFamily: 'var(--font-mono)', fontSize: 12, color: 'var(--text-link)', cursor: 'pointer' }}>ver série completa →</span>
      </div>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(5, 1fr)', gap: 'var(--space-4)' }}>
        {articles.map(a => (
          <div key={a.title} onClick={onOpenArticle} style={{ background: 'var(--surface-card)', border: '1px solid var(--border-subtle)', borderRadius: 'var(--radius-lg)', overflow: 'hidden', display: 'flex', flexDirection: 'column', boxShadow: 'var(--shadow-sm)', cursor: 'pointer' }}>
            <CoverThumb title={a.title} label={a.series} highlight={a.highlight} theme={a.tone === 'success' ? 'var(--signal-600)' : a.tone === 'warning' ? 'var(--gold-600)' : 'var(--blue-600)'} />
            <div style={{ padding: 'var(--space-4)', display: 'flex', flexDirection: 'column', gap: 8 }}>
              <div style={{ fontFamily: 'var(--font-body)', fontSize: 13, color: 'var(--text-secondary)', lineHeight: 'var(--leading-normal)' }}>{a.excerpt}</div>
              <div style={{ fontFamily: 'var(--font-mono)', fontSize: 10, color: 'var(--text-muted)' }}>{a.readTime} de leitura</div>
            </div>
          </div>
        ))}
      </div>
    </section>
  );
}

function BlogListingPage({ onOpenArticle }) {
  const allArticles = [
    { series: 'Arquitetura', title: 'Filas e consistência eventual em sistemas distribuídos', excerpt: 'Um framework para decidir entre consistência forte e eventual em arquiteturas de grande escala.', readTime: '9 min', tone: 'accent', highlight: 'consistência eventual' },
    { series: 'Liderança técnica', title: 'Como conduzir um RFC que sobrevive à revisão', excerpt: 'Estrutura, tom e evidências que fazem uma proposta técnica ser aprovada por comitês de arquitetura.', readTime: '6 min', tone: 'success', highlight: 'RFC' },
    { series: 'Escalabilidade', title: 'Particionamento de dados: o que aprendi migrando um monólito', excerpt: 'Decisões de sharding, trade-offs de latência e o custo real de refatorar em produção.', readTime: '11 min', tone: 'warning', highlight: 'monólito' },
    { series: 'Arquitetura', title: 'Contratos entre serviços: versionamento sem quebrar produção', excerpt: 'Estratégias para evoluir APIs internas em um ambiente com dezenas de times.', readTime: '7 min', tone: 'accent', highlight: 'versionamento' },
    { series: 'Liderança técnica', title: 'Dívida técnica: como comunicar prioridade para o negócio', excerpt: 'Um vocabulário compartilhado para tirar dívida técnica da lista de "algum dia".', readTime: '8 min', tone: 'success', highlight: 'Dívida técnica' },
    { series: 'Escalabilidade', title: 'Cache distribuído: quando ele resolve e quando esconde o problema', excerpt: 'Os limites de usar cache como atalho para performance.', readTime: '10 min', tone: 'warning', highlight: 'Cache distribuído' },
    { series: 'Arquitetura', title: 'Observabilidade como parte do contrato de API', excerpt: 'Por que métricas e traces deveriam ser decididos junto com o endpoint.', readTime: '7 min', tone: 'accent', highlight: 'Observabilidade' },
  ];
  const perPage = 6;
  const [page, setPage] = React.useState(1);
  const totalPages = Math.max(1, Math.ceil(allArticles.length / perPage));
  const articles = allArticles.slice((page - 1) * perPage, page * perPage);
  const tones = { accent: { background: 'var(--accent-soft)', color: 'var(--accent-strong)' }, success: { background: 'var(--signal-100)', color: 'var(--signal-600)' }, warning: { background: 'var(--gold-100)', color: 'var(--gold-600)' } };
  return (
    <section style={{ padding: 'var(--space-8) var(--space-7)' }}>
      <div style={{ fontFamily: 'var(--font-mono)', fontSize: 12, letterSpacing: 'var(--tracking-wide)', textTransform: 'uppercase', color: 'var(--text-muted)', marginBottom: 10 }}>Blog</div>
      <h1 style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 'var(--text-3xl)', color: 'var(--text-primary)', margin: '0 0 8px', lineHeight: 'var(--leading-tight)' }}>Blog</h1>
      <p style={{ fontFamily: 'var(--font-body)', fontSize: 15, color: 'var(--text-secondary)', maxWidth: 640, margin: '0 0 var(--space-7)' }}>Artigos em ordem de lançamento sobre arquitetura, liderança técnica e escalabilidade.</p>
      {articles.length === 0 ? <EmptyState message="Nenhum artigo publicado ainda." /> : (
        <>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 'var(--space-4)' }}>
            {articles.map(a => (
              <div key={a.title} onClick={onOpenArticle} style={{ background: 'var(--surface-card)', border: '1px solid var(--border-subtle)', borderRadius: 'var(--radius-lg)', overflow: 'hidden', display: 'flex', flexDirection: 'column', boxShadow: 'var(--shadow-sm)', cursor: 'pointer' }}>
                <CoverThumb title={a.title} label={a.series} highlight={a.highlight} theme={a.tone === 'success' ? 'var(--signal-600)' : a.tone === 'warning' ? 'var(--gold-600)' : 'var(--blue-600)'} />
                <div style={{ padding: 'var(--space-4)', display: 'flex', flexDirection: 'column', gap: 8 }}>
                  <div style={{ fontFamily: 'var(--font-body)', fontSize: 13, color: 'var(--text-secondary)', lineHeight: 'var(--leading-normal)' }}>{a.excerpt}</div>
                  <div style={{ fontFamily: 'var(--font-mono)', fontSize: 10, color: 'var(--text-muted)' }}>{a.readTime} de leitura</div>
                </div>
              </div>
            ))}
          </div>
          <Pagination page={page} totalPages={totalPages} onChange={setPage} />
        </>
      )}
    </section>
  );
}

function ArticlePage() {
  const [tab, setTab] = React.useState(0);
  const tabs = ['Capítulo 1', 'Capítulo 2', 'Capítulo 3'];
  const { Callout, Quote, CodeBlock, EmbedCard, MermaidBlock, Accordion, Checklist } = window.MarceloCasteloIODesignSystem_5e00d7;
  return (
    <section style={{ padding: 'var(--space-8) var(--space-7)', maxWidth: 1160, margin: '0 auto', display: 'grid', gridTemplateColumns: '1fr 300px', gap: 'var(--space-8)', alignItems: 'flex-start' }}>
      <div style={{ maxWidth: 720 }}>
        <div style={{ fontFamily: 'var(--font-mono)', fontSize: 12, letterSpacing: 'var(--tracking-wide)', textTransform: 'uppercase', color: 'var(--text-muted)', marginBottom: 14 }}>
          <span style={{ color: 'var(--text-muted)' }}>Arquitetura Enterprise</span> ／ <span style={{ color: 'var(--text-primary)', fontWeight: 600 }}>Capítulo 3 ／ Filas e consistência eventual</span>
        </div>
        <h1 style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 'var(--text-3xl)', color: 'var(--text-primary)', lineHeight: 'var(--leading-tight)', margin: '0 0 10px' }}>Filas e consistência eventual em sistemas distribuídos</h1>
        <p style={{ fontFamily: 'var(--font-body)', fontSize: 'var(--text-lg)', color: 'var(--text-secondary)', lineHeight: 'var(--leading-relaxed)', margin: '0 0 var(--space-6)' }}>Um framework prático para decidir, domínio a domínio, entre consistência forte e eventual — sem tratar a escolha como binária.</p>
        <div style={{ display: 'flex', gap: 'var(--space-6)', borderBottom: '1px solid var(--border-subtle)', marginBottom: 'var(--space-6)' }}>
          {tabs.map((t, i) => (
            <div key={t} onClick={() => setTab(i)} style={{ padding: '10px 2px', fontSize: 14, fontWeight: 600, cursor: 'pointer', color: tab === i ? 'var(--text-primary)' : 'var(--text-muted)', borderBottom: tab === i ? '2px solid var(--accent)' : '2px solid transparent', marginBottom: -1, fontFamily: 'var(--font-body)' }}>{t}</div>
          ))}
        </div>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-6)' }}>
          <p style={{ fontFamily: 'var(--font-body)', fontSize: 'var(--text-base)', lineHeight: 'var(--leading-relaxed)', color: 'var(--text-primary)', margin: 0 }}>Em arquiteturas distribuídas de grande porte, a escolha entre consistência forte e eventual raramente é binária — é uma composição de decisões por domínio.</p>
          <Callout tone="insight">Trate consistência como um atributo por domínio, não uma decisão única para o sistema inteiro.</Callout>
          <ImageBlock slotId="article-diagram-1" caption="Figura 1 — filas por domínio, cada uma com sua própria política de consistência." />
          <p style={{ fontFamily: 'var(--font-body)', fontSize: 'var(--text-base)', lineHeight: 'var(--leading-relaxed)', color: 'var(--text-secondary)', margin: 0 }}>Este capítulo cobre como modelar filas de eventos, idempotência e reconciliação — com exemplos de decisões tomadas em ambientes enterprise reais.</p>
          <CodeBlock language="csharp" filename="IQueue.cs">{'public interface IQueue\n{\n    Task PublishAsync(Event evt, string idempotencyKey);\n}'}</CodeBlock>
          <MermaidBlock title="Fluxo de reconciliação" code={'flowchart LR\nA[Evento recebido] --> B{Tem chave de idempotência?}\nB -->|sim| C[Publica na fila]\nB -->|não| D[Rejeita / gera chave]\nC --> E[Consumidor processa]\nE --> F{Sucesso?}\nF -->|sim| G[Confirma]\nF -->|não| H[Reprocessa com a mesma chave]'} />
          <Callout tone="caution">Reprocessar um evento sem chave de idempotência duplica efeitos colaterais — não apenas registros.</Callout>
          <Quote cite="Pat Helland, Data on the Outside vs. Data on the Inside">Once you accept that your system is going to have failures, you have to design for them.</Quote>
          <Callout tone="tip">Comece medindo o custo real de reprocessar antes de escolher entre lock distribuído e idempotência.</Callout>
          <EmbedCard kind="youtube" title="Filas e consistência eventual — palestra completa" url="youtube.com/watch?v=exemplo" />
          <EmbedCard kind="github" title="marcelocastelo/flowqueue" url="github.com/marcelocastelo/flowqueue" />
          <Callout tone="important">Documente o comportamento esperado em caso de falha parcial — isso é parte do contrato, não um detalhe de implementação.</Callout>
          <EmbedCard kind="gist" title="Exemplo de reconciliação de filas" url="gist.github.com/marcelocastelo/exemplo" />
          <Callout tone="reference">Ver também: Enterprise Integration Patterns, Hohpe & Woolf — capítulo sobre mensageria garantida.</Callout>
          <Checklist items={[
            { label: 'Toda mensagem tem chave de idempotência', state: 'success' },
            { label: 'Consumidor trata reprocessamento sem efeito duplicado', state: 'success' },
            { label: 'Rollback testado sob falha parcial', state: 'fail' },
            { label: 'Métricas de fila expostas no dashboard', state: 'unchecked' },
          ]} />
          <Accordion items={[
            { title: 'E se o consumidor cair no meio do processamento?', content: 'A mensagem permanece na fila até ser confirmada (ack) — reprocessar com a mesma chave de idempotência evita efeito duplicado.' },
            { title: 'Consistência eventual é sempre a escolha certa?', content: 'Não. Domínios como saldo financeiro geralmente exigem consistência forte; catálogo e notificações toleram bem consistência eventual.' },
            { title: 'Como monitorar o atraso da fila?', content: 'Exponha a idade da mensagem mais antiga não processada como métrica — é o sinal mais direto de atraso real.' },
          ]} />
        </div>
      </div>
      <aside style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-5)', position: 'sticky', top: 'var(--space-6)' }}>
        <div style={{ fontFamily: 'var(--font-mono)', fontSize: 11, letterSpacing: 'var(--tracking-wide)', textTransform: 'uppercase', color: 'var(--text-muted)' }}>Recomendado</div>
        <TrainingCardBlock title="Sistemas distribuídos na prática" level="Avançado" duration="6 semanas" format="Live" />
        <div style={{ background: 'var(--surface-card)', border: '1px solid var(--border-subtle)', borderRadius: 'var(--radius-lg)', overflow: 'hidden', boxShadow: 'var(--shadow-sm)' }}>
          <SidebarAdImage slotId="sidebar-training-cover" />
          <div style={{ padding: 'var(--space-5)', display: 'flex', flexDirection: 'column', gap: 8 }}>
            <div style={{ fontFamily: 'var(--font-display)', fontSize: 18, fontWeight: 600, color: 'var(--text-primary)' }}>Mentoria individual</div>
            <div style={{ fontFamily: 'var(--font-body)', fontSize: 13, color: 'var(--text-secondary)', lineHeight: 'var(--leading-normal)' }}>Sessões 1:1 focadas em decisões de arquitetura.</div>
          </div>
          <div style={{ background: 'var(--surface-inverse)', color: 'var(--text-on-inverse)', padding: '10px 20px', fontFamily: 'var(--font-mono)', fontSize: 12 }}>a partir de R$ 800/sessão</div>
        </div>
      </aside>
    </section>
  );
}
Object.assign(window, { BlogSection, BlogListingPage, ArticlePage });
