/* Voyage Fleet — Settings (/settings?section=). Mostly read-only inventory with
 * Edit-in-Claude-Code routes; inline-editable notification + display prefs.
 * Exports: Settings.
 */

const { useState: useS_set, useEffect: useEf_set } = React;

const SET_SECTIONS = [
  { id: "cloudflare", label: "Cloudflare Accounts", icon: <Icons.Cloudflare size={15} /> },
  { id: "github", label: "GitHub Organization", icon: <Icons.Github size={15} /> },
  { id: "notifications", label: "Notifications & On-Call", icon: <Icons.Bell size={15} /> },
  { id: "permissions", label: "Permissions", icon: <Icons.Shield size={15} /> },
  { id: "cost", label: "Cost & Billing", icon: <Icons.ChartBar size={15} /> },
  { id: "audit", label: "Audit & Compliance", icon: <Icons.Audit size={15} /> },
  { id: "display", label: "Display preferences", icon: <Icons.Settings size={15} /> },
];

const ROUTES_TABLE = [
  ["Edit a seam", "Opens voyage-fleet-config/seams/<name>.yaml in Claude Code"],
  ["Edit a component's version pin", "PR against <tenant-repo>/package.json"],
  ["Edit changelog", "Opens voyage-platform/packages/<component>/RELEASE_NOTES.md in Claude Code"],
  ["Invite operator", "PR against voyage-fleet-config/operators.yaml"],
  ["Change notification settings", "PR against voyage-fleet-config/notifications.yaml"],
  ["Rotate a secret", "PR updates the secret reference → GitHub Actions rotates"],
  ["Publish a component", "Authored + published in Claude Code"],
  ["Rev a tenant's components", "PR bumps pins → GitHub Actions deploys"],
  ["Migrate a tenant's components", "PR updates package.json → GitHub Actions deploys"],
  ["Provision a new tenant", "PR creates the repo → GitHub Actions provisions"],
  ["Archive / unarchive a tenant", "Run from a Claude Code session"],
];

function StatusPillX({ status }) {
  const map = { active: ["success", "Active"], "refresh-needed": ["warning", "Refresh needed"], revoked: ["danger", "Revoked"] };
  const m = map[status] || map.active;
  return <Pill tone={m[0]}>{m[1]}</Pill>;
}

function ToastMini({ text }) { return text ? <div style={{ position: "fixed", left: "50%", bottom: 24, transform: "translateX(-50%)", zIndex: 300, background: "var(--jrni-color-neutral-1)", color: "white", padding: "10px 16px", borderRadius: 8, boxShadow: "var(--jrni-shadow-lg)", fontSize: 13, fontWeight: 500, display: "flex", alignItems: "center", gap: 8 }}><Icons.Check size={14} color="var(--jrni-color-semantic-green-1)" />{text}</div> : null; }

