/* Design System / Storybook — a single page that exports every atomic component
   with its variants and states. Lives at /system. Lifts the "reverse-engineer from
   screens" burden off engineering. */

const SECTIONS = [
  { id: "tokens", label: "Tokens" },
  { id: "type", label: "Typography" },
  { id: "color", label: "Color" },
  { id: "buttons", label: "Buttons" },
  { id: "badges", label: "Badges & verdicts" },
  { id: "hash", label: "Hash chips" },
  { id: "fields", label: "Form fields" },
  { id: "cards", label: "Cards" },
  { id: "tables", label: "Tables" },
  { id: "feedback", label: "Feedback" },
  { id: "states", label: "Empty · loading · denied" },
  { id: "patterns", label: "Patterns" },
];

const DesignSystem = ({ pushToast }) => {
  const [section, setSection] = React.useState("tokens");

  return (
    <>
      <header className="page-header">
        <div className="page-header__inner">
          <div className="page-header__eyebrow">Handoff · v1.0 · 2026-10-24</div>
          <h1>Design system</h1>
          <p className="page-header__sub">
            Every atom in one place. Variants, states, props, and accessibility notes for engineers and contributors.
            Tokens are CSS custom properties — copy into any framework.
          </p>
        </div>
        <div className="page-actions">
          <Button variant="secondary" size="sm" icon={window.Icon.download({ size: 13 })}>Download tokens.json</Button>
          <Button variant="primary" size="sm" icon={window.Icon.external({ size: 13 })}>Open in Storybook</Button>
        </div>
      </header>

      <div className="ds-layout">
        <nav className="ds-nav">
          {SECTIONS.map((s) => (
            <button key={s.id} className={`ds-nav__item ${section === s.id ? "ds-nav__item--active" : ""}`} onClick={() => setSection(s.id)}>
              <span className="ds-nav__num mono">{String(SECTIONS.indexOf(s) + 1).padStart(2, "0")}</span>
              <span>{s.label}</span>
            </button>
          ))}
        </nav>

        <div className="ds-body">
          {section === "tokens" && <DSTokens />}
          {section === "type" && <DSType />}
          {section === "color" && <DSColor />}
          {section === "buttons" && <DSButtons pushToast={pushToast} />}
          {section === "badges" && <DSBadges />}
          {section === "hash" && <DSHash pushToast={pushToast} />}
          {section === "fields" && <DSFields />}
          {section === "cards" && <DSCards />}
          {section === "tables" && <DSTables />}
          {section === "feedback" && <DSFeedback pushToast={pushToast} />}
          {section === "states" && <DSStates />}
          {section === "patterns" && <DSPatterns />}
        </div>
      </div>
    </>
  );
};

/* ---- Section: Tokens ---- */
const DSTokens = () => (
  <div className="col gap-6">
    <DSBlock title="Spacing scale" desc="8pt grid, multiples of 4. Use --space-1 through --space-10 via CSS vars.">
      <div className="token-row">
        {[1,2,3,4,5,6,7,8,9,10].map((n) => (
          <div key={n} className="space-tok">
            <div className="space-tok__bar" style={{ width: [4,8,12,16,20,24,32,40,48,64][n-1] }} />
            <div className="mono text-xs">--space-{n}</div>
            <div className="mono text-xs muted">{[4,8,12,16,20,24,32,40,48,64][n-1]}px</div>
          </div>
        ))}
      </div>
    </DSBlock>

    <DSBlock title="Radii" desc="Used sparingly. Sharp corners feel auditable; rounded corners feel friendly.">
      <div className="token-row">
        {[
          { name: "sm", v: "3px" }, { name: "md", v: "5px" }, { name: "lg", v: "7px" }, { name: "xl", v: "10px" }, { name: "pill", v: "9999px" },
        ].map((r) => (
          <div key={r.name} className="radius-tok">
            <div className="radius-tok__shape" style={{ borderRadius: r.v }} />
            <div className="mono text-xs">--radius-{r.name}</div>
            <div className="mono text-xs muted">{r.v}</div>
          </div>
        ))}
      </div>
    </DSBlock>

    <DSBlock title="Shadows" desc="Near-flat. Real depth only on modals + drawers. Layered offsets, not blurred halos.">
      <div className="token-row">
        {[{ name: "sm" }, { name: "md" }, { name: "lg" }, { name: "xl" }].map((s) => (
          <div key={s.name} className="shadow-tok">
            <div className="shadow-tok__box" style={{ boxShadow: `var(--shadow-${s.name})` }} />
            <div className="mono text-xs">--shadow-{s.name}</div>
          </div>
        ))}
      </div>
    </DSBlock>

    <DSBlock title="Motion" desc="Trust signals never animate. Page transitions are 200ms ease-out by default.">
      <div className="motion-grid">
        {[
          { name: "instant", v: "0ms" }, { name: "fast", v: "100ms" }, { name: "base", v: "200ms" }, { name: "slow", v: "400ms" },
        ].map((m) => (
          <div key={m.name} className="motion-tok">
            <div className="mono text-sm fw-600">--motion-{m.name}</div>
            <div className="mono text-xs muted">{m.v}</div>
          </div>
        ))}
      </div>
    </DSBlock>
  </div>
);

