From 2b509386eb6c40f7df3028c1c3d30918d0efeac4 Mon Sep 17 00:00:00 2001 From: Felix Klement Date: Sun, 4 Oct 2026 12:55:12 +0200 Subject: [PATCH] comming soon --- README.md | 8 ++ src/components/verifier/ComingSoon.astro | 147 +++++++++++++++++++++ src/components/verifier/SoonHero.astro | 159 +++++++++++++++++++++++ src/data/flags.ts | 5 + src/i18n/ui.ts | 90 +++++++++++++ src/pages/_Verifier.astro | 24 +++- src/pages/de/privacy.astro | 3 + src/pages/privacy.astro | 3 + src/styles/tokens.css | 4 + 9 files changed, 437 insertions(+), 6 deletions(-) create mode 100644 src/components/verifier/ComingSoon.astro create mode 100644 src/components/verifier/SoonHero.astro create mode 100644 src/data/flags.ts diff --git a/README.md b/README.md index 824658b..5031f25 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ npm run check # Astro + TypeScript check | `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. Each drawing is emitted in two groups, the lines that carry its idea and the grid around them, which is what the hover and the reveal act on. | | `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/SoonHero.astro`, `ComingSoon.astro` | The coming-soon version of `/cipherverifier`, shown while `verifierComingSoon` in `src/data/flags.ts` is true: headline with the alpha sign-up beside it, a status strip along the foot of the hero, release path, spec sheet and the first schematic. Copy in `ui.verifier.soon`. | | `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. | | `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. | @@ -43,6 +44,13 @@ npm run check # Astro + TypeScript check - **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. +- **Alpha sign-up.** While `verifierComingSoon` in `src/data/flags.ts` is true, `/cipherverifier` + shows a coming-soon page whose form posts `email`, `consent=yes`, `lang`, + `list=cipherverifier-alpha` and the honeypot `website` to `POST /notify`. The handler is + server-side and not part of this static build. It should store the address with the time of + consent, confirm it by double opt-in, and redirect back with a thank-you. The privacy page + promises deletion after the alpha mail is sent. Set the flag to false to bring back the full + product page. - **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. diff --git a/src/components/verifier/ComingSoon.astro b/src/components/verifier/ComingSoon.astro new file mode 100644 index 0000000..43e0ad0 --- /dev/null +++ b/src/components/verifier/ComingSoon.astro @@ -0,0 +1,147 @@ +--- +import Schematic from './Schematic.astro'; +import { overview } from './diagrams'; +import { t, type Lang } from '../../i18n/ui'; +interface Props { lang: Lang } +const { lang } = Astro.props; +const ui = t(lang); +const s = ui.verifier.soon; +const g = ui.verifier.how.groups[0]; +const pair = overview(g); +/* The step that is current; earlier ones read as passed, later ones as open. */ +const now = 0; +--- +
+
+
+

{s.track.title}

+

{s.track.body}

+
+
    + {s.track.steps.map((step, i) => ( +
  1. +
  2. + ))} +
+
+
+ +
+
+
+

{s.spec.title}

+

{s.spec.body}

+
+
+ {s.spec.rows.map((r) => ( +
+
{r.key}
+
{r.value}
+
+ ))} +
+
+
+
+
+
+
{s.spec.figure}
+
+
+
+ + diff --git a/src/components/verifier/SoonHero.astro b/src/components/verifier/SoonHero.astro new file mode 100644 index 0000000..1ef5acb --- /dev/null +++ b/src/components/verifier/SoonHero.astro @@ -0,0 +1,159 @@ +--- +import { localePath, t, type Lang } from '../../i18n/ui'; +interface Props { lang: Lang } +const { lang } = Astro.props; +const ui = t(lang); +const s = ui.verifier.soon; +const n = s.notify; +--- +
+
+
+

{s.eyebrow}

+

+ {s.title.map((line, i) => 0 }]}>{line})} +

+

{s.lead}

