// JARVIS v3 — layout components: TickerBar, Sidebar, BriefingCard, SyncButton, PageHead, TaskRow, Kpi, CCPayoffMini

// ── TickerBar ────────────────────────────────────────────────────────────────
function TickerBar() {
  const D = window.JARVIS_DATA;
  const [now, setNow] = React.useState(new Date());
  React.useEffect(() => {
    const id = setInterval(() => setNow(new Date()), 1000);
    return () => clearInterval(id);
  }, []);

  const day = now.toLocaleDateString("en-US", { weekday: "short", month: "numeric", day: "numeric" });
  const time = now.toLocaleTimeString("en-US", { hour: "2-digit", minute: "2-digit", hour12: false });

  const m = D.metrics || {};
  const nw = m.netWorth || 0;
  const items = [
    { lbl: "NW",   val: fmtMoney(nw), cls: nw < 0 ? "neg" : "pos" },
    { lbl: "AST",  val: fmtMoney(m.assets || 0), cls: "" },
    { lbl: "DBT",  val: fmtMoney(m.liab || 0), cls: "neg" },
    { lbl: "CC",   val: fmtMoney(m.cc || 0), cls: "neg" },
    { lbl: "RNW",  val: (m.cashRunwayMo || 0).toFixed(1) + " mo", cls: "warn" },
    { lbl: "ACAD", val: (m.gpa || 0).toFixed(2), cls: "pos" },
    { lbl: "HLTH", val: String(m.wellness || 0), cls: "pos" },
    { lbl: "SLP",  val: String((D.health || {}).sleep ? D.health.sleep.val : 0), cls: "pos" },
    { lbl: "REC",  val: String((D.health || {}).recovery ? D.health.recovery.val : 0), cls: "pos" },
    { lbl: "STR",  val: String((D.health || {}).strain ? D.health.strain.val : 0), cls: "warn" },
    { lbl: "SRC",  val: (m.accounts || 0) + " acct", cls: "" },
    { lbl: "MIL",  val: (m.milestones ? m.milestones.done + " / " + m.milestones.total : "—"), cls: "pos" },
    { lbl: "TSK",  val: (m.openTasks || 0) + " open", cls: "warn" },
    { lbl: "RCG",  val: fmtMoney((D.ventures || []).find(v => v.key === "RCG")?.mtd || 0) + " MTD", cls: "neg" },
    { lbl: "RBV",  val: fmtMoney((D.ventures || []).find(v => v.key === "RBV")?.mtd || 0) + " MTD", cls: "neg" },
    { lbl: "HOME", val: fmtMoney(m.homeValue || 0), cls: "" },
    { lbl: "EQTY", val: fmtMoney(m.homeEquity || 0), cls: "" },
  ];
  const doubled = [...items, ...items];

  return (
    <div className="ticker">
      <div className="ticker-now">
        <span className="dot" />
        <span className="live">LIVE</span>
        <span style={{color: "var(--fg-invert-mid)"}}>{day}</span>
        <span style={{color: "white"}}>{time} ET</span>
      </div>
      <div className="ticker-marquee">
        <div className="ticker-track">
          {doubled.map((it, i) => (
            <span key={i} className="ticker-item">
              <span className="lbl">{it.lbl}</span>
              <span className={"val " + it.cls}>{it.val}</span>
            </span>
          ))}
        </div>
      </div>
    </div>
  );
}

