/* Remaining screens: team, person (git log), functions, reporting, people, events, timeline */

const { useState: useStateB, useMemo: useMemoB } = React;

/* ===================================================================
 * WORK GROUP DETAIL
 * ================================================================ */
function TeamScreen() {
  const { route, go, viewDate, setDrawer } = window.useApp();
  const wgId = route.params.id || "wg-core";
  const wg = window.wgById[wgId];
  const [tab, setTab] = useStateB("current");
  if (!wg) return null;

  const dim = window.dimById[wg.dimensionId];
  const children = window.childWorkGroups(wg.id);
  const breadcrumb = window.workGroupBreadcrumb(wg.id);
  const members = window.workGroupMembersAt(wg.id, viewDate).sort((a, b) => a.person.kind === "employee" ? -1 : 1);
  const owner = window.pById[wg.ownerId];
  const totals = window.workGroupTotals(wg.id, viewDate);
  const monthlySpend = members.filter((m) => m.person.kind === "contractor").reduce((s, m) => s + m.person.dailyRate * m.person.daysPerWeek * 4.33, 0);

  // Future planned changes affecting this work group (any descendant or current member)
  const wgIds = window.descendantWorkGroupIds(wg.id);
  const planned = window.EVENTS.filter((ev) => {
    if (ev.date < viewDate) return false;
    return wgIds.includes(ev.payload?.groupId) || wgIds.includes(ev.payload?.toGroup) ||
    (ev.payload?.allocations || []).some((a) => wgIds.includes(a.groupId)) ||
    (ev.payload?.to || []).some((a) => wgIds.includes(a.groupId)) ||
    members.some((m) => m.person.id === ev.personId);
  }).slice(0, 10);

  return (
    <>
      <TopBar crumbs={["Organisation", "Work groups", dim?.name, ...breadcrumb.slice(0, -1).map((b) => b.name), wg.name]} />
      <TTRibbon />
      <div className="page">
        <PageHead
          eyebrow={`${dim?.name} · ${children.length > 0 ? "parent group" : "leaf group"}${breadcrumb.length > 1 ? " · in " + breadcrumb[breadcrumb.length - 2].name : ""}`}
          title={wg.name}
          meta={
          <>
              <span style={{ display: "inline-flex", alignItems: "center", gap: 6 }}>
                <Avatar person={owner} /> Owner · <strong>{owner?.name}</strong>
              </span>
              <span className="muted">·</span>
              <span>{totals.total} people · {totals.emp}e / {totals.con}c</span>
              <span className="muted">·</span>
              <span>Contractor spend · <strong>{window.moneyK(monthlySpend)}</strong> / month</span>
            </>
          }
          actions={
          <>
              <button className="btn" onClick={() => setDrawer({ kind: "hire", payload: { groupId: wg.id } })}><Icon name="plus" />Onboard</button>
              <button className="btn btn-icon"><Icon name="more-horizontal" /></button>
            </>
          } />
        

        {children.length > 0 &&
        <div className="card" style={{ marginBottom: 14, padding: "10px 14px", display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap", fontSize: 12 }}>
            <span className="muted" style={{ letterSpacing: "0.08em", textTransform: "uppercase", fontSize: 10, fontWeight: 600 }}>Sub-groups</span>
            {children.map((ch) => {
            const t = window.workGroupTotals(ch.id, viewDate);
            return (
              <button key={ch.id} className="btn" onClick={() => go("team", { id: ch.id })} style={{ height: 24 }}>
                  {ch.name}
                  <span className="chip chip-fn" style={{ fontSize: 10 }}>{t.total}</span>
                </button>);

          })}
          </div>
        }

        <div className="stat-strip" style={{ gridTemplateColumns: "repeat(4, 1fr)" }}>
          <Stat label="Headcount" value={totals.total} bar={{ emp: totals.emp, con: totals.con }} meta={<><span className="muted">{children.length > 0 ? "incl. sub-groups" : "leaf group"}</span></>} />
          <Stat label="Monthly contractor cost" value={window.moneyK(monthlySpend)} meta={<><span className="muted">{members.filter((m) => m.person.kind === "contractor").length} active contractors</span></>} />
          <Stat label="Avg tenure" value={avgTenure(members, viewDate)} meta={<><span className="muted">across all members</span></>} />
          <Stat label="Planned changes" value={planned.length} meta={<><span className="muted">next 6 months</span></>} />
        </div>

        <TabStrip
          value={tab}
          onChange={setTab}
          tabs={[
          { value: "current", label: "Members", count: totals.total },
          { value: "timeline", label: "Composition over time" },
          { value: "planned", label: "Planned", count: planned.length },
          { value: "history", label: "Event history" }]
          } />
        

        {tab === "current" &&
        <div className="card" style={{ overflow: "hidden" }}>
            <table className="tbl">
              <thead>
                <tr>
                  <th style={{ minWidth: 240 }}>Person</th>
                  <th className="num">% in {wg.name}</th>
                  <th>Type</th>
                  <th>Role</th>
                  <th>Function</th>
                  <th>Manager</th>
                  <th>All allocations</th>
                  <th>Start</th>
                  <th className="num">Cost / month</th>
                </tr>
              </thead>
              <tbody>
                {members.map((m) => {
                const a = m.assignment;
                const monthly = m.person.kind === "contractor" ? m.person.dailyRate * m.person.daysPerWeek * 4.33 : null;
                return (
                  <tr key={m.person.id} onClick={() => go("person", { id: m.person.id })} style={{ cursor: "pointer" }}>
                      <td><PersonCell person={m.person} /></td>
                      <td className="num"><strong style={{ color: "var(--mf-watermelon-900)" }}>{m.pct}%</strong></td>
                      <td><KindChip kind={m.person.kind} /></td>
                      <td>{a.role}</td>
                      <td><span className="chip chip-fn">{window.fnById[a.functionId]?.name}</span></td>
                      <td>{window.pById[a.managerId]?.name || <span className="dim">—</span>}</td>
                      <td style={{ minWidth: 220 }}><window.AllocationBar allocations={a.allocations || []} height={8} /></td>
                      <td>{window.dstrShort(a.from)}</td>
                      <td className="num">{monthly ? window.moneyK(monthly * m.pct / 100) : <span className="dim">—</span>}</td>
                    </tr>);

              })}
              </tbody>
            </table>
          </div>
        }

        {tab === "timeline" && <TeamCompositionTimeline wgId={wg.id} />}
        {tab === "planned" && <PlannedList planned={planned} />}
        {tab === "history" && <TeamHistory wgId={wg.id} />}
      </div>
    </>);

}
window.TeamScreen = TeamScreen;

function avgTenure(members, viewDate) {
  if (members.length === 0) return "—";
  const total = members.reduce((s, m) => s + (viewDate - m.person.startDate), 0);
  const days = total / members.length / (1000 * 60 * 60 * 24);
  const years = days / 365;
  return years.toFixed(1) + "y";
}

/* Composition over time: stacked bar chart of headcount by month */
function TeamCompositionTimeline({ wgId }) {
  const months = [];
  let cur = new Date(window.HORIZON_PAST);
  while (cur <= window.HORIZON_FUTURE) {
    const sample = new Date(cur.getFullYear(), cur.getMonth(), 15);
    const m = window.workGroupMembersAt(wgId, sample);
    months.push({
      date: new Date(cur),
      emp: m.filter((x) => x.person.kind === "employee").length,
      con: m.filter((x) => x.person.kind === "contractor").length
    });
    cur = window.addMonths(cur, 1);
  }
  const max = Math.max(8, ...months.map((m) => m.emp + m.con));
  const today = window.TODAY;
  const todayIdx = months.findIndex((m) => m.date.getMonth() === today.getMonth() && m.date.getFullYear() === today.getFullYear());

  return (
    <div className="card">
      <div className="card-head"><div className="card-title"><Icon name="chart-up" />Composition over time</div>
        <div style={{ display: "flex", gap: 10, fontSize: 11, color: "var(--fg-3)" }}>
          <span><span className="chip-dot emp" style={{ display: "inline-block", marginRight: 4 }} />Employees</span>
          <span><span className="chip-dot con" style={{ display: "inline-block", marginRight: 4 }} />Contractors</span>
        </div>
      </div>
      <div style={{ padding: 18 }}>
        <div style={{ position: "relative", display: "flex", alignItems: "flex-end", gap: 2, height: 180, borderBottom: "1px solid var(--border-line)" }}>
          {months.map((m, i) => {
            const totalH = (m.emp + m.con) / max * 170;
            const empH = m.emp / max * 170;
            const conH = m.con / max * 170;
            const isFuture = i > todayIdx;
            return (
              <div key={i} title={`${window.monthLabel(m.date)}: ${m.emp}e + ${m.con}c = ${m.emp + m.con}`}
              style={{ flex: 1, display: "flex", flexDirection: "column", justifyContent: "flex-end", height: 170, position: "relative", opacity: isFuture ? 0.55 : 1 }}>
                {m.con > 0 && <div style={{ height: conH, background: "var(--mf-watermelon-900)", borderRadius: "2px 2px 0 0", marginBottom: m.emp > 0 ? 0 : 0 }} />}
                {m.emp > 0 && <div style={{ height: empH, background: "var(--mf-aubergine-900)", borderRadius: m.con > 0 ? 0 : "2px 2px 0 0" }} />}
              </div>);

          })}
          {todayIdx >= 0 &&
          <div style={{ position: "absolute", top: -6, bottom: 0, left: `calc(${(todayIdx + 0.5) / months.length * 100}% + ${2 * (todayIdx + 0.5)}px - ${2 * (todayIdx + 0.5)}px)`, width: 2, background: "var(--mf-watermelon-900)", pointerEvents: "none" }}>
              <span style={{ position: "absolute", top: -10, left: -16, fontSize: 9, letterSpacing: "0.1em", textTransform: "uppercase", color: "var(--mf-watermelon-900)", whiteSpace: "nowrap" }}>Today</span>
            </div>
          }
        </div>
        <div style={{ display: "flex", marginTop: 6 }}>
          {months.map((m, i) =>
          <div key={i} style={{ flex: 1, textAlign: "center", fontSize: 9, color: "var(--fg-4)", letterSpacing: "0.04em" }}>
              {m.date.getMonth() === 0 ? m.date.getFullYear() : m.date.getMonth() === 6 ? "Jul" : ""}
            </div>
          )}
        </div>
      </div>
    </div>);

}

function PlannedList({ planned }) {
  const { go } = window.useApp();
  if (planned.length === 0) return <div className="card"><div style={{ padding: 24, color: "var(--fg-4)", fontSize: 13 }}>No planned changes for this team.</div></div>;
  return (
    <div className="card">
      <table className="tbl">
        <thead><tr><th>Date</th><th>Type</th><th>Person</th><th>Detail</th></tr></thead>
        <tbody>
          {planned.map((ev) => {
            const p = window.pById[ev.personId];
            return (
              <tr key={ev.id} onClick={() => go("person", { id: p.id })} style={{ cursor: "pointer" }}>
                <td style={{ color: "#8C5E12" }}>{window.dstr(ev.date)}</td>
                <td><span className="chip chip-planned">{ev.type}</span></td>
                <td><PersonCell person={p} /></td>
                <td className="muted">
                  {ev.type === "hire" && <>Joins {window.tmById[ev.payload?.allocations?.[0]?.groupId]?.name || "the org"} as {ev.payload?.role}</>}
                  {ev.type === "move" && <>{window.tmById[ev.payload?.fromGroup]?.name} → {window.tmById[ev.payload?.toGroup]?.name}</>}
                  {ev.type === "allocate" && <>Re-allocated capacity{ev.payload?.note ? <> · <span style={{ fontStyle: "italic" }}>{ev.payload.note}</span></> : null}</>}
                  {ev.type === "end" && <>{ev.payload?.reason}</>}
                  {ev.type === "role" && <>{ev.payload?.from} → {ev.payload?.to}</>}
                </td>
              </tr>);

          })}
        </tbody>
      </table>
    </div>);

}

function TeamHistory({ wgId }) {
  const groupIds = window.descendantWorkGroupIds(wgId);
  const events = window.EVENTS.filter((ev) => {
    if (ev.date > window.TODAY) return false;
    return groupIds.includes(ev.payload?.groupId) || groupIds.includes(ev.payload?.toGroup) || groupIds.includes(ev.payload?.fromGroup) ||
    (ev.payload?.allocations || []).some((a) => groupIds.includes(a.groupId)) ||
    (ev.payload?.to || []).some((a) => groupIds.includes(a.groupId)) ||
    (ev.payload?.from || []).some((a) => groupIds.includes(a.groupId));
  }).sort((a, b) => b.date - a.date);
  if (events.length === 0) return <div className="card"><div style={{ padding: 24, color: "var(--fg-4)", fontSize: 13 }}>No history yet.</div></div>;
  return (
    <div className="card">
      <table className="tbl">
        <thead><tr><th>Date</th><th>Type</th><th>Person</th><th>Detail</th><th>Actor</th></tr></thead>
        <tbody>
          {events.map((ev) => {
            const p = window.pById[ev.personId];
            return (
              <tr key={ev.id}>
                <td>{window.dstr(ev.date)}</td>
                <td><span className="chip chip-emp">{ev.type}</span></td>
                <td><PersonCell person={p} /></td>
                <td className="muted">
                  {ev.type === "hire" && <>Joins {window.tmById[ev.payload?.allocations?.[0]?.groupId]?.name || "the org"} as {ev.payload?.role}</>}
                  {ev.type === "move" && <>{window.tmById[ev.payload?.fromGroup]?.name} → {window.tmById[ev.payload?.toGroup]?.name}</>}
                  {ev.type === "allocate" && <>Re-allocated capacity{ev.payload?.note ? <> · <span style={{ fontStyle: "italic" }}>{ev.payload.note}</span></> : null}</>}
                  {ev.type === "end" && <>{ev.payload?.reason}</>}
                  {ev.type === "role" && <>{ev.payload?.from} → {ev.payload?.to}</>}
                </td>
                <td className="muted">{window.pById[ev.actor]?.name}</td>
              </tr>);

          })}
        </tbody>
      </table>
    </div>);

}

/* ===================================================================
 * PERSON DETAIL — Git log style
 * ================================================================ */
function PersonScreen() {
  const { route, go, viewDate, setDrawer } = window.useApp();
  const id = route.params.id || "p-ali";
  const person = window.pById[id];
  if (!person) return null;
  const cur = window.assignmentAt(person, viewDate);
  const planned = window.assignmentAt(person, window.HORIZON_FUTURE);
  const history = window.personHistory(person.id);
  const reports = window.directReportsAt(person.id, viewDate);

  return (
    <>
      <TopBar crumbs={["Organisation", "People", person.name]} />
      <TTRibbon />
      <div className="page">
        <div style={{ display: "grid", gridTemplateColumns: "minmax(0, 1fr) 300px", gap: 18 }}>
          <div style={{ minWidth: 0 }}>
            <div style={{ display: "flex", gap: 16, alignItems: "flex-start", marginBottom: 14 }}>
              <Avatar person={person} size="lg" />
              <div style={{ flex: 1, minWidth: 0 }}>
                <span className="eyebrow">{person.kind === "contractor" ? "Contractor" : "Employee"}{person.kind === "contractor" && person.agency ? ` · ${person.agency}` : ""}</span>
                <h1 className="page-title" style={{ marginTop: 2 }}>{person.name}</h1>
                <div className="page-meta" style={{ marginTop: 6, flexWrap: "wrap", rowGap: 4 }}>
                  {cur ? <>
                    <span>{cur.role}</span>
                    <span className="muted">·</span>
                    <span><span className="chip chip-fn">{window.fnById[cur.functionId]?.name}</span></span>
                    <span className="muted">·</span>
                    <span>reports to <strong>{window.pById[cur.managerId]?.name || "—"}</strong></span>
                  </> : <span className="dim">Not currently active in the organisation.</span>}
                </div>
                <div style={{ display: "flex", gap: 6, marginTop: 12, flexWrap: "wrap" }}>
                  <button className="btn" onClick={() => setDrawer({ kind: "allocate", payload: { personId: person.id } })}><Icon name="settings-sliders" />Adjust allocations</button>
                  <button className="btn" onClick={() => setDrawer({ kind: "role", payload: { personId: person.id } })}><Icon name="user-advisor" />Change role</button>
                  <button className="btn" onClick={() => setDrawer({ kind: "manager", payload: { personId: person.id } })}><Icon name="arrow-turn" />Change manager</button>
                  {person.kind === "contractor" &&
                  <button className="btn" onClick={() => setDrawer({ kind: "extend", payload: { personId: person.id } })}><Icon name="arrow-right" />Extend</button>
                  }
                  <button className="btn" onClick={() => setDrawer({ kind: "end", payload: { personId: person.id } })}><Icon name="cancel-circle" />End</button>
                </div>
              </div>
            </div>

            {cur &&
            <div className="person-alloc-card">
                <div className="h"><Icon name="settings-sliders" />Capacity allocation · {window.dstr(viewDate)}</div>
                <window.AllocationStrip allocations={cur.allocations || []} go={go} />
              </div>
            }

            <PersonGantt person={person} />

            <div style={{ height: 18 }} />
            <div style={{ display: "flex", alignItems: "baseline", gap: 10, marginBottom: 10, flexWrap: "wrap" }}>
              <h3 style={{ margin: 0, fontFamily: "var(--font-display)", fontSize: 18, fontWeight: 600, whiteSpace: "nowrap" }}>Event log</h3>
              <span className="muted" style={{ fontSize: 12 }}>{history.length} events · most recent first</span>
              <span className="muted" style={{ marginLeft: "auto", fontSize: 11 }}>Append-only · every change creates a new record</span>
            </div>
            <PersonGitLog person={person} events={history} />
          </div>

          <PersonSidePanel person={person} cur={cur} planned={planned} reports={reports} />
        </div>
      </div>
    </>);

}
window.PersonScreen = PersonScreen;

function PersonGantt({ person }) {
  // Limit window to the last 12 months
  const axisStart = window.addMonths(window.TODAY, -12);
  const axisEnd = window.TODAY;
  const span = axisEnd - axisStart;
  const pct = (d) => Math.max(0, Math.min(100, (d - axisStart) / span * 100));

  const teamColors = ["team-a", "team-b", "team-c", "team-d", "team-e"];
  const teamColor = (teamId) => teamColors[Math.abs(hash(teamId)) % teamColors.length];

  // Find every work group the person had any allocation to within the window
  const overlaps = (from, to) => (!to || to >= axisStart) && from <= axisEnd;
  const groupBands = {};
  for (const a of person.assignments) {
    if (!overlaps(a.from, a.to)) continue;
    for (const al of (a.allocations || [])) {
      const wg = window.wgById[al.groupId];
      if (!wg) continue;
      const segFrom = a.from < axisStart ? axisStart : a.from;
      const segTo = a.to == null || a.to > axisEnd ? axisEnd : a.to;
      (groupBands[al.groupId] = groupBands[al.groupId] || []).push({ from: segFrom, to: segTo, pct: al.pct, key: al.groupId, label: `${wg.name} · ${al.pct}%` });
    }
  }
  const teamLanes = Object.entries(groupBands)
    .sort((a, b) => (window.wgById[b[0]]?.name || "").localeCompare(window.wgById[a[0]]?.name || "")) // stable
    .map(([gid, bands]) => ({ label: window.wgById[gid]?.name, bands, key: gid, group: true }));

  const roleBands = compress(person.assignments.filter(a => overlaps(a.from, a.to)).map((a) => ({
    from: a.from < axisStart ? axisStart : a.from,
    to: a.to == null || a.to > axisEnd ? axisEnd : a.to,
    label: a.role, key: a.role,
  })));
  const mgrBands = compress(person.assignments.filter(a => overlaps(a.from, a.to)).map((a) => ({
    from: a.from < axisStart ? axisStart : a.from,
    to: a.to == null || a.to > axisEnd ? axisEnd : a.to,
    label: window.pById[a.managerId]?.name || "—", key: a.managerId,
  })));
  const lanes = [...teamLanes, { sep: true }, { label: "Role", bands: roleBands }, { label: "Manager", bands: mgrBands }];

  // Monthly ticks
  const ticks = [];
  let cur = new Date(axisStart.getFullYear(), axisStart.getMonth() + 1, 1);
  while (cur <= axisEnd) {
    ticks.push(new Date(cur));
    cur = window.addMonths(cur, 1);
  }

  return (
    <div className="gantt" data-comment-anchor="9d8d27fb58-div-384-5">
      <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 8 }}>
        <span style={{ fontSize: 11, letterSpacing: "0.1em", textTransform: "uppercase", color: "var(--fg-3)", fontWeight: 600 }}>Assignment timeline · last 12 months</span>
        <span className="muted" style={{ fontSize: 11 }}>{window.dstrShort(axisStart)} → {window.dstrShort(axisEnd)}</span>
      </div>
      <div style={{ position: "relative" }}>
        <div className="gantt-axis">
          {ticks.map((t, i) =>
          <div key={i} className="gantt-axis-tick" style={{ left: `${pct(t)}%` }}>{t.toLocaleDateString("en-GB", { month: "short" })}</div>
          )}
        </div>
        <div style={{ position: "relative" }}>
          {lanes.map((lane, idx) => {
            if (lane.sep) return <div key={`sep-${idx}`} className="gantt-sep" />;
            return (
              <div key={lane.label + idx} className={`gantt-row ${lane.group ? "is-group-row" : ""}`}>
                <div className="gr-label">{lane.label}</div>
                <div className="gantt-track" style={{ position: "relative" }}>
                  {lane.bands.map((b, j) => {
                    const cls = `gantt-bar ${teamColor(b.key)}`;
                    const left = pct(b.from);
                    const right = pct(b.to);
                    return (
                      <div key={j} className={cls} style={{ left: `${left}%`, width: `${right - left}%` }}
                        title={b.label || `${window.dstrShort(b.from)} – ${window.dstrShort(b.to)}`}>
                        {b.label}
                      </div>
                    );
                  })}
                  <div className="gantt-now" style={{ left: `${pct(window.TODAY)}%` }} />
                </div>
              </div>
            );
          })}
        </div>
      </div>
    </div>
  );
}

