// docs.jsx — Heartbeat Kit API reference

const { useState, useEffect } = React;

const SECTIONS = [
  { id: 'introduction',   group: 'Get started',  label: 'Introduction' },
  { id: 'quickstart',     group: 'Get started',  label: 'Quickstart' },
  { id: 'authentication', group: 'Get started',  label: 'Authentication' },
  { id: 'concepts',       group: 'Concepts',     label: 'Heartbeats' },
  { id: 'modes',          group: 'Concepts',     label: 'Modes' },
  { id: 'policies',       group: 'Concepts',     label: 'Escalation policies' },
  { id: 'channels',       group: 'Concepts',     label: 'Channels' },
  { id: 'create',         group: 'API reference', label: 'POST /heartbeats' },
  { id: 'checkin',        group: 'API reference', label: 'POST /heartbeats/{slug}/checkin' },
  { id: 'list',           group: 'API reference', label: 'GET /heartbeats' },
  { id: 'ack',            group: 'API reference', label: 'POST /events/{id}/ack' },
  { id: 'webhooks',       group: 'Guides',       label: 'Webhook signatures' },
  { id: 'mcp',            group: 'Guides',       label: 'MCP server' },
  { id: 'errors',         group: 'Reference',    label: 'Error codes' },
];

function App() {
  const [active, setActive] = useState('introduction');

  useEffect(() => {
    const obs = new IntersectionObserver(
      entries => {
        entries.forEach(e => {
          if (e.isIntersecting) setActive(e.target.id);
        });
      },
      { rootMargin: '-30% 0px -60% 0px' }
    );
    SECTIONS.forEach(s => {
      const el = document.getElementById(s.id);
      if (el) obs.observe(el);
    });
    return () => obs.disconnect();
  }, []);

  return (
    <>
      <Nav current="docs" />
      <div style={{ display: 'grid', gridTemplateColumns: '260px 1fr 280px', maxWidth: 1440, margin: '0 auto', minHeight: '100vh' }}>
        <Sidebar active={active} />
        <Main />
        <RightRail />
      </div>
      <Footer />
    </>
  );
}

function Sidebar({ active }) {
  const groups = SECTIONS.reduce((acc, s) => {
    (acc[s.group] = acc[s.group] || []).push(s);
    return acc;
  }, {});
  return (
    <aside style={{
      borderRight: '1px solid rgba(255,255,255,0.05)',
      padding: '40px 20px 40px 32px',
      position: 'sticky', top: 64, alignSelf: 'flex-start',
      height: 'calc(100vh - 64px)', overflowY: 'auto',
    }}>
      <div style={{ marginBottom: 24 }}>
        <div style={{
          display: 'flex', alignItems: 'center', gap: 8,
          padding: '8px 12px', borderRadius: 8,
          background: 'var(--navy-2)', border: '1px solid var(--border)',
          fontFamily: 'var(--f-mono)', fontSize: 12, color: 'var(--slate)',
        }}>
          <svg width="12" height="12" viewBox="0 0 12 12" fill="none">
            <circle cx="5" cy="5" r="3.5" stroke="currentColor" />
            <path d="M8 8 L11 11" stroke="currentColor" strokeLinecap="round" />
          </svg>
          Search docs
          <span style={{ marginLeft: 'auto', fontSize: 10, padding: '2px 5px', border: '1px solid var(--border)', borderRadius: 3 }}>⌘K</span>
        </div>
      </div>
      {Object.entries(groups).map(([g, items]) => (
        <div key={g} style={{ marginBottom: 28 }}>
          <div className="eyebrow" style={{ fontSize: 11, marginBottom: 10 }}>{g}</div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
            {items.map(s => (
              <a key={s.id} href={`#${s.id}`} style={{
                padding: '6px 10px',
                borderRadius: 6,
                fontSize: 14,
                color: active === s.id ? 'var(--cyan)' : 'var(--slate)',
                background: active === s.id ? 'rgba(0,228,168,0.08)' : 'transparent',
                fontWeight: active === s.id ? 500 : 400,
                fontFamily: s.label.startsWith('POST') || s.label.startsWith('GET') ? 'var(--f-mono)' : 'inherit',
                fontSize: s.label.startsWith('POST') || s.label.startsWith('GET') ? 12.5 : 14,
              }}>{s.label}</a>
            ))}
          </div>
        </div>
      ))}
    </aside>
  );
}

