// Afford-X · ALM agent — unique brand mark, state machine, floating chat.
const { useState, useRef, useEffect, useCallback, createContext, useContext } = React;

/* ============================================================
   The ALM mark — an Afford-X spark.
   A 4-point star rotated to read as the brand "X", with a green
   gradient core and an orbiting micro-spark (red accent nod to
   the Afford-X "X"). Distinct from any third-party logo.
   ============================================================ */
const STAR = 'M12 1.6C12.7 6.9 17.1 11.3 22.4 12C17.1 12.7 12.7 17.1 12 22.4C11.3 17.1 6.9 12.7 1.6 12C6.9 11.3 11.3 6.9 12 1.6Z';

function AlmMark({ size = 26, state = 'idle', tone = 'green', id = 'm' }) {
  const gid = `almg-${id}`;
  const core = tone === 'white' ? '#fff' : `url(#${gid})`;
  const sat = tone === 'white' ? 'rgba(255,255,255,0.9)' : 'var(--afx-red-bright)';
  return (
    <span className={`alm-mark alm-state-${state}`} aria-hidden="true">
      <svg width={size} height={size} viewBox="0 0 24 24">
        <defs>
          <linearGradient id={gid} x1="0" y1="0" x2="1" y2="1">
            <stop offset="0" stopColor="#74C07F" />
            <stop offset="0.55" stopColor="var(--afx-green-500)" />
            <stop offset="1" stopColor="var(--afx-green-700)" />
          </linearGradient>
        </defs>
        <g className="alm-core" style={{ transform: 'rotate(45deg)', transformOrigin: '12px 12px' }}>
          <path d={STAR} fill={core} />
        </g>
        <g className="alm-orbit">
          <path d={STAR} fill={sat} transform="translate(20.5 4) scale(0.26)" />
        </g>
      </svg>
    </span>
  );
}

/* ============================================================
   Agent state machine (shared via context)
   phase: idle | engaged | listening | thinking | answering
   ============================================================ */
const GREETING = "Hi — I'm ALM, the Affordability Language Model behind Afford-X. Ask me anything about exclusion filters, segments, or how we make intent better.";
const SUGGESTIONS = [
  'What is the Exclusion Filter?',
  'How does ALM score affordability?',
  'Which industries do you serve?',
];

const SYS_PROMPT = `You are ALM, the Affordability Language Model — the AI agent that powers Afford-X, a martech platform.
Afford-X scores audiences on real purchasing power (not just intent) and offers a first-in-market one-click exclusion filter that removes window-shoppers before a campaign launches.
Key facts you can draw on: nearly 1 billion U.S. MAIDs and HEMs across 100+ data segments (income, credit, purchase behavior, intent); a Dollar Scoring Framework; GDPR/CCPA/LGPD compliant, consented/pseudonymized signals; verticals served include auto, luxury, financial services and e-commerce; tagline "We Make Intent Better."
Voice: confident, modern, benefit-led B2B. Speak to the visitor as "you", refer to Afford-X as "we". Keep replies under 70 words, no emoji, no markdown headers. Be concrete and helpful.`;

const AgentCtx = createContext(null);
const useAgent = () => useContext(AgentCtx);
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));

