// Static docs pages — Quickstart, Authentication, Errors, Async jobs.
// Each is a React component rendered by a thin HTML shell.

const DocPage = ({ activeId, kicker, title, sub, current = 'Docs', children }) => (
  <Page current={current}>
    <Breadcrumbs items={[{ l:'Docs', href:'docs.html' }, { l: title }]} />
    <PageHero kicker={kicker} title={title} sub={sub} />
    <DocsLayout activeId={activeId}>{children}</DocsLayout>
  </Page>
);

const Code = ({ lang = 'cURL', filename, lines }) => (
  <CodeTabs filename={filename} tabs={[{ lang, lines }]} />
);

const Btn = ({ children, primary, size = 13, style, ...rest }) => (
  <button {...rest} style={{
    fontFamily: wf.sans, fontSize: size, fontWeight: 500,
    padding: '9px 14px', borderRadius: 8, cursor: 'pointer',
    border: primary ? '1px solid var(--accent)' : `1px solid ${wf.line}`,
    background: primary ? 'var(--accent)' : wf.card,
    color: primary ? '#fff' : wf.ink,
    ...style,
  }}>{children}</button>
);

// ─────────────────────────────────────────────────────────────── Quickstart ──

const QuickstartPage = () => (
  <DocPage
    activeId="quickstart"
    kicker="Getting started"
    title="Quickstart"
    sub="Run your first MomentIQ call in under 60 seconds. cURL, JavaScript, or Python — same key on every endpoint."
  >
    <H2 id="signup">1. Get your API key</H2>
    <P>Create an account and grab a key from the dashboard. Every account ships with $5 in free credits — no card required.</P>
    <div style={{ display:'flex', gap:8, margin:'8px 0 24px' }}>
      <a href="dashboard.html?auth=signup" style={{ textDecoration:'none' }}><Btn primary size={14}>Start free</Btn></a>
      <a href="docs-authentication.html" style={{ textDecoration:'none' }}><Btn size={14}>Read auth docs →</Btn></a>
    </div>

    <H2 id="first-call">2. Make your first call</H2>
    <P>The simplest call: ask <code style={{ fontFamily: wf.mono, fontSize: 13 }}>video/best-frames</code> to pick the clearest frames from a video.</P>
    <CodeTabs filename="first-call" tabs={[
      { lang:'cURL', lines:[
        `curl https://api.momentiq.dev/v1/video/best-frames \\`,
        `  -H "Authorization: Bearer $MIQ_KEY" \\`,
        `  -H "Content-Type: application/json" \\`,
        `  -d '{"media_url":"https://cdn.momentiq.dev/demo/lecture-08.mp4","max_frames":8}'`,
      ]},
      { lang:'JavaScript', lines:[
        `const res = await fetch("https://api.momentiq.dev/v1/video/best-frames", {`,
        `  method: "POST",`,
        `  headers: {`,
        `    "Authorization": "Bearer " + process.env.MIQ_KEY,`,
        `    "Content-Type": "application/json",`,
        `  },`,
        `  body: JSON.stringify({ media_url: "https://...", max_frames: 8 }),`,
        `});`,
        `const data = await res.json();`,
      ]},
      { lang:'Python', lines:[
        `import os, requests`,
        `r = requests.post(`,
        `  "https://api.momentiq.dev/v1/video/best-frames",`,
        `  headers={"Authorization": f"Bearer {os.environ['MIQ_KEY']}"},`,
        `  json={"media_url": "https://...", "max_frames": 8},`,
        `)`,
        `data = r.json()`,
      ]},
    ]} />

    <H2 id="laughs">3. Find the funny moments — detect-laughter</H2>
    <P>Pass any media URL to <code style={{ fontFamily:wf.mono, fontSize:13 }}>audio/detect-laughter</code> and you'll get back a list of laughter events with confidence scores. Useful for podcast clipping.</P>
    <Code lang="JSON" filename="detect-laughter.req.json" lines={[
      `{`,
      `  "media_url": "https://cdn.momentiq.dev/demo/podcast-ep-42.mp4",`,
      `  "sensitivity": 0.62`,
      `}`,
    ]} />
    <Code lang="JSON" filename="detect-laughter.res.json" lines={[
      `{`,
      `  "results": [`,
      `    { "t": 862.4, "dur": 1.8, "conf": 0.94 },`,
      `    { "t": 948.1, "dur": 0.9, "conf": 0.81 }`,
      `  ],`,
      `  "price_usd": 0.21`,
      `}`,
    ]} />

    <H2 id="chain">4. Chain two endpoints — laugh → render clip</H2>
    <P>The MomentIQ pattern: one endpoint finds moments, another acts on them. Detect a laugh, then call <code style={{ fontFamily:wf.mono, fontSize:13 }}>video/clip-near</code> to render a clip with smart silence-aware boundaries.</P>
    <Code lang="JavaScript" filename="laugh-to-clip.js" lines={[
      `// 1. find laughter`,
      `const laughs = await miq.audio.detectLaughter({`,
      `  media_url: SRC, sensitivity: 0.62,`,
      `});`,
      ``,
      `// 2. render the top laugh as a 30s clip`,
      `const top = laughs.results.sort((a,b) => b.conf - a.conf)[0];`,
      `const clip = await miq.video.clipNear({`,
      `  media_url: SRC,`,
      `  t: top.t,`,
      `  target_duration: 30,`,
      `  snap: true,        // align to silence + cuts`,
      `});`,
      ``,
      `console.log(clip.url);  // → playable mp4`,
    ]} />

    <H2 id="async">5. Long media? Use async jobs</H2>
    <P>Calls under ~5 minutes of source media respond inline. For longer media, submit an async job and poll, or wire a webhook. Full details in <a href="docs-async-jobs.html" style={{ color:'var(--accent)' }}>Async jobs</a>.</P>
    <Code lang="cURL" filename="async-job" lines={[
      `# kick off a job`,
      `curl https://api.momentiq.dev/v1/jobs \\`,
      `  -H "Authorization: Bearer $MIQ_KEY" \\`,
      `  -d '{"endpoint":"audio/detect-speakers","params":{...}}'`,
      `# → { "job_id": "job_8x2…", "status": "pending" }`,
      ``,
      `# poll`,
      `curl https://api.momentiq.dev/v1/jobs/job_8x2… \\`,
      `  -H "Authorization: Bearer $MIQ_KEY"`,
    ]} />

    <H2 id="cost">6. Estimate cost before you run</H2>
    <P>Every endpoint reports its price-per-minute. Multiply by your media length to estimate cost; the API also returns the actual <code style={{ fontFamily:wf.mono, fontSize:13 }}>price_usd</code> on every successful response.</P>
    <ApiTable cols={['Endpoint','Per-minute','30-min media']} rows={[
      ['video/best-frames',  '$0.035 / video min', '$1.05'],
      ['audio/detect-laughter','$0.035 / audio min', '$1.05'],
      ['audio/detect-speakers','$0.045 / audio min', '$1.35'],
      ['video/clip-near',    '$0.035 / clip min','depends on output length'],
      ['timeline/merge',     '$0.005 / request',   '$0.005'],
    ]} />

    <H2 id="caps">7. Set a hard spending cap</H2>
    <P>Open <a href="dashboard-billing.html" style={{ color:'var(--accent)' }}>Billing</a> and set a monthly cap. The API returns <code style={{ fontFamily:wf.mono, fontSize:13 }}>insufficient_credits</code> the moment you'd cross it — no surprise invoices. See <a href="docs-errors.html#insufficient_credits" style={{ color:'var(--accent)' }}>Errors</a> for the response shape.</P>

    <div style={{ marginTop: 36, padding: 22, background: wf.dark, color: wf.card, borderRadius: 12, display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 16, flexWrap: 'wrap' }}>
      <div>
        <div style={{ fontFamily: wf.sans, fontSize: 18, fontWeight: 600 }}>Try in Moment Lab</div>
        <div style={{ fontFamily: wf.sans, fontSize: 13, color: wf.darkInk2, marginTop: 4 }}>Pick any endpoint. Tweak parameters. Copy the call.</div>
      </div>
      <a href="index.html" style={{ textDecoration: 'none' }}><Btn primary size={14}>Try in Moment Lab</Btn></a>
    </div>
  </DocPage>
);

// ───────────────────────────────────────────────────────────── AI Agents ──

