Every line is a test in three engines or a gate on every commit. The gaps are listed the same way, each with the requirement that will close it.
MeasuredARIA APG pattern in the JSDoclibs/components/time/src/time-field.ts — the field's reasons and the decision behind them in the class comment; the columns name their listbox in theirs
MeasuredKeyboard mapapps/sandbox-e2e/src/time.spec.ts — the panel's map in three engines; libs/components/time/src/time-field.spec.ts — Escape, Tab off either end and Tab inside, key by key
Measuredaxe auditapps/sandbox-e2e/src/a11y.spec.ts — the /time view and /all, in both directions, and separately the open panel with the field it belongs to, whole-page: the toggle's aria-controls into the overlay container and the three named listboxes pointing at their rows
MeasuredVisual screenshotapps/sandbox-e2e/src/visual.spec.ts — time-field, time-columns and time-columns-rtl
Measuredforced-colors: activeapps/sandbox-e2e/src/forced-colors.spec.ts — the chosen row takes the mode's SelectedItem pair, the keyboard's row keeps a ring in Highlight (in SelectedItemText on the chosen row, where Highlight may be the surface's own colour), a refused row says GrayText; the field's invalid edge is drawn twice as thick, a shape the substitution keeps
Measuredprefers-reduced-motiontools/check-styles.mjs point 9 — the row's and the field's transitions take --pct-motion-transition-duration, which the token build switches off
MeasuredTouch target ≥ 24×24 pxapps/sandbox-e2e/src/target-min.spec.ts — the clock button is max(--pct-time-toggle-size, --pct-time-target-min), measured with the drawing disarmed; a row is 28 px at sm and taller above
MeasuredSize axisapps/sandbox/src/app/views/size/size-view.html — the /size view puts the field on the shared sm/md/lg axis beside the date field, and the rows follow the field into the panel
GapDensity axisnone — gap (req-token-density has not one token in the sources; the row height is the number a density axis would move) MeasuredRTLapps/sandbox-e2e/src/rtl.spec.ts — the button changes sides and the hour column is drawn on the right; apps/sandbox-e2e/src/time.spec.ts — the same in the panel, and the keys, which are about the row above and below, unchanged
MeasuredSSR + hydrationapps/sandbox-e2e/src/hydration.spec.ts — the /time view is in SBX_ROUTES
MeasuredFormslibs/components/time/src/time-field.spec.ts › the forms that bind it — [formField], [formControl] and [(ngModel)], each from a non-empty value (lesson-26); apps/sandbox-e2e/src/forms.spec.ts — the field in a signal form whose validity waits for it; a form's reset — reset() keeping the value, reset(value) showing it, the form pristine: libs/components/time/src/time-field.spec.ts › the forms that bind it MeasuredBounds from a signal formlibs/components/time/src/time-field.spec.ts › bounds from a signal form (pctTimeBounds) — the bounds reach the field and the panel walks inside them, a time outside is minTime / maxTime and a bound is inside in either shape, a window's gap is both, the message, a bound read off another field, several rules walked as the shortest stretch holding what all of them accept, in either order, rules that accept no time, and a bound read off another field in a rule of its own; apps/sandbox-e2e/src/time.spec.ts › a signal form hands its bounds to the panel — the bounds reaching the panel and a time typed outside reported, in three engines
MeasuredMessage announcedtools/check-aria.mjs (point 7, target check-aria) — the error part carries role="alert", the warning part role="status"
MeasuredTime arithmetic as lawslibs/components/time/src/time.property.spec.ts — the value module's laws; libs/components/time/src/lattice.spec.ts — the rows a step lists and where a walk lands, under bounds, a window and a base off the hour
MeasuredParts in the inventorylibs/components/parts.snapshot.md, tools/check-parts.mjs (target check-parts)
MeasuredTokens + contrast.policy.jsonlibs/tokens/src/contrast.policy.json — 22 pairs for the field and its columns together, the keyboard's ring on the chosen row among them
MeasuredStrings through PCT_TEXTStools/check-texts.mjs — nine keys; the three letters are texts because they are words, and the clock's own words — AM, 오후 — are the formatter's, because they are what the field shows and reads back
MeasuredSize budgetlibs/components/size.snapshot.md, tools/check-bundle.mjs (target check-bundle)
MeasuredNot a time, saidlibs/components/time/src/time-field.spec.ts › junk in the field — the sentence in the message line ahead of the form's, in the default wording and in the application's; apps/sandbox-e2e/src/time.spec.ts › keeps junk in the field and reports it — the same in three engines, in French, with aria-describedby naming it (0070) MeasuredScreen-reader logRead 2026-10-08 from docs/acr/at/ — three readers, whole sandbox, and the act that opens the columns. The field is its label, its time and its hint: Orca Time · entry · 13:05 · selected. · The sandbox runs under fr-FR, so the clock counts to 24., NVDA Time, edit, The sandbox runs under fr-FR, so the clock counts to 24, selected 13:05; VoiceOver left the view after one stop, as on most views of this pass. Each field says its own clock — American English · entry · 1:05 PM · selected. (Orca), Korean, edit, selected 오후 1:05 (NVDA) — and the button says what it opens: Choisir une heure, button, collapsed, opens dialog (NVDA), Choisir une heure · collapsed button. · opens dialog (Orca). Opening lands on the hour column: Orca Choisir une heure · dialog · Heures · List with 24 items · 13, VoiceOver Choisir une heure web dialog 13 selected (14 of 24), NVDA Choisir une heure, dialog and nothing of the column. Escape did not close the panel under NVDA, which closed the date's on the same key: on a listbox NVDA is in focus mode and keeps the first Escape to leave it — and VoiceOver's Escape closed no panel in this pass, the dialog's included
Measureddocs page/components/time on the published site — prerendered, the demo's own source is the code tab