# emergence — frontend UX brief (handoff prompt)

Give this document to the UX/frontend system as-is. Its output is verified against the
"Deliverables" and "Hard constraints" sections at the end.

---

You are designing and building the public frontend of **emergence**, the live-events
section of fact.ngo — a nonprofit, coherence.ngo subproject. You have full creative
freedom over the design language, layout, and interaction model; you must not change
the data contract, the epistemic labeling rules, or the site-wide constraints.

## What emergence is

A sensor net over live news: registered newsrooms' reports (Al Jazeera, BBC World, The
Guardian World at launch; Reuters deferred, stated openly) are machine-distilled — one
call per article, glm-5.3-flash on Cloudflare Workers AI, fixed neutral-framing prompt —
into "essences": what the report says happened, the general principles at play, actors,
places, topic mapping. Every record is **`status: "unverified"`** at birth. A fact-
checking council lane (multi-seat AI deliberation) is built but deliberately inactive.
Total operating cost: under $0.10/day, hard-capped at $1/day.

The product question you are answering: *how do you show what's happening in the world
today, honestly, when nothing is verified and everything is machine-distilled?*

## Epistemic framing rules (non-negotiable, data-contract level)

1. Every record is labeled **"not fact-checked · summarized from news reports"** — visibly, wherever a record
   appears. This is not a footer disclaimer; it is part of the record's identity.
2. Never present an essence as established fact, and never style coverage volume
   (counts) as importance or truth.
3. Source attribution + outbound link on every record.
4. The verified lane renders as an explicit, honest placeholder: the council exists,
   is inactive by design, and zero verified records exist. Do not fake it, do not bury it.
5. Reuters' absence is stated, not hidden.
6. "Distilled by glm-5.3-flash" appears in the interface's method transparency (one
   place, not per record).

## The data contract (all of it)

A `data.json` snapshot ships next to the page at `/emergence/data.json` (rebuild
generates it from the newest `aggregates/<date>/` partition of the emergence-data repo).
Read it; design from it. Shape:

- `date` — UTC day ("today" is this)
- `day` — `{ counts: { articles, essences, failures, events }, sources: { <id>: { status: "ok"|"failed"|"deferred", fetched, new } }, spend: { tokens_in, tokens_out, usd } }`
- `events[]` — **the event layer**: `{ id, members[], sources[], topic, subtopic, facets: [{id, label, members[]}], locations[], reports, weight, continues (yesterday's event id | null), thread_id, thread_days }` — every ok essence belongs to exactly one event; `weight` = corroboration (1/1.6/2 for 1/2/3+ sources) × complexity (1 + 0.25 × facets) × sustention (1 + 0.1 × min(thread_days − 1, 5)); `thread_days > 1` marks an event continuing from previous days
- `topics.tree[]` — fractal rollup, **sorted by event-weight score**: `{ topic, name, count (reports), events, score (Σ weight), subtopics: [{ subtopic, name, count, events, score, event_refs: [{id, weight, reports, sources, facets, essences: [up to 8 refs]}], essences: [up to 3 refs] }] }`
- `gis.countries[]` — `{ country_code, name, lat, lon, count (reports), events (deduped), essences: [up to 5 refs] }` — country-resolution stated limit; dots scale by events
- `essences[]` — full day's records: `{ id, essence, principles[], topics[], actors[], locations[], event_type, uncertainty, article: { title, url, source_id, source_name } }`
- `council` — `{ lane: "verified", active: false }`

Counting semantics: treemap areas rank by `score` (event weight), while labels show
`N events · M reports` — coverage volume stays visible, duplicates don't inflate it,
and corroborated/nuanced events carry more weight than single uncorroborated reports.

Field semantics worth designing with: `uncertainty` (what a reader should not yet
assume), `principles` (the idea isolation layer — a different lens over the same day),
`event_type` (conflict-event, decision, statement, development, data-release, disaster,
analysis-claim, report).

## The "many lenses" mandate — view stage model

The page follows a reader-journey stage model; each stage earns its view. Treat this as
the interaction backbone (you may restyle everything, keep the stage logic):