const PathCard = ({ kicker, title, desc, href, cta, steps = [], accent = 'var(--accent)' }) => (
  <a href={href} style={{
    display:'flex', flexDirection:'column', gap:12,
    textDecoration:'none', color:'inherit',
    background:wf.card, border:`1px solid ${accent}`, borderRadius:10,
    padding:18, boxShadow:`inset 0 2px 0 ${accent}`, minHeight:260,
  }}>
    <div style={{ fontFamily:wf.mono, fontSize:11, letterSpacing:1.2, color:accent, textTransform:'uppercase' }}>{kicker}</div>
    <div style={{ fontFamily:wf.sans, fontSize:21, fontWeight:650, letterSpacing:-0.3 }}>{title}</div>
    <div style={{ fontFamily:wf.sans, fontSize:14, color:wf.ink2, lineHeight:1.55 }}>{desc}</div>
    <div style={{ display:'flex', flexDirection:'column', gap:7, marginTop:2 }}>
      {steps.map((step, i) => (
        <div key={step} style={{ display:'grid', gridTemplateColumns:'22px 1fr', gap:8, alignItems:'baseline', fontFamily:wf.sans, fontSize:13.5, color:wf.ink2 }}>
          <span style={{ fontFamily:wf.mono, fontSize:10.5, color:accent }}>{String(i + 1).padStart(2, '0')}</span>
          <span>{step}</span>
        </div>
      ))}
    </div>
    <div style={{ marginTop:'auto', fontFamily:wf.mono, fontSize:11.5, color:accent }}>{cta} -&gt;</div>
  </a>
);

const SetupPage = () => (
  <DocPage
    activeId="setup"
    current="Start here"
    kicker="Start here"
    title="Choose the right MomentIQ setup."
    sub="MomentIQ has three paths: use the browser, build with the API, or ask an AI agent to build/run the workflow. Start with the path that matches what you are trying to do."
  >
    <H2 id="choose">Pick your path</H2>
    <P>If someone lands on the site and does not know what to do, this is the routing page. It explains what Moment Lab is for, what API keys are for, and what an AI agent needs when the user wants Claude, ChatGPT, Cursor, Replit, or Lovable to help.</P>
    <div style={{ display:'grid', gridTemplateColumns:'repeat(auto-fit, minmax(220px, 1fr))', gap:14, margin:'18px 0 28px' }}>
      <PathCard
        kicker="No-code"
        title="I want to use it myself."
        href="index.html"
        cta="Open Moment Lab"
        desc="Upload a video or use the demo, choose a tool, preview the result, and download clips or timestamp tables. No app integration required."
        steps={[
          'Use the demo video or upload your own media.',
          'Pick one tool or a workflow preset.',
          'Preview and download the result.',
        ]}
      />
      <PathCard
        kicker="Developer"
        title="I am building an app."
        href="docs-quickstart.html"
        cta="Read the quickstart"
        desc="Create an account, put the API key in your server environment, and call the worker-backed API or SDK from backend code."
        steps={[
          'Create an account and API key.',
          'Use signed uploads for local files.',
          'Create jobs and poll results.',
        ]}
        accent="oklch(0.66 0.13 155)"
      />
      <PathCard
        kicker="AI agent"
        title="I want Claude or ChatGPT to help."
        href="docs-ai-agents.html"
        cta="Open agent setup"
        desc="Give the agent a scoped key, a spending cap, copy-ready prompts, and the remote MCP URL so it can guide itself or build for you."
        steps={[
          'Create a scoped key and hard cap.',
          'Use the remote MCP or SDK docs.',
          'Paste a clear workflow prompt.',
        ]}
        accent="oklch(0.70 0.16 52)"
      />
    </div>
    <H2 id="connectors">Direct connector setup</H2>
    <P>If the user already knows which agent they want to use, send them straight to that connector page. These pages explain what to click, what URL to paste, where the key belongs, and what first prompt proves the connector is working without spending credits.</P>
    <ApiTable cols={['Agent','Setup page','When to use']} rows={[
      ['ChatGPT', 'docs-chatgpt.html', 'Use when ChatGPT supports custom connectors or remote MCP in the user workspace.'],
      ['Claude', 'docs-claude.html', 'Use when Claude supports remote MCP connectors in the user plan or client.'],
      ['Other agents', 'docs-ai-agents.html', 'Use the generic MCP/API fallback rules for Cursor, Replit, Lovable, or custom agents.'],
    ]} />

    <H2 id="agent-confusion">If the user says "make Claude use this"</H2>
    <P>Do not send them straight to raw API docs. Send them to AI agent setup and give them a copy-ready prompt. The agent should understand that MomentIQ is a tool/API it can connect to from a backend, not a website it must manually click around.</P>
    <ApiTable cols={['Question','If yes','If no']} rows={[
      ['Can the agent use remote MCP tools?', 'Connect https://api.momentiq.dev/mcp with a scoped MomentIQ API key.', 'Ask the agent to use the REST API or SDK from backend code.'],
      ['Can the agent write backend code or server functions?', 'Store MOMENTIQ_API_KEY server-side and call uploads/jobs from the backend.', 'Use Moment Lab manually on the homepage.'],
      ['Does the user already have an API key and spend cap?', 'Run diagnostics, estimate cost, then create jobs one step at a time.', 'Send them to dashboard signup, API keys, and settings first.'],
    ]} />
    <Code lang="Text" filename="what-to-tell-an-agent.txt" lines={[
      `Use MomentIQ to find useful moments in my media.`,
      `Before processing anything, check whether you have remote MCP/tool access to MomentIQ.`,
      `If you do not have MCP access, tell me exactly how to connect the MomentIQ remote MCP server or use the REST API from backend code.`,
      `If you can use remote MCP, connect to https://api.momentiq.dev/mcp.`,
      `Use MOMENTIQ_API_KEY from server-side environment variables only.`,
      `Never expose the key in browser code.`,
      `Set a hard spend cap before running real jobs.`,
      `Run the beta smoke test from https://momentiq.dev/docs-ai-agents.html#beta-test before trusting the workflow.`,
      `Build the workflow I ask for, show progress and cost, then preview/download the output.`,
    ]} />

    <H2 id="decision-table">Decision table</H2>
    <ApiTable cols={['Situation','Send them to','Why']} rows={[
      ['They just want to upload a video and get a clip.', 'Moment Lab', 'Fastest no-code path with visual output.'],
      ['They are building a website, app, or automation.', 'Quickstart + SDK', 'Server-side API key, uploads, jobs, polling, and result URLs.'],
      ['They want Claude/ChatGPT/Cursor/Replit/Lovable to build it.', 'AI agent setup', 'Explains remote MCP, scoped keys, spend caps, and copy-ready prompts.'],
      ['They are browsing with an agent/crawler.', 'llms.txt + ai-agent-setup.json', 'Plain text and structured setup for tool-aware agents.'],
    ]} />

    <H2 id="canonical-links">Canonical setup links</H2>
    <ApiTable cols={['Resource','URL','Use']} rows={[
      ['Human setup hub', 'https://momentiq.dev/docs-setup.html', 'First stop when the user is unsure what to do.'],
      ['Markdown setup', 'https://momentiq.dev/docs/setup.md', 'Copyable setup guide for AI builders and coding agents.'],
      ['Setup roadmap', 'https://momentiq.dev/docs/setup-simplicity-roadmap.md', 'Plan for simplifying Moment Lab, API/SDK, MCP, dashboard, and billing.'],
      ['Agent examples', 'https://momentiq.dev/docs/agent-examples.md', 'Copy-paste prompts, SDK examples, and raw upload/job/polling flows.'],
      ['OpenAPI starter spec', 'https://momentiq.dev/openapi.json', 'Machine-readable upload, job, polling, and MCP surface.'],
      ['MCP config', 'https://momentiq.dev/mcp.json', 'Copyable remote MCP server config using MIQ_CONNECTOR_TOKEN.'],
      ['Moment Lab', 'https://momentiq.dev/', 'No-code testing and upload UI.'],
      ['AI agent setup', 'https://momentiq.dev/docs-ai-agents.html', 'Prompts, MCP, scoped-key rules, and agent workflows.'],
      ['ChatGPT connector', 'https://momentiq.dev/docs-chatgpt.html', 'ChatGPT-specific remote MCP setup and safe first test.'],
      ['Claude connector', 'https://momentiq.dev/docs-claude.html', 'Claude-specific remote MCP setup and safe first test.'],
      ['AI agent smoke test', 'https://momentiq.dev/docs-ai-agents.html#beta-test', 'Checklist for proving key, cap, MCP, upload, workflow, usage, and revocation.'],
      ['Agent JSON', 'https://momentiq.dev/ai-agent-setup.json', 'Structured setup for AI agents.'],
      ['llms.txt', 'https://momentiq.dev/llms.txt', 'Plain-text instructions for browsing agents.'],
      ['SDK quickstart', 'https://momentiq.dev/docs/sdk-quickstart.md', 'Node SDK usage for app builders.'],
    ]} />
  </DocPage>
);