function AgentProvider({ children }) {
  const [open, setOpen] = useState(false);
  const [phase, setPhase] = useState('idle');
  const [messages, setMessages] = useState([{ role: 'assistant', content: GREETING }]);
  const [draft, setDraft] = useState('');
  const busyRef = useRef(false);

  const openWidget = useCallback(() => {
    setOpen(true);
    setPhase((p) => (p === 'idle' ? 'engaged' : p));
  }, []);
  const closeWidget = useCallback(() => {
    setOpen(false);
    if (!busyRef.current) setPhase('idle');
  }, []);

  // listening reacts to visitor typing
  const onDraft = useCallback((v) => {
    setDraft(v);
    if (busyRef.current) return;
    setPhase(v.trim() ? 'listening' : 'engaged');
  }, []);

  const ask = useCallback(async (qRaw) => {
    const q = (qRaw == null ? draft : qRaw).trim();
    if (!q || busyRef.current) return;
    busyRef.current = true;
    setDraft('');
    setMessages((m) => [...m, { role: 'user', content: q }]);
    setPhase('thinking');

    // build short conversation context
    const history = messages.filter((m) => m.role === 'user' || m.role === 'assistant').slice(-6)
      .map((m) => `${m.role === 'user' ? 'Visitor' : 'ALM'}: ${m.content}`).join('\n');
    const prompt = `${SYS_PROMPT}\n\n${history ? 'Conversation so far:\n' + history + '\n\n' : ''}Visitor: ${q}\nALM:`;

    let reply = '';
    try {
      if (window.claude && window.claude.complete) {
        reply = await window.claude.complete(prompt);
      } else {
        throw new Error('no-api');
      }
    } catch (e) {
      reply = "We narrow your intent audience down to people with real purchasing power — our one-click Exclusion Filter removes window-shoppers before launch, so every ad dollar works harder. (Live answers activate when this page is shared.)";
      await sleep(900);
    }
    reply = (reply || '').trim();

    // stream the reply word-by-word for the "answering" state
    setPhase('answering');
    setMessages((m) => [...m, { role: 'assistant', content: '' }]);
    const parts = reply.split(/(\s+)/);
    let acc = '';
    for (const w of parts) {
      acc += w;
      setMessages((m) => { const c = m.slice(); c[c.length - 1] = { role: 'assistant', content: acc }; return c; });
      await sleep(24);
    }
    busyRef.current = false;
    setPhase(open ? 'engaged' : 'idle');
  }, [draft, messages, open]);

  const value = { open, phase, messages, draft, openWidget, closeWidget, onDraft, ask, busy: () => busyRef.current };
  return <AgentCtx.Provider value={value}>{children}</AgentCtx.Provider>;
}

/* ============================================================
   Header indicator — "Ask ALM" pill that reflects live state
   ============================================================ */
const LABELS = {
  idle: 'Ask ALM',
  engaged: 'ALM is here',
  listening: 'Listening…',
  thinking: 'Thinking…',
  answering: 'Answering…',
};
const DOT_COLOR = {
  idle: 'var(--afx-gray-400)',
  engaged: 'var(--afx-green-500)',
  listening: 'var(--afx-green-500)',
  thinking: 'var(--afx-yellow)',
  answering: 'var(--afx-green-500)',
};

function HeaderAgent() {
  const { phase, open, openWidget, closeWidget } = useAgent();
  const active = phase !== 'idle';
  return (
    <button
      onClick={open ? closeWidget : openWidget}
      style={{
        display: 'inline-flex', alignItems: 'center', gap: 9, cursor: 'pointer',
        height: 40, padding: '0 14px 0 10px', borderRadius: 999,
        border: `1.5px solid ${active ? 'var(--afx-green-500)' : 'var(--afx-gray-200)'}`,
        background: active ? 'var(--afx-green-50)' : '#fff',
        fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 14,
        color: 'var(--afx-ink)', transition: 'border-color 0.18s ease, background 0.18s ease',
      }}
    >
      <AlmMark size={22} state={phase} id="hdr" />
      <span style={{ minWidth: 78, textAlign: 'left' }}>{LABELS[phase]}</span>
      <span className={active ? 'alm-dot' : ''} style={{ width: 8, height: 8, borderRadius: '50%', background: DOT_COLOR[phase], color: DOT_COLOR[phase], display: 'inline-block' }} />
    </button>
  );
}

/* ============================================================
   Floating widget — bottom-right bubble + chat panel
   ============================================================ */
function Bubble() {
  const { open, phase, openWidget } = useAgent();
  if (open) return null;
  const busy = phase === 'thinking' || phase === 'answering';
  return (
    <button
      onClick={openWidget}
      aria-label="Open ALM assistant"
      style={{
        position: 'fixed', right: 26, bottom: 26, zIndex: 60,
        width: 62, height: 62, borderRadius: '50%', cursor: 'pointer', border: 'none',
        background: 'linear-gradient(135deg, var(--afx-green-400), var(--afx-green-600))',
        boxShadow: '0 10px 28px rgba(42,87,52,0.34)',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
      }}
    >
      {!busy && <span className="alm-bubble-ring" />}
      <AlmMark size={32} state={phase} tone="white" id="bub" />
    </button>
  );
}