function Main() {
  return (
    <main style={{ padding: '40px 56px', maxWidth: 880 }}>
      <Section id="introduction" eyebrow="Get started" title="Introduction">
        <p className="lede" style={{ marginBottom: 24 }}>
          Heartbeat Kit is a hosted API for creating <em>heartbeats</em> — promises to check in
          on a schedule. When a promise breaks, an escalation policy fires.
        </p>
        <p>
          This reference covers every endpoint, every concept, every error code. If you're new,
          start with <a href="#quickstart" style={{ color: 'var(--cyan)' }}>Quickstart</a>. If
          you want a flavor first, here it is:
        </p>
        <Code label="agent.ts" lang="typescript">
<span className="kw">import</span>{` { `}<span className="var">HeartbeatKit</span>{` } `}<span className="kw">from</span>{` `}<span className="str">'@heartbeatkit/sdk'</span>{`

`}<span className="kw">const</span>{` `}<span className="var">hbk</span>{` = `}<span className="kw">new</span>{` `}<span className="fn">HeartbeatKit</span>{`({ `}<span className="prop">apiKey</span>{`: process.env.HBK_KEY })

`}<span className="kw">const</span>{` `}<span className="var">task</span>{` = `}<span className="kw">await</span>{` hbk.`}<span className="fn">task</span>{`(`}<span className="str">'process-batch'</span>{`, { `}<span className="prop">timeout</span>{`: `}<span className="num">600</span>{` })
`}<span className="kw">await</span>{` `}<span className="fn">processBatch</span>{`()
`}<span className="kw">await</span>{` task.`}<span className="fn">complete</span>{`()`}
        </Code>
        <Callout kind="info">
          Heartbeat Kit runs entirely on Cloudflare's edge. p50 dispatch is 12 ms, p99 is 120 ms,
          regardless of your client's location.
        </Callout>
      </Section>

      <Section id="quickstart" eyebrow="Get started" title="Quickstart">
        <p>Three steps to your first heartbeat:</p>
        <NumberedSteps steps={[
          {
            t: 'Get an API key',
            d: <>Sign up at <span className="mono" style={{ color: 'var(--cyan)' }}>heartbeatkit.com</span> and grab a key from the dashboard.</>,
          },
          {
            t: 'Create a heartbeat',
            d: 'One POST. Slug is required and must be unique within your project.',
            code: `curl -X POST https://api.heartbeatkit.com/v1/heartbeats \\\n  -H "Authorization: Bearer $HBK_KEY" \\\n  -d '{\n    "name": "nightly-backup",\n    "slug": "nightly-backup",\n    "mode": "scheduled",\n    "schedule": "0 3 * * *",\n    "grace": 1800\n  }'`
          },
          {
            t: 'Check in when the work succeeds',
            d: 'Run this at the end of your job. If it never runs, escalation fires.',
            code: `curl -X POST https://api.heartbeatkit.com/v1/heartbeats/nightly-backup/checkin \\\n  -H "Authorization: Bearer $HBK_KEY"`
          },
        ]} />
      </Section>

      <Section id="authentication" eyebrow="Get started" title="Authentication">
        <p>
          Every request requires a bearer token. Tokens are scoped per-project and can be rotated
          from the dashboard. Use <span className="mono" style={{ color: 'var(--cyan)' }}>hbk_test_</span> keys for development;
          <span className="mono" style={{ color: 'var(--cyan)' }}> hbk_live_</span> for production.
        </p>
        <Code label="Authorization header">
<span className="prop">Authorization</span>{`: `}<span className="str">Bearer hbk_live_4f8e2a1c9b3d7e5f</span>
        </Code>
        <Callout kind="warn">
          Never commit live keys. The dashboard auto-revokes any key found in a public GitHub
          commit within 5 minutes of detection.
        </Callout>
      </Section>

      <Section id="concepts" eyebrow="Concepts" title="Heartbeats">
        <p>
          A heartbeat is a contract between your code and Heartbeat Kit. You promise to check in
          before some deadline; we promise to escalate if you don't. Every heartbeat has:
        </p>
        <DefList items={[
          ['name',     'Human-readable label, shown in the dashboard.'],
          ['slug',     'URL-safe identifier — forms part of the check-in URL.'],
          ['mode',     'recurring · oneshot · scheduled — see Modes below.'],
          ['interval', 'For recurring: seconds between expected check-ins.'],
          ['grace',    'Extra seconds before firing. Default: 10% of interval.'],
          ['policy',   'Escalation policy ID. Determines what happens on miss.'],
          ['namespace', 'Optional grouping label for the dashboard fleet view.'],
        ]} />
      </Section>

      <Section id="modes" eyebrow="Concepts" title="Modes">
        <p>Three flavors of timer cover almost everything:</p>
        <Table headers={['Mode', 'Use when', 'Example']} rows={[
          ['recurring',  'Long-running process should report regularly.',         'AI agent loop · IoT device · cron-like daemon'],
          ['oneshot',    'A finite task must complete by a deadline.',            'Deploy step · batch import · scheduled task'],
          ['scheduled',  'A wall-clock event should happen by a specific time.',  'Nightly backup · weekly report · 3am cleanup'],
        ]} />
      </Section>

      <Section id="policies" eyebrow="Concepts" title="Escalation policies">
        <p>
          When a heartbeat misses its deadline (interval + grace, or schedule + grace), the
          attached policy starts walking its <em>steps</em>. Each step targets a channel and waits
          a delay before continuing. If anyone acks, the chain stops.
        </p>
        <Code label="policy.json" lang="json">
{`{
  `}<span className="prop">"name"</span>{`: `}<span className="str">"critical-response"</span>{`,
  `}<span className="prop">"steps"</span>{`: [
    { `}<span className="prop">"order"</span>{`: `}<span className="num">1</span>{`, `}<span className="prop">"delay"</span>{`: `}<span className="str">"0s"</span>{`,  `}<span className="prop">"channels"</span>{`: [`}<span className="str">"ch_slack"</span>{`],  `}<span className="prop">"unless"</span>{`: `}<span className="str">"acknowledged"</span>{` },
    { `}<span className="prop">"order"</span>{`: `}<span className="num">2</span>{`, `}<span className="prop">"delay"</span>{`: `}<span className="str">"5m"</span>{`,  `}<span className="prop">"channels"</span>{`: [`}<span className="str">"ch_email"</span>{`],  `}<span className="prop">"unless"</span>{`: `}<span className="str">"acknowledged"</span>{` },
    { `}<span className="prop">"order"</span>{`: `}<span className="num">3</span>{`, `}<span className="prop">"delay"</span>{`: `}<span className="str">"15m"</span>{`, `}<span className="prop">"channels"</span>{`: [`}<span className="str">"ch_agent"</span>{`],  `}<span className="prop">"terminal"</span>{`: `}<span className="kw">true</span>{` }
  ]
}`}
        </Code>
      </Section>

      <Section id="channels" eyebrow="Concepts" title="Channels">
        <p>Four channel types. Mix them freely inside a single policy.</p>
        <Table headers={['Channel', 'Description']} rows={[
          ['webhook',  'HMAC-signed POST to any URL.'],
          ['email',    'Native Cloudflare email — instant delivery, zero config.'],
          ['websocket','Real-time push to your dashboard or connected agents.'],
          ['agent',    'AI investigates, acts via configured tools, reports back.'],
        ]} />
      </Section>

      <Section id="create" eyebrow="API reference" title="POST /heartbeats">
        <Endpoint method="POST" path="/v1/heartbeats" />
        <p>Creates a new heartbeat. Slug must be unique within the project.</p>
        <DefList compact title="Body parameters" items={[
          ['name',      'string · required'],
          ['slug',      'string · required · [a-z0-9-]+'],
          ['mode',      "'recurring' | 'oneshot' | 'scheduled' · required"],
          ['interval',  'number · seconds · required when mode = recurring'],
          ['schedule',  'cron string · required when mode = scheduled'],
          ['timeout',   'number · seconds · required when mode = oneshot'],
          ['grace',     'number · seconds · default 10% of interval'],
          ['policy',    'string · escalation policy ID · default project policy'],
        ]} />
        <Code label="Response 201" lang="json">
{`{
  `}<span className="prop">"id"</span>{`: `}<span className="str">"hb_8fka2x9z"</span>{`,
  `}<span className="prop">"slug"</span>{`: `}<span className="str">"order-processor"</span>{`,
  `}<span className="prop">"status"</span>{`: `}<span className="str">"active"</span>{`,
  `}<span className="prop">"next_deadline"</span>{`: `}<span className="str">"2026-05-04T14:03:50Z"</span>{`,
  `}<span className="prop">"created_at"</span>{`: `}<span className="str">"2026-05-04T14:02:50Z"</span>
{`}`}
        </Code>
      </Section>

      <Section id="checkin" eyebrow="API reference" title="POST /heartbeats/{slug}/checkin">
        <Endpoint method="POST" path="/v1/heartbeats/{slug}/checkin" />
        <p>Records a check-in. The next deadline advances by the heartbeat's interval.</p>
        <DefList compact title="Body parameters (all optional)" items={[
          ['healthy',  'boolean · pass false to fire immediately'],
          ['metadata', 'object · arbitrary key/values, available to health rules'],
        ]} />
        <Code label="Example" lang="bash">
{`curl -X POST https://api.heartbeatkit.com/v1/heartbeats/agent-research-7/checkin \\
  -H `}<span className="str">"Authorization: Bearer $HBK_KEY"</span>{` \\
  -d `}<span className="str">{`'{ "metadata": { "processed": 412, "spend": 13.10 } }'`}</span>
        </Code>
      </Section>

      <Section id="list" eyebrow="API reference" title="GET /heartbeats">
        <Endpoint method="GET" path="/v1/heartbeats" />
        <p>Lists heartbeats in the current project. Paginated, default 50 per page.</p>
        <DefList compact title="Query parameters" items={[
          ['status',    "'active' | 'firing' | 'paused'"],
          ['namespace', 'string'],
          ['cursor',    'string · pagination cursor from previous response'],
          ['limit',     'number · 1–100 · default 50'],
        ]} />
      </Section>

      <Section id="ack" eyebrow="API reference" title="POST /events/{id}/ack">
        <Endpoint method="POST" path="/v1/events/{id}/ack" />
        <p>Acknowledges a firing event. Stops escalation immediately. Returns the event with the new state.</p>
      </Section>

      <Section id="webhooks" eyebrow="Guides" title="Webhook signatures">
        <p>
          Every webhook is signed with HMAC-SHA256. The signature is in the
          <span className="mono" style={{ color: 'var(--cyan)' }}> X-HBK-Signature</span> header.
          Verify it before trusting the body.
        </p>
        <Code label="verify.ts" lang="typescript">
<span className="kw">import</span>{` { createHmac } `}<span className="kw">from</span>{` `}<span className="str">'crypto'</span>{`

`}<span className="kw">function</span>{` `}<span className="fn">verify</span>{`(body: `}<span className="prop">string</span>{`, sig: `}<span className="prop">string</span>{`, secret: `}<span className="prop">string</span>{`) {
  `}<span className="kw">const</span>{` expected = `}<span className="fn">createHmac</span>{`(`}<span className="str">'sha256'</span>{`, secret).`}<span className="fn">update</span>{`(body).`}<span className="fn">digest</span>{`(`}<span className="str">'hex'</span>{`)
  `}<span className="kw">return</span>{` sig === `}<span className="str">{`\`sha256=\${expected}\``}</span>
{`}`}
        </Code>
      </Section>

      <Section id="mcp" eyebrow="Guides" title="MCP server">
        <p>
          Heartbeat Kit ships a Model Context Protocol server at
          <span className="mono" style={{ color: 'var(--cyan)' }}> mcp.heartbeatkit.com</span>.
          Any MCP-aware agent gets the full API as native tools — no SDK install required.
        </p>
        <Code label="claude_desktop_config.json" lang="json">
{`{
  `}<span className="prop">"mcpServers"</span>{`: {
    `}<span className="prop">"heartbeat-kit"</span>{`: {
      `}<span className="prop">"url"</span>{`: `}<span className="str">"https://mcp.heartbeatkit.com"</span>{`,
      `}<span className="prop">"headers"</span>{`: {
        `}<span className="prop">"Authorization"</span>{`: `}<span className="str">"Bearer hbk_live_..."</span>
{`      }
    }
  }
}`}
        </Code>
        <p>The agent will see 12 tools: <span className="mono" style={{ fontSize: 13 }}>create_heartbeat, checkin, list_heartbeats, get_heartbeat, pause, resume, create_policy, ...</span></p>
      </Section>

      <Section id="errors" eyebrow="Reference" title="Error codes">
        <Table headers={['Code', 'HTTP', 'Meaning']} rows={[
          ['heartbeat.not_found',     '404', 'No heartbeat with that slug in this project.'],
          ['heartbeat.slug_taken',    '409', 'Slug already exists in this project.'],
          ['policy.not_found',        '404', 'Referenced escalation policy does not exist.'],
          ['auth.invalid_key',        '401', 'API key is malformed, expired, or revoked.'],
          ['auth.scope_mismatch',     '403', 'Key does not have access to this project.'],
          ['rate_limit.exceeded',     '429', 'Too many requests. See Retry-After header.'],
          ['validation.invalid_cron', '422', 'Cron schedule string is invalid.'],
        ]} />
      </Section>
    </main>
  );
}

