/* global React */
/* JXM Brand Standards — Voice & Components */
const { useState: useStateVC } = React;

/* =========================================================================
   VOICE
   ========================================================================= */
function VoicePage() {
  return (
    <div className="page">
      <PageHeader
        eyebrow="06 · Voice"
        title="How we sound."
        lede="Direct, evidence-backed, dry where it can be. We earn the next sentence."
      />
      <div className="stack">

        <section>
          <SectionHead label="6.1" title="Three principles" />
          <div className="grid-3">
            {[
              { t: 'Direct', d: 'Short sentences. Active verbs. The reader\u2019s time is worth more than ours. If a word isn\u2019t earning its place, cut it.' },
              { t: 'Warm', d: 'Real, not corporate. We write the way we\u2019d talk to a sharp friend over coffee. The work is serious; the language doesn\u2019t have to be cold.' },
              { t: 'Quiet', d: 'Confident enough to say less. Skeptical of jargon. The smartest voice in the room is usually the quietest.' },
            ].map((p, i) => (
              <div key={i} style={{ paddingTop: 18 }}>
                <div style={{ fontFamily: 'var(--ff-display)', fontWeight: 500, fontSize: 22, marginBottom: 10, letterSpacing: '-0.01em' }}>{p.t}</div>
                <p style={{ fontFamily: 'var(--ff-body)', fontSize: 14, lineHeight: 1.6, color: 'var(--ink-soft)', maxWidth: '36ch' }}>{p.d}</p>
              </div>
            ))}
          </div>
        </section>

        <section>
          <SectionHead label="6.2" title="The test" />
          <blockquote style={{
            fontFamily: 'var(--ff-edit)', fontStyle: 'italic', fontWeight: 400,
            fontSize: 'clamp(1.5rem, 3vw, 2.25rem)', lineHeight: 1.3, letterSpacing: '-0.005em',
            maxWidth: '30ch', margin: 0, padding: '40px 0',
            position: 'relative',
          }}>
            <span style={{ display: 'block', width: 48, height: 1, background: 'var(--accent)', marginBottom: 28 }}></span>
            Write the sentence a sharp friend would believe — then delete the half that's flattery.
          </blockquote>
        </section>

        <section>
          <SectionHead label="6.3" title="Do / Don't" />
          <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' }}>
                {[
                  '"Media agencies optimze for spend because thats how they\u2019re paid. We optimize for outcomes."',
                  '"The value is often there. The lack of visibility is the problem."',
                  '"We\u2019ll diagnose before we prescribe, always."',
                  '"We are agnostic to media types."',
                  '"Mission-driven. Founder-led. Engineering Preference + Intention."',
                ].map((l, i) => (
                  <li key={i} style={{ padding: '10px 0', borderTop: i === 0 ? 'none' : '1px dashed var(--line)', fontFamily: 'var(--ff-body)', fontSize: 14, lineHeight: 1.55, 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' }}>
                {[
                  '"Unlocking transformative growth synergies."',
                  '"Best-in-class, full-funnel solutions."',
                  '"At the intersection of creativity and data."',
                  '"We\u2019re passionate about driving impact."',
                  '"Game-changing. Industry-leading. World-class."',
                ].map((l, i) => (
                  <li key={i} style={{ padding: '10px 0', borderTop: i === 0 ? 'none' : '1px dashed var(--line)', fontFamily: 'var(--ff-body)', fontSize: 14, lineHeight: 1.55, color: 'var(--ink-soft)', textDecoration: 'line-through', textDecorationColor: 'var(--compassed)', textDecorationThickness: '1px' }}>{l}</li>
                ))}
              </ul>
            </div>
          </div>
        </section>

        <section>
          <SectionHead label="6.4" title="Banned phrases" meta="Reject in copy & AI output" />
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
            {[
              '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',
            ].map((w, i) => (
              <span key={i} style={{
                fontFamily: 'var(--ff-mono)', fontSize: 11.5, padding: '5px 10px',
                border: '1px solid var(--line-strong)', borderRadius: 2,
                color: 'var(--ink-soft)', textDecoration: 'line-through', textDecorationColor: 'var(--compassed)',
              }}>{w}</span>
            ))}
          </div>
        </section>

      </div>
    </div>
  );
}

/* =========================================================================
   COPY SNIPPETS — boilerplate, taglines, bios
   ========================================================================= */
function SnippetsPage() {
  return (
    <div className="page">
      <PageHeader
        eyebrow="06.1 · Voice / Copy snippets"
        title="Drop-in copy."
        lede="Paste-ready boilerplate, one-liners, and bios. All checked against the voice rules. Copy, ship."
      />
      <div className="stack">

        <section>
          <SectionHead label="6.1.1" title="One-liners" />
          <div style={{ display: 'flex', flexDirection: 'column' }}>
            {[
              'JXM is a founder-led growth partner for mission-driven brands.',
              'Media agencies optimze for spend because thats how they\u2019re paid. We optimize for outcomes.',
              'Strategy that shows its work pre-launch.',
              'We are agnostic to media type.',
              'We\u2019ll diagnose before we prescribe, always.',
            ].map((s, i) => (
              <div key={i} style={{ display: 'grid', gridTemplateColumns: '1fr auto', alignItems: 'center', gap: 16, padding: '14px 0', borderTop: i === 0 ? '1px solid var(--line)' : '1px solid var(--line)' }}>
                <div style={{ fontFamily: 'var(--ff-display)', fontWeight: 500, fontSize: 17, color: 'var(--ink)', letterSpacing: '-0.005em' }}>"{s}"</div>
                <CopyButton text={s} />
              </div>
            ))}
          </div>
        </section>

        <section>
          <SectionHead label="6.1.2" title="Boilerplate" meta="50 / 100 / 200 words" />
          <div className="grid-3">
            {[
              {
                len: '50',
                body: 'JXM is a founder-led agency growth partner for mission-driven brands. We sell outcomes, not hours — three concepts with conviction, evidence-backed strategy, and execution that ships. We work with the people building things that matter.',
              },
              {
                len: '100',
                body: 'JXM is a founder-led agency growth partner for mission-driven brands. Mission-driven brands don\u2019t lose because they can\u2019t compete. They lose because their strengths are invisible. Brand growth isn\u2019t a product problem. It\u2019s a visibility problem. When the reasons to choose you aren\u2019t visible, preference never forms. Growth stalls. No bueno. We fix that.',
              },
              {
                len: '200',
                body: 'JXM is a founder-led agency growth partner for mission-driven brands. The model is old: agencies sell hours, founders share shiny decks, no one is accountable for outcomes. We started JXM because we believe great brands need partners who think with them, not vendors who execute through them. Every engagement starts with the same question — what does shipped, working, measurable look like — and is structured to get there. We tell you what\u2019s broken before we start trying to fix it, so we\u2019re all aligned. We sell outcomes, not retainers. Our partners are founders, marketers, and operators at companies doing the kind of work that doesn\u2019t fit on a billboard but does fit on a P&L. If that sounds like you, hi@getjxm.com.',
              },
            ].map((b, i) => (
              <div key={i} 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(--accent)' }}>{b.len} words</span>
                  <CopyButton text={b.body} />
                </div>
                <p style={{ fontFamily: 'var(--ff-body)', fontSize: 13.5, lineHeight: 1.6, color: 'var(--ink-soft)', margin: 0 }}>{b.body}</p>
              </div>
            ))}
          </div>
        </section>

        <section>
          <SectionHead label="6.1.3" title="Bios" meta="Founder · Team · Generic" />
          <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)' }}>Matt · Co-founder · 30 words</span>
                <CopyButton text={`Matt is co-founder of JXM, a founder-led agency growth partner for mission-driven brands. He oversees brand strategy and positioning across all aspects of the agency, creating the conditions for growth.`} />
              </div>
              <p style={{ fontFamily: 'var(--ff-body)', fontSize: 13.5, lineHeight: 1.6, color: 'var(--ink-soft)', margin: 0 }}>
                Matt is co-founder of JXM, a founder-led agency growth partner for mission-driven brands. He oversees brand strategy and positioning across all aspects of the agency, creating the conditions for growth.
              </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)' }}>Jim · Co-founder · 48 words</span>
                <CopyButton text={`Jim is the co-founder of JXM, a founder-led agency growth partner working with mission-driven brands on what to ship and how. Jim leads up business strategy and operations across all aspects of the agency, shipping ideas, strategies and campaigns on time and up to his exceedingly high standards.`} />
              </div>
              <p style={{ fontFamily: 'var(--ff-body)', fontSize: 13.5, lineHeight: 1.6, color: 'var(--ink-soft)', margin: 0 }}>
                Jim is the co-founder of JXM, a founder-led agency growth partner working with mission-driven brands on what to ship and how. Jim leads up business strategy and operations across all aspects of the agency, shipping ideas, strategies and campaigns on time and up to his exceedingly high standards.
              </p>
            </div>
          </div>
        </section>

        <section>
          <SectionHead label="6.1.4" title="Email sign-offs" />
          <div className="grid-3">
            {[
              ['Standard', '— Matt\nJXM\ngetjxm.com'],
              ['Warm', 'Thanks,\nMatt\nFounder, JXM · getjxm.com'],
              ['Cold reply', 'Matt at JXM\nfounder-led growth, mission-driven brands\ngetjxm.com'],
            ].map(([t, body], i) => (
              <div key={i} className="card">
                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 12 }}>
                  <span style={{ fontFamily: 'var(--ff-mono)', fontSize: 10, letterSpacing: '0.18em', textTransform: 'uppercase', color: 'var(--ink-mute)' }}>{t}</span>
                  <CopyButton text={body} />
                </div>
                <pre style={{ fontFamily: 'var(--ff-body)', fontSize: 13, lineHeight: 1.6, color: 'var(--ink-soft)', margin: 0, whiteSpace: 'pre-wrap' }}>{body}</pre>
              </div>
            ))}
          </div>
        </section>

      </div>
    </div>
  );
}

/* =========================================================================
   COMPONENTS — BUTTONS
   ========================================================================= */
function ButtonsPage() {
  const Glyph = window.Glyph;
  return (
    <div className="page">
      <PageHeader
        eyebrow="07 · Components / Buttons"
        title="Buttons."
        lede="Primary, ghost, dark, and destructive. Mono labels, hard-cornered. Gator owns the hover."
      />
      <div className="stack">

        <section>
          <SectionHead label="7.1" title="Variants" />
          <div style={{ fontFamily: 'var(--ff-mono)', fontSize: 10, letterSpacing: '0.18em', textTransform: 'uppercase', color: 'var(--ink-mute)', marginBottom: 10 }}>Mono label · utility / system</div>
          <div className="card" style={{ display: 'flex', flexWrap: 'wrap', gap: 16, alignItems: 'center' }}>
            <button className="jbtn jbtn--primary">Primary action <Glyph name="arr" size={12} stroke="currentColor" /></button>
            <button className="jbtn jbtn--outline">Outline <Glyph name="arr" size={12} stroke="currentColor" /></button>
            <button className="jbtn jbtn--ghost">Secondary</button>
            <button className="jbtn jbtn--dark">Inverse</button>
            <button className="jbtn jbtn--danger">Destructive</button>
            <button className="jbtn jbtn--primary" disabled style={{ opacity: 0.4, cursor: 'not-allowed' }}>Disabled</button>
          </div>

          <div style={{ fontFamily: 'var(--ff-mono)', fontSize: 10, letterSpacing: '0.18em', textTransform: 'uppercase', color: 'var(--ink-mute)', marginTop: 28, marginBottom: 10 }}>Display label · warm / brand CTA · add <code style={{ fontFamily: 'var(--ff-mono)' }}>.jbtn--display</code></div>
          <div className="card" style={{ display: 'flex', flexWrap: 'wrap', gap: 16, alignItems: 'center' }}>
            <button className="jbtn jbtn--primary jbtn--display">Get JXM</button>
            <button className="jbtn jbtn--outline jbtn--display">Reach Out</button>
            <button className="jbtn jbtn--dark jbtn--display">Book a consult</button>
          </div>

          <div style={{ marginTop: 14 }} className="callout">
            <div className="callout-eyebrow">Label style — when to use which</div>
            <strong>Mono label</strong> (default) is the system/utility voice — small caps Plex Mono, 11px, 0.14em tracked. Use for in-app actions, secondary nav, anything that should read as "interface". <strong>Display label</strong> (<code style={{ fontFamily: 'var(--ff-mono)' }}>.jbtn--display</code>) swaps to Inter sentence-case at 15px — the warmer, brand-led voice. Use for hero CTAs, footer "Reach Out", contact moments, anywhere a user is being invited rather than directed. The pattern is pulled from the footer CTA on getjxm.com. Both label styles can pair with any color variant.
          </div>
          <div style={{ marginTop: 14 }} className="callout">
            <div className="callout-eyebrow">Hover</div>
            <strong>Primary</strong> (Kermit) and <strong>Destructive</strong> (Compassed) both transition to <strong>Gator</strong> on hover. <strong>Outline</strong> picks up a faint Kermit tint plus a Kermit border swap on hover — pulled from the founder-card CTA pattern on getjxm.com. That's the only places Gator and the Kermit hover-tint appear. Hover the rows above to see them.
          </div>
        </section>

        <section>
          <SectionHead label="7.2" title="States · Primary" />
          <div className="grid-4">
            {[
              { l: 'Default',  cls: 'jbtn--primary' },
              { l: 'Hover',    cls: 'jbtn--primary', forceHover: true },
              { l: 'Focus',    cls: 'jbtn--primary', forceFocus: true },
              { l: 'Disabled', cls: 'jbtn--primary', disabled: true },
            ].map((b, i) => (
              <div key={i} className="card" style={{ display: 'flex', flexDirection: 'column', gap: 12, alignItems: 'flex-start' }}>
                <div style={{ fontFamily: 'var(--ff-mono)', fontSize: 10, letterSpacing: '0.18em', textTransform: 'uppercase', color: 'var(--ink-mute)' }}>{b.l}</div>
                <button className={'jbtn ' + b.cls} style={{
                  background: b.forceHover ? 'var(--gator)' : undefined,
                  outline: b.forceFocus ? '2px solid var(--abyss)' : 'none',
                  outlineOffset: b.forceFocus ? 3 : 0,
                  opacity: b.disabled ? 0.4 : 1,
                  cursor: b.disabled ? 'not-allowed' : 'pointer',
                  pointerEvents: 'none',
                }}>Get started</button>
              </div>
            ))}
          </div>
        </section>

        <section>
          <SectionHead label="7.3" title="Sizes" />
          <div className="card" style={{ display: 'flex', gap: 14, alignItems: 'center', flexWrap: 'wrap' }}>
            <button className="jbtn jbtn--primary" style={{ padding: '6px 10px', fontSize: 10 }}>Tiny</button>
            <button className="jbtn jbtn--primary" style={{ padding: '8px 14px', fontSize: 10.5 }}>Small</button>
            <button className="jbtn jbtn--primary">Default</button>
            <button className="jbtn jbtn--primary" style={{ padding: '14px 22px', fontSize: 12 }}>Large</button>
          </div>
        </section>

        <section>
          <SectionHead label="7.4" title="Code" />
          <div className="grid-2">
            <div>
              <div className="code-head"><span>HTML</span><CopyButton text={`<button class="jbtn jbtn--primary">\n  Get started\n</button>\n\n<button class="jbtn jbtn--outline">\n  Learn more\n</button>`} /></div>
              <pre className="code">{`<button class="jbtn jbtn--primary">
  Get started
</button>

<button class="jbtn jbtn--outline">
  Learn more
</button>`}</pre>
            </div>
            <div>
              <div className="code-head"><span>CSS · core</span><CopyButton text={`.jbtn{display:inline-flex;align-items:center;gap:8px;\n  padding:11px 20px;font:11px/1.2 var(--ff-mono);\n  letter-spacing:.14em;text-transform:uppercase;\n  border:none;border-radius:999px;cursor:pointer;\n  transition:background 160ms ease;}\n.jbtn--primary{background:#49E385;color:#221F32;}\n.jbtn--primary:hover{background:#2EB36A;} /* Gator */\n\n.jbtn--outline{background:transparent;color:#221F32;\n  border:1.5px solid #221F32;padding:9.5px 20px;}\n.jbtn--outline:hover{\n  background:color-mix(in srgb,#49E385 15%,transparent);\n  border-color:#49E385;}`} /></div>
              <pre className="code">{`.jbtn { display:inline-flex; align-items:center;
  gap:8px; padding:11px 20px;
  font:11px/1.2 var(--ff-mono);
  letter-spacing:.14em; text-transform:uppercase;
  border:none; border-radius:999px; cursor:pointer;
  transition:background 160ms ease; }
.jbtn--primary { background:#49E385; color:#221F32; }
.jbtn--primary:hover { background:#2EB36A; } /* Gator */

.jbtn--outline { background:transparent; color:#221F32;
  border:1.5px solid #221F32; padding:9.5px 20px; }
.jbtn--outline:hover {
  background: color-mix(in srgb, #49E385 15%, transparent);
  border-color: #49E385; }`}</pre>
            </div>
          </div>
        </section>
      </div>
    </div>
  );
}

/* =========================================================================
   COMPONENTS — FORMS
   ========================================================================= */
function FormsPage() {
  const [v, setV] = useStateVC({ name: '', email: '', org: '' });
  return (
    <div className="page">
      <PageHeader
        eyebrow="07.1 · Components / Forms"
        title="Forms."
        lede="Inputs with hairlines, mono labels, Kermit focus rings. Built for filling out, not decorating."
      />
      <div className="stack">

        <section>
          <div className="callout">
            <div className="callout-eyebrow">Processing — as of May 2026</div>
            The contact form on <a href="https://www.getjxm.com" target="_blank" rel="noopener" style={{ borderBottom: '1px solid currentColor' }}>getjxm.com</a> is processed by <a href="https://formspree.io" target="_blank" rel="noopener" style={{ borderBottom: '1px solid currentColor' }}>Formspree</a>. New forms on JXM properties should default to the same — no custom backend, no third-party dashboards to learn, submissions email through to <a href="mailto:hi@getjxm.com" style={{ borderBottom: '1px solid currentColor' }}>hi@getjxm.com</a>. If a form needs anything Formspree can't do (multi-step, conditional logic, gated downloads), check with Matt before introducing a new tool.
          </div>
        </section>

        <section>
          <SectionHead label="7.1.1" title="Inputs" />
          <div className="card" style={{ maxWidth: 480 }}>
            <FormField label="Your name" hint="As you'd like it written." value={v.name} onChange={x => setV(s => ({ ...s, name: x }))} placeholder="Matt" />
            <FormField label="Email" type="email" value={v.email} onChange={x => setV(s => ({ ...s, email: x }))} placeholder="you@company.com" />
            <FormField label="Organization" value={v.org} onChange={x => setV(s => ({ ...s, org: x }))} placeholder="Optional" optional />
            <FormField label="Project notes" textarea value="" onChange={() => {}} placeholder="Three sentences. What's broken." />
            <button className="jbtn jbtn--primary" style={{ marginTop: 6 }}>Submit →</button>
          </div>
        </section>

        <section>
          <SectionHead label="7.1.2" title="States" />
          <div className="grid-3">
            <FieldState label="Default" />
            <FieldState label="Focus" forceFocus />
            <FieldState label="Error" error="Use a valid email address." />
          </div>
        </section>

      </div>
    </div>
  );
}
function FormField({ label, value, onChange, placeholder, hint, type = 'text', textarea = false, optional = false, error }) {
  return (
    <label style={{ display: 'block', marginBottom: 18 }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 6 }}>
        <span style={{ fontFamily: 'var(--ff-mono)', fontSize: 11, letterSpacing: '0.12em', textTransform: 'uppercase', color: 'var(--ink-soft)' }}>{label}</span>
        {optional && <span style={{ fontFamily: 'var(--ff-mono)', fontSize: 10, letterSpacing: '0.14em', textTransform: 'uppercase', color: 'var(--ink-faint)' }}>optional</span>}
      </div>
      {textarea ? (
        <textarea value={value} onChange={(e) => onChange(e.target.value)} placeholder={placeholder} rows={3}
          style={{
            width: '100%', padding: '10px 12px',
            border: '1px solid var(--line-strong)', borderRadius: 3,
            background: 'transparent', color: 'var(--ink)', fontFamily: 'var(--ff-body)', fontSize: 14, lineHeight: 1.55, resize: 'vertical', outline: 'none',
          }}
          onFocus={(e) => e.currentTarget.style.borderColor = 'var(--accent)'}
          onBlur={(e) => e.currentTarget.style.borderColor = error ? 'var(--compassed)' : 'var(--line-strong)'}
        />
      ) : (
        <input type={type} value={value} onChange={(e) => onChange(e.target.value)} placeholder={placeholder}
          style={{
            width: '100%', padding: '10px 12px',
            border: `1px solid ${error ? 'var(--compassed)' : 'var(--line-strong)'}`, borderRadius: 3,
            background: 'transparent', color: 'var(--ink)', fontFamily: 'var(--ff-body)', fontSize: 14, outline: 'none',
          }}
          onFocus={(e) => e.currentTarget.style.borderColor = 'var(--accent)'}
          onBlur={(e) => e.currentTarget.style.borderColor = error ? 'var(--compassed)' : 'var(--line-strong)'}
        />
      )}
      {hint && !error && <div style={{ fontFamily: 'var(--ff-body)', fontSize: 12, color: 'var(--ink-mute)', marginTop: 5 }}>{hint}</div>}
      {error && <div style={{ fontFamily: 'var(--ff-body)', fontSize: 12, color: 'var(--compassed)', marginTop: 5 }}>{error}</div>}
    </label>
  );
}
function FieldState({ label, forceFocus, error }) {
  return (
    <div className="card">
      <div style={{ fontFamily: 'var(--ff-mono)', fontSize: 10, letterSpacing: '0.18em', textTransform: 'uppercase', color: 'var(--ink-mute)', marginBottom: 10 }}>{label}</div>
      <div style={{ fontFamily: 'var(--ff-mono)', fontSize: 11, letterSpacing: '0.12em', textTransform: 'uppercase', color: 'var(--ink-soft)', marginBottom: 6 }}>Email</div>
      <input value="you@company.com" readOnly style={{
        width: '100%', padding: '10px 12px',
        border: `1px solid ${error ? 'var(--compassed)' : forceFocus ? 'var(--accent)' : 'var(--line-strong)'}`,
        borderRadius: 3, background: 'transparent', color: 'var(--ink)',
        fontFamily: 'var(--ff-body)', fontSize: 14, outline: 'none',
        boxShadow: forceFocus ? '0 0 0 3px color-mix(in srgb, var(--accent) 30%, transparent)' : 'none',
      }} />
      {error && <div style={{ fontFamily: 'var(--ff-body)', fontSize: 12, color: 'var(--compassed)', marginTop: 5 }}>{error}</div>}
    </div>
  );
}

