144 lines
9.6 KiB
Markdown
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.
|