const AiAgentsPage = () => (
  <DocPage
    activeId="ai-agents"
    current="AI agents"
    kicker="Getting started"
    title="AI agent setup"
    sub="Use MomentIQ from Claude, ChatGPT, Cursor, Replit, Lovable, or any coding agent without handing it an unlimited key."
  >
    <H2 id="who">Who this is for</H2>
    <P>This page is for users who do not want to manually integrate every endpoint, but do want an AI agent to build or run a media workflow for them. Moment Lab is for no-code testing. API keys are for developers. This page is the middle path: give an agent a clear task, a scoped key, and a spending cap.</P>
    <ApiTable cols={['Path','Best for','Start here']} rows={[
      ['Moment Lab', 'People who want to upload or test media directly.', 'Homepage'],
      ['API docs', 'Developers building a product or backend integration.', 'Docs'],
      ['Remote MCP', 'AI agents that can call tools instead of clicking around a website.', 'This page'],
    ]} />
    <div style={{ display:'flex', gap:8, margin:'8px 0 24px', flexWrap:'wrap' }}>
      <a href="docs-chatgpt.html" style={{ textDecoration:'none' }}><Btn primary size={14}>ChatGPT connector setup</Btn></a>
      <a href="docs-claude.html" style={{ textDecoration:'none' }}><Btn size={14}>Claude connector setup</Btn></a>
      <a href="dashboard-settings.html" style={{ textDecoration:'none' }}><Btn size={14}>Set spend cap</Btn></a>
    </div>

    <H2 id="public-connector-status">Public connector status</H2>
    <P>MomentIQ has a working private/beta remote MCP server today. Users connect it with a revocable connector token from the dashboard. Public ChatGPT and Claude marketplace-style connectors are the next step: OAuth discovery and authorization-code endpoints exist, but they only work after provider-approved client IDs and redirect URIs are configured by the owner.</P>
    <ApiTable cols={['Layer','Status','Where']} rows={[
      ['Private remote MCP', 'Live now', 'https://api.momentiq.dev/mcp'],
      ['Connector-token auth', 'Live now', 'Dashboard -> API keys -> Connectors'],
      ['MCP manifest/status', 'Live now', 'https://api.momentiq.dev/mcp/manifest and /mcp/status'],
      ['Public OAuth connector', 'Client config required', 'OAuth endpoints exist. Requires OpenAI/Anthropic client IDs, redirect URIs, submission, and approval.'],
    ]} />
    <div style={{ display:'flex', gap:8, margin:'8px 0 24px', flexWrap:'wrap' }}>
      <a href="https://api.momentiq.dev/mcp/status" style={{ textDecoration:'none' }}><Btn size={14}>MCP status</Btn></a>
      <a href="https://api.momentiq.dev/mcp/manifest" style={{ textDecoration:'none' }}><Btn size={14}>MCP manifest</Btn></a>
      <a href="docs/mcp-public-connector-plan.md" style={{ textDecoration:'none' }}><Btn size={14}>Public connector plan</Btn></a>
      <a href="docs/mcp-owner-action-list.md" style={{ textDecoration:'none' }}><Btn size={14}>Owner action list</Btn></a>
    </div>

    <H2 id="what-mcp-does">What remote MCP actually does</H2>
    <P>Remote MCP gives an AI agent structured MomentIQ tools. It does not mean the agent magically edits videos by clicking the website. It means the agent can ask MomentIQ for endpoint docs, estimate cost, create uploads, create jobs, poll results, continue workflow chains, and revoke keys through a controlled tool connection.</P>
    <ApiTable cols={['User asks','Agent should say','Next step']} rows={[
      ['"Use MomentIQ on this video."', 'I need MomentIQ tool access first, or I need to build a backend/API integration.', 'Check remote MCP support.'],
      ['"Can you just click the website?"', 'Moment Lab is for humans. For agents, remote MCP or backend API is safer and more reliable.', 'Use MCP if available; otherwise use API/SDK.'],
      ['"I do not know what to paste into Claude."', 'Paste the setup prompt from this page and add MOMENTIQ_API_KEY as a secret, not in chat.', 'Copy the prompt below.'],
    ]} />
    <ApiTable cols={['Agent needs to','Use this MCP tool','Result']} rows={[
      ['Understand MomentIQ before coding.', 'momentiq.get_agent_guide', 'A short product guide, docs links, and safe workflow rules.'],
      ['Turn a vague request into a build plan.', 'momentiq.plan_integration', 'Recommended endpoints, backend shape, UI notes, and a copy-ready prompt.'],
      ['Start a multi-step media workflow.', 'momentiq.create_workflow_job', 'A chain plan and optional first queued job.'],
      ['Continue after one job finishes.', 'momentiq.continue_workflow_job', 'The next safe timestamp-aware step and optional queued job.'],
      ['Read results without guessing JSON shape.', 'momentiq.get_job_result', 'Output URLs, timestamp segments, frames, counts, costs, errors, and next actions.'],
      ['Recover recent run context.', 'momentiq.list_jobs', 'Recent account-scoped jobs, status, costs, timing, and output URLs.'],
      ['Prevent runaway spending.', 'momentiq.get_account_limits + momentiq.set_spend_cap', 'Current credits, usage, caps, and enforced limits.'],
    ]} />

    <H2 id="setup">1. Create a scoped connector token</H2>
    <P>Sign up, create a connector token, and set a monthly hard cap before giving tool access to an agent. Connector tokens are revocable and can be scoped to all endpoints or one endpoint group. Use normal API keys for backend/API integrations, not for public connector setup.</P>
    <div style={{ display:'flex', gap:8, margin:'8px 0 24px', flexWrap:'wrap' }}>
      <a href="dashboard.html?auth=signup" style={{ textDecoration:'none' }}><Btn primary size={14}>Start free</Btn></a>
      <a href="dashboard-api-keys.html#connectors" style={{ textDecoration:'none' }}><Btn size={14}>Manage connector tokens</Btn></a>
      <a href="dashboard-settings.html" style={{ textDecoration:'none' }}><Btn size={14}>Set spend cap</Btn></a>
    </div>

    <H2 id="secret">2. Put the token in the agent environment</H2>
    <P>Do not paste a live key or connector token into public prompts, client-side JavaScript, screenshots, or shared documents. Put connector tokens in the private connector auth field. Put API keys only in server-side environments for apps the agent is building.</P>
    <CodeTabs filename="agent-env" tabs={[
      { lang:'Node', lines:[
        `MIQ_CONNECTOR_TOKEN=miq_conn_...`,
        `MOMENTIQ_API_KEY=miq_live_... # backend apps only`,
        `MOMENTIQ_API_BASE_URL=https://api.momentiq.dev`,
      ]},
      { lang:'Python', lines:[
        `export MIQ_CONNECTOR_TOKEN=miq_conn_...`,
        `export MOMENTIQ_API_KEY=miq_live_... # backend apps only`,
        `export MOMENTIQ_API_BASE_URL=https://api.momentiq.dev`,
      ]},
    ]} />

    <H2 id="mcp">3. Connect the remote MCP server</H2>
    <P>For agents that support remote MCP tools, add MomentIQ as an HTTP MCP server. The recommended Bearer token is a MomentIQ connector token, so billing, credits, spend caps, scopes, and revocation all work without exposing normal API keys.</P>
    <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:12, margin:'0 0 16px' }}>
      <a href="ai-agent-setup.json" style={{ textDecoration:'none', color:'inherit', background:wf.card, border:`1px solid ${wf.line}`, borderRadius:10, padding:14 }}>
        <div style={{ fontFamily:wf.mono, fontSize:11, color:'var(--accent)', textTransform:'uppercase', letterSpacing:1 }}>agent-readable</div>
        <div style={{ fontFamily:wf.sans, fontSize:15, fontWeight:600, marginTop:5 }}>ai-agent-setup.json</div>
        <div style={{ fontFamily:wf.sans, fontSize:12.5, color:wf.ink3, marginTop:5 }}>Structured setup, tools, workflows, billing rules, and troubleshooting.</div>
      </a>
      <a href="llms.txt" style={{ textDecoration:'none', color:'inherit', background:wf.card, border:`1px solid ${wf.line}`, borderRadius:10, padding:14 }}>
        <div style={{ fontFamily:wf.mono, fontSize:11, color:'var(--accent)', textTransform:'uppercase', letterSpacing:1 }}>browser-friendly</div>
        <div style={{ fontFamily:wf.sans, fontSize:15, fontWeight:600, marginTop:5 }}>llms.txt</div>
        <div style={{ fontFamily:wf.sans, fontSize:12.5, color:wf.ink3, marginTop:5 }}>Plain-text instructions for web-browsing agents and coding assistants.</div>
      </a>
    </div>
    <CodeTabs filename="momentiq-mcp-config.json" tabs={[
      { lang:'JSON', lines:[
        `{`,
        `  "mcpServers": {`,
        `    "momentiq": {`,
        `      "url": "https://api.momentiq.dev/mcp",`,
        `      "headers": {`,
        `        "Authorization": "Bearer \${MIQ_CONNECTOR_TOKEN}"`,
        `      }`,
        `    }`,
        `  }`,
        `}`,
      ]},
      { lang:'Tools', lines:[
        `momentiq.get_agent_guide`,
        `momentiq.list_endpoints`,
        `momentiq.plan_integration`,
        `momentiq.get_code_example`,
        `momentiq.check_job_readiness`,
        `momentiq.create_workflow_job`,
        `momentiq.continue_workflow_job`,
        `momentiq.create_upload`,
        `momentiq.create_job`,
        `momentiq.get_job`,
        `momentiq.get_job_result`,
        `momentiq.list_jobs`,
        `momentiq.get_account_limits`,
        `momentiq.set_spend_cap`,
        `momentiq.get_usage_summary`,
        `momentiq.list_api_keys`,
        `momentiq.create_api_key`,
        `momentiq.revoke_api_key`,
      ]},
    ]} />

    <H2 id="tool-snippets">4. Copy the setup for your AI tool</H2>
    <P>Different agents expose MCP and environment variables in different places. Use the matching snippet below, then paste the prompt in the next section. If a tool does not support remote MCP yet, use the backend API/SDK prompt and store the key as a server-side secret.</P>
    <CodeTabs filename="agent-tool-setup" tabs={[
      { lang:'Claude', lines:[
        `1. Create a scoped MomentIQ API key in the dashboard.`,
        `2. Set a hard spend cap before giving the key to Claude.`,
        `3. Add MomentIQ as a remote MCP server if your Claude plan/client supports remote MCP:`,
        ``,
        `{`,
        `  "mcpServers": {`,
        `    "momentiq": {`,
        `      "type": "http",`,
        `      "url": "https://api.momentiq.dev/mcp",`,
        `      "headers": { "Authorization": "Bearer \${MOMENTIQ_API_KEY}" }`,
        `    }`,
        `  }`,
        `}`,
        ``,
        `4. Tell Claude: first call momentiq.get_agent_guide, then momentiq.run_agent_diagnostics.`,
      ]},
      { lang:'Cursor', lines:[
        `Add this MCP server in Cursor's MCP settings if remote HTTP MCP is available:`,
        ``,
        `{`,
        `  "mcpServers": {`,
        `    "momentiq": {`,
        `      "url": "https://api.momentiq.dev/mcp",`,
        `      "headers": { "Authorization": "Bearer \${MOMENTIQ_API_KEY}" }`,
        `    }`,
        `  }`,
        `}`,
        ``,
        `Put MOMENTIQ_API_KEY in your project or hosting secrets, not in browser code.`,
        `Ask Cursor to call momentiq.plan_integration before editing your app.`,
      ]},
      { lang:'Replit', lines:[
        `1. Open Replit Secrets.`,
        `2. Add MOMENTIQ_API_KEY=miq_live_or_test_...`,
        `3. Add MOMENTIQ_API_BASE_URL=https://api.momentiq.dev`,
        `4. Paste the app-builder prompt below into Replit Agent.`,
        ``,
        `If Replit supports remote MCP in your workspace, connect https://api.momentiq.dev/mcp with Authorization: Bearer \${MIQ_CONNECTOR_TOKEN}.`,
        `If not, ask Replit Agent to use the Node SDK or raw /v1/uploads/presign and /v1/jobs API flow from the docs.`,
      ]},
      { lang:'Lovable', lines:[
        `1. Add MOMENTIQ_API_KEY as a server-side secret or backend environment variable.`,
        `2. Never put the key in client-side code, public Supabase edge config, or frontend env vars.`,
        `3. Ask Lovable to build a backend function that calls MomentIQ.`,
        `4. Give it the prompt below and tell it to show progress, costs, output previews, and download buttons.`,
        ``,
        `If Lovable supports remote MCP in your project, connect https://api.momentiq.dev/mcp and call momentiq.plan_integration before coding.`,
      ]},
      { lang:'ChatGPT', lines:[
        `If your ChatGPT workspace supports remote MCP/connectors:`,
        `- MCP URL: https://api.momentiq.dev/mcp`,
        `- Auth header: Authorization: Bearer \${MOMENTIQ_API_KEY}`,
        ``,
        `If it cannot connect remote MCP directly, use ChatGPT to generate backend code with the MomentIQ SDK/API examples.`,
        `Keep MOMENTIQ_API_KEY in your hosting provider's server-side environment variables.`,
      ]},
    ]} />

    <H2 id="prompt">5. Paste this prompt into your AI builder</H2>
    <P>Replace the bracketed parts with your app details. Tell the agent what MomentIQ does, what endpoint chain to use, and where the key lives.</P>
    <Code lang="Text" filename="agent-prompt.txt" lines={[
      `Build a media workflow using MomentIQ.`,
      ``,
      `Before using MomentIQ, check whether you have remote MCP/tool access.`,
      `If you do not have MCP access, tell me exactly where to connect the MomentIQ remote MCP server, or fall back to server-side REST API/SDK code.`,
      ``,
      `MomentIQ is an API for finding useful moments in video and audio.`,
      `Use the API key from the server-side environment variable MOMENTIQ_API_KEY.`,
      `Never expose the API key in browser code.`,
      `If MCP is available, use the remote MomentIQ MCP server at https://api.momentiq.dev/mcp.`,
      `First call momentiq.get_agent_guide, then momentiq.run_agent_diagnostics after authentication.`,
      ``,
      `Goal: [describe what I want, such as "upload a podcast and return 3 funny clips"].`,
      `Recommended chain: [example: audio/detect-laughter -> audio/detect-silence -> video/clip-near].`,
      `For multi-step workflows, call momentiq.create_workflow_job, poll the job, then call momentiq.continue_workflow_job after each completed step.`,
      `After a job completes, call momentiq.get_job_result so output URLs, timestamp segments, frames, costs, and errors are normalized for the UI.`,
      `If you lose the job_id, call momentiq.list_jobs before rerunning paid processing.`,
      `Use async jobs for long media: POST /v1/jobs, then poll GET /v1/jobs/{job_id}.`,
      `Show progress, estimated cost, output preview, and a download button.`,
      ``,
      `Docs: https://momentiq.dev/docs.html`,
      `Agent setup: https://momentiq.dev/docs-ai-agents.html`,
    ]} />

    <H2 id="recipes">6. Copy-ready agent prompts</H2>
    <P>If the user does not know what to ask Claude, Cursor, Replit, or Lovable, start with one of these. Each prompt tells the agent what to build, which endpoints to chain, and what safety rules to follow.</P>
    <CodeTabs filename="agent-recipes" tabs={[
      { lang:'Funny clips', lines:[
        `Build me a podcast clip finder with MomentIQ.`,
        ``,
        `User flow: upload a video or paste a media URL, then return the 3 best funny clips with playable previews and download buttons.`,
        `Use MomentIQ from the backend only. Read MOMENTIQ_API_KEY from server-side environment variables.`,
        `If remote MCP is supported, connect to https://api.momentiq.dev/mcp with Authorization: Bearer \${MIQ_CONNECTOR_TOKEN}.`,
        `Before running paid jobs, call momentiq.run_agent_diagnostics and momentiq.check_job_readiness.`,
        ``,
        `Use this endpoint chain:`,
        `1. audio/detect-laughter to find laugh candidates.`,
        `2. audio/detect-silence to find natural endings after each laugh.`,
        `3. video/clip-near or video/clip-window to render clips.`,
        `If using MCP, start with momentiq.create_workflow_job and then use momentiq.continue_workflow_job after each completed job.`,
        ``,
        `Show upload progress, estimated cost, queued/running/completed job states, clip previews, JSON details behind a toggle, and errors with request_id/job_id.`,
        `Never expose the MomentIQ API key in browser code.`,
      ]},
      { lang:'No-code page', lines:[
        `Build a simple no-code MomentIQ page for content creators.`,
        ``,
        `The page should let a user choose a demo video or upload their own media, pick a MomentIQ tool, run it, preview the output, and download clips or CSV/JSON results.`,
        `Use MomentIQ jobs from the backend. Read MOMENTIQ_API_KEY from server-side environment variables.`,
        `Use signed upload URLs for local files, then pass the returned media_url into jobs.`,
        ``,
        `Start with these live-safe endpoints: video/clip-window, video/clip-near, audio/detect-silence, and audio/detect-energy.`,
        `If using MCP, call momentiq.plan_integration first, then momentiq.get_code_example for copy-paste upload/job/polling code.`,
        `Hide raw JSON behind a details toggle. Use friendly labels for timestamps and costs.`,
        `Never expose the MomentIQ API key in browser code.`,
      ]},
      { lang:'App integration', lines:[
        `Add MomentIQ media intelligence to my app.`,
        ``,
        `Create a backend module named momentiqService that can upload media, create jobs, poll jobs, and return clean results to the frontend.`,
        `Read MOMENTIQ_API_KEY and MOMENTIQ_API_BASE_URL from server-side environment variables.`,
        `Default MOMENTIQ_API_BASE_URL to https://api.momentiq.dev.`,
        `If remote MCP is available, call momentiq.plan_integration first and momentiq.get_code_example before writing custom API plumbing.`,
        ``,
        `Implement helpers for:`,
        `- createUpload(fileName, contentType, fileSize)`,
        `- createJob(endpoint, media_url, settings)`,
        `- pollJob(job_id)`,
        `- clipWindow(media_url, start, end)`,
        `- detectEnergy(media_url, settings)`,
        ``,
        `Add retry/backoff for polling, show request_id/job_id on errors, and never expose the MomentIQ API key to the browser.`,
      ]},
    ]} />

    <H2 id="example">7. Minimal server-side call</H2>
    <P>Agents should call MomentIQ from a backend route, job, or server action. The browser should call your app, not MomentIQ directly with a secret key.</P>
    <CodeTabs filename="server-side-call" tabs={[
      { lang:'JavaScript', lines:[
        `const res = await fetch("https://api.momentiq.dev/v1/jobs", {`,
        `  method: "POST",`,
        `  headers: {`,
        `    "Authorization": "Bearer " + process.env.MOMENTIQ_API_KEY,`,
        `    "Content-Type": "application/json",`,
        `  },`,
        `  body: JSON.stringify({`,
        `    endpoint: "audio/detect-energy",`,
        `    media_url: "https://your-file-url/video.mp4",`,
        `    settings: {},`,
        `  }),`,
        `});`,
        `const job = await res.json();`,
      ]},
      { lang:'Python', lines:[
        `import os, requests`,
        `job = requests.post(`,
        `  "https://api.momentiq.dev/v1/jobs",`,
        `  headers={"Authorization": f"Bearer {os.environ['MOMENTIQ_API_KEY']}"},`,
        `  json={"endpoint": "audio/detect-energy", "media_url": "https://your-file-url/video.mp4", "settings": {}},`,
        `).json()`,
      ]},
    ]} />

    <H2 id="agent-checklist">8. Agent handoff checklist</H2>
    <P>Before handing MomentIQ to an agent, the user should have these five things. If any are missing, the agent should pause and ask for setup instead of guessing.</P>
    <ApiTable cols={['Needed','What to give the agent','Why']} rows={[
      ['Account', 'A MomentIQ dashboard account with $5 starter credits or active billing.', 'The agent cannot run real processing without credits or billing.'],
      ['API key', 'A scoped key stored as MOMENTIQ_API_KEY in the server environment.', 'Keeps secrets out of browser code and prompts.'],
      ['Spend cap', 'A hard monthly cap and optional usage alerts.', 'Lets agents work without surprise bills.'],
      ['Media input', 'A public media_url or a local file the agent can upload with create_upload.', 'Jobs need accessible media.'],
      ['Goal', 'A plain request like "find three high-energy clips from this podcast".', 'The agent can call plan_integration and choose the right workflow.'],
    ]} />

    <H2 id="beta-test">9. Beta agent test checklist</H2>
    <P>Use this checklist before trusting an agent with real customer media or live billing. The goal is to prove the key, spend cap, upload, job flow, output, and revocation all work from the same environment the agent will use.</P>
    <ApiTable cols={['Step','What to test','Pass condition']} rows={[
      ['1. Key', 'Create a scoped test key and store it as MOMENTIQ_API_KEY.', 'The agent can call momentiq.run_agent_diagnostics without exposing the key.'],
      ['2. Cap', 'Set a low hard spend cap and usage alert.', 'momentiq.get_account_limits shows the cap and remaining credits.'],
      ['3. MCP', 'Connect https://api.momentiq.dev/mcp with Authorization: Bearer ${MIQ_CONNECTOR_TOKEN}.', 'The agent can call momentiq.get_agent_guide and momentiq.list_workflows.'],
      ['4. Upload', 'Upload a small local video or use a public media_url.', 'For files, create_upload returns upload_url and media_url. PUT bytes to upload_url, then pass media_url into readiness checks and jobs.'],
      ['5. Workflow', 'Run energy_to_clip with create_workflow_job, get_job, and continue_workflow_job.', 'Only one step is queued at a time and the final clip has a playable output URL.'],
      ['6. Usage', 'Check dashboard usage after the job completes.', 'Usage shows the endpoint, API key, job_id, media seconds, and cost.'],
      ['7. Revoke', 'Revoke the test key.', 'Future calls with that key fail with invalid_api_key.'],
    ]} />
    <Code lang="Text" filename="agent-beta-smoke-test.txt" lines={[
      `Run a MomentIQ beta smoke test.`,
      `Use MOMENTIQ_API_KEY from server-side environment variables only.`,
      `First call momentiq.run_agent_diagnostics and momentiq.get_account_limits.`,
      `Then upload or use a public test media_url. For a local file, call momentiq.create_upload, PUT bytes to upload_url with upload_headers, then pass media_url into readiness checks and jobs.`,
      `Plan the energy_to_clip workflow with momentiq.create_workflow_job.`,
      `Queue only the first step, poll with momentiq.get_job, then call momentiq.continue_workflow_job after each completed job.`,
      `Show me the final output URL, estimated vs final cost, usage summary, and any errors with request_id/job_id.`,
      `After the test, remind me to revoke the test key if I do not need it anymore.`,
    ]} />

    <H2 id="patterns">Recommended agent patterns</H2>
    <ApiTable cols={['User goal','Endpoint chain','Output']} rows={[
      ['Find funny clips', 'audio/detect-laughter -> audio/detect-silence -> video/clip-near', 'Clip URLs with timestamps and JSON proof.'],
      ['Remove dead space', 'audio/detect-silence -> timeline/suggest-ranges -> video/clip-window', 'Suggested keep ranges and rendered clips.'],
      ['Find searchable moments', 'audio/semantic-chunks -> video/text-frames -> timeline/merge', 'Timestamped timeline objects for search/RAG.'],
      ['Pick thumbnails', 'video/best-frames -> video/thumbnail-score', 'Ranked image candidates and scores.'],
    ]} />

    <H2 id="safety">Safety checklist</H2>
    <ApiTable cols={['Check','Why it matters','Where']} rows={[
      ['Use server-side env vars', 'Prevents key exposure in browser code or prompts.', 'Your app hosting settings'],
      ['Scope the key', 'Limits what an agent can call if it makes a mistake.', 'Dashboard -> API keys'],
      ['Set a hard cap', 'Stops unexpected usage before it becomes a bill.', 'Dashboard -> Settings'],
      ['Review usage', 'Shows which endpoint, key, and job created each charge.', 'Dashboard -> Usage'],
      ['Revoke leaked keys', 'Stops future calls immediately.', 'Dashboard -> API keys'],
    ]} />
  </DocPage>
);

