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.
This commit is contained in:
cyclone
2026-06-23 16:28:15 -06:00
parent 2194d35ea1
commit 616d467c65
13 changed files with 5623 additions and 0 deletions
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,103 @@
# 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 lint``eslint` 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
@@ -0,0 +1,110 @@
# CSS Candidates — unused-or-low-value
Generated from `tools/css-candidate-scan.mjs`. 'used' = referenced in any source file. Not used does NOT mean safe to remove — verify with screenshots before keeping a change.
| type | name | used | location |
| ---- | ---- | ---- | -------- |
| css-var | `--background` | **no** | src/index.css :root (referenced inside css/config) |
| css-var | `--card-foreground` | **no** | src/index.css :root (referenced inside css/config) |
| css-var | `--popover` | **no** | src/index.css :root (referenced inside css/config) |
| css-var | `--popover-foreground` | **no** | src/index.css :root (referenced inside css/config) |
| css-var | `--muted` | **no** | src/index.css :root (referenced inside css/config) |
| css-var | `--secondary` | **no** | src/index.css :root (referenced inside css/config) |
| css-var | `--secondary-foreground` | **no** | src/index.css :root (referenced inside css/config) |
| css-var | `--accent-foreground` | **no** | src/index.css :root (referenced inside css/config) |
| css-var | `--primary` | **no** | src/index.css :root (referenced inside css/config) |
| css-var | `--primary-foreground` | **no** | src/index.css :root (referenced inside css/config) |
| css-var | `--destructive-foreground` | **no** | src/index.css :root (referenced inside css/config) |
| css-var | `--success-foreground` | **no** | src/index.css :root (referenced inside css/config) |
| css-var | `--input` | **no** | src/index.css :root (referenced inside css/config) |
| css-var | `--ring` | **no** | src/index.css :root (referenced inside css/config) |
| css-var | `--sidebar` | **no** | src/index.css :root (referenced inside css/config) |
| css-var | `--sidebar-foreground` | **no** | src/index.css :root (referenced inside css/config) |
| css-var | `--sidebar-accent` | **no** | src/index.css :root (referenced inside css/config) |
| css-var | `--sidebar-border` | **no** | src/index.css :root (referenced inside css/config) |
| css-var | `--surface-line` | **no** | src/index.css :root (referenced inside css/config) |
| css-var | `--surface-line-soft` | **no** | src/index.css :root |
| css-var | `--m-error-bg` | **no** | src/index.css :root |
| css-var | `--radius` | **no** | src/index.css :root (referenced inside css/config) |
| css-var | `--font-sans` | **no** | src/index.css :root (referenced inside css/config) |
| css-var | `--font-mono` | **no** | src/index.css :root (referenced inside css/config) |
| css-var | `--font-display` | **no** | src/index.css :root (referenced inside css/config) |
| css-var | `--background` | **no** | src/index.css :root (referenced inside css/config) |
| css-var | `--card-foreground` | **no** | src/index.css :root (referenced inside css/config) |
| css-var | `--muted` | **no** | src/index.css :root (referenced inside css/config) |
| class | `.text-balance` | **no** | src/index.css (components/utilities layer) |
| class | `.text-pretty` | **no** | src/index.css (components/utilities layer) |
| class | `.ring-inset-hairline` | **no** | src/index.css (components/utilities layer) |
| animation | `animate-accordion-down` | **no** | tailwind.config.js animation |
| animation | `animate-accordion-up` | **no** | tailwind.config.js animation |
| animation | `animate-fade-in-soft` | **no** | tailwind.config.js animation |
| animation | `animate-slide-in-right` | **no** | tailwind.config.js animation |
| animation | `animate-ticker-blink` | **no** | tailwind.config.js animation |
| css-var | `--foreground` | yes | src/index.css :root (referenced inside css/config) |
| css-var | `--card` | yes | src/index.css :root (referenced inside css/config) |
| css-var | `--muted-foreground` | yes | src/index.css :root (referenced inside css/config) |
| css-var | `--accent` | yes | src/index.css :root (referenced inside css/config) |
| css-var | `--signal` | yes | src/index.css :root (referenced inside css/config) |
| css-var | `--destructive` | yes | src/index.css :root (referenced inside css/config) |
| css-var | `--success` | yes | src/index.css :root (referenced inside css/config) |
| css-var | `--warning` | yes | src/index.css :root (referenced inside css/config) |
| css-var | `--warning-foreground` | yes | src/index.css :root (referenced inside css/config) |
| css-var | `--border` | yes | src/index.css :root (referenced inside css/config) |
| css-var | `--surface` | yes | src/index.css :root (referenced inside css/config) |
| css-var | `--surface-ink` | yes | src/index.css :root (referenced inside css/config) |
| css-var | `--surface-ink-2` | yes | src/index.css :root (referenced inside css/config) |
| css-var | `--surface-ink-3` | yes | src/index.css :root (referenced inside css/config) |
| css-var | `--tt-bg` | yes | src/index.css :root |
| css-var | `--tt-bg-elev` | yes | src/index.css :root |
| css-var | `--tt-ink` | yes | src/index.css :root |
| css-var | `--tt-ink-dim` | yes | src/index.css :root |
| css-var | `--tt-amber` | yes | src/index.css :root |
| css-var | `--tt-oxblood` | yes | src/index.css :root |
| css-var | `--tt-ink-blue` | yes | src/index.css :root |
| css-var | `--tt-muted` | yes | src/index.css :root |
| css-var | `--m-surface` | yes | src/index.css :root |
| css-var | `--m-ink-primary` | yes | src/index.css :root |
| css-var | `--m-ink-secondary` | yes | src/index.css :root |
| css-var | `--m-ink-tertiary` | yes | src/index.css :root |
| css-var | `--m-border-heavy` | yes | src/index.css :root |
| css-var | `--m-font-mono` | yes | src/index.css :root |
| css-var | `--m-error` | yes | src/index.css :root |
| css-var | `--m-success` | yes | src/index.css :root |
| css-var | `--m-warning` | yes | src/index.css :root |
| css-var | `--m-accent` | yes | src/index.css :root |
| css-var | `--foreground` | yes | src/index.css :root (referenced inside css/config) |
| css-var | `--card` | yes | src/index.css :root (referenced inside css/config) |
| css-var | `--muted-foreground` | yes | src/index.css :root (referenced inside css/config) |
| css-var | `--border` | yes | src/index.css :root (referenced inside css/config) |
| css-var | `--accent` | yes | src/index.css :root (referenced inside css/config) |
| class | `.num` | yes | src/index.css (components/utilities layer) |
| class | `.display` | yes | src/index.css (components/utilities layer) |
| class | `.mono` | yes | src/index.css (components/utilities layer) |
| class | `.surface` | yes | src/index.css (components/utilities layer) |
| class | `.surface-2` | yes | src/index.css (components/utilities layer) |
| class | `.hairline` | yes | src/index.css (components/utilities layer) |
| class | `.nav-active` | yes | src/index.css (components/utilities layer) |
| class | `.skip-link` | yes | src/index.css (components/utilities layer) |
| class | `.kbd` | yes | src/index.css (components/utilities layer) |
| class | `.eyebrow` | yes | src/index.css (components/utilities layer) |
| class | `.editorial` | yes | src/index.css (components/utilities layer) |
| class | `.row-hover` | yes | src/index.css (components/utilities layer) |
| class | `.animate-scan` | yes | src/index.css (components/utilities layer) |
| class | `.drillable` | yes | src/index.css (components/utilities layer) |
| keyframes | `accordion-down` | yes | tailwind.config.js keyframes |
| keyframes | `accordion-up` | yes | tailwind.config.js keyframes |
| keyframes | `fade-in` | yes | tailwind.config.js keyframes |
| keyframes | `fade-in-soft` | yes | tailwind.config.js keyframes |
| keyframes | `fade-in-up` | yes | tailwind.config.js keyframes |
| keyframes | `slide-in-right` | yes | tailwind.config.js keyframes |
| keyframes | `row-flash` | yes | tailwind.config.js keyframes |
| keyframes | `pulse-dot` | yes | tailwind.config.js keyframes |
| keyframes | `ticker-blink` | yes | tailwind.config.js keyframes |
| animation | `animate-fade-in` | yes | tailwind.config.js animation |
| animation | `animate-fade-in-up` | yes | tailwind.config.js animation |
| animation | `animate-row-flash` | yes | tailwind.config.js animation |
| animation | `animate-pulse-dot` | yes | tailwind.config.js animation |
## Summary
- 36 unused / 100 total
- 64 used / 100 total
@@ -0,0 +1 @@
{"id":"01-var-surface-line-soft","priority":"H","label":"drop --surface-line-soft declaration","file":"src/index.css","before":" --surface-line-soft: 30 14% 14% / 0.12;\n","after":""}
@@ -0,0 +1,42 @@
# CSS Reduction — Candidate Queue
Atomic removals to try, in priority order. Each is one revertable unit
(edit one file, revert if pixel-identical or project checks regress).
Priority legend: **H** (high confidence, no visible effect expected),
**M** (medium, may affect pixels in edge cases), **L** (low, will likely
revert because it changes visible output).
| # | priority | id | what | where | expected | notes |
|---|----------|----|------|-------|----------|-------|
| 1 | H | `var-surface-line-soft` | drop the `--surface-line-soft` declaration | `src/index.css` line 77 | ~30 B | Only mentioned in a comment in `BarChart.tsx`; no `var(--surface-line-soft)` ref anywhere |
| 2 | H | `var-m-error-bg` | drop the `--m-error-bg` declaration | `src/index.css` line 102 | ~30 B | No `var(--m-error-bg)` ref anywhere in src |
| 3 | H | `kf-fade-in-soft` | drop `fade-in-soft` keyframe + `animate-fade-in-soft` util | `tailwind.config.js` | ~150 B | `animate-fade-in-soft` is not used in any source file |
| 4 | H | `kf-slide-in-right` | drop `slide-in-right` keyframe + animation | `tailwind.config.js` | ~180 B | `animate-slide-in-right` not used |
| 5 | H | `kf-ticker-blink` | drop `ticker-blink` keyframe + animation | `tailwind.config.js` | ~200 B | `animate-ticker-blink` not used |
| 6 | H | `kf-accordion-down` | drop `accordion-down` keyframe + animation | `tailwind.config.js` | ~150 B | `animate-accordion-down` not used; no accordion in app |
| 7 | H | `kf-accordion-up` | drop `accordion-up` keyframe + animation | `tailwind.config.js` | ~150 B | same as above |
| 8 | H | `media-print` | drop the entire `@media print { ... }` block | `src/index.css` lines 402446 | ~1 KB | Print not in test matrix; the `display: none` rules apply to aside/header — they don't appear in screenshots anyway. **Risk**: a printed detail drawer would no longer be styled for paper, but no print preview is captured. |
| 9 | M | `body-before` | drop the `body::before` radial gradients (the upper-right accent + top-center softbox) | `src/index.css` lines 147156 | ~400 B | Subtle background. Likely visible on all screenshots. **Will likely revert.** |
| 10 | M | `body-after` | drop the `body::after` hairline grid | `src/index.css` lines 163176 | ~450 B | Subtle background grid. Likely visible. **Will likely revert.** |
| 11 | M | `scrollbar` | drop `::-webkit-scrollbar*` rules | `src/index.css` lines 179195 | ~330 B | Scrollbars only visible when content overflows. Most screenshots are above-the-fold; may not trigger. |
| 12 | M | `nav-active-before` | drop the `::before` accent strip on `.nav-active` | `src/index.css` lines 290300 | ~180 B | Visible on the active sidebar item. |
| 13 | M | `surface-2` | drop the `.surface-2` class entirely | `src/index.css` lines 266277 | ~250 B | Used in some components — likely a revert. |
| 14 | M | `focus-visible` | drop the global `:focus-visible` ring | `src/index.css` lines 200204 | ~90 B | All focusable elements would lose the global ring (but Tailwind focus-visible: utilities still apply). May or may not change pixels. |
| 15 | L | `body-bg-image` | drop the body background-image gradients | `src/index.css` lines 136139 | ~250 B | **Will revert** — visible. |
| 16 | L | `skip-link` | drop the `.skip-link` class | `src/index.css` lines 303338 | ~700 B | Component exists (`ui/skip-link.tsx`). Removing the class breaks it visually. **Will revert.** |
| 17 | L | `drillable` | drop `.drillable` and its hover | `src/index.css` lines 449461 | ~220 B | Used in `DrillableCell.tsx`. **Will revert.** |
| 18 | L | `row-hover` | drop the `.row-hover` hover state | `src/index.css` lines 379384 | ~100 B | Used in tables. Hover state not captured (no mouse). Could be safe. |
## Out of scope (intentionally not tried)
- Tailwind preflight (`*, ::before, ::after`, `::backdrop` with `--tw-*` vars). These power the utility system; removing would break all utilities.
- `@media (prefers-reduced-motion)`. Safety block, removing would change behavior in non-default OS settings.
- Specific custom class definitions that are heavily used (`.num`, `.display`, `.mono`, `.surface`, `.eyebrow`, `.editorial`).
- Any Tailwind utility removal in component `className` props (small wins, lots of churn — would be done in a follow-up pass).
- The `index.html` Google Fonts `<link>` (it's HTML, not CSS, and removing it would change the rendered output).
## Stopping conditions
- Queue exhausted.
- 5 consecutive candidates fail the **size** check (CSS not smaller after the change).
- 2 hours elapsed in Phase 3.
- User requests a stop.
@@ -0,0 +1,468 @@
{
"baseDir": "docs/reviews/2026-06-23-css-reduction/iter/01-var-surface-line-soft/_ref",
"candDir": "docs/reviews/2026-06-23-css-reduction/iter/01-var-surface-line-soft/_cand",
"diffOutDir": "docs/reviews/2026-06-23-css-reduction/iter/01-var-surface-line-soft/_diff",
"threshold": 0,
"compared": 57,
"diffCount": 15,
"missingCount": 0,
"extraCount": 0,
"results": [
{
"file": "404--desktop.png",
"size": "ok",
"width": 1440,
"height": 900,
"diffPixels": 0,
"totalPixels": 1296000
},
{
"file": "404--mobile.png",
"size": "ok",
"width": 375,
"height": 812,
"diffPixels": 0,
"totalPixels": 304500
},
{
"file": "404--tablet.png",
"size": "ok",
"width": 768,
"height": 1024,
"diffPixels": 0,
"totalPixels": 786432
},
{
"file": "acks--desktop.png",
"size": "ok",
"width": 1440,
"height": 900,
"diffPixels": 0,
"totalPixels": 1296000
},
{
"file": "acks--mobile.png",
"size": "ok",
"width": 375,
"height": 812,
"diffPixels": 0,
"totalPixels": 304500
},
{
"file": "acks--tablet.png",
"size": "ok",
"width": 768,
"height": 1024,
"diffPixels": 0,
"totalPixels": 786432
},
{
"file": "activity--desktop.png",
"size": "ok",
"width": 1440,
"height": 900,
"diffPixels": 0,
"totalPixels": 1296000
},
{
"file": "activity--mobile.png",
"size": "ok",
"width": 375,
"height": 812,
"diffPixels": 0,
"totalPixels": 304500
},
{
"file": "activity--tablet.png",
"size": "ok",
"width": 768,
"height": 1024,
"diffPixels": 0,
"totalPixels": 786432
},
{
"file": "batch-diff--desktop.png",
"size": "ok",
"width": 1440,
"height": 900,
"diffPixels": 0,
"totalPixels": 1296000
},
{
"file": "batch-diff--mobile.png",
"size": "ok",
"width": 375,
"height": 812,
"diffPixels": 0,
"totalPixels": 304500
},
{
"file": "batch-diff--tablet.png",
"size": "ok",
"width": 768,
"height": 1024,
"diffPixels": 0,
"totalPixels": 786432
},
{
"file": "batches--desktop.png",
"size": "ok",
"width": 1440,
"height": 900,
"diffPixels": 0,
"totalPixels": 1296000
},
{
"file": "batches--mobile.png",
"size": "ok",
"width": 375,
"height": 812,
"diffPixels": 0,
"totalPixels": 304500
},
{
"file": "batches--tablet.png",
"size": "ok",
"width": 768,
"height": 1024,
"diffPixels": 0,
"totalPixels": 786432
},
{
"file": "cheatsheet-open--desktop.png",
"size": "ok",
"width": 1440,
"height": 900,
"diffPixels": 2523,
"totalPixels": 1296000
},
{
"file": "cheatsheet-open--mobile.png",
"size": "ok",
"width": 375,
"height": 812,
"diffPixels": 0,
"totalPixels": 304500
},
{
"file": "cheatsheet-open--tablet.png",
"size": "ok",
"width": 768,
"height": 1024,
"diffPixels": 0,
"totalPixels": 786432
},
{
"file": "claims--desktop.png",
"size": "ok",
"width": 1440,
"height": 900,
"diffPixels": 0,
"totalPixels": 1296000
},
{
"file": "claims--mobile.png",
"size": "ok",
"width": 375,
"height": 812,
"diffPixels": 1,
"totalPixels": 304500
},
{
"file": "claims--tablet.png",
"size": "ok",
"width": 768,
"height": 1024,
"diffPixels": 0,
"totalPixels": 786432
},
{
"file": "claims-denied--desktop.png",
"size": "ok",
"width": 1440,
"height": 900,
"diffPixels": 0,
"totalPixels": 1296000
},
{
"file": "claims-denied--mobile.png",
"size": "ok",
"width": 375,
"height": 812,
"diffPixels": 0,
"totalPixels": 304500
},
{
"file": "claims-denied--tablet.png",
"size": "ok",
"width": 768,
"height": 1024,
"diffPixels": 0,
"totalPixels": 786432
},
{
"file": "claims-drawer--desktop.png",
"size": "ok",
"width": 1440,
"height": 900,
"diffPixels": 0,
"totalPixels": 1296000
},
{
"file": "claims-drawer--mobile.png",
"size": "ok",
"width": 375,
"height": 812,
"diffPixels": 0,
"totalPixels": 304500
},
{
"file": "claims-drawer--tablet.png",
"size": "ok",
"width": 768,
"height": 1024,
"diffPixels": 0,
"totalPixels": 786432
},
{
"file": "dashboard--desktop.png",
"size": "ok",
"width": 1440,
"height": 900,
"diffPixels": 2523,
"totalPixels": 1296000
},
{
"file": "dashboard--mobile.png",
"size": "ok",
"width": 375,
"height": 812,
"diffPixels": 3,
"totalPixels": 304500
},
{
"file": "dashboard--tablet.png",
"size": "ok",
"width": 768,
"height": 1024,
"diffPixels": 0,
"totalPixels": 786432
},
{
"file": "inbox--desktop.png",
"size": "ok",
"width": 1440,
"height": 900,
"diffPixels": 530,
"totalPixels": 1296000
},
{
"file": "inbox--mobile.png",
"size": "ok",
"width": 375,
"height": 812,
"diffPixels": 142,
"totalPixels": 304500
},
{
"file": "inbox--tablet.png",
"size": "ok",
"width": 768,
"height": 1024,
"diffPixels": 271,
"totalPixels": 786432
},
{
"file": "inbox-row-focused--desktop.png",
"size": "ok",
"width": 1440,
"height": 900,
"diffPixels": 529,
"totalPixels": 1296000
},
{
"file": "inbox-row-focused--mobile.png",
"size": "ok",
"width": 375,
"height": 812,
"diffPixels": 150,
"totalPixels": 304500
},
{
"file": "inbox-row-focused--tablet.png",
"size": "ok",
"width": 768,
"height": 1024,
"diffPixels": 150,
"totalPixels": 786432
},
{
"file": "providers--desktop.png",
"size": "ok",
"width": 1440,
"height": 900,
"diffPixels": 0,
"totalPixels": 1296000
},
{
"file": "providers--mobile.png",
"size": "ok",
"width": 375,
"height": 812,
"diffPixels": 0,
"totalPixels": 304500
},
{
"file": "providers--tablet.png",
"size": "ok",
"width": 768,
"height": 1024,
"diffPixels": 0,
"totalPixels": 786432
},
{
"file": "reconciliation--desktop.png",
"size": "ok",
"width": 1440,
"height": 900,
"diffPixels": 0,
"totalPixels": 1296000
},
{
"file": "reconciliation--mobile.png",
"size": "ok",
"width": 375,
"height": 812,
"diffPixels": 0,
"totalPixels": 304500
},
{
"file": "reconciliation--tablet.png",
"size": "ok",
"width": 768,
"height": 1024,
"diffPixels": 0,
"totalPixels": 786432
},
{
"file": "remittances--desktop.png",
"size": "ok",
"width": 1440,
"height": 900,
"diffPixels": 0,
"totalPixels": 1296000
},
{
"file": "remittances--mobile.png",
"size": "ok",
"width": 375,
"height": 812,
"diffPixels": 0,
"totalPixels": 304500
},
{
"file": "remittances--tablet.png",
"size": "ok",
"width": 768,
"height": 1024,
"diffPixels": 0,
"totalPixels": 786432
},
{
"file": "remittances-drawer--desktop.png",
"size": "ok",
"width": 1440,
"height": 900,
"diffPixels": 0,
"totalPixels": 1296000
},
{
"file": "remittances-drawer--mobile.png",
"size": "ok",
"width": 375,
"height": 812,
"diffPixels": 0,
"totalPixels": 304500
},
{
"file": "remittances-drawer--tablet.png",
"size": "ok",
"width": 768,
"height": 1024,
"diffPixels": 372,
"totalPixels": 786432
},
{
"file": "search-focused--desktop.png",
"size": "ok",
"width": 1440,
"height": 900,
"diffPixels": 9684,
"totalPixels": 1296000
},
{
"file": "search-focused--mobile.png",
"size": "ok",
"width": 375,
"height": 812,
"diffPixels": 47,
"totalPixels": 304500
},
{
"file": "search-focused--tablet.png",
"size": "ok",
"width": 768,
"height": 1024,
"diffPixels": 0,
"totalPixels": 786432
},
{
"file": "upload--desktop.png",
"size": "ok",
"width": 1440,
"height": 900,
"diffPixels": 1,
"totalPixels": 1296000
},
{
"file": "upload--mobile.png",
"size": "ok",
"width": 375,
"height": 812,
"diffPixels": 1,
"totalPixels": 304500
},
{
"file": "upload--tablet.png",
"size": "ok",
"width": 768,
"height": 1024,
"diffPixels": 0,
"totalPixels": 786432
},
{
"file": "upload-dropzone-focused--desktop.png",
"size": "ok",
"width": 1440,
"height": 900,
"diffPixels": 0,
"totalPixels": 1296000
},
{
"file": "upload-dropzone-focused--mobile.png",
"size": "ok",
"width": 375,
"height": 812,
"diffPixels": 0,
"totalPixels": 304500
},
{
"file": "upload-dropzone-focused--tablet.png",
"size": "ok",
"width": 768,
"height": 1024,
"diffPixels": 0,
"totalPixels": 786432
}
]
}
@@ -0,0 +1,11 @@
[
{
"id": "01-var-surface-line-soft",
"priority": "H",
"label": "drop --surface-line-soft declaration",
"file": "src/index.css",
"kept": false,
"diffCount": 15,
"diffMax": 9684
}
]
@@ -0,0 +1,10 @@
# CSS Reduction — Progress Log
## Baseline
- raw: 60,695 B · gzip: 11,786 B · brotli: 9,875 B
- 57 screenshots captured
- vitest: 498/501 (3 pre-existing failures)
- tsc: 15 pre-existing failures (gate skipped)
- lint: `eslint` not installed (gate skipped)
## Candidates