K3 (card purchases on the web, landed faeb752; web gate 70 files, 684 tests,
build ok; contracts-check 157):
- SPEC §15.6 W-21 to W-23 as built, with W-5's ?cardPurchase= prefill and link,
W-6's card line, W-13's "Anslut kort" row; §15.5 the card snapshot; §15.3
the shared card pieces (api/cards.ts, fixtures, dev proxy, three icons) and
matchCardPurchase ported; §11.1, §11.2 K3 row, §11.3, §14.7, §15.9; v0.40 row.
- decisions D-201 to D-207 (refresh while fetching, query names, https-only
auth_url, attempt outcome, W-5 purchase errors, date forms, S-27 on the web);
D-208 to D-210 unused.
- HANDOFF: K0 to K3 landed, v1.0.4 deployed, v1.0.5 being built, kvitt-164 on
the Pi; pending owner steps PLAN-K2 §8, PLAN-K3 §8, PLAN-K1 §8 steps 5 to 7;
K3's open questions; next free D-212, v0.41.
- web/README.md: card routes, the card snapshot, query names, the new icons;
prompts/README.md: K2 and K3 done.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TQd3pEP9UeN2uifbHknQ7B
web/ is the browser client's scaffold: Vite 8, React 19, TypeScript 5.9 strict, React Router 7 (basename /app, every
fixed route with a lazy placeholder page), TanStack Query 5 (refetch on focus and every 60 s), openapi-typescript
types generated from contracts/openapi.yaml with openapi-fetch. Reads go through GET /sync (no REST reads exist for
the ledger, SPEC §7): useLedger() pulls from cursor 0 and then incrementally, restarting on a new epoch or
cursor_ahead. Login pairs the browser as "Web · <browser>" with an invite code (E-3); every call sends the SPEC
§14.3.1 headers, a 401 signs out. kvitt-domain's split, balances, allocation and settlement rules are ported to
web/src/lib and pass every case of contracts/test-vectors. Design tokens from design-spec §2 in tokens.css
(light-dark()), Material Symbols Rounded (Apache-2.0) as generated inline SVG, sv/en catalogs generated from
docs/ux/strings.csv plus web-strings.csv. Gate: cd web && npm run check.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TQd3pEP9UeN2uifbHknQ7B