/* ============ Activity / Audit Trail — per-project + workspace-wide ============ */

/* Action metadata */
const ACTION_META = {
  publish: { icon:"check-circle", label:"Publish",    cls:"sign"   },
  upload:  { icon:"upload",       label:"Upload",     cls:"upload" },
  edit:    { icon:"pencil",       label:"Edit",       cls:"edit"   },
  sign:    { icon:"check",        label:"Sign-off",   cls:"sign"   },
  return:  { icon:"arrow-r",      label:"Return",     cls:"return" },
  delete:  { icon:"trash",        label:"Delete",     cls:"delete" },
  perm:    { icon:"shield",       label:"Permission", cls:"perm"   },
  login:   { icon:"user",         label:"Session",    cls:"login"  },
  view:    { icon:"eye",          label:"View",       cls:"view"   },
  approve: { icon:"check-circle", label:"Approve",    cls:"sign"   },
  grant:   { icon:"check-circle", label:"Grant",      cls:"sign"   },
  decline: { icon:"x-circle",     label:"Decline",    cls:"return" },
};

/* Day bucket for grouping in timeline mode */
const NOW = new Date('2026-05-22T10:00:00');
const dayBucket = (ts) => {
  const dt = new Date(ts);
  const days = Math.floor((NOW - dt) / 86400000);
  if (days <= 0) return "Today";
  if (days === 1) return "Yesterday";
  const pad = n => n < 10 ? "0"+n : ""+n;
  return `${pad(dt.getDate())}/${pad(dt.getMonth()+1)}/${dt.getFullYear()}`;
};