function hash(str) {
  let h = 0;
  if (!str) return 0;
  for (let i = 0; i < str.length; i++) {h = (h << 5) - h + str.charCodeAt(i);h |= 0;}
  return h;
}

/* collapse consecutive bands with same key */
function compress(bands) {
  bands = bands.slice().sort((a, b) => a.from - b.from);
  const out = [];
  for (const b of bands) {
    const last = out[out.length - 1];
    if (last && last.key === b.key) {
      last.to = b.to;
    } else {
      out.push({ ...b });
    }
  }
  return out;
}

function PersonGitLog({ person, events }) {
  const ordered = events.slice().reverse();
  const icons = { hire: "user", move: "exchange", role: "user-advisor", manager: "arrow-turn", extend: "arrow-right", end: "cancel-circle", allocate: "settings-sliders" };
  return (
    <div className="gitlog">
      {ordered.map((ev, i) => {
        const isFuture = ev.date > window.TODAY;
        const isPast = ev.date < window.TODAY;
        const cls = `gl-node ${isFuture ? "is-planned" : isPast ? "is-past" : ""} fadein-soft`;
        const actor = window.pById[ev.actor];
        return (
          <div key={ev.id} className={cls}>
            <div className="gl-card">
              <div className="gl-row1">
                <Icon name={icons[ev.type] || "info-circle"} style={{ color: isFuture ? "#C58A2C" : "var(--mf-watermelon-900)" }} />
                <span className="gl-type">{ev.type}{isFuture && " · planned"}</span>
                <span className="gl-meta">
                  <span className="gl-hash">{ev.id.replace("e-", "")}</span>
                  <span>{window.dstr(ev.date)}</span>
                </span>
              </div>
              <div className="gl-title">{titleFor(ev, person)}</div>
              <div className="gl-diff">
                {ev.type === "hire" &&
                <>
                    <div className="gl-diff-item"><span className="dk">role</span><span className="dv-to">{ev.payload?.role}</span></div>
                    {ev.payload?.kind && <div className="gl-diff-item"><span className="dk">type</span><span className="dv-to">{ev.payload.kind}</span></div>}
                    {ev.payload?.allocations &&
                  <div className="gl-diff-item" style={{ width: "100%", padding: 0, background: "transparent" }}>
                        <window.AllocationStrip allocations={ev.payload.allocations} compact />
                      </div>
                  }
                  </>
                }
                {ev.type === "move" &&
                <>
                    <div className="gl-diff-item"><span className="dk">group</span><span className="dv-from">{window.tmById[ev.payload?.fromGroup]?.name}</span><span className="dv-arrow">→</span><span className="dv-to">{window.tmById[ev.payload?.toGroup]?.name}</span></div>
                    {ev.payload?.fromManager && <div className="gl-diff-item"><span className="dk">manager</span><span className="dv-from">{window.pById[ev.payload.fromManager]?.name}</span><span className="dv-arrow">→</span><span className="dv-to">{window.pById[ev.payload.toManager]?.name}</span></div>}
                  </>
                }
                {ev.type === "role" &&
                <div className="gl-diff-item"><span className="dk">role</span><span className="dv-from">{ev.payload?.from}</span><span className="dv-arrow">→</span><span className="dv-to">{ev.payload?.to}</span></div>
                }
                {ev.type === "end" &&
                <div className="gl-diff-item"><span className="dk">closes</span><span className="dv-to">{ev.payload?.reason}</span></div>
                }
                {ev.type === "allocate" &&
                <div style={{ width: "100%" }}>
                    <window.AllocationDiff from={ev.payload?.from || []} to={ev.payload?.to || []} note={ev.payload?.note} />
                  </div>
                }
              </div>
              <div style={{ display: "flex", alignItems: "center", gap: 8, marginTop: 8, fontSize: 11, color: "var(--fg-3)" }}>
                <div className="gl-author"><Avatar person={actor} /><span>by <strong style={{ color: "var(--fg-2)" }}>{actor?.name}</strong></span></div>
                <span>·</span>
                <span>{relTime(ev.date)}</span>
              </div>
            </div>
          </div>);

      })}
    </div>);

}

