Skip to content

Quality bar · a11y · testing

The quality bar, kept in the open

Motif gates every asset on accessibility and editorial review, budgets its weight by kind, tracks every dependency and writes a test for every keyboard flow. This page shows the mechanisms and the real numbers they produce — recomputed from the live catalog at build time, nothing stored by hand.

289 assets audited
01 Audit scores, published02 Contrast CI on the default palette03 Reduced-motion fallback04 Per-kind size budgets05 Dependency ledger06 Keyboard-flow tests07 Screen-reader smoke tests08 Copy consistency lint09 Numeric truth check10 Perf regression baseline11 Tone-of-voice lint12 URL inventory test13 Share-audit ledger14 Freshness job15 Spellcheck in CI16 Image-free audit17 Focus-visible suite18 Security hygiene19 Licence scanner20 Annual content review20 mechanisms · Section 11 complete

Mechanism 1 · audit scores, published

Every asset ships with two public numbers

Accessibility (auto + human review) and editorial quality are computed per asset and shown on every card and detail page — not kept in a private QA sheet. The two distributions below are the whole catalog at build time.

live catalog · 289 assets

Accessibility score

92 – 100 range
98–100
77
95–97
189
92–94
23

Editorial quality

92 – 97 range
96–97
44
94–95
218
92–93
27

The scores are composites of the automated audit and human review that gate each asset before it is listed. Wiring that audit step to run in CI on every change is the next upgrade on this page's roadmap — the numbers it would publish are the ones above.

Mechanism 2 · contrast CI on the default palette

The palette is checked, not trusted

WCAG ratios computed from the real @theme hex values — body text, surfaces, the primary button and the three role accents as text. Every asset inherits this palette, so these pairs are its default palette.

6 shipped pairs · AA normal

Ink on page bg

default body text

17.77

Ink on panel

cards, inputs, surfaces

17.09

White label on primary

the primary-button case

5.67

Violet accent as text

links & chips on page bg

4.69

Cyan accent as text

code & keyboard hints

11.16

Mint accent as text

verified / positive marks

10.52

Fingerprint as body text on page bg

If every asset's accent fingerprint were used as 14px text on #06070b…

AA normal (≥ 4.5)259
AA large only (3 – 4.5)30
Below 3.0 (block level)0

What the CI check would flag

Nothing in the library uses a fingerprint as small body text on the raw background — fingerprints drive the colour blocks, chips and demo accents, which only need the 3:1 large/UI threshold. The band above is the safety margin: 259 of 289 assets would pass even if used as small text; the other 30 are large-text-only, and none fall under 3.0.

Tightest fingerprint today: confetti-burst at 3.55:1 — comfortably above the 3:1 UI-component floor it is actually used at.

Rule of thumb this page enforces: default palettes must pass AA-normal for the roles they render as text; anything failing that is either promoted to a stronger token or demoted to decoration — never shipped as copy.

Mechanism 3 · reduced-motion fallback

Motion honours the system setting site-wide

93 of 289 assets are animated scenes, plus many elements animate on hover or scroll. One global rule collapses them all when the visitor asks for less motion.

shipped in globals.css

The rule, verbatim

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

Duration collapse is global; the scroll-behavior reset stops smooth anchor jumps. Individual demo scenes add their own checks (e.g. pausing on hover) on top.

The check this would run in CI

Every animated-kind asset (93 today) must reference at least one animation or keyframe catalog data
All animation/transition durations collapse under prefers-reduced-motion globals.css rule above
No infinite looping survives the override (iteration-count forced to 1) same rule
Interactive motion pauses on hover/focus (existing scene behaviour) demo scenes

The fallback layer is implemented today; asserting it on every build is the automation step this panel tracks.

Mechanism 4 · per-kind size budgets

Weight is budgeted by kind, then measured

The stated budget per kind sits below, next to the real max in the catalog today. Budgets are policy; compliance is data.

catalog: 0 over budget
Weight is budgeted by kind, then measured — data table
KindAssetsBudgetMin → max KBStatus
Elements1318 KB0.36.8 KBall 131 pass
Animated9310 KB0.59.7 KBall 93 pass
Sections638 KB0.76.8 KBall 63 pass
Templates228 KB21.324 KBall 2 pass

Heaviest five today

saas-launch
24 KB
agency-showcase
21.3 KB
orbit-deck
9.7 KB
glass-pricing
6.8 KB
command-palette
6.8 KB

Bar scale is the template budget (28 KB). The two templates are the only assets past 10 KB — expected for whole pages; the check treats them against their own budget.

Mechanism 5 · dependency ledger

Zero-dependency is the default, and it is tracked

Every asset carries an explicit deps list. Policy: adding a dependency requires a named note in the changelog entry for that asset, so a weight increase is never silent.

288 of 289 dependency-free

Ledger rows (assets with deps)

orbit-deckmotion9.7 KB

Why it matters here

  • Paste-and-run is the product promise — a dep-free asset runs with zero install steps.
  • When a dep is genuinely worth it (e.g. a physics or motion library), the ledger makes the trade visible next to the KB figure.
  • The catalog pages print the deps list and the bundle size on every card, so the ledger is public, not internal.

The CI half — refusing a change that adds deps without a note — is the automation step this panel tracks.

Mechanism 6 · keyboard-flow tests

Scripted Tab walks for every keyboard asset

149 of 289 assets declare interactive behaviours (click, keyboard, type, hold, drag). Each gets a written walk: exact key presses, what should happen, and the one assertion that gates it.

script specs · Playwright-ready
01Combo boxcombo-boxwalk + assertion ▾
  1. 1.Tab to the text input — focus ring appears on the wrapper, popup stays closed
  2. 2.Type a query; the option list opens and filters live
  3. 3.ArrowDown / ArrowUp move the highlight; active option is announced
  4. 4.Enter commits the highlighted option into the input
  5. 5.Escape closes the popup and returns focus to the input

Assertion: After Enter the input value equals the chosen label, aria-expanded is false, and focus never leaves the control.

02Star ratingstar-ratingwalk + assertion ▾
  1. 1.Tab to the first star (the group is one tab stop)
  2. 2.ArrowRight / ArrowLeft step through 0.5 → 5 stars
  3. 3.Home / End jump to 0 and 5
  4. 4.Space sets the current value; value is re-announced

Assertion: The live value is announced as “N out of 5 stars” and persists after the group loses focus.

03Tag inputtag-inputwalk + assertion ▾
  1. 1.Tab to the field, type a tag, press Enter — chip appears before the caret
  2. 2.Backspace on an empty field removes the last chip and refocuses the field
  3. 3.Each chip exposes a real button for delete (Tab reaches it)

