Method — we measure before we design

Design measurement pipeline

Measures how reference sites really move and are typeset, flags what it failed to measure, and scores references against a brief.

  • 5

    reference sites measured

    Palette, type and motion for each. Site names withheld.

    Five references, 2026

  • 4 of 5

    motion probes returned data

    The fifth failed and is marked unmeasured, never read as “no motion”.

    Five references, 2026

  • 0.001s

    the duration an off-the-shelf extractor reported on all five

    A parsing bug. The probe reads computed styles instead: 12 distinct durations on the richest site.

    Five references, 2026

The same figures, restyled

Five references · motion probe

  • Reference A3 curve pairscomplete
  • Reference Bunmeasuredincomplete
  • Reference C15 curve pairscomplete
  • Reference D15 curve pairscomplete
  • Reference E0 transitionsincomplete

A failed probe is unknown, never zero.

The problem

A reference site moves well, but nobody can say how long, or on what curve, so the build guesses.

Before and after

Before

  • Screenshots and a feeling.
  • Durations eyeballed from a recording.
  • A failed capture read as a design choice.

After

  • Durations, easings and properties measured from computed styles.
  • Every reference carries a completeness flag and a list of gaps.
  • A brief is scored against references, and the spec uses numbers, not adjectives.

Measured output — five references

The curves and the type scale, as measured.

Each curve is one measured duration and easing pair, drawn over its real length. Where the probe recorded a custom curve only partially, the curve is shown as unrecorded rather than guessed.

0s0.25s0.5s0.75s1s100%00.12s0.15s0.2s0.3s0.4s0.5s0.52s0.7s1seaseease-in-outcustom curve, recorded only partially: duration known, shape unknown
12 measured pairs, 5 partially recorded, across 4 references with motion data.
  1. Aa50px · 1 ref
  2. Aa40px · 1 ref
  3. Aa36px · 1 ref
  4. Aa32px · 3 refs
  5. Aa27.2px · 1 ref
  6. Aa24px · 2 refs
  7. Aa22px · 2 refs
  8. Aa20px · 2 refs
  9. Aa17px · 1 ref
  10. Aa16px · 5 refs
  11. Aa15px · 2 refs
  12. Aa14px · 4 refs
  13. Aa13.3px · 1 ref
  14. Aa13px · 1 ref
  15. Aa12px · 2 refs
  16. Aa10px · 2 refs
Every distinct font size measured across the references, largest first. Specimens are set in this site’s serif; the families measured are not reproduced.

Run replay

One run, stage by stage.

Five references: five token sets extracted, four motion probes returned data, three references complete. A sample brief kept five patterns and rejected five, each with a reason.

Design decisions

What we chose, and what we turned down.

01

Measure from computed styles.

Rejected

Trust the extractor’s duration field, or read durations off a recording.

Why

The extractor reported 0.001s on all five sites. A probe over computed styles returns real durations, each paired with its easing and property.

02

A failed probe is unknown, never zero.

Rejected

Leave the field empty.

Why

An empty motion field reads as “this site chose stillness”. Each reference carries a quality flag and a list of gaps, and the scorer is told to omit or caveat anything that rests on an incomplete one. A site with zero transitions is recorded as a measured zero, not a failure.

03

Pin the reduced-motion setting inside the probe.

Rejected

Inherit the machine’s setting.

Why

An OS setting or a changed browser default would silently flatten every animation. The probe pins it and says why in a comment.

04

Score fit, not quality.

Rejected

Rank references by how good they look.

Why

Everything in a curated gallery is good, so quality carries no signal. The scorer judges which pattern fits this brief, what it costs, and what it fights with, and lists what it rejected.

Human in control

What a person still decides

The pipeline measures; it does not judge taste. Each reference ships with an empty verdict, and a person fills in what to take and what to leave. Those decisions go into a ledger the scorer reads on the next run.

Mock — illustrative data
ReferenceData qualityWorth keepingWhat to take
Reference Acompleteyesnav fades on scroll, 0.5s
Reference Bincompleteundecided—
Reference Ccompleteno—
Add to ledgerSkipIllustrative data.

The hard part

Every duration read 0.001 seconds

Symptom

The extractor returned a duration of 0.001s for every transition on every site.

First reading

Reduced-motion emulation was zeroing the animations.

Check

It was not. The value was unrelated to the reduced-motion setting.

Root cause

A parsing bug in the extractor’s duration field.

Fix

A separate probe over computed styles, with reduced motion pinned anyway as insurance.

Now guaranteed

Durations are paired with their easings, and the extractor’s values are never used.

Stack

Node and a headless browser for the probe; an open-source token extractor; Python to merge, flag and score; a routed model for the scoring step only.

Cost to run

Measurement needs no paid service. Only the scoring step calls a model.

Where this engineering shows up

Measured, not eyeballed: the same discipline sets the performance budget every direct-booking site we build is held to.

Start here

Turn your website into the place guests book.

If a build makes sense, the teardown says which tier and why. If it doesn’t, it says that too.