/* ---- Section: Typography ---- */
const DSType = () => (
  <div className="col gap-6">
    <DSBlock title="Font stacks" desc="Geist for UI, IBM Plex / Geist Mono for hashes and code, Instrument Serif italic for editorial display moments.">
      <div className="type-stacks">
        <div className="type-stack">
          <div className="muted text-xs mono">--font-sans</div>
          <div style={{ fontSize: 22, fontWeight: 400, marginTop: 4 }}>Geist · sans · 400/500/600/700</div>
          <div className="muted text-xs" style={{ marginTop: 4 }}>The quick brown fox · 0123456789 · Cohen's κ</div>
        </div>
        <div className="type-stack">
          <div className="muted text-xs mono">--font-display</div>
          <div style={{ fontSize: 28, fontStyle: "italic", fontFamily: "Instrument Serif, serif", marginTop: 4 }}>Instrument Serif · italic</div>
          <div className="muted text-xs" style={{ marginTop: 4 }}>Page titles · hero numbers · "moment" headings</div>
        </div>
        <div className="type-stack">
          <div className="muted text-xs mono">--font-mono</div>
          <div className="mono" style={{ fontSize: 18, marginTop: 4 }}>Geist Mono · 0xa3b9c4d2…</div>
          <div className="muted text-xs" style={{ marginTop: 4 }}>Hashes · keys · labels · code blocks</div>
        </div>
      </div>
    </DSBlock>

    <DSBlock title="Scale" desc="Editorial display + tight UI body. Tabular numerals where they appear in tables.">
      <div className="scale-rows">
        {[
          { name: "display-2xl", size: 72, fam: "serif", style: "italic", text: "Built for proof, not promises." },
          { name: "display-xl", size: 56, fam: "serif", style: "italic", text: "Verify Trace af_x3k…7yv" },
          { name: "h1", size: 48, fam: "serif", style: "italic", text: "Dashboard" },
          { name: "h2", size: 32, fam: "serif", style: "italic", text: "Verification" },
          { name: "h3", size: 18, fam: "sans", style: "normal", text: "Section title", weight: 600 },
          { name: "body", size: 13.5, fam: "sans", text: "Default UI body — claims, descriptions, modal content." },
          { name: "caption", size: 11.5, fam: "sans", text: "Metadata, timestamps, helper hints." },
          { name: "mono", size: 12.5, fam: "mono", text: "0xa3b9c4d27f201e8b · Block #1247 · purpose=\"discharge_summary\"" },
        ].map((row) => (
          <div key={row.name} className="scale-row">
            <div className="scale-row__label mono">{row.name} · {row.size}px</div>
            <div style={{
              fontSize: row.size,
              fontFamily: row.fam === "serif" ? "var(--font-display)" : row.fam === "mono" ? "var(--font-mono)" : "var(--font-sans)",
              fontStyle: row.style || "normal",
              fontWeight: row.weight || 400,
              letterSpacing: row.size > 32 ? "-0.03em" : "-0.005em",
              lineHeight: 1.15,
              color: "var(--ink-1)",
            }}>{row.text}</div>
          </div>
        ))}
      </div>
    </DSBlock>
  </div>
);