// ── NavIcon ──────────────────────────────────────────────────────────────────
function NavIcon({ name }) {
  const common = { width: 15, height: 15, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1.8, strokeLinecap: "round", strokeLinejoin: "round" };
  switch(name) {
    case "overview":  return <svg {...common}><rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><rect x="14" y="14" width="7" height="7" rx="1"/></svg>;
    case "finance":   return <svg {...common}><path d="M3 20V6"/><path d="M3 20h18"/><path d="M7 16v-4"/><path d="M11 16V9"/><path d="M15 16v-6"/><path d="M19 16V7"/></svg>;
    case "ventures":  return <svg {...common}><path d="M3 17l6-6 4 4 8-8"/><path d="M14 7h7v7"/></svg>;
    case "academics": return <svg {...common}><path d="M22 10L12 5 2 10l10 5 10-5z"/><path d="M6 12v5c0 1 3 3 6 3s6-2 6-3v-5"/></svg>;
    case "family":    return <svg {...common}><circle cx="9" cy="8" r="3"/><circle cx="17" cy="10" r="2"/><path d="M3 20c0-3 3-5 6-5s6 2 6 5"/><path d="M15 20c0-2 1-3 2-3s2 1 2 3"/></svg>;
    case "calendar":  return <svg {...common}><rect x="3" y="5" width="18" height="16" rx="2"/><path d="M3 10h18"/><path d="M8 3v4"/><path d="M16 3v4"/></svg>;
    case "health":    return <svg {...common}><path d="M3 12h4l2-6 4 12 2-6h6"/></svg>;
    case "projects":  return <svg {...common}><rect x="3" y="4" width="18" height="16" rx="2"/><path d="M7 9h10"/><path d="M7 13h7"/><path d="M7 17h5"/></svg>;
    case "home":      return <svg {...common}><path d="M3 11l9-7 9 7"/><path d="M5 10v10h14V10"/><path d="M10 20v-5h4v5"/></svg>;
    case "chat":      return <svg {...common}><path d="M21 12c0 4-4 7-9 7-1.5 0-2.9-.3-4-.7L3 20l1-4c-.6-1-1-2.4-1-4 0-4 4-7 9-7s9 3 9 7z"/></svg>;
    case "inbox":     return <svg {...common}><path d="M3 13l3-8h12l3 8"/><path d="M3 13v6h18v-6"/><path d="M3 13h5l2 3h4l2-3h5"/></svg>;
    default:          return null;
  }
}

// ── Sidebar ──────────────────────────────────────────────────────────────────
function Sidebar({ current, onNavigate, collapsed, onToggleCollapsed }) {
  const D = window.JARVIS_DATA;
  const healthScore = D.metrics ? D.metrics.wellness : 92;
  const inboxUnread = (D.inboxItems || []).filter(i => !i.read).length;

  const items = [
    { group: "MAIN", entries: [
      { id: "overview",  label: "Overview",         icon: "overview",  kbd: "⌘1" },
      { id: "finances",  label: "Finances",          icon: "finance",   kbd: "⌘2" },
      { id: "academics", label: "Academics",         icon: "academics", kbd: "⌘3" },
      { id: "ventures",  label: "Ventures",          icon: "ventures",  kbd: "⌘4" },
      { id: "family",    label: "Child Development", icon: "family",    kbd: "⌘5" },
      { id: "calendar",  label: "Calendar",          icon: "calendar",  kbd: "⌘6" },
      { id: "health",    label: "Health",            icon: "health",    kbd: "⌘7", badge: { txt: String(healthScore), cls: "good" } },
      { id: "projects",  label: "Projects",          icon: "projects",  kbd: "⌘8" }
    ]},
    { group: "PROPERTY", entries: [
      { id: "home", label: "Home Value", icon: "home", kbd: "⌘H" }
    ]},
    { group: "ASSISTANT", entries: [
      { id: "chat",  label: "JARVIS Chat",   icon: "chat",  kbd: "⌘K" },
      { id: "inbox", label: "Action Inbox",  icon: "inbox", kbd: "⌘I", badge: inboxUnread > 0 ? { txt: String(inboxUnread) } : undefined }
    ]}
  ];

  return (
    <aside className={"sidebar" + (collapsed ? " collapsed" : "")}>
      <div className="sidebar-brand">
        <div className="logo" title={collapsed ? "JARVIS Command Center" : undefined}>J</div>
        {!collapsed && (
          <div>
            <div className="name">JARVIS</div>
            <div className="sub">Command Center</div>
          </div>
        )}
      </div>

      {items.map(group => (
        <div key={group.group} className="sidebar-section">
          {!collapsed && <div className="sidebar-label">{group.group}</div>}
          {group.entries.map(it => (
            <button
              key={it.id}
              className={"nav-item" + (current === it.id ? " active" : "")}
              onClick={() => onNavigate(it.id)}
              title={collapsed ? it.label : undefined}
            >
              <span className="icon"><NavIcon name={it.icon} /></span>
              {!collapsed && <span className="label">{it.label}</span>}
              {!collapsed && (it.badge
                ? <span className={"badge " + (it.badge.cls || "")}>{it.badge.txt}</span>
                : <span className="kbd">{it.kbd}</span>)}
            </button>
          ))}
        </div>
      ))}

      <div className="sidebar-foot">
        <div className="avatar" title={collapsed ? "Stephen Robinson" : undefined}>S</div>
        {!collapsed && (
          <div style={{lineHeight: 1.3, minWidth: 0}}>
            <div style={{color: "var(--fg)", fontWeight: 500, fontSize: 12}}>Stephen Robinson</div>
            <div style={{fontSize: 10.5, fontFamily: "var(--font-mono)"}}>v3.0 · JARVIS</div>
          </div>
        )}
      </div>
    </aside>
  );
}

