/* global React */
/* JXM Brand Standards — AI prompts, Press kit, Downloads, Request asset */
const { useState: useStateAI } = React;

/* =========================================================================
   AI PRIMER — top-level entry point
   ========================================================================= */
const AI_PRIMER = `# JXM Brand & Voice Primer

You are writing or designing on behalf of JXM — a founder-led agency growth partner for mission-driven brands.

## Voice
- Direct. Warm. Quiet.
- Short sentences. Active verbs. Numbers over adjectives.
- Confident enough to say less. Skeptical of jargon.
- Earn the next sentence. Cut anything that isn't earning its place.

## Banned phrases — reject in output
leverage, synergy, unlock, transformative, full-funnel, best-in-class, world-class, cutting-edge, game-changing, industry-leading, next-gen, innovative, disruptive, paradigm, passionate, rockstar, ninja, thought leadership, reach out, circle back, bandwidth, mission-critical, turn-key, holistic, frictionless, seamless.

## One-liners to draw from
- "Most agencies sell hours. We sell outcomes."
- "Three concepts, with conviction. Never thirty."
- "We tell you what's broken before we touch it."
- "Strategy that shows its work."

## Visual system (when designing)
- Type: Inter (display), DM Sans (body), IBM Plex Mono (eyebrows/spec), Libre Baskerville italic (standalone pullquotes only).
- Color tokens:
  abyss     #221F32   primary dark
  cedar     #1C2D20   secondary dark
  soylent   #233935   tinted ground
  tusk      #F7F2EB   reading ground
  kermit    #49E385   primary signal / CTA
  gator     #2EB36A   HOVER ONLY for Kermit & Compassed buttons
  compassed #FF6464   alert / destructive
  fly       #BDDEED   RESTRICTED — requires Matt's approval
  blurple   #5E4FF5   RESTRICTED — requires Matt's approval
- Distribution: ~50% Tusk, ~28% Abyss, ~14% Kermit, ~8% accents.
- Spacing: 8-pt scale. Hard corners (0–6px radii). No drop shadows by default.

## Hard rules
1. Never use Fly or Blurple as an accent without Matt's approval. Default to Kermit and follow the guidelines for distribution above.
2. Never mix italic serif words into Inter headlines.
3. Never use stock photography. Always editorial / atmospheric.
4. All body copy must hit 4.5:1 contrast. Don't put Kermit text on Tusk.

If you're unsure, ask one direct question. Don't pad the answer.`;

