Veris
It reads a screen the way a senior designer would — and shows its work.
Scroll to watch one audit travel the whole pipeline — from the frame you select, across the runtime boundary, through six evaluators running at once, to the graded report you read.
One frame in.
A graded critique out.
You select a frame. Veris extracts every node, works out what kind of screen it is, then measures it against contrast, layout, typography, colour, interaction heuristics and your design library — all at once. Nothing leaves your machine unless you turn on AI. Here is exactly how a single run unfolds.
You choose
a frame.
The run begins with your selection — a single frame or the whole page. On mount the UI and the sandbox shake hands (UI_READY → INIT) so the first message is never missed, and the Run button stays in sync with what's selected.
- ›selection audits just the chosen frame(s)
- ›page audits every root frame on the current page
Read the canvas.
SerializedNodesUnderstand
the screen.
Before a single rule runs, inferScreenContext() decides what this screen is — so rules know whether they even apply. Touch-target rules skip desktop; "no empty state" only fires where a list is expected; a component sheet skips palette and hierarchy checks.
The evaluator engine.
Contrast
- ›Reads every text layer and resolves its true, alpha-composited backdrop through ancestors
- ›Checks AA and AAA, non-text control contrast, and text sitting on images without a scrim
- ›Flags gradients & image fills for manual review instead of guessing
Layout
- ›Measures touch targets, tap spacing, input heights and safe-area collisions
- ›Detects off-grid spacing, asymmetric padding and stray corner-radius tokens
- ›Knows the device — skips desktop for touch rules, watches the keyboard zone on mobile
Typography
- ›Judges size, line-height, tracking and real hierarchy — not just how many sizes exist
- ›Enforces the 16px mobile baseline for body and input text (iOS focus-zoom)
- ›Catches long measures, mixed families and text frames that will clip real content
Color
- ›Counts the working palette and folds near-duplicate tokens together
- ›Re-simulates each pair under deuteranopia, protanopia & tritanopia
- ›Notices a near-grayscale palette that may have lost its hierarchy cues
Heuristics
- ›System status, user control, consistency, error prevention & recovery — the 10 heuristics
- ›Mental models: Hick, Miller, Fitts, Jakob, Von Restorff, goal-gradient, peak-end
- ›Deceptive patterns (confirmshaming, false urgency) and microcopy lint
Design Library
- ›Matches every instance against the components you've imported
- ›Spots detached instances, unregistered components and ±2px size drift
- ›Reports overall library coverage — how system-built the screen really is
A second
opinion.
When you enable it, multiple AI providers analyse the same screenshot in parallel via Promise.allSettled. interpretAIResults clusters their findings, dedupes across providers, and blends them in consensus-weighted and capped — AI nudges the score, it never dominates it.
- ›One screenshot, shared across every provider
- ›Keys live in
clientStorage— they never leave your machine - ›A provider error never aborts the audit — rule results still stand
Score & grade.
Each category gets a damped-sigmoid penalty — errors weigh more than warnings, warnings more than infos — then the overall score is a weighted blend, and a letter grade.
- Contrast30%
- Layout20%
- Typography20%
- Heuristics20%
- Color10%
What you get back.
The finished AuditResult renders as a dashboard — a score ring and grade, a card per principle, the top priorities, the inferred-context chip, and a score delta versus the last run of the same target.
Where the eye goes.
- 1Capture & tile the frameScreenshot the frame and slice it into device-sized tiles — the raw pixels the model reads.engine/capture.ts
- 2Neural saliency modelA saliency net (WebGL, WASM fallback) predicts each tile, stitched into one bottom-up "where the eye lands" grid.engine/model.ts
- 3Semantic channels + priorsFaces & text pull gaze on their own; reading follows an F-pattern with above-the-fold decay. Each becomes a grid.semantic.ts · priors.ts
- 4Fuse the channelsNormalized, blended with screen-family weights, fovea-blurred and percentile-normalized so no magnet flattens the map.engine/fusion.ts
- 5Build outputsA heat grid, ranked areas of interest, a deterministic scanpath, and a focus score fall out of the fused grid.engine/outputs.ts
- 6Render on canvasUnderlay, colour-ramped heat, AOI boxes, numbered scanpath and the top attention magnets — deterministic, same frame → same map.ui · AttentionView
One frame, read end to end — extracted, contextualised, measured by six evaluators and 90 rules at once, optionally weighed against AI, scored, graded, and handed back as something you can act on. And when you want to know where attention actually lands, the engine draws that too.