// ──────────────────────────────────────────────────────────── Authentication ──

const ChatGPTConnectorPage = () => (
  <DocPage
    activeId="chatgpt"
    current="ChatGPT connector"
    kicker="AI agent setup"
    title="Connect MomentIQ.dev to ChatGPT."
    sub="Use the remote MCP connector when ChatGPT can call tools. Keep keys scoped, set a hard cap, and start with diagnostics before creating media jobs."
  >
    <H2 id="what-it-is">What this connector does</H2>
    <P>The MomentIQ ChatGPT connector gives ChatGPT structured tools for media workflows. ChatGPT can discover endpoints, estimate cost, create uploads, queue jobs, poll results, regenerate output URLs, and summarize results without scraping the website.</P>
    <ApiTable cols={['Thing','Value','Why']} rows={[
      ['Connector URL', 'https://api.momentiq.dev/mcp', 'Public remote MCP endpoint for ChatGPT and other MCP-capable agents.'],
      ['Fallback URL', 'https://momentiq-production-7fdd.up.railway.app/mcp', 'Use only if the API subdomain is not resolving.'],
      ['Auth', 'Authorization: Bearer <MIQ_CONNECTOR_TOKEN>', 'Uses a revocable connector token tied to the same account, credits, billing, and spend cap rules as the API.'],
      ['Scopes', 'all, video/*, audio/*, timeline/*', 'Use all for general ChatGPT access. Use a group scope when the agent should only run that endpoint family.'],
      ['First safe tools', 'get_agent_guide, list_endpoints, estimate_cost', 'These help ChatGPT learn the product without spending credits.'],
      ['First authenticated tool', 'run_agent_diagnostics', 'Confirms account, storage, worker, billing, credits, and cap readiness.'],
    ]} />

    <H2 id="setup">Setup in ChatGPT</H2>
    <P>If your ChatGPT workspace supports custom connectors or remote MCP, add MomentIQ as a connector. The recommended auth value is a MomentIQ connector token created from the dashboard, not a normal API key. If ChatGPT cannot connect remote MCP in your workspace, ask it to build backend code with the SDK or REST API instead.</P>
    <Code lang="Text" filename="chatgpt-setup.txt" lines={[
      `1. Sign up or log in to MomentIQ.dev.`,
      `2. Create a ChatGPT connector token in Dashboard -> Connectors. Use scope=all for general access, or a group scope for limited access.`,
      `3. Set a hard monthly spend cap in Dashboard -> Settings. The connector cannot spend past that cap.`,
      `4. In ChatGPT connector settings, create a new connector named MomentIQ.dev.`,
      `5. Set the connector URL to https://api.momentiq.dev/mcp.`,
      `6. Configure Authorization: Bearer <MIQ_CONNECTOR_TOKEN>.`,
      `7. Start a new chat, select the MomentIQ connector, and run the safe test prompt below.`,
    ]} />

    <H2 id="config">Copyable MCP config</H2>
    <Code lang="JSON" filename="momentiq-chatgpt-mcp.json" lines={[
      `{`,
      `  "name": "MomentIQ.dev",`,
      `  "url": "https://api.momentiq.dev/mcp",`,
      `  "headers": {`,
      `    "Authorization": "Bearer \${MIQ_CONNECTOR_TOKEN}"`,
      `  }`,
      `}`,
    ]} />

    <H2 id="first-test">First ChatGPT prompt</H2>
    <P>This test should not create paid processing jobs. It proves ChatGPT can see the connector, read MomentIQ guidance, and inspect account readiness.</P>
    <Code lang="Text" filename="chatgpt-first-test.txt" lines={[
      `Use the MomentIQ.dev connector.`,
      `Do not create uploads or processing jobs yet.`,
      `First call momentiq.get_agent_guide.`,
      `Then call momentiq.list_endpoints and momentiq.list_workflows with live_safe_only=true.`,
      `If authenticated tools are available, call momentiq.run_agent_diagnostics and momentiq.get_account_limits.`,
      `Tell me whether my API key, free credits, billing status, worker health, and hard spend cap are ready for a small beta job.`,
    ]} />

    <H2 id="paid-test">First paid-safe media test</H2>
    <P>After diagnostics pass, use a small public media URL or a tiny upload. Queue one step at a time and check readiness before each job.</P>
    <Code lang="Text" filename="chatgpt-paid-safe-test.txt" lines={[
      `Run one small MomentIQ beta job.`,
      `Use live-safe endpoints only.`,
      `Before spending credits, call momentiq.check_job_readiness for audio/detect-energy.`,
      `If readiness passes, create one job with momentiq.create_job.`,
      `Poll with momentiq.get_job until completed or failed.`,
      `Then call momentiq.get_job_result and show the output summary, cost, job_id, and request_id.`,
      `Do not queue any second job without asking me.`,
    ]} />

    <H2 id="fallback">If ChatGPT cannot connect MCP</H2>
    <ApiTable cols={['Limitation','Fallback','Instruction']} rows={[
      ['No custom connector setting', 'Use backend API or SDK', 'Ask ChatGPT to write server-side code using MOMENTIQ_API_KEY from environment variables.'],
      ['Cannot attach auth header', 'Use public planning tools only', 'Use docs, OpenAPI, and SDK examples; create real jobs from your backend.'],
      ['No file upload to connector', 'Use MomentIQ upload presign from backend', 'Backend calls /v1/uploads/presign, uploads bytes, then creates jobs with media_url.'],
    ]} />
  </DocPage>
);

