// Optimisation page — informational recommendations, scoped to project + person
// No "Apply" buttons — these are advisories with savings estimates and how-to guides.

const REC_KINDS = {
  "model-swap":   { label:"Model swap",      icon:"refresh", color:"#5b50ee", bg:"rgba(91,80,238,0.10)",  line:"rgba(91,80,238,0.28)" },
  "prompt-cache": { label:"Prompt cache",    icon:"chip",    color:"#0f8a4f", bg:"rgba(15,138,79,0.10)",  line:"rgba(15,138,79,0.28)" },
  "batch-async":  { label:"Batch API",       icon:"layers",  color:"#b9710d", bg:"rgba(185,113,13,0.10)", line:"rgba(185,113,13,0.28)" },
  "output-cap":   { label:"Output cap",      icon:"target",  color:"#d97757", bg:"rgba(217,119,87,0.10)", line:"rgba(217,119,87,0.30)" },
  "context-trim": { label:"Context trim",    icon:"tokens",  color:"#4285f4", bg:"rgba(66,133,244,0.10)", line:"rgba(66,133,244,0.28)" },
  "tool-budget":  { label:"Tool budget",     icon:"cube",    color:"#9b5cf6", bg:"rgba(155,92,246,0.10)", line:"rgba(155,92,246,0.30)" },
  "embedding":    { label:"Embedding swap",  icon:"sparkles",color:"#10a37f", bg:"rgba(16,163,127,0.10)", line:"rgba(16,163,127,0.28)" },
};

const RECOMMENDATIONS = [
  {
    id:"r1",
    kind:"model-swap",
    title:"Switch claude-opus-4-7 → Sonnet 4.6 on contract-ai",
    project:"contract-ai",
    members:["vk"],
    savingsGBP:51.13,
    saveBasis:"per month",
    requests:1972,
    confidence:"high",
    effort:"low",
    qualityRisk:"low",
    why:"65% of these requests are short prompts (<800 input tokens) with simple outputs. Sonnet 4.6 matches Opus quality on this profile in our calibration set, at 1/5 the price.",
    how:[
      { title:"Set model per request", code:'await client.messages.create({\n  model: "claude-sonnet-4-6",  // was opus-4-7\n  max_tokens: 1024,\n  messages: [...]\n})' },
      { title:"Or route via .haltonrc", code:'# .haltonrc\n[routing]\nshort_prompts = "claude-sonnet-4-6"\nlong_reasoning = "claude-opus-4-7"' },
    ],
    docs:"docs.anthropic.com/models",
    tradeoffs:"Sonnet's tool-use accuracy is ~3% lower on multi-step reasoning. Not recommended for /contract-ai where complex refactors run.",
  },
  {
    id:"r2",
    kind:"prompt-cache",
    title:"Enable prompt caching on contract-ai",
    project:"contract-ai",
    members:["vk"],
    savingsGBP:21.91,
    saveBasis:"per month",
    requests:1972,
    confidence:"high",
    effort:"low",
    qualityRisk:"none",
    why:"We see repeated long prefixes (~6,400 tokens) across 84% of requests in this project — likely system prompt + tool definitions. Caching reduces input cost by ~90% on hits.",
    how:[
      { title:"Add cache_control breakpoints", code:'messages: [{\n  role: "user",\n  content: [\n    { type: "text", text: SYSTEM_PROMPT,\n      cache_control: { type: "ephemeral" } },\n    { type: "text", text: userMessage }\n  ]\n}]' },
    ],
    docs:"docs.anthropic.com/prompt-caching",
    tradeoffs:"5-minute cache TTL. If prefix changes more than every 5 min, savings will be lower than estimated.",
  },
  {
    id:"r3",
    kind:"batch-async",
    title:"Batch claude-opus-4-7 requests on contract-ai",
    project:"contract-ai",
    members:["vk"],
    savingsGBP:60.87,
    saveBasis:"per month",
    requests:1972,
    confidence:"medium",
    effort:"high",
    qualityRisk:"none",
    why:"1,640 of these requests don't need real-time responses (overnight or background jobs). Message Batches API gives a flat 50% discount with <24h SLA.",
    how:[
      { title:"Use Message Batches API", code:'const batch = await client.messages.batches.create({\n  requests: tasks.map(t => ({\n    custom_id: t.id,\n    params: { model, messages: [...] }\n  }))\n})' },
    ],
    docs:"docs.anthropic.com/message-batches",
    tradeoffs:"Up to 24h latency. Re-architect required for code that synchronously consumes responses.",
  },
  {
    id:"r4",
    kind:"model-swap",
    title:"Switch claude-opus-4-7 → Sonnet 4.6 on contract-ai",
    project:"contract-ai",
    members:["vk","sm"],
    savingsGBP:47.39,
    saveBasis:"per month",
    requests:2078,
    confidence:"high",
    effort:"low",
    qualityRisk:"medium",
    why:"65% of requests are short-context lookups (avg 920 input / 240 output tokens). Sonnet 4.6 likely sufficient. Reserve Opus for the 35% multi-file refactor flows.",
    how:[
      { title:"Tag requests by intent", code:'// Tag with X-Halton-Intent header so the\n// router can pick the right model per call.\nheaders: { "X-Halton-Intent": "lookup" }' },
    ],
    docs:"docs.halton.dev/routing",
    tradeoffs:"Quality risk: multi-step tool use 3-5% worse on Sonnet. Suggest A/B test first.",
  },
  {
    id:"r5",
    kind:"prompt-cache",
    title:"Enable prompt caching on contract-ai",
    project:"contract-ai",
    members:["vk","sm"],
    savingsGBP:20.31,
    saveBasis:"per month",
    requests:2078,
    confidence:"high",
    effort:"medium",
    qualityRisk:"none",
    why:"Codebase context (~22k tokens) is re-sent in 76% of requests. Caching this prefix reduces input cost ~90% on cache hits.",
    how:[
      { title:"Cache the codebase prefix", code:'messages: [\n  { role: "user", content: [\n    { type: "text", text: codebaseDigest,\n      cache_control: { type: "ephemeral" } },\n    { type: "text", text: userQuery }\n  ]}\n]' },
    ],
    docs:"docs.anthropic.com/prompt-caching",
    tradeoffs:"Refresh strategy needed when codebase mutates. Recommend triggering cache rebuild on git push.",
  },
  {
    id:"r6",
    kind:"batch-async",
    title:"Batch claude-opus-4-7 requests on contract-ai",
    project:"contract-ai",
    members:["vk"],
    savingsGBP:56.42,
    saveBasis:"per month",
    requests:2078,
    confidence:"medium",
    effort:"high",
    qualityRisk:"none",
    why:"Nightly evaluation runs (~870 requests/week) and report generation jobs are batchable. 50% discount on those alone is ≈£56/mo.",
    how:[
      { title:"Split sync / async pipelines", code:'// Move report-gen + eval to a worker that\n// uses /v1/messages/batches with custom_id\n// per task. Poll status, store outputs.' },
    ],
    docs:"docs.anthropic.com/message-batches",
    tradeoffs:"Adds latency for nightly jobs (irrelevant) and worker orchestration complexity.",
  },
  {
    id:"r7",
    kind:"output-cap",
    title:"Cap max_tokens on lookup-style requests",
    project:"document-processor",
    members:["sm"],
    savingsGBP:8.20,
    saveBasis:"per month",
    requests:446,
    confidence:"high",
    effort:"low",
    qualityRisk:"none",
    why:"Lookup-style requests have avg output of 180 tokens but max_tokens is currently 4096. The model can over-generate when not capped — costs paid on every generated token.",
    how:[
      { title:"Lower max_tokens for lookups", code:'await client.messages.create({\n  model: "claude-sonnet-4-6",\n  max_tokens: 512,  // was 4096\n  stop_sequences: ["\\n\\n---"],\n  messages: [...]\n})' },
    ],
    docs:"docs.anthropic.com/api/messages",
    tradeoffs:"None for lookup tasks. Don't apply on long-form generation flows.",
  },
  {
    id:"r8",
    kind:"context-trim",
    title:"Trim context on /unattributed",
    project:"unattributed",
    members:[],
    savingsGBP:6.40,
    saveBasis:"per month",
    requests:422,
    confidence:"low",
    effort:"high",
    qualityRisk:"medium",
    why:"Unattributed requests average 11k input tokens — suspiciously high for 525 calls. Likely whole-file dumps where summaries would do.",
    how:[
      { title:"First, tag the project", code:'# Add a .haltonrc to the working folder\n[project]\nslug = "your-project"\nname = "Your Project"' },
      { title:"Then use a context budget", code:'// Cap context at 4k tokens\n// Summarize anything larger before sending' },
    ],
    docs:"docs.halton.dev/attribution",
    tradeoffs:"Need to know which project these belong to first. Hard to recommend without scope.",
  },
  {
    id:"r9",
    kind:"embedding",
    title:"Use embeddings for invoice classification",
    project:"meridian-studio",
    members:["vk"],
    savingsGBP:4.80,
    saveBasis:"per month",
    requests:327,
    confidence:"medium",
    effort:"medium",
    qualityRisk:"low",
    why:"327 requests are short classification tasks (label invoice line items). An embedding-based classifier costs <1% of an Opus call and runs locally.",
    how:[
      { title:"Swap to embeddings", code:'// Use voyage-3 + a small classifier\nconst emb = await voyage.embed(text)\nconst label = await classifier.predict(emb)' },
    ],
    docs:"docs.halton.dev/embeddings",
    tradeoffs:"Need to train + maintain the classifier. Worth it only if classification volume grows.",
  },
];

