docs: add clement.saillant.cc design spec
Demoscene-style personal identity hub: bus on a giant PCB, 4 content stops, MOD tracker audio, semantic DOM fallback with rel=me Mastodon verification. Static build, deployed on Tower behind Traefik + cloudflared tunnel.
This commit is contained in:
@@ -0,0 +1,143 @@
|
|||||||
|
# clement.saillant.cc — "LE BUS" — Design
|
||||||
|
|
||||||
|
**Date:** 2026-07-09
|
||||||
|
**Status:** Approved by user (brainstorming session 2026-07-09)
|
||||||
|
**Target:** https://clement.saillant.cc (personal identity hub, hosted on Tower)
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Personal identity hub for Clément Saillant, built as a **demoscene-style
|
||||||
|
3D experience**: a crazy bus driving across a giant PCB landscape,
|
||||||
|
carrying I2C frames as passengers, stopping at "bus stops" that hold the
|
||||||
|
site's content (bio, identity links, L'Électron Fou music, greetings).
|
||||||
|
Amiga/demoscene aesthetics throughout: copper bars, sine scroller,
|
||||||
|
boing ball, tracker music, flat-shaded low-poly, dithering.
|
||||||
|
|
||||||
|
The page doubles as the canonical "Clément Saillant" entry point on the
|
||||||
|
web and provides the reciprocal `rel="me"` link so Mastodon verifies
|
||||||
|
`clement.saillant.cc` on the `@clement@mastodon.saillant.cc` profile.
|
||||||
|
|
||||||
|
## Goals
|
||||||
|
|
||||||
|
- One memorable page that says who Clément is and links every identity.
|
||||||
|
- Reciprocal `rel="me"` verification with Mastodon (green badge).
|
||||||
|
- Pure fun: demoscene tribute (Amiga, cracktro culture, tracker music,
|
||||||
|
tube amps, electronics, L'Électron Fou noise project).
|
||||||
|
- Zero-maintenance content: no blog, no CMS, static build.
|
||||||
|
|
||||||
|
## Non-goals
|
||||||
|
|
||||||
|
- Not a CV / recruiting page (lelectronrare.fr and ailiance.fr cover
|
||||||
|
professional needs).
|
||||||
|
- No entry cracktro (approach "A" chosen over "A + cracktro").
|
||||||
|
- No backend, no analytics, no comments, no CMS.
|
||||||
|
|
||||||
|
## Scene design
|
||||||
|
|
||||||
|
**World:** a giant PCB seen as a landscape. Dark green substrate,
|
||||||
|
glowing copper traces, vias as light wells, low-poly flat-shaded
|
||||||
|
components as buildings (electrolytic caps, resistors, QFP chips).
|
||||||
|
Saturated Amiga-like palette (~32 colors) with a light ordered-dithering
|
||||||
|
post-process. Sky: animated **copper bars** shader. A red/white
|
||||||
|
**boing ball** orbits as a moon.
|
||||||
|
|
||||||
|
**The bus:** a crazy van, L'Électron Fou paint job, driving along a main
|
||||||
|
copper trace that snakes between components. **Scroll drives the bus**
|
||||||
|
(wheel, arrow keys, touch swipe); the camera follows with easing.
|
||||||
|
**I2C frames** (small glowing packets labeled `0x42 ACK`, `SDA`, `SCL`…)
|
||||||
|
board and alight at stops like passengers.
|
||||||
|
|
||||||
|
**Permanent HUD:**
|
||||||
|
- Bottom **sine-wave text scroller**: greetings, project shout-outs,
|
||||||
|
free-form nonsense. Content is a plain text array in one source file.
|
||||||
|
- Mini tracker panel: play/pause MOD, mute.
|
||||||
|
|
||||||
|
## The 4 stops (content)
|
||||||
|
|
||||||
|
1. **"BOOT"** — bio. An oversized bus-stop sign with a 5-6 line bio
|
||||||
|
(electronics, sovereign AI, noise music, escape rooms) + pixel-art
|
||||||
|
avatar.
|
||||||
|
2. **"IDENTITÉS"** — the hub core. A forest of hijacked road signs,
|
||||||
|
clickable in 3D:
|
||||||
|
- Mastodon `@clement@mastodon.saillant.cc` (rel=me)
|
||||||
|
- Gitea `git.saillant.cc`
|
||||||
|
- lelectronrare.fr
|
||||||
|
- ailiance.fr
|
||||||
|
- Hypneum Lab
|
||||||
|
- HuggingFace
|
||||||
|
3. **"L'ÉLECTRON FOU"** — a giant **tube amp** whose tubes glow in
|
||||||
|
rhythm, VU meters moving. Presents the noise project; listen links
|
||||||
|
point to **Bandcamp**.
|
||||||
|
4. **"GREETINGS"** (terminus) — end-of-demo style credits: greetings to
|
||||||
|
communities (KiCad, fediverse, French demoscene…), credits,
|
||||||
|
"ride again?" teleports back to start.
|
||||||
|
|
||||||
|
## Audio
|
||||||
|
|
||||||
|
- **MOD tracker player** (libopenmpt via chiptune2.js): a real chiptune
|
||||||
|
module as background music. Starts only after first user interaction
|
||||||
|
(browser autoplay policy), mutable at all times.
|
||||||
|
- At the Électron Fou stop, audio ambience shifts toward the noise
|
||||||
|
universe.
|
||||||
|
- Module licensing: use an original module or one with an explicit
|
||||||
|
redistribution license (Mod Archive licensed works). Ideally an
|
||||||
|
original Électron Fou chiptune (open item).
|
||||||
|
|
||||||
|
## Architecture & tech stack
|
||||||
|
|
||||||
|
- **Vite + React + React Three Fiber + drei** (same pattern as
|
||||||
|
RELAIS-07 / adn.saillant.cc).
|
||||||
|
- GLSL shaders: copper bars, ordered dithering post-process.
|
||||||
|
- chiptune2.js / libopenmpt (WASM) for MOD playback.
|
||||||
|
- Static build output; no server-side code.
|
||||||
|
|
||||||
|
### Units
|
||||||
|
|
||||||
|
- `scene/` — world (PCB, components, traces), bus, I2C passengers,
|
||||||
|
boing ball, sky shaders. Consumes a declarative `stops.ts` config.
|
||||||
|
- `hud/` — sine scroller, tracker panel. Independent of the 3D scene.
|
||||||
|
- `content/` — single source of truth: bio text, links (with rel
|
||||||
|
attributes), greetings list, stop definitions. Used by BOTH the 3D
|
||||||
|
scene and the semantic DOM fallback so they can never diverge.
|
||||||
|
- `audio/` — MOD player wrapper (lazy-loads WASM after first
|
||||||
|
interaction).
|
||||||
|
|
||||||
|
## Fallback, accessibility, rel=me (non-negotiable)
|
||||||
|
|
||||||
|
- Beneath the canvas, a **real semantic DOM**: `h1` "Clément Saillant",
|
||||||
|
bio, and all links including
|
||||||
|
`<a rel="me" href="https://mastodon.saillant.cc/@clement">`.
|
||||||
|
- Served in the static HTML (pre-rendered at build time, not injected
|
||||||
|
client-side) so Mastodon's verifier and crawlers see it.
|
||||||
|
- JS disabled or `prefers-reduced-motion` → the semantic page is shown,
|
||||||
|
styled with bitmap fonts; fully usable.
|
||||||
|
- Keyboard navigation: arrows drive the bus, links are real focusable
|
||||||
|
anchors.
|
||||||
|
|
||||||
|
## Deployment
|
||||||
|
|
||||||
|
- **Repo:** Gitea `electron-rare/clement-saillant-cc`.
|
||||||
|
- **Host:** Tower — static build served by an nginx container,
|
||||||
|
Traefik labels, hostname `clement.saillant.cc` added to the existing
|
||||||
|
cloudflared tunnel ingress (same path as mastodon.saillant.cc,
|
||||||
|
2026-07-08).
|
||||||
|
- DNS already resolves (Cloudflare proxied); currently 404 because no
|
||||||
|
ingress rule exists.
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
- **vitest**: bus progression logic, stop activation, content config
|
||||||
|
integrity (every link has href + label; Mastodon link has rel=me).
|
||||||
|
- **Playwright smoke**: page loads, canvas mounts, semantic DOM contains
|
||||||
|
all links, `rel="me"` present in served HTML (fetch raw HTML, not
|
||||||
|
rendered DOM).
|
||||||
|
- **Perf budget**: 60 fps desktop on the M5, acceptable on mid-range
|
||||||
|
mobile; low-poly + instanced components; total JS+assets < ~3 MB
|
||||||
|
gzipped excluding MOD/WASM lazy chunks.
|
||||||
|
|
||||||
|
## Open items (to resolve during implementation)
|
||||||
|
|
||||||
|
- Bandcamp URL for L'Électron Fou.
|
||||||
|
- Final bio text + pixel-art avatar.
|
||||||
|
- Greetings list content.
|
||||||
|
- MOD module choice (original Électron Fou chiptune vs licensed module).
|
||||||
Reference in New Issue
Block a user