// ===== m9-outcomes.jsx =====
// M9 · Outcomes — replaces window.OrgOutcomes
// FR6  hierarchy: Strategic objectives → Programs → Results → Indicators → Indicator values
// FR7  outcome capture from projects / self-scheduled roles (separate from approved hours)
// FR8  outcomes & impact reporting with scoped "Preview as"
// FR9  beneficiaries / constituents (org or individual)
// FR12 admin / audit / data quality

const {
  React,
  Card, Btn, IconBtn, StatusChip, Avatar, Kpi, Progress, Field, Input, Textarea, Select, Checkbox, Toggle, Tabs, Empty, SectionHead, TopBar,
  IconPlus, IconCheck, IconX, IconArrow, IconArrowL, IconDownload, IconUpload,
  IconBook, IconClock, IconUsers, IconAward, IconShield, IconSearch, IconFilter, IconBell,
  IconStar, IconEdit, IconExternal, IconChevron, IconChevronD, IconEye, IconMore, IconCal,
  IconClipboard, IconMail, IconFlag, IconPin,
  VOLUNTEERS,
} = window;
const { useState: useO9, useMemo: useO9M } = React;

const o9_over = { fontSize: 11, letterSpacing: "0.12em", textTransform: "uppercase", color: "var(--fg-3)", fontWeight: 500 };
const o9_meta = { fontSize: 11, color: "var(--fg-3)" };

// ============================================================
// DATA — full hierarchy
// ============================================================
const OBJECTIVES = [
  {
    id: "obj-conservation",
    name: "Conservation of Colorado's lands & waters",
    owner: "Aliyah Chen · Statewide",
    start: "Jan 1, 2024", end: "Dec 31, 2028",
    state: "active",
    narrative: "Five-year strategic objective to expand volunteer capacity for habitat restoration, trail stewardship, invasive species management, and shoreline care.",
    programs: 3, results: 7, indicators: 12, ytdValue: "1.24M service hours", target: 80,
  },
  {
    id: "obj-education",
    name: "Public education & hunter safety",
    owner: "Marcus Chen · Hunter Outreach",
    start: "Jan 1, 2024", end: "Dec 31, 2028",
    state: "active",
    narrative: "Build a sustainable pipeline of trained instructors and ambassadors for hunter education, wildlife stewardship, and outdoor literacy.",
    programs: 2, results: 4, indicators: 7, ytdValue: "184k visitors contacted", target: 74,
  },
  {
    id: "obj-community",
    name: "Community partnerships & access",
    owner: "Priya Sandoval · Statewide",
    start: "Jan 1, 2024", end: "Dec 31, 2028",
    state: "active",
    narrative: "Deepen partnerships with schools, conservation groups, and corporate partners. Expand equitable access to CPW programs.",
    programs: 2, results: 3, indicators: 5, ytdValue: "38 partner orgs · 4,162 students", target: 62,
  },
  {
    id: "obj-2030",
    name: "2030 statewide volunteer plan",
    owner: "Aliyah Chen",
    start: "Jan 1, 2026", end: "Dec 31, 2030",
    state: "draft",
    narrative: "Successor plan covering 2028–2030. In drafting.",
    programs: 0, results: 0, indicators: 0, ytdValue: "—", target: 0,
  },
];

const PROGRAMS_O = [
  { id: "prog-trail",    name: "Trail crew & maintenance",            type: "Operational", objective: "obj-conservation", scope: "Statewide · 42 parks", lead: "Priya Sandoval", start: "Jan 1, 2024", state: "active",  results: 3, indicators: 5 },
  { id: "prog-camp",     name: "Camp host program",                    type: "Operational", objective: "obj-conservation", scope: "32 parks with campgrounds", lead: "Aliyah Chen",   start: "Apr 1, 2024", state: "active",  results: 2, indicators: 3 },
  { id: "prog-cleanup",  name: "Shoreline & invasive species cleanup", type: "Operational", objective: "obj-conservation", scope: "Front Range parks",         lead: "Marcus Chen",    start: "Mar 15, 2024", state: "active", results: 2, indicators: 4 },
  { id: "prog-hunter",   name: "Hunter Outreach instruction",          type: "Education",   objective: "obj-education",     scope: "Statewide · 12 ranges",     lead: "Marcus Chen",    start: "Jan 1, 2024", state: "active",  results: 2, indicators: 4 },
  { id: "prog-natu",     name: "Naturalist program",                    type: "Education",   objective: "obj-education",     scope: "8 parks",                    lead: "Aliyah Chen",    start: "May 1, 2024", state: "active",  results: 2, indicators: 3 },
  { id: "prog-schools",  name: "School field-trip pipeline",            type: "Partnership", objective: "obj-community",     scope: "K-12 statewide",             lead: "Priya Sandoval", start: "Sep 1, 2024", state: "active",  results: 2, indicators: 3 },
  { id: "prog-corp",     name: "Corporate volunteer days",              type: "Partnership", objective: "obj-community",     scope: "Statewide",                  lead: "Aliyah Chen",    start: "Mar 1, 2024", state: "active",  results: 1, indicators: 2 },
];

const RESULTS = [
  { id: "res-trail-miles",  program: "prog-trail",   name: "Sustainable trail miles maintained", description: "Multi-year sustained trail care", state: "active",   start: "Jan 1, 2024", end: "Dec 31, 2028" },
  { id: "res-trail-back",   program: "prog-trail",   name: "Backcountry trails reopened",         description: "Reopen trails closed by storms", state: "active",   start: "Jan 1, 2024", end: "Dec 31, 2028" },
  { id: "res-trail-safety", program: "prog-trail",   name: "Trail crew safety record",            description: "Maintain zero incidents",         state: "active",   start: "Jan 1, 2024", end: "Dec 31, 2028" },
  { id: "res-camp-host",    program: "prog-camp",    name: "Camp host coverage at all sites",     description: "Every campground has 1+ host",    state: "active",   start: "Apr 1, 2024", end: "—" },
  { id: "res-camp-sat",     program: "prog-camp",    name: "Camper satisfaction & complaints",    description: "Reduce complaints, raise sat",    state: "active",   start: "Apr 1, 2024", end: "—" },
  { id: "res-cleanup-vol",  program: "prog-cleanup", name: "Volunteer participation in cleanups", description: "Sustain participation",            state: "active",   start: "Mar 15, 2024", end: "—" },
  { id: "res-cleanup-mat",  program: "prog-cleanup", name: "Material collected & habitat impact", description: "Tons + areas restored",            state: "active",   start: "Mar 15, 2024", end: "—" },
  { id: "res-hunter-inst",  program: "prog-hunter",  name: "Hunter ed instructor pipeline",       description: "Instructor counts + retention",    state: "active",   start: "Jan 1, 2024", end: "—" },
  { id: "res-hunter-stu",   program: "prog-hunter",  name: "Hunter ed students certified",        description: "Certifications issued + audience", state: "active",   start: "Jan 1, 2024", end: "—" },
  { id: "res-natu",         program: "prog-natu",    name: "Naturalist program reach",            description: "Visitors contacted by naturalists", state: "active", start: "May 1, 2024", end: "—" },
  { id: "res-natu-prog",    program: "prog-natu",    name: "Naturalist programs run",             description: "Number of programs delivered",     state: "active",   start: "May 1, 2024", end: "—" },
  { id: "res-schools",      program: "prog-schools", name: "Schools reached",                      description: "Schools, students, teachers",      state: "active",   start: "Sep 1, 2024", end: "—" },
  { id: "res-schools-stu",  program: "prog-schools", name: "Students served via field trips",     description: "Aggregate student count",          state: "active",   start: "Sep 1, 2024", end: "—" },
  { id: "res-corp",         program: "prog-corp",    name: "Corporate participation",              description: "Corporate days run",                state: "active",   start: "Mar 1, 2024", end: "—" },
];

