johnandersen777.bsky.social/knotless
git that lives in your Atmosphere account
Forked from chadtmiller.com/knotless
0
0
# Working on the web pages
This is part of the root `AGENTS.md`, loaded when work reaches `web/`.
- The web pages are the SvelteKit app in `web/`; knotless-serve answers
what they show as XRPC queries, each with its lexicon under
`lexicons/` and the views it shares in `dev.knotless.defs`, as
atproto's appviews do. The pages' TypeScript types are made from those
lexicons by @atproto/lex (`npm run lex` in `web/`, which `dev`, `build`
and `check` run first), into `web/src/lib/lexicons`, not kept in git.
`just lex` checks the answers the screenshots recorded against their
lexicons, and the `test` check every answer the serve tests receive.
- Before changing a page, load the `ui` skill (`.claude/skills/ui`):
its house rules (sentence case, empty states, space), and `just
look`, which draws any page in any state from the recording as
pictures to open: empty, signed in, a menu open, a long title. Look
at every state you touch before pushing.
- For the web pages: the pull's `shots` check shows what moved, with
pictures. No screenshot is kept anywhere: the pages are shot as main
draws them and as the change does, in one run. To look before pushing,
`just shots`, which builds `web/` and main's, shoots only the pages
whose HTML differs, drawn from `harness/shots/fixtures.json` with no
PDS, and leaves each that moved under `target/shots/results/` (its
expected, actual and diff). After a change to what a page's answer
holds, `just shots-up` in the background once, then `just
shots-record`. Each checkout's shots have three ports of their own,
from its path; `SHOTS_PORT` sets another base for all of these.
- `shots-live` shoots this checkout's pages from the recording and again
through knotless-serve over a world: one that moved means the
recording is out of date. Keep `just shots-up` running in the
background while working on pages: `shots-live` then reuses its world
rather than seeding one, which is most of its time.
- The social cards are drawn by knotless-serve: `just shots-cards` takes
them from a world into `target/shots/cards` to look at.
- The components in `web/src/lib` are layered, atomic design's way:
`atoms` (one element: an icon, an avatar), `molecules` (a few atoms
that mean something together: a person, a commit row), `organisms` (a
part of a page: a check list, a feed), `templates` (a page's layout,
without its data). A component uses its own layer and those below it,
never one above; `just lint` checks it. Pages under `web/src/routes`
fill a template with what the queries answer.
- The pages' styles are `web/src/app.css`, and every colour, size,
space, radius and weight in it is a token from `web/src/tokens.css`:
take one by name rather than writing a value, and add one there when
none fits. A colour for what it means is its role, `--danger`,
`--success`, `--attention`, `--done` or `--neutral`, never the hue
under it (`--red`), so a theme can draw success in blue. Every colour that is text meets WCAG AA (4.5:1) on what
it is drawn on, in every theme: `harness/contrast.mjs` checks it, in
`web` and `just lint`, and a new colour that is text goes in
`web/src/lib/contrast.json`, which the theme editor, and knotless's
own check of a theme made anywhere (`crates/knotless/src/theme.rs`),
hold people's own themes to too. A menu that opens is a `<details class="popover …">`.
- In Svelte markup, keep a run of inline text one expression or one line:
a block or component beside it splits the text into nodes, which shapes
differently from the same text whole and moves pixels.