## In plain English Add a feedback widget to book_app that matches the reading app's visual theme. Readers can report bugs or request features without leaving the app, and session logs are attached automatically so developers have full context. ## User story As a book_app reader, I want to submit a bug report or feature request from within the app so that I can give feedback without switching to an external tool. ## Context This is the book_app-side UI for the feedback system. The widget POSTs to the shared Cloudflare feedback worker (#109). It must use book_app's design tokens and theme — it should feel like a native part of the reading experience, not a generic form. This story is structurally identical to the gaming_app story (#110) but scoped to book_app's theme, component conventions, and tech stack. Part of: #46 Depends on: #109 (worker must exist before integration) ## Acceptance criteria - [ ] Feedback entry point accessible from book_app's main navigation or reader settings menu (exact placement TBD with design) - [ ] Form fields: Title (required), Description (required), Type selector: Bug Report | Feature Request - [ ] Screenshot attachment: user can capture current screen or upload from device (optional) - [ ] Session log attachment: last N minutes of client-side logs attached automatically on submit (user-visible disclosure: "Your session logs will be included") - [ ] Submit POSTs to worker URL configured via env var `VITE_FEEDBACK_WORKER_URL` (or equivalent build-time env var for book_app's stack) - [ ] Success state: confirmation message with link to the created GitHub issue - [ ] Error states handled: rate limited (friendly message + retry timer), content rejected (generic message), network error (retry option) - [ ] Widget fully keyboard-navigable (WCAG 2.1 AA — tab order, focus management on open/close) - [ ] All UI copy goes through i18next (no hardcoded strings) - [ ] Widget uses book_app design tokens for colors, typography, spacing — no hardcoded CSS values - [ ] Widget does not render if `VITE_FEEDBACK_WORKER_URL` is unset (graceful no-op) ## Technical notes - Worker payload shape: `{ appId: "book_app", title, description, type: "bug"|"feature", screenshotBase64?, sessionLogs? }` - Session log capture: hook into book_app's existing logging utility (investigate actual logger in book_app repo before implementing) - i18n namespace: `feedback` — add keys to book_app's locale files (same namespace name as gaming_app for consistency) - Design token contract documented in theme contract story (child story 6 of epic #46) - Component location: follow book_app's existing component directory conventions ## Test coverage ### Unit tests - [ ] Form validation: submit blocked when title or description empty - [ ] Type selector: correct `type` value sent in payload - [ ] Session log attachment: logs present in payload on submit - [ ] Error state: rate-limit response renders friendly message with retry timer - [ ] Error state: content-rejected response renders generic rejection message ### E2E tests - [ ] Happy path: fill form → submit → success confirmation with issue link displayed - [ ] Screenshot attachment: attach screenshot → submit → payload includes base64 image ### Performance - [ ] Widget JS chunk < 50 KB gzipped ### Regression - [ ] Widget opens and closes without disrupting book reader state (reading position, scroll position preserved) ## Documentation to update - [ ] book_app CLAUDE.md or README: document `VITE_FEEDBACK_WORKER_URL` env var requirement - [ ] Add `feedback` i18n namespace to book_app's locale inventory ## Unknowns / needs investigation - Confirm book_app's build tool and env var naming convention - Confirm book_app's existing logging utility API - Confirm book_app's design token naming convention (needed for theme contract story) - Confirm book_app's component structure/directory conventions before placing widget ## Out of scope - Localization suggestion form variant (separate story #localization-story) - Admin-side review of submitted feedback - In-app display of feedback history ## Dependencies - Part of: #46 - Blocked by: #109 (worker core must be deployable before UI integration) - Blocks: none ## Definition of done - [ ] All acceptance criteria met - [ ] Test coverage added per above - [ ] Documentation updated - [ ] CI green (lint, type check, tests) - [ ] PR reviewed and merged to dev