const INDICATORS = [
  { id: "ind-trail-mi", result: "res-trail-miles",  name: "Trail miles improved",        unit: "miles",        type: "count",   ytd: 218, goal: 320, last: "May 18, 2026 · Priya Sandoval", state: "active" },
  { id: "ind-trail-h",  result: "res-trail-miles",  name: "Volunteer trail hours",       unit: "hours",        type: "count",   ytd: 3818, goal: 5000, last: "May 22, 2026 · System", state: "active" },
  { id: "ind-trail-rh", result: "res-trail-back",   name: "Reopened backcountry miles",  unit: "miles",        type: "count",   ytd: 14.4, goal: 22, last: "May 17, 2026 · Priya Sandoval", state: "active" },
  { id: "ind-trail-inc",result: "res-trail-safety", name: "Trail crew safety incidents", unit: "incidents",    type: "count",   ytd: 0, goal: 0, lower: true, last: "May 22, 2026 · System", state: "active" },
  { id: "ind-camp-cov", result: "res-camp-host",    name: "Campground coverage",         unit: "% campgrounds", type: "percentage", ytd: 96, goal: 100, last: "May 21, 2026 · Aliyah Chen", state: "active" },
  { id: "ind-camp-sat", result: "res-camp-sat",     name: "Camper satisfaction score",   unit: "out of 5",     type: "number",  ytd: 4.6, goal: 4.5, last: "May 22, 2026 · System", state: "active" },
  { id: "ind-cleanup-vols", result: "res-cleanup-vol", name: "Volunteers in cleanups",     unit: "volunteers",   type: "count",  ytd: 1842, goal: 2200, last: "May 22, 2026 · Marcus Chen", state: "active" },
  { id: "ind-cleanup-lbs",  result: "res-cleanup-mat", name: "Material collected",         unit: "pounds",       type: "count",  ytd: 18420, goal: 22000, last: "May 18, 2026 · System", state: "active" },
  { id: "ind-cleanup-mi",   result: "res-cleanup-mat", name: "Shoreline miles cleared",    unit: "miles",        type: "count",  ytd: 36, goal: 48, last: "May 18, 2026 · Marcus Chen", state: "active" },
  { id: "ind-cleanup-trees",result: "res-cleanup-mat", name: "Trees planted",              unit: "trees",        type: "count",  ytd: 3286, goal: 5000, last: "May 17, 2026 · Marcus Chen", state: "active" },
  { id: "ind-cleanup-sign", result: "res-cleanup-mat", name: "Signs installed",            unit: "signs",        type: "count",  ytd: 78, goal: 96, last: "May 14, 2026 · Marcus Chen", state: "active" },
  { id: "ind-hunter-inst",  result: "res-hunter-inst",name: "Active hunter ed instructors", unit: "instructors", type: "count",  ytd: 22, goal: 28, last: "May 22, 2026 · System", state: "active" },
  { id: "ind-hunter-h",     result: "res-hunter-inst",name: "Instructor hours",            unit: "hours",        type: "count",  ytd: 86, goal: 1200, last: "May 22, 2026 · System", state: "active" },
  { id: "ind-hunter-stu",   result: "res-hunter-stu", name: "Students certified",          unit: "certifications", type: "count", ytd: 412, goal: 580, last: "May 17, 2026 · Marcus Chen", state: "active" },
  { id: "ind-natu-vis",     result: "res-natu",       name: "Visitors contacted",          unit: "visitors",     type: "count",  ytd: 184220, goal: 250000, last: "May 22, 2026 · System", state: "active" },
  { id: "ind-natu-prog",    result: "res-natu-prog",  name: "Programs delivered",           unit: "programs",     type: "count",  ytd: 144, goal: 220, last: "May 22, 2026 · System", state: "active" },
  { id: "ind-schools",      result: "res-schools",    name: "Schools partnered",            unit: "schools",      type: "count",  ytd: 32, goal: 48, last: "May 4, 2026 · Priya Sandoval", state: "active" },
  { id: "ind-schools-stu",  result: "res-schools-stu",name: "Students served",              unit: "students",     type: "count",  ytd: 4162, goal: 6000, last: "May 4, 2026 · Priya Sandoval", state: "active" },
  { id: "ind-corp",         result: "res-corp",       name: "Corporate days",               unit: "events",       type: "count",  ytd: 12, goal: 22, last: "May 16, 2026 · Aliyah Chen", state: "active" },
  { id: "ind-corp-vols",    result: "res-corp",       name: "Corp volunteers hosted",       unit: "volunteers",   type: "count",  ytd: 412, goal: 580, last: "May 16, 2026 · Aliyah Chen", state: "active" },
  { id: "ind-animal",       result: "res-cleanup-mat",name: "Animals transported",          unit: "animals",      type: "count",  ytd: 38, goal: 60, last: "May 12, 2026 · Marcus Chen", state: "active" },
  { id: "ind-patrol",       result: "res-trail-miles",name: "Miles patrolled",              unit: "miles",        type: "count",  ytd: 1284, goal: 2400, last: "May 22, 2026 · System", state: "active" },
];

const INDICATOR_VALUES_SAMPLE = [
  { date: "May 17, 2026", value: 14, unit: "trees", source: "Cherry Creek shoreline cleanup · May 17", beneficiaries: "Cherry Creek SP visitors", staff: "Marcus Chen", note: "Spring planting · cottonwood saplings." },
  { date: "May 17, 2026", value: 86, unit: "lbs",   source: "Cherry Creek shoreline cleanup · May 17", beneficiaries: "Cherry Creek SP visitors", staff: "Marcus Chen", note: "Mixed trash + 4 tires." },
  { date: "May 10, 2026", value: 0.6, unit: "miles", source: "Boyd Lake trail crew · May 10", beneficiaries: "Boyd Lake hikers", staff: "Priya Sandoval", note: "Drainage repair on north loop." },
  { date: "May 4, 2026",  value: 18, unit: "certifications", source: "Hunter ed youth class · Boulder", beneficiaries: "ben-students-boulder", staff: "Marcus Chen", note: "All 18 students passed." },
  { date: "May 4, 2026",  value: 24, unit: "hours", source: "Hunter ed youth class · Boulder", beneficiaries: null, staff: "Maya Okonkwo", note: "Instructor hours · grant-tracked." },
  { date: "Apr 27, 2026", value: 96, unit: "students", source: "Field trip · Boyd Lake K-5", beneficiaries: "ben-bvsd", staff: "Priya Sandoval", note: "BVSD field-trip pipeline." },
  { date: "Apr 27, 2026", value: 4.7, unit: "out of 5", source: "Post-event survey · Hunter ed Boulder", beneficiaries: null, staff: "System", note: "Auto-rolled from survey." },
];

const BENEFICIARIES = [
  { id: "ben-bvsd",       kind: "organization", name: "Boulder Valley School District", type: "School district",  contacts: 1, programs: 1, attributed: 4162, status: "active", scope: "NE", desc: "8 schools partnered for field-trip pipeline." },
  { id: "ben-oia",        kind: "organization", name: "Outdoor Industry Association",    type: "Partner",          contacts: 2, programs: 1, attributed: 218,  status: "active", scope: "Statewide", desc: "Statewide industry partner." },
  { id: "ben-audubon",    kind: "organization", name: "Audubon Colorado",                 type: "Partner",          contacts: 3, programs: 2, attributed: 86,   status: "active", scope: "Statewide", desc: "Birds-of-Colorado co-curriculum + naturalist support." },
  { id: "ben-cherry-vis", kind: "individual",   name: "Cherry Creek SP visitors (aggregate)", type: "Visitors", contacts: 0, programs: 2, attributed: 42180, status: "active", scope: "Statewide", desc: "Aggregate constituent record for general public served at Cherry Creek SP." },
  { id: "ben-boyd-vis",   kind: "individual",   name: "Boyd Lake SP visitors (aggregate)",     type: "Visitors", contacts: 0, programs: 2, attributed: 18420, status: "active", scope: "NE", desc: "Aggregate constituent record for general public served at Boyd Lake SP." },
  { id: "ben-students-boulder", kind: "individual", name: "Boulder hunter ed students (cohort)", type: "Students", contacts: 0, programs: 1, attributed: 412, status: "active", scope: "Statewide", desc: "Cohort attribution for Boulder field-office hunter ed classes." },
  { id: "ben-leave-no-trace", kind: "organization", name: "Leave No Trace Center",          type: "Partner",        contacts: 1, programs: 1, attributed: 42,    status: "active", scope: "Statewide", desc: "Training partner for the LNT-for-volunteers course." },
];

const STORIES = [
  { id: "st-1",  v: "v-arenas", project: "Boyd Lake trail crew · May 10", photo: "var(--sage-700)", text: "We rebuilt 340 feet of switchback after the spring runoff washed out the old line. Three hikers stopped to thank us — one said this is the trail her dad taught her to hike on.", metrics: { miles: 0.34, visitors: 8 } },
  { id: "st-2",  v: "v-okonkwo", project: "Hunter ed youth class · Boulder", photo: "var(--iris-600)", text: "Class of 18, all under 16. Two girls were the strongest shots in the group — afterward, their dad came up and said they couldn't stop talking about it on the drive home.", metrics: { certifications: 18 } },
  { id: "st-3",  v: "v-mendez", project: "Lake Pueblo shoreline cleanup · Apr 22", photo: "var(--coral-700)", text: "Hauled out two old fishing nets that had been tangled in the rocks for who-knows-how-long. The water looked different by the end of the day.", metrics: { lbs: 142, miles: 1.2 } },
];

// ============================================================
// ROOT
// ============================================================
const OrgOutcomes = ({ go }) => {
  const [tab, setTab] = useO9("dashboard");
  const [viewAs, setViewAs] = useO9("universal");
  const [drillId, setDrillId] = useO9(null);
  const [drillType, setDrillType] = useO9(null);
  const [createKind, setCreateKind] = useO9(null); // "objective" | "program" | "indicator" | null

  if (drillType === "indicator" && drillId) {
    const ind = INDICATORS.find(i => i.id === drillId);
    if (ind) return <IndicatorDetail ind={ind} onBack={() => { setDrillType(null); setDrillId(null); }} />;
  }
  if (drillType === "program" && drillId) {
    const prog = PROGRAMS_O.find(p => p.id === drillId);
    if (prog) return <ProgramDetail prog={prog} onBack={() => { setDrillType(null); setDrillId(null); }} onOpenIndicator={(id) => { setDrillType("indicator"); setDrillId(id); }} />;
  }

  const tabs = [
    { id: "dashboard",     label: "Impact dashboard" },
    { id: "objectives",    label: "Objectives",      count: OBJECTIVES.length },
    { id: "programs",      label: "Programs",         count: PROGRAMS_O.length },
    { id: "results",       label: "Results",          count: RESULTS.length },
    { id: "indicators",    label: "Indicators",       count: INDICATORS.length },
    { id: "values",        label: "Indicator values" },
    { id: "beneficiaries", label: "Beneficiaries",    count: BENEFICIARIES.length },
    { id: "stories",       label: "Stories",          count: STORIES.length },
    { id: "capture",       label: "Capture config" },
  ];

  return (
    <>
      <TopBar
        title="Outcomes & impact"
        subtitle="Strategic objectives · programs · results · indicators · beneficiaries — distinct from approved hours"
        primary={<Btn icon={IconPlus} onClick={() => setTab("indicators")}>Record an indicator value</Btn>}
        secondary={<Btn kind="secondary" icon={IconDownload}>Impact report</Btn>}
      />
      <div style={{ flex: 1, overflow: "auto", padding: "20px 32px 56px" }}>
        <ViewAs viewAs={viewAs} setViewAs={setViewAs} />
        <Tabs active={tab} onChange={setTab} tabs={tabs} />

        {tab === "dashboard"     && <Dashboard viewAs={viewAs} />}
        {tab === "objectives"    && <Objectives viewAs={viewAs} onNew={() => setCreateKind("objective")} />}
        {tab === "programs"      && <Programs viewAs={viewAs} onOpen={(id) => { setDrillType("program"); setDrillId(id); }} onNew={() => setCreateKind("program")} />}
        {tab === "results"       && <Results />}
        {tab === "indicators"    && <Indicators viewAs={viewAs} onOpen={(id) => { setDrillType("indicator"); setDrillId(id); }} onNew={() => setCreateKind("indicator")} />}
        {tab === "values"        && <IndicatorValues />}
        {tab === "beneficiaries" && <Beneficiaries />}
        {tab === "stories"       && <Stories />}
        {tab === "capture"       && <CaptureConfig />}
      </div>
      {createKind === "objective" && <NewObjectiveDrawer onClose={() => setCreateKind(null)} />}
      {createKind === "program"   && <NewProgramDrawer   onClose={() => setCreateKind(null)} />}
      {createKind === "indicator" && <NewIndicatorDrawer onClose={() => setCreateKind(null)} />}
    </>
  );
};