// ── BriefingCard ─────────────────────────────────────────────────────────────
function BriefingCard({ items, onDismiss, defaultExpanded = true }) {
  const [expanded, setExpanded] = React.useState(defaultExpanded);
  const [dismissed, setDismissed] = React.useState(false);

  if (dismissed) return null;

  const critical = items.filter(b => b.level === "red").length;
  const amber = items.filter(b => b.level === "amber").length;

  if (!expanded) {
    return (
      <div style={{marginBottom: 14}}>
        <span className="brief-pill" onClick={() => setExpanded(true)}>
          <span className="pulse" />
          <span className="lbl">JARVIS Briefing</span>
          <span className="count">{items.length}</span>
          <span style={{color: "var(--fg-soft)", fontSize: 11, marginLeft: 4}}>{critical} critical · {amber} watch</span>
        </span>
      </div>
    );
  }

  return (
    <div className="briefing">
      <div className="briefing-h">
        <div className="lbl" style={{flexWrap: "wrap"}}>
          <span style={{ display: "inline-block", width: 6, height: 6, borderRadius: "50%", background: "var(--green)" }} />
          <span style={{whiteSpace: "nowrap"}}>JARVIS Briefing</span>
          <span className="count">{items.length}</span>
          <span style={{color: "var(--fg-soft)", marginLeft: 6, fontSize: 10.5, whiteSpace: "nowrap"}}>
            {critical} critical · {amber} watch · {items.length - critical - amber} info
          </span>
        </div>
        <div style={{display: "flex", gap: 4, flexShrink: 0}}>
          <button className="x" onClick={() => setExpanded(false)} title="Minimize">−</button>
          <button className="x" onClick={() => { setDismissed(true); if (onDismiss) onDismiss(); }} title="Dismiss">×</button>
        </div>
      </div>
      <div className="briefing-list">
        {items.map(b => (
          <div className="briefing-row" key={b.id}>
            <div className="top">
              <span className={"dot " + b.level} />
              <span className="age">{b.age}</span>
            </div>
            <div className="ttl">{b.title}</div>
            <div className="ctx">{b.ctx}</div>
          </div>
        ))}
      </div>
    </div>
  );
}

// ── SyncButton ───────────────────────────────────────────────────────────────
function SyncIcon({ spinning }) {
  return (
    <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"
      strokeLinecap="round" strokeLinejoin="round"
      style={{ transition: "transform 0.3s", animation: spinning ? "sync-spin 0.9s linear infinite" : "none" }}>
      <path d="M21 12a9 9 0 1 1-3-6.7"/>
      <polyline points="21 4 21 10 15 10"/>
    </svg>
  );
}

function relativeTime(ms) {
  const d = Date.now() - ms;
  if (d < 60000) return Math.max(1, Math.floor(d/1000)) + "s ago";
  if (d < 3600000) return Math.floor(d/60000) + "m ago";
  if (d < 86400000) return Math.floor(d/3600000) + "h ago";
  return Math.floor(d/86400000) + "d ago";
}

