Skip to content

Clarity pass: lead with the result, explain on hover, safer contracts - #6

Merged
thundermage117 merged 11 commits into
mainfrom
feature/clarity-pass
Oct 10, 2026
Merged

thundermage117 merged 11 commits into
mainfrom
feature/clarity-pass

Conversation

@thundermage117

Copy link
Copy Markdown
Owner

Builds on #5. Makes the app easier to read for a newcomer, and the codebase safer to change.

Viewer

  • Opens on a sample image already compressed, instead of an empty frame. Drop an image file anywhere on the viewer to load it.
  • Image header: Image / Y / Cr / Cb (plus Subbands for wavelets), Zoom and Download. Removed the Comparison/Original/Processed toggle (the split slider does this) and the Error view (the Artifact Analyzer covers it).
  • One "Inspect a block" / "Analyze artifacts" row under the image replaces three separate entry points.
  • Sidebar: Image / Compression / Result. The result leads with estimated size, then luma PSNR and SSIM.
  • RD and sparsity charts share one "Compare transforms" card. Both compute on their own, with no Generate buttons.
  • Arrow keys move the comparison split. On phones, controls come right after the image.

Block Inspector

  • Reads top to bottom: a compact block header, then encode (Original → DCT → Quantized), decode (Dequantized → Reconstructed → Error), then what it costs (four stats beside the quant table).
  • The duplicate Quantized grid is gone. Coefficient editing now happens on the stored Quantized grid.
  • Opens on the top suggested block instead of an empty page.

Hover help

  • Labels a newcomer might not know now explain themselves, marked with a dotted underline.
  • A small app-wide tooltip shows title text after 150 ms instead of the browser's ~1 s delay. Keyboard focus shows it too.

Safer to change

  • CLAUDE.md: layout, commands, contracts and conventions, for coding agents.
  • INSPECTOR_IDS: one registry for the element IDs the inspector's imperative code updates, with a test that each is rendered. It caught a stale lookup straight away.
  • wasm-contracts.test.js checks that the C++ and TypeScript halves agree on view modes, transforms, chroma modes, histogram bins and the block buffer layout.

Testing

  • npm run check: clean.
  • npm run test:all: 270 unit and 46 browser tests pass.
  • Checked by hand in Chromium at desktop and phone widths, in light and dark mode.

CI note: build-native fails at the SonarCloud step with HTTP 403 (the SONAR_TOKEN secret). main has failed the same way since Sep 26. The C++ tests themselves pass.

🤖 Generated with Claude Code

thundermage117 and others added 11 commits October 10, 2026 19:45
Entering the Block Inspector from the viewer used to land on an empty
"click a block" page; it now starts on the first suggested block.

Also drops the sidebar's "Transform" group, which held only a note and
no control, and the emoji in the suggested-block category headers (each
block already carries its own icon).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
"Codec Explorer" instead of "WASM Codec Explorer"; the privacy badge
becomes a small "Runs locally" note and the GitHub link an icon button,
so the header stays on one row on phones.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CodecSettings (transform + chroma subsampling) and ResultSummary
(estimated size, luma PSNR/SSIM, per-channel table on demand) replace
the copies in each mode. The Artifact Analyzer uses both, and its Error
Gain slider moves into a "Display" section with the other map options,
since it changes how the map is drawn rather than the compression.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The viewer now answers "what does compression cost, and what does it
lose?" without setup, and offers each tool once.

- Opens on a Kodak sample already compressed instead of an empty frame;
  drop an image file anywhere on the viewer to load it.
- Image header: Image / Y / Cr / Cb (/ Subbands for wavelets), Zoom and
  Download. The Comparison/Original/Processed toggle is gone (the split
  slider does that; captions name each side), and so is the Error view,
  which the Artifact Analyzer covers properly.
- One "Inspect a block" / "Analyze artifacts" row under the image
  replaces the quickstart banner and the Advanced tools section.
- Sidebar: plain Image / Compression / Result sections instead of the
  Basic / Analysis / Advanced accordions.
- The RD and sparsity charts share one "Compare transforms" card with
  tabs; both compute on their own, no Generate buttons. The RD callout
  row, which repeated the sidebar, is dropped.