// ============================================================
// VIEW-AS SCOPED PREVIEW
// ============================================================
const ViewAs = ({ viewAs, setViewAs }) => {
  const opts = [
    { id: "universal", label: "Universal admin",           desc: "Full hierarchy · all programs · all values · audit · edit" },
    { id: "regional",  label: "Regional admin · NE",       desc: "NE region only · scoped indicators + beneficiaries · cannot edit objectives" },
    { id: "readonly",  label: "Read-only exec / funder",   desc: "Aggregated dashboards · narratives · evidence · no per-record drill, no PII" },
  ];
  return (
    <div style={{ display: "flex", gap: 10, padding: "10px 14px", marginBottom: 16, borderRadius: 12, background: "var(--paper-soft)", border: "1px solid var(--border-soft)", alignItems: "center", flexWrap: "wrap" }}>
      <div style={{ display: "flex", gap: 6, alignItems: "center", whiteSpace: "nowrap" }}>
        <IconShield size={14} style={{ color: "var(--fg-3)" }} />
        <span style={{ ...o9_over }}>Preview as</span>
      </div>
      <div style={{ display: "flex", gap: 4 }}>
        {opts.map(o => (
          <button key={o.id} onClick={() => setViewAs(o.id)} style={{
            background: viewAs === o.id ? "var(--ink)" : "transparent",
            color: viewAs === o.id ? "var(--paper)" : "var(--fg-1)",
            border: "1px solid " + (viewAs === o.id ? "var(--ink)" : "var(--border)"),
            padding: "6px 12px", borderRadius: 999, fontSize: 12, fontWeight: 500, cursor: "pointer", fontFamily: "inherit", whiteSpace: "nowrap",
          }}>{o.label}</button>
        ))}
      </div>
      <div style={{ flex: 1, minWidth: 200, fontSize: 12, color: "var(--fg-2)" }}>
        {opts.find(o => o.id === viewAs)?.desc}
      </div>
    </div>
  );
};

// ============================================================
// DASHBOARD
// ============================================================
const Dashboard = ({ viewAs }) => (
  <>
    <div style={{ display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 14, marginBottom: 24 }}>
      <Kpi label="Service hours YTD" value="1.24M" delta={`Across ${PROGRAMS_O.length} programs`} tone="up" icon={IconClock} />
      <Kpi label="Visitors contacted" value="184k" delta="74% to 2026 goal" tone="up" icon={IconUsers} />
      <Kpi label="Trees planted" value="3,286" delta="66% to goal" tone="up" icon={IconAward} />
      <Kpi label="Beneficiaries served" value="27,632" delta={`${BENEFICIARIES.length} attribution records`} tone="up" icon={IconShield} />
    </div>

    <SectionHead title="Objectives at a glance" />
    <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 14, marginBottom: 24 }}>
      {OBJECTIVES.filter(o => o.state === "active").map(o => (
        <Card key={o.id}>
          <div style={{ display: "flex", justifyContent: "space-between", marginBottom: 8 }}>
            <span style={{ ...o9_over }}>{o.start} → {o.end}</span>
            <StatusChip status="confirmed" size="sm" label="Active" />
          </div>
          <div style={{ fontSize: 16, fontWeight: 500, color: "var(--ink)", lineHeight: 1.3, marginBottom: 8 }}>{o.name}</div>
          <div style={{ fontSize: 12, color: "var(--fg-2)", lineHeight: 1.5, marginBottom: 14 }}>{o.narrative}</div>
          <div style={{ display: "flex", gap: 14, fontSize: 11, color: "var(--fg-3)", marginBottom: 12 }}>
            <span>{o.programs} programs</span>
            <span>{o.results} results</span>
            <span>{o.indicators} indicators</span>
          </div>
          <div style={{ fontSize: 11, color: "var(--fg-3)", marginBottom: 6 }}>YTD: <strong style={{ color: "var(--ink)" }}>{o.ytdValue}</strong> · {o.target}% to goal</div>
          <Progress value={o.target} max={100} />
        </Card>
      ))}
    </div>

    <SectionHead title="Top indicators · last 30 days" action={viewAs === "readonly" ? null : <button style={{ background: "none", border: "none", color: "var(--coral-700)", fontSize: 12, fontWeight: 500, cursor: "pointer" }}>Open builder</button>} />
    <Card padded={false}>
      <div style={{ display: "grid", gridTemplateColumns: "minmax(220px, 1.6fr) minmax(160px, 1fr) 110px 100px 130px 110px", gap: 14, padding: "12px 18px", fontSize: 11, letterSpacing: "0.1em", textTransform: "uppercase", color: "var(--fg-3)", borderBottom: "1px solid var(--border)" }}>
        <span>Indicator</span><span>Program</span><span>Unit</span><span>YTD</span><span>Goal · % to</span><span>Last updated</span>
      </div>
      {INDICATORS.slice(0, 6).map((ind, i, arr) => {
        const prog = PROGRAMS_O.find(p => p.id === RESULTS.find(r => r.id === ind.result)?.program);
        const pct = ind.lower ? (ind.ytd === 0 ? 100 : 0) : Math.min(100, Math.round((ind.ytd / ind.goal) * 100));
        return (
          <div key={ind.id} style={{ display: "grid", gridTemplateColumns: "minmax(220px, 1.6fr) minmax(160px, 1fr) 110px 100px 130px 110px", gap: 14, padding: "13px 18px", alignItems: "center", borderBottom: i === arr.length - 1 ? "none" : "1px solid var(--border-soft)", fontSize: 13 }}>
            <span style={{ fontWeight: 500 }}>{ind.name}</span>
            <span style={{ ...o9_meta }}>{prog?.name || "—"}</span>
            <span style={{ ...o9_meta }}>{ind.unit}</span>
            <span style={{ fontSize: 13, fontVariantNumeric: "tabular-nums", color: "var(--ink)" }}>{typeof ind.ytd === "number" ? ind.ytd.toLocaleString() : ind.ytd}</span>
            <div style={{ display: "flex", gap: 8, alignItems: "center" }}>
              <Progress value={pct} max={100} />
              <span style={{ fontSize: 11, color: "var(--fg-3)", fontVariantNumeric: "tabular-nums" }}>{pct}%</span>
            </div>
            <span style={{ ...o9_meta }}>{ind.last.split(" · ")[0]}</span>
          </div>
        );
      })}
    </Card>

    {viewAs !== "readonly" && (
      <>
        <SectionHead title="Latest qualitative evidence" />
        <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 14 }}>
          {STORIES.slice(0, 3).map(s => {
            const v = VOLUNTEERS.find(x => x.id === s.v);
            return (
              <Card key={s.id} padded={false} style={{ overflow: "hidden" }}>
                <div style={{ aspectRatio: "16/9", background: s.photo }} />
                <div style={{ padding: 16 }}>
                  <div style={{ display: "flex", gap: 8, alignItems: "center", marginBottom: 8 }}>
                    {v && <Avatar {...v} />}
                    <div>
                      <div style={{ fontSize: 13, fontWeight: 500 }}>{v?.name}</div>
                      <div style={{ ...o9_meta }}>{s.project}</div>
                    </div>
                  </div>
                  <div style={{ fontSize: 13, fontStyle: "italic", color: "var(--fg-1)", lineHeight: 1.6, fontFamily: "var(--font-serif)" }}>"{s.text}"</div>
                  <div style={{ display: "flex", gap: 6, marginTop: 12, flexWrap: "wrap" }}>
                    {Object.entries(s.metrics).map(([k, v]) => <span key={k} style={{ fontSize: 11, padding: "2px 8px", borderRadius: 999, background: "var(--paper-deep)", color: "var(--fg-1)" }}>{v} {k}</span>)}
                  </div>
                </div>
              </Card>
            );
          })}
        </div>
      </>
    )}
  </>
);

// ============================================================
// OBJECTIVES
// ============================================================
const Objectives = ({ viewAs, onNew }) => (
  <>
    <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 14 }}>
      <p style={{ fontSize: 13, color: "var(--fg-2)", maxWidth: 620, margin: 0 }}>
        Strategic objectives sit at the top of the outcomes hierarchy. Each objective rolls up programs, results, indicators, and indicator values.
      </p>
      <Btn size="sm" kind="secondary" icon={IconPlus} disabled={viewAs === "readonly"} onClick={onNew}>New objective</Btn>
    </div>
    <Card padded={false}>
      <div style={{ display: "grid", gridTemplateColumns: "minmax(220px, 1.6fr) minmax(160px, 1fr) 120px 110px 110px 120px 36px", gap: 14, padding: "12px 18px", fontSize: 11, letterSpacing: "0.1em", textTransform: "uppercase", color: "var(--fg-3)", borderBottom: "1px solid var(--border)" }}>
        <span>Objective</span><span>Owner</span><span>Date range</span><span>Programs</span><span>Indicators</span><span>State</span><span />
      </div>
      {OBJECTIVES.map((o, i, arr) => (
        <div key={o.id} style={{ display: "grid", gridTemplateColumns: "minmax(220px, 1.6fr) minmax(160px, 1fr) 120px 110px 110px 120px 36px", gap: 14, padding: "13px 18px", alignItems: "start", borderBottom: i === arr.length - 1 ? "none" : "1px solid var(--border-soft)", fontSize: 13 }}>
          <div>
            <div style={{ fontWeight: 500 }}>{o.name}</div>
            <div style={{ ...o9_meta, marginTop: 4, lineHeight: 1.4 }}>{o.narrative.slice(0, 100)}…</div>
          </div>
          <span style={{ ...o9_meta }}>{o.owner}</span>
          <span style={{ ...o9_meta }}>{o.start.split(",")[1]} → {o.end.split(",")[1]}</span>
          <span style={{ fontSize: 13, fontVariantNumeric: "tabular-nums" }}>{o.programs}</span>
          <span style={{ fontSize: 13, fontVariantNumeric: "tabular-nums" }}>{o.indicators}</span>
          <StatusChip status={o.state === "active" ? "confirmed" : "draft"} size="sm" label={o.state === "active" ? "Active" : "Draft"} />
          <IconBtn icon={IconMore} size={28} />
        </div>
      ))}
    </Card>
  </>
);