/* ---- Section: Color ---- */
const DSColor = () => (
  <div className="col gap-6">
    <DSBlock title="Trust spine" desc="Near-monochrome with warm undertones. Ink + paper define everything else.">
      <div className="color-grid">
        {[
          { name: "ink-1", hex: "#18181b", use: "Primary text · CTA bg" },
          { name: "ink-2", hex: "#3f3f46", use: "Body text" },
          { name: "ink-3", hex: "#71717a", use: "Secondary text" },
          { name: "ink-4", hex: "#a1a1aa", use: "Hint / placeholder" },
          { name: "paper", hex: "#ffffff", use: "Base surface" },
          { name: "paper-alt", hex: "#fafaf9", use: "Page background" },
          { name: "paper-shadow", hex: "#f4f4f2", use: "Recessed surface" },
          { name: "rule", hex: "#ebe9e4", use: "Hairline borders" },
        ].map((c) => <ColorChip key={c.name} {...c} />)}
      </div>
    </DSBlock>

    <DSBlock title="Verdict palette" desc="Functional only. Always paired with icon and text label. Backgrounds use the --soft variants.">
      <div className="color-grid">
        <ColorChip name="verified" hex="#2f6e47" use="Verified state · Active badges" />
        <ColorChip name="verified-soft" hex="#eaf2ec" use="Verified background tint" />
        <ColorChip name="partial" hex="#9a6418" use="Partial · warnings · in-review" />
        <ColorChip name="partial-soft" hex="#f6efdf" use="Partial background tint" />
        <ColorChip name="contra" hex="#9b2c2c" use="Contradicted · destructive · revoked" />
        <ColorChip name="contra-soft" hex="#f6e7e6" use="Contradicted background tint" />
        <ColorChip name="unverif" hex="#71717a" use="Unverifiable" />
        <ColorChip name="unverif-soft" hex="#f4f4f2" use="Unverifiable background tint" />
      </div>
    </DSBlock>

    <DSBlock title="Contrast" desc="WCAG 2.2 AA verified for every text-on-background pair. Hint color (--ink-4) is allowed at ≥18px only.">
      <table className="table" style={{ marginTop: 8 }}>
        <thead><tr><th>Pair</th><th>Ratio</th><th>Use</th><th>Pass</th></tr></thead>
        <tbody>
          <tr><td className="mono">ink-1 on paper</td><td className="mono tabular">18.6 : 1</td><td>Body text</td><td><Badge tone="sealed">AAA</Badge></td></tr>
          <tr><td className="mono">ink-2 on paper</td><td className="mono tabular">12.3 : 1</td><td>Headers</td><td><Badge tone="sealed">AAA</Badge></td></tr>
          <tr><td className="mono">ink-3 on paper</td><td className="mono tabular">5.4 : 1</td><td>Secondary text</td><td><Badge tone="sealed">AA</Badge></td></tr>
          <tr><td className="mono">ink-4 on paper</td><td className="mono tabular">3.1 : 1</td><td>Hints (≥18px)</td><td><Badge tone="partial">AA-large</Badge></td></tr>
          <tr><td className="mono">verified on verified-soft</td><td className="mono tabular">5.8 : 1</td><td>Verdict badges</td><td><Badge tone="sealed">AA</Badge></td></tr>
        </tbody>
      </table>
    </DSBlock>
  </div>
);

const ColorChip = ({ name, hex, use }) => (
  <div className="color-chip">
    <div className="color-chip__swatch" style={{ background: hex, border: hex === "#ffffff" ? "1px solid var(--rule)" : "none" }} />
    <div className="color-chip__body">
      <div className="mono fw-600 text-sm">--{name}</div>
      <div className="mono text-xs muted">{hex}</div>
      <div className="text-xs muted" style={{ marginTop: 4 }}>{use}</div>
    </div>
  </div>
);

/* ---- Section: Buttons ---- */
const DSButtons = ({ pushToast }) => (
  <div className="col gap-6">
    <DSBlock title="Variants" desc="Primary uses ink-1. Destructive only for type-to-confirm actions. Link for inline navigation only.">
      <div className="ds-row">
        <Button variant="primary">Primary</Button>
        <Button variant="secondary">Secondary</Button>
        <Button variant="ghost">Ghost</Button>
        <Button variant="destructive">Destructive</Button>
        <Button variant="success">Success</Button>
        <Button variant="link">Link action</Button>
      </div>
      <Code>{`<Button variant="primary | secondary | ghost | destructive | success | link" />`}</Code>
    </DSBlock>

    <DSBlock title="Sizes">
      <div className="ds-row">
        <Button variant="primary" size="sm">Small · 32px</Button>
        <Button variant="primary">Default · 40px</Button>
        <Button variant="primary" size="lg">Large · 44px</Button>
      </div>
    </DSBlock>

    <DSBlock title="With icons">
      <div className="ds-row">
        <Button variant="primary" icon={window.Icon.plus({ size: 13 })}>New key</Button>
        <Button variant="secondary" iconRight={window.Icon.arrowRight({ size: 13 })}>Continue</Button>
        <Button variant="ghost" icon={window.Icon.copy({ size: 13 })}>Copy</Button>
        <Button variant="destructive" icon={window.Icon.xCircle({ size: 13 })}>Revoke</Button>
      </div>
    </DSBlock>

    <DSBlock title="States">
      <div className="ds-row">
        <Button variant="primary">Default</Button>
        <Button variant="primary" disabled>Disabled</Button>
        <Button variant="primary" onClick={() => pushToast({ kind: "info", title: "Pressed" })}>Click me</Button>
      </div>
    </DSBlock>
  </div>
);