function SubLine({ phase }) {
  if (phase === 'thinking') return (
    <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}>
      Thinking <span className="alm-think-dots"><span></span><span></span><span></span></span>
    </span>
  );
  if (phase === 'answering') return <span>Answering…</span>;
  if (phase === 'listening') return <span>Listening…</span>;
  return <span>Online · replies in seconds</span>;
}

function Panel() {
  const { open, phase, messages, draft, closeWidget, onDraft, ask, busy } = useAgent();
  const scrollRef = useRef(null);
  const inputRef = useRef(null);
  useEffect(() => {
    if (scrollRef.current) scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
  }, [messages, phase, open]);
  useEffect(() => { if (open && inputRef.current) inputRef.current.focus(); }, [open]);
  if (!open) return null;
  const isBusy = busy();

  return (
    <div className="alm-panel" style={{
      position: 'fixed', right: 26, bottom: 26, zIndex: 60,
      width: 380, maxWidth: 'calc(100vw - 32px)', height: 560, maxHeight: 'calc(100vh - 52px)',
      background: '#fff', borderRadius: 18, overflow: 'hidden',
      border: '1px solid var(--afx-gray-200)', boxShadow: '0 24px 60px rgba(5,7,8,0.22)',
      display: 'flex', flexDirection: 'column',
    }}>
      {/* header */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '14px 16px', background: 'linear-gradient(135deg, #0c2414, #061a0e)', color: '#fff' }}>
        <div style={{ width: 42, height: 42, borderRadius: 12, background: 'rgba(255,255,255,0.08)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
          <AlmMark size={26} state={phase} tone="white" id="pnl" />
        </div>
        <div style={{ flex: 1, lineHeight: 1.2 }}>
          <div style={{ fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 16 }}>ALM</div>
          <div style={{ fontSize: 12, opacity: 0.85 }}><SubLine phase={phase} /></div>
        </div>
        <button onClick={closeWidget} aria-label="Close" style={{ background: 'rgba(255,255,255,0.1)', border: 'none', color: '#fff', width: 30, height: 30, borderRadius: 8, cursor: 'pointer', fontSize: 18, lineHeight: 1 }}>×</button>
      </div>

      {/* messages */}
      <div ref={scrollRef} className="alm-scroll" style={{ flex: 1, overflowY: 'auto', padding: '18px 16px', background: 'var(--afx-gray-50)', display: 'flex', flexDirection: 'column', gap: 12 }}>
        {messages.map((m, i) => (
          <div key={i} className="alm-msg" style={{ display: 'flex', justifyContent: m.role === 'user' ? 'flex-end' : 'flex-start' }}>
            <div style={{
              maxWidth: '82%', padding: '10px 13px', fontSize: 14, lineHeight: 1.5,
              fontFamily: 'var(--font-body)',
              borderRadius: m.role === 'user' ? '14px 14px 4px 14px' : '14px 14px 14px 4px',
              background: m.role === 'user' ? 'var(--afx-green-500)' : '#fff',
              color: m.role === 'user' ? '#fff' : 'var(--afx-gray-700)',
              border: m.role === 'user' ? 'none' : '1px solid var(--afx-gray-200)',
              boxShadow: m.role === 'user' ? 'none' : '0 1px 2px rgba(5,7,8,0.04)',
            }}>{m.content || '\u200b'}</div>
          </div>
        ))}
        {phase === 'thinking' && (
          <div className="alm-msg" style={{ display: 'flex', justifyContent: 'flex-start' }}>
            <div style={{ padding: '12px 14px', background: '#fff', border: '1px solid var(--afx-gray-200)', borderRadius: '14px 14px 14px 4px', display: 'flex', alignItems: 'center', gap: 4 }}>
              <span className="alm-think-dots"><span></span><span></span><span></span></span>
            </div>
          </div>
        )}
        {messages.length <= 1 && (
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8, marginTop: 4 }}>
            {SUGGESTIONS.map((s) => (
              <button key={s} className="alm-chip" onClick={() => ask(s)} style={{
                padding: '7px 12px', borderRadius: 999, fontSize: 13, fontFamily: 'var(--font-body)',
                background: '#fff', border: '1px solid var(--afx-gray-300)', color: 'var(--afx-green-700)', cursor: 'pointer',
              }}>{s}</button>
            ))}
          </div>
        )}
      </div>

      {/* input */}
      <form onSubmit={(e) => { e.preventDefault(); ask(); }} style={{ display: 'flex', alignItems: 'center', gap: 8, padding: 12, borderTop: '1px solid var(--afx-gray-200)', background: '#fff' }}>
        <input
          ref={inputRef}
          value={draft}
          onChange={(e) => onDraft(e.target.value)}
          placeholder={isBusy ? 'ALM is responding…' : 'Ask about Afford-X…'}
          disabled={isBusy}
          style={{
            flex: 1, height: 42, padding: '0 14px', borderRadius: 999, fontSize: 14, fontFamily: 'var(--font-body)',
            border: '1.5px solid var(--afx-gray-200)', outline: 'none', color: 'var(--afx-ink)', background: 'var(--afx-gray-50)',
          }}
          onFocus={(e) => (e.target.style.borderColor = 'var(--afx-green-500)')}
          onBlur={(e) => (e.target.style.borderColor = 'var(--afx-gray-200)')}
        />
        <button type="submit" disabled={isBusy || !draft.trim()} aria-label="Send" style={{
          width: 42, height: 42, borderRadius: '50%', border: 'none', flexShrink: 0,
          cursor: isBusy || !draft.trim() ? 'default' : 'pointer',
          background: !draft.trim() || isBusy ? 'var(--afx-gray-200)' : 'var(--afx-green-500)',
          color: '#fff', display: 'flex', alignItems: 'center', justifyContent: 'center',
          transition: 'background 0.15s ease',
        }}>
          <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/></svg>
        </button>
      </form>
    </div>
  );
}