// ============================================================
// PROGRAMS
// ============================================================
const Programs = ({ viewAs, onOpen, onNew }) => {
  const filtered = viewAs === "regional" ? PROGRAMS_O.filter(p => p.scope.includes("NE") || p.scope.includes("Statewide")) : PROGRAMS_O;
  return (
    <>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 14 }}>
        <p style={{ fontSize: 13, color: "var(--fg-2)", maxWidth: 620, margin: 0 }}>
          Programs roll up under objectives. A program has a type, scope, lead, planned/actual dates, and the results that measure it.
        </p>
        <Btn size="sm" kind="secondary" icon={IconPlus} disabled={viewAs === "readonly"} onClick={onNew}>New program</Btn>
      </div>
      <div style={{ display: "grid", gridTemplateColumns: "repeat(2, 1fr)", gap: 14 }}>
        {filtered.map(p => {
          const obj = OBJECTIVES.find(o => o.id === p.objective);
          return (
            <Card key={p.id} style={{ cursor: "pointer" }} onClick={() => onOpen(p.id)}>
              <div style={{ display: "flex", justifyContent: "space-between", marginBottom: 8 }}>
                <span style={{ ...o9_over }}>{p.type}</span>
                <StatusChip status="confirmed" size="sm" label="Active" />
              </div>
              <div style={{ fontSize: 16, fontWeight: 500, color: "var(--ink)", marginBottom: 6 }}>{p.name}</div>
              <div style={{ ...o9_meta, marginBottom: 8 }}>Objective: {obj?.name}</div>
              <div style={{ fontSize: 12, color: "var(--fg-2)", marginBottom: 14 }}>{p.scope} · lead {p.lead}</div>
              <div style={{ display: "flex", gap: 14, fontSize: 11, color: "var(--fg-3)" }}>
                <span>{p.results} results</span>
                <span>{p.indicators} indicators</span>
                <span style={{ marginLeft: "auto" }}>Started {p.start}</span>
              </div>
            </Card>
          );
        })}
      </div>
    </>
  );
};

const ProgramDetail = ({ prog, onBack, onOpenIndicator }) => {
  const obj = OBJECTIVES.find(o => o.id === prog.objective);
  const results = RESULTS.filter(r => r.program === prog.id);
  const indicators = INDICATORS.filter(i => results.some(r => r.id === i.result));
  return (
    <>
      <TopBar title={prog.name}
        breadcrumb={["Outcomes & impact", "Programs", prog.name]} onBack={onBack}
        subtitle={`${prog.type} · scope: ${prog.scope} · lead ${prog.lead}`}
        primary={<Btn icon={IconEdit}>Edit program</Btn>}
        secondary={<Btn kind="secondary" icon={IconDownload}>Export program report</Btn>} />
      <div style={{ flex: 1, overflow: "auto", padding: "20px 32px 56px" }}>
        <Card style={{ marginBottom: 18 }}>
          <div style={{ ...o9_over, marginBottom: 6 }}>Rolls up to</div>
          <div style={{ fontSize: 15, fontWeight: 500, marginBottom: 6 }}>{obj?.name}</div>
          <div style={{ fontSize: 12, color: "var(--fg-2)" }}>{obj?.narrative}</div>
        </Card>

        <SectionHead title="Results" />
        <Card padded={false} style={{ marginBottom: 22 }}>
          {results.map((r, i, arr) => (
            <div key={r.id} style={{ display: "grid", gridTemplateColumns: "30px minmax(0, 1fr) 150px 110px 36px", gap: 14, padding: "12px 18px", alignItems: "center", borderBottom: i === arr.length - 1 ? "none" : "1px solid var(--border-soft)" }}>
              <span style={{ fontFamily: "var(--font-display)", fontSize: 18, color: "var(--fg-3)" }}>{i + 1}</span>
              <div>
                <div style={{ fontSize: 13, fontWeight: 500 }}>{r.name}</div>
                <div style={{ ...o9_meta, marginTop: 2 }}>{r.description}</div>
              </div>
              <span style={{ ...o9_meta }}>{r.start} → {r.end}</span>
              <StatusChip status="confirmed" size="sm" label="Active" />
              <IconBtn icon={IconMore} size={28} />
            </div>
          ))}
        </Card>

        <SectionHead title="Indicators in this program" />
        <Card padded={false}>
          <div style={{ display: "grid", gridTemplateColumns: "minmax(200px, 1.6fr) minmax(160px, 1fr) 110px 100px 130px 36px", gap: 14, padding: "12px 18px", fontSize: 11, letterSpacing: "0.1em", textTransform: "uppercase", color: "var(--fg-3)", borderBottom: "1px solid var(--border)" }}>
            <span>Indicator</span><span>Result</span><span>Unit</span><span>YTD</span><span>Goal · % to</span><span />
          </div>
          {indicators.map((ind, i, arr) => {
            const r = results.find(rs => rs.id === ind.result);
            const pct = ind.lower ? (ind.ytd === 0 ? 100 : 0) : Math.min(100, Math.round((ind.ytd / ind.goal) * 100));
            return (
              <div key={ind.id} onClick={() => onOpenIndicator(ind.id)} style={{ display: "grid", gridTemplateColumns: "minmax(200px, 1.6fr) minmax(160px, 1fr) 110px 100px 130px 36px", gap: 14, padding: "13px 18px", alignItems: "center", borderBottom: i === arr.length - 1 ? "none" : "1px solid var(--border-soft)", cursor: "pointer", fontSize: 13 }}>
                <span style={{ fontWeight: 500 }}>{ind.name}</span>
                <span style={{ ...o9_meta }}>{r?.name}</span>
                <span style={{ ...o9_meta }}>{ind.unit}</span>
                <span style={{ fontSize: 13, fontVariantNumeric: "tabular-nums", color: "var(--ink)" }}>{typeof ind.ytd === "number" ? ind.ytd.toLocaleString() : ind.ytd}</span>
                <div style={{ display: "flex", gap: 8, alignItems: "center" }}>
                  <Progress value={pct} max={100} />
                  <span style={{ fontSize: 11, color: "var(--fg-3)", fontVariantNumeric: "tabular-nums" }}>{pct}%</span>
                </div>
                <IconBtn icon={IconExternal} size={28} />
              </div>
            );
          })}
        </Card>
      </div>
    </>
  );
};

// ============================================================
// RESULTS TAB
// ============================================================
const Results = () => (
  <>
    <p style={{ fontSize: 13, color: "var(--fg-2)", marginBottom: 14, maxWidth: 620 }}>
      Results sit under programs and describe what success looks like. Indicators measure progress against results.
    </p>
    <Card padded={false}>
      <div style={{ display: "grid", gridTemplateColumns: "minmax(220px, 1.6fr) minmax(180px, 1.2fr) minmax(180px, 1.4fr) 130px 100px 36px", gap: 14, padding: "12px 18px", fontSize: 11, letterSpacing: "0.1em", textTransform: "uppercase", color: "var(--fg-3)", borderBottom: "1px solid var(--border)" }}>
        <span>Result</span><span>Program</span><span>Description</span><span>Date range</span><span>State</span><span />
      </div>
      {RESULTS.map((r, i, arr) => {
        const p = PROGRAMS_O.find(x => x.id === r.program);
        return (
          <div key={r.id} style={{ display: "grid", gridTemplateColumns: "minmax(220px, 1.6fr) minmax(180px, 1.2fr) minmax(180px, 1.4fr) 130px 100px 36px", gap: 14, padding: "12px 18px", alignItems: "center", borderBottom: i === arr.length - 1 ? "none" : "1px solid var(--border-soft)", fontSize: 13 }}>
            <span style={{ fontWeight: 500 }}>{r.name}</span>
            <span style={{ ...o9_meta }}>{p?.name}</span>
            <span style={{ fontSize: 12, color: "var(--fg-2)", lineHeight: 1.4 }}>{r.description}</span>
            <span style={{ ...o9_meta }}>{r.start} → {r.end}</span>
            <StatusChip status="confirmed" size="sm" label="Active" />
            <IconBtn icon={IconMore} size={28} />
          </div>
        );
      })}
    </Card>
  </>
);

// ============================================================
// INDICATORS
// ============================================================
const Indicators = ({ viewAs, onOpen, onNew }) => (
  <>
    <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 14 }}>
      <p style={{ fontSize: 13, color: "var(--fg-2)", maxWidth: 620, margin: 0 }}>
        Indicators measure progress on results. Click any indicator to see its values, sources, and beneficiary attribution.
      </p>
      <Btn size="sm" kind="secondary" icon={IconPlus} disabled={viewAs === "readonly"} onClick={onNew}>New indicator</Btn>
    </div>
    <Card padded={false}>
      <div style={{ display: "grid", gridTemplateColumns: "minmax(200px, 1.5fr) minmax(160px, 1.1fr) 100px 100px 100px 130px 36px", gap: 14, padding: "12px 18px", fontSize: 11, letterSpacing: "0.1em", textTransform: "uppercase", color: "var(--fg-3)", borderBottom: "1px solid var(--border)" }}>
        <span>Indicator</span><span>Result</span><span>Unit</span><span>Type</span><span>YTD</span><span>Goal · % to</span><span />
      </div>
      {INDICATORS.map((ind, i, arr) => {
        const r = RESULTS.find(rs => rs.id === ind.result);
        const pct = ind.lower ? (ind.ytd === 0 ? 100 : 0) : Math.min(100, Math.round((ind.ytd / ind.goal) * 100));
        return (
          <div key={ind.id} onClick={() => onOpen(ind.id)} style={{ display: "grid", gridTemplateColumns: "minmax(200px, 1.5fr) minmax(160px, 1.1fr) 100px 100px 100px 130px 36px", gap: 14, padding: "13px 18px", alignItems: "center", borderBottom: i === arr.length - 1 ? "none" : "1px solid var(--border-soft)", cursor: "pointer", fontSize: 13 }}>
            <span style={{ fontWeight: 500 }}>{ind.name}</span>
            <span style={{ ...o9_meta }}>{r?.name}</span>
            <span style={{ ...o9_meta }}>{ind.unit}</span>
            <span style={{ ...o9_meta, textTransform: "capitalize" }}>{ind.type}</span>
            <span style={{ fontSize: 13, fontVariantNumeric: "tabular-nums", color: "var(--ink)" }}>{typeof ind.ytd === "number" ? ind.ytd.toLocaleString() : ind.ytd}</span>
            <div style={{ display: "flex", gap: 8, alignItems: "center" }}>
              <Progress value={pct} max={100} />
              <span style={{ fontSize: 11, color: "var(--fg-3)", fontVariantNumeric: "tabular-nums" }}>{pct}%</span>
            </div>
            <IconBtn icon={IconExternal} size={28} />
          </div>
        );
      })}
    </Card>
  </>
);

