Report button moves under the exercise, bottom-right

The red "!" left the top chrome (it read as chrome and was easy to
mis-tap) and now sits in a row under the exercise: the AI disclaimer stays
centred, the report control is right-aligned with the card edge and is a
44px target. Applies to study, Smart Review and exam sessions; the results
slides keep just the disclaimer.

phase-2 suite now asserts the placement (below the card, right-aligned,
not in the header, >=44px) — 60 checks.

README: decision 52 updated. SW -> freezmo-v43.
This commit is contained in:
Martin Dvořák 2026-10-12 12:29:59 +00:00
commit 33c0ad1ed0
6 changed files with 88 additions and 37 deletions

View file

@ -1368,16 +1368,18 @@ Things I chose while building, with the reasoning:
tree. Reduced motion skips the spring and the swap still lands via `onAnimationComplete`. The
phase-2 suite asserts the painted-face invariant at rest, flipped and flipped back.
52. **Reporting a question is local-first, with a server copy for the operator.** The red "!" in
the feed chrome records the question in this browser — that local list is the skip state, so the
card leaves study, review, mistakes and exam sessions, and Undo in the toast brings it back
(the server file is append-only). It also POSTs a copy to `/api/reports`, which appends one JSON
line to `shared/freezmo/reports/reports.jsonl`. The app has no auth, so the route is write-only:
the question text is readable on the server (that is the point — prompt tuning) but never over
HTTP. A reported card counts as "not attempted" in the results rather than wrong, and a deck
where everything is reported stays studiable so it can be regenerated. Verified by the phase-1
suite (append, validation, no GET) and the phase-2 suite (button, toast, server POST, local
copy, skip, hidden next session, Undo, exam pool).
52. **Reporting a question is local-first, with a server copy for the operator.** The red "!" under
the card (bottom-right of the exercise — it used to sit in the top chrome, where it read as
chrome and was easy to mis-tap) records the question in this browser — that local list is the
skip state, so the card leaves study, review, mistakes and exam sessions, and Undo in the toast
brings it back (the server file is append-only). It also POSTs a copy to `/api/reports`, which
appends one JSON line to `shared/freezmo/reports/reports.jsonl`. The app has no auth, so the
route is write-only: the question text is readable on the server (that is the point — prompt
tuning) but never over HTTP. A reported card counts as "not attempted" in the results rather
than wrong, and a deck where everything is reported stays studiable so it can be regenerated.
Verified by the phase-1 suite (append, validation, no GET) and the phase-2 suite (button
placement under the card with a 44px target, toast, server POST, local copy, skip, hidden next
session, Undo, exam pool).
51. **Cards with repeated wording never ship.** The model sometimes pads a matching card with one
definition copied across several terms (a Czech literature deck arrived on a phone with three