/* ============ Sample audit log ============
   RULES:
   - Draft / Pending projects have NO log entries (logging starts on Publish).
   - Every active or archived project has at least one event: "publish" (oldest).
   - Workspace-level events (entity perms, sessions) belong to no project scope.
============================================ */
const ACT_LOG = [
  /* === P-2025-008 · Annual Audit FY2025 · Northwind (active) === */
  { id:"L-2050", ts:"2026-05-22 07:14:02", actor:"U-ST1", scope:"P-2025-008", action:"upload", obj:"WP-3202 inv_count_memo.docx",        detail:"Initial upload · 124 KB",                                  ip:"10.0.4.15", device:"Chrome · Windows", hash:"sha256:bb48…71c3", severity:"normal" },
  { id:"L-2049", ts:"2026-05-21 16:30:44", actor:"U-ST2", scope:"P-2025-008", action:"upload", obj:"WP-2202 materiality_calc_v2.xlsx",    detail:"Uploaded v2 · 82 KB · revised PBT benchmark",              ip:"10.0.4.12", device:"Chrome · macOS",   hash:"sha256:44fb…6d18", severity:"normal" },
  { id:"L-2048", ts:"2026-05-20 18:45:00", actor:"U-AD1", scope:"P-2025-008", action:"delete", obj:"WP-2210 draft_notes.txt",             detail:"Soft-deleted · recoverable for 90 days",                  ip:"10.0.4.02", device:"Chrome · Windows", hash:"sha256:01a0…73cc", severity:"critical" },
  { id:"L-2047", ts:"2026-05-18 11:20:08", actor:"U-SV1", scope:"P-2025-008", action:"sign",   obj:"WP-2204 briefing_minutes.pdf",        detail:"Signed-off · batch with 2 other WPIDs",                    ip:"10.0.4.08", device:"Chrome · Windows", hash:"sha256:a3d7…b9e1", severity:"critical" },
  { id:"L-2046", ts:"2026-05-05 09:14:00", actor:"U-ST3", scope:"P-2025-008", action:"upload", obj:"WP-2206 client_org_chart.pdf",        detail:"Initial upload · 210 KB",                                  ip:"10.0.4.15", device:"Chrome · Windows", hash:"sha256:e2a5…f430", severity:"normal" },
  { id:"L-2045", ts:"2025-10-08 14:30:00", actor:"U-AD1", scope:"P-2025-008", action:"publish",obj:"Project P-2025-008",                  detail:"Approved by Admin — project published. Activity logging begins here.", ip:"10.0.4.02", device:"Chrome · Windows", hash:"sha256:1a8d…44ec", severity:"critical" },

  /* === P-2025-009 · Annual Audit FY2025 · Kalama Foods (active) === */
  { id:"L-2044", ts:"2026-05-19 14:08:00", actor:"U-SV3", scope:"P-2025-009", action:"upload", obj:"WP-3101 revenue_testing.xlsx",        detail:"Initial upload · 142 KB",                                  ip:"10.0.4.05", device:"Chrome · Windows", hash:"sha256:7c0a…2f81", severity:"normal" },
  { id:"L-2043", ts:"2026-04-12 10:40:22", actor:"U-ST1", scope:"P-2025-009", action:"sign",   obj:"WP-1101 ind_declaration.pdf",         detail:"Independence declarations signed-off",                     ip:"10.0.4.15", device:"Chrome · Windows", hash:"sha256:9091…2b77", severity:"critical" },
  { id:"L-2042", ts:"2025-11-13 11:00:00", actor:"U-AD2", scope:"P-2025-009", action:"publish",obj:"Project P-2025-009",                  detail:"Approved by Admin — project published. Activity logging begins here.", ip:"10.0.4.04", device:"Safari · macOS",   hash:"sha256:dd90…05b1", severity:"critical" },

  /* === P-2025-010 · Annual Audit FY2025 · Orion (active) === */
  { id:"L-2041", ts:"2026-05-22 08:00:00", actor:"U-SV1", scope:"P-2025-010", action:"upload", obj:"WP-4101 final_review_notes.docx",     detail:"Uploaded v2 · 58 KB",                                      ip:"10.0.4.08", device:"Chrome · Windows", hash:"sha256:c1f4…9b2e", severity:"normal" },
  { id:"L-2040", ts:"2026-03-18 16:42:00", actor:"U-ST5", scope:"P-2025-010", action:"upload", obj:"WP-3301 receivables_conf.xlsx",       detail:"Initial upload · 96 KB",                                   ip:"10.0.4.20", device:"Chrome · macOS",   hash:"sha256:5b2c…8d31", severity:"normal" },
  { id:"L-2039", ts:"2025-09-04 16:00:00", actor:"U-AD1", scope:"P-2025-010", action:"publish",obj:"Project P-2025-010",                  detail:"Approved by Admin — project published. Activity logging begins here.", ip:"10.0.4.02", device:"Chrome · Windows", hash:"sha256:b7e0…1f45", severity:"critical" },

  /* === P-2024-002 · FY2024 (final) · Meridian (archived) === */
  { id:"L-2038", ts:"2025-04-01 00:00:00", actor:"U-AD1", scope:"P-2024-002", action:"edit",   obj:"Project status",                       detail:"Archived — entity wind-down",                              ip:"10.0.4.02", device:"Chrome · Windows", hash:"sha256:af11…22cd", severity:"critical" },
  { id:"L-2037", ts:"2024-09-05 11:00:00", actor:"U-AD1", scope:"P-2024-002", action:"publish",obj:"Project P-2024-002",                  detail:"Approved by Admin — project published. Activity logging begins here.", ip:"10.0.4.02", device:"Chrome · Windows", hash:"sha256:0044…2b77", severity:"critical" },

  /* === Workspace-level events (no project scope) === */
  { id:"L-2036", ts:"2026-05-21 17:52:18", actor:"U-AD1", scope:null, action:"perm",  obj:"User Sarah Mitchell · added as Creator", detail:"Sarah Mitchell assigned as Project Creator for Harbor Logistics Co. (E-002)", ip:"10.0.4.02", device:"Chrome · Windows", hash:"sha256:ff10…84a2", severity:"critical" },
  { id:"L-2035", ts:"2026-05-21 09:02:15", actor:"U-ST1", scope:null, action:"login", obj:"Session started",                       detail:"SSO login · MFA verified",                                                ip:"10.0.4.15", device:"Chrome · Windows", hash:"—",                 severity:"low" },
  { id:"L-2034", ts:"2026-05-20 08:42:00", actor:"U-AD1", scope:null, action:"grant", obj:"Access · Lin Wei · P-2025-010",          detail:"Granted as Reviewer",                                                     ip:"10.0.4.02", device:"Chrome · Windows", hash:"sha256:6d20…0c1a", severity:"normal" },
];