function AIPage() {
  return (
    <div className="page">
      <PageHeader
        eyebrow="08 · AI prompt library"
        title="Tell the model who we are."
        lede="Copy-paste primers for the AI tools we delegate to. Drop one into your system prompt before any task on JXM's behalf."
      />
      <div className="stack">

        <section>
          <SectionHead label="8.1" title="Universal primer" meta="Works in any model" />
          <div className="callout">
            <div className="callout-eyebrow">How to use</div>
            Paste this once at the start of any session — Claude project instructions, ChatGPT custom GPT, Cursor rules, or a Midjourney profile note. It's the shortest version we trust.
          </div>
          <div style={{ marginTop: 24 }}>
            <div className="code-head">
              <span><span className="lang">primer</span> — JXM brand & voice</span>
              <CopyButton text={AI_PRIMER} label="Copy primer" />
            </div>
            <pre className="code" style={{ maxHeight: 360, overflow: 'auto' }}>{AI_PRIMER}</pre>
          </div>
        </section>

        <section>
          <SectionHead label="8.2" title="Per-tool prompts" />
          <div className="grid-3">
            {[
              { id: 'ai-claude', tag: 'Claude', file: 'claude.md', desc: 'Anthropic models — Claude.ai, API, projects.', icon: 'spark' },
              { id: 'ai-gpt',    tag: 'ChatGPT', file: 'chatgpt.md', desc: 'GPT-4o, GPT-5, custom GPTs, Copilot.', icon: 'spark' },
              { id: 'ai-mj',     tag: 'Midjourney', file: 'midjourney.md', desc: 'Style strings for image generation.', icon: 'spark' },
              { id: 'ai-stitch', tag: 'Google Stitch', file: 'DESIGN.md', desc: 'Agent-friendly design system for Stitch’s AI canvas.', icon: 'spark' },
            ].map((t, i) => (
              <a key={i} href={'#' + t.id} onClick={(e) => { e.preventDefault(); window.location.hash = t.id; }} className="card" style={{ display: 'flex', flexDirection: 'column', cursor: 'pointer', textDecoration: 'none', color: 'inherit' }}>
                <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 14 }}>
                  <span style={{ fontFamily: 'var(--ff-mono)', fontSize: 11, color: 'var(--accent)' }}>{t.file}</span>
                  <span style={{ fontFamily: 'var(--ff-mono)', fontSize: 10, color: 'var(--ink-mute)', letterSpacing: '0.14em', textTransform: 'uppercase' }}>Open →</span>
                </div>
                <div style={{ fontFamily: 'var(--ff-display)', fontWeight: 500, fontSize: 22, letterSpacing: '-0.01em', marginBottom: 6 }}>{t.tag}</div>
                <p style={{ fontFamily: 'var(--ff-body)', fontSize: 13, color: 'var(--ink-mute)', lineHeight: 1.55 }}>{t.desc}</p>
              </a>
            ))}
          </div>
        </section>

        <section>
          <SectionHead label="8.3" title="When using AI for JXM" />
          <div className="grid-2">
            <div className="card">
              <div style={{ fontFamily: 'var(--ff-mono)', fontSize: 10, letterSpacing: '0.18em', textTransform: 'uppercase', color: 'var(--kermit)', marginBottom: 14 }}>Do</div>
              <ul style={{ margin: 0, padding: 0, listStyle: 'none' }}>
                {[
                  'Paste the primer before any drafting task.',
                  'Review every output against the banned-phrases list.',
                  'Use Kermit (#49E385) for CTAs in generated images.',
                  'Cite Matt as founder, JXM as company name.',
                ].map((l, i) => (
                  <li key={i} style={{ padding: '10px 0', borderTop: i === 0 ? 'none' : '1px dashed var(--line)', fontFamily: 'var(--ff-body)', fontSize: 13.5, color: 'var(--ink)' }}>{l}</li>
                ))}
              </ul>
            </div>
            <div className="card">
              <div style={{ fontFamily: 'var(--ff-mono)', fontSize: 10, letterSpacing: '0.18em', textTransform: 'uppercase', color: 'var(--compassed)', marginBottom: 14 }}>Don't</div>
              <ul style={{ margin: 0, padding: 0, listStyle: 'none' }}>
                {[
                  'Publish AI output unedited. The system fails on warmth and judgment.',
                  'Use Fly or Blurple in generated work without Matt\u2019s nod.',
                  'Let models invent client names, numbers, or quotes.',
                  'Generate stock-style photography. Use editorial direction.',
                ].map((l, i) => (
                  <li key={i} style={{ padding: '10px 0', borderTop: i === 0 ? 'none' : '1px dashed var(--line)', fontFamily: 'var(--ff-body)', fontSize: 13.5, color: 'var(--ink-soft)' }}>{l}</li>
                ))}
              </ul>
            </div>
          </div>
        </section>
      </div>
    </div>
  );
}