/* =========================================================================
   COMPONENTS — CARDS & NAV
   ========================================================================= */
function CardsPage() {
  const Glyph = window.Glyph;
  return (
    <div className="page">
      <PageHeader
        eyebrow="07.2 · Components / Cards & nav"
        title="Cards & navigation."
        lede="Hairline cards on the page tone. Mono eyebrows, display titles, body for the rest. Don't add shadows by default."
      />
      <div className="stack">

        <section>
          <SectionHead label="7.2.1" title="Default card" />
          <div className="grid-3">
            <div className="card">
              <div style={{ fontFamily: 'var(--ff-mono)', fontSize: 10, letterSpacing: '0.18em', textTransform: 'uppercase', color: 'var(--accent)', marginBottom: 10 }}>Outcome</div>
              <div style={{ fontFamily: 'var(--ff-display)', fontWeight: 500, fontSize: 18, marginBottom: 8, letterSpacing: '-0.01em' }}>Pipeline doubled in 90 days.</div>
              <p style={{ fontFamily: 'var(--ff-body)', fontSize: 13, color: 'var(--ink-mute)', lineHeight: 1.55 }}>Series B SaaS, two-quarter engagement. Strategy → execution → ship.</p>
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginTop: 14 }}>
                <span style={{ fontFamily: 'var(--ff-mono)', fontSize: 10, color: 'var(--ink-mute)', letterSpacing: '0.14em', textTransform: 'uppercase' }}>Case · 04 min</span>
                <Glyph name="arr" size={14} stroke="var(--ink-mute)" />
              </div>
            </div>
            <div className="card" style={{ background: 'var(--abyss)', color: 'var(--tusk)', borderColor: 'transparent' }}>
              <div style={{ fontFamily: 'var(--ff-mono)', fontSize: 10, letterSpacing: '0.18em', textTransform: 'uppercase', color: 'var(--accent)', marginBottom: 10 }}>Feature</div>
              <div style={{ fontFamily: 'var(--ff-display)', fontWeight: 500, fontSize: 18, marginBottom: 8, letterSpacing: '-0.01em' }}>Three concepts, with conviction.</div>
              <p style={{ fontFamily: 'var(--ff-body)', fontSize: 13, color: 'rgba(247,242,235,0.7)', lineHeight: 1.55 }}>The deliverables you'll see, the calls you'll have, the way we work.</p>
              <button className="jbtn jbtn--primary" style={{ marginTop: 14 }}>Read more <Glyph name="arr" size={12} stroke="currentColor" /></button>
            </div>
            <div className="card" style={{ background: 'color-mix(in srgb, var(--accent) 10%, transparent)', borderColor: 'color-mix(in srgb, var(--accent) 40%, transparent)' }}>
              <div style={{ fontFamily: 'var(--ff-mono)', fontSize: 10, letterSpacing: '0.18em', textTransform: 'uppercase', color: 'var(--accent-ink)', marginBottom: 10 }}>Tint variant</div>
              <div style={{ fontFamily: 'var(--ff-display)', fontWeight: 500, fontSize: 18, marginBottom: 8, letterSpacing: '-0.01em' }}>For highlight rows.</div>
              <p style={{ fontFamily: 'var(--ff-body)', fontSize: 13, color: 'var(--ink-soft)', lineHeight: 1.55 }}>Use sparingly — once per page is plenty.</p>
            </div>
          </div>
        </section>

        <section>
          <SectionHead label="7.2.2" title="Tabs" />
          <div className="card" style={{ padding: 0 }}>
            <div style={{ display: 'flex', borderBottom: '1px solid var(--line)' }}>
              {['Overview', 'Strategy', 'Execution', 'Outcomes'].map((t, i) => (
                <div key={t} style={{
                  padding: '14px 22px', fontFamily: 'var(--ff-mono)', fontSize: 11, letterSpacing: '0.14em', textTransform: 'uppercase',
                  borderBottom: i === 0 ? '2px solid var(--accent)' : '2px solid transparent',
                  color: i === 0 ? 'var(--ink)' : 'var(--ink-mute)',
                  marginBottom: -1, cursor: 'pointer',
                }}>{t}</div>
              ))}
            </div>
            <div style={{ padding: 22, fontFamily: 'var(--ff-body)', fontSize: 14, color: 'var(--ink-soft)' }}>
              Tab content uses the same scale as the parent. Don't nest a second tab row — flatten the IA.
            </div>
          </div>
        </section>

        <section>
          <SectionHead label="7.2.3" title="Badge & pill" />
          <div className="card" style={{ display: 'flex', flexWrap: 'wrap', gap: 8, alignItems: 'center' }}>
            <span style={{ fontFamily: 'var(--ff-mono)', fontSize: 10, letterSpacing: '0.14em', textTransform: 'uppercase', padding: '3px 8px', borderRadius: 2, background: 'var(--accent)', color: 'var(--accent-ink)' }}>New</span>
            <span style={{ fontFamily: 'var(--ff-mono)', fontSize: 10, letterSpacing: '0.14em', textTransform: 'uppercase', padding: '3px 8px', borderRadius: 2, background: 'var(--abyss)', color: 'var(--accent)' }}>AI</span>
            <span style={{ fontFamily: 'var(--ff-mono)', fontSize: 10, letterSpacing: '0.14em', textTransform: 'uppercase', padding: '3px 8px', borderRadius: 2, background: 'var(--compassed)', color: '#fff' }}>Restricted</span>
            <span style={{ fontFamily: 'var(--ff-mono)', fontSize: 11, letterSpacing: '0.04em', padding: '6px 12px', borderRadius: 999, border: '1px solid var(--line-strong)', color: 'var(--ink-soft)' }}>Strategy</span>
            <span style={{ fontFamily: 'var(--ff-mono)', fontSize: 11, letterSpacing: '0.04em', padding: '6px 12px', borderRadius: 999, border: '1px solid var(--line-strong)', color: 'var(--ink-soft)' }}>Execution</span>
            <span style={{ fontFamily: 'var(--ff-mono)', fontSize: 11, letterSpacing: '0.04em', padding: '6px 12px', borderRadius: 999, background: 'var(--accent)', color: 'var(--accent-ink)' }}>Outcomes</span>
          </div>
        </section>

      </div>
    </div>
  );
}