function titleFor(ev, person) {
  switch (ev.type) {
    case "hire":{
        const firstGroup = ev.payload?.allocations?.[0]?.groupId;
        const gname = firstGroup ? window.wgById[firstGroup]?.name : "the organisation";
        return `${person.name} ${ev.date > window.TODAY ? "will join" : "joined"} ${gname}`;
      }
    case "move":return `Moved from ${window.tmById[ev.payload?.fromGroup]?.name} to ${window.tmById[ev.payload?.toGroup]?.name}`;
    case "role":return `Role changed to ${ev.payload?.to}`;
    case "end":return `Contract ${ev.date > window.TODAY ? "will end" : "ended"}`;
    case "extend":return "Contract extended";
    case "manager":return "Line manager changed";
    case "allocate":return `Capacity re-allocated`;
    default:return ev.type;
  }
}

function relTime(date) {
  const days = window.daysBetween(window.TODAY, date);
  if (days === 0) return "today";
  if (days > 0) return `in ${days} day${days === 1 ? "" : "s"}`;
  return `${-days} day${days === -1 ? "" : "s"} ago`;
}

function PersonSidePanel({ person, cur, planned, reports }) {
  const { go } = window.useApp();
  const expected = window.expectedTotalCost(person);
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 14 }}>
      <div className="card">
        <div className="card-head"><div className="card-title">Identity</div></div>
        <div style={{ padding: 14, display: "flex", flexDirection: "column", gap: 8, fontSize: 12 }}>
          <Row k="Type" v={<KindChip kind={person.kind} />} />
          {person.location && <Row k="Location" v={person.location} />}
          {person.agency && <Row k="Agency" v={person.agency} />}
          {person.cost_center && <Row k="Cost centre" v={<code style={{ fontSize: 11, background: "var(--mf-aubergine-100)", padding: "1px 5px", borderRadius: 3 }}>{person.cost_center}</code>} />}
          {person.netsuite && <Row k="NetSuite" v={<code style={{ fontSize: 11, background: "var(--mf-aubergine-100)", padding: "1px 5px", borderRadius: 3 }}>{person.netsuite}</code>} />}
          <Row k="Start" v={window.dstr(person.startDate)} />
          <Row k="End" v={person.endDate ? window.dstr(person.endDate) : <span className="dim">— (open-ended)</span>} />
          {person.notes && <div style={{ marginTop: 6, padding: 10, background: "var(--bg-tint)", borderRadius: 6, color: "var(--fg-3)", fontStyle: "italic" }}>{person.notes}</div>}
        </div>
      </div>

      {person.kind === "contractor" &&
      <div className="card">
          <div className="card-head"><div className="card-title"><Icon name="euro" />Contractor economics</div></div>
          <div style={{ padding: 14, display: "flex", flexDirection: "column", gap: 8, fontSize: 12 }}>
            <Row k="Daily rate" v={<strong>{window.money(person.dailyRate)}</strong>} />
            <Row k="Days / week" v={person.daysPerWeek} />
            <Row k="Monthly run-rate" v={<strong>{window.moneyK(person.dailyRate * person.daysPerWeek * 4.33)}</strong>} />
            <Row k="Expected total" v={<strong style={{ color: "var(--mf-watermelon-900)" }}>{window.moneyK(expected)}</strong>} />
          </div>
        </div>
      }

      {reports.length > 0 &&
      <div className="card">
          <div className="card-head"><div className="card-title">Direct reports</div><span className="muted" style={{ fontSize: 11 }}>{reports.length}</span></div>
          <div style={{ padding: "8px 0" }}>
            {reports.map((r) =>
          <div key={r.person.id} onClick={() => go("person", { id: r.person.id })} style={{ display: "flex", alignItems: "center", gap: 8, padding: "6px 14px", cursor: "pointer", fontSize: 12 }}>
                <Avatar person={r.person} />
                <div>
                  <div style={{ fontWeight: 500 }}>{r.person.name}</div>
                  <div className="muted" style={{ fontSize: 11 }}>{r.assignment.role}</div>
                </div>
              </div>
          )}
          </div>
        </div>
      }
    </div>);

}