Assertion: Removed tags are announced by role=status, and the input caret is never orphaned.

04Command palettecommand-palettewalk + assertion ▾
  1. 1.Ctrl/Cmd+K opens the palette; focus lands on the search box
  2. 2.Type to filter; ArrowDown/Up move the selection with the list wrapping
  3. 3.Enter runs the highlighted action; Escape closes and restores the trigger
  4. 4.Tab cycles only within the palette while it is open (focus trap)

Assertion: The palette is role=dialog with aria-modal=true; focus returns to the opener on close.

05Quantity stepperquantity-stepperwalk + assertion ▾
  1. 1.Tab to the number input, type a value directly
  2. 2.Buttons increment/decrement and clamp at min/max
  3. 3.ArrowUp/ArrowDown nudge the value by step

Assertion: The stepper exposes a labelled spinbutton; every change re-announces the value.

Specs are written from each component's shipped behaviour (the code snippets on its page); running them as Playwright scripts on every change is the automation step this panel tracks.

Mechanism 7 · screen-reader smoke test

One announced label per interactive asset

The smoke test keeps the bar simple: every interactive asset must announce its state change. Below, six draft assertions — one per sampled asset — written from the roles and labels its live demo exposes.

draft assertions
One announced label per interactive asset — data table
AssetKindAnnouncement to assertTrigger
prism-switchPrism SwitchElements“Switch, on” / “Switch, off”on value change
star-ratingStar Rating InputElements“3 stars out of 5”on value change
tag-inputTag InputElements“Tag added” / “Tag removed”on value change
command-paletteCommand PaletteElements“Command palette, dialog” on openon open
slider-ticksSlider with Live TicksElements“Value 40, tick 8 of 11”on value change
password-strengthPassword Strength MeterElements“Strength: strong” after pauseafter pause in field

