whiskers.git / web / CLAUDE.md
1@README.md
2
3## Notes for agents
4
5- **Datastar with Rust is the standing rule** (the owner). Do not add another front-end stack, bundler,
6  or client-side framework. The page's scripts are `jev-ui`'s: Datastar (`/datastar.js`) and `ui.js`
7  (the copy buttons and the dot fields), both embedded in the crate and served by this Worker.
8- **The look is `jev-ui`'s** (`~/jevcrates/jev-ui`, the submodule at `../third-party/jevcrates`): the same as lmjtfy.fun's, by design.
9  Shared presentation goes there, not here; this repository keeps the cat, the demo and the words. Change it in
10  `~/jevcrates` and move the pin.
11- **What the page says about Jev is read from the code that uses it** (`site/src/jev.rs`, `worker/src/explain.rs`):
12  `whiskers_core::journey`, `whiskers_judge`. Do not write a topic, a threshold or a step into the page by hand. The
13  example responses are hand-written and the page says so; the requests are the guard's own bytes.
14- **Follow `~/lmjtfy`'s conventions** (crate layout, a README and CLAUDE.md in
15  every directory, nix devshell). Read, never edit, `~/lmjtfy` and `~/nixos-config`; a change
16  they need is a proposed patch, written outside this repository.
17- **Deploys follow the owner's permission.** The owner has allowed redeploying this Worker whenever the site improves (verified first: tests, `tools/check-private.sh`, regenerated preview); publishing anything else, creating DNS beyond the route in `worker/wrangler.toml`, or touching another site is still the owner's call.
18- **Ginger is the default mascot and first in the picker**, then Grey, then Bunny. The link preview's card and video are drawn with the default.
19- **The stage is black** (`cat::stage::STAGE`; `page.css` takes it from there, a test holds them together). A new effect or
20  mascot colour must stand out from it (3 to 1) or lie on a light shape; `cat/src/stage.rs`'s tests fail otherwise. Which mood pill spins
21  is `site::demo::pill`, the server's word, drawn into every answer; do not bind it in the browser.
22- **A mascot is an enum variant with art for every mood.** `cat::scene` is an exhaustive match on
23  `Mascot`, and each art matches `Mood` without a wildcard: a new mascot or mood does not compile
24  until it is drawn. Names from a visitor go through `Mascot::parse` and nothing else; a query
25  value that is not a mascot is the default, a POST that is not one is refused.
26- **No family or machine detail on the page, in code, or in comments**; say "a young child". Run
27  `tools/check-private.sh` (repo root) before committing. The page has a test for a few words.
28- **The downloads are served by the code host, never by this Worker.** "Get it" only links `config::RELEASES_URL` + a file name (plain links need no CSP directive); the builds are the one table `config::APP_DOWNLOADS`, a test holds each linked once, and the links may 404 until the code host ships them. Do not proxy or invent other addresses.
29- **Pixel icons are `site::config::Pic`**: files from three directories of `third-party/` (shuqikhor's pack and SerenityOS's, both unchanged; `pixel-icons-extra`, drawn here), embedded with `include_str!`/`include_bytes!`. Real brand logos are wanted where a pack has them; where neither does, draw one in `pixel-icons-extra`. Which icons go with which download is `APP_DOWNLOADS`/`SERVER_DOWNLOAD`'s `icons` and nowhere else; the footer keeps the credits. Lists of facts are `pic::facts` tables (icon, `th scope="row"`, text), not bullets.
30- **The download menu is a `<details>` with no script.** Hover-open is CSS where `::details-content` exists; there is no Escape handler (the shared `ui.js` has no such pattern). Keep the menu in the page's flow so it cannot overflow.
31- **Nothing is loaded from elsewhere.** No CDN, analytics, or third-party image or font (the three faces are `jev-ui`'s own files). A test
32  scans the page and CSS; the CSP forbids it too.
33- **Never log a visitor.** `worker/src/log.rs` builds lines only from a route, method, status and
34  time. Do not add a free-text log call in the Worker.
35- **One definition of motion** (`cat/src/motion.rs`) serves the page (CSS keyframes) and the
36  video (baked frames). Do not animate anything with hand-written CSS or JS.
37- **Toolchain:** run everything inside `nix develop ~/whiskers#web`. The `wasm-bindgen` pin in
38  `Cargo.toml` must equal the devshell's CLI version.