const ClaudeConnectorPage = () => (
  <DocPage
    activeId="claude"
    current="Claude connector"
    kicker="AI agent setup"
    title="Connect MomentIQ.dev to Claude."
    sub="Use the remote MCP connector when Claude can call tools. If not, ask Claude to build a backend API integration with the same safe key and spend-cap rules."
  >
    <H2 id="what-it-is">What this connector does</H2>
    <P>The MomentIQ Claude connector is the same remote MCP server used by other agents. Claude can ask MomentIQ for endpoint schemas, plan workflows, create uploads, queue jobs, poll results, and continue timestamp-aware workflow chains.</P>
    <ApiTable cols={['Thing','Value','Why']} rows={[
      ['MCP URL', 'https://api.momentiq.dev/mcp', 'Remote MCP endpoint for Claude clients that support HTTP MCP.'],
      ['Fallback URL', 'https://momentiq-production-7fdd.up.railway.app/mcp', 'Use only if the API subdomain is not resolving.'],
      ['Auth', 'Authorization: Bearer <MIQ_CONNECTOR_TOKEN>', 'Uses a revocable connector token tied to normal MomentIQ account billing, credits, and spend caps.'],
      ['Scopes', 'all, video/*, audio/*, timeline/*', 'Use all when Claude should manage workflows and account guardrails. Use a group scope for narrow media tasks.'],
      ['Best first call', 'momentiq.get_agent_guide', 'Gives Claude the safe product rules before it builds or runs anything.'],
      ['Best guardrail call', 'momentiq.get_account_limits', 'Shows free credits, spend cap, usage alerts, and billing state.'],
    ]} />

    <H2 id="setup">Setup in Claude</H2>
    <P>If your Claude plan or client supports remote MCP connectors, add MomentIQ as an HTTP MCP server. The recommended auth value is a MomentIQ connector token created from the dashboard, not a normal API key. If it only supports local MCP servers, use the REST API/SDK from backend code until remote connectors are available in that environment.</P>
    <Code lang="Text" filename="claude-setup.txt" lines={[
      `1. Sign up or log in to MomentIQ.dev.`,
      `2. Create a Claude connector token in Dashboard -> Connectors. Use scope=all for general access, or a group scope for limited access.`,
      `3. Set a hard monthly spend cap in Dashboard -> Settings. The connector cannot spend past that cap.`,
      `4. Add a remote MCP server named momentiq.`,
      `5. Set URL to https://api.momentiq.dev/mcp.`,
      `6. Set Authorization: Bearer <MIQ_CONNECTOR_TOKEN>.`,
      `7. Start with the Claude test prompt below before processing media.`,
    ]} />

    <H2 id="config">Copyable MCP config</H2>
    <Code lang="JSON" filename="momentiq-claude-mcp.json" lines={[
      `{`,
      `  "mcpServers": {`,
      `    "momentiq": {`,
      `      "type": "http",`,
      `      "url": "https://api.momentiq.dev/mcp",`,
      `      "headers": {`,
      `        "Authorization": "Bearer \${MIQ_CONNECTOR_TOKEN}"`,
      `      }`,
      `    }`,
      `  }`,
      `}`,
    ]} />

    <H2 id="first-test">First Claude prompt</H2>
    <P>Use this when a user says, "I want Claude to use MomentIQ," but does not know what to paste or what access Claude needs.</P>
    <Code lang="Text" filename="claude-first-test.txt" lines={[
      `Use the MomentIQ.dev MCP connector if you have it available.`,
      `Do not create uploads or processing jobs yet.`,
      `First call momentiq.get_agent_guide.`,
      `Then call momentiq.plan_integration for this goal: find useful clips in a podcast video.`,
      `If authenticated tools are available, call momentiq.run_agent_diagnostics and momentiq.get_account_limits.`,
      `Tell me whether MomentIQ is ready, what key/billing/cap issues remain, and what the first live-safe test should be.`,
    ]} />

    <H2 id="builder-prompt">Prompt for Claude to build an app</H2>
    <Code lang="Text" filename="claude-build-app.txt" lines={[
      `Build a small app that uses MomentIQ from the backend only.`,
      `Read MOMENTIQ_API_KEY from server-side environment variables.`,
      `Never expose the key in browser code.`,
      `If you have MomentIQ MCP access, call momentiq.plan_integration first and momentiq.get_code_example before writing code.`,
      `Start with live-safe endpoints: video/clip-window, video/clip-near, audio/detect-silence, and audio/detect-energy.`,
      `The UI should upload media, estimate cost, queue one job, poll status, preview the result, and show JSON behind a toggle.`,
      `Before creating jobs, check account limits and hard spend cap.`,
    ]} />

    <H2 id="fallback">If Claude cannot connect remote MCP</H2>
    <ApiTable cols={['Claude environment','Use this path','Why']} rows={[
      ['Claude supports remote MCP', 'Connect https://api.momentiq.dev/mcp', 'Best tool-native path with MomentIQ schemas and safety tools.'],
      ['Claude can write backend code but not connect MCP', 'REST API or SDK', 'Still safe if MOMENTIQ_API_KEY stays server-side.'],
      ['Claude can only chat or browse', 'Moment Lab manual flow', 'Human uploads and runs jobs; Claude can explain steps but should not claim tool access.'],
    ]} />
  </DocPage>
);

