cyberine
Design notes

ARCHIVED — Plasma home + "Six Instruments" routes (2026-08-27 to 2026-10-01)

Superseded on 2026-10-01 by website-master.md, the "run record" direction. Kept as the record of what was locked and why. Why it ended: on 2026-10-01 the operator compared four rendered site versions built from different evidence and picked the one that reads as a run record over this one. Plasma survives in the TUI and the web dashboard.

Read this before any website work. It replaces website-master-20260827-parallel-cut.md, which was rejected at prototype the same day it was written — read its post-mortem before proposing anything, because it records what already failed.

Process, and why this file is deliberately incomplete

The previous MASTER was written complete, from written proposals and ASCII wireframes, and locked a direction the user could not visualize from a terminal. It died at first render. The rule that replaced it:

Render first, lock second. Nothing enters this file until the user has seen it in a browser and picked it.

This file grew in stages, each one rendered and approved before being written down. The palette was picked from a rendered comparison of six schemes shown in use. The structure was picked from a navigable six-route prototype. Nothing here was locked from prose.

Palette — LOCKED 2026-09-25: Plasma

The operator rejected Mineral/Sulfur on 2026-09-22 and picked Plasma from four rendered dark schemes (Ion, Plasma, Ember, Aurora) for the marketing site: "toi thich plasma cho marketing site". Dark is primary. The site stays theme-aware, so Plasma ships with a light companion derived from the same hues; a screenshot or mark legible in only one mode is still a defect (T672). Every text role is WCAG AA-body (>= 4.5:1) against base, surface and lift of its own mode, measured, and scripts/qa.mjs re-checks the same table on every run.

RoleDark "Plasma"ratio base/surf/liftLight companionratio base/surf/lift
base#0A0616—#F6F2FD—
surface#130C26—#FDFBFF—
lift#1D1338—#ECE4FA—
ink#EFE9FA16.85 / 15.98 / 14.72#170D2E16.80 / 18.02 / 15.04
action#C77DFF violet7.43 / 7.04 / 6.49#7A2BD16.15 / 6.60 / 5.51
second#FF4FD8 magenta7.01 / 6.64 / 6.12#A3137F6.44 / 6.91 / 5.76
verified#4FF0C0 mint13.86 / 13.14 / 12.11#00705A5.49 / 5.89 / 4.92
refute#FF7A7A7.92 / 7.50 / 6.92#B423355.89 / 6.32 / 5.27
muted#9D90B86.77 / 6.42 / 5.92#5B4F746.76 / 7.25 / 6.05