const ADOPTED = [
  { id:"a1", title:"Switched gpt-4-turbo → gpt-4o on Frontend 3", project:"frontend-3", at:"13 May", est:0.0124, actual:0.0119, delta:-0.04 },
  { id:"a2", title:"Enabled prompt caching on Analytics 1",      project:"analytics-1", at:"6 May",  est:0.0087, actual:0.0092, delta:+0.06 },
];

function Optimisation(){
  const [groupBy, setGroupBy] = useState("type");     // project | type | member | none
  const [view, setView] = useState("list");          // list | cards
  const [filterType, setFilterType] = useState("all");
  const [filterProject, setFilterProject] = useState("all");
  const [filterMember, setFilterMember] = useState("all");
  const [sort, setSort] = useState("savings");
  const [collapsed, setCollapsed] = useState({});    // groupKey -> bool

  let recs = RECOMMENDATIONS;
  if (filterType !== "all")    recs = recs.filter(r => r.kind === filterType);
  if (filterProject !== "all") recs = recs.filter(r => r.project === filterProject);
  if (filterMember !== "all")  recs = recs.filter(r => r.members.includes(filterMember));
  recs = [...recs].sort((a,b) => sort === "savings" ? b.savingsGBP - a.savingsGBP : (a.effort==="low"?-1:1));

  const totalSavings = RECOMMENDATIONS.reduce((s,r)=>s+r.savingsGBP, 0);
  const filteredSavings = recs.reduce((s,r)=>s+r.savingsGBP, 0);
  const byKind = {};
  RECOMMENDATIONS.forEach(r => {
    if (!byKind[r.kind]) byKind[r.kind] = { count:0, savings:0 };
    byKind[r.kind].count++;
    byKind[r.kind].savings += r.savingsGBP;
  });

  const groups = groupBy === "none"
    ? [{ key:"_all", label:"All recommendations", sub:`${recs.length} item${recs.length!==1?"s":""}`, swatch:"var(--accent)", savings: filteredSavings, items: recs }]
    : groupRecs(recs, groupBy);

  return (
    <div data-screen-label="07 Optimisation" style={{ padding:"24px 28px 40px", maxWidth:1380, margin:"0 auto", display:"flex", flexDirection:"column", gap:20 }}>
      {/* Header */}
      <header style={{ display:"flex", alignItems:"flex-end", justifyContent:"space-between", gap:16 }}>
        <div>
          <div style={{ fontSize:11, letterSpacing:0.08, textTransform:"uppercase", color:"var(--fg-3)", fontWeight:600, marginBottom:6 }}>Workspace</div>
          <h1 style={{ margin:0, fontSize:28, fontWeight:600, letterSpacing:-0.5 }}>Optimisation</h1>
          <div style={{ color:"var(--fg-2)", fontSize:13, marginTop:5 }}>Reduce spend without changing what you ship · <span className="mono">9</span> advisories from your last 30 days of usage</div>
        </div>
        <div style={{ display:"flex", gap:8, alignItems:"center" }}>
          <span style={{ fontSize:11.5, color:"var(--fg-3)" }}>Last scanned <span className="mono" style={{ color:"var(--fg-1)" }}>1m ago</span></span>
          <button style={btnSecondary()}><Icon name="refresh" size={13}/> Rescan</button>
          <button style={btnSecondary()}><Icon name="download" size={13}/> Export playbook</button>
        </div>
      </header>

      {/* Hero — potential savings + breakdown */}
      <SavingsHero total={totalSavings} byKind={byKind}/>

      {/* Spotlight rec */}
      <SpotlightRec rec={RECOMMENDATIONS.sort((a,b)=>b.savingsGBP-a.savingsGBP)[0]}/>

      {/* Two-column main */}
      <div style={{ display:"grid", gridTemplateColumns:"minmax(0, 1fr) 320px", gap:18 }}>
        {/* Left column */}
        <div style={{ display:"flex", flexDirection:"column", gap:14 }}>
          {/* Filter row */}
          <section className="card" style={{ padding:"12px 16px", display:"flex", flexWrap:"wrap", alignItems:"center", gap:10 }}>
            <span style={{ fontSize:11, color:"var(--fg-3)", textTransform:"uppercase", letterSpacing:0.08, fontWeight:600, marginRight:4 }}>Filter</span>
            <SelectMini value={filterType}    onChange={setFilterType}    icon="filter"
              options={[{id:"all",label:"All types"}, ...Object.entries(REC_KINDS).map(([k,v]) => ({id:k,label:v.label,dot:v.color}))]}/>
            <SelectMini value={filterProject} onChange={setFilterProject} icon="folder"
              options={[{id:"all",label:"All projects"}, ...Array.from(new Set(RECOMMENDATIONS.map(r=>r.project))).map(p=>({id:p,label:"/"+p}))]}/>
            <SelectMini value={filterMember}  onChange={setFilterMember}  icon="user"
              options={[{id:"all",label:"Everyone"}, {id:"vk",label:"Alex Pemberton"}, {id:"sm",label:"Jamie Lowe"}]}/>
            <div style={{ width:1, height:20, background:"var(--line-1)", margin:"0 4px" }}/>
            <span style={{ fontSize:11, color:"var(--fg-3)", textTransform:"uppercase", letterSpacing:0.08, fontWeight:600 }}>Group by</span>
            <Segmented value={groupBy} onChange={setGroupBy} options={[
              { id:"type",    label:"Type" },
              { id:"project", label:"Project" },
              { id:"member",  label:"Person" },
              { id:"none",    label:"None" },
            ]}/>
            <div style={{ width:1, height:20, background:"var(--line-1)", margin:"0 4px" }}/>
            <span style={{ fontSize:11, color:"var(--fg-3)", textTransform:"uppercase", letterSpacing:0.08, fontWeight:600 }}>View</span>
            <Segmented value={view} onChange={setView} options={[
              { id:"list",  label:"List" },
              { id:"cards", label:"Cards" },
            ]}/>
            <div style={{ flex:1 }}/>
            <span style={{ fontSize:11.5, color:"var(--fg-2)" }}>
              <span className="mono" style={{ color:"var(--fg-0)" }}>{recs.length}</span> of {RECOMMENDATIONS.length} · <span className="mono" style={{ color:"var(--pos)" }}>{fmtGBP(filteredSavings)}</span> potential
            </span>
          </section>

          {/* Recommendation groups */}
          {groups.map((g, gi) => {
            const isCollapsed = collapsed[g.key] ?? (gi >= 3 && groups.length > 3);
            const toggle = () => setCollapsed({ ...collapsed, [g.key]: !isCollapsed });
            return (
              <section key={g.key} className="card" style={{ padding:0, overflow:"hidden" }}>
                {groupBy !== "none" && (
                  <button onClick={toggle} style={{
                    appearance:"none", border:"none", background: isCollapsed ? "transparent" : "rgba(20,16,8,0.012)",
                    width:"100%", padding:"12px 18px",
                    display:"flex", alignItems:"center", gap:12,
                    borderBottom: isCollapsed ? "none" : "1px solid var(--line-1)",
                    cursor:"pointer", textAlign:"left",
                    transition:"background 80ms ease",
                  }}
                    onMouseEnter={e=>{ if(isCollapsed) e.currentTarget.style.background="rgba(20,16,8,0.02)" }}
                    onMouseLeave={e=>{ if(isCollapsed) e.currentTarget.style.background="transparent" }}
                  >
                    <Icon name={isCollapsed?"chevron":"chevDown"} size={12} stroke="var(--fg-2)"/>
                    {g.swatch && <span style={{ width:9, height:9, borderRadius:3, background:g.swatch, flexShrink:0 }}/>}
                    <span style={{ fontSize:13, fontWeight:600, color:"var(--fg-0)" }}>{g.label}</span>
                    <span style={{ fontSize:11.5, color:"var(--fg-2)" }}>{g.sub}</span>
                    <div style={{ flex:1 }}/>
                    <span className="mono" style={{ fontSize:11.5, color:"var(--pos)", fontWeight:500 }}>{fmtGBP(g.savings)}<span style={{ color:"var(--fg-3)", fontWeight:400, marginLeft:3 }}>potential</span></span>
                    <span className="badge badge--ghost" style={{ fontSize:10 }}>{g.items.length}</span>
                  </button>
                )}
                {!isCollapsed && (
                  view === "cards" ? (
                    <div style={{ display:"grid", gridTemplateColumns:"repeat(2, minmax(0,1fr))", gap:14, padding:14 }}>
                      {g.items.map(r => <RecCard key={r.id} rec={r}/>)}
                    </div>
                  ) : (
                    <div>
                      {g.items.map((r, i) => <RecRow key={r.id} rec={r} divider={i>0}/>)}
                    </div>
                  )
                )}
              </section>
            );
          })}

          {groups.length === 0 && (
            <section className="card" style={{ padding:"50px 24px", textAlign:"center", color:"var(--fg-2)" }}>
              <Icon name="check" size={28} stroke="var(--fg-3)"/>
              <div style={{ marginTop:10, fontSize:14, color:"var(--fg-1)" }}>No recommendations match those filters</div>
              <button style={{ ...btnGhost(), marginTop:14 }} onClick={()=>{ setFilterType("all"); setFilterProject("all"); setFilterMember("all"); }}>Clear filters</button>
            </section>
          )}

          {/* Adopted log */}
          <AdoptedLog/>
        </div>

        {/* Sidebar */}
        <aside style={{ display:"flex", flexDirection:"column", gap:14 }}>
          <SavingsBreakdownCard byKind={byKind} total={totalSavings}/>
          <MethodologyCard/>
          <PlaybookCard/>
          <StatusCard total={RECOMMENDATIONS.length}/>
        </aside>
      </div>
    </div>
  );
}