const AuthPage = () => (
  <DocPage
    activeId="auth"
    kicker="Getting started"
    title="Authentication"
    sub="One key works on every MomentIQ endpoint. Bearer auth. Test and live keys. Hard caps."
  >
    <H2 id="bearer">Bearer authentication</H2>
    <P>All requests use a Bearer token in the <code style={{ fontFamily:wf.mono, fontSize:13 }}>Authorization</code> header. Never put your key in URL params, query strings, or client-side code.</P>
    <Code lang="cURL" filename="auth" lines={[
      `Authorization: Bearer miq_live_8a3f9e2c4d6b1a05e7f9c8b3d4a2…`,
    ]} />

    <H2 id="prefixes">Key prefixes</H2>
    <ApiTable cols={['Prefix','Purpose','Behavior']} rows={[
      ['miq_live_*', 'Live key',        'Charges your real balance. Returned data is real.'],
      ['miq_test_*', 'Test key',        'Free. Returns realistic synthetic data. No charge.'],
      ['miq_pub_*',  'Public-side key', 'Read-only. Scoped to safe endpoints (Moment Lab replays).'],
    ]} />

    <H2 id="rotation">Rotation</H2>
    <P>Rotate from the <a href="dashboard-api-keys.html" style={{ color:'var(--accent)' }}>API keys</a> page. Generating a new key never invalidates existing keys — revoke explicitly. Keep the previous key live for an overlap window while you redeploy, then revoke.</P>
    <ApiTable cols={['Action','Result']} rows={[
      ['Create',  'New key issued. Existing keys unaffected.'],
      ['Revoke',  'Key invalidated immediately. Future calls return 401.'],
      ['Restrict','Scope a key to a subset of endpoints or environments.'],
    ]} />

    <H2 id="envs">Test vs live</H2>
    <P>Use a <code style={{ fontFamily:wf.mono, fontSize:13 }}>miq_test_*</code> key in CI and during local dev. Test keys never charge and return realistic synthetic data shaped exactly like live responses, so your code paths exercise the same parsing logic.</P>

    <H2 id="caps">Spending caps</H2>
    <P>Set a hard monthly cap from the <a href="dashboard-billing.html" style={{ color:'var(--accent)' }}>Billing</a> page. When you'd cross the cap, requests return <code style={{ fontFamily:wf.mono, fontSize:13 }}>insufficient_credits</code> instead of charging — see <a href="docs-errors.html#insufficient_credits" style={{ color:'var(--accent)' }}>Errors</a>.</P>

    <H2 id="logs">Usage logs</H2>
    <P>Every request — including failed ones — appears in <a href="dashboard-usage.html" style={{ color:'var(--accent)' }}>Usage</a> with timestamp, endpoint, status, and cost. Filter by API key to attribute usage to specific deployments.</P>

    <H2 id="security">Security</H2>
    <P>Treat keys like passwords. Inject from environment variables. If a key leaks, revoke immediately and create a new one. MomentIQ never includes the full key in any UI after creation — you'll see a one-shot reveal at create time only.</P>
  </DocPage>
);