/* ---- Section: Badges & verdicts ---- */
const DSBadges = () => (
  <div className="col gap-6">
    <DSBlock title="Verdict badges" desc="Mandatory pairing of color + icon + text. Never use color alone. Used for trace verdicts, evidence pack mixes, judge votes.">
      <div className="ds-row">
        <Verdict kind="verified" />
        <Verdict kind="partial" />
        <Verdict kind="unverif" />
        <Verdict kind="contra" />
      </div>
      <div className="ds-row" style={{ marginTop: 8 }}>
        <Verdict kind="verified" size="lg" />
        <Verdict kind="partial" size="lg" />
        <Verdict kind="unverif" size="lg" />
        <Verdict kind="contra" size="lg" />
      </div>
      <Code>{`<Verdict kind="verified | partial | unverif | contra" size="lg?" />`}</Code>
    </DSBlock>

    <DSBlock title="Status badges" desc="Non-verdict states: active resources, info chips, pending generation.">
      <div className="ds-row">
        <Badge tone="sealed" icon={window.Icon.checkSimple({ size: 11 })}>Sealed</Badge>
        <Badge tone="pending">Generating</Badge>
        <Badge tone="info">Beta</Badge>
        <Badge tone="neutral">Archived</Badge>
        <Badge tone="partial" icon={window.Icon.warning({ size: 11 })}>Watch</Badge>
        <Badge tone="contra" icon={window.Icon.xCircle({ size: 11 })}>Revoked</Badge>
      </div>
    </DSBlock>
  </div>
);

/* ---- Section: Hash chips ---- */
const DSHash = ({ pushToast }) => (
  <div className="col gap-6">
    <DSBlock title="Hash chip" desc="The single most-used compliance atom. Mono font, copy button, full value on hover. Never display a truncated hash without a way to reveal the full value.">
      <div className="ds-row">
        <HashChip value="0xa3b9c4d27f201e8b9c4d27f201" short="0xa3b9c4d2…7f201" />
        <HashChip value="af_live_x3k2qz9a8mn4lp2rt7yv" short="af_live_x3k…rt7yv" />
        <HashChip value="sha256:7e2104b3f9aa…2d" short="sha256:7e2…2d" />
      </div>
      <Code>{`<HashChip value="<full>" short="<displayed>" onCopy={fn?} />`}</Code>
    </DSBlock>

    <DSBlock title="Inline mono" desc="When you want the value without a chip — e.g. inside body copy or metadata strips.">
      <p className="text-sm" style={{ lineHeight: 1.7 }}>
        Trace <span className="mono">af_x3k…7yv</span> sealed at <span className="mono">10:34:01.342 UTC</span> · root <span className="mono">af3c…91</span>, anchored to bulletin <span className="mono">2026-10-24</span>.
      </p>
    </DSBlock>
  </div>
);

