Files
cyclone/docs/reviews/2026-06-23-css-reduction/baseline.md
T
cyclone 616d467c65 docs(reviews): capture 2026-06-23 docset review + CSS reduction experiment
Commit the day's review artifacts so they aren't lost in the working tree:

* 2026-06-23-cyclone-docset-review-A.md — full docset review (Reviewer A:
  requirements + architecture lens; flags the 8-state vs 7-state claim
  lifecycle divergence, FR-20 vs ARCHITECTURE §5.4 tail-endpoint conflict,
  api_routers/ package split status, etc.)
* 2026-06-23-cyclone-docset-review-B.md — code-first counterpart (Reviewer B)
* 2026-06-23-cyclone-groundtruth-audit.md — live-data readiness audit
* 2026-06-23-css-reduction/ — iterative CSS reduction experiment
  (baseline 60,695 B raw / 11,786 B gzip / 9,875 B brotli; 18 prioritized
  candidates; per-iter reports and progress log)

Binary artifacts (PNGs, dist build output) are intentionally not committed —
they're working files for the experiment, not review records.
2026-06-23 16:28:15 -06:00

5.0 KiB
Raw Blame History

CSS Reduction — Baseline (2026-06-23)

Goal

Reduce dist/assets/index-*.css bytes without changing any tested screen. One declaration/rule at a time, verified by pixel-identical screenshots and project checks. This file is the baseline the iterative loop is compared against.

Build (the size we are trying to shrink)

metric bytes
raw 60,695
gzip 11,786
brotli 9,875

dist/assets/index-BznqBut5.css, built with npx vite build (Vite 5.4.21, 8.9s).

Test matrix (the screens we will hold pixel-identical)

  • Theme: dark only (the app is <html class="dark"> + theme="dark" for the Toaster; no light path exists in the design system).
  • Sizes: 3 (desktop 1440×900, tablet 768×1024, mobile 375×812).
  • Routes: 13 (/, /upload, /inbox, /claims, /claims?status=denied, /remittances, /providers, /reconciliation, /acks, /batches, /batch-diff, /activity, /does-not-exist).
  • Interactive states: 6 (claim drawer open, remit drawer open, inbox row focused, search focused, keyboard cheatsheet open, upload dropzone focused) × 3 sizes = 18 captures.
  • Total: 13 × 3 + 6 × 3 = 57 screenshots per build.

Capture source: audit-uiux-extended.mjs (new, superset of audit-uiux.mjs). Pixel-diff harness: tools/css-screenshots-diff.mjs using pixelmatch (threshold 0).

Project checks (the gates we hold green)

check baseline used as gate? reason
npx vite build passes yes produces the CSS bundle under reduction
npx vitest run 498 / 501 yes pre-existing 3 failures, see "Known failures" below
tsc -b (in npm run build) fails no 15 type errors in test files + Upload.tsx, all pre-existing
npm run typecheck fails no same as above
npm run lint fails no sh: eslint: command not found (eslint not installed)

Known pre-existing failures (not caused by this work)

vitest run — 3 failing tests:

  • src/pages/Inbox.test.tsx > Inbox page > SP14: payer-rejected row count rolls up into the need-eyes header
  • src/store/tail-store.test.ts > useTailStore > test_fifo_cap_evicts_oldest_when_over_10000
  • src/components/inbox/InboxHeader.test.tsx > InboxHeader > renders the date and counts None touch CSS. Each candidate run will compare the new vitest exit status and failure set to the baseline — a candidate is rejected if it adds a new failure, even if the count stays at 3.

tsc -b / npm run typecheck — 15 errors in test files and src/pages/Upload.tsx. Not exercised by the reduction loop. npm run linteslint is not installed in devDependencies; the script npm run lint exits 127. Not exercised.

Interactive-state coverage

Out of 18 interactive captures, 15 succeed and 3 fail (the same 3 every run):

  • remittances-drawer × all sizes — the /remittances page renders with no table rows in the current backend state, so the row-click step finds nothing. The screenshot falls back to the static /remittances page with no drawer; pixel-identical comparison still works for that fallback, but the remittance-drawer CSS itself is not exercised. This is captured here as an untested state for the final report.

The other 15 interactions (claims-drawer, inbox-row-focused, search-focused, cheatsheet-open, upload-dropzone-focused × 3 sizes) all succeed. They exercise the CSS for the open claim drawer, the keyboard cheatsheet overlay, the focused search button, the focused upload dropzone, and the focus ring on inbox rows.

Pre-existing noise (not regressions, not caused by this work)

From the baseline run (baseline-report.json):

  • 6/57 flows have ≥1 console error. All from the inbox route and the inbox-row-focused state. The 4 interactive ones are the same source.
  • 24/57 flows have ≥1 failed request. Likely the dashboard summary endpoint (/api/dashboard/summary) and a few analytics / SSE probes in the inbox.
  • 0 page errors.

A candidate that does not increase these counts is fine; an increase is informational, not a gate.

Self-diff sanity check

tools/css-screenshots-diff.mjs compare with BASE == CAND returns PIXEL-IDENTICAL — 57 compared, 0 differing. The harness works.

What is in scope for the iterative loop

  • Source: src/index.css (custom CSS + Tailwind base/components/utilities)
  • Config: tailwind.config.js
  • Component .tsx files (only if removing a Tailwind utility from a className produces a smaller bundle)

What is out of scope

  • index.html (Google Fonts preconnect, hard to prove pixel-identical after font source change)
  • The JS bundle (separate goal)
  • The backend (backend/)
  • Any non-CSS build artifact