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
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 four wireframe objects on the stage cards (sphere, cube, plane, wave). Geometry is computed at build time; single stroke in --ink. |
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). |
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,messageand a honeypot fieldwebsitetoPOST /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 insrc/layouts/Base.astroif 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.
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
Technologyenum inrayfusion/plugins/base.py. The security profile is described indocs/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 aredeptrace/commands. - Git providers, archive upload, CI webhook, scoped settings, live pipeline, PDF report and artefacts
are the
cipherverifierDjango app; the installer iscvm.
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.