function groupRecs(recs, by){
  const m = {};
  recs.forEach(r => {
    let key;
    if (by === "project") key = r.project;
    else if (by === "type") key = r.kind;
    else key = r.members[0] || "_unassigned";
    if (!m[key]) m[key] = [];
    m[key].push(r);
  });
  return Object.entries(m).map(([k, items]) => {
    const savings = items.reduce((s,r)=>s+r.savingsGBP, 0);
    if (by === "project") {
      const p = PROJECTS.find(p => p.slug === k);
      return {
        key:k, label:k, sub:`${items.length} recommendation${items.length!==1?"s":""}${p?` · ${fmtGBP(p.spend)} period spend`:""}`,
        swatch: p ? PROVIDERS[MODELS[p.primaryModel].provider].color : "var(--fg-3)",
        savings, items,
      };
    }
    if (by === "type") {
      const def = REC_KINDS[k];
      return { key:k, label:def.label, sub:`${items.length} recommendation${items.length!==1?"s":""}`, swatch:def.color, savings, items };
    }
    const name = k === "vk" ? "Alex Pemberton" : k === "sm" ? "Jamie Lowe" : "Unassigned";
    return { key:k, label:name, sub:`${items.length} recommendation${items.length!==1?"s":""}`, swatch:"var(--accent)", savings, items };
  }).sort((a,b)=>b.savings-a.savings);
}