function RightRail() {
  return (
    <aside style={{
      borderLeft: '1px solid rgba(255,255,255,0.05)',
      padding: '40px 32px 40px 24px',
      position: 'sticky', top: 64, alignSelf: 'flex-start',
      height: 'calc(100vh - 64px)', overflowY: 'auto',
    }}>
      <div className="eyebrow" style={{ fontSize: 11, marginBottom: 14 }}>API status</div>
      <div style={{
        background: 'var(--navy-2)', border: '1px solid var(--border-soft)',
        borderRadius: 10, padding: '14px 16px', fontFamily: 'var(--f-mono)', fontSize: 12,
      }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 10 }}>
          <span style={{ color: 'var(--slate)' }}>api.heartbeatkit.com</span>
          <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6, color: 'var(--cyan)' }}>
            <span className="dot active" /> 200
          </span>
        </div>
        <div style={{ display: 'flex', justifyContent: 'space-between', color: 'var(--slate)', fontSize: 11.5 }}>
          <span>p50 latency</span><span style={{ color: 'var(--sand)' }}>12ms</span>
        </div>
        <div style={{ display: 'flex', justifyContent: 'space-between', color: 'var(--slate)', fontSize: 11.5, marginTop: 4 }}>
          <span>p99 latency</span><span style={{ color: 'var(--sand)' }}>120ms</span>
        </div>
        <div style={{ display: 'flex', justifyContent: 'space-between', color: 'var(--slate)', fontSize: 11.5, marginTop: 4 }}>
          <span>uptime · 90d</span><span style={{ color: 'var(--cyan)' }}>99.99%</span>
        </div>
      </div>

      <div className="eyebrow" style={{ fontSize: 11, marginTop: 28, marginBottom: 14 }}>SDKs</div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
        {[
          ['@heartbeatkit/sdk', 'TypeScript · Node, Bun, Deno, Workers'],
          ['heartbeatkit (PyPI)', 'Python 3.10+'],
          ['heartbeatkit-go', 'Go 1.22+'],
          ['MCP server', 'For any MCP-aware agent'],
        ].map(([n, d]) => (
          <a key={n} href="#" style={{
            display: 'block', padding: '10px 12px',
            border: '1px solid var(--border-soft)', borderRadius: 8,
            background: 'var(--navy-2)',
          }}>
            <div className="mono" style={{ fontSize: 12.5, color: 'var(--cyan)' }}>{n}</div>
            <div style={{ fontSize: 12, color: 'var(--slate)', marginTop: 2 }}>{d}</div>
          </a>
        ))}
      </div>

      <div className="eyebrow" style={{ fontSize: 11, marginTop: 28, marginBottom: 14 }}>Help</div>
      <a href="#" style={{ fontSize: 13, color: 'var(--slate)', display: 'block', padding: '6px 0' }}>Discord community</a>
      <a href="#" style={{ fontSize: 13, color: 'var(--slate)', display: 'block', padding: '6px 0' }}>GitHub issues</a>
      <a href="#" style={{ fontSize: 13, color: 'var(--slate)', display: 'block', padding: '6px 0' }}>support@heartbeatkit.com</a>
    </aside>
  );
}

