This commit is contained in:
Felix Klement committed 2026-10-04 22:29:17 +02:00
1 parent cc41849cf5
commit f84687d745
22 files changed
+555 -14

No files matched your search

+30 -4
View File
@@ -26,7 +26,8 @@ docker run --rm -p 8080:80 ciphercell # http://localhost:8080
In Dokploy: create an Application from this repository, set Build Type to **Dockerfile**
(path `Dockerfile`), and under Domains add the domain with container port **80** and HTTPS on.
TLS is handled by Dokploy's Traefik.
TLS is handled by Dokploy's Traefik. The contact form needs the SMTP variables under
Environment; see *Contact form* below.
## Where things live
@@ -43,6 +44,7 @@ TLS is handled by Dokploy's Traefik.
| `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: hero on a build-time SVG relief of ridge lines in the logo blues, under the floating header, "Coming soon." with the alpha sign-up beside it, a status strip, and the product name set across the full width and cut by the hero's lower edge, 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. |
| `server/contact.mjs` | The contact form handler: validates, rate-limits and sends by SMTP. Its own `package.json`, so the image only carries nodemailer. |
| `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. |
@@ -56,9 +58,33 @@ TLS is handled by Dokploy's Traefik.
## 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.
- **Contact form.** The form posts `first_name`, `last_name`, `email`, `message`, `lang` and a
honeypot field `website` to `POST /contact`. That one path is handled by `server/contact.mjs`
(Node, nodemailer), which sends the message by SMTP to `CONTACT_TO` with the sender as
Reply-To. With scripting the form sends in place and shows the result under the button;
without, the handler redirects to `/contact/sent` or `/contact/error` (under `/de` for German).
Both pages are `noindex` and left out of the sitemap. The handler caps size and field lengths,
refuses cross-site posts, and allows 5 messages per address per 10 minutes and 60 per hour
overall.
In the container, nginx proxies `/contact` to the handler on `127.0.0.1:3000`; both are started
by `docker/entrypoint.sh`, which restarts the handler if it crashes. If the handler is down,
visitors are sent to the error page. Without SMTP settings the handler does not start and the
rest of the site is served as usual.
| Variable | Default | Purpose |
|---|---|---|
| `SMTP_HOST` | (required) | Mail server. |
| `SMTP_PORT` | `587` | `587` uses STARTTLS (required), `465` TLS from the start. |
| `SMTP_USER`, `SMTP_PASS` | | Login. Leave unset for a server without authentication. |
| `CONTACT_FROM` | `SMTP_USER` | Sender address; must be one the SMTP account may send as. |
| `CONTACT_TO` | `office@ciphercell.de` | Where messages go. |
| `SMTP_SECURE` | by port | Force TLS from the start (`true`) or not (`false`). |
| `SMTP_REQUIRE_TLS` | `true` | `false` only for a local mail catcher. |
In Dokploy, set these under the application's Environment. Locally, put them in `.env` (see
`.env.example`), run `npm run contact` next to `npm run dev`; the dev server proxies `/contact`
to it.
- **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