// ── Savings hero ───────────────────────────────────────────
function SavingsHero({ total, byKind }){
  const items = Object.entries(byKind).map(([k,v])=>({ k, ...v, def:REC_KINDS[k] })).sort((a,b)=>b.savings-a.savings);
  return (
    <div className="card" style={{
      padding:0, overflow:"hidden",
      borderColor:"rgba(15,138,79,0.22)",
      background:"linear-gradient(135deg, rgba(15,138,79,0.06) 0%, transparent 55%)",
      display:"grid",
      gridTemplateColumns:"1.1fr 1.5fr",
    }}>
      {/* Left: total */}
      <div style={{ padding:"24px 26px 22px", borderRight:"1px solid var(--line-1)" }}>
        <div style={{ display:"flex", alignItems:"center", gap:8, marginBottom:8 }}>
          <Icon name="sparkles" size={14} stroke="var(--pos)"/>
          <span style={{ fontSize:11, letterSpacing:0.08, textTransform:"uppercase", color:"var(--pos)", fontWeight:600 }}>Potential monthly savings</span>
        </div>
        <div style={{ display:"flex", alignItems:"baseline", gap:14 }}>
          <span className="mono" style={{ fontSize:44, fontWeight:600, color:"var(--fg-0)", letterSpacing:-0.6 }}>
            <span style={{ color:"var(--fg-3)", fontWeight:400, marginRight:2 }}>£</span>{total.toFixed(2)}
          </span>
        </div>
        <div style={{ fontSize:12.5, color:"var(--fg-2)", marginTop:10, lineHeight:1.5 }}>
          Across <span className="mono" style={{ color:"var(--fg-0)", fontWeight:500 }}>{RECOMMENDATIONS.length} opportunities</span> in your workspace.
          If everything were adopted, May 2026 spend would drop from <span className="mono" style={{ color:"var(--fg-1)" }}>£277.88</span> to <span className="mono" style={{ color:"var(--pos)" }}>{fmtGBP(277.88 - total*0.36)}</span> at this period's pace.
        </div>
      </div>

      {/* Right: category breakdown */}
      <div style={{ padding:"24px 26px 22px", display:"flex", flexDirection:"column", justifyContent:"center" }}>
        <div style={{ fontSize:11, letterSpacing:0.08, textTransform:"uppercase", color:"var(--fg-3)", fontWeight:600, marginBottom:14 }}>Where savings come from</div>
        {/* Stacked bar */}
        <div style={{ display:"flex", height:14, borderRadius:99, overflow:"hidden", background:"var(--bg-3)", marginBottom:14, border:"1px solid var(--line-1)" }}>
          {items.map(it => (
            <div key={it.k} title={`${it.def.label}: ${fmtGBP(it.savings)}`} style={{
              width: (it.savings/total*100)+"%",
              background: it.def.color, opacity:0.9,
            }}/>
          ))}
        </div>
        {/* Legend grid */}
        <div style={{ display:"grid", gridTemplateColumns:"repeat(2, 1fr)", gap:"7px 18px" }}>
          {items.map(it => (
            <div key={it.k} style={{ display:"flex", alignItems:"center", gap:8, fontSize:12 }}>
              <span style={{ width:8, height:8, borderRadius:2, background:it.def.color, flexShrink:0 }}/>
              <span style={{ color:"var(--fg-1)", flex:1 }}>{it.def.label}</span>
              <span className="mono" style={{ color:"var(--fg-2)", fontSize:11 }}>{it.count}</span>
              <span className="mono" style={{ color:"var(--fg-0)", fontWeight:500, minWidth:48, textAlign:"right" }}>{fmtGBP(it.savings)}</span>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

// ── Spotlight: single biggest opportunity with rich context ─
function SpotlightRec({ rec }){
  const kind = REC_KINDS[rec.kind];
  const project = PROJECTS.find(p => p.slug === rec.project);
  return (
    <div className="card" style={{ padding:0, overflow:"hidden", borderColor:"var(--accent-line)", background:"linear-gradient(135deg, rgba(91,80,238,0.04) 0%, transparent 60%)" }}>
      <div style={{ padding:"6px 22px", background:"rgba(91,80,238,0.07)", borderBottom:"1px solid var(--accent-line)", display:"flex", alignItems:"center", gap:8 }}>
        <Icon name="starOn" size={11} stroke="var(--accent)"/>
        <span style={{ fontSize:11, color:"var(--accent)", fontWeight:600, letterSpacing:0.06, textTransform:"uppercase" }}>Biggest opportunity this period</span>
      </div>
      <div style={{ padding:"20px 22px", display:"grid", gridTemplateColumns:"1.4fr 1fr", gap:24 }}>
        <div>
          <div style={{ display:"flex", alignItems:"center", gap:10, marginBottom:10, flexWrap:"wrap" }}>
            <KindBadge kind={rec.kind}/>
            <ScopeChip project={rec.project}/>
            {rec.members.map(mid => <PersonChip key={mid} id={mid}/>)}
          </div>
          <h2 style={{ margin:0, fontSize:18, fontWeight:600, color:"var(--fg-0)", letterSpacing:-0.2 }}>{rec.title}</h2>
          <p style={{ margin:"8px 0 0", fontSize:13, color:"var(--fg-1)", lineHeight:1.55 }}>{rec.why}</p>
          <div style={{ display:"flex", gap:8, marginTop:14 }}>
            <button style={btnPrimary()}><Icon name="ext" size={13}/> View migration guide</button>
            <button style={btnSecondary()}><Icon name="check" size={13}/> Mark as reviewed</button>
            <button style={btnGhost()}>Snooze</button>
          </div>
        </div>
        <div style={{ display:"flex", flexDirection:"column", gap:10, padding:"12px 14px", background:"#fff", border:"1px solid var(--line-1)", borderRadius:10 }}>
          <div style={{ display:"flex", justifyContent:"space-between", alignItems:"baseline" }}>
            <span style={{ fontSize:11, color:"var(--fg-3)", textTransform:"uppercase", letterSpacing:0.06, fontWeight:600 }}>Est. savings</span>
            <span className="mono" style={{ fontSize:20, fontWeight:600, color:"var(--pos)" }}>{fmtGBP(rec.savingsGBP)}<span style={{ color:"var(--fg-3)", fontWeight:400, fontSize:11, marginLeft:4 }}>/mo</span></span>
          </div>
          <div style={{ display:"flex", justifyContent:"space-between", fontSize:12, color:"var(--fg-2)" }}>
            <span>Affected requests</span><span className="mono" style={{ color:"var(--fg-0)" }}>{rec.requests.toLocaleString()}</span>
          </div>
          <div style={{ display:"flex", justifyContent:"space-between", fontSize:12, color:"var(--fg-2)" }}>
            <span>Project spend</span><span className="mono" style={{ color:"var(--fg-0)" }}>{project ? fmtGBP(project.spend) : "—"}</span>
          </div>
          <div style={{ height:1, background:"var(--line-1)", margin:"2px 0" }}/>
          <div style={{ display:"flex", justifyContent:"space-between", fontSize:12, color:"var(--fg-2)" }}>
            <span>Confidence</span><ConfidencePill v={rec.confidence}/>
          </div>
          <div style={{ display:"flex", justifyContent:"space-between", fontSize:12, color:"var(--fg-2)" }}>
            <span>Effort</span><EffortPill v={rec.effort}/>
          </div>
          <div style={{ display:"flex", justifyContent:"space-between", fontSize:12, color:"var(--fg-2)" }}>
            <span>Quality risk</span><RiskPill v={rec.qualityRisk}/>
          </div>
        </div>
      </div>
    </div>
  );
}

// ── Recommendation list row (dense, scales to 100s) ───────
function RecRow({ rec, divider }){
  const [open, setOpen] = useState(false);
  const [tab, setTab] = useState(0);
  const kind = REC_KINDS[rec.kind];
  return (
    <div style={{ borderTop: divider ? "1px solid var(--line-1)" : "none" }}>
      <button
        onClick={()=>setOpen(!open)}
        style={{
          appearance:"none", border:"none", background: open ? "rgba(91,80,238,0.025)" : "transparent",
          width:"100%", padding:"12px 16px",
          display:"grid",
          gridTemplateColumns:"28px minmax(0, 1fr) 252px 92px 14px",
          gap:14, alignItems:"center",
          cursor:"pointer", textAlign:"left",
          transition:"background 80ms ease",
        }}
        onMouseEnter={e=>{ if(!open) e.currentTarget.style.background="rgba(20,16,8,0.018)" }}
        onMouseLeave={e=>{ if(!open) e.currentTarget.style.background="transparent" }}
      >
        {/* Kind icon */}
        <span style={{ width:28, height:28, borderRadius:7, background:kind.bg, color:kind.color, border:"1px solid "+kind.line, display:"inline-flex", alignItems:"center", justifyContent:"center", flexShrink:0 }}>
          <Icon name={kind.icon} size={13}/>
        </span>

        {/* Title + scope */}
        <div style={{ display:"flex", flexDirection:"column", gap:4, minWidth:0 }}>
          <span style={{ fontSize:13, fontWeight:500, color:"var(--fg-0)", overflow:"hidden", textOverflow:"ellipsis", whiteSpace:"nowrap" }}>{rec.title}</span>
          <div style={{ display:"flex", gap:6, alignItems:"center", flexWrap:"nowrap", overflow:"hidden" }}>
            <span style={{ fontSize:10.5, color:kind.color, fontWeight:600, letterSpacing:0.04, textTransform:"uppercase" }}>{kind.label}</span>
            <span style={{ width:2, height:2, borderRadius:"50%", background:"var(--line-2)", flexShrink:0 }}/>
            <ScopeChip project={rec.project}/>
            {rec.members.map(mid => <PersonChip key={mid} id={mid}/>)}
          </div>
        </div>

        {/* Inline metrics — fixed widths so columns align across rows */}
        <div style={{ display:"grid", gridTemplateColumns:"repeat(4, 1fr)", gap:6, fontSize:11, minWidth:0 }}>
          <MetricInline label="reqs"   value={rec.requests.toLocaleString()} mono/>
          <MetricInline label="conf"   value={<ConfidencePill v={rec.confidence} inline/>}/>
          <MetricInline label="effort" value={<EffortPill v={rec.effort}/>}/>
          <MetricInline label="risk"   value={<RiskPill v={rec.qualityRisk}/>}/>
        </div>

        {/* Savings — fixed column, right-aligned */}
        <div style={{ textAlign:"right", whiteSpace:"nowrap" }}>
          <div className="mono" style={{ fontSize:14, fontWeight:600, color:"var(--pos)", lineHeight:1.2 }}>{fmtGBP(rec.savingsGBP)}<span style={{ color:"var(--fg-3)", fontWeight:400, fontSize:10, marginLeft:2 }}>/mo</span></div>
          <div style={{ fontSize:9, color:"var(--fg-3)", textTransform:"uppercase", letterSpacing:0.06, fontWeight:600, marginTop:2 }}>estimated</div>
        </div>

        {/* Chevron */}
        <Icon name={open ? "chevDown" : "chevron"} size={13} stroke="var(--fg-3)"/>
      </button>

      {open && (
        <div style={{ padding:"4px 16px 18px 56px", borderTop:"1px solid var(--line-1)", background:"rgba(91,80,238,0.025)" }}>
          <div style={{ display:"grid", gridTemplateColumns:"minmax(0,1.4fr) minmax(0,1fr)", gap:18, paddingTop:14 }}>
            {/* Why */}
            <div>
              <div style={{ fontSize:10.5, color:"var(--fg-3)", textTransform:"uppercase", letterSpacing:0.06, fontWeight:600, marginBottom:6 }}>Why we suggest this</div>
              <p style={{ margin:0, fontSize:12.5, color:"var(--fg-1)", lineHeight:1.55 }}>{rec.why}</p>

              <div style={{ marginTop:14, padding:"10px 11px", border:"1px dashed var(--line-2)", borderRadius:7, fontSize:11.5, color:"var(--fg-2)", lineHeight:1.5, background:"#fff" }}>
                <div style={{ display:"flex", alignItems:"center", gap:7, marginBottom:3 }}>
                  <Icon name="info" size={11} stroke="var(--warn)"/>
                  <span style={{ color:"var(--fg-0)", fontWeight:500 }}>Trade-offs</span>
                </div>
                {rec.tradeoffs}
              </div>

              <div style={{ marginTop:12, display:"flex", justifyContent:"space-between", alignItems:"center", flexWrap:"wrap", gap:8 }}>
                <a href={`https://${rec.docs}`} target="_blank" rel="noreferrer" style={{ fontSize:11.5, color:"var(--accent)", textDecoration:"none", display:"inline-flex", alignItems:"center", gap:5 }}>
                  <Icon name="ext" size={11} stroke="var(--accent)"/>{rec.docs}
                </a>
                <div style={{ display:"flex", gap:6 }}>
                  <button onClick={e=>e.stopPropagation()} style={btnGhost()}><Icon name="check" size={11}/> Mark reviewed</button>
                  <button onClick={e=>e.stopPropagation()} style={btnGhost()}><Icon name="clock" size={11}/> Snooze</button>
                  <button onClick={e=>e.stopPropagation()} style={btnGhost()}><Icon name="archive" size={11}/> N/A</button>
                </div>
              </div>
            </div>

            {/* How */}
            <div>
              <div style={{ fontSize:10.5, color:"var(--fg-3)", textTransform:"uppercase", letterSpacing:0.06, fontWeight:600, marginBottom:6 }}>How to apply</div>
              <div style={{ display:"flex", gap:6, marginBottom:10, borderBottom:"1px solid var(--line-1)" }}>
                {rec.how.map((step, i) => (
                  <button key={i} onClick={e=>{ e.stopPropagation(); setTab(i); }} style={{
                    appearance:"none", background:"transparent", border:"none",
                    padding:"6px 4px", fontSize:11.5,
                    color: tab===i ? "var(--fg-0)" : "var(--fg-2)",
                    fontWeight: tab===i ? 500 : 400,
                    borderBottom: tab===i ? "2px solid var(--accent)" : "2px solid transparent",
                    marginBottom:-1, cursor:"pointer",
                  }}>{step.title}</button>
                ))}
              </div>
              <CodeBlock code={rec.how[tab]?.code || ""}/>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

function MetricInline({ label, value, mono }){
  return (
    <span style={{ display:"flex", flexDirection:"column", gap:2, alignItems:"flex-start", minWidth:0 }}>
      <span style={{ color:"var(--fg-3)", textTransform:"uppercase", letterSpacing:0.06, fontWeight:600, fontSize:9 }}>{label}</span>
      <span style={{ color:"var(--fg-0)", fontWeight:500, fontSize:12, whiteSpace:"nowrap" }} className={mono ? "mono" : ""}>{value}</span>
    </span>
  );
}

// ── Recommendation card (expandable for how-to) ─────────────
function RecCard({ rec }){
  const [open, setOpen] = useState(false);
  const [tab, setTab] = useState(0);
  const kind = REC_KINDS[rec.kind];
  return (
    <article className="card" style={{ padding:0, overflow:"hidden", display:"flex", flexDirection:"column" }}>
      <div style={{ padding:"16px 18px 14px", display:"flex", flexDirection:"column", gap:11, flex:1 }}>
        <div style={{ display:"flex", justifyContent:"space-between", alignItems:"flex-start", gap:10 }}>
          <KindBadge kind={rec.kind}/>
          <div style={{ textAlign:"right" }}>
            <div className="mono" style={{ fontSize:15, fontWeight:600, color:"var(--pos)" }}>{fmtGBP(rec.savingsGBP)}<span style={{ color:"var(--fg-3)", fontWeight:400, fontSize:10, marginLeft:2 }}>/mo</span></div>
            <div style={{ fontSize:10, color:"var(--fg-3)" }}>estimated</div>
          </div>
        </div>

        <h3 style={{ margin:0, fontSize:14, fontWeight:600, color:"var(--fg-0)", lineHeight:1.35 }}>{rec.title}</h3>

        <div style={{ display:"flex", flexWrap:"wrap", gap:6 }}>
          <ScopeChip project={rec.project}/>
          {rec.members.map(mid => <PersonChip key={mid} id={mid}/>)}
        </div>

        <p style={{ margin:0, fontSize:12, color:"var(--fg-2)", lineHeight:1.55 }}>{rec.why}</p>

        <div style={{ display:"flex", flexWrap:"wrap", alignItems:"center", gap:10, paddingTop:6, marginTop:"auto" }}>
          <Metric label="reqs" value={rec.requests.toLocaleString()}/>
          <Sep/>
          <Metric label="conf" value={<ConfidencePill v={rec.confidence} inline/>}/>
          <Sep/>
          <Metric label="effort" value={<EffortPill v={rec.effort} inline/>}/>
          <Sep/>
          <Metric label="risk" value={<RiskPill v={rec.qualityRisk} inline/>}/>
        </div>
      </div>

      <div style={{ borderTop:"1px solid var(--line-1)", padding:"10px 18px", background:"rgba(20,16,8,0.012)", display:"flex", alignItems:"center", justifyContent:"space-between", gap:8 }}>
        <button onClick={()=>setOpen(!open)} style={{ ...btnSubtle(), color:"var(--accent)", padding:0 }}>
          {open ? "Hide" : "Show me how"}<Icon name={open?"chevDown":"chevron"} size={11} stroke="var(--accent)"/>
        </button>
        <div style={{ display:"flex", gap:6 }}>
          <button style={btnSubtle()} title="Mark reviewed"><Icon name="check" size={12}/></button>
          <button style={btnSubtle()} title="Snooze"><Icon name="clock" size={12}/></button>
          <button style={btnSubtle()} title="Not applicable"><Icon name="archive" size={12}/></button>
        </div>
      </div>

      {open && (
        <div style={{ padding:"14px 18px 18px", borderTop:"1px solid var(--line-1)", background:"#fff" }}>
          <div style={{ display:"flex", gap:8, marginBottom:10, borderBottom:"1px solid var(--line-1)" }}>
            {rec.how.map((step, i) => (
              <button key={i} onClick={()=>setTab(i)} style={{
                appearance:"none", background:"transparent", border:"none",
                padding:"6px 4px", fontSize:11.5,
                color: tab===i ? "var(--fg-0)" : "var(--fg-2)",
                fontWeight: tab===i ? 500 : 400,
                borderBottom: tab===i ? "2px solid var(--accent)" : "2px solid transparent",
                marginBottom:-1, cursor:"pointer",
              }}>{step.title}</button>
            ))}
          </div>
          <CodeBlock code={rec.how[tab]?.code || ""}/>
          <div style={{ marginTop:12, padding:"9px 11px", border:"1px dashed var(--line-2)", borderRadius:7, fontSize:11.5, color:"var(--fg-2)", lineHeight:1.5 }}>
            <div style={{ display:"flex", alignItems:"center", gap:7, marginBottom:3 }}>
              <Icon name="info" size={11} stroke="var(--warn)"/>
              <span style={{ color:"var(--fg-0)", fontWeight:500 }}>Trade-offs</span>
            </div>
            {rec.tradeoffs}
          </div>
          <div style={{ marginTop:10, display:"flex", justifyContent:"space-between", alignItems:"center" }}>
            <a href={`https://${rec.docs}`} target="_blank" rel="noreferrer" style={{ fontSize:11.5, color:"var(--accent)", textDecoration:"none", display:"inline-flex", alignItems:"center", gap:5 }}>
              <Icon name="ext" size={11} stroke="var(--accent)"/>{rec.docs}
            </a>
            <button style={btnGhost()}><Icon name="download" size={11}/> Copy as Slack message</button>
          </div>
        </div>
      )}
    </article>
  );
}

// ── Pieces ─────────────────────────────────────────────────
function KindBadge({ kind }){
  const def = REC_KINDS[kind];
  return (
    <span style={{ display:"inline-flex", alignItems:"center", gap:6, padding:"3px 9px 3px 7px", borderRadius:99, background:def.bg, color:def.color, border:"1px solid "+def.line, fontSize:11, fontWeight:500, letterSpacing:0.02 }}>
      <Icon name={def.icon} size={11.5}/>{def.label}
    </span>
  );
}

function ScopeChip({ project }){
  return (
    <span style={{ display:"inline-flex", alignItems:"center", gap:6, padding:"3px 9px 3px 7px", borderRadius:99, background:"var(--bg-3)", border:"1px solid var(--line-1)", fontSize:11, color:"var(--fg-1)" }}>
      <Icon name="folder" size={11} stroke="var(--fg-2)"/>
      <span className="mono">/{project}</span>
    </span>
  );
}

function PersonChip({ id }){
  const name = id === "vk" ? "Alex" : id === "sm" ? "Jamie" : id === "jm" ? "Jamie" : id;
  const hue = id.split("").reduce((s,c)=>s+c.charCodeAt(0),0) % 360;
  return (
    <span style={{ display:"inline-flex", alignItems:"center", gap:6, padding:"3px 9px 3px 4px", borderRadius:99, background:"var(--bg-3)", border:"1px solid var(--line-1)", fontSize:11, color:"var(--fg-1)" }}>
      <span style={{ width:16, height:16, borderRadius:"50%", background:`linear-gradient(135deg, hsl(${hue} 70% 55%), hsl(${(hue+45)%360} 65% 45%))`, color:"#fff", fontSize:8, fontWeight:600, display:"inline-flex", alignItems:"center", justifyContent:"center" }}>{name[0]}</span>
      {name}
    </span>
  );
}

function ConfidencePill({ v, inline }){
  const map = { high:{fg:"var(--pos)",bg:"var(--pos-soft)",line:"rgba(15,138,79,0.28)"}, medium:{fg:"var(--warn)",bg:"var(--warn-soft)",line:"rgba(185,113,13,0.28)"}, low:{fg:"var(--fg-3)",bg:"var(--bg-3)",line:"var(--line-2)"} };
  const c = map[v] || map.low;
  return (
    <span style={{ display:"inline-flex", alignItems:"center", gap:4, padding: inline?"0":"2px 7px", borderRadius:99, background: inline?"transparent":c.bg, color:c.fg, fontSize:11, fontWeight:500, border: inline?"none":"1px solid "+c.line, textTransform:"capitalize" }}>
      {v}
    </span>
  );
}
function EffortPill({ v, inline }){
  const map = { low:{fg:"var(--pos)"}, medium:{fg:"var(--warn)"}, high:{fg:"var(--neg)"} };
  const c = map[v] || map.low;
  return <span style={{ color:c.fg, fontSize:11, fontWeight:500, textTransform:"capitalize" }}>{v}</span>;
}
function RiskPill({ v, inline }){
  const map = { none:{fg:"var(--pos)"}, low:{fg:"var(--pos)"}, medium:{fg:"var(--warn)"}, high:{fg:"var(--neg)"} };
  const c = map[v] || map.low;
  return <span style={{ color:c.fg, fontSize:11, fontWeight:500, textTransform:"capitalize" }}>{v}</span>;
}

function Metric({ label, value }){
  return (
    <span style={{ display:"inline-flex", alignItems:"baseline", gap:5, fontSize:11 }}>
      <span style={{ color:"var(--fg-3)", textTransform:"uppercase", letterSpacing:0.06, fontWeight:600, fontSize:10 }}>{label}</span>
      <span style={{ color:"var(--fg-0)", fontWeight:500 }} className={typeof value === "string" ? "mono" : ""}>{value}</span>
    </span>
  );
}
function Sep(){ return <span style={{ width:3, height:3, borderRadius:"50%", background:"var(--line-2)" }}/>; }

function SelectMini({ value, onChange, options, icon }){
  return (
    <div style={{ position:"relative", display:"inline-block" }}>
      <select value={value} onChange={e=>onChange(e.target.value)} style={{
        appearance:"none", background:"#fff",
        border:"1px solid var(--line-2)", borderRadius:7,
        padding:"5px 26px 5px 26px", fontSize:12, fontFamily:"inherit",
        color:"var(--fg-0)", cursor:"pointer", outline:"none",
      }}>
        {options.map(o => <option key={o.id} value={o.id}>{o.label}</option>)}
      </select>
      <span style={{ position:"absolute", left:8, top:"50%", transform:"translateY(-50%)", color:"var(--fg-3)", pointerEvents:"none", display:"flex" }}>
        <Icon name={icon} size={11} stroke="var(--fg-3)"/>
      </span>
      <span style={{ position:"absolute", right:8, top:"50%", transform:"translateY(-50%)", color:"var(--fg-3)", pointerEvents:"none", display:"flex" }}>
        <Icon name="chevDown" size={11} stroke="var(--fg-3)"/>
      </span>
    </div>
  );
}

function CodeBlock({ code }){
  return (
    <pre style={{
      margin:0, padding:"11px 13px",
      background:"#1a1814",
      borderRadius:7,
      fontFamily:"var(--font-mono)", fontSize:11.5,
      color:"#f5f4f1",
      overflowX:"auto",
      lineHeight:1.55,
      whiteSpace:"pre",
    }}>{code}</pre>
  );
}

// ── Sidebar cards ─────────────────────────────────────────
function SavingsBreakdownCard({ byKind, total }){
  const items = Object.entries(byKind).map(([k,v])=>({ k, ...v, def:REC_KINDS[k] })).sort((a,b)=>b.savings-a.savings);
  return (
    <div className="card" style={{ padding:"16px 18px" }}>
      <h3 style={{ margin:"0 0 12px", fontSize:12.5, fontWeight:600 }}>Savings summary</h3>
      <div style={{ display:"flex", flexDirection:"column", gap:9 }}>
        <div style={{ display:"flex", justifyContent:"space-between", alignItems:"baseline" }}>
          <span style={{ fontSize:11.5, color:"var(--fg-2)" }}>Total potential</span>
          <span className="mono" style={{ fontSize:14, fontWeight:600, color:"var(--pos)" }}>{fmtGBP(total)}<span style={{ fontSize:10, color:"var(--fg-3)", fontWeight:400, marginLeft:3 }}>/mo</span></span>
        </div>
        <div style={{ display:"flex", justifyContent:"space-between", fontSize:11.5 }}>
          <span style={{ color:"var(--fg-2)" }}>Recommendations</span>
          <span className="mono" style={{ color:"var(--fg-0)" }}>{RECOMMENDATIONS.length}</span>
        </div>
        <div style={{ display:"flex", justifyContent:"space-between", fontSize:11.5 }}>
          <span style={{ color:"var(--fg-2)" }}>Reviewed this period</span>
          <span className="mono" style={{ color:"var(--fg-0)" }}>2</span>
        </div>
      </div>
      <div style={{ height:1, background:"var(--line-1)", margin:"12px 0" }}/>
      <div style={{ fontSize:10.5, color:"var(--fg-3)", textTransform:"uppercase", letterSpacing:0.06, fontWeight:600, marginBottom:8 }}>By type</div>
      <div style={{ display:"flex", flexDirection:"column", gap:7 }}>
        {items.map(it => (
          <div key={it.k} style={{ display:"flex", alignItems:"center", gap:8, fontSize:11.5 }}>
            <span style={{ width:8, height:8, borderRadius:2, background:it.def.color, flexShrink:0 }}/>
            <span style={{ flex:1, color:"var(--fg-1)" }}>{it.def.label}</span>
            <span className="mono" style={{ color:"var(--fg-3)" }}>{it.count}</span>
            <span className="mono" style={{ color:"var(--fg-0)", fontWeight:500, minWidth:48, textAlign:"right" }}>{fmtGBP(it.savings)}</span>
          </div>
        ))}
      </div>
    </div>
  );
}

function MethodologyCard(){
  return (
    <div className="card" style={{ padding:"16px 18px" }}>
      <div style={{ display:"flex", alignItems:"center", gap:7, marginBottom:8 }}>
        <Icon name="info" size={13} stroke="var(--fg-2)"/>
        <h3 style={{ margin:0, fontSize:12.5, fontWeight:600 }}>How we recommend</h3>
      </div>
      <ol style={{ margin:0, padding:"0 0 0 18px", fontSize:11.5, color:"var(--fg-2)", lineHeight:1.55 }}>
        <li>Scan last 30 days of usage by project & member.</li>
        <li>Match call patterns against known savings playbooks (caching, batching, model fit).</li>
        <li>Estimate savings using published rates + token equivalence.</li>
        <li>Bound quality risk per recommendation using our calibration set.</li>
      </ol>
      <div style={{ marginTop:10, paddingTop:10, borderTop:"1px solid var(--line-1)" }}>
        <button style={{ ...btnSubtle(), color:"var(--accent)", padding:0 }}>Read full methodology <Icon name="arrow" size={11} stroke="var(--accent)"/></button>
      </div>
    </div>
  );
}

function PlaybookCard(){
  const links = [
    { title:"Prompt caching guide",       sub:"~10 min · with code samples", icon:"chip" },
    { title:"Message Batches API",        sub:"~15 min · async workflows",   icon:"layers" },
    { title:"Model routing playbook",     sub:"~20 min · cost/quality trade-offs", icon:"refresh" },
    { title:"Token economics 101",        sub:"~5 min · reading",            icon:"tokens" },
  ];
  return (
    <div className="card" style={{ padding:"16px 18px" }}>
      <h3 style={{ margin:"0 0 10px", fontSize:12.5, fontWeight:600 }}>Optimisation playbook</h3>
      <div style={{ display:"flex", flexDirection:"column", gap:6 }}>
        {links.map((l,i) => (
          <a key={i} href="#" style={{ display:"flex", alignItems:"center", gap:9, padding:"8px 9px", borderRadius:7, textDecoration:"none", color:"var(--fg-0)", border:"1px solid transparent" }}
             onMouseEnter={e=>{ e.currentTarget.style.background="var(--bg-3)"; e.currentTarget.style.borderColor="var(--line-1)" }}
             onMouseLeave={e=>{ e.currentTarget.style.background="transparent"; e.currentTarget.style.borderColor="transparent" }}>
            <div style={{ width:24, height:24, borderRadius:6, background:"var(--accent-soft)", color:"var(--accent)", display:"flex", alignItems:"center", justifyContent:"center" }}>
              <Icon name={l.icon} size={12}/>
            </div>
            <div style={{ flex:1, minWidth:0 }}>
              <div style={{ fontSize:12, fontWeight:500 }}>{l.title}</div>
              <div style={{ fontSize:10.5, color:"var(--fg-3)" }}>{l.sub}</div>
            </div>
            <Icon name="ext" size={11} stroke="var(--fg-3)"/>
          </a>
        ))}
      </div>
    </div>
  );
}

function StatusCard({ total }){
  const states = [
    { id:"new",      label:"New",         n:7, color:"var(--accent)" },
    { id:"reviewed", label:"Reviewed",    n:2, color:"var(--pos)" },
    { id:"snoozed",  label:"Snoozed",     n:0, color:"var(--warn)" },
    { id:"na",       label:"Not applicable", n:0, color:"var(--fg-3)" },
  ];
  return (
    <div className="card" style={{ padding:"16px 18px" }}>
      <h3 style={{ margin:"0 0 10px", fontSize:12.5, fontWeight:600 }}>Status</h3>
      <div style={{ display:"flex", flexDirection:"column", gap:8 }}>
        {states.map(s => (
          <div key={s.id} style={{ display:"flex", alignItems:"center", justifyContent:"space-between", fontSize:12 }}>
            <span style={{ display:"inline-flex", alignItems:"center", gap:8 }}>
              <span style={{ width:8, height:8, borderRadius:"50%", background:s.color }}/>
              <span style={{ color:"var(--fg-1)" }}>{s.label}</span>
            </span>
            <span className="mono" style={{ color:"var(--fg-0)", fontWeight:500 }}>{s.n}</span>
          </div>
        ))}
      </div>
    </div>
  );
}

// ── Adopted log ───────────────────────────────────────────
function AdoptedLog(){
  return (
    <section className="card" style={{ padding:0, overflow:"hidden" }}>
      <div style={{ padding:"14px 18px", borderBottom:"1px solid var(--line-1)", display:"flex", alignItems:"center", justifyContent:"space-between" }}>
        <div>
          <h2 style={{ margin:0, fontSize:13.5, fontWeight:600 }}>Adopted recently</h2>
          <div style={{ fontSize:11, color:"var(--fg-2)", marginTop:2 }}>Realised savings vs. estimate · last 30 days</div>
        </div>
        <span style={{ fontSize:11, color:"var(--fg-3)" }}>{ADOPTED.length} adopted</span>
      </div>
      <div>
        {ADOPTED.map((a, i) => (
          <div key={a.id} style={{ padding:"12px 18px", borderTop: i>0 ? "1px solid var(--line-1)" : "none", display:"flex", alignItems:"center", gap:12 }}>
            <div style={{ width:28, height:28, borderRadius:7, background:"var(--pos-soft)", color:"var(--pos)", display:"flex", alignItems:"center", justifyContent:"center" }}>
              <Icon name="check" size={13}/>
            </div>
            <div style={{ flex:1, minWidth:0 }}>
              <div style={{ fontSize:12.5, fontWeight:500, color:"var(--fg-0)" }}>{a.title}</div>
              <div style={{ fontSize:11, color:"var(--fg-3)", marginTop:2 }}>Applied <span className="mono">{a.at}</span> · <span className="mono">/{a.project}</span></div>
            </div>
            <div style={{ textAlign:"right" }}>
              <div className="mono" style={{ fontSize:13, fontWeight:600, color:"var(--pos)" }}>£{a.actual.toFixed(4)} / call</div>
              <div className="mono" style={{ fontSize:10.5, color:"var(--fg-3)", marginTop:2 }}>est £{a.est.toFixed(4)} · {a.delta>0?"↑":"↓"}{Math.abs(a.delta*100).toFixed(0)}%</div>
            </div>
          </div>
        ))}
      </div>
    </section>
  );
}

Object.assign(window, { Optimisation });