+
+ + + + +
+
{s.status.label}
+ {s.status.rows.map((r) => ( +
+
{r.key}
+
{'live' in r && r.live &&
+
+ ))} +
+
+
+ + diff --git a/src/data/flags.ts b/src/data/flags.ts new file mode 100644 index 0000000..107366d --- /dev/null +++ b/src/data/flags.ts @@ -0,0 +1,5 @@ +/* Site-wide switches. Flip a flag and rebuild; nothing else needs to change. */ + +/* While true, /cipherverifier shows the coming-soon page with the alpha sign-up instead of the + full product page. The full page (src/components/verifier/*) is kept as it is. */ +export const verifierComingSoon = true; diff --git a/src/i18n/ui.ts b/src/i18n/ui.ts index 104f15e..7ad4ba9 100644 --- a/src/i18n/ui.ts +++ b/src/i18n/ui.ts @@ -215,6 +215,51 @@ const en = { body: 'Bring a repository you know well, and we will show you what CipherVerifier makes of it: what it finds, what it rules out, and why.', cta: 'Talk to us', }, + soon: { + eyebrow: 'Product', + title: ['CipherVerifier.', 'Coming soon.'], + lead: 'A self-hosted verification pipeline for software. Currently in a closed demonstrator phase.', + status: { + label: 'System status', + rows: [ + { key: 'Phase', value: 'Closed demonstrator', live: true }, + { key: 'Next', value: 'Alpha release' }, + { key: 'Deployment', value: 'Self-hosted' }, + ], + }, + notify: { + title: 'Register for the alpha.', + body: 'One email when the first alpha is released. Nothing else.', + email: 'Work email', + placeholder: 'name@company.com', + consent: 'CipherCell may store my email address to notify me about the CipherVerifier alpha. I can withdraw this at any time.', + privacy: 'Privacy policy', + submit: 'Register', + }, + track: { + title: 'Release path.', + body: 'Access opens in stages. Registered addresses hear first when it moves.', + steps: [ + { state: 'Now', name: 'Closed demonstrator', body: 'Running in a closed setting, by invitation only.' }, + { state: 'Next', name: 'Alpha', body: 'The first release outside the demonstrator. Registered addresses are told first.' }, + { state: 'Later', name: 'General availability', body: 'Date to follow.' }, + ], + }, + spec: { + title: 'What is being built.', + body: 'CipherVerifier takes a repository, runs seventeen static analysers and two bill-of-materials generators over it, reads each finding in its context and ranks what is real by security impact.', + rows: [ + { key: 'Static analysers', value: '17, each in its own container' }, + { key: 'Languages', value: '14, plus Docker, Kubernetes, Helm, Terraform and CloudFormation' }, + { key: 'Bill of materials', value: '2 generators, merged into one CycloneDX document' }, + { key: 'Vocabulary', value: '970 CWE entries' }, + { key: 'Pipeline', value: '5 stages, each switchable per repository' }, + { key: 'Review', value: 'Two-stage verdict on every finding' }, + { key: 'Deployment', value: 'Self-hosted' }, + ], + figure: 'Figure 1. One run, five stages.', + }, + }, }, team: { title: ['Researchers,', 'engineers,', 'architects.'], @@ -451,6 +496,51 @@ const de: typeof en = { body: 'Bringen Sie ein Repository mit, das Sie gut kennen, und wir zeigen Ihnen, was CipherVerifier daraus macht: was es findet, was es ausschließt, und warum.', cta: 'Sprechen Sie mit uns', }, + soon: { + eyebrow: 'Produkt', + title: ['CipherVerifier.', 'Demnächst.'], + lead: 'Eine selbst gehostete Verifikations-Pipeline für Software. Derzeit in einer geschlossenen Demonstratorphase.', + status: { + label: 'Systemstatus', + rows: [ + { key: 'Phase', value: 'Geschlossener Demonstrator', live: true }, + { key: 'Als Nächstes', value: 'Alpha-Release' }, + { key: 'Betrieb', value: 'Selbst gehostet' }, + ], + }, + notify: { + title: 'Für die Alpha registrieren.', + body: 'Eine E-Mail, sobald die erste Alpha erscheint. Sonst nichts.', + email: 'Geschäftliche E-Mail', + placeholder: 'name@firma.de', + consent: 'CipherCell darf meine E-Mail-Adresse speichern, um mich über die Alpha von CipherVerifier zu benachrichtigen. Ich kann dies jederzeit widerrufen.', + privacy: 'Datenschutzerklärung', + submit: 'Registrieren', + }, + track: { + title: 'Weg zum Release.', + body: 'Der Zugang öffnet sich in Stufen. Registrierte Adressen erfahren zuerst, wenn es weitergeht.', + steps: [ + { state: 'Jetzt', name: 'Geschlossener Demonstrator', body: 'Läuft in einem geschlossenen Rahmen, nur auf Einladung.' }, + { state: 'Als Nächstes', name: 'Alpha', body: 'Das erste Release außerhalb des Demonstrators. Registrierte Adressen erfahren es zuerst.' }, + { state: 'Später', name: 'Allgemeine Verfügbarkeit', body: 'Termin folgt.' }, + ], + }, + spec: { + title: 'Was entsteht.', + body: 'CipherVerifier nimmt ein Repository, lässt siebzehn statische Analysewerkzeuge und zwei Stücklisten-Generatoren darüber laufen, liest jeden Fund in seinem Kontext und ordnet, was echt ist, nach Sicherheitsrelevanz.', + rows: [ + { key: 'Statische Analyse', value: '17 Werkzeuge, jedes im eigenen Container' }, + { key: 'Sprachen', value: '14, dazu Docker, Kubernetes, Helm, Terraform und CloudFormation' }, + { key: 'Stückliste', value: '2 Generatoren, zu einem CycloneDX-Dokument zusammengeführt' }, + { key: 'Vokabular', value: '970 CWE-Einträge' }, + { key: 'Pipeline', value: '5 Stufen, jede pro Repository abschaltbar' }, + { key: 'Urteil', value: 'Zweistufig, für jeden Fund' }, + { key: 'Betrieb', value: 'Selbst gehostet' }, + ], + figure: 'Abbildung 1. Ein Lauf, fünf Stufen.', + }, + }, }, team: { title: ['Forschende,', 'Ingenieure,', 'Architekten.'], diff --git a/src/pages/_Verifier.astro b/src/pages/_Verifier.astro index aedf040..931d553 100644 --- a/src/pages/_Verifier.astro +++ b/src/pages/_Verifier.astro @@ -6,6 +6,9 @@ import HowItWorks from '../components/verifier/HowItWorks.astro'; import Cards from '../components/verifier/Cards.astro'; import Facts from '../components/verifier/Facts.astro'; import Outro from '../components/verifier/Outro.astro'; +import SoonHero from '../components/verifier/SoonHero.astro'; +import ComingSoon from '../components/verifier/ComingSoon.astro'; +import { verifierComingSoon } from '../data/flags'; import { t, type Lang } from '../i18n/ui'; interface Props { lang: Lang } @@ -13,10 +16,19 @@ const { lang } = Astro.props; const ui = t(lang); --- - - - - - - + {verifierComingSoon ? ( + <> + + + + ) : ( + <> + + + + + + + + )} diff --git a/src/pages/de/privacy.astro b/src/pages/de/privacy.astro index c4d2bc1..59cedcd 100644 --- a/src/pages/de/privacy.astro +++ b/src/pages/de/privacy.astro @@ -17,6 +17,9 @@ const ui = t('de');

Kontaktaufnahme

Wenn Sie uns per E-Mail oder auf anderem Wege kontaktieren, speichern wir Ihre übermittelten personenbezogenen Daten (z. B. Name, E-Mail-Adresse, Inhalt der Nachricht), um Ihre Anfrage zu bearbeiten. Diese Daten werden ausschließlich für die Kommunikation mit Ihnen verwendet und nicht an Dritte weitergegeben. Rechtsgrundlage für die Verarbeitung der Daten ist Art. 6 Abs. 1 lit. b DSGVO (Anbahnung eines Vertragsverhältnisses) oder Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an der Bearbeitung der Anfrage).

