Files
homepage_relaunch/README.md
T
2026-09-18 19:25:48 +02:00

144 lines
9.6 KiB
Markdown

# CipherCell homepage relaunch
Static site for www.ciphercell.de, built with Astro. Design foundation: `CLAUDE.md`
(European deep-tech minimalism: warm paper, one neo-grotesque, hairlines, no accent colour).
## Run
```sh
npm install
npm run dev # http://localhost:4321
npm run build # static output in dist/
npm run preview # serve dist/
npm run check # Astro + TypeScript check
```
## Where things live
| Path | Purpose |
|---|---|
| `src/styles/tokens.css` | Every colour, type step, spacing, radius and duration. Components use only these. |
| `src/styles/base.css` | Font faces, reset, focus ring, primitives (`.container`, `.grid`, `.section`, `.prose`, `.link`, `.button`). |
| `src/i18n/ui.ts` | All interface copy, English and German, one object per language with the same shape. |
| `src/data/team.ts` | Team members, roles, portraits, links. |
| `src/content/insights/*.md` | Insights posts (content collection). Front matter: title, date, lang, category, readingTime, author, cover. |
| `src/components/home/*` | One file per home section, in page order: Hero, Manifesto, Method (with `MethodDiagram`), Stages (with `GridObject`), Sectors, Proof, Quote, Insights, Contact. |
| `src/components/home/GridObject.astro` | The wireframe objects on the stage and product cards (sphere, cube, plane, wave, steps, nested, stack). Geometry is computed at build time; single stroke in `--ink`. Each drawing is laid out by hand, so the `viewBox` is derived from the points as they are emitted, not assumed: a square centred on the drawing, padded for the stroke. A new kind can therefore never be clipped, and the card gives the drawing the flexible row so it sits centred between title and body. |
| `src/components/home/MethodDiagram.astro` | The four-stage loop, wide and tall compositions. Labels come from `ui.method.stages`. |
| `src/components/verifier/*` | The CipherVerifier product page, in page order: Hero (line burst), Intro (image band), HowItWorks (five group cards, one schematic each; on wide screens the heading is sticky and the cards stack under it as you scroll), Cards, Facts, Outro. |
| `src/components/verifier/diagrams.ts` | The five schematics as data: a hand-placed wide layout and an auto-generated tall spine per group. `Schematic.astro` renders either. Labels come from `ui.verifier.how.groups`; the tuple shape is in `types.ts`. Every element carries the `group` of the node it belongs to, which drives the hover focus and the draw-in order. |
| `src/scripts/reveal.ts` | Marks `[data-animate]` drawings as drawn once they scroll into view. The drawings' own CSS turns that into the plotter-style reveal, wide screens only, off under `prefers-reduced-motion`. |
| `scripts/*.mjs` | Review tooling: `shot.mjs` (full page), `scroll-shots.mjs` (viewport by viewport), `tabs-test.mjs` (keyboard test for the sectors tabs), `contact-sheet.mjs`. Need `npx astro preview --port 4322`. |
| `src/pages/_*.astro` | Shared page bodies. `index.astro` and `de/index.astro` render `_Home.astro` with a `lang` prop, and so on. |
| `src/assets/images/` | Source images. Astro emits AVIF with a WebP fallback and explicit dimensions. |
| `public/fonts/` | Self-hosted Inter Tight variable (latin, latin-ext). |
| `public/video/` | The home hero's background loop, MP4 and WebM. Shipped as-is; Astro does not process video. |
## Routes
`/`, `/cipherverifier`, `/team`, `/insights`, `/insights/<slug>`, `/imprint`, `/privacy`, `/404` and the same under `/de`.
`hreflang` alternates and a sitemap are generated. The language switch sits in the footer.
## Things the host has to provide
- **Contact form.** The form posts `first_name`, `last_name`, `email`, `message` and a honeypot
field `website` to `POST /contact`, as the current site does. The handler is server-side and
not part of this static build.
- **Matomo.** The privacy page links to the existing opt-out on `cipher.uber.space`. The tracking
snippet itself is not included; add it in `src/layouts/Base.astro` if analytics should continue.
## Adding a post
Create `src/content/insights/<slug>.md` with the front matter used in `xg-aloe-user-forum.md`.
Put the cover image in `src/assets/images/` and reference it with a relative path.
The three newest posts appear on the home page automatically.
## The hero video
The home hero plays `public/video/hero-plant.mp4` / `.webm` behind the headline, over the
`plant-at-dusk.jpg` still. The still is the video's own first frame, so it carries the hero until
the video is ready and stays put for anyone who never gets one.
The video is only fetched when it will be seen: not under `prefers-reduced-motion`, not on
`saveData`, and not below 48rem, where a 21:9 frame would be cropped to a sliver for the most
expensive bytes. The sources are attached by script rather than in the markup, so nothing is
requested otherwise. A blocked autoplay also just leaves the still in place.
The source clip was generated with Magnific (Kling 2.5, 10 s, from the hero still as its start
frame, https://www.magnific.com/app/creation/5jPaI3qKxe). `scripts/encode-hero-video.sh` turns a
clip into the looping file: it plays forward, then backward, so the loop point cannot be seen, and
encodes 1920-wide H.264 and VP9. A 20-second loop lands at 862 KB and 472 KB. To replace it:
```sh
FFMPEG=/path/to/ffmpeg ./scripts/encode-hero-video.sh source.mp4 public/video/hero-plant 1920
```
Keep the first frame of any replacement equal to `plant-at-dusk.jpg`, or replace both together.
## Imagery
The mast at dusk (`mast-at-dusk.jpg`) is the one documentary photograph from the old site; it
remains the cover of the first post. The five other scene images were generated with Magnific
(Seedream 5 Pro) on 18 September 2026 in a desaturated documentary style, because no real
photography existed:
| File | Used in | Magnific creation |
|---|---|---|
| `plant-at-dusk.jpg` | Hero | https://www.magnific.com/app/creation/DoQZmiipcl |
| `engineer-glass.jpg` | Method section | https://www.magnific.com/app/creation/3zdScUIREY |
| `sector-5g.jpg` | Sectors, tab 1 | https://www.magnific.com/app/creation/s7ZQP52l8e |
| `sector-substation.jpg` | Sectors, tab 2 | https://www.magnific.com/app/creation/yi0r27vPW9 |
| `sector-datacentre.jpg` | Sectors, tab 3 | https://www.magnific.com/app/creation/eIHAvetdqL |
They are placeholders in the sense of the brief: swap them for the company's own documentary
photography when it exists, keeping the same file names and the `img-doc` treatment. The grid
objects on the stage cards were prototyped as a Magnific sheet
(https://www.magnific.com/app/creation/aFsD5crfSh) and then rebuilt as procedural SVG so the
stroke matches the rest of the site.
## Product page
`/cipherverifier` describes the pipeline in `product_repo/monocipher` (mounted for reference, ignored
by git). Everything on the page was read from that repository on 18 September 2026:
- The five stages and their order come from `orchestrator/pipeline_plan.py`.
- The seventeen analysers are rayfusion's built-in plugins plus converters; the fourteen languages
are the `Technology` enum in `rayfusion/plugins/base.py`. The security profile is described in
`docs/rayfusion-rule-policy.md`.
- The two-stage classification, escalation rules, budgets and replay-validated cache are from
`docs/polygraph-classification-pipeline.md`.
- 970 is the number of entries in `sarifcombiner/cwe_information.json`.
- SBOM merging (Syft and cdxgen, package-URL deduplication, CycloneDX 1.6) is `spectograph/backend`,
Dependency-Track upload and the ephemeral container are `deptrace/commands`.
- Git providers, archive upload, CI webhook, scoped settings, live pipeline, PDF report and artefacts
are the `cipherverifier` Django app; the installer is `cvm`.
When the product changes, update `ui.verifier` (copy and diagram labels) and, if a stage or tool is
added, the layouts in `diagrams.ts`. All five schematics are on the page; `scroll-shots.mjs` renders
them for review.
## Interaction and motion
Three islands of script: the mobile navigation toggle in `Header.astro`, the sectors tabs in
`Sectors.astro` (`src/scripts/tabs.ts`: ARIA tablist, arrow keys, Home and End), and the reveal
observer used by the product page's drawings.
Motion on the product page, all of it on wide screens: the hero's seventeen lines draw in on load
and meet in one point (off under `prefers-reduced-motion`); hovering a node in a schematic dims
everything that does not belong to it. The drawings themselves do not animate.
The "How CipherVerifier works" cards are `position: sticky` with a growing top offset, so they
stack into a deck under the pinned heading. Every card has the same height, bound to the viewport
and capped at 37rem, and the drawing fills what the text leaves, so a card always fits and fully
covers the one beneath it. The page snaps to each card (`scroll-snap-type: y proximity` on the
root while this component is on the page, `scroll-snap-stop: always`) via invisible anchors placed
at each card's natural position: snapping to the sticky cards themselves would create phantom snap
points at the current offset in Chrome. The pinned bar carries one dot per card; the filled one is
the card currently on top, and each dot links to its card. A small script sets `--covered` on each
card as the next one slides over it (the card darkens under an opaque veil) and moves the filled
dot. The heading is pinned inside a track that ends one card before the deck does, so heading and
deck leave the screen together. Phones get the same drawings in a plain flow without any of this. This goes
beyond the home page's single load moment on purpose, at the client's request; the home page is
unchanged. Without JavaScript every sector panel
and its image is shown in full; the `html.js` class set in `Base.astro` switches to one at a time.