Time-Machine Mode
Concept
A site-wide chronological scrubber living in the header of the vault explorer. Drag a single handle from 100,000 BP to today and the entire site responds at once:
- Domain cards reorder by what existed at the scrubbed moment — Prehistoric leads at 30,000 BP; Mesopotamia and Egypt jump to the front at 2350 BCE; Abrahamic and Dharmic surge in the Axial window.
- Notes outside the era dim. A claim attested c. 800 BCE (Kuntillet Ajrud) fades to a ghost when you stand in 5500 BCE — it doesn't exist yet. Scrub forward and it lights up the moment its
attestation_earliestis crossed. - The ambient palette shifts with the epoch: firelight ambers in the deep Paleolithic → ochre and megalith grey in the Neolithic → lapis-and-temple-stone in the Bronze Age → parchment and ink in the Axial/Classical world → the current cool dark theme at the modern end.
- A "you are in 2350 BCE" context strip sits under the header on every page, telling you what is being built, written, and worshipped right now across the world — generated entirely from the vault's own dated attestation data, never invented.
The scrubber is not a page; it is a mode the whole explorer enters. Every directory listing, every note, every navigation keeps the era you chose until you scrub again.
Why it takes you back in time
The vault's core discipline — date or label (AGENTS.md §1.6) — means every origin claim already carries a machine-recoverable earliest date. Time-Machine Mode turns that epistemological rule into a physical sensation: standing at a moment in time and seeing only what the evidence says existed.
- It makes deep time felt, not stated. Dragging from Qafzeh's ochre burials (92,000 BP) and watching nothing else light up for eighty thousand years communicates the loneliness of early symbolic behavior better than any paragraph.
- It enforces the vault's own epistemics viscerally. A note that dims isn't censored — it hasn't been attested yet. The user experiences attestation-dating as the ground truth it is. Composition-vs-attestation gaps (the Rigveda's ~2,500-year oral gap) become dramatic: the hymns glow faintly at 1500 BCE ("composition, inferential") but only fully ignite at 1464 CE (manuscript).
- Simultaneity is the payoff. Standing in 2350 BCE and reading "Pyramid Texts being carved at Saqqara · Eridu's temple already 3,000 years old · Stonehenge's sarsen circle rising · no Rigveda, no Bible, no Buddha for another millennium-plus" — that cross-world synchrony is exactly the comparative instinct the 09_comparative domain exists to test, delivered as an instant.
- The palette shift is era-empathy. Light itself changes: the world before lamps is firelit; the world of scribes is parchment-toned. The reader's eye adapts the way a traveler's would.
Experience walkthrough
1. Arrive at the home page. Under the sticky header sits a thin horizontal scrubber — a timeline rail with faint tick marks at the vault's attested events (each tick is a real note). The handle rests at "today"; the site looks as it does now.
2. Grab the handle and drag left. The year readout counts down — 1900 CE, 800 BCE, 2350 BCE — on a logarithmic scale, so the crowded last 5,000 years get most of the rail and the long Paleolithic compresses gracefully.
3. At 2350 BCE the site transforms. Background deepens to temple-stone and lapis. The domain grid reorders: Mesopotamia, Egypt, Prehistoric first (all attested); Abrahamic, Dharmic, East Asian dim to 30% opacity with a small "not yet attested" whisper-label. The context strip reads: ⌛ You are in c. 2350 BCE — the Pyramid Texts are being inscribed in the pyramid of Unas at Saqqara; Eridu's temple sequence is ~3,000 years old; Sumerian god-lists have been written for two centuries; Osiris has just entered the written record. Each item links to its note.
4. Click into a domain. The era persists (URL hash #t=-2350). In 02_mesopotamian/2_notes/, the Atrahasis flood-tablet note (1635 BCE) is dimmed — it doesn't exist for another seven centuries — while the Eridu temple claim glows fully.
5. Open a dimmed note. It still opens (read-only honesty — nothing is hidden), but a banner says "First attested c. 1635 BCE — 715 years after your current position." One click jumps the scrubber to that note's moment.
6. Keep dragging left to 30,000 BP. Nearly everything fades. The palette goes near-black with ember-orange accents. The strip reads: You are in c. 30,000 BP — Sungir's burials are fresh; Chauvet's walls were painted six millennia ago; every religion with a name lies tens of thousands of years in the future.
7. Drag back to today. The palette warms back to the familiar dark theme, all cards re-light in domain order, and the strip dissolves. A small "⏱ Time-Machine" toggle in the header collapses the rail when you want the plain explorer.
Data from the vault
Everything the mode shows is already in frontmatter — no new data entry required:
| Field | Where | Use |
|---|---|---|
attestation_earliest | claims, motifs, traditions (REQUIRED by template) | The note's "lights up" moment; first parseable date in the string |
date_of_evidence | source records | Tick marks + context-strip events for tier-1 sources |
transmission, confidence | motifs/claims | Strip styling — speculative items render with a dashed "inferential" treatment |
region_origin | traditions | Lets the strip group events by region ("Egypt: … · Mesopotamia: …") |
domain / directory | all notes | Domain-card ordering: a domain's "born" date = min attested date of its notes |
Real values already present and parseable today: c. 92,000 BP (Qafzeh), c. 34,000–30,000 BP (Sungir), c. 5500 BCE (Eridu Level XVIII), c. 2350 BCE (Unas Pyramid Texts), c. 1635 BCE (Atrahasis), c. 1380 BCE (Mitanni treaty), c. 1250 BCE (oracle bones), c. 800 BCE (Kuntillet Ajrud), 712 CE (Kojiki). That is already enough density for a compelling rail; every new researched note enriches the machine automatically.
Notes with speculative or unparseable dates never dim — they render in a neutral "undated" state with a small hourglass marker, honoring rule §1.6 rather than guessing.
Implementation sketch
Bun, zero npm deps, all inside tools/server.ts (the existing single-file, server-rendered explorer). Four additions, ~250 lines total:
1. Date parser (pure function next to parseFrontmatter):
```ts
// returns astronomical year: BCE → negative (2350 BCE → -2349), CE → positive, BP → 1950 - n
function earliestYear(s: string): number | null {
const bp = s.match(/([\d,]+)(?:[–-][\d,]+)?\s*(?:cal\s+)?BP/i);
const bce = s.match(/([\d,]+)(?:[–-][\d,]+)?\s*BCE/);
const ce = s.match(/(\d{3,4})\s*CE/);
// prefer the oldest hit; strip commas; return null if /speculative/ leads the string
}
```
Take the oldest parseable date in the string (the fields often list several anchors; the first/oldest is the attestation headline).
2. /api/timeline endpoint (new route alongside /api/version): walk the vault once (reuse the vaultVersion() walk pattern, cache keyed on version), parse frontmatter of every .md, emit
```json
[{ "p": "/02_mesopotamian/2_notes/eridu-temple-level-xviii…md",
"t": "Eridu temple Level XVIII…", "d": "02_mesopotamian",
"y": -5499, "label": "mud-brick altar with food offerings, Eridu",
"type": "claim", "conf": "high" }]
```
This one payload powers the rail ticks, the context strip, and domain birth-dates.
3. Server-side data- attributes (two one-line edits): noteCard() adds data-y="${year ?? ''}" to each .cardlink; the domain grid on home() adds data-born per domain card. Dimming/reordering is then pure CSS class toggling — no re-render, no flicker.
4. Header rail + client script (one TIMEJS const, injected by page() like the existing version-poll script; one CSS block appended to CSS):
- Rail markup appended inside
nav()'s<header class="top">:<div class="trail"><input type="range" id="tm" min="0" max="1000" value="1000"><span id="tmyear"></span></div>plus a collapse toggle. - Log mapping: slider position
p∈[0,1]→ years-before-presentybp = 10^(5·(1−p)), so 100,000 BP sits at 0 and the dense historical era gets ~60% of the rail. Year readout formats asN BPbeyond 12,000 BP, elseBCE/CE. - On input: fetch (once, cached)
/api/timeline; toggle.era-dimon every[data-y]whose year > scrub year; reorder domain cards withstyle.order; rewrite the context strip from the 3–6 timeline events nearest before the scrub year (grouped by domain, each linking to its note, the freshest flagged "just now"); set palette. - Palette = CSS custom properties. The whole theme already lives in
:rootvars (--bg --panel --fg --blue …). Define 5 era palettes as a JS table anddocument.documentElement.style.setProperty(...)with a CSStransitionon background/color — firelight (≥12,000 BP), ochre/megalith (12,000 BP–3500 BCE), lapis/temple-stone (3500–1200 BCE), parchment/ink (1200 BCE–1500 CE), current theme (modern). Optional: swap the hero background to the matchingassets/illustrations/era-*.png. - Persistence: scrub year →
location.hash = '#t=-2350'+localStorage; the injected script restores it on every page load, so the era survives navigation site-wide.
Read-only guarantee untouched: the mode only renders differently; the server still serves the same markdown.
Images needed
Numbered GPT-5.5 (codex CLI) prompts — all photorealistic, cinematic, archaeologically grounded, no text in image, 21:9 for ambient backdrops, saved to assets/illustrations/:
1. era-paleolithic.png — "Interior of a deep limestone cave at night lit only by a single small fire; ochre handprints and faded animal paintings barely visible on the rock wall; long shadows, ember-orange and near-black palette, photorealistic, cinematic wide shot, no people facing camera, no text."
2. era-neolithic.png — "Dawn at a megalithic hilltop enclosure of carved T-shaped limestone pillars in the style of Göbekli Tepe, low golden light raking across worked stone and dry steppe grass, ochre and bone-grey palette, photorealistic archaeological reconstruction, no modern objects, no text."
3. era-bronze.png — "A Mesopotamian mud-brick temple platform at dusk beside a reed-lined river, oil lamps glowing in doorways, lapis-blue twilight sky over warm baked-brick tones, distant figures carrying offerings, photorealistic cinematic reconstruction, no text."
4. era-axial.png — "A quiet scriptorium scene of the ancient world: papyrus scrolls and clay tablets on a wooden table lit by a clay oil lamp, parchment and ink palette, warm candle-toned shadow, extreme detail, photorealistic, no readable writing, no text."
5. era-modern.png — "Museum gallery at night: a single illuminated display case holding a cuneiform tablet, cool dark-blue ambient light, glass reflections, contemplative cinematic mood, photorealistic, no text."
6. time-machine-mode.png (banner for this idea note) — "A single horizontal beam of light crossing a dark landscape that transitions seamlessly from a firelit cave on the left, through standing stones and a ziggurat at center, to a modern city skyline on the far right, dawn gradient sky, photorealistic composite panorama, cinematic, no text."
Effort
M overall, with a genuinely small core:
- Ships first (S, one sitting): date parser +
/api/timeline+ header rail + note dimming + URL-hash persistence. This alone is the time machine — scrubbing and watching notes ignite/fade already lands the experience. - Second (S): context strip ("you are in 2350 BCE" + nearest-events list) — pure client templating over the same JSON.
- Third (M): era palettes with transitions, domain-card reordering, era backdrop images (6 codex renders), dimmed-note banner with "jump to this note's moment."
- Out of scope for v1: per-region map view, animated autoplay ("press play, watch 100,000 years"), composition-vs-attestation dual handles — all natural v2s on the same
/api/timelinepayload.