Public Access
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
94 lines
11 KiB
Markdown
94 lines
11 KiB
Markdown
# W1: Website
|
|
|
|
**Status:** phase 1 is built and checked in a browser (branch `site`, pull request to follow); the Install page works against the real server once Caddy allows the origin (below). Issue #12.
|
|
|
|
**Goal:** a public home for the project at **roro9stack.net**, separate from the blog (stories) and from Gitea (developers): what it is, how to install it, how to use each App, and the docs.
|
|
|
|
The home page was designed on a canvas in a Claude chat (a dark and a light theme, built on the device's own 256-colour palette, pixel-notched corners, DM Mono and Hanken Grotesk). It is the starting point, not the final copy: it has to say only what the firmware does today.
|
|
|
|
## What was found while planning (2026-10-06)
|
|
|
|
- `roro9stack.net` already points at the server that hosts Gitea. Plain HTTP redirects to HTTPS; HTTPS has no certificate yet, which is the server's side to set up.
|
|
- **Release downloads from Gitea carry no CORS header,** so a browser can't fetch the factory image from another origin as things are. Gitea is behind Caddy, which can add the header (below).
|
|
- Zola can read JSON from a URL at build time (`load_data`), so the home page's "latest version" can come from the Gitea API.
|
|
- There is no Gitea wiki: the design's "Wiki" links would 404.
|
|
- The blog is published by pulling its repository on the web server and running `zola build`. The site does the same.
|
|
|
|
## Decisions (design round 2026-10-06)
|
|
|
|
| # | Decision |
|
|
|---|---|
|
|
| Q175 | The site lives in this repository, in `site/`, so the documentation is built from `docs/`, `CONTEXT.md` and the README instead of being copied. |
|
|
| Q176 | **Zola,** like the blog. The design becomes a template, its tokens CSS custom properties. Dark and light follow the visitor's setting, with a visible switch. No JavaScript except the flasher's. |
|
|
| Q177 | Domain: **roro9stack.net.** The blog stays at experiments.twis.la. |
|
|
| Q178 | **Publishing is the blog's way:** the web server pulls `main` and runs `zola build`; that part is the maintainer's. Changes reach `main` through pull requests as everywhere. **CI is split:** a dedicated `site` job builds the site (`zola build`) when `site/`, `docs/`, `README.md` or `CONTEXT.md` change, and the firmware tests and builds skip a change that touches nothing else. A change that touches both runs both. |
|
|
| Q179 | Phases, each its own pull request: **1.** the CI split, the home page, an Install page with the browser flasher, downloads and the changelog. **2.** a user guide page per App. **3.** how-tos and the FAQ. **4.** developer docs generated from the repository. |
|
|
| Q180 | **A browser flasher** (ESP Web Tools), **without copying the firmware.** Caddy, in front of Gitea, adds `Access-Control-Allow-Origin: https://roro9stack.net` (and `Vary: Origin`) to GET and HEAD on `/twisla/roro9stack/releases/download/*` and `/api/v1/repos/twisla/roro9stack/releases*`: both are public already. The Install page asks the API for the latest release in the browser, finds the asset ending `-factory.bin`, and gives ESP Web Tools a manifest built on the spot, so it offers a new release as soon as it exists, with no rebuild. The library is **vendored** into `site/static/` (Apache-2.0), not loaded from a CDN. The file's SHA-256 is shown on the page. Chrome or Edge on a desktop only; other browsers, and visitors without JavaScript, get the `esptool` steps on the same page. |
|
|
| Q181 | Docs for the latest version only. The changelog is the Gitea releases, read at build time. |
|
|
| Q182 | English only. |
|
|
| Q183 | The FAQ starts from real questions: the README, and issues labelled `kind/docs`. |
|
|
| Q184 | Fonts are **self-hosted** (no request to a third party). The hero keeps the design's illustrations, labelled as illustrations, and a section of **real device screenshots** is added. |
|
|
| Q185 | **The site says only what the firmware does today.** Planned features are marked as planned, with their milestone. The mesh messenger is **planned**: the LoRa Scanner listens, nothing is sent. |
|
|
| Q186 | Left out, each with its issue: a Gemini capsule mirror (#57), French (#58), docs per version (#59), search (#60). |
|
|
| Q187 | The site has no version of its own. Contact is **contact@roro9stack.net,** and the issue tracker. |
|
|
|
|
## The design, reviewed
|
|
|
|
Kept as designed: the layout, the tokens, the nine App cards (their facts check out against the code: Probation 3 minutes, Safe Mode after 3 crashes, 60 seconds of typing before an update restarts the device).
|
|
|
|
Changed before it ships:
|
|
|
|
- **Install, not Download, is the first action.** Downloads are for developers; a visitor wants to try it.
|
|
- **A "what you need" strip:** Cardputer ADV, the Cap LoRa-1262 (only the radio needs it), a microSD card, Wi-Fi. And a plain status line: the version, and what isn't there yet.
|
|
- **The mesh card and the hero** no longer promise sending and reading mesh messages.
|
|
- **The latest version is read from the API,** not typed.
|
|
- **"Wiki" is replaced by Docs.** The updates section gains what v0.11.0 added: the device installs releases from the project's server itself.
|
|
- **An independence line:** not affiliated with or endorsed by M5Stack or Meshtastic.
|
|
- **No cookies, no analytics, no third-party requests,** said on the page (fonts self-hosted).
|
|
- **The keyboard focus ring** is invisible on the notched buttons: `clip-path` clips an outline. Another way to show focus is needed.
|
|
- **The wordmark SVGs** carry an embedded C2PA content-credentials block: stripped from the site's copies.
|
|
|
|
## Done when (phase 1)
|
|
|
|
- Pushing a change under `site/` runs the `site` job and not the firmware tests; a firmware change runs the firmware jobs and not the site's.
|
|
- The home page renders in both themes, at phone width, with the keyboard, and says nothing the firmware doesn't do.
|
|
- The latest version on the page is the latest release.
|
|
- The browser flasher installs the latest release on a Cardputer ADV from Chrome (tried by hand), the page shows the file's SHA-256, and the `esptool` steps are on the same page.
|
|
- A release published after the site was built is the one the Install page offers.
|
|
- The home and Downloads pages make no request to another origin, and the Install page only asks git.twis.la.
|
|
|
|
## Work breakdown
|
|
|
|
1. **CI split:** a `site` workflow, path filters on the firmware workflow.
|
|
2. **The skeleton:** `site/` with the tokens, fonts, base template and the theme switch.
|
|
3. **The home page,** from the design, with the changes above.
|
|
4. **Install and downloads:** the flasher with its manifest built in the page, the `esptool` steps, the changelog. Needs the Caddy headers on the Gitea host (the maintainer's side); the page is tested against them once they're in.
|
|
5. **Checks,** recorded here.
|
|
|
|
## As built (phase 1)
|
|
|
|
- **CI is split.** `ci.yml` (the firmware) has `paths-ignore: site/**, docs/**, README.md, CONTEXT.md` on pushes to `main` and on pull requests. `site.yml` runs `zola check` and `zola build` with a Zola pinned by its checksum, then `site/tools/check_site.py`, when those files change. Gitea's own source (v1.24, read, not run against the 1.27 server) shows that path filters count as matched for tag pushes, so a tag still releases. A change that touches both runs both.
|
|
- **The site** is in `site/`: `config.toml`, templates (base, home, install, downloads, 404), `data/` for the App cards and the screenshots' captions, `static/` (stylesheet, theme switch, fonts, wordmark, icons, real screenshots, the vendored flasher). `site/README.md` says how to build it and what the server needs.
|
|
- **The home page** follows the design. Changed from it: the hero and the mesh card promise nothing that isn't built (the mesh messenger is a "planned" card), an Install button first, a status box, a "what you need" row, a section of real screenshots, the updates section says the device installs releases itself, an independence line and a statement about cookies and third-party requests in the footer, the latest version read from the Gitea API at build time, and the nav's Wiki replaced. The two hero drawings are generated by `site/tools/make_illustrations.py` (a port of the design's scripted shapes) as inline SVG.
|
|
- **The focus ring.** `clip-path` clips outlines, so a focused notched control drops its notches and shows square corners and its ring.
|
|
- **The Install page** asks the API for the latest release in the browser, builds the ESP Web Tools manifest as a blob, shows the version, size and SHA-256, and only ever hands the flasher a download from the project's own server for this repository. The flasher library (ESP Web Tools 10.4.0, Apache-2.0) is vendored, trimmed to the ESP32-S3. Fonts (DM Mono, Hanken Grotesk, SIL OFL) are self-hosted.
|
|
- **The Downloads page** lists the last 30 releases with their files, read at build time.
|
|
- **The wordmark SVGs** from the design carried an embedded C2PA content-credentials block; it is removed from the site's copies.
|
|
|
|
## Checks (2026-10-06)
|
|
|
|
| Check | Result |
|
|
|---|---|
|
|
| The Site workflow's own commands, in a clean container with the pinned Zola | `zola check` clean, build and page checks pass |
|
|
| `tools/check_site.py` | 4 pages, 0 problems: titles, descriptions, a language, every image with alt text, every local file referenced exists, nothing loaded from another origin |
|
|
| Browser tests (Chromium, 16 checks) | All pass: no request to another origin from the home, Downloads and 404 pages; no horizontal scroll at 1280 and 390 px; a visible focus ring on a notched button; the Install page reads the latest release, shows its version, size and SHA-256, builds a blob manifest naming an ESP32-S3 factory image at offset 0, and loads only git.twis.la; a download on another host is refused; the real server (no CORS header today) makes the page fall back to the esptool steps |
|
|
| The pages looked at | Home in dark and light, at desktop and phone width; Install; Downloads |
|
|
| `esptool` against the real v0.11.0 factory image | An ESP32-S3 image, bootloader at 0x0, partition table at 0x8000: flashing at offset 0 is right. The command's syntax was checked, not a flash |
|
|
|
|
**Not checked:**
|
|
- **Flashing a real Cardputer from Chrome.** It needs the device on a machine with a browser; the page's flasher logic is tested, the flashing itself isn't.
|
|
- **Caddy's headers** on the real server (not applied yet), and **HTTPS on roro9stack.net** (the name resolves, the certificate isn't there).
|
|
- **The CI split on a change that touches only `site/` or `docs/`.** This pull request touches both the workflows and the site, so it runs both; the first docs-only pull request will show it.
|
|
- Firefox and Safari rendering, screen readers, and a printed page.
|
|
- The unverified wording in the Install text is kept to what's known: nothing about how long flashing takes, or what the screen shows in download mode.
|