function Row({ k, v }) {
  return (
    <div style={{ display: "flex", gap: 10, alignItems: "center", justifyContent: "space-between" }}>
      <span className="muted">{k}</span>
      <span style={{ textAlign: "right" }}>{v}</span>
    </div>);

}

/* ===================================================================
 * FUNCTIONS SCREEN
 * ================================================================ */
function FunctionsScreen() {
  const { route, viewDate, go } = window.useApp();
  const fnId = route.params.id;
  if (fnId) return <FunctionDetail fnId={fnId} />;
  return (
    <>
      <TopBar crumbs={["Organisation", "Functions"]} />
      <TTRibbon />
      <div className="page">
        <PageHead eyebrow="Organisation" title="Functions"
        meta={<>{window.FUNCTIONS.length} functions · independent from work groups and from line reporting</>}
        actions={<><button className="btn"><Icon name="plus" />New function</button></>} />
        
        <div className="cards-grid">
          {window.FUNCTIONS.map((fn) => {
            const t = window.functionTotals(fn.id, viewDate);
            const owner = window.pById[fn.ownerId];
            return (
              <div key={fn.id} className="team-card" onClick={() => go("function", { id: fn.id })}>
                <div className="team-card-name">{fn.name}</div>
                <div className="team-card-sub">Owned by {owner?.name}</div>
                <div className="team-card-row">
                  <div style={{ fontFamily: "var(--font-display)", fontWeight: 600, fontSize: 22 }}>{t.total}</div>
                  <div className="stack-meta">{t.emp}e · {t.con}c · {fn.roles.length} allowed roles</div>
                </div>
                <div className="team-card-bar">
                  <div className="seg-emp" style={{ width: `${t.emp / Math.max(t.total, 1) * 100}%` }} />
                  <div className="seg-con" style={{ width: `${t.con / Math.max(t.total, 1) * 100}%` }} />
                </div>
              </div>);

          })}
        </div>
      </div>
    </>);

}
window.FunctionsScreen = FunctionsScreen;

