Screenshotting the pages under dark mode and compact density (rather than
trusting that design tokens were enough) turned up two mistakes repeated across
every page this feature set added:
- `.card` carries only the surface, border and radius — padding comes from the
separate `.card-pad`. Fifteen cards were rendering with their content flush
against the edges.
- `.field` *is* the input box, a 40px-tall flex row. Wrapping a label plus a
control in it produced a joined addon rather than a label above its field.
`.field-block` is the label-above layout, and thirty-seven wrappers now use it.
Both were invisible to type-checking and to the tests, which is exactly why the
visual pass was worth running. Numbers in the new UI now go through
formatNumber so they render as Persian digits, and the utilization page's
header no longer repeats the sentence that appears under its filters verbatim.
The QA driver gained a `--ui` flag: theme and density live in
localStorage['clinicpro-ui'], so without seeding them dark mode and compact
density cannot be screenshotted at all.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Task 08's pricing chain was reachable only through the API, so a clinic could
not define a price list or see what a booked appointment was actually charged.
Price lists
- Draft / active / expired are shown as three states because they mean three
different things operationally: a draft has no effect on today's price at all
- Activation is a separate action rather than a checkbox in the form, matching
the backend rule that creating a list must not change anything
- "Copy" seeds a new list from an existing one starting the day the old one
ends, since most lists are last quarter's with a few numbers moved
- "All branches" is an explicit option, not an empty field
Invoice card
- Renders the recorded chain down to the final amount, hiding zero rows so the
card stays readable
- A missing invoice renders as a normal state, not an error: an appointment
that was never confirmed has no invoice
- Says outright that the numbers are from the appointment's own date and later
tariff changes do not move them — otherwise someone who edited a price
yesterday reads today's older number as a bug
Also corrects task 08's checklist: its test section carried a copy-pasted "no
UI was built" note against rows whose tests have existed since the task
shipped. Replaced with the real test names and the two that genuinely are not
covered.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>