/* ---- Section: Form fields ---- */
const DSFields = () => (
  <div className="col gap-6">
    <DSBlock title="Input" desc="Label-above, hint-below. Hint becomes error on validation. Required indicator is a red asterisk in --contra.">
      <div className="ds-grid">
        <Field label="Default" hint="Helper text"><input className="input" placeholder="placeholder" /></Field>
        <Field label="Required" required><input className="input" defaultValue="value" /></Field>
        <Field label="Error" error="Please enter a complete email address."><input className="input" defaultValue="priya@" style={{ borderColor: "var(--contra)" }} /></Field>
        <Field label="Disabled" hint="Cannot edit"><input className="input" disabled defaultValue="locked" /></Field>
        <Field label="Mono input" hint="For hashes, keys, IDs"><input className="input mono" defaultValue="af_x3k2qz9a8" /></Field>
        <Field label="Textarea"><textarea className="textarea" rows="3" placeholder="Multi-line" /></Field>
      </div>
    </DSBlock>

    <DSBlock title="Radio cards" desc="Used for compliance presets, share-link expiry, etc. Single-select with prominent visual feedback.">
      <div className="radio-row">
        <RadioCard selected title="7 days" sub="Recommended" />
        <RadioCard title="14 days" sub="Standard" />
        <RadioCard title="30 days" sub="Maximum" />
      </div>
    </DSBlock>

    <DSBlock title="Segmented controls" desc="Used for density, tabs-in-toolbar, view switchers.">
      <div className="ds-row">
        <div className="segmented">
          <button className="active">Comfortable</button>
          <button>Compact</button>
        </div>
        <div className="segmented">
          <button>All</button>
          <button className="active">Verified</button>
          <button>Partial</button>
          <button>Contradicted</button>
        </div>
      </div>
    </DSBlock>
  </div>
);

/* ---- Section: Cards ---- */
const DSCards = () => (
  <div className="col gap-6">
    <DSBlock title="Card" desc="Hairline border, near-flat shadow. Header is mono caps; body uses sans. Footer for actions.">
      <div className="ds-grid">
        <Card title="Default card" meta="With meta">
          <p className="text-sm muted">Body content goes here.</p>
        </Card>
        <Card title="With action" action={<Button variant="link" size="sm">View all →</Button>}>
          <p className="text-sm muted">A linked action sits in the header.</p>
        </Card>
      </div>
    </DSBlock>

    <DSBlock title="Trust seal" desc="The signature visual moment. Wax-seal SVG + Ed25519 metadata. Never animates — trust is quiet.">
      <div className="evidence-seal" style={{ margin: 0, maxWidth: 720 }}>
        <div className="evidence-seal__layout">
          <div className="evidence-seal__mark">
            <svg width="88" height="88" viewBox="0 0 88 88">
              <defs>
                <path id="ds-top" d="M 8 44 A 36 36 0 0 1 80 44" />
                <path id="ds-bot" d="M 8 44 A 36 36 0 0 0 80 44" />
              </defs>
              <circle cx="44" cy="44" r="42" fill="none" stroke="#2f6e47" strokeWidth="1" opacity="0.5" />
              <circle cx="44" cy="44" r="36" fill="none" stroke="#2f6e47" strokeWidth="1.5" />
              <circle cx="44" cy="44" r="34" fill="none" stroke="#2f6e47" strokeWidth="0.5" strokeDasharray="1 2" opacity="0.6" />
              <text fontFamily="Geist Mono, monospace" fontSize="6.5" fill="#2f6e47" letterSpacing="2">
                <textPath href="#ds-top" startOffset="50%" textAnchor="middle">ATTESTIA · EVIDENCE · ED25519</textPath>
              </text>
              <text fontFamily="Geist Mono, monospace" fontSize="6.5" fill="#2f6e47" letterSpacing="2">
                <textPath href="#ds-bot" startOffset="50%" textAnchor="middle">· BLOCK 1247 · LEAF 23 ·</textPath>
              </text>
              <text x="44" y="42" textAnchor="middle" fontFamily="Instrument Serif, serif" fontStyle="italic" fontSize="22" fill="#2f6e47">A</text>
              <line x1="32" y1="50" x2="56" y2="50" stroke="#2f6e47" strokeWidth="0.5" />
              <text x="44" y="60" textAnchor="middle" fontFamily="Geist Mono, monospace" fontSize="4.5" fill="#2f6e47" letterSpacing="0.5">SEALED</text>
            </svg>
          </div>
          <div className="evidence-seal__content">
            <div className="evidence-seal__head-row">
              <span className="evidence-seal__title">Sealed evidence</span>
              <span className="evidence-seal__head-meta">Ed25519</span>
            </div>
            <div className="evidence-seal__rows">
              <div className="evidence-row">
                <span className="evidence-row__label">Hash</span>
                <span className="evidence-row__value"><HashChip value="0xa3b9c4d27f201" short="0xa3b9…7f201" /></span>
              </div>
              <div className="evidence-row">
                <span className="evidence-row__label">Bulletin</span>
                <span className="evidence-row__value"><Badge tone="verified" icon={window.Icon.checkSimple({ size: 11 })}>Verified</Badge></span>
              </div>
            </div>
          </div>
        </div>
      </div>
    </DSBlock>
  </div>
);