+

Benachrichtigung zur CipherVerifier-Alpha

+

Wenn Sie sich für die Benachrichtigung zur Alpha von CipherVerifier eintragen, speichern wir Ihre E-Mail-Adresse und den Zeitpunkt Ihrer Einwilligung, um Ihnen mitzuteilen, wann die erste Alpha veröffentlicht ist. Wir nutzen sie für nichts anderes und geben sie nicht an Dritte weiter. Rechtsgrundlage ist Ihre Einwilligung nach Art. 6 Abs. 1 lit. a DSGVO. Sie können Ihre Einwilligung jederzeit per E-Mail an office@ciphercell.de widerrufen; wir löschen Ihre Adresse dann. Nach dem Versand der Benachrichtigung löschen wir sie ebenfalls.

+

Recht auf Auskunft, Berichtigung, Sperrung oder Löschung

Nach dem anwendbaren Datenschutzrecht haben Sie ein Recht auf unentgeltliche Auskunft über Ihre gespeicherten Daten sowie ggf. ein Recht auf Berichtigung, Sperrung oder Löschung dieser Daten. Wenden Sie sich bei weitergehenden Fragen zum Datenschutz und zur Verarbeitung Ihrer personenbezogenen Daten, bei Auskünften oder zur Ausübung Ihres Rechts auf Berichtigung, Sperrung oder Löschung oder für den Fall des Widerrufs einer Einwilligung bitte per E-Mail an office@ciphercell.de. Selbstverständlich können Sie auch die im Impressum angegebenen Kontaktdaten oder das Kontaktformular auf der Website nutzen. CipherCell verarbeitet und nutzt die von Ihnen mitgeteilten Informationen ausschließlich für die Bearbeitung Ihres Anliegens.