// Section primitive
function Section({ id, eyebrow, title, children }) {
  return (
    <section id={id} data-screen-label={id} style={{ scrollMarginTop: 80, padding: '32px 0 64px', borderBottom: '1px solid rgba(255,255,255,0.04)' }}>
      <div className="eyebrow" style={{ marginBottom: 12 }}>{eyebrow}</div>
      <h2 style={{
        fontFamily: 'var(--f-display)', fontSize: 38, fontWeight: 600,
        letterSpacing: '-0.02em', margin: '0 0 24px',
      }}>{title}</h2>
      <div style={{ fontSize: 16, lineHeight: 1.65, color: '#cfd0d6', display: 'flex', flexDirection: 'column', gap: 20 }}>
        {children}
      </div>
    </section>
  );
}

function Callout({ kind = 'info', children }) {
  const accent = kind === 'warn' ? 'var(--coral)' : 'var(--cyan)';
  const bg = kind === 'warn' ? 'rgba(255,111,97,0.06)' : 'rgba(0,228,168,0.06)';
  const tag = kind === 'warn' ? 'WARN' : 'NOTE';
  return (
    <div style={{
      borderLeft: `2px solid ${accent}`,
      background: bg, padding: '16px 20px',
      borderRadius: 4, fontSize: 14.5, color: '#cfd0d6',
      display: 'flex', gap: 16,
    }}>
      <span className="mono" style={{ fontSize: 11, color: accent, fontWeight: 700, letterSpacing: '0.08em', flexShrink: 0, marginTop: 2 }}>{tag}</span>
      <span>{children}</span>
    </div>
  );
}