/* ---- Section: Tables ---- */
const DSTables = () => (
  <div className="col gap-6">
    <DSBlock title="Table" desc="Mono uppercase headers, hairline rows, hover state, tabular numerals on numeric columns, clickable rows go to detail.">
      <Card padded={false}>
        <table className="table">
          <thead><tr><th>Time</th><th>Trace</th><th>Verdict</th><th style={{ textAlign: "right" }}>Cost</th></tr></thead>
          <tbody>
            {SCENARIO.recentTraces.slice(0, 4).map((t, i) => (
              <tr key={i} className="clickable">
                <td className="mono text-sm muted">{t.time}</td>
                <td><HashChip value={t.id} short={t.id} /></td>
                <td><Verdict kind={t.verdict === "contradicted" ? "contra" : t.verdict} /></td>
                <td className="mono tabular text-sm" style={{ textAlign: "right" }}>{t.cost}</td>
              </tr>
            ))}
          </tbody>
        </table>
      </Card>
    </DSBlock>
  </div>
);

/* ---- Section: Feedback ---- */
const DSFeedback = ({ pushToast }) => (
  <div className="col gap-6">
    <DSBlock title="Toast" desc="Auto-dismisses after 5s for success/info, persists for error. Bottom-right by default.">
      <div className="ds-row">
        <Button variant="secondary" size="sm" onClick={() => pushToast({ kind: "success", title: "Saved", sub: "Changes applied immediately." })}>Success toast</Button>
        <Button variant="secondary" size="sm" onClick={() => pushToast({ kind: "warn", title: "Sandbox slow", sub: "Verification queue depth 3." })}>Warning toast</Button>
        <Button variant="secondary" size="sm" onClick={() => pushToast({ kind: "error", title: "Couldn't reach server", sub: "Retrying in 30 seconds." })}>Error toast</Button>
      </div>
    </DSBlock>

    <DSBlock title="State banners" desc="Above-content alerts. Always actionable — never blame the user.">
      <div className="state-banner state-banner--warn">
        <div className="state-banner__icon">{window.Icon.alertTriangle({ size: 14 })}</div>
        <div>
          <div className="state-banner__title">Sandbox unreachable</div>
          <div className="state-banner__sub">Your call is stored. We'll retry in 30 seconds.</div>
        </div>
      </div>
      <div className="state-banner state-banner--error" style={{ marginTop: 8 }}>
        <div className="state-banner__icon">{window.Icon.xCircle({ size: 14 })}</div>
        <div>
          <div className="state-banner__title">Verification failed</div>
          <div className="state-banner__sub">3 traces have unrecoverable errors. Open them to investigate.</div>
        </div>
      </div>
      <div className="state-banner state-banner--info" style={{ marginTop: 8 }}>
        <div className="state-banner__icon">{window.Icon.shield({ size: 14 })}</div>
        <div>
          <div className="state-banner__title">Auditor read-only view</div>
          <div className="state-banner__sub">You're viewing a shared trace. Verify offline with the CLI.</div>
        </div>
      </div>
    </DSBlock>
  </div>
);

/* ---- Section: Empty / loading / denied ---- */
const DSStates = () => (
  <div className="col gap-6">
    <DSBlock title="Empty" desc="Single illustration optional, headline + 1-sentence body + 1 CTA. Never two CTAs.">
      <Card padded>
        <div style={{ textAlign: "center", padding: "32px 16px" }}>
          <div style={{ width: 48, height: 48, borderRadius: 12, background: "var(--paper-alt)", color: "var(--ink-3)", margin: "0 auto 12px", display: "grid", placeItems: "center" }}>
            {window.Icon.activity({ size: 22 })}
          </div>
          <h3 style={{ margin: 0, fontFamily: "var(--font-display)", fontStyle: "italic", fontSize: 22, color: "var(--ink-1)" }}>No traces yet.</h3>
          <p className="text-sm muted" style={{ margin: "6px auto 16px", maxWidth: 320 }}>Wrap your first OpenAI call to start the evidence chain.</p>
          <Button variant="primary" size="sm">View install guide</Button>
        </div>
      </Card>
    </DSBlock>

    <DSBlock title="Loading skeleton" desc="Pulse via opacity 0.6→1.0 every 400ms. Skipped under prefers-reduced-motion.">
      <Card padded>
        <SkeletonLine w="40%" h={16} />
        <div style={{ marginTop: 12 }}><SkeletonLine w="100%" h={12} /></div>
        <div style={{ marginTop: 8 }}><SkeletonLine w="92%" h={12} /></div>
        <div style={{ marginTop: 8 }}><SkeletonLine w="76%" h={12} /></div>
      </Card>
    </DSBlock>

    <DSBlock title="Permission denied" desc="Clear about which role is required. Never accusatory.">
      <PermissionDenied requiredRole="Compliance" currentRole="Engineer" />
    </DSBlock>
  </div>
);