// ──────────────────────────────────────────────────────────────────── Errors ──

const ERR_ENVELOPE = `{
  "error": {
    "code": "invalid_media_url",
    "message": "The provided media URL could not be accessed.",
    "request_id": "req_123",
    "docs_url": "https://momentiq.dev/docs/errors#invalid_media_url"
  }
}`;

const ERROR_CODES = [
  ['invalid_media_url',     400, 'media_url is missing, malformed, or unreachable.',                                                'Verify the URL returns 200 from a public network. Signed URLs must not be expired.'],
  ['unsupported_file_type', 400, 'The media format is not supported by this endpoint.',                                              'See the supported-formats matrix on the endpoint page. Convert to mp4/mp3/wav.'],
  ['media_too_large',       413, 'Media exceeds the inline-call size limit (~5 minutes / 500 MB).',                                  'Submit as an async job — see /docs/async-jobs.'],
  ['invalid_timestamp',     400, 'A timestamp parameter is outside the media duration or is malformed.',                              'Ensure t / start / end are within [0, media_seconds]. Numbers, not strings.'],
  ['connector_scope_denied',403, 'A connector token tried to use an endpoint, job, or account setting outside its scope.',             'Create a connector token with scope=all, or use video/*, audio/*, or timeline/* only with matching endpoints.'],
  ['insufficient_credits',  402, 'The call would exceed the account spending cap or available credits.',                              'Top up credits or raise the spending cap in /dashboard/billing.'],
  ['processing_timeout',    504, 'The job took longer than the inline-call timeout.',                                                 'Retry as an async job — long media should always go through /v1/jobs.'],
  ['rate_limited',          429, 'Per-second or per-minute rate limit exceeded.',                                                     'Back off and retry; respect the Retry-After header. Default: 60 req/s per key.'],
];