function NumberedSteps({ steps }) {
  return (
    <ol style={{ margin: 0, padding: 0, listStyle: 'none', display: 'flex', flexDirection: 'column', gap: 24 }}>
      {steps.map((s, i) => (
        <li key={i} style={{ display: 'grid', gridTemplateColumns: '40px 1fr', gap: 16 }}>
          <span style={{
            width: 30, height: 30, borderRadius: '50%',
            border: '1px solid var(--border)',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            fontFamily: 'var(--f-mono)', fontSize: 13, color: 'var(--cyan)',
          }}>{i + 1}</span>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
            <div style={{ fontFamily: 'var(--f-display)', fontSize: 18, fontWeight: 600, color: 'var(--sand)' }}>{s.t}</div>
            <div>{s.d}</div>
            {s.code && (
              <pre style={{
                margin: 0, background: '#06070b', border: '1px solid var(--border)',
                borderRadius: 8, padding: '14px 16px',
                fontFamily: 'var(--f-mono)', fontSize: 13, lineHeight: 1.6,
                color: '#cdd0d8', overflow: 'auto',
              }}>{s.code}</pre>
            )}
          </div>
        </li>
      ))}
    </ol>
  );
}

function DefList({ title, items, compact }) {
  return (
    <div>
      {title && <div className="eyebrow" style={{ fontSize: 11, marginBottom: 12 }}>{title}</div>}
      <div style={{ borderTop: '1px solid var(--border-soft)' }}>
        {items.map(([k, v]) => (
          <div key={k} style={{
            display: 'grid', gridTemplateColumns: '180px 1fr',
            padding: compact ? '10px 0' : '12px 0',
            borderBottom: '1px solid var(--border-soft)',
            fontSize: 14,
          }}>
            <span className="mono" style={{ color: 'var(--cyan)' }}>{k}</span>
            <span style={{ color: '#cfd0d6' }}>{v}</span>
          </div>
        ))}
      </div>
    </div>
  );
}