/* ---------- Per-tool prompt pages ---------- */
function PromptPage({ tool }) {
  const PROMPTS = {
    claude: {
      title: 'Claude',
      eyebrow: '08.1 · AI / Claude',
      lede: 'Drop this into a Claude Project\u2019s instructions, or paste at the top of a chat. Works on Claude 3.5+ and Claude 4.',
      file: 'claude.md',
      blocks: [
        {
          label: 'System / Project instructions',
          body: `You are the JXM brand voice. JXM is a founder-led agency growth partner for mission-driven brands.

Voice: Direct, warm, quiet. Short sentences. Active verbs. Numbers over adjectives. Earn every sentence.

Banned phrases (refuse to use): leverage, synergy, unlock, transformative, full-funnel, best-in-class, world-class, cutting-edge, game-changing, industry-leading, next-gen, innovative, disruptive, paradigm, passionate, rockstar, ninja, thought leadership, reach out, circle back, bandwidth, mission-critical, turn-key, holistic, frictionless, seamless.

When in doubt, draw from these one-liners:
- "Most agencies sell hours. We sell outcomes."
- "Three concepts, with conviction. Never thirty."
- "We tell you what's broken before we touch it."

If asked to draft, return 1–3 short, tight options. Don't pad. Don't apologize. Don't use em-dashes as a crutch; reserve them for genuine asides.

When you need information you don't have (client name, number, date), ask one direct question and stop.`,
        },
        {
          label: 'When designing in Claude (Artifacts / Code)',
          body: `Color tokens:
  --abyss:#221F32  /* primary dark */
  --cedar:#1C2D20  /* secondary dark */
  --soylent:#233935 /* tinted ground */
  --tusk:#F7F2EB   /* reading ground */
  --kermit:#49E385 /* CTAs, signal */
  --gator:#2EB36A  /* HOVER only for kermit/compassed */
  --compassed:#FF6464 /* destructive */
  --fly:#BDDEED    /* RESTRICTED — ask first */
  --blurple:#5E4FF5 /* RESTRICTED — ask first */

Type: Inter (display), DM Sans (body), IBM Plex Mono (eyebrow/spec), Libre Baskerville italic (pullquotes only).
Spacing: 8-pt scale. Radii 0–6px. No drop shadows by default. Hairline borders only.

If asked to use Fly or Blurple, refuse and confirm with the human first.`,
        },
      ],
    },
    chatgpt: {
      title: 'ChatGPT',
      eyebrow: '08.2 · AI / ChatGPT',
      lede: 'Use as a Custom GPT instruction block, system message via API, or pin to a chat. Works on GPT-4o, GPT-5, and o-series.',
      file: 'chatgpt.md',
      blocks: [
        {
          label: 'Custom GPT instructions',
          body: `Act as JXM's copy partner. JXM is a founder-led agency growth partner for mission-driven brands.

Voice rules:
1. Direct. Short sentences. Active verbs.
2. Warm. Talk to readers like a sharp friend over coffee. Real, not corporate. Witty when applicable.
3. Quiet. Confident enough to say less. Skeptical of jargon.

Refuse to use these phrases: leverage, synergy, unlock, transformative, full-funnel, best-in-class, world-class, cutting-edge, game-changing, industry-leading, next-gen, innovative, disruptive, paradigm, passionate, rockstar, ninja, thought leadership, reach out, circle back, bandwidth, mission-critical, turn-key, holistic, frictionless, seamless.

When asked to draft:
- Return 1–3 tight options, not ten.
- Cut anything that doesn't earn its place.
- Don't apologize, don't preamble. Just the work.
- Ask one direct question if you're missing input. Don't invent.

Sign-off: "— Matt / JXM / getjxm.com"`,
        },
        {
          label: 'For visual outputs (Create Image/ Code Interpreter)',
          body: `Visual system:
- Type: Inter, DM Sans, IBM Plex Mono, Libre Baskerville (italic, pullquotes only).
- Palette: Abyss #221F32, Tusk #F7F2EB, Kermit #49E385 (CTA), Compassed #FF6464 (destructive).
- Gator #2EB36A is hover-only for Kermit/Compassed buttons.
- Fly #BDDEED and Blurple #5E4FF5 require approval. Ask before using.
- Distribution: 50% Tusk, 28% Abyss, 14% Kermit, 8% accents.
- Photography: editorial, atmospheric, low saturation, deep contrast. Never stock.`,
        },
      ],
    },
    mj: {
      title: 'Midjourney',
      eyebrow: '08.3 · AI / Midjourney',
      lede: 'Style strings for consistent JXM image direction. Append to any prompt.',
      file: 'midjourney.md',
      blocks: [
        {
          label: 'Universal JXM style suffix',
          body: `--style raw editorial documentary low-saturation deep-contrast tonal-palette Tusk-#F7F2EB-and-Abyss-#221F32 atmospheric mid-thought subjects 35mm-grain natural-light no-stock --ar 16:9 --s 50`,
        },
        {
          label: 'For people · "mid-thought"',
          body: `[subject] in [environment], shot on 35mm, natural light, low saturation, deep contrast, palette of Tusk #F7F2EB and Abyss #221F32 with one Kermit #49E385 highlight, mid-thought expression, candid, editorial documentary style, atmospheric, no stock photography, no smiles, --style raw --ar 3:2 --s 50`,
        },
        {
          label: 'For spaces · "ambient"',
          body: `[environment] without occupants, mid-morning light, low saturation, deep contrast, palette of Cedar #1C2D20 and Tusk #F7F2EB, hint of Fly #BDDEED in glass or sky, slightly empty, suggestive of a wider scene, editorial documentary, --style raw --ar 16:9 --s 75`,
        },
        {
          label: 'Hard rules',
          body: `Never: bright primary colors, glossy CG renders, exaggerated bokeh, smiles, isolated white backgrounds, gradients, lens flares, AI-typical hands.
Always: --style raw, palette anchored to Tusk + Abyss, ≤8% saturation in accents, --no stock-photo, --no white-background`,
        },
      ],
    },
    stitch: {
      title: 'Google Stitch',
      eyebrow: '09.4 · AI / Google Stitch',
      lede: 'Stitch reads a DESIGN.md file as persistent context for every UI generation. Paste this into the design-system panel of any Stitch project so the AI canvas respects the JXM rules.',
      file: 'DESIGN.md',
      blocks: [
        {
          label: 'How to use this',
          body: `1. Open your Stitch project (stitch.withgoogle.com).
2. In the canvas sidebar, open the Design System panel.
3. Paste the DESIGN.md below — or upload it as a file.
4. Confirm tokens are picked up by asking Stitch to "generate a CTA button" — it should return Kermit on Abyss, pill shape.

DESIGN.md is plain markdown. Every prompt you send is paired with this file before reaching Gemini, so you don't have to repeat brand rules.

Keep this file in sync: when JXM brand standards change, re-export from this page and re-upload to Stitch.`,
        },
        {
          label: 'DESIGN.md · the full file',
          body: `# DESIGN.md — JXM Brand System v2.6

This file defines the JXM visual and content system. It is the source of truth for any AI-generated UI on behalf of JXM. Read this in full before generating, editing, or critiquing designs.

## 1. Identity

**Brand**: JXM — a founder-led agency growth partner for mission-driven brands.
**Voice**: Direct. Warm. Quiet.
**Personality**: Confident enough to say less. Skeptical of jargon. Evidence-backed.

## 2. Color tokens

| Token       | Hex     | Role                                       |
| ----------- | ------- | ------------------------------------------ |
| abyss       | #221F32 | Primary dark — structure, ink              |
| cedar       | #1C2D20 | Secondary dark — sections                  |
| soylent     | #233935 | Tertiary dark — tinted ground              |
| tusk        | #F7F2EB | Reading ground, canvas                     |
| kermit      | #49E385 | Primary signal — CTAs, links               |
| gator       | #2EB36A | HOVER ONLY for kermit & compassed buttons  |
| compassed   | #FF6464 | Alerts, destructive actions                |
| fly         | #BDDEED | RESTRICTED — requires Matt's approval      |
| blurple     | #5E4FF5 | RESTRICTED — requires Matt's approval      |

**Distribution rule**: ~50% Tusk, ~28% Abyss, ~14% Kermit, ~8% accents.
**Hard rule**: Do not use Fly or Blurple in generated output. If a user requests them, return Kermit and ask the user to confirm with Matt.
**Hard rule**: Never put Kermit text on Tusk (contrast fails). Use Abyss for text.

## 3. Typography

| Role            | Family             | Weight       |
| --------------- | ------------------ | ------------ |
| Display         | Inter              | 300, 500     |
| Body            | DM Sans            | 400, 500     |
| Eyebrow / spec  | IBM Plex Mono      | 400, 500     |
| Editorial pull  | Libre Baskerville  | Italic 400   |

**Scale (clamp-fluid)**:
- display-xl  clamp(7rem, 22vw, 22rem)
- display-lg  clamp(5rem, 17vw, 13rem)
- display-md  clamp(3.5rem, 11vw, 9.5rem)
- headline    clamp(2rem, 4.4vw, 3.5rem)
- subhead     clamp(1.5rem, 2.4vw, 2rem)
- lead        clamp(1.0625rem, 1.4vw, 1.25rem)
- body        1rem
- meta        0.875rem
- eyebrow     0.75rem (uppercase, letter-spacing 0.18em)

**Pairing rule**: Pair Inter display with DM Sans body. Reserve Libre Baskerville italic for *standalone* pullquotes only. Never mix italic serif words into Inter headlines.

## 4. Spacing & grid

**Scale (8pt)**: 0, 4, 8, 12, 16, 24, 32, 48, 64, 96, 128 px.
**Grid**: 12 columns fluid. 24px gutter (desktop), 16px (mobile). 56px outer margin (desktop), 22px (mobile). Content max 1280px.
**Radii**: 0 (default), 3px (buttons-old), 4px (inputs/swatches), 6px (cards), 8px (modals), 999px (pills, buttons).
**Shadows**: None by default. Hairline borders (1px var(--line)) carry hierarchy.

## 5. Components

### Button
- Shape: pill (border-radius: 999px).
- Padding: 11px 20px.
- Typography: IBM Plex Mono, 11px, uppercase, letter-spacing 0.14em.
- Variants: primary (kermit/abyss), ghost (transparent/border), dark (abyss/tusk), danger (compassed/white).
- Hover: primary → gator. Danger → gator.

### Card
- Background: tusk or white. Border: 1px solid var(--line).
- Border-radius: 6px. Padding: 22px.
- No drop shadow.

### Input
- Border: 1px solid var(--line-strong). Border-radius: 3px.
- Focus ring: 3px color-mix(in srgb, var(--accent) 30%, transparent).
- Label: IBM Plex Mono, 11px, uppercase, letter-spacing 0.12em.

### Badge / pill
- Background: kermit (new), abyss (AI), compassed (restricted).
- IBM Plex Mono, 10px, uppercase, letter-spacing 0.14em.

## 6. Voice & copy

**Tone**: Direct, warm, quiet. Short sentences. Active verbs. Numbers over adjectives.

**Banned phrases** — refuse to use in generated copy:
leverage, synergy, unlock, transformative, full-funnel, best-in-class, world-class, cutting-edge, game-changing, industry-leading, next-gen, innovative, disruptive, paradigm, passionate, rockstar, ninja, thought leadership, reach out, circle back, bandwidth, mission-critical, turn-key, holistic, frictionless, seamless.

**Reference one-liners** when drafting:
- "Most agencies sell hours. We sell outcomes."
- "Three concepts, with conviction. Never thirty."
- "We tell you what's broken before we touch it."
- "Strategy that shows its work."

## 7. Imagery

**Two flagship treatments**:
1. **Cinematic** — vintage editorial / found photography. Full-bleed at hero. Used behind a single line of display type.
2. **Texture** — B&W abstract macro (paper, hands, light). Portrait crop next to copy.

**Never**: stock photography, smiles, gradient overlays, lens flares, off-palette tints, white-isolated subjects.
**Palette-tinted tiles** (when no photo available): radial glows on Soylent/Cedar/Abyss grounds, ~50% opacity, mix-blend-mode: screen, never more than two glow centers.

## 8. Motion

- **Principle**: Quiet, intentional, cancelable. Most motion should travel 4–8px, not 40.
- **Easings**: ease-out cubic-bezier(0.2, 0, 0, 1) for entries; ease-in-out for state changes.
- **Durations**: 80ms (hover), 160ms (buttons), 240ms (drawers), 420ms (page).
- Respect prefers-reduced-motion.

## 9. Hard rules for generation

1. Default to Kermit for any CTA / signal. Never substitute Fly or Blurple.
2. Buttons are pills. Cards are 6px-radius hairline boxes. No drop shadows.
3. No stock photography. Use the palette-tinted tile recipe when imagery is unavailable.
4. All body copy must hit 4.5:1 contrast (AA). Verify before shipping.
5. If a user asks for an off-palette color, off-rule typography, or a banned phrase, ask one direct question instead of obliging.

## 10. Source

Maintained at: brand.getjxm.com
Questions or requests: hi@getjxm.com
File version: 2.6 · May 2026`,
        },
        {
          label: 'Stitch prompt cheatsheet',
          body: `Once DESIGN.md is loaded, prompt Stitch with intent, not style:

• "Build a landing page hero for JXM with one line of display type and a pill CTA."
• "Design a case study card row — three cards, each with eyebrow / title / 2-line description / arrow."
• "Generate a contact form with name, email, and a textarea, plus a primary submit button."
• "Make a press kit page with downloadable headshots and a boilerplate block."

Don't repeat style rules — Stitch pulls those from DESIGN.md every generation. If something looks off-brand in the output, edit DESIGN.md before re-prompting; that's the lever.

Never upload sketches that contain off-palette colors as Stitch will sometimes copy the input style over the DESIGN.md rules.`,
        },
      ],
    },
  };

  const p = PROMPTS[tool];
  return (
    <div className="page">
      <PageHeader eyebrow={p.eyebrow} title={p.title + '.'} lede={p.lede} />
      <div className="stack">
        {p.blocks.map((b, i) => (
          <section key={i}>
            <SectionHead label={`${p.file} · ${String(i + 1).padStart(2, '0')}`} title={b.label} />
            <div>
              <div className="code-head">
                <span><span className="lang">prompt</span> · {b.label}</span>
                <CopyButton text={b.body} />
              </div>
              <pre className="code" style={{ whiteSpace: 'pre-wrap' }}>{b.body}</pre>
            </div>
          </section>
        ))}
        <div className="callout">
          <div className="callout-eyebrow">Feedback</div>
          If a prompt produces work that misses, send the chat link to <a href="mailto:hi@getjxm.com" style={{ borderBottom: '1px solid currentColor' }}>hi@getjxm.com</a>. We'll update the primer here within the week.
        </div>
      </div>
    </div>
  );
}

