Note

    page

    "use client"; import { useMemo, useState } from "react"; const projects = ["all", "hyphenomenon", "rps-etsy", "family-shapes", "tmora", "shopi...

    "use client"; import { useMemo, useState } from "react"; const projects = ["all", "hyphenomenon", "rps-etsy", "family-shapes", "tmora", "shopify", "codex-skills"]; const frames = Array. from({ length: 72 }).

    "use client";

    import { useMemo, useState } from "react";

    const projects = ["all", "hyphenomenon", "rps-etsy", "family-shapes", "tmora", "shopify", "codex-skills"];

    const frames = Array.from({ length: 72 }).map((_, index) => { const hour = 12 - Math.floor(index / 12); const minute = 55 - ((index * 5) % 60); const project = projects[(index % (projects.length - 1)) + 1]; const status = index % 9 === 0 ? "quarantine" : index % 4 === 0 ? "candidate" : "private"; return { id: frame-${index + 1}, time: ${Math.max(7, hour)}:${String(Math.max(0, minute)).padStart(2, "0")} ${hour >= 12 ? "PM" : "AM"}, group: hour >= 11 ? "June 4, 2026 - Midday Capture" : "June 4, 2026 - Morning Capture", project, status, summary: project === "tmora" ? "Inferred TMORA print-production context. Raw screen content stays private until reviewed." : Inferred ${project} work context. Publication requires redaction review and source-safe summary text. }; });

    const statusLabels = { private: "raw private", candidate: "redaction candidate", quarantine: "quarantined" };

    export default function Home() { const [project, setProject] = useState("all"); const [query, setQuery] = useState(""); const [selected, setSelected] = useState(frames[7]);

    const visibleFrames = useMemo(() => { const normalized = query.trim().toLowerCase(); return frames.filter((frame) => { const projectMatch = project === "all" || frame.project === project; const text = ${frame.project} ${frame.status} ${frame.summary}.toLowerCase(); return projectMatch && (!normalized || text.includes(normalized)); }); }, [project, query]);

    const groups = useMemo(() => { return visibleFrames.reduce((acc, frame) => { acc[frame.group] ||= []; acc[frame.group].push(frame); return acc; }, {}); }, [visibleFrames]);

    return ( <main className="viewer-shell"> <aside className="side-nav" aria-label="Chronicle viewer sections"> <a className="brand" href="/"> <span className="brand-mark" aria-hidden="true" /> Chronicle </a> <nav> <a className="active" href="/">Timeline</a> <a href="/docs">Docs</a> <a href="/projects">Projects</a> </nav> <div className="storage-note"> <strong>Raw archive</strong> <span>Private object storage planned. Git is for source and reviewed public derivatives.</span> </div> </aside>

      <section className="timeline-app">
        <header className="app-toolbar">
          <div>
            <h1>Visual Timeline</h1>
            <p>Public app scaffold using synthetic/redacted placeholders. Raw captures are not loaded here.</p>
          </div>
          <div className="toolbar-controls">
            <label className="app-search">
              <span>Search</span>
              <input
                value={query}
                onChange={(event) => setQuery(event.target.value)}
                placeholder="project, redaction status, summary"
              />
            </label>
            <button type="button">Archive setup</button>
            <button type="button">Redaction queue</button>
          </div>
        </header>
    
        <section className="filter-row" aria-label="Project filters">
          {projects.map((item) => (
            <button
              className={project === item ? "selected" : ""}
              key={item}
              onClick={() => setProject(item)}
              type="button"
            >
              {item === "all" ? "All projects" : item}
            </button>
          ))}
        </section>
    
        <div className="viewer-content">
          <section className="timeline-canvas" aria-label="Chronicle visual timeline">
            {Object.entries(groups).map(([group, items]) => (
              <section className="frame-group" key={group}>
                <header>
                  <h2>{group}</h2>
                  <span>{items.length} frames</span>
                </header>
                <div className="frame-grid">
                  {items.map((frame, index) => (
                    <button
                      className={`frame-card ${frame.status} ${selected?.id === frame.id ? "is-selected" : ""}`}
                      key={frame.id}
                      onClick={() => setSelected(frame)}
                      type="button"
                    >
                      <span className="synthetic-screen">
                        <span className="screen-bar" />
                        <span className="screen-line short" />
                        <span className="screen-line" />
                        <span className={index % 5 === 0 ? "redaction-block wide" : "redaction-block"} />
                      </span>
                      <span className="frame-time">{frame.time}</span>
                      <span className="frame-project">{frame.project}</span>
                    </button>
                  ))}
                </div>
              </section>
            ))}
          </section>
    
          <aside className="detail-panel" aria-label="Selected frame details">
            <div className="date-rail" aria-label="Date scrubber">
              <a href="#june-4" className="active">Jun 4</a>
              <a href="#summaries">Summaries</a>
              <a href="#archive">Archive</a>
            </div>
    
            {selected ? (
              <article className="inspector">
                <div className={`status-pill ${selected.status}`}>{statusLabels[selected.status]}</div>
                <h2>{selected.time}</h2>
                <p>{selected.summary}</p>
    
                <dl>
                  <div>
                    <dt>Project label</dt>
                    <dd>{selected.project} <span>inferred</span></dd>
                  </div>
                  <div>
                    <dt>Source visibility</dt>
                    <dd>private raw frame</dd>
                  </div>
                  <div>
                    <dt>Publication state</dt>
                    <dd>{selected.status === "candidate" ? "needs review" : "not public"}</dd>
                  </div>
                </dl>
    
                <section className="policy-box">
                  <h3>Publication boundary</h3>
                  <p>
                    This app must publish only reviewed redacted derivatives. Raw screenshots, OCR,
                    local paths, and private summaries stay outside git and public deploys.
                  </p>
                </section>
              </article>
            ) : null}
          </aside>
        </div>
      </section>
    </main>
    

    ); }

    Provenance

    Metadata

    Created
    Not recorded
    Last updated
    Not recorded