function Settings({ params }) {
  const F = window.FLEET;
  const section = params.section || "cloudflare";
  const [toast, setToast] = useS_set(null);
  const [invite, setInvite] = useS_set(false);
  const [expandedAcct, setExpandedAcct] = useS_set("prod");
  const [prefs, setPrefs] = useS_set(() => { try { return JSON.parse(localStorage.getItem("vf_prefs")) || { theme: "light", density: "default", pageSize: "25" }; } catch (e) { return { theme: "light", density: "default", pageSize: "25" }; } });
  const [notif, setNotif] = useS_set({ channel: "#voyage-fleet-alerts", cadence: "daily", oncall: true });
  const fireToast = t => { setToast(t); setTimeout(() => setToast(null), 2400); };
  const setPref = (k, v) => { const n = { ...prefs, [k]: v }; setPrefs(n); try { localStorage.setItem("vf_prefs", JSON.stringify(n)); } catch (e) {} };

  const accounts = [
    { id: "prod", name: "Voyage (production)", status: "active", zones: 12, validated: "2h ago", expiry: "in 84 days", by: "Sven Lindstrom · 12 Mar 2026" },
    { id: "staging", name: "Voyage (staging)", status: "refresh-needed", zones: 4, validated: "6 days ago", expiry: "in 3 days", by: "Lori Owens · 2 Jan 2026" },
    { id: "irongate", name: "Irongate (customer-hosted)", status: "active", zones: 1, validated: "1 day ago", expiry: "in 210 days", by: "Imani Okafor · 28 Apr 2026" },
  ];

  return (
    <div style={{ flex: 1, display: "flex", minHeight: 0 }}>
      {/* section nav */}
      <div style={{ width: 224, flexShrink: 0, borderRight: "1px solid var(--jrni-color-surface-border)", background: "white", overflowY: "auto", display: "flex", flexDirection: "column" }}>
        <div style={{ padding: "16px 14px 8px" }}><h1 style={{ margin: 0, fontSize: 17, fontWeight: 700, color: "var(--jrni-color-neutral-1)" }}>Settings</h1></div>
        <nav style={{ padding: "0 8px", flex: 1 }}>
          {SET_SECTIONS.map(s => (
            <button key={s.id} onClick={() => navigate("/settings", { section: s.id })} style={{ display: "flex", alignItems: "center", gap: 10, width: "100%", padding: "9px 12px", borderRadius: 6, border: "none", cursor: "pointer", background: section === s.id ? "var(--jrni-color-primary-3)" : "transparent", color: section === s.id ? "var(--jrni-color-primary-1)" : "var(--jrni-color-neutral-2)", fontSize: 13, fontWeight: section === s.id ? 600 : 500, marginBottom: 2, fontFamily: "var(--jrni-font-family-sans)", textAlign: "left" }}>
              <span style={{ display: "inline-flex", flexShrink: 0 }}>{s.icon}</span><span style={{ flex: 1 }}>{s.label}</span>
            </button>
          ))}
        </nav>
      </div>

      {/* content */}
      <div style={{ flex: 1, minWidth: 0, overflowY: "auto", padding: "22px 26px 30px" }}>
        <div style={{ maxWidth: 760 }}>

          {section === "cloudflare" && (<div>
            <SettingsHead title="Cloudflare Accounts" body="Registered accounts the fleet deploys into. Account inventory is git-managed." cc="voyage-fleet-config/cloudflare-accounts.yaml" ccLabel="Register new account" />
            <div style={{ display: "flex", flexDirection: "column", gap: 10, marginTop: 16 }}>
              {accounts.map(a => (
                <Card key={a.id} padding={0} style={{ overflow: "hidden" }}>
                  <button onClick={() => setExpandedAcct(expandedAcct === a.id ? null : a.id)} style={{ display: "flex", alignItems: "center", gap: 12, width: "100%", padding: "13px 16px", border: "none", background: "transparent", cursor: "pointer", fontFamily: "var(--jrni-font-family-sans)", textAlign: "left" }}>
                    <Icons.Cloudflare size={17} color="var(--jrni-color-text-soft)" />
                    <span style={{ fontSize: 13.5, fontWeight: 600, color: "var(--jrni-color-neutral-1)", flex: 1 }}>{a.name}</span>
                    <StatusPillX status={a.status} />
                    <span style={{ fontSize: 12, color: "var(--jrni-color-text-soft)" }}>{a.zones} zones · validated {a.validated}</span>
                    <Icons.Chevron dir={expandedAcct === a.id ? "up" : "down"} size={13} color="var(--jrni-color-neutral-3)" />
                  </button>
                  {expandedAcct === a.id ? (
                    <div style={{ padding: "0 16px 14px", borderTop: "1px solid var(--jrni-color-surface-border)" }}>
                      <div style={{ display: "flex", gap: 28, flexWrap: "wrap", marginTop: 12 }}>
                        <div><div style={subLbl}>Token expiry</div><div style={{ fontSize: 13, color: "var(--jrni-color-neutral-1)" }}>{a.expiry}</div></div>
                        <div><div style={subLbl}>Configured by</div><div style={{ fontSize: 13, color: "var(--jrni-color-neutral-1)" }}>{a.by}</div></div>
                        <div style={{ flex: 1 }} />
                      </div>
                      <div style={{ display: "flex", gap: 8, marginTop: 14, flexWrap: "wrap" }}>
                        <GatedButton cap="edit-config" reason="Token operations require Platform Engineer permission." variant="secondary" size="sm" icon={<Icons.Refresh size={12} />} onClick={() => fireToast(`Re-validation handed to Claude Code for ${a.name}`)}>Re-validate in Claude Code</GatedButton>
                        <GatedButton cap="edit-config" reason="Token operations require Platform Engineer permission." variant="secondary" size="sm" icon={<Icons.Terminal size={12} />} onClick={() => fireToast(`Token-rotation command copied for ${a.name}`)}>Rotate token in Claude Code</GatedButton>
                        <ClaudeCodeLink path="voyage-fleet-config/cloudflare-accounts.yaml" label="Edit account config" variant="button" size="sm" />
                      </div>
                    </div>
                  ) : null}
                </Card>
              ))}
            </div>
          </div>)}

          {section === "github" && (<div>
            <SettingsHead title="GitHub Organization" body="Registered orgs and team-to-fleet-role mappings. Org inventory is git-managed." cc="voyage-fleet-config/github-orgs.yaml" ccLabel="Add GitHub org" />
            <div style={{ display: "flex", flexDirection: "column", gap: 10, marginTop: 16 }}>
              {[{ org: "ryanbreen", status: "active", repos: 52 }, { org: "voyage-fleet", status: "active", repos: 6 }].map(o => (
                <Card key={o.org} padding={16}>
                  <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
                    <Icons.Github size={17} color="var(--jrni-color-text-soft)" />
                    <span style={{ fontFamily: "var(--jrni-font-family-mono)", fontSize: 13.5, fontWeight: 600, color: "var(--jrni-color-neutral-1)", flex: 1 }}>{o.org}</span>
                    <Pill tone="success">token active</Pill>
                    <span style={{ fontSize: 12, color: "var(--jrni-color-text-soft)" }}>{o.repos} repos</span>
                    <a href="#" onClick={e => e.preventDefault()} style={{ fontSize: 12, fontWeight: 600, color: "var(--jrni-color-primary-1)", display: "inline-flex", alignItems: "center", gap: 4 }}>Open<Icons.External size={11} /></a>
                  </div>
                  <div style={{ marginTop: 12, paddingTop: 12, borderTop: "1px solid var(--jrni-color-surface-border)", display: "flex", gap: 8, flexWrap: "wrap", alignItems: "center" }}>
                    <span style={{ fontSize: 12, color: "var(--jrni-color-text-soft)" }}>Team mappings:</span>
                    {[["@platform → Platform Engineer"], ["@success → Customer Success"], ["@release → Release Manager"]].map(t => <Mono key={t} color="var(--jrni-color-neutral-1)">{t}</Mono>)}
                    <div style={{ flex: 1 }} />
                    <ClaudeCodeLink path="voyage-fleet-config/github-orgs.yaml" label="Edit mappings" />
                  </div>
                </Card>
              ))}
            </div>
          </div>)}

          {section === "notifications" && (<div>
            <SettingsHead title="Notifications & On-Call" body="One of the few inline-editable surfaces. Saving opens a PR against the config repo." />
            <Card padding={20} style={{ marginTop: 16 }}>
              <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
                <Field label="Slack channel for fleet alerts"><Input value={notif.channel} onChange={e => setNotif(n => ({ ...n, channel: e.target.value }))} style={{ fontFamily: "var(--jrni-font-family-mono)" }} /></Field>
                <Field label="Email digest cadence">
                  <div style={{ display: "flex", gap: 18, paddingTop: 6 }}>{["daily", "weekly", "never"].map(c => <Radio key={c} checked={notif.cadence === c} onChange={() => setNotif(n => ({ ...n, cadence: c }))} label={c[0].toUpperCase() + c.slice(1)} />)}</div>
                </Field>
                <label style={{ display: "flex", alignItems: "center", gap: 10, cursor: "pointer" }}><Toggle checked={notif.oncall} onChange={v => setNotif(n => ({ ...n, oncall: v }))} /><span style={{ fontSize: 13.5, color: "var(--jrni-color-neutral-1)" }}>On-call rota integration (PagerDuty)</span></label>
              </div>
              <div style={{ marginTop: 16, paddingTop: 16, borderTop: "1px solid var(--jrni-color-surface-border)", display: "flex", alignItems: "center", gap: 10 }}>
                <Button variant="secondary" size="sm" icon={<Icons.Send size={12} />} onClick={() => fireToast("Test notification sent to " + notif.channel)}>Test notification</Button>
                <div style={{ flex: 1 }} />
                <span style={{ fontSize: 11.5, color: "var(--jrni-color-text-soft)" }}>Saving opens a PR against <Mono>voyage-fleet-config/notifications.yaml</Mono>.</span>
                <Button variant="primary" size="sm" icon={<Icons.GitPr size={12} />} onClick={() => fireToast("Opened PR against notifications.yaml")}>Save (open PR)</Button>
              </div>
            </Card>
          </div>)}

          {section === "permissions" && (<div>
            <SettingsHead title="Permissions" body="Operator roster and role permission matrix. Roster is git-managed; invites open a PR." cc="voyage-fleet-config/operators.yaml" ccLabel="Edit roster" extra={<GatedButton cap="manage-permissions" reason="Managing permissions requires Release Manager permission." variant="primary" size="sm" icon={<Icons.Plus size={12} />} onClick={() => setInvite(true)}>Invite operator</GatedButton>} />
            <Card padding={0} style={{ overflow: "hidden", marginTop: 16 }}>
              <table style={{ width: "100%", borderCollapse: "collapse" }}>
                <thead><tr style={{ background: "var(--jrni-color-surface-card-soft)", borderBottom: "1px solid var(--jrni-color-surface-border)" }}>{["Operator", "Email", "Role", "Last active"].map((h, i) => <th key={i} style={thStyle}>{h}</th>)}</tr></thead>
                <tbody>{[["Lori Owens", "lori@voyage.dev", "Platform Engineer", "now"], ["Sven Lindstrom", "sven@voyage.dev", "Release Manager", "12m ago"], ["Marek Singh", "marek@voyage.dev", "Customer Success", "1h ago"], ["Imani Okafor", "imani@voyage.dev", "Customer Success", "3h ago"]].map((o, i) => (
                  <tr key={i} style={{ borderBottom: i < 3 ? "1px solid var(--jrni-color-surface-border)" : "none" }}>
                    <td style={{ padding: "10px 14px" }}><span style={{ display: "inline-flex", alignItems: "center", gap: 8 }}><Avatar initials={o[0].split(" ").map(w => w[0]).join("")} color="var(--jrni-color-tertiary-light-blue)" size={24} /><span style={{ fontSize: 13, fontWeight: 600, color: "var(--jrni-color-neutral-1)" }}>{o[0]}</span></span></td>
                    <td style={{ padding: "0 14px", fontSize: 12.5, color: "var(--jrni-color-text-soft)", fontFamily: "var(--jrni-font-family-mono)" }}>{o[1]}</td>
                    <td style={{ padding: "0 14px" }}><Pill tone={o[2] === "Release Manager" ? "primary" : o[2] === "Platform Engineer" ? "info" : "neutral"}>{o[2]}</Pill></td>
                    <td style={{ padding: "0 14px", fontSize: 12.5, color: "var(--jrni-color-neutral-2)" }}>{o[3]}</td>
                  </tr>
                ))}</tbody>
              </table>
            </Card>
            <div style={{ marginTop: 18 }}>
              <SectionLabel>Role permission matrix · read-only</SectionLabel>
              <Card padding={0} style={{ overflow: "auto", marginTop: 8 }}>
                <table style={{ width: "100%", borderCollapse: "collapse" }}>
                  <thead><tr style={{ background: "var(--jrni-color-surface-card-soft)", borderBottom: "1px solid var(--jrni-color-surface-border)" }}><th style={thStyle}>Capability</th>{["Customer Success", "Platform Engineer", "Release Manager"].map(r => <th key={r} style={{ ...thStyle, textAlign: "center" }}>{r}</th>)}</tr></thead>
                  <tbody>{[["View fleet & audit", 1, 1, 1], ["Provision tenants", 1, 1, 1], ["Low-risk bulk ops", 1, 1, 1], ["High-risk bulk ops", 0, 1, 1], ["Edit tenant config", 0, 1, 1], ["Migrate seams", 0, 1, 1], ["Rotate secrets", 0, 1, 1], ["Publish releases", 0, 0, 1], ["Manage permissions", 0, 0, 1]].map((row, i) => (
                    <tr key={i} style={{ borderBottom: i < 8 ? "1px solid var(--jrni-color-surface-border)" : "none" }}>
                      <td style={{ padding: "8px 14px", fontSize: 13, color: "var(--jrni-color-neutral-1)" }}>{row[0]}</td>
                      {[1, 2, 3].map(c => <td key={c} style={{ padding: "8px 0", textAlign: "center" }}>{row[c] ? <Icons.Check size={15} color="var(--jrni-color-semantic-green-1)" /> : <span style={{ color: "var(--jrni-color-neutral-3)" }}>—</span>}</td>)}
                    </tr>
                  ))}</tbody>
                </table>
              </Card>
            </div>
          </div>)}

          {section === "cost" && (<div>
            <SettingsHead title="Cost & Billing" body="Fleet-wide spend. Read-only observability." />
            <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 12, marginTop: 16 }}>
              {[["This month", "$2,840", "info"], ["Last month", "$2,610", "neutral"], ["Projected month-end", "$3,120", "warning"]].map(c => (
                <Card key={c[0]} padding={16}><div style={subLbl}>{c[0]}</div><div style={{ fontSize: 26, fontWeight: 700, color: c[2] === "warning" ? "var(--jrni-color-semantic-orange-1)" : "var(--jrni-color-neutral-1)", marginTop: 4 }}>{c[1]}</div></Card>
              ))}
            </div>
            <Card padding={18} style={{ marginTop: 12 }}>
              <SectionLabel>Cloudflare spend by resource</SectionLabel>
              <div style={{ marginTop: 12, display: "flex", flexDirection: "column", gap: 10 }}>
                {[["Workers", 42, "var(--jrni-color-tertiary-purple)"], ["D1", 24, "var(--jrni-color-tertiary-light-blue)"], ["R2", 18, "var(--jrni-color-tertiary-turquoise)"], ["KV + DO + Queues", 16, "var(--jrni-color-tertiary-orange)"]].map(r => (
                  <div key={r[0]} style={{ display: "flex", alignItems: "center", gap: 12 }}><span style={{ width: 130, fontSize: 12.5, color: "var(--jrni-color-text-soft)" }}>{r[0]}</span><div style={{ flex: 1, height: 18, background: "var(--jrni-color-neutral-6)", borderRadius: 4, overflow: "hidden" }}><div style={{ width: `${r[1]}%`, height: "100%", background: r[2] }} /></div><span style={{ width: 44, textAlign: "right", fontSize: 12.5, fontWeight: 600, color: "var(--jrni-color-neutral-1)" }}>{r[1]}%</span></div>
                ))}
              </div>
              <div style={{ display: "flex", gap: 24, marginTop: 16, paddingTop: 14, borderTop: "1px solid var(--jrni-color-surface-border)", flexWrap: "wrap" }}>
                <div><div style={subLbl}>npm publish costs</div><div style={{ fontSize: 14, fontWeight: 600, color: "var(--jrni-color-neutral-1)" }}>$0 (public)</div></div>
                <div><div style={subLbl}>Audit-log retention</div><div style={{ fontSize: 14, fontWeight: 600, color: "var(--jrni-color-neutral-1)" }}>$84 / mo</div></div>
              </div>
            </Card>
          </div>)}

          {section === "audit" && (<div>
            <SettingsHead title="Audit & Compliance" body="Retention and export policy are git-managed; test triggers are pipelines." />
            <div style={{ display: "flex", flexDirection: "column", gap: 12, marginTop: 16 }}>
              {[["Retention policy", "400 days", "voyage-fleet-config/audit-retention.yaml", "Change retention"], ["Export schedule", "0 3 * * * (daily 03:00 UTC)", "voyage-fleet-config/audit-retention.yaml", "Edit schedule"], ["SIEM export endpoint", "splunk-hec.voyage.internal:8088", "voyage-fleet-config/siem.yaml", "Configure SIEM export"]].map(r => (
                <Card key={r[0]} padding={16}>
                  <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
                    <div style={{ flex: 1 }}><div style={subLbl}>{r[0]}</div><div style={{ fontSize: 13.5, color: "var(--jrni-color-neutral-1)", fontFamily: "var(--jrni-font-family-mono)", marginTop: 2 }}>{r[1]}</div></div>
                    <ClaudeCodeLink path={r[2]} label={r[3]} />
                  </div>
                </Card>
              ))}
              <div><Button variant="secondary" size="sm" icon={<Icons.Download size={12} />} onClick={() => fireToast("One-off export triggered")}>Test export</Button></div>
            </div>
          </div>)}

          {section === "display" && (<div>
            <SettingsHead title="Display preferences" body="Per-operator preferences, stored locally. No PR involved." />
            <Card padding={20} style={{ marginTop: 16 }}>
              <div style={{ display: "flex", flexDirection: "column", gap: 18 }}>
                <div><div style={subLbl}>Theme</div><div style={{ marginTop: 8 }}><Segmented value={prefs.theme} onChange={v => setPref("theme", v)} options={[{ value: "light", label: "Light" }, { value: "dark", label: "Dark" }, { value: "auto", label: "Auto" }]} /></div></div>
                <div><div style={subLbl}>Density</div><div style={{ marginTop: 8 }}><Segmented value={prefs.density} onChange={v => setPref("density", v)} options={[{ value: "compact", label: "Compact" }, { value: "default", label: "Default" }, { value: "comfortable", label: "Comfortable" }]} /></div></div>
                <div><div style={subLbl}>Default page size</div><div style={{ marginTop: 8 }}><Segmented value={prefs.pageSize} onChange={v => setPref("pageSize", v)} options={[{ value: "25", label: "25" }, { value: "50", label: "50" }, { value: "100", label: "100" }, { value: "200", label: "200" }]} /></div></div>
                <div>
                  <div style={subLbl}>Keyboard shortcuts</div>
                  <div style={{ marginTop: 8, display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8 }}>
                    {[["⌘K", "Global search"], ["g h", "Go to Fleet Overview"], ["g d", "Go to Drift Report"], ["g r", "Go to Ralph Processes"]].map(k => (
                      <div key={k[0]} style={{ display: "flex", alignItems: "center", gap: 8, fontSize: 12.5 }}><kbd style={{ fontFamily: "var(--jrni-font-family-mono)", fontSize: 11, border: "1px solid var(--jrni-color-surface-border)", borderRadius: 4, padding: "1px 6px", background: "var(--jrni-color-neutral-6)", color: "var(--jrni-color-neutral-1)" }}>{k[0]}</kbd><span style={{ color: "var(--jrni-color-text-soft)" }}>{k[1]}</span></div>
                    ))}
                  </div>
                </div>
              </div>
            </Card>
          </div>)}

          {/* About this UI — routes table */}
          <div style={{ marginTop: 28, paddingTop: 20, borderTop: "1px solid var(--jrni-color-surface-border)" }}>
            <SectionLabel>About this UI — routes from UI action to code agent</SectionLabel>
            <p style={{ fontSize: 12, color: "var(--jrni-color-text-soft)", margin: "4px 0 12px", lineHeight: 1.5, maxWidth: 620 }}>Tenant-lifecycle and fleet-config writes happen here via forms (→ PRs) and pipeline triggers (→ Ralphs). Platform-authoring (seam YAML, module source, release notes) routes to Claude Code.</p>
            <Card padding={0} style={{ overflow: "hidden" }}>
              <table style={{ width: "100%", borderCollapse: "collapse" }}>
                <thead><tr style={{ background: "var(--jrni-color-surface-card-soft)", borderBottom: "1px solid var(--jrni-color-surface-border)" }}><th style={thStyle}>UI action</th><th style={thStyle}>What actually happens</th></tr></thead>
                <tbody>{ROUTES_TABLE.map((r, i) => (
                  <tr key={i} style={{ borderBottom: i < ROUTES_TABLE.length - 1 ? "1px solid var(--jrni-color-surface-border)" : "none" }}>
                    <td style={{ padding: "8px 14px", fontSize: 12.5, fontWeight: 600, color: "var(--jrni-color-neutral-1)", whiteSpace: "nowrap" }}>{r[0]}</td>
                    <td style={{ padding: "8px 14px", fontSize: 12, color: "var(--jrni-color-neutral-2)", fontFamily: /yaml|json|\.md|repo/.test(r[1]) ? "var(--jrni-font-family-mono)" : "inherit" }}>{r[1]}</td>
                  </tr>
                ))}</tbody>
              </table>
            </Card>
          </div>
        </div>
      </div>

      <Modal open={invite} onClose={() => setInvite(false)} title="Invite operator" subtitle="Opens a PR against operators.yaml adding the entry." width={440}
        footer={<React.Fragment><Button variant="tertiary" onClick={() => setInvite(false)}>Cancel</Button><Button variant="primary" icon={<Icons.GitPr size={13} />} onClick={() => { setInvite(false); fireToast("Opened PR: add operator to operators.yaml"); }}>Open PR</Button></React.Fragment>}>
        <div style={{ display: "flex", flexDirection: "column", gap: 14 }}>
          <Field label="Name"><Input placeholder="Jordan Reyes" /></Field>
          <Field label="Email"><Input placeholder="jordan@voyage.dev" /></Field>
          <Field label="Role"><Select value="cs" onChange={() => {}} options={[{ value: "cs", label: "Customer Success" }, { value: "pe", label: "Platform Engineer" }, { value: "rm", label: "Release Manager" }]} /></Field>
        </div>
      </Modal>

      <ToastMini text={toast} />
    </div>
  );
}

function SettingsHead({ title, body, cc, ccLabel, extra }) {
  return (
    <div style={{ display: "flex", alignItems: "flex-start", justifyContent: "space-between", gap: 16 }}>
      <div><h2 style={{ margin: 0, fontSize: 18, fontWeight: 700, color: "var(--jrni-color-neutral-1)" }}>{title}</h2><p style={{ margin: "4px 0 0", fontSize: 13, color: "var(--jrni-color-text-soft)", maxWidth: 520, lineHeight: 1.5 }}>{body}</p></div>
      <div style={{ display: "flex", gap: 8, alignItems: "center", flexShrink: 0 }}>{extra}{cc ? <ClaudeCodeLink path={cc} label={ccLabel} variant="button" size="sm" icon={<Icons.Plus size={12} />} /> : null}</div>
    </div>
  );
}

window.Settings = Settings;