function SyncButton({ label, sources, defaultLastSyncMin = 8, onSync }) {
  const [open, setOpen] = React.useState(false);
  const [syncing, setSyncing] = React.useState(null);
  const [synced, setSynced] = React.useState(false);
  const [items, setItems] = React.useState(() =>
    (sources || []).map((s, i) => ({
      ...s,
      lastSync: s.lastSync ?? (Date.now() - (defaultLastSyncMin + i * 3) * 60 * 1000)
    }))
  );
  const [, setTick] = React.useState(0);
  React.useEffect(() => {
    const id = setInterval(() => setTick(t => t + 1), 30000);
    return () => clearInterval(id);
  }, []);

  const ref = React.useRef(null);
  React.useEffect(() => {
    if (!open) return;
    const onDoc = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener("mousedown", onDoc);
    return () => document.removeEventListener("mousedown", onDoc);
  }, [open]);

  const runSync = (sourceId) => {
    setSyncing(sourceId || "all");
    setSynced(false);
    // Trigger a real backend refresh if available
    if (onSync) onSync();
    else if (window.__jarvisRefresh) window.__jarvisRefresh();
    setTimeout(() => {
      setItems(its => its.map(it =>
        (!sourceId || it.id === sourceId) ? { ...it, lastSync: Date.now(), status: "ok" } : it
      ));
      setSyncing(null);
      setSynced(true);
      setTimeout(() => setSynced(false), 1800);
    }, 1300);
  };

  const oldest = items.length ? Math.min(...items.map(it => it.lastSync)) : Date.now();

  return (
    <div className="sync-btn-wrap" ref={ref}>
      <button
        className={"sync-btn" + (syncing ? " syncing" : "") + (synced ? " synced" : "")}
        onClick={() => {
          if (items.length === 1) { runSync(items[0].id); }
          else { setOpen(o => !o); }
        }}
        title={"Last sync: " + relativeTime(oldest)}
      >
        <SyncIcon spinning={!!syncing} />
        <span className="sync-label">
          {syncing ? "Syncing…" : synced ? "Synced" : (label || "Sync")}
        </span>
        <span className="sync-time">{relativeTime(oldest)}</span>
        {items.length > 1 && (
          <svg width="9" height="9" viewBox="0 0 12 12" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" style={{opacity: 0.6, marginLeft: 2}}>
            <polyline points="3,4.5 6,7.5 9,4.5"/>
          </svg>
        )}
      </button>

      {open && (
        <div className="sync-menu">
          <div className="sync-menu-head">
            <span className="mono" style={{fontSize: 10, letterSpacing: "0.08em", textTransform: "uppercase", color: "var(--fg-soft)"}}>Connected sources</span>
            <button className="sync-all" onClick={() => { runSync(); setOpen(false); }}>Sync all</button>
          </div>
          {items.map(it => (
            <button key={it.id} className="sync-item" onClick={() => { runSync(it.id); setOpen(false); }}>
              <span className={"dot " + (it.status === "error" ? "red" : it.status === "pending" ? "amber" : "green")} />
              <span className="sync-item-body">
                <span className="sync-item-lbl">{it.label}</span>
                <span className="sync-item-time">Last sync · {relativeTime(it.lastSync)}</span>
              </span>
              <SyncIcon spinning={syncing === it.id} />
            </button>
          ))}
        </div>
      )}
    </div>
  );
}

// ── PageHead ─────────────────────────────────────────────────────────────────
function PageHead({ navigate }) {
  const now = new Date();
  const hour = now.getHours();
  const greeting = hour < 12 ? "GOOD MORNING" : hour < 17 ? "GOOD AFTERNOON" : "GOOD EVENING";
  const dateStr = now.toLocaleDateString("en-US", { weekday: "long", month: "long", day: "numeric" }).toUpperCase();

  return (
    <div className="page-head">
      <div>
        <div className="eyebrow">{greeting}, STEPHEN · {dateStr}</div>
        <h1>Life Status</h1>
      </div>
      <div className="actions">
        <div className="seg">
          <button className="active">Today</button>
          <button>Week</button>
          <button>Month</button>
        </div>
        <button className="icon-btn" title="Alerts">
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.7 21a2 2 0 0 1-3.4 0"/></svg>
        </button>
      </div>
    </div>
  );
}

// ── TaskRow ──────────────────────────────────────────────────────────────────
function TaskRow({ task }) {
  const [done, setDone] = React.useState(false);
  const toggle = (e) => { e.stopPropagation(); setDone(d => !d); };
  return (
    <div className={"task" + (done ? " done" : "")} onClick={toggle}>
      <span className="check" />
      <div className="body">
        <div className="ttl">{task.title}</div>
        <div className="meta">
          <span>{task.area.toUpperCase()}</span>
          <span>·</span>
          <span>P{task.priority}</span>
        </div>
      </div>
      <div className={"due " + (task.dueLevel || "")}>{task.due}</div>
    </div>
  );
}