function FunctionDetail({ fnId }) {
  const { viewDate, go, setDrawer } = window.useApp();
  const fn = window.fnById[fnId];
  const members = window.peopleAt(viewDate).filter((x) => x.assignment.functionId === fnId);
  const totals = window.functionTotals(fnId, viewDate);
  const owner = window.pById[fn.ownerId];

  // role distribution
  const byRole = {};
  for (const m of members) byRole[m.assignment.role] = (byRole[m.assignment.role] || 0) + 1;

  return (
    <>
      <TopBar crumbs={["Organisation", "Functions", fn.name]} />
      <TTRibbon />
      <div className="page">
        <PageHead eyebrow="Function" title={fn.name}
        meta={<><span style={{ display: "inline-flex", alignItems: "center", gap: 6 }}><Avatar person={owner} />Owner · <strong>{owner?.name}</strong></span> <span className="muted">·</span> <span>{totals.total} people</span></>} />
        

        <div style={{ display: "grid", gridTemplateColumns: "2fr 1fr", gap: 16 }}>
          <div className="card">
            <div className="card-head"><div className="card-title">Members</div></div>
            <table className="tbl">
              <thead><tr><th>Person</th><th>Role</th><th>Team</th><th>Manager</th><th>Type</th></tr></thead>
              <tbody>
                {members.map((m) =>
                <tr key={m.person.id} onClick={() => go("person", { id: m.person.id })} style={{ cursor: "pointer" }}>
                    <td><PersonCell person={m.person} /></td>
                    <td>{m.assignment.role}</td>
                    <td>{window.primaryGroupName(m.assignment, "dim-bubble") || "—"}</td>
                    <td>{window.pById[m.assignment.managerId]?.name || <span className="dim">—</span>}</td>
                    <td><KindChip kind={m.person.kind} /></td>
                  </tr>
                )}
              </tbody>
            </table>
          </div>
          <div style={{ display: "flex", flexDirection: "column", gap: 14 }}>
            <div className="card" data-comment-anchor="a1ae57daf5-div-675-13">
              <div className="card-head"><div className="card-title">Roles</div>
                <button className="btn btn-ghost" onClick={() => setDrawer({ kind: "create-role", payload: { functionId: fn.id } })} style={{ height: 24, padding: "0 8px" }}>
                  <Icon name="plus" />New role
                </button>
              </div>
              <div className="role-list">
                {fn.roles.map((r) => {
                  const count = byRole[r] || 0;
                  const ev = window.EVENTS.find((e) => e.type === "role-create" && e.functionId === fn.id && e.payload?.role === r);
                  const actor = ev ? window.pById[ev.actor] : null;
                  return (
                    <div key={r} className="role-row">
                      <div className="role-row-main">
                        <div className="role-name">{r}</div>
                        <div className="role-meta">
                          {ev && (
                            <>
                              <code className="gl-hash">{ev.id.replace("e-", "")}</code>
                              <span>created {window.dstrShort(ev.date)}{actor ? ` · by ${actor.name.split(" ")[0]}` : ""}</span>
                            </>
                          )}
                          {!ev && <span className="muted">No creation event recorded.</span>}
                        </div>
                      </div>
                      <span className="role-count" style={{ color: count > 0 ? "var(--fg-1)" : "var(--fg-4)" }}>{count} person{count === 1 ? "" : "s"}</span>
                    </div>);

                })}
              </div>
              <div className="card-foot">
                <Icon name="info-circle" /> Roles are scoped to <strong>{fn.name}</strong>. People can only be assigned to one of these roles — never free text.
              </div>
            </div>
          </div>
        </div>
      </div>
    </>);

}