function AgentWidget() {
  return <><Bubble /><Panel /></>;
}

Object.assign(window, { AgentProvider, useAgent, HeaderAgent, AgentWidget, AlmMark });
// Afford-X · shared site chrome for blog pages (header + footer).
const { Button } = window.AffordXDesignSystem_998110;
const { HeaderAgent } = window;
const CHROME_A = 'assets/';
// resolve assets via the inliner's __resources when bundled offline, else fall back to the file path
const CHROME_RES = (id, path) => (window.__resources && window.__resources[id]) || path;

const SITE_NAV = [
  { label: 'Product Highlights', href: '/' },
  { label: 'How Afford-X Works', href: '/' },
  { label: 'Blog', href: '/blog' },
  { label: 'Pricing', href: '/pricing' },
];

function SiteHeader({ current }) {
  return (
    <header style={{ position: 'sticky', top: 0, zIndex: 30, background: 'rgba(255,255,255,0.92)', backdropFilter: 'blur(8px)', borderBottom: '1px solid var(--afx-gray-200)' }}>
      <div style={{ maxWidth: 1200, margin: '0 auto', padding: '0 28px', height: 72, display: 'flex', alignItems: 'center', gap: 32 }}>
        <a href="/"><img src={CHROME_RES('logo', CHROME_A + 'logo.png')} alt="Afford-X" style={{ height: 30, display: 'block' }} /></a>
        <nav style={{ display: 'flex', gap: 28, marginLeft: 12 }}>
          {SITE_NAV.map((l) => {
            const active = l.label === current;
            return <a key={l.label} href={l.href} style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 14, color: active ? 'var(--afx-green-700)' : 'var(--afx-gray-600)', textDecoration: 'none' }}>{l.label}</a>;
          })}
        </nav>
        <div style={{ marginLeft: 'auto', display: 'flex', gap: 12, alignItems: 'center' }}>
          <HeaderAgent />
          <Button variant="primary" size="sm">Contact us</Button>
        </div>
      </div>
    </header>
  );
}