const IndicatorDetail = ({ ind, onBack }) => {
  const r = RESULTS.find(rs => rs.id === ind.result);
  const p = PROGRAMS_O.find(pr => pr.id === r?.program);
  const o = OBJECTIVES.find(obj => obj.id === p?.objective);
  const values = INDICATOR_VALUES_SAMPLE.filter(v => v.unit === ind.unit).slice(0, 5);
  const pct = ind.lower ? (ind.ytd === 0 ? 100 : 0) : Math.min(100, Math.round((ind.ytd / ind.goal) * 100));
  return (
    <>
      <TopBar title={ind.name}
        breadcrumb={["Outcomes & impact", "Indicators", ind.name]} onBack={onBack}
        subtitle={`${ind.unit} · ${ind.type} · last updated ${ind.last}`}
        primary={<Btn icon={IconPlus}>Record value</Btn>}
        secondary={<Btn kind="secondary" icon={IconDownload}>Export history</Btn>} />
      <div style={{ flex: 1, overflow: "auto", padding: "20px 32px 56px" }}>
        <Card style={{ marginBottom: 18 }}>
          <div style={{ ...o9_over, marginBottom: 8 }}>Rolls up</div>
          <div style={{ display: "grid", gridTemplateColumns: "auto auto auto 1fr", gap: 10, alignItems: "center", fontSize: 13 }}>
            <span style={{ padding: "5px 11px", borderRadius: 999, background: "var(--paper-deep)" }}>{o?.name}</span>
            <span style={{ color: "var(--fg-3)" }}>→</span>
            <span style={{ padding: "5px 11px", borderRadius: 999, background: "var(--paper-deep)" }}>{p?.name}</span>
            <span style={{ color: "var(--fg-3)" }}>→</span>
          </div>
          <div style={{ display: "grid", gridTemplateColumns: "auto auto 1fr", gap: 10, alignItems: "center", fontSize: 13, marginTop: 8 }}>
            <span style={{ padding: "5px 11px", borderRadius: 999, background: "var(--paper-deep)" }}>{r?.name}</span>
            <span style={{ color: "var(--fg-3)" }}>→</span>
            <span style={{ padding: "5px 11px", borderRadius: 999, background: "var(--coral-100)", color: "var(--coral-700)", fontWeight: 500 }}>{ind.name}</span>
          </div>
        </Card>

        <div style={{ display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 14, marginBottom: 22 }}>
          <Kpi label="YTD" value={typeof ind.ytd === "number" ? ind.ytd.toLocaleString() : ind.ytd} delta={`Unit: ${ind.unit}`} tone="up" icon={IconAward} />
          <Kpi label="Goal" value={ind.goal.toLocaleString()} delta={`${pct}% to goal`} tone="up" icon={IconShield} />
          <Kpi label="Type" value={ind.type} delta={ind.lower ? "Lower-is-better" : "Higher-is-better"} tone="neutral" icon={IconStar} />
          <Kpi label="Values recorded" value={values.length.toString()} delta="in last 60 days" tone="neutral" icon={IconClipboard} />
        </div>

        <SectionHead title="Recent values" />
        <Card padded={false}>
          <div style={{ display: "grid", gridTemplateColumns: "130px 100px 130px minmax(220px, 1.6fr) minmax(160px, 1fr) 130px 36px", gap: 14, padding: "12px 18px", fontSize: 11, letterSpacing: "0.1em", textTransform: "uppercase", color: "var(--fg-3)", borderBottom: "1px solid var(--border)" }}>
            <span>Date</span><span>Value</span><span>Source</span><span>Note</span><span>Beneficiary</span><span>Staff</span><span />
          </div>
          {values.map((v, i, arr) => (
            <div key={i} style={{ display: "grid", gridTemplateColumns: "130px 100px 130px minmax(220px, 1.6fr) minmax(160px, 1fr) 130px 36px", gap: 14, padding: "13px 18px", alignItems: "center", borderBottom: i === arr.length - 1 ? "none" : "1px solid var(--border-soft)", fontSize: 13 }}>
              <span style={{ ...o9_meta }}>{v.date}</span>
              <span style={{ fontVariantNumeric: "tabular-nums", fontWeight: 500 }}>{v.value}</span>
              <span style={{ ...o9_meta }}>{v.source.split(" · ")[0]}</span>
              <span style={{ fontSize: 12, color: "var(--fg-2)", lineHeight: 1.4 }}>{v.note}</span>
              <span style={{ ...o9_meta }}>{(BENEFICIARIES.find(b => b.id === v.beneficiaries) || {}).name || v.beneficiaries || "—"}</span>
              <span style={{ ...o9_meta }}>{v.staff}</span>
              <IconBtn icon={IconMore} size={28} />
            </div>
          ))}
        </Card>

        <div style={{ marginTop: 22, padding: 14, background: "var(--iris-100)", color: "var(--iris-600)", borderRadius: 12, fontSize: 12, lineHeight: 1.5 }}>
          <IconShield size={14} style={{ verticalAlign: "middle", marginRight: 6 }} />
          Indicator values are separate from approved hours and attendance. Edits here do not change service totals, grant exports, or recognition calculations.
        </div>
      </div>
    </>
  );
};

// ============================================================
// INDICATOR VALUES (cross-indicator)
// ============================================================
const IndicatorValues = () => (
  <>
    <p style={{ fontSize: 13, color: "var(--fg-2)", marginBottom: 14, maxWidth: 620 }}>
      All recorded indicator values across programs. Drill into any to see the source project/event, the staff recorder, and the beneficiary attribution.
    </p>
    <div style={{ display: "flex", gap: 8, marginBottom: 14 }}>
      <Btn size="sm" kind="ghost" icon={IconFilter}>Filter</Btn>
      <Btn size="sm" kind="ghost">Last 30 days</Btn>
      <div style={{ marginLeft: "auto", display: "flex", gap: 6 }}>
        <Btn size="sm" kind="secondary" icon={IconUpload}>Bulk record</Btn>
        <Btn size="sm" icon={IconPlus}>Record value</Btn>
      </div>
    </div>
    <Card padded={false}>
      <div style={{ display: "grid", gridTemplateColumns: "130px minmax(180px, 1.4fr) 100px 100px minmax(200px, 1.6fr) minmax(160px, 1fr) 130px", gap: 14, padding: "12px 18px", fontSize: 11, letterSpacing: "0.1em", textTransform: "uppercase", color: "var(--fg-3)", borderBottom: "1px solid var(--border)" }}>
        <span>Date</span><span>Indicator</span><span>Value</span><span>Unit</span><span>Source</span><span>Beneficiary</span><span>Staff</span>
      </div>
      {INDICATOR_VALUES_SAMPLE.map((v, i, arr) => {
        const ind = INDICATORS.find(x => x.unit === v.unit) || INDICATORS[0];
        return (
          <div key={i} style={{ display: "grid", gridTemplateColumns: "130px minmax(180px, 1.4fr) 100px 100px minmax(200px, 1.6fr) minmax(160px, 1fr) 130px", gap: 14, padding: "13px 18px", alignItems: "center", borderBottom: i === arr.length - 1 ? "none" : "1px solid var(--border-soft)", fontSize: 13 }}>
            <span style={{ ...o9_meta }}>{v.date}</span>
            <span style={{ fontWeight: 500 }}>{ind.name}</span>
            <span style={{ fontVariantNumeric: "tabular-nums" }}>{v.value}</span>
            <span style={{ ...o9_meta }}>{v.unit}</span>
            <span style={{ ...o9_meta }}>{v.source}</span>
            <span style={{ ...o9_meta }}>{(BENEFICIARIES.find(b => b.id === v.beneficiaries) || {}).name || v.beneficiaries || "—"}</span>
            <span style={{ ...o9_meta }}>{v.staff}</span>
          </div>
        );
      })}
    </Card>
  </>
);