/* ===================================================================
 * REPORTING TREE
 * ================================================================ */
function ReportingScreen() {
  const { viewDate, go } = window.useApp();
  const all = window.peopleAt(viewDate);
  // Build manager → reports map
  const map = {};
  for (const x of all) {
    const mgr = x.assignment.managerId || "_root";
    (map[mgr] = map[mgr] || []).push(x);
  }
  const roots = (map["_root"] || []).concat(all.filter((x) => x.assignment.managerId && !window.pById[x.assignment.managerId]));

  const renderRow = (m, depth) => {
    const reports = map[m.person.id] || [];
    const isManager = reports.length > 0;
    return (
      <React.Fragment key={m.person.id}>
        <div className={`tree-row ${isManager ? "is-manager" : ""}`} onClick={() => go("person", { id: m.person.id })}>
          <div className="person-cell">
            <span className="branch">{"  ".repeat(Math.max(0, depth - 1))}{depth > 0 ? "└─ " : ""}</span>
            <Avatar person={m.person} />
            <div>
              <div className="pname">{m.person.name}</div>
              <div className="prole">{m.assignment.role}</div>
            </div>
          </div>
          <div className="muted">{window.primaryGroupName(m.assignment, "dim-bubble") || "—"}</div>
          <div className="muted">{window.fnById[m.assignment.functionId]?.name}</div>
          <div style={{ textAlign: "right" }}>
            {reports.length > 0 ? <span className="chip chip-fn">{reports.length} report{reports.length === 1 ? "" : "s"}</span> : <span className="dim">·</span>}
          </div>
        </div>
        {reports.map((r) => renderRow(r, depth + 1))}
      </React.Fragment>);

  };

  return (
    <>
      <TopBar crumbs={["Organisation", "Line reporting"]} />
      <TTRibbon />
      <div className="page">
        <PageHead eyebrow="Reporting structure" title="Line reporting"
        meta={<>Managerial hierarchy — independent of team allocation and function. {all.length} people.</>} />
        
        <div className="card" style={{ overflow: "hidden" }}>
          <div className="tree-row" style={{ background: "var(--mf-aubergine-100)", fontSize: 10, letterSpacing: "0.1em", textTransform: "uppercase", color: "var(--fg-4)" }}>
            <span>Person</span>
            <span>Team</span>
            <span>Function</span>
            <span style={{ textAlign: "right" }}>Reports</span>
          </div>
          <div className="tree">{roots.map((r) => renderRow(r, 0))}</div>
        </div>
      </div>
    </>);

}
window.ReportingScreen = ReportingScreen;