const ErrorsPage = () => (
  <DocPage
    activeId="errors"
    kicker="Reference"
    title="Errors"
    sub="One error envelope across every endpoint. Same shape on inline calls and async jobs."
  >
    <H2 id="envelope">Standard error envelope</H2>
    <P>Every failed request returns an HTTP status code in the 4xx/5xx range and a JSON body with this exact shape. Successful requests never include an <code style={{ fontFamily:wf.mono, fontSize:13 }}>error</code> field.</P>
    <Code lang="JSON" filename="error-envelope" lines={ERR_ENVELOPE.split('\n')} />
    <ApiTable cols={['Field','Type','Description']} rows={[
      ['error.code',       'string', 'Machine-readable error code. Always one of the values below.'],
      ['error.message',    'string', 'Human-readable explanation. Safe to surface to end users.'],
      ['error.request_id', 'string', 'Echo this in support requests — we can replay the call.'],
      ['error.docs_url',   'string', 'Deep link to the docs section for this code.'],
    ]} />

    <H2 id="codes">Error codes</H2>
    <div style={{ display:'flex', flexDirection:'column', gap:12 }}>
      {ERROR_CODES.map(([code, http, msg, fix]) => (
        <div key={code} id={code} style={{
          background: wf.card, border:`1px solid ${wf.line}`, borderRadius:10,
          padding:16, scrollMarginTop: 80,
        }}>
          <div style={{ display:'flex', alignItems:'center', gap:10, marginBottom:8 }}>
            <span style={{ fontFamily:wf.mono, fontSize:13.5, fontWeight:600, color:wf.ink }}>{code}</span>
            <span style={{
              fontFamily:wf.mono, fontSize:11, padding:'2px 7px', borderRadius:4,
              background:'color-mix(in oklch, oklch(0.62 0.16 25) 14%, transparent)',
              color:'oklch(0.55 0.16 25)',
            }}>HTTP {http}</span>
          </div>
          <div style={{ fontFamily:wf.sans, fontSize:14, color:wf.ink2, lineHeight:1.55, marginBottom:6 }}>{msg}</div>
          <div style={{ fontFamily:wf.sans, fontSize:13, color:wf.ink3, lineHeight:1.55 }}><b style={{ color:wf.ink2 }}>Fix:</b> {fix}</div>
        </div>
      ))}
    </div>

    <H2 id="retries">Retries</H2>
    <P>Retry on <code style={{ fontFamily:wf.mono, fontSize:13 }}>rate_limited</code> (429) and <code style={{ fontFamily:wf.mono, fontSize:13 }}>processing_timeout</code> (504). Do not retry on 4xx other than 429 — the request will fail again. Use exponential backoff starting at 1s, capped at 30s.</P>

    <H2 id="async-errors">Async-job errors</H2>
    <P>An async job can fail after acceptance. <code style={{ fontFamily:wf.mono, fontSize:13 }}>GET /v1/jobs/{'{job_id}'}</code> returns the same error envelope under <code style={{ fontFamily:wf.mono, fontSize:13 }}>job.error</code>. See <a href="docs-async-jobs.html#failed" style={{ color:'var(--accent)' }}>Async jobs · Failed response</a>.</P>
  </DocPage>
);

// ───────────────────────────────────────────────────────────────── Async jobs ──

const AsyncJobsPage = () => (
  <DocPage
    activeId="async-jobs"
    kicker="Reference"
    title="Async jobs"
    sub="Process media longer than 5 minutes. Submit a job, poll or wire a webhook."
  >
    <H2 id="why">Why async</H2>
    <P>Inline calls have a hard timeout of about 60 seconds and accept media up to ~5 minutes. Anything longer — a 4-hour meeting archive, a 90-minute lecture — must run as an async job, which decouples processing time from your HTTP request lifecycle.</P>
    <ApiTable cols={['Mode','Best for','Limit']} rows={[
      ['Inline POST',           'Short media (≤ 5 min)', '60s response timeout, 500 MB body cap'],
      ['Async job',             'Anything longer',        'No practical upper bound. Polls or webhooks.'],
      ['Async job + webhook',   'Background pipelines',   'Result delivered to your URL when ready.'],
    ]} />

    <H2 id="submit">POST /v1/jobs</H2>
    <P>Wrap any endpoint call in a job submission. The job inherits the same params, the same error codes, the same pricing.</P>
    <Code lang="JSON" filename="POST /v1/jobs" lines={[
      `{`,
      `  "endpoint": "audio/detect-speakers",`,
      `  "params": {`,
      `    "media_url": "https://cdn.../meeting-4h.mp4",`,
      `    "estimated_speakers": 6`,
      `  },`,
      `  "webhook_url": "https://your-app.com/miq/hook"   // optional`,
      `}`,
    ]} />
    <Code lang="JSON" filename="POST /v1/jobs · 202 Accepted" lines={[
      `{`,
      `  "job_id": "job_8x2k4n9pq3",`,
      `  "status": "pending",`,
      `  "endpoint": "audio/detect-speakers",`,
      `  "submitted_at": "2026-05-08T14:22:09Z",`,
      `  "poll_url":   "https://api.momentiq.dev/v1/jobs/job_8x2k4n9pq3"`,
      `}`,
    ]} />

    <H2 id="poll">GET /v1/jobs/{'{job_id}'}</H2>
    <P>Poll up to once per 5 seconds. The response shape is the same regardless of <code style={{ fontFamily:wf.mono, fontSize:13 }}>status</code> — only the populated fields change.</P>

    <H3 id="pending">Pending response</H3>
    <Code lang="JSON" filename="GET /v1/jobs · pending" lines={[
      `{`,
      `  "job_id": "job_8x2k4n9pq3",`,
      `  "status": "pending",`,
      `  "endpoint": "audio/detect-speakers",`,
      `  "progress": 0.42,`,
      `  "started_at":  "2026-05-08T14:22:14Z",`,
      `  "estimated_finish_at": "2026-05-08T14:28:50Z"`,
      `}`,
    ]} />

    <H3 id="completed">Completed response</H3>
    <Code lang="JSON" filename="GET /v1/jobs · completed" lines={[
      `{`,
      `  "job_id": "job_8x2k4n9pq3",`,
      `  "status": "completed",`,
      `  "endpoint": "audio/detect-speakers",`,
      `  "completed_at": "2026-05-08T14:28:42Z",`,
      `  "result": {`,
      `    "speakers": [{ "id":"A","share":0.38,"segments":14 }],`,
      `    "price_usd": 12.04`,
      `  }`,
      `}`,
    ]} />

    <H3 id="failed">Failed response</H3>
    <Code lang="JSON" filename="GET /v1/jobs · failed" lines={[
      `{`,
      `  "job_id": "job_8x2k4n9pq3",`,
      `  "status": "failed",`,
      `  "endpoint": "audio/detect-speakers",`,
      `  "failed_at": "2026-05-08T14:24:01Z",`,
      `  "error": {`,
      `    "code": "unsupported_file_type",`,
      `    "message": "Codec 'opus-foo' not supported.",`,
      `    "request_id": "req_8x2k4n9pq3",`,
      `    "docs_url": "https://momentiq.dev/docs/errors#unsupported_file_type"`,
      `  }`,
      `}`,
    ]} />

    <H2 id="webhooks">Webhooks</H2>
    <P>Pass <code style={{ fontFamily:wf.mono, fontSize:13 }}>webhook_url</code> when submitting a job. We POST the completed-or-failed response body to your URL with header <code style={{ fontFamily:wf.mono, fontSize:13 }}>X-MomentIQ-Signature</code> (HMAC-SHA256 of the body using your webhook secret).</P>
    <Code lang="HTTP" filename="webhook POST · headers" lines={[
      `POST /miq/hook HTTP/1.1`,
      `Content-Type: application/json`,
      `X-MomentIQ-Signature: sha256=8a3f9e2c4d…`,
      `X-MomentIQ-Job-Id: job_8x2k4n9pq3`,
      `X-MomentIQ-Status: completed`,
    ]} />
    <P>Webhook delivery retries on non-2xx responses with exponential backoff for 24 hours. Configure secrets in <a href="dashboard-api-keys.html" style={{ color:'var(--accent)' }}>API keys</a>.</P>

    <H2 id="cancel">Cancelling a job</H2>
    <P>Send <code style={{ fontFamily:wf.mono, fontSize:13 }}>DELETE /v1/jobs/{'{job_id}'}</code> while the job is pending. You're charged only for media processed up to the cancellation point.</P>
  </DocPage>
);

window.SetupPage      = SetupPage;
window.QuickstartPage = QuickstartPage;
window.AiAgentsPage   = AiAgentsPage;
window.ChatGPTConnectorPage = ChatGPTConnectorPage;
window.ClaudeConnectorPage  = ClaudeConnectorPage;
window.AuthPage       = AuthPage;
window.ErrorsPage     = ErrorsPage;
window.AsyncJobsPage  = AsyncJobsPage;