function SiteFooter() {
  return (
    <footer style={{ background: 'var(--afx-black)', color: 'var(--afx-gray-400)' }}>
      <div style={{ maxWidth: 1200, margin: '0 auto', padding: '48px 28px', display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 24, flexWrap: 'wrap' }}>
        <div style={{ background: '#fff', borderRadius: 'var(--radius-md)', padding: '12px 18px' }}><img src={CHROME_RES('logo', CHROME_A + 'logo.png')} alt="Afford-X" style={{ height: 26, display: 'block' }} /></div>
        <div style={{ display: 'flex', gap: 24, fontFamily: 'var(--font-display)', fontSize: 14 }}>
          {['Product Highlights', 'How Afford-X Works', 'Terms & Conditions', 'Privacy Policy'].map((l) => <a key={l} href="#" style={{ color: 'var(--afx-gray-400)', textDecoration: 'none' }}>{l}</a>)}
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
          <span style={{ fontSize: 13 }}>Find us on</span>
          <span style={{ width: 34, height: 34, borderRadius: 'var(--radius-sm)', background: '#fff', display: 'inline-flex', alignItems: 'center', justifyContent: 'center' }}>
            <img src={CHROME_RES('linkedin', CHROME_A + 'linkedin.svg')} alt="LinkedIn" style={{ width: 18, height: 18 }} />
          </span>
        </div>
      </div>
    </footer>
  );
}

function CtaBand() {
  return (
    <section style={{ background: 'var(--afx-green-500)' }}>
      <div style={{ maxWidth: 1000, margin: '0 auto', padding: '60px 28px', textAlign: 'center', color: '#fff' }}>
        <h2 style={{ fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 36, letterSpacing: '-0.02em', margin: '0 0 12px', color: '#fff' }}>Affordability Makes Intent Better</h2>
        <p style={{ fontSize: 17, opacity: 0.95, margin: '0 0 26px' }}>Your efficiency accelerator — because real buyers drive real results.</p>
        <div style={{ display: 'flex', gap: 12, justifyContent: 'center' }}>
          <Button variant="danger" size="lg">Free Evaluation</Button>
          <Button variant="secondary" size="lg" style={{ background: 'rgba(255,255,255,0.12)', borderColor: '#fff', color: '#fff' }}>Contact us</Button>
        </div>
      </div>
    </section>
  );
}

// shared category tones + avatar
const CAT_TONE = { Perspective: 'neutral', Product: 'green', 'Data Science': 'slate', Industry: 'yellow', Privacy: 'red' };
function Avatar({ name, size = 38 }) {
  const initials = name.split(' ').map((p) => p[0]).slice(0, 2).join('');
  return (
    <span style={{ width: size, height: size, borderRadius: '50%', flexShrink: 0, background: 'var(--afx-green-100)', color: 'var(--afx-green-700)', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: size * 0.36 }}>{initials}</span>
  );
}

Object.assign(window, { SiteHeader, SiteFooter, CtaBand, CAT_TONE, Avatar });
// Afford-X · blog post data (placeholder content for presentation).
const AFX_POSTS = [
  {
    slug: 'intent-isnt-enough', cat: 'Perspective', title: "Why intent isn't enough anymore",
    excerpt: "Intent tells you who's looking. Affordability tells you who can actually buy. Here's the gap that's quietly draining ad budgets.",
    author: 'Maya Chen', role: 'Head of Product', date: 'Jun 18, 2026', read: '6 min read', featured: true,
  },
  {
    slug: 'inside-exclusion-filter', cat: 'Product', title: 'Inside the Exclusion Filter',
    excerpt: 'How one click removes window-shoppers from an intent audience before a campaign ever launches.',
    author: 'Devin Park', role: 'Product Marketing', date: 'Jun 11, 2026', read: '5 min read',
  },
  {
    slug: 'dollar-scoring-framework', cat: 'Data Science', title: 'The Dollar Scoring Framework, explained',
    excerpt: 'A look under the hood at how ALM scores each user on both ability and likelihood to convert.',
    author: 'Priya Nair', role: 'Data Science Lead', date: 'Jun 4, 2026', read: '8 min read',
  },
  {
    slug: 'auto-marketers', cat: 'Industry', title: 'Affordability intelligence for auto marketers',
    excerpt: 'Why dealerships and OEMs are the clearest early win for purchasing-power targeting.',
    author: 'Sam Ortiz', role: 'Industry Strategy', date: 'May 28, 2026', read: '5 min read',
  },
  {
    slug: 'privacy-first', cat: 'Privacy', title: 'Privacy-first targeting, by design',
    excerpt: 'How consented, pseudonymized signals keep Afford-X GDPR, CCPA and LGPD compliant.',
    author: 'Lena Fischer', role: 'Trust & Compliance', date: 'May 20, 2026', read: '7 min read',
  },
  {
    slug: 'billion-maids', cat: 'Data Science', title: 'From 1B MAIDs to your best 5%',
    excerpt: 'A primer on how nearly a billion signals become a single campaign-ready Afford-X segment.',
    author: 'Priya Nair', role: 'Data Science Lead', date: 'May 12, 2026', read: '6 min read',
  },
];

Object.assign(window, { AFX_POSTS });
// Afford-X · blog index page.
const { Badge } = window.AffordXDesignSystem_998110;
const { AgentProvider, AgentWidget, SiteHeader, SiteFooter, CtaBand, CAT_TONE, Avatar } = window;
const POSTS = window.AFX_POSTS;
const ART = '/blog-posts';

function Slot({ id, h = 190, radius = 0 }) {
  return (
    <image-slot
      id={id}
      shape="rect"
      placeholder="Drop post image"
      style={{ display: 'block', width: '100%', height: h, background: 'var(--afx-green-50)', borderRadius: radius }}
    ></image-slot>
  );
}

function MetaRow({ p, dark }) {
  const c = dark ? 'rgba(255,255,255,0.85)' : 'var(--afx-gray-500)';
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginTop: 16 }}>
      <Avatar name={p.author} size={34} />
      <div style={{ lineHeight: 1.3 }}>
        <div style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 13.5, color: dark ? '#fff' : 'var(--afx-ink)' }}>{p.author}</div>
        <div style={{ fontSize: 12.5, color: c }}>{p.date} · {p.read}</div>
      </div>
    </div>
  );
}

function Featured({ p }) {
  return (
    <a href={ART} className="blog-card" style={{ display: 'grid', gridTemplateColumns: '1.05fr 0.95fr', gap: 0, textDecoration: 'none', background: '#fff', border: '1px solid var(--afx-gray-200)', borderRadius: 18, overflow: 'hidden' }}>
      <div className="blog-thumb" style={{ minHeight: 320 }}>
        <Slot id="blog-featured" h="100%" />
      </div>
      <div style={{ padding: '38px 40px', display: 'flex', flexDirection: 'column', justifyContent: 'center' }}>
        <div style={{ display: 'flex', gap: 8, alignItems: 'center', marginBottom: 16 }}>
          <Badge tone="green" solid>Featured</Badge>
          <Badge tone={CAT_TONE[p.cat]}>{p.cat}</Badge>
        </div>
        <h2 className="blog-title" style={{ fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 34, lineHeight: 1.12, letterSpacing: '-0.025em', color: 'var(--afx-ink)', margin: '0 0 14px', transition: 'color 0.15s ease' }}>{p.title}</h2>
        <p style={{ fontSize: 16.5, lineHeight: 1.6, color: 'var(--afx-gray-600)', margin: 0 }}>{p.excerpt}</p>
        <MetaRow p={p} />
      </div>
    </a>
  );
}

