Atomic pattern
Frontend uses Astro, DaisyUI, and atomic design.
Components live in atomic layers. Pages compose atomic layers. Frontend does not own feature slices.
src/features/** is target-architecture debt. It exists only as a temporary
migration holding area for older frontend worker output. No new file, import, or
route dependency may be added there. Existing feature code must be moved into
atomic UI, Nanostores UI stores, or backend API client wrappers.
All interactive client state goes through Nanostores. Stores may hold backend projection state, command progress, conflict status, retry state, and client-only conversational flow state. Stores must not derive backend-owned payment, reservation, document, workflow, RBAC, pricing, or settlement decisions locally.
Security rule: UI affordances are advisory only. Backend checks remain the only
authority. Frontend must render can*, status, amount, and readiness fields
received from backend contracts, not recompute them from raw rows or hidden DOM
state.
E2E rule: a reservation/payment/settlement browser scenario is not migration
proof if the page imports src/features/** or fills missing backend decisions
with UI logic. The browser can prove contract consumption; backend facts prove
authority.
*.feature-ui.tsx files are no longer allowed. The ESLint boundary treats src/features/**/*.tsx as non-UI and blocks React local/context state hooks for business state, including useState, useReducer, useContext, useActionState, and useOptimistic.
Reusable navigation controls belong in atoms. Repeated DaisyUI anchor buttons use the LinkButton atom instead of duplicating class="btn ..." in organisms or templates.