- Arrow keys move the comparison split.
- Phones: controls come right after the image, charts last.
- No hover-lift or stagger animations on cards and sections.
- Removes the viewer's unreachable hover-to-inspect path, the old
  CodecControls / MetricsPanel / ToolsPanel, and the CSS only they used.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every term a newcomer might not know now explains itself on hover, with
a dotted underline marking text labels that do:

- Viewer: quality, transform, chroma subsampling, the size estimate,
  per-channel metrics, sample images, chart axes and zeroed shares.
- Block Inspector: each pipeline stage, the colour legend, the
  coordinate and luma/chroma badges, and the sidebar headings. The
  quantization arrows' existing tooltips now say it is the lossy step.
- Artifact Analyzer: what Blink, Heat Map and Grid actually do.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The browser's title tooltip waits about a second and can't be tuned.
A single delegated handler now shows title text (and SVG <title>
children) in a styled tooltip after 150 ms, switching instantly between
neighbouring hints. The native source is set aside while showing so the
two never double up, then restored. Keyboard focus shows the hint too
(without touching the title, which may be the accessible name); touch,
clicks, scrolling and Escape dismiss it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Block Inspector now reads top to bottom: which block, how it is
encoded, how it is decoded and what was lost, then what it cost and why.

- A compact block header (small context crop, position, one line on what
  the page follows) replaces the full-screen Block Context card, so the
  pipeline starts above the fold. The arrow-key hint hides on phones.
- Encode: Original -> DCT -> Quantized, which is now the stored data and
  the grid you edit coefficients on.
- Decode: the duplicate Quantized grid is gone; Dequantized ->
  Reconstructed -> Error, so the loss sits next to the reconstruction.
- "What it costs": four stats instead of six (bits with bits per pixel,
  zeros with their share, MSE, peak error) beside the quant table that
  causes them. The "Quality %" meter becomes "Fidelity" so it isn't
  mistaken for the quality setting.
- The top bar drops its duplicate Luma/Chroma badge; "View Mode" in the
  sidebar becomes "Channel".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The inspector's imperative code finds its elements by ID and skips missing
ones silently, so a renamed element just stopped updating. All such IDs now
live in INSPECTOR_IDS (lib/inspector-dom.ts) and inspection.ts,
grid-renderer.ts and basis-popover.ts use it instead of string literals.

tests/unit/inspector-dom.test.js fails if an ID isn't rendered by a
component, or if lib code looks up an ID outside the registry.

It caught one straight away: the top-bar Luma/Chroma badge removed in the
previous commit was still being written to. The write is gone, and the
remaining badge's id goes back from qTableType2 to qTableType.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
View-mode and transform numbers, the chroma modes, the histogram bin count
and the BlockDebugData buffer layout are each defined once in C++ and once
in TypeScript, with nothing linking them at compile time.
tests/unit/wasm-contracts.test.js reads the C++ sources and compares.

inspection.ts names the block buffer layout as BLOCK_GRID instead of bare
indices, and each side of every pair now says where its other half lives
(comments only on the C++ side, so the WASM build is unchanged).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A one-page guide for coding agents: what each part of the repo does, the
commands and what to run before calling a change done, the C++/TS
contracts and the tests that guard them, the inspector ID rule, and the
conventions and gotchas (checked-in WASM, pinned Svelte plugin, the paused
motion-estimation work).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CI installed Emscripten 'latest', which moved to 6.x. Its emcc no longer
links the C++ standard library when used as the driver, so the WASM link
failed (undefined operator new, __cxa_throw, std::invalid_argument...) and
build-web, and with it deploy, broke.

The Makefile now uses em++, the C++ driver, and CI pins Emscripten to
5.0.1, the version that built the checked-in codec.wasm. Locally, em++
5.0.1 reproduces web/public/codec.{js,wasm} byte for byte.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@thundermage117
thundermage117 changed the base branch from feature/quality-pass to main October 10, 2026 15:26
@sonarqubecloud

Copy link
Copy Markdown

@thundermage117
thundermage117 merged commit 0a4ab7b into main Oct 10, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant