// Blog data + components — all AI systems focused placeholders
const { useState: bS, useEffect: bE } = React;

const POSTS = [
  {
    id: 'orchestrator-patterns',
    date: '2026-04-15',
    category: 'AI Systems',
    title: 'The three orchestrator patterns every AI system eventually needs',
    dek: "Pipelines, supervisors, and swarms — when to reach for each, and the failure mode each one hides.",
    minutes: 9,
    featured: true,
    body: [
      "Every AI system I've shipped has ended up using one of three orchestration patterns. You can argue the edges, but the core three hold: pipelines, supervisors, and swarms.",
      "Pipelines are the boring one. A fixed DAG — step A feeds step B, B feeds C. They're fast, cheap, and easy to debug. They fall apart the moment your branches get non-trivial.",
      "Supervisors are the adult in the room. One model holds context and routes work to specialists. They cost more per run but recover from mistakes gracefully. The failure mode is bloat — the supervisor becomes a dumping ground for every new feature.",
      "Swarms are the glamorous one. Many agents, loose coupling, emergent behaviour. Great demo, terrible unit economics. Use sparingly and never as your first pass.",
      "My rule: start with a pipeline. Move to a supervisor when branching gets ugly. Only reach for swarms if you're doing genuine search or simulation."
    ],
  },
  { id: 'retrieval-is-not-a-database',   date: '2026-04-08', category: 'AI Systems', title: 'Retrieval is not a database',                                dek: "Why chunking matters more than embedding choice, and what happens when you treat your vector store like Postgres.",    minutes: 6 },
  { id: 'evals-before-agents',           date: '2026-04-01', category: 'AI Systems', title: 'Write the evals before you write the agent',                   dek: "A week of evals will save you a month of demo-ware. Here's the minimum viable harness.",                                minutes: 7 },
  { id: 'cheap-models-good',             date: '2026-03-24', category: 'AI Systems', title: 'Cheap models are good enough for 80% of your pipeline',         dek: "Stop routing everything to the frontier. A tiered stack costs 1/10th and performs indistinguishably on most tasks.",    minutes: 5 },
  { id: 'tool-calls-as-api',             date: '2026-03-17', category: 'AI Systems', title: "Treat your tool calls as the real API",                          dek: "The prompt is disposable. The tool schema is your contract. Version it, lock it, test it like production.",             minutes: 8 },
  { id: 'context-is-a-resource',         date: '2026-03-10', category: 'AI Systems', title: 'Context is a resource, not a bucket',                            dek: "Why 'stuff it all in' fails at 30k tokens and how to budget context like you'd budget RAM.",                             minutes: 6 },
  { id: 'memory-three-layers',           date: '2026-03-03', category: 'AI Systems', title: 'The three layers of agent memory',                               dek: "Working, episodic, semantic — what each one is actually for, and why most memory systems conflate all three.",           minutes: 7 },
  { id: 'observability-first',           date: '2026-02-24', category: 'AI Systems', title: 'If you can\'t see what your agent is doing, you don\'t have an agent', dek: 'Span-level tracing, token-level audit, and why observability is the cheapest investment you can make.',          minutes: 5 },
  { id: 'prompt-spec-not-prose',         date: '2026-02-17', category: 'AI Systems', title: 'Prompts should read like specs, not prose',                      dek: "A 30-line numbered spec beats a 300-word essay every time. Here's the template I use.",                                  minutes: 4 },
  { id: 'hallucination-isnt-the-problem',date: '2026-02-10', category: 'AI Systems', title: "Hallucination isn't the problem — vagueness is",                 dek: "Most 'hallucinations' are actually underspecified tasks. Tighten the task, halve the errors.",                           minutes: 6 },
  { id: 'human-in-loop-budget',          date: '2026-02-03', category: 'AI Systems', title: 'Human-in-the-loop is a budget line, not a feature',              dek: "When to pay a reviewer, when to pay a model, and the crossover point you should actually calculate.",                    minutes: 7 },
  { id: 'ship-the-boring-one',           date: '2026-01-27', category: 'AI Systems', title: 'Ship the boring system first',                                   dek: "The unsexy baseline usually wins. A case study from the £50k challenge build log.",                                      minutes: 5 },
];

function formatDate(iso) {
  const d = new Date(iso);
  return d.toLocaleDateString('en-GB', { day: 'numeric', month: 'short', year: 'numeric' });
}

// --- Latest writing teaser (on landing) ---
function LatestWriting({ onOpen, onAll }) {
  const latest = POSTS.slice(0, 3);
  return (
    <section id="writing" style={{ marginTop: 48 }}>
      <SectionHead kicker="Writing" title="Latest from the blog" byline="Notes on building AI systems. New posts most weeks." />
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 20 }}>
        {latest.map(p => (
          <TeaserCard key={p.id} post={p} onOpen={onOpen} />
        ))}
      </div>
      <div style={{ marginTop: 22, display: 'flex', justifyContent: 'flex-end' }}>
        <button onClick={onAll} style={{
          fontFamily: "'Press Start 2P', monospace",
          fontSize: 11, letterSpacing: '0.1em',
          padding: '12px 18px',
          background: 'var(--ink)', color: 'var(--paper)',
          border: '3px solid var(--ink)', boxShadow: '4px 4px 0 var(--accent)',
          cursor: 'pointer', textTransform: 'uppercase',
        }}>Read all posts →</button>
      </div>
    </section>
  );
}

function TeaserCard({ post, onOpen }) {
  return (
    <article
      onClick={() => onOpen(post.id)}
      style={{
        background: 'var(--paper)',
        border: '3px solid var(--ink)',
        boxShadow: '5px 5px 0 var(--ink)',
        padding: 18,
        cursor: 'pointer',
        display: 'flex', flexDirection: 'column', gap: 10,
      }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', fontFamily: "'JetBrains Mono',monospace", fontSize: 10, letterSpacing: '0.12em', textTransform: 'uppercase', color: 'var(--dark)' }}>
        <span>{post.category}</span>
        <span>{formatDate(post.date)}</span>
      </div>
      <h3 style={{ margin: 0, fontFamily: "'Old Standard TT',serif", fontSize: 24, fontWeight: 700, lineHeight: 1.1 }}>
        {post.title}
      </h3>
      <p style={{ margin: 0, fontFamily: "'Old Standard TT',serif", fontSize: 17, lineHeight: 1.4, color: 'var(--ink)' }}>
        {post.dek}
      </p>
      <div style={{ marginTop: 'auto', paddingTop: 8, fontFamily: "'JetBrains Mono',monospace", fontSize: 11, letterSpacing: '0.1em', color: 'var(--dark)', textTransform: 'uppercase', borderTop: '1px dotted var(--dark)' }}>
        {post.minutes} min read  ·  Read →
      </div>
    </article>
  );
}

// --- Full blog page (newspaper grid) ---
function BlogPage({ onOpen, onBack }) {
  const [lead, ...rest] = POSTS;
  const second = rest.slice(0, 2);
  const columns = rest.slice(2);
  return (
    <section id="blog-page">
      <div style={{ display: 'flex', alignItems: 'center', gap: 12, margin: '8px 0 18px' }}>
        <button onClick={onBack} style={{
          fontFamily: "'Press Start 2P',monospace", fontSize: 10, letterSpacing: '0.1em',
          padding: '8px 12px', background: 'transparent', border: '2px solid var(--ink)',
          cursor: 'pointer', textTransform: 'uppercase',
        }}>← Home</button>
        <div style={{ fontFamily: "'Press Start 2P',monospace", fontSize: 10, letterSpacing: '0.15em', color: 'var(--dark)' }}>— THE BLOG —</div>
      </div>

      <div style={{ borderTop: '3px double var(--rule)', borderBottom: '1px solid var(--rule)', padding: '20px 0' }}>
        <h1 style={{ margin: 0, fontFamily: "'Old Standard TT',serif", fontSize: 96, fontWeight: 700, letterSpacing: '-0.02em', lineHeight: 0.9 }}>
          Field Notes
        </h1>
        <div style={{ marginTop: 10, fontFamily: "'Old Standard TT',serif", fontStyle: 'italic', fontSize: 20 }}>
          On building AI systems — in business, in investing, and in public.
        </div>
      </div>

      {/* Lead story */}
      <div style={{ display: 'grid', gridTemplateColumns: '2fr 1fr', gap: 32, marginTop: 28 }}>
        <article onClick={() => onOpen(lead.id)} style={{ cursor: 'pointer' }}>
          <div style={{ fontFamily: "'JetBrains Mono',monospace", fontSize: 11, letterSpacing: '0.15em', textTransform: 'uppercase', color: 'var(--accent)', marginBottom: 8 }}>
            ★ LEAD STORY · {formatDate(lead.date)}
          </div>
          <h2 style={{ margin: 0, fontFamily: "'Old Standard TT',serif", fontSize: 56, fontWeight: 700, lineHeight: 0.95, letterSpacing: '-0.015em' }}>
            {lead.title}
          </h2>
          <div style={{ borderTop: '1px solid var(--rule)', margin: '14px 0', paddingTop: 14 }}>
            <p style={{ margin: 0, fontFamily: "'Old Standard TT',serif", fontStyle: 'italic', fontSize: 22, lineHeight: 1.45 }}>
              {lead.dek}
            </p>
          </div>
          <div style={{
            columnCount: 2, columnGap: 24,
            fontFamily: "'Old Standard TT',serif", fontSize: 17, lineHeight: 1.5, textAlign: 'justify',
          }}>
            <p style={{ marginTop: 0 }}>
              <span style={{ fontFamily: "'Press Start 2P',monospace", fontSize: 24, marginRight: 6, verticalAlign: '-2px', float: 'left', lineHeight: 0.9 }}>E</span>
              very AI system I've shipped has ended up using one of three orchestration patterns…
            </p>
            <p>Read the full piece — nine minute read, with examples from the £50k challenge build log and the trading infrastructure series.</p>
          </div>
          <button onClick={(e) => { e.stopPropagation(); onOpen(lead.id); }} style={{
            marginTop: 12,
            fontFamily: "'Press Start 2P',monospace", fontSize: 10, letterSpacing: '0.1em',
            padding: '10px 14px', background: 'var(--accent)', color: '#fff',
            border: '3px solid var(--ink)', boxShadow: '4px 4px 0 var(--ink)',
            cursor: 'pointer', textTransform: 'uppercase',
          }}>Read the lead →</button>
        </article>

        <div style={{ borderLeft: '1px solid var(--rule)', paddingLeft: 22, display: 'flex', flexDirection: 'column', gap: 18 }}>
          <div style={{ fontFamily: "'Press Start 2P',monospace", fontSize: 10, letterSpacing: '0.15em', color: 'var(--dark)' }}>— ALSO NEW —</div>
          {second.map(p => (
            <article key={p.id} onClick={() => onOpen(p.id)} style={{ cursor: 'pointer', borderBottom: '1px dotted var(--dark)', paddingBottom: 14 }}>
              <div style={{ fontFamily: "'JetBrains Mono',monospace", fontSize: 10, letterSpacing: '0.12em', textTransform: 'uppercase', color: 'var(--dark)', marginBottom: 6 }}>
                {p.category} · {formatDate(p.date)}
              </div>
              <h3 style={{ margin: 0, fontFamily: "'Old Standard TT',serif", fontSize: 24, fontWeight: 700, lineHeight: 1.1 }}>{p.title}</h3>
              <p style={{ margin: '8px 0 0', fontFamily: "'Old Standard TT',serif", fontSize: 17, lineHeight: 1.4 }}>{p.dek}</p>
            </article>
          ))}
        </div>
      </div>

      {/* Columns */}
      <div style={{ borderTop: '3px double var(--rule)', marginTop: 32, paddingTop: 24 }}>
        <div style={{ fontFamily: "'Press Start 2P',monospace", fontSize: 10, letterSpacing: '0.15em', color: 'var(--dark)', marginBottom: 16 }}>— THE ARCHIVE —</div>
        <div style={{
          display: 'grid',
          gridTemplateColumns: 'repeat(3, 1fr)',
          columnGap: 24,
          rowGap: 26,
        }}>
          {columns.map(p => (
            <article key={p.id} onClick={() => onOpen(p.id)} style={{ cursor: 'pointer', borderTop: '1px solid var(--rule)', paddingTop: 12 }}>
              <div style={{ fontFamily: "'JetBrains Mono',monospace", fontSize: 10, letterSpacing: '0.12em', textTransform: 'uppercase', color: 'var(--dark)', marginBottom: 6 }}>
                {formatDate(p.date)} · {p.minutes} min
              </div>
              <h4 style={{ margin: 0, fontFamily: "'Old Standard TT',serif", fontSize: 20, fontWeight: 700, lineHeight: 1.15 }}>{p.title}</h4>
              <p style={{ margin: '6px 0 0', fontFamily: "'Old Standard TT',serif", fontSize: 16, lineHeight: 1.4 }}>{p.dek}</p>
              <div style={{ marginTop: 8, fontFamily: "'JetBrains Mono',monospace", fontSize: 10, letterSpacing: '0.1em', textTransform: 'uppercase', color: 'var(--accent)' }}>
                Read →
              </div>
            </article>
          ))}
        </div>
      </div>
    </section>
  );
}

// --- Post detail reader ---
function PostPage({ id, onBack }) {
  const post = POSTS.find(p => p.id === id);
  if (!post) return null;
  const body = post.body || [
    "Placeholder body — this post will be filled in with the full piece.",
    "This is an AI-systems field note; the final version will run 600–1,200 words with examples from real builds.",
    "In the meantime, enjoy the headline. More soon."
  ];
  return (
    <section id="post-page" style={{ maxWidth: 720, margin: '0 auto' }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 12, margin: '8px 0 24px' }}>
        <button onClick={onBack} style={{
          fontFamily: "'Press Start 2P',monospace", fontSize: 10, letterSpacing: '0.1em',
          padding: '8px 12px', background: 'transparent', border: '2px solid var(--ink)',
          cursor: 'pointer', textTransform: 'uppercase',
        }}>← Back to blog</button>
      </div>

      <div style={{ fontFamily: "'JetBrains Mono',monospace", fontSize: 11, letterSpacing: '0.15em', textTransform: 'uppercase', color: 'var(--dark)', marginBottom: 12 }}>
        {post.category} · {formatDate(post.date)} · {post.minutes} min read
      </div>
      <h1 style={{ margin: 0, fontFamily: "'Old Standard TT',serif", fontSize: 56, fontWeight: 700, lineHeight: 0.95, letterSpacing: '-0.015em' }}>
        {post.title}
      </h1>
      <div style={{ borderTop: '1px solid var(--rule)', borderBottom: '1px solid var(--rule)', margin: '18px 0', padding: '14px 0' }}>
        <div style={{ fontFamily: "'Old Standard TT',serif", fontStyle: 'italic', fontSize: 22, lineHeight: 1.4 }}>
          {post.dek}
        </div>
      </div>

      <div style={{ fontFamily: "'Old Standard TT',serif", fontSize: 19, lineHeight: 1.65 }}>
        {body.map((para, i) => (
          <p key={i} style={{ margin: '0 0 18px', textAlign: 'justify' }}>
            {i === 0 && (
              <span style={{ fontFamily: "'Press Start 2P',monospace", fontSize: 28, marginRight: 6, verticalAlign: '-2px', float: 'left', lineHeight: 0.9 }}>
                {para.charAt(0)}
              </span>
            )}
            {i === 0 ? para.slice(1) : para}
          </p>
        ))}
      </div>

      <div style={{ marginTop: 32, borderTop: '3px double var(--rule)', paddingTop: 20, display: 'flex', justifyContent: 'space-between', flexWrap: 'wrap', gap: 14 }}>
        <div style={{ fontFamily: "'Old Standard TT',serif", fontStyle: 'italic', fontSize: 16, color: 'var(--dark)' }}>
          — Lewis, writing from London
        </div>
        <button onClick={onBack} style={{
          fontFamily: "'Press Start 2P',monospace", fontSize: 10, letterSpacing: '0.1em',
          padding: '10px 14px', background: 'var(--ink)', color: 'var(--paper)',
          border: '3px solid var(--ink)', boxShadow: '4px 4px 0 var(--accent)',
          cursor: 'pointer', textTransform: 'uppercase',
        }}>More posts →</button>
      </div>
    </section>
  );
}

Object.assign(window, { LatestWriting, BlogPage, PostPage, POSTS });