// ============================================================
// BENEFICIARIES
// ============================================================
const Beneficiaries = () => {
  const [kind, setKind] = useO9("all");
  const filtered = kind === "all" ? BENEFICIARIES : BENEFICIARIES.filter(b => b.kind === kind);
  return (
    <>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 14 }}>
        <p style={{ fontSize: 13, color: "var(--fg-2)", maxWidth: 620, margin: 0 }}>
          Beneficiaries are the people, organizations, students, partners, or constituents your outcomes serve. A single record can represent an organization or an aggregate of individuals.
        </p>
        <Btn size="sm" kind="secondary" icon={IconPlus}>New beneficiary</Btn>
      </div>
      <div style={{ display: "flex", gap: 8, marginBottom: 14 }}>
        {[
          { id: "all", t: "All", n: BENEFICIARIES.length },
          { id: "organization", t: "Organizations", n: BENEFICIARIES.filter(b => b.kind === "organization").length },
          { id: "individual", t: "Individuals / aggregate", n: BENEFICIARIES.filter(b => b.kind === "individual").length },
        ].map(f => (
          <button key={f.id} onClick={() => setKind(f.id)} style={{
            padding: "7px 13px", borderRadius: 999, fontSize: 12, fontWeight: 500, cursor: "pointer", fontFamily: "inherit",
            background: kind === f.id ? "var(--coral-100)" : "transparent",
            color: kind === f.id ? "var(--coral-700)" : "var(--fg-1)",
            border: "1px solid " + (kind === f.id ? "var(--coral-200)" : "var(--border)"),
          }}>{f.t} <span style={{ opacity: 0.65, marginLeft: 4 }}>{f.n}</span></button>
        ))}
      </div>
      <Card padded={false}>
        <div style={{ display: "grid", gridTemplateColumns: "minmax(220px, 1.6fr) 130px 120px minmax(160px, 1fr) 100px 100px 36px", gap: 14, padding: "12px 18px", fontSize: 11, letterSpacing: "0.1em", textTransform: "uppercase", color: "var(--fg-3)", borderBottom: "1px solid var(--border)" }}>
          <span>Beneficiary</span><span>Kind</span><span>Type</span><span>Description</span><span>Programs</span><span>Attributed</span><span />
        </div>
        {filtered.map((b, i, arr) => (
          <div key={b.id} style={{ display: "grid", gridTemplateColumns: "minmax(220px, 1.6fr) 130px 120px minmax(160px, 1fr) 100px 100px 36px", gap: 14, padding: "13px 18px", alignItems: "center", borderBottom: i === arr.length - 1 ? "none" : "1px solid var(--border-soft)", fontSize: 13 }}>
            <div>
              <div style={{ fontWeight: 500 }}>{b.name}</div>
              <div style={{ ...o9_meta, marginTop: 2 }}>{b.scope}</div>
            </div>
            <span style={{ ...o9_meta, textTransform: "capitalize" }}>{b.kind === "organization" ? "Organization" : "Aggregate"}</span>
            <span style={{ ...o9_meta }}>{b.type}</span>
            <span style={{ fontSize: 12, color: "var(--fg-2)", lineHeight: 1.4 }}>{b.desc}</span>
            <span style={{ fontSize: 13, fontVariantNumeric: "tabular-nums" }}>{b.programs}</span>
            <span style={{ fontSize: 13, fontVariantNumeric: "tabular-nums" }}>{b.attributed.toLocaleString()}</span>
            <IconBtn icon={IconMore} size={28} />
          </div>
        ))}
      </Card>
      <div style={{ marginTop: 18, padding: 14, background: "var(--paper-soft)", borderRadius: 12, fontSize: 12, color: "var(--fg-2)", lineHeight: 1.5, border: "1px solid var(--border-soft)" }}>
        <IconShield size={14} style={{ verticalAlign: "middle", marginRight: 6, color: "var(--fg-3)" }} />
        Beneficiary records follow tenant data-minimization policy. PII fields are only collected when needed for reporting and respect retention rules. This is intentionally simpler than a full CRM.
      </div>
    </>
  );
};

// ============================================================
// STORIES
// ============================================================
const Stories = () => (
  <>
    <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 14 }}>
      <p style={{ fontSize: 13, color: "var(--fg-2)", maxWidth: 620, margin: 0 }}>
        Qualitative evidence — quotes, notes, photos, and links — that bring the numbers to life in funder and board reports. Subject to volunteer media consent.
      </p>
      <Btn size="sm" kind="secondary" icon={IconPlus}>Add story</Btn>
    </div>
    <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 14 }}>
      {STORIES.map(s => {
        const v = VOLUNTEERS.find(x => x.id === s.v);
        return (
          <Card key={s.id} padded={false} style={{ overflow: "hidden" }}>
            <div style={{ aspectRatio: "16/9", background: s.photo }} />
            <div style={{ padding: 16 }}>
              <div style={{ display: "flex", gap: 8, alignItems: "center", marginBottom: 8 }}>
                {v && <Avatar {...v} />}
                <div>
                  <div style={{ fontSize: 13, fontWeight: 500 }}>{v?.name}</div>
                  <div style={{ ...o9_meta }}>{s.project}</div>
                </div>
              </div>
              <div style={{ fontSize: 13, fontStyle: "italic", color: "var(--fg-1)", lineHeight: 1.6, fontFamily: "var(--font-serif)" }}>"{s.text}"</div>
              <div style={{ display: "flex", gap: 6, marginTop: 12, flexWrap: "wrap" }}>
                {Object.entries(s.metrics).map(([k, v]) => <span key={k} style={{ fontSize: 11, padding: "2px 8px", borderRadius: 999, background: "var(--paper-deep)", color: "var(--fg-1)" }}>{v} {k}</span>)}
              </div>
              <div style={{ display: "flex", gap: 6, marginTop: 12 }}>
                <Btn size="sm" kind="ghost">Edit</Btn>
                <Btn size="sm" kind="ghost" icon={IconExternal}>Share</Btn>
              </div>
            </div>
          </Card>
        );
      })}
    </div>
  </>
);

// ============================================================
// CAPTURE CONFIG — FR7
// ============================================================
const CaptureConfig = () => (
  <>
    <p style={{ fontSize: 13, color: "var(--fg-2)", marginBottom: 18, maxWidth: 620 }}>
      Configure which outcomes can be captured from projects, events, trainings, and self-scheduled role hour workflows. Captured values feed indicators without modifying approved hours or attendance.
    </p>

    <SectionHead title="Capture forms" />
    <Card padded={false} style={{ marginBottom: 22 }}>
      <div style={{ display: "grid", gridTemplateColumns: "minmax(200px, 1.4fr) minmax(180px, 1fr) minmax(180px, 1.4fr) 130px 100px 36px", gap: 14, padding: "12px 18px", fontSize: 11, letterSpacing: "0.1em", textTransform: "uppercase", color: "var(--fg-3)", borderBottom: "1px solid var(--border)" }}>
        <span>Form</span><span>Applies to</span><span>Outputs captured</span><span>Required?</span><span>State</span><span />
      </div>
      {[
        { name: "Trail crew workday",     applies: "Opportunity type: Trail crew",    outputs: ["Miles improved", "Trees planted", "Hours"], req: true,  state: "active" },
        { name: "Shoreline cleanup",       applies: "Opportunity type: Cleanup",        outputs: ["Material (lbs)", "Miles cleared", "Animals (if found)"], req: true, state: "active" },
        { name: "Hunter ed class",         applies: "Program: Hunter Outreach",          outputs: ["Students certified", "Instructor hours", "Class size"], req: true, state: "active" },
        { name: "Naturalist program day",   applies: "Program: Naturalist program",       outputs: ["Visitors contacted", "Programs delivered", "Notes"], req: true, state: "active" },
        { name: "Self-scheduled patrol",    applies: "Role: Trail steward (self-sched.)", outputs: ["Miles patrolled", "Conditions noted", "Hours"], req: false, state: "active" },
        { name: "Corporate volunteer day",   applies: "Program: Corporate volunteer days",  outputs: ["Volunteers hosted", "Hours", "Material (if any)"], req: false, state: "draft" },
      ].map((f, i, arr) => (
        <div key={i} style={{ display: "grid", gridTemplateColumns: "minmax(200px, 1.4fr) minmax(180px, 1fr) minmax(180px, 1.4fr) 130px 100px 36px", gap: 14, padding: "12px 18px", alignItems: "center", borderBottom: i === arr.length - 1 ? "none" : "1px solid var(--border-soft)", fontSize: 13 }}>
          <div>
            <div style={{ fontWeight: 500 }}>{f.name}</div>
          </div>
          <span style={{ ...o9_meta }}>{f.applies}</span>
          <div style={{ display: "flex", gap: 4, flexWrap: "wrap" }}>
            {f.outputs.map(o => <span key={o} style={{ fontSize: 10, padding: "1px 7px", borderRadius: 4, background: "var(--paper-deep)", color: "var(--fg-2)" }}>{o}</span>)}
          </div>
          <Checkbox checked={f.req} onChange={() => {}} label={f.req ? "Required" : "Optional"} />
          <StatusChip status={f.state === "active" ? "confirmed" : "draft"} size="sm" label={f.state[0].toUpperCase() + f.state.slice(1)} />
          <IconBtn icon={IconMore} size={28} />
        </div>
      ))}
    </Card>

    <SectionHead title="Sample capture form preview · Trail crew workday" />
    <Card>
      <p style={{ fontSize: 13, color: "var(--fg-2)", marginBottom: 14 }}>
        This is what volunteers and on-site leads see when they capture outcomes for a Trail crew workday after completing the shift.
      </p>
      <div style={{ display: "grid", gridTemplateColumns: "repeat(2, 1fr)", gap: 14 }}>
        <Field label="Miles improved"><Input type="number" placeholder="0.0" /></Field>
        <Field label="Trees planted"><Input type="number" placeholder="0" /></Field>
        <Field label="Crew size">
          <Input type="number" defaultValue="6" />
        </Field>
        <Field label="Visitors encountered">
          <Input type="number" placeholder="0" />
        </Field>
      </div>
      <Field label="Notes (visible in stories if photo released)">
        <Textarea rows={3} placeholder="What changed about this section of trail today? Anything notable?" />
      </Field>
      <Field label="Photo (optional)">
        <Btn size="sm" kind="secondary" icon={IconUpload}>Upload photo</Btn>
        <span style={{ ...o9_meta, marginLeft: 12 }}>Goes into outcomes story only if volunteer has signed the media release.</span>
      </Field>
      <div style={{ marginTop: 14, padding: 12, background: "var(--paper-deep)", borderRadius: 10, fontSize: 12, color: "var(--fg-2)", lineHeight: 1.5 }}>
        <IconShield size={13} style={{ verticalAlign: "middle", marginRight: 6, color: "var(--fg-3)" }} />
        Outcome values do not modify approved hours, attendance, or recognition. If corrections are needed to those, a separately permissioned hour-correction workflow is used.
      </div>
    </Card>
  </>
);

// ============================================================
// CREATE DRAWERS — new objective, program, indicator
// ============================================================
const o9_overlay = { position: "fixed", inset: 0, background: "rgba(31,27,22,0.45)", backdropFilter: "blur(4px)", zIndex: 80, display: "flex", justifyContent: "flex-end" };
const o9_drawer  = { width: "min(720px, 100%)", height: "100%", background: "var(--paper)", display: "flex", flexDirection: "column", boxShadow: "var(--shadow-lg)" };
const o9_head    = { padding: "20px 24px 16px", display: "flex", justifyContent: "space-between", alignItems: "start", gap: 14, borderBottom: "1px solid var(--border-soft)" };
const o9_foot    = { padding: "14px 24px", borderTop: "1px solid var(--border-soft)", display: "flex", alignItems: "center", gap: 8, background: "var(--paper-soft)" };