/* =========================================================================
   PRESS KIT
   ========================================================================= */
function PressPage() {
  const Glyph = window.Glyph;
  return (
    <div className="page">
      <PageHeader
        eyebrow="09 · Press kit"
        title="For media."
        lede="Quotes, boilerplate, contact, and assets — everything you need for a story without an email."
      />
      <div className="stack">

        <section>
          <SectionHead label="9.1" title="Contact" meta="response within 24h" />
          <div className="grid-3">
            {[
              ['Press inquiries', 'hi@getjxm.com', 'Matt — founder'],
              ['Partnerships', 'hi@getjxm.com', 'Matt — founder'],
              ['Everything else', 'hi@getjxm.com', 'General'],
            ].map(([a, b, c], i) => (
              <div key={i} className="card">
                <div style={{ fontFamily: 'var(--ff-mono)', fontSize: 10, letterSpacing: '0.18em', textTransform: 'uppercase', color: 'var(--ink-mute)', marginBottom: 8 }}>{a}</div>
                <a href={'mailto:' + b} style={{ fontFamily: 'var(--ff-display)', fontWeight: 500, fontSize: 17, letterSpacing: '-0.01em', color: 'var(--ink)', display: 'block', borderBottom: '1px solid var(--line-strong)', paddingBottom: 4 }}>{b}</a>
                <div style={{ fontFamily: 'var(--ff-body)', fontSize: 12, color: 'var(--ink-mute)', marginTop: 6 }}>{c}</div>
              </div>
            ))}
          </div>
        </section>

        <section>
          <SectionHead label="9.2" title="Boilerplate" />
          <div className="grid-2">
            <div className="card" style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
                <span style={{ fontFamily: 'var(--ff-mono)', fontSize: 10, letterSpacing: '0.18em', textTransform: 'uppercase', color: 'var(--ink-mute)' }}>50 words</span>
                <CopyButton text={`JXM is a founder-led agency growth partner for mission-driven brands. We work with the people building things that matter and help them grow.`} />
              </div>
              <p style={{ fontFamily: 'var(--ff-body)', fontSize: 14, lineHeight: 1.6, color: 'var(--ink-soft)', margin: 0 }}>
                JXM is a founder-led agency growth partner for mission-driven brands. We work with the people building things that matter and help them grow.
              </p>
            </div>
            <div className="card" style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
                <span style={{ fontFamily: 'var(--ff-mono)', fontSize: 10, letterSpacing: '0.18em', textTransform: 'uppercase', color: 'var(--ink-mute)' }}>One-liner</span>
                <CopyButton text={`JXM — a founder-led agency growth partner for mission-driven brands.`} />
              </div>
              <p style={{ fontFamily: 'var(--ff-display)', fontWeight: 500, fontSize: 22, lineHeight: 1.3, letterSpacing: '-0.01em', color: 'var(--ink)', margin: 0 }}>
                JXM — a founder-led agency growth partner for mission-driven brands.
              </p>
            </div>
          </div>
        </section>

        <section>
          <SectionHead label="9.3" title="Headshots" meta="3 images · JPG + WebP" />
          <div className="grid-3">
            {[
              { label: 'Founders · environmental', src: 'assets/founders.webp', aspect: '3 / 5' },
              { label: 'Matt MaGuy · portrait', src: 'assets/matt-maguy.jpg', aspect: '4 / 5' },
              { label: 'Jim Pond · portrait', src: 'assets/jim-pond.jpg', aspect: '4 / 5' },
            ].map((h, i) => (
              <div key={i} style={{ aspectRatio: h.aspect, background: 'var(--soylent)', position: 'relative', borderRadius: 4, overflow: 'hidden' }}>
                <img src={h.src} alt={h.label} style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block' }} />
                <div style={{ position: 'absolute', bottom: 0, left: 0, right: 0, padding: '32px 14px 12px 14px', background: 'linear-gradient(to top, rgba(34,31,50,0.75), transparent)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                  <span style={{ fontFamily: 'var(--ff-mono)', fontSize: 10, letterSpacing: '0.16em', textTransform: 'uppercase', color: 'var(--tusk)' }}>{h.label}</span>
                  <a href={h.src} download style={{ fontFamily: 'var(--ff-mono)', fontSize: 10, letterSpacing: '0.14em', textTransform: 'uppercase', background: 'rgba(247,242,235,0.16)', color: 'var(--tusk)', border: 'none', padding: '5px 8px', borderRadius: 2, cursor: 'pointer', textDecoration: 'none' }}>↓ File</a>
                </div>
              </div>
            ))}
          </div>
        </section>

        <section>
          <SectionHead label="9.4" title="Recent coverage" />
          <div style={{ display: 'flex', flexDirection: 'column' }}>
            {[
              ['JXM Ideas', 'On Standards', 'Apr 2026', 'https://getjxm.com/thoughts/on-standards.html'],
              ['JXM Ideas', 'Sonar? So What.', 'Apr 2026', 'https://getjxm.com/thoughts/sonar-so-what.html'],
              ['JXM Ideas', 'Engineering Consumer Preference in Uncertain Times', 'Mar 2026', 'https://getjxm.com/thoughts/engineering-preference.html'],
              ['JXM Ideas', 'Walking on Glass? Ouch.', 'Feb 2026', 'https://getjxm.com/thoughts/walking-on-glass.html'],
            ].map(([pub, title, date, href], i) => (
              <a key={i} href={href} target="_blank" rel="noopener" style={{ display: 'grid', gridTemplateColumns: '180px 1fr 100px 20px', gap: 16, padding: '16px 0', borderTop: '1px solid var(--line)', alignItems: 'baseline' }}>
                <span style={{ fontFamily: 'var(--ff-mono)', fontSize: 11, letterSpacing: '0.14em', textTransform: 'uppercase', color: 'var(--ink-mute)' }}>{pub}</span>
                <span style={{ fontFamily: 'var(--ff-display)', fontWeight: 500, fontSize: 16, color: 'var(--ink)', letterSpacing: '-0.005em' }}>{title}</span>
                <span style={{ fontFamily: 'var(--ff-mono)', fontSize: 11, color: 'var(--ink-mute)', letterSpacing: '0.12em' }}>{date}</span>
                <Glyph name="ext" size={14} stroke="var(--ink-mute)" />
              </a>
            ))}
          </div>
        </section>

      </div>
    </div>
  );
}

/* =========================================================================
   DOWNLOADS
   ========================================================================= */
function DownloadsPage() {
  const groups = [
    {
      eyebrow: '01 / Logo',
      title: 'JXM wordmark & mark variants.',
      desc: 'Primary wordmark plus inverse for dark grounds. SVG for scaling, PNG for quick paste-ins.',
      files: [
        ['JXM Lockup · with frame', 'SVG', false, 'assets/JXM.svg'],
        ['JXM Mark · unframed', 'SVG', false, 'assets/jxm-small.svg'],
        ['JXM Lockup · light bg', 'PNG · 2400px', false, 'assets/jxm-lockup-light-bg.png'],
        ['JXM Lockup · dark bg', 'PNG · 2400px', false, 'assets/jxm-lockup-dark-bg.png'],
      ],
    },
    {
      eyebrow: '02 / Pattern',
      title: 'Brand pattern asset.',
      desc: 'The textural mark. Use full-bleed, on Tusk or Abyss only. Never on a tight card.',
      files: [
        ['JXM Pattern · full library', 'PNG · 3200px', false, 'assets/pattern.png'],
        ['JXM Pattern · Abyss on Tusk', 'PNG'],
        ['JXM Pattern · Tusk on Abyss', 'PNG'],
      ],
    },
    {
      eyebrow: '03 / Fonts',
      title: 'Type families via Google.',
      desc: 'Inter, DM Sans, IBM Plex Mono, Libre Baskerville. Open source, served on the live site.',
      files: [
        ['Inter', 'fonts.google.com ↗', true],
        ['DM Sans', 'fonts.google.com ↗', true],
        ['IBM Plex Mono', 'fonts.google.com ↗', true],
        ['Libre Baskerville', 'fonts.google.com ↗', true],
      ],
    },
  ];
  return (
    <div className="page">
      <PageHeader
        eyebrow="10 · Downloads"
        title="Take it with you."
        lede="Logos, patterns, fonts, and the full kit. Grab what you need."
      />
      <div style={{ background: 'var(--ink)', color: 'var(--bg)', borderRadius: 6, overflow: 'hidden' }}>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: 1, background: 'rgba(247,242,235,0.1)' }} className="dl-grid">
          {groups.map((g, i) => (
            <div key={i} style={{ background: 'var(--ink)', padding: '32px 28px', display: 'flex', flexDirection: 'column', gap: 18, minHeight: 320 }}>
              <div style={{ fontFamily: 'var(--ff-mono)', fontSize: 11, letterSpacing: '0.18em', textTransform: 'uppercase', color: 'var(--accent)' }}>{g.eyebrow}</div>
              <div style={{ fontFamily: 'var(--ff-display)', fontWeight: 400, fontSize: 22, letterSpacing: '-0.01em', lineHeight: 1.2 }}>{g.title}</div>
              <p style={{ fontFamily: 'var(--ff-body)', fontSize: 13, lineHeight: 1.6, color: 'color-mix(in srgb, var(--bg) 70%, transparent)', flex: 1, margin: 0 }}>{g.desc}</p>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 1, background: 'rgba(247,242,235,0.1)' }}>
                {g.files.map((file, j) => {
                  const [t, fmt, external, href] = file;
                  return (
                  <a key={j} href={href || '#'} {...(href ? { download: true } : {})} style={{
                    background: 'var(--ink)', color: 'var(--bg)',
                    padding: '12px 0', display: 'flex', justifyContent: 'space-between', alignItems: 'center',
                    fontFamily: 'var(--ff-mono)', fontSize: 12, letterSpacing: '0.04em',
                    transition: 'color 160ms ease',
                  }}
                    onMouseEnter={(e) => e.currentTarget.style.color = 'var(--accent)'}
                    onMouseLeave={(e) => e.currentTarget.style.color = 'var(--bg)'}>
                    <span>{t}</span>
                    <span style={{ fontSize: 10, letterSpacing: '0.18em', textTransform: 'uppercase', opacity: 0.6 }}>{external ? '↗' : '↓'} {fmt}</span>
                  </a>
                  );
                })}
              </div>
            </div>
          ))}
        </div>
      </div>
      <p className="prose" style={{ marginTop: 24, fontSize: 14, color: 'var(--ink-mute)' }}>
        Need a format that isn't here — EPS, single-color SVG, packaged ZIP for a print vendor? <a href="#request" style={{ borderBottom: '1px solid currentColor', color: 'var(--ink)' }}>Open an asset request →</a>
      </p>
    </div>
  );
}