/* ---- Section: Patterns ---- */
const DSPatterns = () => (
  <div className="col gap-6">
    <DSBlock title="Type-to-confirm">
      <div style={{ padding: 16, border: "1px solid var(--rule)", borderRadius: "var(--radius-md)", maxWidth: 420 }}>
        <div className="fw-600">Revoke API key <span className="mono">af_live_x3k…</span></div>
        <div className="text-xs muted" style={{ marginTop: 4 }}>This cannot be undone. Type <span className="mono">revoke</span> to confirm.</div>
        <input className="input mono" style={{ marginTop: 12 }} placeholder="revoke" />
        <div className="row gap-2" style={{ marginTop: 12, justifyContent: "flex-end" }}>
          <Button variant="ghost" size="sm">Cancel</Button>
          <Button variant="destructive" size="sm" disabled>Revoke key</Button>
        </div>
      </div>
    </DSBlock>

    <DSBlock title="Reveal-once" desc={`Critical secret shown once in a high-contrast dark block with a copy button and an explicit "won't show again" warning.`}>
      <div className="reveal-key" style={{ maxWidth: 540 }}>
        <div className="reveal-key__label mono">Production API key · Encounter Summary</div>
        <div className="reveal-key__row">
          <span className="mono">af_live_x3k2qz9a8mn4lp2rt7yvWERrt22aaPP9xKk</span>
          <Button variant="ghost" size="sm" icon={window.Icon.copy({ size: 12 })}>Copy</Button>
        </div>
      </div>
    </DSBlock>

    <DSBlock title="Density">
      <div className="row gap-2">
        <div data-density="comfortable" style={{ padding: 12, border: "1px solid var(--rule)", borderRadius: "var(--radius-md)" }}>
          <div className="text-xs muted mono">comfortable · 48px rows</div>
          <Button variant="secondary" size="sm" style={{ marginTop: 8 }}>Button · 40px h</Button>
        </div>
        <div data-density="compact" style={{ padding: 12, border: "1px solid var(--rule)", borderRadius: "var(--radius-md)" }}>
          <div className="text-xs muted mono">compact · 36px rows</div>
          <Button variant="secondary" size="sm" style={{ marginTop: 8 }}>Button · 32px h</Button>
        </div>
      </div>
    </DSBlock>
  </div>
);

const DSBlock = ({ title, desc, children }) => (
  <section className="ds-block">
    <div className="ds-block__head">
      <h2 className="ds-block__title">{title}</h2>
      {desc && <p className="ds-block__desc">{desc}</p>}
    </div>
    <div className="ds-block__body">{children}</div>
  </section>
);

const Code = ({ children }) => (
  <pre className="ds-code"><code>{children}</code></pre>
);

/* Permission-denied component — also exported globally */
const PermissionDenied = ({ requiredRole = "Admin", currentRole = "Engineer", onContact, onBack }) => (
  <div className="permission-denied">
    <div className="permission-denied__icon">{window.Icon.lock({ size: 22 })}</div>
    <h2 className="permission-denied__title"><em>This requires {requiredRole} access.</em></h2>
    <p className="permission-denied__sub">
      You're signed in as <strong>{currentRole}</strong>. Compliance dashboards, evidence pack generation, and the audit room are scoped to <strong>{requiredRole}</strong> and above.
    </p>
    <div className="row gap-2" style={{ marginTop: 16, justifyContent: "center" }}>
      <Button variant="secondary" size="sm" icon={window.Icon.share({ size: 12 })} onClick={onContact}>
        Request access from admin
      </Button>
      <Button variant="ghost" size="sm" onClick={onBack}>
        Back to dashboard
      </Button>
    </div>
  </div>
);

window.DesignSystem = DesignSystem;
window.PermissionDenied = PermissionDenied;