// ── Kpi ──────────────────────────────────────────────────────────────────────
function Kpi({ lbl, val, sub, tiny }) {
  return (
    <div className={"kpi" + (tiny ? " tiny" : "")} style={tiny ? {padding: "10px 12px"} : undefined}>
      <div className="lbl">{lbl}</div>
      <div className="val" style={tiny ? {fontSize: 18} : undefined}>{val}</div>
      {sub ? <div className="sub">{sub}</div> : null}
    </div>
  );
}

// ── CCPayoffMini ─────────────────────────────────────────────────────────────
function CCPayoffMini() {
  const months = ["Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
  const plan = [26500, 25200, 23200, 20800, 18200, 15400, 12000, 8400, 4200, 0];
  const actual = [26500, 25200, 22729];
  const glide2 = [null, null, 22729, 19500, 16200, 13000, 10000, 7000, 4000, 0];
  const fillNulls = (arr) => {
    const out = []; let last = arr.find(v => v !== null);
    for (let i = 0; i < arr.length; i++) { if (arr[i] != null) last = arr[i]; out.push(last); }
    return out;
  };
  const padToLen = (arr, len) => {
    const out = arr.slice();
    while (out.length < len) out.push(out[out.length - 1]);
    return out;
  };
  return (
    <div>
      <LineChart
        series={[
          { values: plan, color: "#A4A4AC", dash: "4 3", strokeWidth: 1.4 },
          { values: fillNulls(glide2), color: "#3b6bd6", dash: "5 3", strokeWidth: 1.6 },
          { values: padToLen(actual, months.length), color: "oklch(0.6 0.2 25)", strokeWidth: 2.2 }
        ]}
        w={600} h={160}
        yFmt={v => "$" + Math.round(v/1000) + "k"}
        xLabels={months}
      />
      <div style={{display: "flex", gap: 14, marginTop: 6, fontSize: 11, color: "var(--fg-soft)", fontFamily: "var(--font-mono)"}}>
        <span><span style={{display: "inline-block", width: 14, height: 2, background: "#A4A4AC", verticalAlign: "middle", marginRight: 4}}/> Plan</span>
        <span><span style={{display: "inline-block", width: 14, height: 2, background: "#3b6bd6", verticalAlign: "middle", marginRight: 4}}/> Glide path</span>
        <span><span style={{display: "inline-block", width: 14, height: 2, background: "oklch(0.6 0.2 25)", verticalAlign: "middle", marginRight: 4}}/> Actual</span>
      </div>
    </div>
  );
}

// ── OverviewV3 ────────────────────────────────────────────────────────────────
function BentoHead({ status, lbl, right }) {
  return (
    <div className="head">
      <span className="lbl" style={{display: "flex", alignItems: "center", gap: 8}}>
        <span className={"dot " + status} />
        {lbl}
      </span>
      {right}
    </div>
  );
}

function MiniStat({ lbl, val, red, amber }) {
  return (
    <div style={{
      background: "var(--bg-sunken)",
      border: "1px solid var(--border-soft)",
      borderRadius: 6,
      padding: "8px 10px"
    }}>
      <div className="mono" style={{fontSize: 9.5, color: "var(--fg-soft)", letterSpacing: "0.08em", textTransform: "uppercase", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis"}}>{lbl}</div>
      <div style={{
        fontSize: 14, fontWeight: 600, marginTop: 2, fontVariantNumeric: "tabular-nums", whiteSpace: "nowrap",
        color: red ? "var(--red)" : amber ? "oklch(0.55 0.14 65)" : "var(--fg)"
      }}>{val}</div>
    </div>
  );
}

function OverviewV3({ navigate }) {
  const D = window.JARVIS_DATA;
  const m = D.metrics || {};

  return (
    <div className="main-inner">
      <PageHead navigate={navigate} />

      <BriefingCard items={(D.briefing || []).slice(0, 4)} defaultExpanded={true} />

      <div className="bento">
        <div className="bento-cell" style={{cursor: "pointer"}} onClick={() => navigate("finances")}>
          <BentoHead status="red" lbl="Finance" right={<span className="pill amber">CC P1 · {m.ccApr || 0}%</span>} />
          <div className="metric-row">
            <div className={"big-num" + (m.netWorth < 0 ? " neg" : "")}>{fmtMoney(m.netWorth || 0)}</div>
            <span className="big-sub">Net worth · 12mo</span>
          </div>
          <div style={{margin: "0 -4px"}}>
            <Sparkline values={D.sparks.netWorth} w={580} h={56} responsive color="oklch(0.6 0.2 25)" fill="oklch(0.94 0.06 25)" strokeWidth={1.8} />
          </div>
          <div style={{display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 8, marginTop: "auto"}}>
            <MiniStat lbl="Assets" val={fmtMoney(m.assets || 0)} />
            <MiniStat lbl="Debt" val={fmtMoney(m.liab || 0)} red />
            <MiniStat lbl="Runway" val={(m.cashRunwayMo || 0).toFixed(1) + " mo"} amber />
          </div>
        </div>

        <div className="bento-cell" style={{cursor: "pointer"}} onClick={() => navigate("ventures")}>
          <BentoHead status="red" lbl="Ventures" right={<span className="pill red">2 STALLED</span>} />
          <div className="metric-row">
            <div className="big-num">{fmtMoney(m.mtdRev || 0)}</div>
            <span className="big-sub">MTD revenue · 12mo</span>
          </div>
          <div style={{margin: "0 -4px"}}>
            <Sparkline values={D.sparks.rev} w={580} h={56} responsive color="oklch(0.72 0.14 70)" fill="oklch(0.94 0.06 80)" strokeWidth={1.8} />
          </div>
          <div style={{display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8, marginTop: "auto"}}>
            {(D.ventures || []).map(v => (
              <MiniStat key={v.key} lbl={v.key + " · " + (v.stage || "").toLowerCase()} val={"$" + (v.mrrAvg || 0).toLocaleString() + " MRR"} amber={v.status === "stalled"} red={v.mtd === 0 && v.status !== "active"} />
            ))}
          </div>
        </div>

        <div className="bento-cell" style={{cursor: "pointer"}} onClick={() => navigate("academics")}>
          <BentoHead status="green" lbl="Academics" right={<span className="pill">FALL 26 · 2 UPCOMING</span>} />
          <div className="metric-row">
            <div className="big-num">{(m.gpa || 0).toFixed(2)}</div>
            <span className="big-sub">GPA · M.S. AI · {(D.courses || []).filter(c => c.status === "passed").length} of {(D.courses || []).length} passed</span>
          </div>
          <div style={{marginTop: "auto", display: "flex", flexDirection: "column", gap: 7}}>
            {(D.courses || []).slice(0, 6).map(c => (
              <div key={c.code} style={{display: "grid", gridTemplateColumns: "70px 1fr 24px", alignItems: "center", gap: 8, fontSize: 11.5}}>
                <span className="mono" style={{color: "var(--fg-mid)", fontWeight: 500}}>{c.code}</span>
                <Progress value={c.progress} color={c.progress === 0 ? "var(--fg-mute)" : "oklch(0.62 0.15 145)"} height={4} />
                <span className="mono" style={{color: c.progress === 0 ? "var(--fg-soft)" : "var(--fg-mid)", fontSize: 11, textAlign: "right", fontWeight: 500}}>{c.grade}</span>
              </div>
            ))}
          </div>
        </div>

        <div className="bento-cell" style={{cursor: "pointer"}} onClick={() => navigate("health")}>
          <BentoHead status="green" lbl="Wellness" right={<span className="pill green">RECOVERY HIGH</span>} />
          <div className="metric-row">
            <div className="big-num">{m.wellness || 0}</div>
            <span className="big-sub">Wellness · today</span>
          </div>
          <div style={{display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 8, marginTop: "auto", paddingTop: 4}}>
            {D.health && (
              <>
                <Ring value={D.health.sleep.val} label="Sleep" sub={D.health.sleep.sub} color={D.health.sleep.color} size={64} />
                <Ring value={D.health.recovery.val} label="Recovery" sub={D.health.recovery.sub} color={D.health.recovery.color} size={64} />
                <Ring value={D.health.strain.val} label="Strain" sub={D.health.strain.sub} color={D.health.strain.color} size={64} />
                <Ring value={D.health.calories.val} label="Calories" sub={D.health.calories.sub} color={D.health.calories.color} size={64} />
              </>
            )}
          </div>
        </div>
      </div>

      <div className="today-row">
        <div className="card" style={{cursor: "pointer"}} onClick={() => navigate("family")}>
          <div className="card-h">
            <div className="left">
              <div className="eyebrow">Family · {D.family ? D.family.child.name + " " + D.family.child.age : "Mason"}</div>
              <div className="title">Child development</div>
            </div>
            <span className="pill green">{m.milestones ? m.milestones.done + " / " + m.milestones.total : "26 / 26"}</span>
          </div>
          <div className="card-b">
            <div style={{display: "flex", alignItems: "baseline", justifyContent: "space-between", marginBottom: 10}}>
              <div>
                <div style={{fontSize: 22, fontWeight: 600, letterSpacing: "-0.01em"}}>All on track</div>
                <div style={{fontSize: 11, color: "var(--fg-soft)", fontFamily: "var(--font-mono)", marginTop: 2}}>5 domains · {m.milestones ? m.milestones.done : 26} milestones met</div>
              </div>
            </div>
            {D.family && D.family.milestones && D.family.milestones[0] && (
              <>
                <div style={{fontSize: 11, color: "var(--fg-soft)", textTransform: "uppercase", letterSpacing: "0.08em", fontFamily: "var(--font-mono)", marginBottom: 6}}>Latest · {D.family.milestones[0].date}</div>
                <div style={{fontWeight: 500, fontSize: 13}}>{D.family.milestones[0].text}</div>
              </>
            )}
            <hr className="div"/>
            {D.family && D.family.next && (
              <div style={{display: "flex", justifyContent: "space-between", fontSize: 12}}>
                <span style={{color: "var(--fg-soft)"}}>Next appointment</span>
                <span style={{fontWeight: 500}} className="mono">{D.family.next.date} · {D.family.next.time}</span>
              </div>
            )}
          </div>
        </div>

        <div className="card">
          <div className="card-h">
            <div className="left">
              <div className="eyebrow">Priority queue · top 5 of {m.openTasks || 14}</div>
              <div className="title">Open tasks</div>
            </div>
            <span className="pill" style={{cursor: "pointer"}} onClick={(e) => { e.stopPropagation(); navigate("inbox"); }}>All →</span>
          </div>
          <div className="card-b flush">
            {(D.tasks || []).slice(0, 5).map(t => <TaskRow key={t.id} task={t} />)}
          </div>
        </div>

        <div className="card">
          <div className="card-h">
            <div className="left">
              <div className="eyebrow">Calendar · next 4</div>
              <div className="title">Week ahead</div>
            </div>
            <span className="pill" style={{cursor: "pointer"}} onClick={(e) => { e.stopPropagation(); navigate("calendar"); }}>Cal →</span>
          </div>
          <div className="card-b flush">
            {(D.schedule || []).map(s => (
              <div className="sched-row" key={s.id}>
                <div className="time">{s.time}<span className="d">{s.date ? s.date.split(" ").slice(1).join(" ") : ""}</span></div>
                <div>
                  <div className="ttl">{s.title}</div>
                  <div className="ctx">{s.ctx}</div>
                </div>
              </div>
            ))}
          </div>
        </div>
      </div>

      <div className="card" style={{marginTop: 12}}>
        <div className="card-h">
          <div className="left">
            <div className="eyebrow">Today · last 6h</div>
            <div className="title">Activity stream</div>
          </div>
          <span className="pill green">LIVE</span>
        </div>
        <div className="card-b flush" style={{display: "grid", gridTemplateColumns: "repeat(2, 1fr)"}}>
          {(D.activity || []).map((a, i) => (
            <div className="act-row" key={a.id} style={{borderRight: i % 2 === 0 ? "1px solid var(--border-soft)" : "none"}}>
              <div className="time">{a.time}</div>
              <div className="body">{a.text}</div>
              <div className={"amt " + a.level}>{a.amt}</div>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

Object.assign(window, {
  TickerBar, Sidebar, BriefingCard, SyncButton, PageHead, TaskRow, Kpi, CCPayoffMini, OverviewV3, MiniStat, BentoHead
});