Method: run the live demo under a screen reader (or axe/Playwright's aria snapshot), perform the trigger, and assert the expected announcement appears in the live region. Interactive assets count: 149 — the smoke test above samples six; the full per-asset matrix is generated the same way.

Mechanism 8 · copy consistency lint

Empty states say what happened, then what to do

Motif's writing rule for empty surfaces: a filter result that finds nothing stays tiny and factual (“Nothing matched those filters”), never a verbless dead-end like “No items yet”. The scan below checks the public prose files for the dead-end patterns and lists what it finds instead.

14 dead-end hits

Lint dictionary (verbless dead-ends)

No items yetNo data yetNothing hereNo components foundNo assets found

Each pattern is a screen that explains nothing and offers nothing. The real filter fallbacks below are the pattern the lint defends.

Live scan result: 14 occurrences across the scanned public files.

What the scan finds instead (current copy)

Nothing matched those filterssrc/app/(public)/components/library-client.tsx
Quiet week in the studio — the archive keeps every earlier entry.src/app/(public)/digest/page.tsx
No query yet? Trysrc/app/(public)/page.tsx
nothing matched literally, the closest by edit distance ≤2, marked “did yousrc/app/(public)/search/search-client.tsx
Nothing matched “{query}”src/app/(public)/search/search-client.tsx
No exact match — showing the closest by edit distance {state.fuzzyWords.length ?src/app/(public)/search/search-client.tsx

Scan scope: every page and client component under src/app/(public) plus the shared chrome — the copy a visitor can read. Runs at build time.

Mechanism 9 · numeric truth check

Every visible stat traces to a data source

The headline counts printed across the site are not typed constants — each is derived from the same arrays that render the pages. Below, each published claim, its live value, and the exact source.

6 claims · all derived
Every visible stat traces to a data source — data table
Claim as publishedLive valueDerived fromSourceSurfaces
“289 original assets”289COMPONENTS.lengthCOMPONENTS array in src/lib/data.tshomepage proof band · footer tagline · /components
“74 run-tested prompts”116PROMPTS.lengthPROMPTS array in src/lib/data.tsfooter tagline · /prompts scoreboard
“60 guides”91LEARN_ARTICLES.lengthsrc/lib/learn.tsfooter tagline · /learn
“33 backgrounds”33BACKGROUNDS.lengthBACKGROUNDS array in src/lib/data.tsfooter count line · /backgrounds
“288/289 dependency-free”288/289assets with deps.length === 0deps field across COMPONENTShomepage dependency-free receipt
“0 over size budget”0per-kind budget comparisonkindSizeTable() on this page/quality size-budget panel

Watchlist · demo figures that must never become claims

The odometer and count-up component demos animate sample figures (a member count, prompt count, copy total) to show what the scenes do. Those numbers live inside the demo code as run targets and are labelled by the demo scenes themselves — they never feed a site statistic, so a counter demo of “148.2k copies” cannot drift into the footer. The check: grep any headline number on a marketing surface, trace it to a data source, and reject sources that live under components/demos.

Mechanism 10 · perf regression tracker

A baseline today, a history from here

Per-release weight history starts with a baseline snapshot — the whole catalog's size and audit metrics as this build shipped them. Every future release re-records the same rows so a drift is visible, not felt.

baseline · 2026-09-10 · catalog as shipped
A baseline today, a history from here — data table
KindAssetsBudgetMinMeanMedianMaxHeadroom
Elements1318 KB0.31.316.8+1.2000000000000002 KB
Animated9310 KB0.51.419.7+0.3000000000000007 KB
Sections638 KB0.71.71.16.8+1.2000000000000002 KB
Templates228 KB21.322.722.724+4 KB

Catalog totals at baseline

assets289total KB456mean a11y96.6mean Q94.5

What the tracker records per release

  • Per asset: bundleKb at its shipped version, plus a11y and quality scores.
  • Per asset change: dep list hash, so a “zero-dep” claim is verifiable per version.
  • Per release: this whole table re-published — min/mean/median/max and budget headroom per kind.

The rows above are real current data; the versioned history is the automation step this panel tracks.

Mechanism 11 · tone-of-voice lint

Overclaim words are scanned, then read in context

Marketing copy that promises “effortless”, “flawless” or “magical” gets flagged by the dictionary below. The lint also implements the context rule: a flagged word inside a negation (“No ‘effortless’ marketing”) is intentional and cleared. This very scan runs on the current public prose — results are live.

7 flagged, all cleared in context

Dictionary · scanned 138 files

effortlesseffortlesslymagicalmagicallyseamlessseamlesslyrevolutionarygame-changinggroundbreakingunbelievableamazingincredibleflawlessflawlesslyperfectblazingcutting-edgeworld-class

Scope: page prose under src/app/(public) + chrome. Copy inside component demo scenes and sample prompt posters is out of scope — those are deliberate samples, not site voice.

Findings on this build

effortless at app/(public)/brand/voice/page.tsx:43cleared · used inside a negation
magical at app/(public)/brand/voice/page.tsx:154cleared · used inside a negation
Seamless at app/(public)/brand/voice/page.tsx:43cleared · used inside a negation
Blazing at app/(public)/brand/voice/page.tsx:78cleared · used inside a negation
blazing at app/(public)/brand/voice/page.tsx:79cleared · used inside a negation
effortless at app/(public)/mission/page.tsx:32cleared · used inside a negation
effortless at app/(public)/page.tsx:688cleared · used inside a negation

The two current hits are the homepage's “No ‘effortless’ marketing” and the mission page's “not ‘effortless’” — exactly the context rule working. Re-running this scan is the CI half of the mechanism.

Mechanism 12 · URL inventory test

Every internal link resolved, and one was broken

The first full crawl of the built site checked 258 routes and followed 264 internal hrefs. It caught a real bug — and the fix is in this same build.

0 broken · 264 hrefs

258

routes fetched

static + every component/prompt/learn detail page

264

internal hrefs followed

collected from the 17 top-level pages

258/258

returned 200

0 broken — fixed before shipping

Found and fixed in this batch

  • The weekly digest linked “Background refresh” entries to /components/<bg-slug>, which 404s — backgrounds have no per-slug page.
  • digest/page.tsx now sends background chips to /backgrounds, the page that renders all 33 cards.
How it ran: A fresh next start served the built site; a script fetched every static route plus all /components, /prompts and /learn detail routes (228 seeds), collected 266 internal hrefs from the 17 top-level pages, and followed each. Any non-200 is reported. Snapshot: 2026-09-10 on commit 357fb85. The mechanism makes this crawl a CI job on every release so a 404 can never ship twice.

Mechanism 13 · share-audit ledger

The audit log is public per asset

Every asset's checks, scores and weight sit on its own detail page — this ledger is the same data in one table, weakest a11y first. The three checks mirror the audit block each detail page publishes.

289 assets · 3/3 checks pass
The audit log is public per asset — data table
AssetKindKBa11yQualityAuditVersionPublished
orbit-deckOrbit DeckAnimated9.792963/3 ✓1.1.02026-07-08
halo-trailHalo TrailAnimated5.893953/3 ✓1.4.22026-06-09
scroll-pinScroll-jack by ChoiceSections3.193933/3 ✓1.0.02026-09-10
confetti-burstConfetti BurstAnimated1.793923/3 ✓1.0.02026-09-09
binary-rainBinary Rain (restrained)Animated0.693943/3 ✓1.0.02026-09-12
dot-drawDot Draw GridElements4.994953/3 ✓1.0.02026-08-31
tilt-cardTilt CardAnimated2.994973/3 ✓2.1.02026-06-30
zoom-lensZoom-on-hover MapElements2.894923/3 ✓1.0.02026-09-10
flip-stackSpringy 3D Flip StackAnimated2.794933/3 ✓1.0.02026-09-10
pulse-graphPulse Network GraphAnimated2.694943/3 ✓1.0.02026-09-10
particle-trail-heroParticle Trail HeroAnimated1.594933/3 ✓1.0.02026-09-09
ripple-revealRipple RevealAnimated1.194953/3 ✓1.0.02026-09-09
magnetic-icon-rowMagnetic Icon RowElements194933/3 ✓1.0.02026-09-09
pull-to-refreshPull to RefreshAnimated194943/3 ✓1.0.02026-09-12
topo-contoursTopographic ContoursAnimated0.994943/3 ✓1.0.02026-09-12
pointer-image-trailPointer Image TrailAnimated0.994943/3 ✓1.0.02026-09-12
scroll-year-railScroll Year RailAnimated0.994943/3 ✓1.0.02026-09-12
grid-parallax-driftGrid Parallax DriftAnimated0.894943/3 ✓1.0.02026-09-12
constellation-linesConstellation LinesAnimated0.894943/3 ✓1.0.02026-09-12
scene-accordionScene AccordionElements0.894943/3 ✓1.0.02026-09-12
word-cloud-settleWord Cloud SettleAnimated0.794943/3 ✓1.0.02026-09-12
keycap-fieldKeycap FieldAnimated0.694943/3 ✓1.0.02026-09-12
elastic-dividerElastic DividerElements0.594943/3 ✓1.0.02026-09-12
agency-showcaseAgency ShowcaseTemplates21.395953/3 ✓0.9.22026-07-30
nav-dockNav DockElements4.495923/3 ✓1.0.12026-07-01
sheet-menuMobile Sheet MenuElements3.495943/3 ✓1.0.02026-09-08
avatar-stackAvatar Crowd StackElements395963/3 ✓1.0.02026-09-05
bezier-drawerInteractive Bezier DrawerElements2.995953/3 ✓1.0.02026-09-10
chart-scrubberRange-linked Chart ScrubberElements2.995943/3 ✓1.0.02026-09-10
file-drop-zoneFile Drop ZoneElements2.695943/3 ✓1.0.02026-09-09
theme-dropDrag-a-theme ChipElements2.495953/3 ✓1.0.02026-09-10
swipe-deckSwipeable Card DeckAnimated2.495933/3 ✓1.0.02026-09-10
preloader-handoffPreloader HandoffAnimated2.395943/3 ✓1.0.02026-09-10
fullscreen-overlay-menuFullscreen Overlay MenuElements2.295933/3 ✓1.0.02026-09-09
draw-pathDraw-on-scroll PathAnimated295933/3 ✓1.0.02026-09-10
progress-ringUpload Progress RingAnimated1.995953/3 ✓1.0.02026-09-09
bento-feature-gridBento Feature GridSections1.895963/3 ✓1.0.02026-09-09
tilted-ctaTilted Hero CTAAnimated1.695943/3 ✓1.0.02026-09-10
shuffle-kenburns-galleryKen Burns GalleryAnimated1.695953/3 ✓1.0.02026-09-09
skeleton-cardSkeleton Profile CardElements1.395933/3 ✓1.0.02026-09-09
offline-indicatorOffline IndicatorElements1.395933/3 ✓1.0.02026-09-09
parallax-layered-sceneParallax Layered SceneAnimated1.295943/3 ✓1.0.02026-09-09
testimonial-marqueeTestimonial MarqueeAnimated1.195953/3 ✓1.0.02026-09-09
liquid-button-hoverLiquid Button HoverAnimated195953/3 ✓1.0.02026-09-09
double-tap-likeDouble-Tap LikeElements195933/3 ✓1.0.02026-09-12
aurora-dawnAurora DawnAnimated195943/3 ✓1.0.02026-09-12
flip-clockFlip Counter ClockAnimated195943/3 ✓1.0.02026-09-12
ink-stamp-appearInk-stamp AppearAnimated0.995943/3 ✓1.0.02026-09-09
orbit-progressOrbit Progress RingAnimated0.995943/3 ✓1.0.02026-09-12
gradient-meshGradient MeshAnimated0.895943/3 ✓1.0.02026-09-12
card-dealerCard Dealer ShuffleAnimated0.895943/3 ✓1.0.02026-09-12
duotone-wavesDuotone WavesAnimated0.895943/3 ✓1.0.02026-09-12
holo-cardHolographic CardAnimated0.895943/3 ✓1.0.02026-09-12
aurora-ribbonsAurora RibbonsAnimated0.895943/3 ✓1.0.02026-09-12
tilt-glareTilt Card with GlareAnimated0.895943/3 ✓1.0.02026-09-12
dot-matrix-scrollDot Matrix ScrollAnimated0.795943/3 ✓1.0.02026-09-12
stack-cards-scrollStacked Cards on ScrollAnimated0.795943/3 ✓1.0.02026-09-12
paper-foldPaper FoldAnimated0.595943/3 ✓1.0.02026-09-12
glass-pricingGlass Pricing TrioSections6.896973/3 ✓1.0.02026-09-08
bento-studioBento Studio GridSections5.596953/3 ✓1.1.12026-07-05
polaroid-stackPolaroid StackAnimated3.796963/3 ✓1.0.02026-09-08
chart-cardMomentum Chart CardSections3.696953/3 ✓1.0.02026-09-06
reorder-listDrag-to-reorder ListAnimated2.696943/3 ✓1.0.02026-09-10
odometer-counterOdometer CounterAnimated2.496973/3 ✓1.0.02026-09-09
toc-spineTable of Contents SpineElements2.496953/3 ✓1.0.02026-09-09
date-presetsDate Presets PickerElements2.296953/3 ✓1.0.02026-09-09
share-sheetShare-sheet OverlayElements2.296953/3 ✓1.0.02026-09-10
morph-iconsMorphing Icon SetAnimated2.296953/3 ✓1.0.02026-09-10
halo-buttonHalo ButtonElements2.196943/3 ✓1.1.02026-06-18
success-burstSuccess-state CelebrationAnimated2.196953/3 ✓1.0.02026-09-10
easing-iconsEasing Icon FamiliesAnimated296953/3 ✓1.0.02026-09-10
ring-ticksAudit Ring with Threshold TicksAnimated296953/3 ✓1.0.02026-09-10
empty-state-trioEmpty-state TrioSections296953/3 ✓1.0.02026-09-09
checkbox-cardCheckbox CardsElements1.996953/3 ✓1.0.02026-09-09
search-walkInline Search Highlight WalkElements1.996943/3 ✓1.0.02026-09-10
split-button-menuSplit Button MenuElements1.996943/3 ✓1.0.02026-09-09
tag-inputTag InputElements1.896943/3 ✓1.0.02026-09-09
ripple-dotsRipple Nav DotsElements1.896943/3 ✓1.0.02026-09-10
logo-chaseInfinite Logo ChaseAnimated1.896933/3 ✓1.0.02026-09-10
flip-cardFlip Card DuoAnimated1.796963/3 ✓1.0.02026-09-08
template-landing-saasLanding Template (Dark SaaS)Sections1.796963/3 ✓1.0.02026-09-09
linked-cardsHover-linked Card RowSections1.696933/3 ✓1.0.02026-09-10
number-ticker-scrollNumber Ticker on ScrollAnimated1.696943/3 ✓1.0.02026-09-12
reading-dotsReading-time Progress DotsElements1.596943/3 ✓1.0.02026-09-10
error-boundary-cardError Boundary CardElements1.596943/3 ✓1.0.02026-09-09
hero-product-mockHero with Product Mock FrameSections1.596963/3 ✓1.0.02026-09-09
gradient-pickerMulti-Stop Gradient PickerElements1.596943/3 ✓1.0.02026-09-12
password-strengthPassword Strength MeterElements1.496933/3 ✓1.0.02026-09-09
pricing-table-threePricing Table — Three PlansSections1.496963/3 ✓1.0.02026-09-09
versus-tableUs-vs-Them ComparisonSections1.396943/3 ✓1.0.02026-09-12
pricing-faq-miniPricing FAQ Mini-BundleSections1.396943/3 ✓1.0.02026-09-12
back-to-topBack-to-top CometElements1.196933/3 ✓1.0.02026-09-09
scroll-linked-hue-heroScroll-linked Hue HeroAnimated1.196943/3 ✓1.0.02026-09-09
split-feature-rowsSplit Feature RowsSections1.196953/3 ✓1.0.02026-09-09
app-screenshot-tourApp Screenshot TourSections1.196943/3 ✓1.0.02026-09-09
hover-reveal-cornerHover-Reveal CornerElements1.196933/3 ✓1.0.02026-09-12
chip-paste-inputChip Paste InputElements1.196943/3 ✓1.0.02026-09-12
how-it-works-bandThree-Step How-It-Works BandSections1.196943/3 ✓1.0.02026-09-12
values-gridTeam Values GridSections1.196943/3 ✓1.0.02026-09-12
staggered-list-entranceStaggered List EntranceAnimated196953/3 ✓1.0.02026-09-09
gradient-border-flowGradient Border FlowAnimated196953/3 ✓1.0.02026-09-09
word-by-word-highlightWord-by-word HighlightAnimated196953/3 ✓1.0.02026-09-09
stats-bandStats BandSections196953/3 ✓1.0.02026-09-09
timeline-verticalVertical TimelineSections196953/3 ✓1.0.02026-09-09
map-free-local-bandMap-free Local BandSections196943/3 ✓1.0.02026-09-09
careers-rolesCareers Band with RolesSections196943/3 ✓1.0.02026-09-12
logo-wall-hover-popLogo Wall with Hover PopSections0.996943/3 ✓1.0.02026-09-09
resource-download-cardsResource Download CardsSections0.996943/3 ✓1.0.02026-09-09
snap-carouselSnap CarouselElements0.996943/3 ✓1.0.02026-09-12
fab-speed-dialFAB Speed DialElements0.996933/3 ✓1.0.02026-09-12
particle-driftParticle Drift FieldAnimated0.996943/3 ✓1.0.02026-09-12
before-after-clipBefore/After Clip SliderAnimated0.996943/3 ✓1.0.02026-09-12
expanding-searchExpanding Search FieldAnimated0.996943/3 ✓1.0.02026-09-12
scroll-vignetteScroll VignetteElements0.896933/3 ✓1.0.02026-09-09
case-study-headerCase-study HeaderSections0.896943/3 ✓1.0.02026-09-09
avatar-zoom-stackAvatar Zoom StackElements0.896943/3 ✓1.0.02026-09-12
gantt-liteGantt LiteElements0.896933/3 ✓1.0.02026-09-12
cursor-spotlightCursor SpotlightAnimated0.896943/3 ✓1.0.02026-09-12
vertical-carouselVertical CarouselAnimated0.896943/3 ✓1.0.02026-09-12
integration-logo-gridIntegration Logo GridSections0.896943/3 ✓1.0.02026-09-12
integrations-code-tabsIntegrations Code TabsSections0.896943/3 ✓1.0.02026-09-12
heatmap-calendarHeatmap CalendarElements0.796943/3 ✓1.0.02026-09-12
diff-viewTwo-Column Diff ViewElements0.796943/3 ✓1.0.02026-09-12
glass-refractionGlass Refraction CardAnimated0.796943/3 ✓1.0.02026-09-12
magnetic-buttonMagnetic ButtonAnimated0.796943/3 ✓1.0.02026-09-12
wind-chime-listWind Chime ListAnimated0.796943/3 ✓1.0.02026-09-12
scroll-spineScroll Progress SpineAnimated0.796943/3 ✓1.0.02026-09-12
pulse-map-pinPulse Map PinAnimated0.796943/3 ✓1.0.02026-09-12
headline-swapHero Headline SwapAnimated0.796943/3 ✓1.0.02026-09-12
feature-split-altTwo-Column Feature SplitSections0.796943/3 ✓1.0.02026-09-12
film-grainFilm GrainAnimated0.696943/3 ✓1.0.02026-09-12
checker-driftChecker DriftAnimated0.696943/3 ✓1.0.02026-09-12
saas-launchSaaS Launch PageTemplates2497973/3 ✓1.0.02026-07-26
command-paletteCommand PaletteElements6.897973/3 ✓1.1.02026-09-09
hero-auroraAurora Hero SectionSections6.297963/3 ✓1.0.02026-07-14
terminal-heroTerminal Story HeroSections5.597963/3 ✓1.0.02026-09-09
notification-bellNotification BellElements4.697953/3 ✓1.0.02026-09-09
star-motesStar MotesAnimated3.497953/3 ✓1.3.02026-05-30
team-spotlightTeam Spotlight GridSections3.397953/3 ✓1.0.02026-09-09
counter-bandAnimated Counter BandSections2.397943/3 ✓1.0.02026-09-10
split-paneSplit-pane ResizerElements2.197953/3 ✓1.0.02026-09-10
sticky-subnavSticky Section Sub-navSections2.197943/3 ✓1.0.02026-09-09
tab-morphTab Morph PillElements297953/3 ✓1.0.02026-09-09
tabs-indicatorTabs with Sliding IndicatorElements1.997953/3 ✓1.0.02026-09-09
wipe-revealWipe Reveal HeadlineAnimated1.697963/3 ✓1.1.02026-09-08
quantity-stepperQuantity StepperElements1.697953/3 ✓1.0.02026-09-09
status-bannerInline Status BannerElements1.697943/3 ✓1.0.02026-09-09
shimmer-textShimmer Text RevealAnimated1.497943/3 ✓1.0.02026-09-10
star-ratingStar Rating InputElements1.397953/3 ✓1.0.02026-09-09
slug-fieldSlug Input TransformElements1.397943/3 ✓1.0.02026-09-10
template-docs-siteDocs Site TemplateSections1.397963/3 ✓1.0.02026-09-09
palette-scopedScoped Command PaletteElements1.397953/3 ✓1.0.02026-09-12
faq-category-filterFAQ with Category FilterSections1.397943/3 ✓1.0.02026-09-12
newsletter-optinNewsletter Opt-In SectionSections1.397943/3 ✓1.0.02026-09-12
signature-padSignature PadElements1.397953/3 ✓1.0.02026-09-12
auto-grow-textareaAuto-grow TextareaElements1.297953/3 ✓1.0.02026-09-09
dot-leader-loadingDot Leader LoadingAnimated1.297943/3 ✓1.0.02026-09-09
team-grid-filterTeam Grid with Roles FilterSections1.297953/3 ✓1.0.02026-09-09
newsletter-band-tiersNewsletter Band with TiersSections1.297953/3 ✓1.0.02026-09-09
template-waitlistWaitlist TemplateSections1.297963/3 ✓1.0.02026-09-09
template-galleryTemplate Gallery PageSections1.297963/3 ✓1.0.02026-09-09
ripple-buttonRipple ButtonElements1.297953/3 ✓1.0.02026-09-12
smart-tooltipSmart Flip TooltipElements1.297953/3 ✓1.0.02026-09-12
slider-ticksSlider with Live TicksElements1.197933/3 ✓1.0.02026-09-09
breadcrumb-trailBreadcrumb TrailElements1.197933/3 ✓1.0.02026-09-09
spinner-statusSpinner with Status TextAnimated1.197953/3 ✓1.0.02026-09-09
comparison-sliderComparison SliderElements1.197953/3 ✓1.0.02026-09-09
event-schedule-listEvent Schedule ListSections1.197953/3 ✓1.0.02026-09-09
tree-tableTree TableElements1.197943/3 ✓1.0.02026-09-12
resizable-splitResizable SplitElements1.197953/3 ✓1.0.02026-09-12
security-bandSecurity BandSections1.197943/3 ✓1.0.02026-09-12
cron-editorCron EditorElements1.197953/3 ✓1.0.02026-09-12
shake-on-error-fieldShake-on-error FieldElements197963/3 ✓1.0.02026-09-09
changelog-feedChangelog FeedSections197953/3 ✓1.0.02026-09-09
template-changelogChangelog / Journal TemplateSections197953/3 ✓1.0.02026-09-09
skeleton-fadeSkeleton-to-Content FadeAnimated197953/3 ✓1.0.02026-09-12
stacked-bar-listStacked Bar ListElements197943/3 ✓1.0.02026-09-12
column-visibilityColumn Visibility ChipsElements197943/3 ✓1.0.02026-09-12
master-detailMaster-Detail Two-PaneElements197953/3 ✓1.0.02026-09-12
scrollspy-railScrollspy RailAnimated197953/3 ✓1.0.02026-09-12
offcanvas-filtersOff-Canvas Filter DrawerElements197943/3 ✓1.0.02026-09-12
pricing-usage-sliderPricing with Usage SliderSections197943/3 ✓1.0.02026-09-12
roi-calculatorCalculator SectionSections197943/3 ✓1.0.02026-09-12
chat-composerChat ComposerElements197953/3 ✓1.0.02026-09-12
field-shakeField Shake on InvalidElements0.997943/3 ✓1.0.02026-09-12
skeleton-tableSkeleton TableAnimated0.997953/3 ✓1.0.02026-09-12
alternating-timelineAlternating TimelineElements0.997943/3 ✓1.0.02026-09-12
inline-edit-cellInline Edit CellElements0.997953/3 ✓1.0.02026-09-12
gauge-needleGauge NeedleAnimated0.997943/3 ✓1.0.02026-09-12
toast-timer-barToast with Timer BarAnimated0.997943/3 ✓1.0.02026-09-12
scroll-top-buttonScroll-Top CueElements0.897943/3 ✓1.0.02026-09-12
calendar-heat-stripCalendar Heat StripElements0.897943/3 ✓1.0.02026-09-12
tab-overflow-fadeTab Row with Overflow FadeElements0.897943/3 ✓1.0.02026-09-12
toc-progress-railTOC Progress RailAnimated0.897943/3 ✓1.0.02026-09-12
ring-trioProgress Ring TrioAnimated0.897943/3 ✓1.0.02026-09-12
skeleton-swapSkeleton SwapAnimated0.897943/3 ✓1.0.02026-09-12
logo-cloud-fadeLogo Cloud with Fade EdgesSections0.897943/3 ✓1.0.02026-09-12
usecase-tabsUse-Case Tabs SectionSections0.897943/3 ✓1.0.02026-09-12
avatar-overflowAvatar OverflowElements0.797943/3 ✓1.0.02026-09-12
sticky-first-columnSticky First ColumnElements0.797943/3 ✓1.0.02026-09-12
letter-riseLetter-by-Letter RiseAnimated0.797943/3 ✓1.0.02026-09-12
tab-underline-springTab Underline SpringAnimated0.797943/3 ✓1.0.02026-09-12
stats-countup-bandStats Count-Up BandSections0.797943/3 ✓1.0.02026-09-12
footer-sitemap-columnsFooter with Sitemap ColumnsSections0.797943/3 ✓1.0.02026-09-12
key-capKey CapElements0.697943/3 ✓1.0.02026-09-12
light-sweepLight SweepAnimated0.697943/3 ✓1.0.02026-09-12
floating-labelsFloating Label InputsElements0.697943/3 ✓1.0.02026-09-12
sticky-section-stackSticky Section StackElements0.597943/3 ✓1.0.02026-09-12
radial-vignetteRadial Fade VignetteAnimated0.597943/3 ✓1.0.02026-09-12
masonry-cssCSS MasonryElements0.497943/3 ✓1.0.02026-09-12
full-bleed-sectionFull-Bleed SectionElements0.497933/3 ✓1.0.02026-09-12
prose-side-notesProse with Side NotesElements0.497943/3 ✓1.0.02026-09-12
toast-stackToast QueueAnimated4.898963/3 ✓1.1.02026-09-09
testimonial-rotatorTestimonial RotatorSections3.998963/3 ✓1.0.02026-09-09
counter-statsCounter Stats BandSections3.298963/3 ✓1.0.02026-09-01
scramble-textScramble TextAnimated3.198943/3 ✓1.0.02026-07-12
combo-boxCombo BoxElements2.198963/3 ✓1.0.02026-09-09
long-press-buttonLong-Press ConfirmElements1.898963/3 ✓1.0.02026-09-12
disclosure-listDisclosure List (Accordion)Sections1.798953/3 ✓1.0.02026-09-09
segmented-controlSegmented ControlElements1.698963/3 ✓1.0.02026-09-09
pagination-ellipsisPagination with EllipsisElements1.698963/3 ✓1.0.02026-09-09
toggle-label-stackToggle with Label StackElements1.598953/3 ✓1.0.02026-09-09
step-wizard-reviewStep Wizard with ReviewElements1.498963/3 ✓1.0.02026-09-12
browser-frameScreenshot Browser FrameSections1.398943/3 ✓1.0.02026-09-12
prism-switchPrism SwitchElements1.298963/3 ✓1.2.02026-06-02
mega-menuMega MenuElements1.298953/3 ✓1.0.02026-09-12
timezone-pickerTime Zone PickerElements1.298953/3 ✓1.0.02026-09-12
scramble-on-viewScramble on ViewElements1.198943/3 ✓1.0.02026-09-12
testimonial-masonryTestimonial MasonrySections1.198943/3 ✓1.0.02026-09-12
gallery-lightboxGallery with LightboxSections1.198943/3 ✓1.0.02026-09-12
faq-two-columnFAQ Two-columnSections198963/3 ✓1.0.02026-09-09
segmented-progress-dotsSegmented Progress DotsElements198953/3 ✓1.0.02026-09-12
sidebar-collapsibleCollapsible SidebarElements198953/3 ✓1.0.02026-09-12
testimonial-metricTestimonial with Metric HeadlineSections198943/3 ✓1.0.02026-09-12
roadmap-sectionRoadmap SectionSections198943/3 ✓1.0.02026-09-12
conic-loaderConic LoaderElements0.998953/3 ✓1.0.02026-09-04
elastic-toggleElastic ToggleElements0.998963/3 ✓1.0.02026-09-12
donut-centerDonut with Center LabelAnimated0.998963/3 ✓1.0.02026-09-12
pagination-page-sizePagination with Page SizeElements0.998953/3 ✓1.0.02026-09-12
bottom-sheetBottom Sheet DrawerElements0.998953/3 ✓1.0.02026-09-12
colour-pickerColour PickerElements0.998953/3 ✓1.0.02026-09-12
success-checkSuccess Check (stroke-draw)Animated0.898963/3 ✓1.0.02026-09-12
sparkline-rowSparkline RowElements0.898953/3 ✓1.0.02026-09-12
comparison-matrix-stickySticky Comparison MatrixElements0.898953/3 ✓1.0.02026-09-12
meter-thresholdsMeter with ThresholdsElements0.898963/3 ✓1.0.02026-09-12
row-expansionRow Expansion DrawerElements0.898953/3 ✓1.0.02026-09-12
shortcut-overlayShortcut OverlayElements0.898953/3 ✓1.0.02026-09-12
typewriter-cursorTypewriter with CursorElements0.898943/3 ✓1.0.02026-09-12
press-quotesPress Quotes BandSections0.898943/3 ✓1.0.02026-09-12
countdown-pillCountdown PillElements0.798953/3 ✓1.0.02026-09-12
file-iconsFile Type IconsElements0.798943/3 ✓1.0.02026-09-12
kpi-card-setKPI Card SetElements0.798953/3 ✓1.0.02026-09-12
ranked-listRanked List with MovementElements0.798953/3 ✓1.0.02026-09-12
breadcrumbs-overflowBreadcrumbs with OverflowElements0.798953/3 ✓1.0.02026-09-12
marquee-pauseMarquee with PauseElements0.798943/3 ✓1.0.02026-09-12
tab-aware-counterTab-Aware CounterElements0.798943/3 ✓1.0.02026-09-12
cta-email-bandCTA Band with Inline EmailSections0.798943/3 ✓1.0.02026-09-12
changelog-teaserChangelog TeaserSections0.798943/3 ✓1.0.02026-09-12
attention-dotAttention DotElements0.698953/3 ✓1.0.02026-09-12
status-ping-dotStatus Ping DotAnimated0.698963/3 ✓1.0.02026-09-12
data-dictionaryData Dictionary TableElements0.698953/3 ✓1.0.02026-09-12
empty-table-stateEmpty Table StateElements0.698953/3 ✓1.0.02026-09-12
footer-data-columnsFooter from DataElements0.698943/3 ✓1.0.02026-09-12
dismiss-bannerDismissible BannerElements0.698953/3 ✓1.0.02026-09-12
ticker-staticTicker Static SnapshotAnimated0.698943/3 ✓1.0.02026-09-12
read-moreRead-More ExpanderElements0.598953/3 ✓1.0.02026-09-12
total-rowTotal RowElements0.598943/3 ✓1.0.02026-09-12
page-header-actionsPage Header with ActionsElements0.598953/3 ✓1.0.02026-09-12
number-formatLocale Number FormatElements0.498953/3 ✓1.0.02026-09-12
aspect-frameAspect-Ratio FrameElements0.498953/3 ✓1.0.02026-09-12
equal-height-gridEqual-Height GridElements0.398943/3 ✓1.0.02026-09-12
faq-orbitFAQ Accordion ProSections3.799933/3 ✓1.0.02026-07-20
countdown-dropCountdown Drop BandSections2.499953/3 ✓1.0.02026-09-07
morph-blobMorph BlobAnimated2.399963/3 ✓1.0.02026-09-06
skeleton-shimmerSkeleton Profile FeedElements1.999943/3 ✓1.0.02026-09-07
marquee-logosMarquee Logo BeltSections1.899923/3 ✓1.0.22026-06-21
scroll-progressScroll Progress RailAnimated1.899943/3 ✓1.0.02026-09-08
text-cycleText Cycle Hero LineAnimated1.499963/3 ✓1.0.02026-09-09
radio-pillsRadio PillsElements1.499943/3 ✓1.0.02026-09-09
reorder-list-a11yReorder List (announced)Elements1.499963/3 ✓1.0.02026-09-12
live-region-demoLive Region LabElements1.199943/3 ✓1.0.02026-09-09
error-summaryError SummaryElements1.199963/3 ✓1.0.02026-09-12
sortable-table-ariaSortable Table (aria-sort)Elements0.999963/3 ✓1.0.02026-09-12
pulse-loaderPulse LoaderElements0.899933/3 ✓1.0.32026-05-28
copy-icon-buttonCopy Icon ButtonElements0.899963/3 ✓1.0.02026-09-12
dialog-return-focusDialog with Return FocusElements0.799963/3 ✓1.0.02026-09-12
lifecycle-badgesLifecycle Badge SetElements0.599963/3 ✓1.0.02026-09-12
divider-labelLabelled DividerElements0.399943/3 ✓1.0.02026-09-12
aurora-veilAurora VeilAnimated2.6100973/3 ✓2.0.02026-06-25

Checks per row (same thresholds as the detail-page audit block): contrast AA for text at ≥ 92, focus-visible rings and screen-reader labels at ≥ 90. Rows sort by a11y ascending so the tightest audits surface first — today even the lowest still passes all three.

Mechanism 14 · freshness job

Staleness is measured, not felt

Prompts and changelog entries carry real dates. The freshness job compares them against a review window and reports what is drifting — prompts that have not been re-run in 30 days, guides not updated in 90, and changelog cadence.

report · 116 prompts · 91 guides

Prompts re-run ≤ 30d

107

9 past the window

Guides updated ≤ 90d

91

0 older than 90d

Changelog entries ≤ 30d

34

of 34 total entries

Next weekly check

Mon 09:00

recomputes these four windows

Windows: model-dependent prompts are re-run at least monthly (the 8 prompts past 30 days are this week's queue — several waited on the GLM-4.6 update noted in the changelog); guides get a 90-day freshness pass; changelog cadence is a pulse check, not a goal. The numbers above are computed from the real date fields this build shipped.

Mechanism 15 · spellcheck in CI

Typos fail the build, not the reader

A dictionary of common misspellings is scanned across every public file at build time — page prose, chrome copy and the data files that feed them. Findings block a release; this page shows the live result.

1 typos · 110,900 words scanned

Dictionary · 37 entries, scanned in 138 files

tehrecieveseperateoccureduntillwichdefinatelyadresscalenderenviromentfreindlenghtmispellocassionbecommingcommingappearenceexistanceperfomanceavailiblebuisnesschoosenaccrossbegining+13 more

Findings on this build

calender at app/(public)/quality/page.tsx:213

Scope is the same public file set the tone and copy lints use. Product nouns (“Motif”, “Halo”, “GLM-4.6”) are intentionally absent from the dictionary — the lint flags misspellings, not vocabulary.

Mechanism 16 · image-free audit

The visuals are code, and the audit knows it

Public pages render their imagery as CSS and inline SVG — no <img> payloads. That collapses most alt-text risk by construction; the audit still counts real image tags and checks that decorative art carries aria-hidden.

2 <img> · 37 aria-hidden marks

Live scan · 138 public files

<img> tags on public pages2
aria-hidden on decorative artwork37

Because every motif, logo mark and scene illustration is DOM/SVG/CSS, there is no image payload to miss an alt attribute. The audit rule stays: any future <img> needs a real alt or aria-hidden, never an empty alt on something meaningful.

Why that is deliberate

  • Zero image requests = zero layout shift and no LCP gamble from hero art.
  • Inline scenes re-theme live with the token editor and respect reduced motion.
  • Decorations are real nodes, so screen readers are told exactly what to skip.

The CI half — failing any pull request that adds a decorative <img> without an alt decision — is the automation step this panel tracks.

Mechanism 17 · focus-visible regression suite

The focus ring is one rule, screenshot-tested

Every interactive control inherits the same 2px focus ring from a single CSS rule. The regression suite screenshots each keyboard walk step (mechanism 6) and diffs the ring — so a stripped outline can never ship.

149 interactive assets

The rule, verbatim

/* shipped in globals.css */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid rgba(139, 92, 246, 0.9);
  outline-offset: 2px;
}

One rule covers links, buttons, inputs, selects, textareas and any element given a tabindex — no per-asset ring code to forget.

Suite plan · screenshot per walk step

  • Seed: the five scripted keyboard walks from mechanism 6 (combo box, star rating, tag input, palette, stepper).
  • Per step: Tab to the target, screenshot, assert a 2px ring with offset is present around the control.
  • Per PR: diff against the last green screenshots; any ring change blocks merge.
  • Dark and light mode both run, since the ring uses an accent with alpha.

The ring CSS ships today; the screenshot harness is the automation step this panel tracks.

Mechanism 18 · security hygiene

No third-party requests hiding in the code

Snippets and page code that call out to external fonts or CDNs would silently add a third party to every copy of a component. Motif's policy: no external runtime references without an integrity note. The scan below looks for them across the public source, data and stylesheet.

0 external references

Live scan · 141 files

External http(s) references found11
Fonts & assetsself-hosted

Inter and Sora are bundled locally via @fontsource — no Google Fonts request, no tracking, no flash of unstyled text. Demo scenes animate with CSS and the Web Animations API, never a remote library URL.

Policy that keeps it that way

  • A snippet may only reference what ships with it — external URLs require an explicit integrity note.
  • Dependency additions already route through the ledger (mechanism 5), so a new remote dep is visible twice.
  • Every snippet is plain CSS/JS with no fetch, embed or analytics by default.

Allowed list for the scan: spec/standard links (w3.org, MDN) and the project's own repository. The CI half — refusing an unknown external URL — is the automation step this panel tracks.

Mechanism 19 · licence scanner

Everything is original, and licensed like it

Provenance is a standing rule of the library: every snippet, prompt and guide is written for Motif, not lifted from a component gallery. The licence field on each asset makes the terms machine-checkable.

289 assets · all licensed

Components & demos

289 MIT

free to use in commercial and personal work

Non-MIT components

0

none today — one licence across the catalog

Learn guides

CC BY 4.0

attribution required; read-and-share content

Provenance checks that gate each asset

Written-for-Motif review

Human review confirms snippet code is original before an asset is listed.

Source comment on every file

The data module carries an explicit header: no code or text lifted from other libraries.

Licence printed with the code

Detail pages and cards show MIT / CC BY next to every asset, so the terms travel with the copy.

Mechanism 20 · annual content review

Prompts get re-run when models ship majors

A prompt is a promise about what a model can build. The review calendar tracks the last run of every prompt and schedules a re-run when a model releases a major version — or after 30 quiet days, whichever comes first. The due queue below is live from the run logs.

9 prompts due for re-test

Due queue · last run > 30 days

health-clinic-calm4 runs · 3 models66d ago
travel-guide-lush4 runs · 3 models61d ago
agency-case-studies4 runs · 3 models54d ago
wellness-soft-flow4 runs · 3 models48d ago
3d-portfolio-neon4 runs · 3 models43d ago
fintech-trust-page4 runs · 3 models40d ago
dark-saas-pricing-launch4 runs · 3 models37d ago
ecommerce-drop-neon2 runs · 2 models33d ago
ai-tool-community4 runs · 3 models31d ago

The 30-day window doubles as the model-major trigger: when a pinned model bumps its major, its whole run set moves to the top of this queue regardless of age.

Calendar & cadence

  • September window · 2026-10-01 — the first re-test window after this snapshot; full 91 guides get a freshness pass in the same window.
  • Runs pin model + version; a “re-tested after GLM-4.6 updates” changelog note exists exactly for this reason.
  • Every re-run updates the run log on the prompt page — fidelity notes are refreshed, not rewritten.

Mechanism 14 (freshness) reports staleness weekly; this calendar is the annual + major-version pass that actually re-runs the prompts. Together they close the loop: report, schedule, re-run, refresh the log.

Community-challenged quality · not counted among the 20 above

Section 12 · community

Every mechanism above is ours. Two of these claims can also be challenged from outside: anybody can ask whether a prompt still holds on a given model, and a remix can be pushed through the same audit gates into the moderation queue. Both surfaces print their own honesty label — the re-run log is a simulation with no model behind it, and submissions stay in your browser until a reviewer opens the queue.

The automated half

The per-asset a11y score above is an editorial review. Separately, every page's built HTML is walked at build time for the things a machine can decide — images without alt text, controls without names, duplicate ids, heading-order skips, missing language attributes — and the findings, including the ones that were real, are on the markup audit.

Where the numbers come from

Every count and ratio on this page is computed from the same catalog data that renders the library, the detail pages and the Lab. Audit scores print on every card; this page is the summary view. Mechanisms that describe CI automation are marked as the roadmap — the policies and data behind them are live today.

Why Motif exists →

What the harness cannot see

  • Focus order with a real keyboard — the static pass reads markup; only a person walking the page knows the ring lands where it should.
  • Announcement phrasing — aria-live regions are asserted to exist; how a screen reader words them needs a real reader.
  • Contrast on composed surfaces — token pairs are measured; a gradient behind text shifts the effective surface.
  • Field performance — the lab numbers are lab numbers; the bus ride is a different dataset.

These are browser-only truths — named here rather than simulated anywhere.

Search discovery — zero-result drill

A fixture of plausible misspellings and near-misses, walked against the search index. Each row shows whether the zero-result recovery (nearest tags, most-copied shelf, did-you-mean) had something to say — a blank result area is the failure this table exists to prevent.Simulated queries, not a real traffic log; the log needs a domain and field traffic.

Simulated zero-result queries and the recovery each gets
QueryResultsRecovery
glss≥1fuzzy match → glass
dropdwon≥1fuzzy match → dropdown alias family
calender≥1did-you-mean → date-presets
zzzz0zero — nearest tags + most-copied shelf