/* =========================================================================
   COMPONENTS — EMAIL SIGNATURE
   ========================================================================= */
function EmailSigPage() {
  const SIG_HTML = `<table cellpadding="0" cellspacing="0" border="0" role="presentation" style="border-collapse:collapse; max-width:540px; width:100%;">
  <tr>
    <td style="border-top:1px solid #221F32; padding-top:14px;">
      <p style="margin:0; font-family:'DM Sans','Helvetica Neue',Helvetica,Arial,sans-serif; font-size:16px; line-height:1.95; color:#221F32; -webkit-text-size-adjust:100%; mso-line-height-rule:exactly;">
        I&rsquo;m from
        <a href="https://www.getjxm.com" style="display:inline-block; background-color:transparent; color:#221F32; padding:2px 12px 3px; border:1px solid #221F32; border-radius:999px; line-height:1.3; white-space:nowrap; text-decoration:none;"><span style="color:#221F32;">an agency called JXM.</span></a>
        We help mission-driven brands grow with our
        <a href="https://www.getjxm.com/services" style="display:inline-block; background-color:transparent; color:#221F32; padding:2px 12px 3px; border:1px solid #221F32; border-radius:999px; line-height:1.3; white-space:nowrap; text-decoration:none;"><span style="color:#221F32;">strategies and campaigns.</span></a>
        If that piques your curiosity, we should totally
        <a href="https://www.getjxm.com/contact" style="display:inline-block; background-color:transparent; color:#221F32; padding:2px 12px 3px; border:1px solid #221F32; border-radius:999px; line-height:1.3; white-space:nowrap; text-decoration:none;"><span style="color:#221F32;">meet up sometime.</span></a>
      </p>
    </td>
  </tr>
</table>`;

  const SIG_PLAIN = `I'm from "an agency called JXM" (https://www.getjxm.com). We help mission-driven brands grow with our "strategies and campaigns" (https://www.getjxm.com/services). If that piques your curiosity, we should totally "meet up sometime" (https://www.getjxm.com/contact).`;

  const installs = [
    {
      tag: 'Gmail (web)',
      steps: [
        'Settings (gear icon) → See all settings → General tab.',
        'Scroll to "Signature" → Create new → name it "JXM 2026".',
        'Click into the editor field → ⌘V to paste the rendered preview from this page.',
        'Set "Signature defaults" for new emails and reply/forward.',
        'Save Changes (bottom of page — easy to miss).',
      ],
    },
    {
      tag: 'Outlook on Mac',
      steps: [
        'Outlook menu → Settings → Signatures → +.',
        'Paste the rendered preview into the editor.',
        'Set as default for new messages and replies.',
      ],
    },
    {
      tag: 'Outlook on Windows',
      steps: [
        'File → Options → Mail → Signatures → New.',
        'Paste into the editor. Save.',
        'Or, for full HTML control, edit the .htm file at C:\\Users\\<you>\\AppData\\Roaming\\Microsoft\\Signatures\\.',
      ],
    },
    {
      tag: 'Apple Mail (macOS)',
      steps: [
        'Mail → Settings → Signatures → +.',
        'Paste the rendered preview.',
        'Uncheck "Always match my default message font" (otherwise it’ll squash the fonts).',
      ],
    },
    {
      tag: 'Apple Mail (iOS)',
      steps: [
        'Settings → Mail → Signature.',
        'iOS strips most HTML — paste the plain-text fallback (§8.3.3) instead.',
      ],
    },
  ];

  return (
    <div className="page">
      <PageHeader
        eyebrow="08.3 · Components / Email signature"
        title="Sign off, on brand."
        lede="The official JXM email signature. Render the preview, copy, paste into your client of choice, send."
      />
      <div className="stack">

        <section>
          <SectionHead label="8.3.1" title="Preview" meta="Live render" />
          <div style={{ background: 'white', padding: 36, border: '1px solid var(--line)', borderRadius: 6 }}
               dangerouslySetInnerHTML={{ __html: SIG_HTML }} />
          <p className="prose" style={{ marginTop: 14, fontSize: 13, color: 'var(--ink-mute)' }}>
            To install: drag-select the rendered signature above (start at “I’m from”, end after “meet up sometime.”), ⌘C, then paste into your email client’s signature editor. Browser-clipboard handoff preserves links and inline styles better than pasting raw HTML.
          </p>
        </section>

        <section>
          <SectionHead label="8.3.2" title="HTML source" meta="Paste-ready" />
          <div>
            <div className="code-head"><span><span className="lang">html</span> · signature</span><CopyButton text={SIG_HTML} /></div>
            <pre className="code" style={{ maxHeight: 320, overflow: 'auto', whiteSpace: 'pre-wrap' }}>{SIG_HTML}</pre>
          </div>
        </section>

        <section>
          <SectionHead label="8.3.3" title="Plain-text fallback" meta="For HTML-stripped clients" />
          <div>
            <div className="code-head"><span><span className="lang">text</span> · fallback</span><CopyButton text={SIG_PLAIN} /></div>
            <pre className="code" style={{ whiteSpace: 'pre-wrap' }}>{SIG_PLAIN}</pre>
          </div>
        </section>

        <section>
          <SectionHead label="8.3.4" title="Install per client" />
          <div className="grid-2">
            {installs.map((c, i) => (
              <div key={i} className="card">
                <div style={{ fontFamily: 'var(--ff-mono)', fontSize: 10, letterSpacing: '0.18em', textTransform: 'uppercase', color: 'var(--accent-ink)', marginBottom: 12 }}>{c.tag}</div>
                <ol style={{ margin: 0, paddingLeft: 20, fontFamily: 'var(--ff-body)', fontSize: 13.5, lineHeight: 1.6, color: 'var(--ink-soft)' }}>
                  {c.steps.map((s, j) => <li key={j} style={{ marginBottom: 6 }}>{s}</li>)}
                </ol>
              </div>
            ))}
          </div>
        </section>

        <section>
          <SectionHead label="8.3.5" title="Compatibility" meta="What renders where" />
          <div className="callout">
            <div className="callout-eyebrow">Universal</div>
            Hairline divider, outlined chips, and links render correctly in Gmail (web + iOS + Android), Apple Mail (macOS + iOS), Outlook on Mac, Outlook.com web, and Yahoo / AOL. No background panel means the signature adapts cleanly to whatever the client paints behind it — including dark mode.
          </div>
          <div className="callout callout--warn" style={{ marginTop: 14 }}>
            <div className="callout-eyebrow">Outlook on Windows desktop</div>
            Uses Word’s HTML rendering engine. The hairline divider renders. Chip outlines render as squared rectangles instead of rounded pills — same 1px Abyss stroke, same padding, links still active. Acceptable degradation; no inline workaround for that engine.
          </div>
          <div className="callout" style={{ marginTop: 14 }}>
            <div className="callout-eyebrow">Fonts</div>
            DM Sans isn’t bundled. Web Gmail loads it only if the recipient has it locally; otherwise the stack falls back to Helvetica Neue → Helvetica → Arial. Outlook desktop ignores web fonts and uses Calibri or the user’s default. The visual character holds across all of them.
          </div>
        </section>

      </div>
    </div>
  );
}

window.VoicePage = VoicePage;
window.SnippetsPage = SnippetsPage;
window.ButtonsPage = ButtonsPage;
window.FormsPage = FormsPage;
window.CardsPage = CardsPage;
window.EmailSigPage = EmailSigPage;