function Endpoint({ method, path }) {
  return (
    <div style={{
      display: 'inline-flex', alignItems: 'center', gap: 12,
      padding: '8px 14px', background: '#06070b',
      border: '1px solid var(--border)', borderRadius: 8,
      fontFamily: 'var(--f-mono)', fontSize: 13.5,
    }}>
      <span style={{
        padding: '2px 8px', borderRadius: 4,
        background: method === 'GET' ? 'rgba(158,195,255,0.15)' : 'rgba(0,228,168,0.15)',
        color: method === 'GET' ? '#9ec3ff' : 'var(--cyan)',
        fontWeight: 700, fontSize: 11, letterSpacing: '0.06em',
      }}>{method}</span>
      <span style={{ color: 'var(--sand)' }}>{path}</span>
    </div>
  );
}

function Table({ headers, rows }) {
  return (
    <div style={{
      border: '1px solid var(--border-soft)', borderRadius: 10, overflow: 'hidden',
    }}>
      <div style={{
        display: 'grid', gridTemplateColumns: `repeat(${headers.length}, 1fr)`,
        background: '#0e0f17', padding: '12px 18px',
        fontFamily: 'var(--f-mono)', fontSize: 11,
        textTransform: 'uppercase', letterSpacing: '0.06em',
        color: 'var(--slate)', borderBottom: '1px solid var(--border-soft)',
      }}>
        {headers.map(h => <span key={h}>{h}</span>)}
      </div>
      {rows.map((r, i) => (
        <div key={i} style={{
          display: 'grid', gridTemplateColumns: `repeat(${headers.length}, 1fr)`,
          padding: '12px 18px',
          borderBottom: i === rows.length - 1 ? 'none' : '1px solid rgba(255,255,255,0.04)',
          fontSize: 14, color: '#cfd0d6',
        }}>
          {r.map((v, j) => (
            <span key={j} style={{
              fontFamily: j === 0 ? 'var(--f-mono)' : 'inherit',
              color: j === 0 ? 'var(--cyan)' : '#cfd0d6',
              fontSize: j === 0 ? 13 : 14,
            }}>{v}</span>
          ))}
        </div>
      ))}
    </div>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