// ---- NEW OBJECTIVE ----
const NewObjectiveDrawer = ({ onClose }) => {
  const [data, setData] = useO9({
    name: "", narrative: "",
    owner: "", scope: "Statewide",
    start: "", end: "",
    state: "draft",
    publishImmediately: false,
  });
  const [submitted, setSubmitted] = useO9(false);
  const update = (patch) => setData({ ...data, ...patch });

  if (submitted) return <CreateDone kind="Objective" name={data.name} onClose={onClose} onAnother={() => { setSubmitted(false); setData({ name: "", narrative: "", owner: "", scope: "Statewide", start: "", end: "", state: "draft", publishImmediately: false }); }} />;

  return (
    <div style={o9_overlay} onClick={onClose}>
      <div style={o9_drawer} onClick={(e) => e.stopPropagation()}>
        <div style={o9_head}>
          <div>
            <div style={o9_over}>New strategic objective</div>
            <div style={{ fontSize: 19, fontWeight: 500, color: "var(--ink)", marginTop: 4 }}>Top-level outcome</div>
            <div style={{ fontSize: 12, color: "var(--fg-2)", marginTop: 4, maxWidth: 540 }}>
              Strategic objectives are multi-year goals. Programs roll up under them. Each indicator value eventually rolls up to one objective.
            </div>
          </div>
          <IconBtn icon={IconX} size={32} onClick={onClose} aria-label="Close" />
        </div>
        <div style={{ flex: 1, overflow: "auto", padding: 24 }}>
          <Field label="Objective name" required>
            <Input value={data.name} onChange={(e) => update({ name: e.target.value })}
              placeholder="e.g. Conservation of Colorado's lands & waters" autoFocus />
          </Field>
          <Field label="Narrative">
            <Textarea rows={4} value={data.narrative} onChange={(e) => update({ narrative: e.target.value })}
              placeholder="The why behind this objective. Reviewers read this when interpreting indicator values and impact." />
          </Field>
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 14 }}>
            <Field label="Owner" required>
              <Select value={data.owner} onChange={(e) => update({ owner: e.target.value })}
                options={[
                  { value: "", label: "— select —" },
                  { value: "Aliyah Chen · Statewide", label: "Aliyah Chen · Statewide" },
                  { value: "Marcus Chen · Hunter Outreach", label: "Marcus Chen · Hunter Outreach" },
                  { value: "Priya Sandoval · NE Region", label: "Priya Sandoval · NE Region" },
                ]} />
            </Field>
            <Field label="Scope">
              <Select value={data.scope} onChange={(e) => update({ scope: e.target.value })}
                options={["Statewide", "Northeast region", "Northwest region", "Southeast region", "Southwest region"]} />
            </Field>
            <Field label="Start date" required>
              <Input type="date" value={data.start} onChange={(e) => update({ start: e.target.value })} />
            </Field>
            <Field label="End date">
              <Input type="date" value={data.end} onChange={(e) => update({ end: e.target.value })} />
            </Field>
          </div>
          <Field label="State">
            <div style={{ display: "flex", gap: 8 }}>
              {[
                { id: "draft",  t: "Draft",  d: "Only visible to authors. Cannot link programs yet." },
                { id: "active", t: "Active", d: "Live. Programs can be linked and indicator values roll up." },
              ].map(s => (
                <Card key={s.id} onClick={() => update({ state: s.id })} style={{ padding: 14, cursor: "pointer", flex: 1, borderColor: data.state === s.id ? "var(--coral-500)" : "var(--border-soft)", borderWidth: data.state === s.id ? 2 : 1 }}>
                  <div style={{ fontSize: 13, fontWeight: 500 }}>{s.t}</div>
                  <div style={{ ...o9_meta, marginTop: 3 }}>{s.d}</div>
                </Card>
              ))}
            </div>
          </Field>
          <div style={{ marginTop: 14, padding: 12, background: "var(--paper-deep)", borderRadius: 10, fontSize: 12, color: "var(--fg-2)", lineHeight: 1.5 }}>
            <IconShield size={13} style={{ verticalAlign: "middle", marginRight: 6, color: "var(--fg-3)" }} />
            Objective records create an immutable audit entry. You can edit details later, but date ranges and identity changes are logged.
          </div>
        </div>
        <div style={o9_foot}>
          <Btn kind="ghost" onClick={onClose}>Cancel</Btn>
          <div style={{ marginLeft: "auto", display: "flex", gap: 8 }}>
            <Btn kind="secondary" onClick={() => { update({ state: "draft" }); setSubmitted(true); }}>Save as draft</Btn>
            <Btn icon={IconCheck} onClick={() => setSubmitted(true)} disabled={!data.name || !data.owner || !data.start}>Create objective</Btn>
          </div>
        </div>
      </div>
    </div>
  );
};

// ---- NEW PROGRAM ----
const NewProgramDrawer = ({ onClose }) => {
  const [data, setData] = useO9({
    name: "", type: "Operational",
    objective: "", scope: "",
    lead: "", plannedStart: "", plannedEnd: "",
    goal: "",
    state: "draft",
    initialResults: 1,
  });
  const [submitted, setSubmitted] = useO9(false);
  const update = (patch) => setData({ ...data, ...patch });

  if (submitted) return <CreateDone kind="Program" name={data.name} onClose={onClose} onAnother={() => { setSubmitted(false); setData({ name: "", type: "Operational", objective: "", scope: "", lead: "", plannedStart: "", plannedEnd: "", goal: "", state: "draft", initialResults: 1 }); }} />;

  return (
    <div style={o9_overlay} onClick={onClose}>
      <div style={o9_drawer} onClick={(e) => e.stopPropagation()}>
        <div style={o9_head}>
          <div>
            <div style={o9_over}>New program</div>
            <div style={{ fontSize: 19, fontWeight: 500, color: "var(--ink)", marginTop: 4 }}>Operational unit that delivers outcomes</div>
            <div style={{ fontSize: 12, color: "var(--fg-2)", marginTop: 4, maxWidth: 540 }}>
              A program has a type, scope, lead, and results that measure it. Each program belongs to one strategic objective.
            </div>
          </div>
          <IconBtn icon={IconX} size={32} onClick={onClose} aria-label="Close" />
        </div>
        <div style={{ flex: 1, overflow: "auto", padding: 24 }}>
          <Field label="Program name" required>
            <Input value={data.name} onChange={(e) => update({ name: e.target.value })}
              placeholder="e.g. Trail crew & maintenance" autoFocus />
          </Field>
          <Field label="Rolls up to objective" required>
            <Select value={data.objective} onChange={(e) => update({ objective: e.target.value })}
              options={[
                { value: "", label: "— select an objective —" },
                ...OBJECTIVES.filter(o => o.state === "active").map(o => ({ value: o.id, label: o.name })),
              ]} />
          </Field>
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 14 }}>
            <Field label="Type" required>
              <Select value={data.type} onChange={(e) => update({ type: e.target.value })}
                options={["Operational", "Education", "Partnership", "Research"]} />
            </Field>
            <Field label="Lead" required>
              <Select value={data.lead} onChange={(e) => update({ lead: e.target.value })}
                options={[
                  { value: "", label: "— select —" },
                  { value: "Priya Sandoval", label: "Priya Sandoval (NE)" },
                  { value: "Marcus Chen",     label: "Marcus Chen" },
                  { value: "Aliyah Chen",     label: "Aliyah Chen" },
                ]} />
            </Field>
            <Field label="Scope" required>
              <Input value={data.scope} onChange={(e) => update({ scope: e.target.value })}
                placeholder="e.g. Statewide · 42 parks" />
            </Field>
            <Field label="Initial results">
              <Select value={String(data.initialResults)} onChange={(e) => update({ initialResults: parseInt(e.target.value, 10) })}
                options={[
                  { value: "0", label: "Add later" },
                  { value: "1", label: "1 result (recommended)" },
                  { value: "3", label: "3 results (full)" },
                ]} />
            </Field>
            <Field label="Planned start" required>
              <Input type="date" value={data.plannedStart} onChange={(e) => update({ plannedStart: e.target.value })} />
            </Field>
            <Field label="Planned end">
              <Input type="date" value={data.plannedEnd} onChange={(e) => update({ plannedEnd: e.target.value })} />
            </Field>
          </div>
          <Field label="Goal narrative">
            <Textarea rows={3} value={data.goal} onChange={(e) => update({ goal: e.target.value })}
              placeholder="What this program is trying to achieve. Used in funder reports." />
          </Field>
          <Field label="State">
            <div style={{ display: "flex", gap: 8 }}>
              {[
                { id: "draft",  t: "Draft",  d: "Hidden from regional admins. Cannot record indicator values yet." },
                { id: "active", t: "Active", d: "Live. Indicator values can be recorded." },
              ].map(s => (
                <Card key={s.id} onClick={() => update({ state: s.id })} style={{ padding: 14, cursor: "pointer", flex: 1, borderColor: data.state === s.id ? "var(--coral-500)" : "var(--border-soft)", borderWidth: data.state === s.id ? 2 : 1 }}>
                  <div style={{ fontSize: 13, fontWeight: 500 }}>{s.t}</div>
                  <div style={{ ...o9_meta, marginTop: 3 }}>{s.d}</div>
                </Card>
              ))}
            </div>
          </Field>
          {data.initialResults > 0 && (
            <div style={{ marginTop: 14, padding: 12, background: "var(--iris-100)", color: "var(--iris-600)", borderRadius: 10, fontSize: 12, lineHeight: 1.5 }}>
              <IconClipboard size={13} style={{ verticalAlign: "middle", marginRight: 6 }} />
              {data.initialResults} placeholder result{data.initialResults === 1 ? "" : "s"} will be created with the program. You can rename them and add indicators on the next screen.
            </div>
          )}
        </div>
        <div style={o9_foot}>
          <Btn kind="ghost" onClick={onClose}>Cancel</Btn>
          <div style={{ marginLeft: "auto", display: "flex", gap: 8 }}>
            <Btn kind="secondary" onClick={() => { update({ state: "draft" }); setSubmitted(true); }}>Save as draft</Btn>
            <Btn icon={IconCheck} onClick={() => setSubmitted(true)}
              disabled={!data.name || !data.objective || !data.lead || !data.scope || !data.plannedStart}>
              Create program
            </Btn>
          </div>
        </div>
      </div>
    </div>
  );
};