/* ===================================================================
 * PEOPLE LISTING
 * ================================================================ */
function PeopleScreen() {
  const { viewDate, go } = window.useApp();
  const [filter, setFilter] = useStateB("all");
  const [q, setQ] = useStateB("");
  const all = window.peopleAt(viewDate);
  const filtered = all.filter((m) => {
    if (filter === "emp" && m.person.kind !== "employee") return false;
    if (filter === "con" && m.person.kind !== "contractor") return false;
    if (q && !m.person.name.toLowerCase().includes(q.toLowerCase())) return false;
    return true;
  });
  return (
    <>
      <TopBar crumbs={["Organisation", "People"]} />
      <TTRibbon />
      <div className="page">
        <PageHead eyebrow="Directory" title="People"
        meta={<>{all.length} active at {window.dstr(viewDate)}</>}
        actions={<>
            <div className="seg">
              {[["all", "All"], ["emp", "Employees"], ["con", "Contractors"]].map(([v, l]) =>
            <button key={v} className={filter === v ? "active" : ""} onClick={() => setFilter(v)}>{l}</button>
            )}
            </div>
            <div className="search-pill" style={{ minWidth: 220 }}>
              <Icon name="search" />
              <input style={{ border: 0, outline: 0, background: "transparent", flex: 1, fontSize: 12 }} value={q} onChange={(e) => setQ(e.target.value)} placeholder="Filter people…" />
            </div>
          </>} />
        
        <div className="card">
          <table className="tbl">
            <thead><tr><th>Person</th><th>Type</th><th>Role</th><th>Team</th><th>Function</th><th>Manager</th><th>Location</th><th>Start</th><th>End</th></tr></thead>
            <tbody>
              {filtered.map((m) =>
              <tr key={m.person.id} onClick={() => go("person", { id: m.person.id })} style={{ cursor: "pointer" }}>
                  <td><PersonCell person={m.person} /></td>
                  <td><KindChip kind={m.person.kind} /></td>
                  <td>{m.assignment.role}</td>
                  <td>{window.primaryGroupName(m.assignment, "dim-bubble") || "—"}</td>
                  <td><span className="chip chip-fn">{window.fnById[m.assignment.functionId]?.name}</span></td>
                  <td>{window.pById[m.assignment.managerId]?.name || <span className="dim">—</span>}</td>
                  <td className="muted">{m.person.location || (m.person.agency ? <span style={{ fontStyle: "italic" }}>{m.person.agency}</span> : "—")}</td>
                  <td>{window.dstrShort(m.assignment.from)}</td>
                  <td>{m.assignment.to ? window.dstrShort(m.assignment.to) : <span className="dim">—</span>}</td>
                </tr>
              )}
            </tbody>
          </table>
        </div>
      </div>
    </>);

}
window.PeopleScreen = PeopleScreen;

/* ===================================================================
 * WORK GROUPS LISTING (grouped by dimension)
 * ================================================================ */
function TeamsScreen() {
  const { viewDate, go } = window.useApp();
  return (
    <>
      <TopBar crumbs={["Organisation", "Work groups"]} />
      <TTRibbon />
      <div className="page">
        <PageHead eyebrow="Organisation" title="Work groups"
        meta={<>{window.WORK_GROUPS.length} work groups across {window.DIMENSIONS.length} categories</>}
        actions={<><button className="btn"><Icon name="plus" />New work group</button></>} />
        
        {window.DIMENSIONS.map((dim) => {
          const roots = window.rootWorkGroups(dim.id);
          const tot = window.dimensionTotals(dim.id, viewDate);
          return (
            <div key={dim.id} className="fn-group">
              <div className="fn-group-head">
                <span className="fn-group-name">{dim.name}</span>
                <span className="fn-group-meta">{dim.description} · {tot.total} people · {tot.emp}e / {tot.con}c</span>
                <div className="fn-group-rule" />
                <button className="btn btn-ghost" onClick={() => go("explorer", { dim: dim.id })}>Explore <Icon name="arrow-right" /></button>
              </div>
              <div className="cards-grid">
                {roots.map((root) => {
                  const tt = window.workGroupTotals(root.id, viewDate);
                  const kids = window.childWorkGroups(root.id);
                  return (
                    <div key={root.id} className="team-card" onClick={() => go("team", { id: root.id })}>
                      <div>
                        <div className="team-card-name">{root.name}</div>
                        <div className="team-card-sub">
                          {dim.name}
                          {kids.length > 0 && <> · {kids.length} sub-groups</>}
                          {" · "}owner {window.pById[root.ownerId]?.name?.split(" ")[0]}
                        </div>
                      </div>
                      <div className="team-card-row">
                        <div style={{ fontFamily: "var(--font-display)", fontWeight: 600, fontSize: 22 }}>{tt.total}</div>
                        <div className="stack-meta">{tt.emp} employees · {tt.con} contractors</div>
                      </div>
                      <div className="team-card-bar">
                        <div className="seg-emp" style={{ width: `${tt.emp / Math.max(tt.total, 1) * 100}%` }} />
                        <div className="seg-con" style={{ width: `${tt.con / Math.max(tt.total, 1) * 100}%` }} />
                      </div>
                      {kids.length > 0 &&
                      <div style={{ display: "flex", gap: 4, flexWrap: "wrap" }}>
                          {kids.map((c) => {
                          const ct = window.workGroupTotals(c.id, viewDate);
                          return <span key={c.id} className="chip" style={{ background: "var(--mf-aubergine-100)" }}>{c.name} · {ct.total}</span>;
                        })}
                        </div>
                      }
                    </div>);

                })}
              </div>
            </div>);

        })}
      </div>
    </>);

}
window.TeamsScreen = TeamsScreen;

/* ===================================================================
 * EVENTS LOG
 * ================================================================ */