The primary button is base text on action fill (7.43:1 dark, 6.15:1 light). second is the new role: magenta for secondary emphasis (the hero's orbit ring, terminal labels), never for a verdict. verified stays the winner colour in both modes, and colour is still never the sole signal: every pass/reject state carries a text verdict too. color-scheme is declared on :root in both modes.

The alternates stay on file in .local/design/2026-09-22-site-redesign-options.m3max.md; the old Mineral/Sulfur table is in git history.

Typography — LOCKED 2026-09-25

Display Sora (weights 400-700), body Geist (400-600), mono Geist Mono (400-500), all SIL OFL, self-hosted by site/scripts/fetch-fonts.mjs, which verifies the license from each family's METADATA.pb before downloading. They are exposed as --cyb-font-display, --cyb-font-body and --cyb-font-mono; no component names a family directly. Headlines are moderate and sentence case (.dsp: Sora 600, -0.025em), never poster-sized, per the 2026-09-22 brief.

Home page — LOCKED 2026-09-25

/ is the approved conventional dev-tool landing from the Plasma prototype, in this order: fixed nav, hero (three.js decoration behind DOM text, dotted scrim, word-by-word headline reveal), a tilted terminal replaying a REAL recorded run, a four-card bento, "one engine, four ways in" tabs (the fleet TUI and dashboard tabs show the real T697 captures), four-step how-it-works, four judges, a worker marquee, final CTA. Every claim on it was checked against source on 2026-09-25: the install line is the git clone (the npm package is not published), the terminal lines are trimmed from run 81cbc07c, the worker names come from the live registry, and "open source" was dropped because the repository is private.

Motion: Lenis inertial scroll on marketing routes only; hero camera intro, damped pointer and scroll parallax; blurred reveals on scroll. Under prefers-reduced-motion the hero renders one static frame, Lenis never starts, reveals and the terminal tilt are removed and every perspective flattens. Bloom runs in dark mode only; the light companion renders the scene without it.

The other five routes keep their structure from the Six Instruments lock below and inherit the new palette and type.

Structure — LOCKED 2026-08-27

Six marketing routes, each with a different spatial idea. Approved by the user from a rendered, navigable prototype.

How this was arrived at, because the reasoning constrains future changes

Five single-page layout skeletons were rendered first (Ledger 5/7, full-width Bands, sticky Split, centered Editorial, left Rail) and all five were rejected. The user's words were "thiếu 1 cái slider, 3d, animation, stunning 3d etc." — and that was misread as a feature list. It was not. The correction: "Mấy cái tôi nói là suggestion, không phải kêu bạn add các sec đó vào. Hiện tại layout chỉ trong 1 page, rất boring."

So the real defect was structural: the entire marketing surface was ONE route. A slider and a WebGL hero bolted onto one long scroll is still one long scroll.

The cure for boring is variety of STRUCTURE, not added effects. Six routes, six different skeletons. Do not "simplify" this back into one page with more effects — that is the exact mistake this structure replaced.

The governing rule

The whole site is ONE dispatch, examined from six angles. Every route carries the same runId in its footer readout and states its own angle: — the race, the pipeline, the verdict, the roster, the windows, the meter. Six skeletons, one run.

That single shared element is what lets six deliberately dissimilar layouts read as one site instead of six templates.

The routes

RouteSpatial ideaWhat makes it unlike its neighbours
/The viewport IS the race track. Strips run edge to edge with no container; display type sits ON themnothing centred, nothing carded
/how-it-worksA stage rail PINS while the evidence scrolls past itthe only route with sticky + scroll state
/judgesAsymmetric four-up where panel AREA encodes load-bearing weight — DiffJudge takes double, being the only judge that gates on machine-checkable evidencesize carries meaning; an equal grid would be the pricing-table failure again
/providersA dense data table, mono, including all seven retired workers with dates and reasonsthe only deliberately dense route, placed after four airy ones
/surfacesSix panes offset in Z inside a CSS 3D perspectivethe only route with real depth
/costOne enormous figure owning the viewport, plus one barthe only near-empty route

/surfaces: CSS 3D, not WebGL — and why

The depth is built from CSS 3D transforms on real DOM elements. This is a deliberate trade, not timidity: there is no shader, no triangle budget, and nothing to fall back from. Text stays selectable, every pane is tab-reachable, and a screen reader reads an ordinary list. A WebGL canvas is invisible to assistive tech and would need its entire accessibility story rebuilt by hand.

Known shortfall: at rotateX(12deg) rotateZ(-1deg) the effect reads as "slightly tilted rows" more than "windows stacked in depth".

DECIDED 2026-08-28 — the hybrid, not a swap. three.js may be used for DECORATION ONLY: a canvas behind or around the panes. Every word of content stays real DOM on top of it. The 3D scene may never contain text or be the only carrier of information.

Why this and not full three.js: a <canvas> is pixels, so the browser cannot know there is text inside it. Full three.js would cost the screen reader, Tab traversal, Ctrl+F, text selection, browser zoom, Google Translate, AND search-engine indexing — the last one being disqualifying on a marketing page. Recovering any of that means hand-authoring a parallel hidden DOM of the same content plus manual keyboard handling plus ARIA, then keeping both copies in sync forever. That is real work and it rots.

The hybrid keeps text as text and buys the lighting, material, and true-depth qualities CSS transforms cannot reach. Where the canvas fails to load or prefers-reduced-motion is set, the page must still be complete without it.

Motion

Named personality: "instrument settling" — arrives fast, resolves once, never oscillates. Nothing orbits, nothing glows, nothing loops forever. Only transforms and opacity animate.

Tokens live in tokens.css and are referenced BY NAME; no bare ms or cubic-bezier literal belongs in component code.

TokenValueCharacter
--cyb-ease-entercubic-bezier(0.16, 1, 0.3, 1)expo-out: arrives fast, settles without overshoot
--cyb-ease-exitcubic-bezier(0.7, 0, 0.84, 0)expo-in: leaves decisively
--cyb-ease-onscreencubic-bezier(0.4, 0, 0.2, 1)even, deliberate, no drama
--cyb-ease-snapcubic-bezier(0.22, 1, 0.36, 1)one hard step, critically damped
--cyb-dur-micro / -fast / -base / -slow / -scenic / -hold120 / 200 / 320 / 520 / 900 / 180 mshover -> full resolution

Never linear, never a bouncy spring, never transition: all.

Reduced motion: the resolved final state renders immediately; the 3D perspective flattens entirely; fades survive, every transform-based entrance is dropped.

Spacing

Base 4px, geometric, in tokens.css as --cyb-space-0 through --cyb-space-8 (4/8/12/16/24/32/48/72/112). --cyb-space-3 (16px) is the hard floor for panel inner padding on all four sides. Role bindings: --cyb-pad-page, --cyb-gap-stack, --cyb-gap-section, dropping one step at phone width.

Verified evidence — 2026-08-27

Measured, not asserted:

  • detect-slop.mjs --surface marketing over all 9 site files: 0 HIGH / 0 MEDIUM / 0 LOW.
  • layout-audit.js across 36 combinations (6 routes x 360/768/1280 x light/dark), 0 errored: 0 real HIGH findings.
  • One real HIGH was found and fixed: every /surfaces pane bled 5-27px outside #deck because a cosmetic translateX accompanied the translateZ. Depth is carried by Z alone; the X offset is gone and #deck is padded to absorb the perspective spread.
  • / had a horizontal overflow where a fixed 11rem nowrap note column pushed text past the right edge. Fixed to auto with a minmax(0,1fr) track; re-measured horizontal overflow 0px.

Two layout-audit false-positive classes — do not "fix" these

Verified by hand-measuring rects. Both are limitations of the tool on this structure, not defects in the pages, and they account for 40 of the raw findings:

  1. stack-overlap on a 2D grid. judges.html reported .j--adv overlapping .j--llm by 229px. Measured: hOverlap = -1px, vOverlap = 229px — they sit side by side with a 1px gap. The check compares only vertical rects between document-order siblings and never tests horizontal separation, so any grid cell spanning two rows trips it.
  2. misaligned-top on center-aligned rows. a.nav-brand reported a 6px top drift in 24 of 36 combos. Measured: both centres at exactly 28px; the boxes differ in height (20px vs 33px) because the links carry padding. With align-items: center this is correct.

Remaining MEDIUMs, explicitly justified: a 2px left drift between h2 (Martian Mono) and .kind (Archivo) inside a pane, which is font side-bearing rather than layout; and the /cost cap marker deliberately protruding 8px above and below its bar so the cap line is visible.

Task kx7dm (make the QA pass a committed script) should encode these two filters with their justification, so a future run does not re-litigate 40 findings.

Docs surface at reduced boldness

Shared: the full role-token palette, all three typefaces, the spacing scale, and the motion personality reduced to hover and focus only.

Dropped: every scroll-triggered move, the CSS 3D perspective, and the display-scale Archivo setting. Docs pages load fully composed. Density rises one step; line length stays 60-75ch.

Restyling later

Archive this file as website-master-<yyyymmdd>-<slug>.md with a post-mortem, and write a fresh one. Never edit it into a different direction in place.