function PostCard({ p }) {
  return (
    <a href={ART} className="blog-card" style={{ display: 'flex', flexDirection: 'column', textDecoration: 'none', background: '#fff', border: '1px solid var(--afx-gray-200)', borderRadius: 16, overflow: 'hidden' }}>
      <div className="blog-thumb"><Slot id={'blog-thumb-' + p.slug} /></div>
      <div style={{ padding: '20px 20px 22px', display: 'flex', flexDirection: 'column', flex: 1 }}>
        <Badge tone={CAT_TONE[p.cat]} style={{ alignSelf: 'flex-start', marginBottom: 12 }}>{p.cat}</Badge>
        <h3 className="blog-title" style={{ fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 19, lineHeight: 1.22, letterSpacing: '-0.015em', color: 'var(--afx-ink)', margin: '0 0 8px', transition: 'color 0.15s ease' }}>{p.title}</h3>
        <p style={{ fontSize: 14, lineHeight: 1.55, color: 'var(--afx-gray-600)', margin: 0 }}>{p.excerpt}</p>
        <div style={{ marginTop: 'auto' }}><MetaRow p={p} /></div>
      </div>
    </a>
  );
}

function BlogIndex() {
  const featured = POSTS.find((p) => p.featured) || POSTS[0];
  const rest = POSTS.filter((p) => p !== featured);
  const cats = ['All', ...Array.from(new Set(POSTS.map((p) => p.cat)))];
  const [active, setActive] = React.useState('All');
  const shown = active === 'All' ? rest : rest.filter((p) => p.cat === active);

  return (
    <section style={{ position: 'relative', overflow: 'hidden' }}>
      <div style={{ position: 'absolute', top: -140, right: -80, width: 560, height: 460, background: 'radial-gradient(circle, rgba(84,169,102,0.13), transparent 70%)', pointerEvents: 'none' }} />
      <div style={{ maxWidth: 1200, margin: '0 auto', padding: '56px 28px 8px', position: 'relative' }}>
        <span className="afx-eyebrow">The Afford-X Journal</span>
        <h1 style={{ fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 46, lineHeight: 1.08, letterSpacing: '-0.03em', color: 'var(--afx-ink)', margin: '14px 0 12px' }}>
          Notes on making intent better<span style={{ color: 'var(--afx-red-bright)' }}>.</span>
        </h1>
        <p style={{ fontSize: 18, lineHeight: 1.6, color: 'var(--afx-gray-600)', maxWidth: 600, margin: 0 }}>
          Affordability intelligence, exclusion filters and the data science behind real purchasing power — straight from the team.
        </p>
      </div>

      <div style={{ maxWidth: 1200, margin: '0 auto', padding: '32px 28px 0' }}>
        <Featured p={featured} />
      </div>

      <div style={{ maxWidth: 1200, margin: '0 auto', padding: '40px 28px 0', display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap' }}>
        {cats.map((c) => (
          <button key={c} className="cat-chip" data-on={active === c} onClick={() => setActive(c)} style={{
            height: 34, padding: '0 16px', borderRadius: 999, cursor: 'pointer',
            border: '1.5px solid var(--afx-gray-200)', background: '#fff', color: 'var(--afx-gray-600)',
            fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 13.5,
          }}>{c}</button>
        ))}
      </div>

      <div style={{ maxWidth: 1200, margin: '0 auto', padding: '24px 28px 8px', display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 22, alignItems: 'stretch' }}>
        {shown.map((p) => <PostCard key={p.slug} p={p} />)}
      </div>
      <p style={{ textAlign: 'center', fontSize: 13, color: 'var(--afx-gray-500)', margin: '20px 0 0' }}>
        Placeholder articles for presentation. Drop an image onto any card to fill its cover.
      </p>
    </section>
  );
}

function BlogPage() {
  return (
    <AgentProvider>
      <div style={{ background: '#fff' }}>
        <SiteHeader current="Blog" />
        <BlogIndex />
        <div style={{ height: 64 }} />
        <CtaBand />
        <SiteFooter />
      </div>
      <AgentWidget />
    </AgentProvider>
  );
}

Object.assign(window, { BlogPage });

// auto-render
document.body.innerHTML = '<div id="afx-root"></div>';
ReactDOM.createRoot(document.getElementById('afx-root')).render(<window.BlogPage />);