function EventsScreen() {
  const { go } = window.useApp();
  const events = window.EVENTS.slice().sort((a, b) => b.date - a.date);
  return (
    <>
      <TopBar crumbs={["Planning", "Events"]} />
      <TTRibbon />
      <div className="page">
        <PageHead eyebrow="Ledger" title="Event log" meta={<>{events.length} events · oldest first append-only. Every change is recorded as a new entry.</>} actions={<><button className="btn btn-primary"><Icon name="plus" />New event</button></>} />
        <div className="card">
          <table className="tbl">
            <thead><tr><th>Date</th><th>Type</th><th>Person</th><th>Detail</th><th>Actor</th><th>Ref</th></tr></thead>
            <tbody>
              {events.map((ev) => {
                const p = window.pById[ev.personId];
                const isFuture = ev.date > window.TODAY;
                return (
                  <tr key={ev.id} onClick={() => go("person", { id: p.id })} style={{ cursor: "pointer" }}>
                    <td style={{ color: isFuture ? "#8C5E12" : "var(--fg-1)" }}>{window.dstr(ev.date)}</td>
                    <td><span className={isFuture ? "chip chip-planned" : "chip chip-emp"}>{ev.type}</span></td>
                    <td><PersonCell person={p} /></td>
                    <td className="muted">
                      {ev.type === "hire" && <>Joins {window.tmById[ev.payload?.allocations?.[0]?.groupId]?.name || "the org"} as {ev.payload?.role}</>}
                      {ev.type === "move" && <>{window.tmById[ev.payload?.fromGroup]?.name} → {window.tmById[ev.payload?.toGroup]?.name}</>}
                      {ev.type === "end" && <>{ev.payload?.reason}</>}
                      {ev.type === "role" && <>{ev.payload?.from} → {ev.payload?.to}</>}
                    </td>
                    <td className="muted">{window.pById[ev.actor]?.name}</td>
                    <td><code className="gl-hash">{ev.id}</code></td>
                  </tr>);

              })}
            </tbody>
          </table>
        </div>
      </div>
    </>);

}
window.EventsScreen = EventsScreen;

/* ===================================================================
 * TIMELINE (Time Machine global view)
 * ================================================================ */
function TimelineScreen() {
  const { viewDate, setScrubOpen } = window.useApp();
  const stats = window.orgStats(viewDate);
  return (
    <>
      <TopBar crumbs={["Planning", "Time machine"]} />
      <TTRibbon />
      <div className="page">
        <PageHead eyebrow="Projection" title="Time machine"
        meta={<>Rebuild the organisation at any past or future date. Currently viewing <strong>{window.dstr(viewDate)}</strong>.</>}
        actions={<>
            <button className="btn btn-primary" onClick={() => setScrubOpen(true)}><Icon name="settings-sliders" />Open scrubber</button>
          </>} />
        
        <div className="stat-strip">
          <Stat label="People" value={stats.total} bar={{ emp: stats.emp, con: stats.con }} />
          <Stat label="Employees" value={stats.emp} />
          <Stat label="Contractors" value={stats.con} />
          <Stat label="Monthly run-rate" value={window.moneyK(stats.monthlySpend)} />
        </div>
        <OverviewMatrix />
      </div>
    </>);

}
window.TimelineScreen = TimelineScreen;

/* ===================================================================
 * COSTS
 * ================================================================ */
function CostsScreen() {
  const { viewDate, go } = window.useApp();
  const contractors = window.peopleAt(viewDate).filter((x) => x.person.kind === "contractor");
  const total = contractors.reduce((s, x) => s + x.person.dailyRate * x.person.daysPerWeek * 4.33, 0);

  // by team
  const byTeam = {};
  for (const c of contractors) {
    const tid = window.primaryGroupId(c.assignment, "dim-bubble");
    byTeam[tid] = (byTeam[tid] || 0) + c.person.dailyRate * c.person.daysPerWeek * 4.33;
  }
  const ranked = Object.entries(byTeam).sort((a, b) => b[1] - a[1]);

  return (
    <>
      <TopBar crumbs={["Planning", "Contractor costs"]} />
      <TTRibbon />
      <div className="page">
        <PageHead eyebrow="Visibility" title="Contractor costs"
        meta={<>Monthly run-rate · across {contractors.length} active contractors at {window.dstr(viewDate)}</>} />
        
        <div className="stat-strip" style={{ gridTemplateColumns: "repeat(3, 1fr)" }}>
          <Stat label="Monthly run-rate" value={window.moneyK(total)} />
          <Stat label="Avg daily rate" value={window.money(Math.round(contractors.reduce((s, x) => s + x.person.dailyRate, 0) / Math.max(contractors.length, 1)))} />
          <Stat label="Contractors" value={contractors.length} />
        </div>

        <div className="col2">
          <div className="card">
            <div className="card-head"><div className="card-title">Active contractors</div></div>
            <table className="tbl">
              <thead><tr><th>Person</th><th>Agency</th><th>Team</th><th className="num">Daily</th><th className="num">d/wk</th><th className="num">Monthly</th><th>Ends</th></tr></thead>
              <tbody>
                {contractors.sort((a, b) => b.person.dailyRate * b.person.daysPerWeek - a.person.dailyRate * a.person.daysPerWeek).map((c) => {
                  const monthly = c.person.dailyRate * c.person.daysPerWeek * 4.33;
                  return (
                    <tr key={c.person.id} onClick={() => go("person", { id: c.person.id })} style={{ cursor: "pointer" }}>
                      <td><PersonCell person={c.person} /></td>
                      <td className="muted">{c.person.agency}</td>
                      <td>{window.primaryGroupName(c.assignment, "dim-bubble") || "—"}</td>
                      <td className="num">{window.money(c.person.dailyRate)}</td>
                      <td className="num">{c.person.daysPerWeek}</td>
                      <td className="num"><strong>{window.moneyK(monthly)}</strong></td>
                      <td>{window.dstrShort(c.person.endDate)}</td>
                    </tr>);

                })}
              </tbody>
            </table>
          </div>
          <div className="card">
            <div className="card-head"><div className="card-title">By team</div></div>
            <div style={{ padding: 12 }}>
              {ranked.map(([tid, amt]) =>
              <div key={tid} style={{ padding: "8px 4px", borderBottom: "1px solid var(--border-subtle)" }}>
                  <div style={{ display: "flex", justifyContent: "space-between", fontSize: 12, marginBottom: 4 }}>
                    <span>{window.tmById[tid]?.name}</span>
                    <strong style={{ fontVariantNumeric: "tabular-nums" }}>{window.moneyK(amt)}</strong>
                  </div>
                  <div style={{ height: 4, background: "var(--mf-aubergine-100)", borderRadius: 2, overflow: "hidden" }}>
                    <div style={{ height: "100%", width: `${amt / Math.max(...ranked.map((r) => r[1])) * 100}%`, background: "var(--mf-watermelon-900)" }} />
                  </div>
                </div>
              )}
            </div>
          </div>
        </div>
      </div>
    </>);

}
window.CostsScreen = CostsScreen;