// ---- NEW INDICATOR ----
const NewIndicatorDrawer = ({ onClose }) => {
  const [data, setData] = useO9({
    name: "", result: "",
    unit: "", valueType: "count", direction: "higher",
    goal: "", description: "",
    start: "", end: "",
    state: "draft",
    captureSource: "manual",
  });
  const [submitted, setSubmitted] = useO9(false);
  const update = (patch) => setData({ ...data, ...patch });
  const selectedResult = RESULTS.find(r => r.id === data.result);
  const parentProgram = selectedResult ? PROGRAMS_O.find(p => p.id === selectedResult.program) : null;
  const parentObjective = parentProgram ? OBJECTIVES.find(o => o.id === parentProgram.objective) : null;

  if (submitted) return <CreateDone kind="Indicator" name={data.name} onClose={onClose} onAnother={() => { setSubmitted(false); setData({ name: "", result: "", unit: "", valueType: "count", direction: "higher", goal: "", description: "", start: "", end: "", state: "draft", captureSource: "manual" }); }} />;

  return (
    <div style={o9_overlay} onClick={onClose}>
      <div style={o9_drawer} onClick={(e) => e.stopPropagation()}>
        <div style={o9_head}>
          <div>
            <div style={o9_over}>New indicator</div>
            <div style={{ fontSize: 19, fontWeight: 500, color: "var(--ink)", marginTop: 4 }}>Measure progress on a result</div>
            <div style={{ fontSize: 12, color: "var(--fg-2)", marginTop: 4, maxWidth: 540 }}>
              Indicators are the numbers you report. Each indicator has a unit, value type, and goal. Values are recorded over time and attributed to beneficiaries.
            </div>
          </div>
          <IconBtn icon={IconX} size={32} onClick={onClose} aria-label="Close" />
        </div>
        <div style={{ flex: 1, overflow: "auto", padding: 24 }}>
          <Field label="Measures which result" required>
            <Select value={data.result} onChange={(e) => update({ result: e.target.value })}
              options={[
                { value: "", label: "— select a result —" },
                ...RESULTS.map(r => {
                  const p = PROGRAMS_O.find(x => x.id === r.program);
                  return { value: r.id, label: `${p?.name} → ${r.name}` };
                }),
              ]} />
          </Field>

          {selectedResult && parentProgram && parentObjective && (
            <Card style={{ background: "var(--paper-soft)", marginBottom: 14 }}>
              <div style={{ ...o9_over, marginBottom: 8 }}>Rolls up to</div>
              <div style={{ display: "flex", gap: 8, alignItems: "center", flexWrap: "wrap", fontSize: 13 }}>
                <span style={{ padding: "4px 10px", borderRadius: 999, background: "var(--paper)", border: "1px solid var(--border-soft)" }}>{parentObjective.name}</span>
                <span style={{ color: "var(--fg-3)" }}>→</span>
                <span style={{ padding: "4px 10px", borderRadius: 999, background: "var(--paper)", border: "1px solid var(--border-soft)" }}>{parentProgram.name}</span>
                <span style={{ color: "var(--fg-3)" }}>→</span>
                <span style={{ padding: "4px 10px", borderRadius: 999, background: "var(--paper)", border: "1px solid var(--border-soft)" }}>{selectedResult.name}</span>
                <span style={{ color: "var(--fg-3)" }}>→</span>
                <span style={{ padding: "4px 10px", borderRadius: 999, background: "var(--coral-100)", color: "var(--coral-700)", fontWeight: 500 }}>{data.name || "(new indicator)"}</span>
              </div>
            </Card>
          )}

          <Field label="Indicator name" required>
            <Input value={data.name} onChange={(e) => update({ name: e.target.value })}
              placeholder="e.g. Trees planted" autoFocus />
          </Field>

          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 14 }}>
            <Field label="Unit of measure" required>
              <Input value={data.unit} onChange={(e) => update({ unit: e.target.value })}
                placeholder="e.g. trees, miles, hours, students" />
            </Field>
            <Field label="Value type" required>
              <Select value={data.valueType} onChange={(e) => update({ valueType: e.target.value })}
                options={[
                  { value: "count",     label: "Count (integer)" },
                  { value: "number",    label: "Number (decimal)" },
                  { value: "currency",  label: "Currency amount" },
                  { value: "percentage",label: "Percentage" },
                ]} />
            </Field>
            <Field label="Goal · YTD or period">
              <Input type="number" value={data.goal} onChange={(e) => update({ goal: e.target.value })}
                placeholder={data.unit ? `e.g. 5000 ${data.unit}` : "e.g. 5000"} />
            </Field>
            <Field label="Direction">
              <Select value={data.direction} onChange={(e) => update({ direction: e.target.value })}
                options={[
                  { value: "higher", label: "Higher is better" },
                  { value: "lower",  label: "Lower is better (e.g. incidents)" },
                ]} />
            </Field>
            <Field label="Start date" required>
              <Input type="date" value={data.start} onChange={(e) => update({ start: e.target.value })} />
            </Field>
            <Field label="End date">
              <Input type="date" value={data.end} onChange={(e) => update({ end: e.target.value })} />
            </Field>
          </div>

          <Field label="Description">
            <Textarea rows={3} value={data.description} onChange={(e) => update({ description: e.target.value })}
              placeholder="What counts toward this indicator? How is it captured?" />
          </Field>

          <Field label="Value capture source">
            <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 8 }}>
              {[
                { id: "manual",  t: "Manual",        d: "Staff record values directly." },
                { id: "capture", t: "Capture form",  d: "Auto from project/event capture form." },
                { id: "system",  t: "System rollup", d: "Computed from existing records (e.g. hours)." },
              ].map(o => (
                <Card key={o.id} onClick={() => update({ captureSource: o.id })} style={{ padding: 14, cursor: "pointer", borderColor: data.captureSource === o.id ? "var(--coral-500)" : "var(--border-soft)", borderWidth: data.captureSource === o.id ? 2 : 1 }}>
                  <div style={{ fontSize: 13, fontWeight: 500 }}>{o.t}</div>
                  <div style={{ ...o9_meta, marginTop: 3 }}>{o.d}</div>
                </Card>
              ))}
            </div>
          </Field>

          <Field label="State">
            <Select value={data.state} onChange={(e) => update({ state: e.target.value })}
              options={[
                { value: "draft",  label: "Draft (no values can be recorded yet)" },
                { value: "active", label: "Active (live)" },
              ]} />
          </Field>

          <div style={{ marginTop: 14, padding: 12, background: "var(--paper-deep)", borderRadius: 10, fontSize: 12, color: "var(--fg-2)", lineHeight: 1.5 }}>
            <IconShield size={13} style={{ verticalAlign: "middle", marginRight: 6, color: "var(--fg-3)" }} />
            Indicator values are separate from approved hours and grant records. Editing them never alters service totals or recognition calculations.
          </div>
        </div>
        <div style={o9_foot}>
          <Btn kind="ghost" onClick={onClose}>Cancel</Btn>
          <div style={{ marginLeft: "auto", display: "flex", gap: 8 }}>
            <Btn kind="secondary" onClick={() => { update({ state: "draft" }); setSubmitted(true); }}>Save as draft</Btn>
            <Btn icon={IconCheck} onClick={() => setSubmitted(true)}
              disabled={!data.name || !data.result || !data.unit || !data.start}>
              Create indicator
            </Btn>
          </div>
        </div>
      </div>
    </div>
  );
};

// ---- SHARED CREATE-DONE SCREEN ----
const CreateDone = ({ kind, name, onClose, onAnother }) => (
  <div style={o9_overlay} onClick={onClose}>
    <div style={o9_drawer} onClick={(e) => e.stopPropagation()}>
      <div style={o9_head}>
        <div>
          <div style={o9_over}>{kind} created</div>
          <div style={{ fontSize: 19, fontWeight: 500, color: "var(--ink)", marginTop: 4 }}>{name}</div>
        </div>
        <IconBtn icon={IconX} size={32} onClick={onClose} aria-label="Close" />
      </div>
      <div style={{ flex: 1, overflow: "auto", padding: 24 }}>
        <div style={{ textAlign: "center", padding: "20px 0 30px" }}>
          <div style={{ width: 56, height: 56, borderRadius: 999, background: "var(--sage-100)", color: "var(--sage-700)", display: "flex", alignItems: "center", justifyContent: "center", margin: "0 auto 16px" }}>
            <IconCheck size={28} />
          </div>
          <div style={{ fontFamily: "var(--font-display)", fontSize: 28, color: "var(--ink)" }}>{kind} saved</div>
          <div style={{ fontSize: 13, color: "var(--fg-2)", marginTop: 6 }}>
            Audit ref <code style={{ background: "var(--paper-deep)", padding: "2px 7px", borderRadius: 4, fontFamily: "var(--font-mono)", fontSize: 12 }}>{kind.toLowerCase()}-{new Date().toISOString().slice(0, 10)}-{Math.random().toString(36).slice(2, 5)}</code>
          </div>
        </div>
        <Card style={{ background: "var(--paper-soft)" }}>
          <div style={{ ...o9_over, marginBottom: 10 }}>What's next</div>
          <ul style={{ margin: 0, paddingLeft: 18, fontSize: 13, color: "var(--fg-1)", lineHeight: 1.7 }}>
            {kind === "Objective" && <>
              <li>Add programs that roll up to this objective</li>
              <li>Set targets and review windows</li>
              <li>Invite stakeholders (owner + reviewers)</li>
            </>}
            {kind === "Program" && <>
              <li>Define results (what success looks like)</li>
              <li>Add indicators under each result</li>
              <li>Wire to project / event capture forms when ready</li>
            </>}
            {kind === "Indicator" && <>
              <li>Record a first value to validate the unit + flow</li>
              <li>Attach to a capture form if one applies</li>
              <li>Set a reminder for first reporting period</li>
            </>}
          </ul>
        </Card>
      </div>
      <div style={o9_foot}>
        <Btn kind="ghost" onClick={onAnother}>Create another</Btn>
        <div style={{ marginLeft: "auto" }}><Btn icon={IconCheck} onClick={onClose}>Done</Btn></div>
      </div>
    </div>
  </div>
);

// ============================================================
Object.assign(window, { OrgOutcomes });