| Stage | Reader question | View | Status |
| --- | --- | --- | --- |
| Arrive (0–5s, phone) | "What kind of day is it?" | Day stats + the topic treemap as one image: the day's *shape* | built |
| Orient (~30s) | "Where is attention?" | The night-earth attention map: ghost land, glowing countries, volume dots | built |
| Drill (semantic zoom) | "Go deeper into this" | Fractal treemap zoom topic → subtopic → essence cards; hash-linkable (`#t/...`) | built |
| Inspect (terminus) | "What exactly is claimed, by whom?" | Essence card: essence · principles · uncertainty · source link. Dead end by design | built |
| Compare (returning reader) | "What changed since yesterday?" | Timeline/scrubber over day partitions | stub — one day of data exists; make it real once ~a week accumulates |
| Trust (skeptic) | "How does this work?" | Method & status: model, cost, sources, unverified rule, council status | built |

You decide hierarchy and visual treatment; the one thing you may re-conceive freely is
a lens of your own invention (below).

Fractal zoom rules (the Google-Maps-style part):
- Semantic zoom, not magnification: every level re-tiles the same frame as a complete,
  legible page. No getting lost in pixels.
- Labels appear only when a tile can hold them; empty subtopics render as nothing
  (honest gaps).
- Breadcrumb doubles as back-button and shareable URL state.
- Coverage-volume captions must survive: territory/dot size = newsroom attention,
  never importance or truth. A treemap that *feels* like "big events" is a failure.

A lens of your own invention — grounded in the fields (`principles`, `actors`,
`event_type`, `uncertainty` are the underexploited ones). This is the ideation the
owner explicitly wants: propose one strong new lens, not five.

## Current scaffold (replace or extend freely)

`site/scripts/build.js` (emergence section) already renders, zero-dependency:
- `emTreemapStatic` — server-rendered level-1 squarified treemap (day portrait)
- inline drill JS — hash-routed zoom into subtopics + essence cards (no-JS floor: the
  full day is always listed as plain sections)
- `emergenceMapSvg` — attention map over a vendored Natural Earth 110m basemap
  (`assets/emergence-world.json`, public domain, regenerated by
  `scripts/gen-world-svg.js`)
- `data.json` snapshot alongside the page for client-side lenses

Keep the build's data plumbing intact; replace markup, CSS, and JS wholesale at will.

## The app-shell regime (in force)

Emergence and the xray case files run as an app inside the browser: the site header stays
fixed, sections are on-screen panes toggled by the pane nav (`data-shell` / `data-pane` /
`data-shell-nav`, see `site/assets/app-shell.js`), and scrolling happens inside the
active pane, never the page. The no-JS floor is a plain stacked page and must stay
byte-identical. Deep links (`#record-…`, `#topic-…`, `#country-…`, `#t/…`) must keep
resolving to their pane. Design within this regime — new big views become panes, not
lower scroll sections.

## Hard constraints

- Static site, zero runtime dependencies, no external JS/CDN at runtime (fonts and
  images vendored or system; a map library only if vendored and self-hosted).
- Works without JS: server-rendered (build-time) core content; JS may enhance.
- Dark and light modes (existing site pattern: `data-mode`, `localStorage 'fact-mode'`).
- No sideways scroll at 320, 375, 1280 px. Small text ≥ 15px. WCAG AA contrast.
- Chrome: persistent badge "fact.ngo · a coherence.ngo project" linking coherence.ngo;
  header nav consistent with the rest of fact.ngo (parent site + /xray/).
- Tone: sober, precise, warm-allowed but never hype. This is an instrument panel for
  epistemic humility, not a breaking-news adrenaline product.
- Mobile-first: most readers will skim this daily on a phone.

## Deliverables

1. An `em-*` (or successor) design system: layout, type, color, and interaction specs —
   dark + light.
2. The full `/emergence/` page (or page set): markup, vendored CSS/JS, wired to the
   `data.json` contract, produced through `site/scripts/build.js`.
3. A one-screen "method & status" treatment: what this feed is, what it is not, which
   model distills it, what it costs, what's deferred (Reuters, council-inactive).
4. Design notes: your invented lens explained in 5 sentences or fewer.

## Verification (what will be checked)

- Build reproduces: `node scripts/build.js` from `site/` with the mono-folder intact.
- Every essence record visible carries the not-fact-checked label and a working source link.
- Verified-lane placeholder is present and honest; no verified records are implied.
- Viewports 320/375/1280: no horizontal scroll; small text ≥ 15px.
- Dark and light mode both coherent.
- `data.json` contract unchanged (fields may be consumed, not redefined).