/* =========================================================================
   REQUEST ASSET
   ========================================================================= */
function RequestPage() {
  const [form, setForm] = useStateAI({ name: '', email: '', org: '', what: '', deadline: '', notes: '' });
  const [submitted, setSubmitted] = useStateAI(false);
  const submit = (e) => { e.preventDefault(); setSubmitted(true); };
  return (
    <div className="page">
      <PageHeader
        eyebrow="11 · Request an asset"
        title="Need something else?"
        lede="EPS, single-color SVG, a particular crop, a custom print pack, or a missing snippet — tell us what you need."
      />
      <div style={{ display: 'grid', gridTemplateColumns: '1.4fr 1fr', gap: 60 }} className="req-grid">
        <div>
          {submitted ? (
            <div className="card" style={{ borderColor: 'var(--accent)', background: 'color-mix(in srgb, var(--accent) 10%, transparent)' }}>
              <div style={{ fontFamily: 'var(--ff-mono)', fontSize: 10, letterSpacing: '0.18em', textTransform: 'uppercase', color: 'var(--accent-ink)', marginBottom: 8 }}>Request received</div>
              <div style={{ fontFamily: 'var(--ff-display)', fontWeight: 500, fontSize: 22, marginBottom: 10, letterSpacing: '-0.01em' }}>Thanks. We'll have you something within 48h.</div>
              <p style={{ fontFamily: 'var(--ff-body)', fontSize: 14, color: 'var(--ink-soft)', lineHeight: 1.55 }}>You'll hear from Matt or someone he hands it to. If it's urgent, email <a href="mailto:hi@getjxm.com" style={{ borderBottom: '1px solid currentColor' }}>hi@getjxm.com</a> with "URGENT" in the subject.</p>
              <button className="jbtn jbtn--ghost" style={{ marginTop: 18 }} onClick={() => { setSubmitted(false); setForm({ name: '', email: '', org: '', what: '', deadline: '', notes: '' }); }}>Submit another</button>
            </div>
          ) : (
            <form onSubmit={submit} className="card">
              <FormField label="Your name" value={form.name} onChange={x => setForm(s => ({ ...s, name: x }))} placeholder="Matt" />
              <FormField label="Email" type="email" value={form.email} onChange={x => setForm(s => ({ ...s, email: x }))} placeholder="you@company.com" />
              <FormField label="Organization" value={form.org} onChange={x => setForm(s => ({ ...s, org: x }))} placeholder="Optional" optional />
              <FormField label="What do you need?" textarea value={form.what} onChange={x => setForm(s => ({ ...s, what: x }))} placeholder="e.g. JXM logo as single-colour SVG, transparent bg, for a print vendor in Brooklyn." />
              <FormField label="When do you need it?" value={form.deadline} onChange={x => setForm(s => ({ ...s, deadline: x }))} placeholder="ISO date or 'EOD Friday'" />
              <FormField label="Anything else?" textarea value={form.notes} onChange={x => setForm(s => ({ ...s, notes: x }))} placeholder="Optional context." optional />
              <button type="submit" className="jbtn jbtn--primary" style={{ marginTop: 6 }}>Send request →</button>
            </form>
          )}
        </div>
        <div>
          <div style={{ fontFamily: 'var(--ff-mono)', fontSize: 10, letterSpacing: '0.18em', textTransform: 'uppercase', color: 'var(--ink-mute)', marginBottom: 12 }}>How it works</div>
          {[
            ['01', 'You submit.', 'A real person reads it.'],
            ['02', 'Reply within 24h.', 'Even if just to ask a clarifying question.'],
            ['03', 'Asset delivered within 48h.', 'Sometimes faster. Sometimes one back-and-forth.'],
          ].map(([n, t, d], i) => (
            <div key={i} style={{ display: 'grid', gridTemplateColumns: '32px 1fr', gap: 14, padding: '14px 0', borderTop: '1px solid var(--line)' }}>
              <span style={{ fontFamily: 'var(--ff-mono)', fontSize: 11, color: 'var(--accent)' }}>{n}</span>
              <div>
                <div style={{ fontFamily: 'var(--ff-display)', fontWeight: 500, fontSize: 15, marginBottom: 4, letterSpacing: '-0.005em' }}>{t}</div>
                <div style={{ fontFamily: 'var(--ff-body)', fontSize: 13, color: 'var(--ink-mute)', lineHeight: 1.55 }}>{d}</div>
              </div>
            </div>
          ))}
          <div className="callout" style={{ marginTop: 24 }}>
            <div className="callout-eyebrow">Direct</div>
            Skip the form: <a href="mailto:hi@getjxm.com" style={{ borderBottom: '1px solid currentColor' }}>hi@getjxm.com</a>
          </div>
        </div>
      </div>
    </div>
  );
}

window.AIPage = AIPage;
window.PromptPage = PromptPage;
window.PressPage = PressPage;
window.DownloadsPage = DownloadsPage;
window.RequestPage = RequestPage;