diff --git a/src/pages/privacy.astro b/src/pages/privacy.astro index 951e1df..bacd1d6 100644 --- a/src/pages/privacy.astro +++ b/src/pages/privacy.astro @@ -17,6 +17,9 @@ const ui = t('en');

Contact

If you contact us by email or other means, we will store the personal data you provide (e.g. name, email address, content of the message) in order to process your request. This data will be used exclusively for communication with you and will not be passed on to third parties. The legal basis for processing the data is Art. 6 para. 1 lit. b GDPR (initiation of a contractual relationship) or Art. 6 para. 1 lit. f GDPR (legitimate interest in processing the request).

+

CipherVerifier alpha notification

+

If you register for the CipherVerifier alpha notification, we store your email address and the time of your consent in order to tell you when the first alpha is released. We use it for nothing else and do not pass it on to third parties. The legal basis is your consent under Art. 6 para. 1 lit. a GDPR. You can withdraw your consent at any time by email to office@ciphercell.de; we then delete your address. We also delete it once the notification has been sent.

+

Right to information, correction, blocking, or deletion

Under applicable data protection law, you have the right to obtain information about your stored data free of charge and, if necessary, the right to correct, block, or delete this data. If you have any further questions about data protection and the processing of your personal data, if you require information, or if you wish to exercise your right to correction, blocking, or deletion, or in the event of revocation of consent, please send an email to office@ciphercell.de. You can also use the contact details provided in the legal notice or the contact form on the website. CipherCell processes and uses the information you provide exclusively for the purpose of processing your request.

diff --git a/src/styles/tokens.css b/src/styles/tokens.css index 07ced49..fc1be88 100644 --- a/src/styles/tokens.css +++ b/src/styles/tokens.css @@ -30,6 +30,10 @@ --field-slate: #3A4862; --field-plum: #66508E; + /* Signal: the one status tone the brief allows. Used only for a live state (the coming-soon + page's current phase), at most twice per page. Never for text, links or decoration. */ + --signal: #58C8D8; + /* Immutable copies for resetting inside a .night or overlay context */ --ink-base: #1A1A18; --ink-muted-base: #57564F;