/* ====== Activity Screen — per-project OR workspace-wide ====== */
const ActivityScreen = ({ state, nav, projectId, workspace, embedded }) => {
  const isWorkspace = !!workspace;
  const project = !isWorkspace && projectId ? state.projects.find(p => p.id === projectId) : null;
  const entity = project ? entityById(project.entityId) : null;

  const [sel, setSel] = React.useState(null);
  const [mode, setMode] = React.useState("table");
  const [actionF, setActionF] = React.useState("all");
  const [actorF, setActorF] = React.useState("all");
  const [entityF, setEntityF] = React.useState("all");
  const [projectF, setProjectF] = React.useState("all");
  const [q, setQ] = React.useState("");

  const eventsSource = (state && state.events) || ACT_LOG;
  const events = React.useMemo(() => {
    const scoped = isWorkspace ? eventsSource : eventsSource.filter(e => e.scope === projectId);
    /* Audit log must read newest-first regardless of seed order; ts strings are
       ISO-like — normalise the "T"/" " separator so both formats compare cleanly */
    const k = (e) => (e.ts || "").replace("T", " ");
    return [...scoped].sort((a, b) => k(b).localeCompare(k(a)));
  }, [isWorkspace, projectId, eventsSource]);

  /* Map event scope → entity for entity filter (workspace mode) */
  const entityOfEvent = (ev) => {
    if (!ev.scope) return null;
    const p = state?.projects?.find(p => p.id === ev.scope);
    return p ? p.entityId : null;
  };

  /* Project options filtered by selected entity */
  const projectOptions = React.useMemo(() => {
    if (!isWorkspace) return [];
    const allProjects = state?.projects || [];
    return entityF === "all" ? allProjects : allProjects.filter(p => p.entityId === entityF);
  }, [isWorkspace, state?.projects, entityF]);

  /* Reset project filter when entity changes */
  React.useEffect(() => {
    if (entityF !== "all" && projectF !== "all") {
      const stillInScope = projectOptions.some(p => p.id === projectF);
      if (!stillInScope) setProjectF("all");
    }
  }, [entityF, projectOptions, projectF]);

  const filtered = events.filter(e =>
    (actionF === "all"
      || e.action === actionF
      || (actionF === "access" && (e.action === "grant" || e.action === "decline"))) &&
    (actorF === "all"  || e.actor === actorF) &&
    (!isWorkspace || entityF === "all" || entityOfEvent(e) === entityF) &&
    (!isWorkspace || projectF === "all" || e.scope === projectF) &&
    (!q || (e.obj + " " + e.detail).toLowerCase().includes(q.toLowerCase()))
  );
  const selected = filtered.find(e => e.id === sel) || filtered[0] || events[0];

  /* Group filtered by day bucket (preserve order within group) */
  const byDay = {};
  filtered.forEach(e => {
    const day = dayBucket(e.ts);
    (byDay[day] ||= []).push(e);
  });

  if (!isWorkspace && !project) {
    return (
      <div className="page-body">
        <div className="empty">Project not found.</div>
      </div>
    );
  }

  const stats = [
    { lbl: "Events",     val: events.length },
    { lbl: "Uploads",    val: events.filter(e => e.action === "upload").length },
    { lbl: "Sign-offs",  val: events.filter(e => e.action === "sign").length },
    { lbl: "Publishes",  val: events.filter(e => e.action === "publish").length },
    { lbl: "Critical",   val: events.filter(e => e.severity === "critical").length },
  ];

  const ActionTag = ({ a }) => {
    const m = ACTION_META[a] || ACTION_META.view;
    return <span className={"action-tag " + m.cls}><Icon n={m.icon} s={11}/> {m.label}</span>;
  };
  const severityBadge = s => s === "critical"
    ? <span className="badge danger"><span className="dot"/>critical</span>
    : s === "low"
      ? <span className="badge">info</span>
      : <span className="badge">normal</span>;
  const actorName = (id) => userById(id).name;
  const actorShort = (id) => userById(id).name.split(" ")[0];

  const scopeLabel = (ev) => {
    if (!ev.scope) return "Workspace";
    const p = state.projects.find(p => p.id === ev.scope);
    if (!p) return ev.scope;
    const e = entityById(p.entityId);
    return `${p.name} · ${e?.code || ev.scope}`;
  };

  const backTarget = project ? (
    project.status === "active"
      ? { view:"project-structure", projectId: project.id }
      : { view:"project-draft", projectId: project.id }
  ) : null;

  return (
    <>
      {!isWorkspace && !embedded && (
        <div className="crumbbar">
          <a onClick={()=>nav.go({view:"entities"})}>Entities</a>
          <Icon n="chev-r" s={10}/>
          <a onClick={()=>nav.go({view:"entity-detail", entityId:entity.id, tab:"projects"})}>{entity.name}</a>
          <Icon n="chev-r" s={10}/>
          <a onClick={()=>nav.go(backTarget)}>{project.name}</a>
          <Icon n="chev-r" s={10}/>
          <span className="cur">Activity</span>
        </div>
      )}

      {/* Embedded as a project tab: the tab label + top breadcrumb already say
          "Activity" for this project, so the page-head title/subtitle is redundant.
          The immutability badge survives in the trust strip just below. */}
      {!embedded && (
        <div className="page-head tight">
          <div className="page-title-row">
            <h1 className="page-title">{isWorkspace ? "Activity Log" : "Activity"}</h1>
            <span className="badge mono">Immutable · SHA-256 chained</span>
            {!isWorkspace && (
              <div className="page-actions">
                <button className="btn" onClick={()=>nav.go(backTarget)}><Icon n="arrow-l" s={13}/> Back to project</button>
              </div>
            )}
          </div>
          {isWorkspace ? (
            <div className="page-sub">
              Workspace-wide audit trail across all entities and projects, plus admin actions and access decisions. Every event is hashed and append-only, retained for 7 years.
            </div>
          ) : (
            <div className="page-sub" style={{display:"flex",alignItems:"center",gap:14,flexWrap:"wrap"}}>
              <span>Audit trail for <b style={{color:"var(--ink)"}}>{project.name}</b></span>
              <span className="muted">·</span>
              <span><b style={{color:"var(--ink)"}}>{entity.name}</b> · <span className="mono">{project.id}</span></span>
              {events.length === 0 && (
                <>
                  <span className="muted">·</span>
                  <span className="muted">Drafts and pending submissions are not logged — logging begins when the project is published.</span>
                </>
              )}
            </div>
          )}
        </div>
      )}

      {/* Immutable trust strip */}
      <div className="trust-strip">
        <Icon n="shield" s={14}/>
        <span style={{fontWeight:600}}>Immutable audit trail</span>
        <span className="muted mono" style={{fontSize:11}}>append-only · 7-year retention</span>
        <div className="grow"/>
        <span className="mono" style={{fontSize:11,color:"var(--muted)"}}>Last verified: 22/05/2026 09:58:00 · chain integrity OK</span>
      </div>

      {events.length === 0 ? (
        <div className="page-body">
          <div className="card">
            <EmptyState
              icon="history"
              title="No activity yet"
              sub="Drafts and pending projects don't record activity. Once this project is published by Admin, every action — uploads, edits, sign-offs — will be logged here, hashed, and immutable."
            />
          </div>
        </div>
      ) : (
        <>
          {/* Toolbar */}
          <div className="act-toolbar">
            <div className="input" style={{maxWidth:260}}>
              <Icon n="search" s={13} c="muted"/>
              <input placeholder="Search events, actors, objects…" value={q} onChange={e=>setQ(e.target.value)}/>
            </div>
            <div style={{display:"flex",gap:4,flexWrap:"wrap"}}>
              {[
                ["all","All"],
                ["publish","Publish"],["upload","Upload"],["edit","Edit"],["sign","Sign-off"],
                ["delete","Delete"],
                ...(isWorkspace ? [["perm","Permission"],["access","Access decisions"],["grant","Grant"],["decline","Decline"],["login","Session"]] : []),
              ].map(([k,l])=>(
                <button key={k} className={"chip " + (actionF===k?"active":"")} onClick={()=>setActionF(k)}>{l}</button>
              ))}
            </div>
            <div className="grow"/>
            {isWorkspace && (
              <>
                <select className="btn sm" value={entityF} onChange={e=>setEntityF(e.target.value)}
                  style={{paddingRight:24, maxWidth:180}}
                  title="Filter by entity (client)">
                  <option value="all">All entities</option>
                  {(state?.entities || []).map(en => (
                    <option key={en.id} value={en.id}>{en.code} · {en.name}</option>
                  ))}
                </select>
                <select className="btn sm" value={projectF} onChange={e=>setProjectF(e.target.value)}
                  style={{paddingRight:24, maxWidth:220}}
                  title={entityF === "all" ? "Filter by project" : "Filter by project (scoped to selected entity)"}>
                  <option value="all">All projects{entityF !== "all" ? " (in entity)" : ""}</option>
                  {projectOptions.map(p => (
                    <option key={p.id} value={p.id}>{p.id} · {p.name}</option>
                  ))}
                </select>
              </>
            )}
            <select className="btn sm" value={actorF} onChange={e=>setActorF(e.target.value)} style={{paddingRight:24}}>
              <option value="all">All actors</option>
              {USERS.map(u=><option key={u.id} value={u.id}>{u.name}</option>)}
            </select>
            <div className="seg-wrap">
              <div className="seg">
                <button className={mode==="table"?"active":""} onClick={()=>setMode("table")}>Table</button>
                <button className={mode==="timeline"?"active":""} onClick={()=>setMode("timeline")}>Timeline</button>
              </div>
            </div>
            <button className="btn sm"><Icon n="download" s={12}/> Export CSV</button>
          </div>

          {/* Stats */}
          <div className="act-stat">
            {stats.map((s,i)=>(
              <div key={i} className="stat">
                <div className="stat-lbl">{s.lbl}</div>
                <div className="stat-val">{s.val}</div>
              </div>
            ))}
          </div>

          {/* Main split: log + drawer */}
          <div className="act-split">
            <div className="act-list">
              {mode === "table" ? (
                <table className="tbl">
                  <thead><tr>
                    <th style={{width:170}}>When</th>
                    <th style={{width:140}}>Actor</th>
                    <th style={{width:130}}>Action</th>
                    <th>Object {isWorkspace && "/ Scope"}</th>
                    <th style={{width:100}}>Severity</th>
                    <th style={{width:40}}></th>
                  </tr></thead>
                  <tbody>
                    {filtered.map(e => (
                      <tr key={e.id} className={"act-row " + (e.id===sel?"selected":"")} onClick={()=>setSel(e.id)}>
                        <td className="time">
                          <span className="mono" style={{fontSize:11}}>{fmtTs(e.ts)}</span>
                        </td>
                        <td>
                          <div style={{display:"flex",alignItems:"center",gap:6}}>
                            <Avatar id={e.actor} name={actorName(e.actor)} size="sm"/>
                            <span style={{fontSize:12}}>{actorShort(e.actor)}</span>
                          </div>
                        </td>
                        <td><ActionTag a={e.action}/></td>
                        <td>
                          <div style={{fontWeight:500,fontSize:12.5,whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis",maxWidth:440}}>{e.obj}</div>
                          {isWorkspace && (
                            <div className="mono muted" style={{fontSize:10.5,marginTop:2,whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis",maxWidth:440}}>{scopeLabel(e)}</div>
                          )}
                        </td>
                        <td>{severityBadge(e.severity)}</td>
                        <td><Icon n="chev-r" s={14} c="muted"/></td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              ) : (
                <div className="tl-list">
                  {Object.entries(byDay).map(([day, evs]) => (
                    <div key={day} className="tl-day">
                      <div className="tl-day-head">
                        <span className="tl-day-label">{day}</span>
                        <span className="tl-day-count">· {evs.length} event{evs.length>1?"s":""}</span>
                      </div>
                      {evs.map(e => {
                        const cls = e.action==="sign" || e.action==="approve" || e.action==="publish" ? "signoff" :
                                    e.action==="upload" || e.action==="submit" ? "upload" :
                                    e.severity==="critical" ? "critical" : "";
                        return (
                          <div key={e.id} className={"tl-card " + cls + (e.id===sel?" selected":"")} onClick={()=>setSel(e.id)}>
                            <div className="tl-card-head">
                              <Avatar id={e.actor} name={actorName(e.actor)} size="sm"/>
                              <span style={{fontSize:12.5}}><b>{actorName(e.actor)}</b> · <span className="mono" style={{fontSize:11,color:"var(--muted)"}}>{e.obj}</span></span>
                              <div className="grow"/>
                              <ActionTag a={e.action}/>
                            </div>
                            <div className="tl-card-body">{e.detail}</div>
                            <div className="tl-card-meta">
                              <span className="mono">{fmtTs(e.ts)}</span>
                              {isWorkspace && <><span>·</span><span>{scopeLabel(e)}</span></>}
                              <span>·</span><span>{e.ip}</span>
                              {e.severity==="critical" && <span style={{color:"var(--danger-ink)"}}>· critical</span>}
                            </div>
                          </div>
                        );
                      })}
                    </div>
                  ))}
                </div>
              )}
              <div className="act-foot">
                <span className="mono muted">Showing {filtered.length} of {events.length} events{isWorkspace ? "" : " for this project"}</span>
                <div className="grow"/>
                {filtered.length < events.length && <button className="btn sm" onClick={()=>{setActionF("all");setActorF("all");setEntityF("all");setProjectF("all");setQ("");}}>Clear filters</button>}
              </div>
            </div>

            {/* Detail drawer */}
            <div className="act-drawer">
              {selected ? <>
              <div style={{display:"flex",alignItems:"center",gap:8,marginBottom:14,flexWrap:"wrap"}}>
                <span className="mono" style={{fontSize:11,color:"var(--muted)"}}>{selected.id}</span>
                <ActionTag a={selected.action}/>
                {severityBadge(selected.severity)}
              </div>
              <div style={{fontSize:15,fontWeight:600,lineHeight:1.35,marginBottom:4}}>{selected.obj}</div>
              <div className="mono muted" style={{fontSize:11,marginBottom:16}}>{fmtTs(selected.ts)}</div>

              <div className="dfield">
                <label>Actor</label>
                <div className="dval" style={{display:"flex",alignItems:"center",gap:8}}>
                  <Avatar id={selected.actor} name={actorName(selected.actor)} size="md"/>
                  <div>
                    <div style={{fontWeight:500}}>{actorName(selected.actor)}</div>
                    <div className="mono muted" style={{fontSize:10.5}}>{userById(selected.actor).role}</div>
                  </div>
                </div>
              </div>

              <div style={{display:"grid",gridTemplateColumns:"1fr 1fr",gap:14}}>
                <div className="dfield">
                  <label>IP address</label>
                  <div className="dval mono" style={{fontSize:12}}>{selected.ip}</div>
                </div>
                <div className="dfield">
                  <label>Device</label>
                  <div className="dval" style={{fontSize:12}}>{selected.device}</div>
                </div>
              </div>

              {isWorkspace && (
                <div className="dfield">
                  <label>Scope</label>
                  <div className="dval">
                    <div style={{fontWeight:500}}>{scopeLabel(selected)}</div>
                    <div className="mono muted" style={{fontSize:11,marginTop:2}}>{selected.scope || "Workspace"}</div>
                  </div>
                </div>
              )}

              <div className="dfield">
                <label>Detail</label>
                <div className="dval" style={{fontSize:12.5,lineHeight:1.55}}>{selected.detail}</div>
              </div>

              <div className="dfield">
                <label>Evidence hash (SHA-256)</label>
                {selected.hash !== "—" ? (
                  <div className="hash-box">
                    <span className="hchip">verified</span>
                    <span style={{flex:1}}>{selected.hash}</span>
                    <button className="btn ghost sm" title="Copy"><Icon n="copy" s={12}/></button>
                  </div>
                ) : <div className="dval muted">— no artifact —</div>}
              </div>

              <div className="hr"/>
              <div className="section-label" style={{marginBottom:8}}>Chain anchor</div>
              {(() => {
                /* δ Hash Chain — events are ordered newest-first; the entry
                   directly after `selected` in the list is the older one
                   (= prev), and the one before it is the newer (= next). */
                const idx = filtered.findIndex(e => e.id === selected.id);
                const prev = idx >= 0 ? filtered[idx + 1] : null;
                const next = idx > 0  ? filtered[idx - 1] : null;
                return (
                  <>
                    <div className="hash-box" style={{fontSize:10, display:"flex", alignItems:"center", gap:6, flexWrap:"wrap"}}>
                      <span className="hchip">verified</span>
                      <span style={{color:"var(--muted)"}}>prev ·</span>
                      <span className="mono">{prev?.hash || "— genesis —"}</span>
                      <span style={{color:"var(--muted)"}}>→</span>
                      <b style={{color:"var(--ink-2)"}}>this</b>
                      <span style={{color:"var(--muted)"}}>→</span>
                      <span className="mono">{next?.hash || "— most recent —"}</span>
                    </div>
                    <div className="mono muted" style={{fontSize:10.5,marginTop:8,lineHeight:1.5}}>
                      Events form an append-only hash chain. Each entry stores the previous entry's hash; rewriting any past event would break the chain at the next verify.
                    </div>
                  </>
                );
              })()}
              </> : (
                <div className="muted" style={{padding:"24px 8px",fontSize:12.5,textAlign:"center"}}>
                  No events match the current filters.
                </div>
              )}
            </div>
          </div>
        </>
      )}
    </>
  );
};

Object.assign(window, { ACTION_META, ACT_LOG, ActivityScreen, dayBucket });
