Skip to main content

Accessibility statement and conformance report

Accessibility at Latchkey

Our own conformance report for our own product, with the issues we know about and have not fixed yet, the surfaces we have not evaluated at all, and the check that runs against this site before a release.

Conformance target: WCAG 2.2 Level AA · Last evaluated 8 September 2026 · Next evaluation due 7 December 2026 · Owner: accessibility-lead · Version 1

  • WCAG 2.2 Level AA target
  • 8 surfaces in scope
  • 4 open issues listed
  • 6 recorded evaluation gaps
  • Re-evaluated every 90 days

Our commitment, in one paragraph

We build accessibility tooling, so we hold our own surfaces to the standard we sell against: WCAG 2.2 Level AA. We check them with the same engine our scanner runs before a release goes out, and a state our harness cannot reach is reported as skipped rather than counted as passing. We publish what we have not fixed, below, and what we have not evaluated at all. And we answer a report about a barrier on this site from anyone, whether or not you are a customer.

One thing to be clear about before the detail: this page does not claim that latchkey.app is fully accessible, and it is not a compliance certification. Automated checks cover roughly one third of WCAG success criteria, which bounds what any gate of this kind can tell you, ours included. What automated testing cannot find applies to this site exactly as it applies to yours. Every claim below uses the same five values a procurement reviewer expects, and no surface claims Supports, because a claim of Supports needs a person driving assistive technology behind it and we have not done that yet.

What we evaluated, and how

One row per surface. The claim is one of five values and nothing else: the registry this table is generated from cannot hold another word, and the build fails if it did. The Method cell says what was run, at what widths, on what date, and what was not run, because a one-word method is how “tested” comes to mean nothing.

Conformance claim per surface, version 1 of this report, evaluated 8 September 2026. Claims use the five reporting values only.
SurfaceStandard and levelConformance claimEvaluated onMethodKnown issues
latchkey.app marketing site, the free scanner and its result screensWCAG 2.2 Level AAPartially Supports8 September 2026axe-core 4.10 driven by scripts/audit-self.mjs against the built site at 1440, 1200, 375 and 320 CSS pixels, covering 72 page-states including interactive states (an expanded issue row, a switched tab, an open share popover, an open download dialog). Result on 8 September 2026: 72 page-states checked, no violations, 14 designed states the run could not reach. No screen reader pass and no manual keyboard-only traversal has been done, so the claim rests on automated evidence plus source review only (gaps ACC-GAP-01 and ACC-GAP-02).
app.latchkey.app portal: projects, scans and metricsWCAG 2.2 Level AANot EvaluatedNo evaluation yetNothing has been run against the portal. The self-audit route map in scripts/audit-self.mjs covers the marketing routes, the help centre, the status page, sign-up, log-in and the 404 page. It does not include /projects, /scans or /metrics, so there is no axe result, no keyboard pass and no screen reader pass for this surface. First evaluation is scheduled with the portal work in Phase 3.
help.latchkey.app help centreWCAG 2.2 Level AAPartially Supports8 September 2026Served from the same Next.js application and the same marketing layout as the site above, and audited in the same run: axe-core 4.10 at 1440, 1200, 375 and 320 CSS pixels with no violations on 8 September 2026. It inherits the shared footer, so it inherits issue ACC-003. No screen reader pass and no manual keyboard-only traversal (ACC-GAP-01, ACC-GAP-02).
status.latchkey.app status pageWCAG 2.2 Level AAPartially Supports8 September 2026Audited in the same axe-core 4.10 run at 1440, 1200, 375 and 320 CSS pixels with no violations on 8 September 2026. The audit sees the page as rendered at that moment: an incident state, a degraded state and a maintenance state were not present during the run and so were not evaluated. It inherits the shared footer and issue ACC-003. No screen reader pass and no manual keyboard-only traversal (ACC-GAP-01, ACC-GAP-02).
The widget's own visitor interface, as shipped, in a Shadow DOM host on a fixture siteWCAG 2.2 Level AANot EvaluatedNo evaluation yetThe widget browser corpus (packages/latchkey-widget/test/browser, 39 cases across 6 files) loads the shipped loader and interface bundles in a real browser on a fixture page and asserts mounting into a Shadow DOM host, initialisation, lifecycle, behaviour under a strict Content Security Policy, isolation from host CSS, and locale resolution. That is behavioural evidence, not a conformance evaluation: the corpus runs no axe-core pass over the interface and no screen reader has ever been pointed at it. Two defects listed below were found by reading the source rather than by evaluating the surface, which is why they appear here under a claim of Not Evaluated. First evaluation is scheduled for Phase 2 with the axe pass over the mounted interface.
Published accessibility statement pages at /statement/{publicId}WCAG 2.2 Level AANot EvaluatedNo evaluation yetThe route is not built yet. A request to /statement/{publicId} on the current build returns 404, so there is no surface to evaluate and no claim is being made. The statement generator and its public pages land in Phase 2, and the first evaluation is scheduled with them.None recorded
Public Evidence Pack share view at /share/evidence-pack/{token}WCAG 2.2 Level AANot EvaluatedNo evaluation yetThe route is not built yet. Sharing lands in Phase 5 module 10, and the surface is registered here before it exists so that the first evaluation is a precondition of shipping it rather than a follow-up. When it does ship it is audited in both themes and gets a manual pass, not only axe: the passcode gate, the access-denied states and the read-only pack render are each their own page-state.None recorded
PDF deliverables: the Remediation Report and the Evidence PackPDF/UA-1 with WCAG 2.2 Level AA Level AANot EvaluatedNo evaluation yetA tagged PDF is a different conformance question from a web page and needs its own tool. The only print surface that exists today is /scan/{scanId}/print, rendered by the (print) route group as HTML for the browser to print. It is not in the self-audit route map, no tagged-PDF or PDF/UA check has been run against any generated file, and this repository contains no such checker. Choosing one and running it is Phase 2 work owned by reports-eng.None recorded

This page is a dated report about our own product. It is not a signed third-party audit and it is not a VPAT. Standard-edition reports for procurement (WCAG 2.2, Revised Section 508, EN 301 549) are human work we produce on request: ask us through the contact page.

What each claim means

The five values are the reporting vocabulary a procurement reviewer already knows. Not Evaluated is one of them, and it is used here rather than leaving a blank or borrowing another surface’s claim.

Supports
Every part of the surface we evaluated meets the criterion.
Partially Supports
Some functionality on the surface does not meet the criterion.
Does Not Support
The majority of the functionality on the surface does not meet the criterion.
Not Applicable
The criterion is not relevant to this surface.
Not Evaluated
The surface has not been evaluated against the criterion. No claim is being made.

Out of scope, and why

Three surfaces a reader could reasonably expect to find above are not ours to claim for. A vendor that quietly includes a checkout it does not control in its own conformance claim is making a claim it cannot support, and a vendor that quietly drops the line saying so leaves a reader to assume it does control it.

Dodo Payments' hosted checkout and its customer portal
Payment is taken on a page Dodo Payments serves and controls. We do not write its markup, we cannot fix a barrier in it, and we would be making a claim we cannot support if we counted it as ours. We link their own statement instead, and a barrier reported to us on that page is forwarded with a copy to the reporter. Their own accessibility statement.
Embedded platform admin frames (Shopify, Wix, Webflow and other marketplace hosts)
Our app renders inside chrome the platform owns: their navigation, their modals, their focus management, their colour tokens. We claim the interface we render inside that frame and nothing around it, because the surrounding controls are not ours to evaluate or to fix.
Customer websites the widget runs on
A customer site is the thing our product works on, not a surface we can claim for. Its markup is the customer's, the widget adjusts a defined set of properties on it, and the coverage table on each result says what was and was not addressed. Reporting a customer site as conforming because our widget is installed on it is the overlay claim this company exists to argue against.

The honest half

What we have not evaluated, and what not to read into the claims

No screen reader has been run against any Latchkey surface. NVDA, JAWS, VoiceOver and TalkBack passes have not been done, and this report records that as an evaluation gap with an owner and a target phase rather than as a pass. Where a surface has had nothing run against it at all, its claim above reads Not Evaluated. Each gap below carries the sentence that matters most: what a reader must not conclude from the table above.

  • ACC-GAP-01 · Owner: accessibility-lead · Target: Phase 2

    What was not evaluated
    No assistive technology pass has been performed on any Latchkey surface. No NVDA, JAWS, VoiceOver, TalkBack, Dragon, ZoomText or braille display session has been run against the marketing site, the portal, the widget interface, the statement pages or the PDFs.
    Why not
    The environment this product is currently built in cannot run a screen reader, and no session has been run outside it either. An assistive technology matrix is planned for Phase 2 and is not in place today.
    So do not conclude
    Do not read any claim on this page as saying a screen reader user can complete a task. The evidence behind every claim here is automated checking plus source review, and automated checking reaches roughly one third of the WCAG 2.2 AA criteria. This is the same limit we publish about our own product on /limitations, applied to ourselves.

    Surfaces affected: latchkey.app marketing site, app.latchkey.app portal, help.latchkey.app help centre, status.latchkey.app status page, The widget's own visitor interface, Published accessibility statement pages at /statement/{publicId}, PDF deliverables.

  • ACC-GAP-02 · Owner: accessibility-lead · Target: Phase 2

    What was not evaluated
    No manual keyboard-only traversal has been recorded for any surface. Focus order, focus return after a dialog closes, keyboard operability of custom components and escape from a focus trap have not been tested by a person.
    Why not
    The self-audit script drives the interface through role-based queries in order to reach interactive states for the axe pass. Reaching a state by asking the browser for a button by its role is not the same as arriving at it with the Tab key, and it asserts nothing about the order or the return path.
    So do not conclude
    Do not read the absence of keyboard issues in the table above as evidence that keyboard journeys work. Nothing in this evaluation would have found a broken one.

    Surfaces affected: latchkey.app marketing site, app.latchkey.app portal, help.latchkey.app help centre, status.latchkey.app status page, The widget's own visitor interface.

  • ACC-GAP-03 · Owner: growth-eng · Target: Phase 2

    What was not evaluated
    Fourteen designed page-states are named by the self-audit and were not reached by it. Six are the scan result screens (barriers found, needs review, clean, failed, expired, in progress), which need a fixture scan id the run was not given. Four are the scan landing page inline validation error at each width, where the address field was not on the page. Three are the desktop mega-menu at widths where the desktop navigation does not render, and one is the mobile menu at a width where the hamburger does not render.
    Why not
    The result screens need seeded fixtures the audit run did not receive. The remaining eight are the audit asking for a control that does not exist at that viewport, which is the harness describing its own coverage honestly rather than a product defect.
    So do not conclude
    Do not read 72 page-states checked with no violations as covering the result screens. The result screens are where a score is shown and are the most consequential states on the site, and they were not audited in this run.

    Surfaces affected: latchkey.app marketing site, status.latchkey.app status page.

  • ACC-GAP-04 · Owner: platform-eng · Target: Phase 3

    What was not evaluated
    The axe gate covers the marketing route map only. The portal, the widget interface as mounted in a Shadow DOM host, and the print surface have never had an axe-core pass.
    Why not
    The route list in scripts/audit-self.mjs was written for the Phase 0 marketing exit criterion and has not been extended. Extending it needs an authenticated session for the portal and a fixture host page for the widget, neither of which the script sets up.
    So do not conclude
    Do not read this page as a statement about the portal or the widget interface. Both are recorded as Not Evaluated for that reason.

    Surfaces affected: app.latchkey.app portal, The widget's own visitor interface, PDF deliverables.

  • ACC-GAP-05 · Owner: portal-eng · Target: Phase 2

    What was not evaluated
    The published statement pages at /statement/{publicId} have not been evaluated.
    Why not
    The route does not exist yet. A request to it on the current build returns 404.
    So do not conclude
    Do not read the row as a claim held in reserve. There is no surface, so there is no claim.

    Surfaces affected: Published accessibility statement pages at /statement/{publicId}.

  • ACC-GAP-06 · Owner: reports-eng · Target: Phase 2

    What was not evaluated
    No tagged-PDF check has been run against any generated document, and no PDF/UA checker has been chosen.
    Why not
    A tagged PDF is a different conformance question from a web page: reading order, tags, artifacts, table headers and alternative text live in the document structure, and a web checker sees none of it. No such tool is in this repository.
    So do not conclude
    Do not assume the PDF inherits the web report's evaluation. It does not, and the two are evaluated separately for that reason.

    Surfaces affected: PDF deliverables.

Known issues

Our own barriers, with the WCAG criterion each maps to, who it affects, whether there is anything you can do about it today, who owns it and when we intend to fix it. Every row is generated from the same registry our own accessibility work is tracked in, so the public list cannot be a shorter version of the internal one. Each row has a permanent link, so a report we answer can point at the exact issue.

  • Open (4)
  • In progress (0)
  • Fixed (3)
Every published issue on our own surfaces as of 8 September 2026: 4 open, 0 in progress, 3 fixed and kept visible. Fixed rows stay on the list because a list that only ever grows, or only ever shrinks, is not being maintained.
# Issue referenceWhat is wrongSurfaceWCAG criterionWho it affectsWorkaround available nowOwnerTargetStatus
ACC-001The widget panel never declares the language of its own content. The panel sets its text direction from the active translator on every render, but no code anywhere in the widget sets a lang attribute, so a panel rendered in Japanese inside an English host page is announced with the English voice and English pronunciation rules.The widget's own visitor interface3.1.2 Language of Parts (AA)Screen reader users on any host page whose language differs from the interface language they chose, which is the normal case for a visitor who switches the panel to their own language on an English site.None inside the widget. A site owner whose visitors mostly share one language can set the widget default language to match the host page lang, so the two at least agree.widget-engPhase 2Open
ACC-002Two of the 35 interface languages the widget offers are not translated. The Vietnamese and Simplified Chinese locale files ship English strings, so a visitor who selects either gets an English interface from a menu that offered them their own language.The widget's own visitor interface3.1.2 Language of Parts (AA)Mapped to 3.1.2 because the part is served in a language other than the one it is presented as. A reader could reasonably file this as a localisation defect rather than a WCAG failure. It is on the list either way.Vietnamese and Simplified Chinese speaking visitors, who are the people least able to use the fallback they are given.The other 33 languages are translated, and English is served rather than blank strings, so the interface stays operable for anyone who reads some English.widget-engPhase 2Open
ACC-003Four links in the site footer point at pages that do not exist. Privacy, Cookies and local storage, Billing terms and Evidence Pack policy all return 404, so a reader following the footer to a policy page lands on an error.latchkey.app marketing site, help.latchkey.app help centre, status.latchkey.app status page2.4.4 Link Purpose (In Context) (A)Mapped to 2.4.4 on the reading that a link whose stated purpose cannot be fulfilled does not let a reader determine where it goes. The mapping is arguable. The defect is not.Everyone, and most sharply anyone who relies on the footer as the predictable route to policy pages rather than on search, including screen reader users navigating by landmark and link list.None. There is nothing a reader can do about this one until we fix it.legal-opsPhase 2Open
ACC-004The share control on a scan result computes whether the result has expired once, while rendering. If a result expires while the page is open, the button keeps reporting itself as available: aria-disabled stays false and the tooltip that says the result has expired never appears. React's own purity rule flags the call as an error.latchkey.app marketing site4.1.2 Name, Role, Value (A)The state a control exposes to assistive technology disagrees with the state the control is actually in, which is a 4.1.2 failure on the value and state half of the criterion.Anyone who leaves a result page open past its retention window, and screen reader users in particular, because the disabled state is the only signal the control gives them that the link will not work.Reloading the page recomputes the state. Nothing on the page tells you to.growth-engPhase 2Open
ACC-005Every primary button rendered dark ink on brand green at 2.6:1, on the home page of an accessibility product. The cause was a utility name collision: the type scale was implemented as text-body-lg, text-h1 and so on, and tailwind-merge cannot tell a custom text-* utility from a text colour, so it treated them as one group and silently dropped the colour. The scale is now type-*, which cannot collide by construction.latchkey.app marketing site, app.latchkey.app portal1.4.3 Contrast (Minimum) (AA)Anyone with low vision or reading in bright light, on every primary action on the site. It was invisible in development because the scaffold forced dark mode and dark ink on a dark ground happened to pass.None. There is nothing a reader can do about this one until we fix it.design-systemPhase 0Fixed7 September 2026
ACC-006Every control was 32 pixels tall, below both WCAG 2.5.8 and the design system's own 44 pixel floor, and navigation links sized themselves to their text. Fixed in the Button component rather than at each call site, because per-caller means the next caller gets it wrong.latchkey.app marketing site, app.latchkey.app portal2.5.8 Target Size (Minimum) (AA)Anyone with a tremor, limited fine motor control, or a touch screen, on every button and navigation link in the product.None. There is nothing a reader can do about this one until we fix it.design-systemPhase 0Fixed7 September 2026
ACC-007The 404 page had no lang attribute and no title, because notFound() called from inside a page makes Next render its own error document instead of the root layout. The missing-result cases now redirect to a path that deliberately has no route, so Next renders the real root boundary and the page gets its language and its title back.latchkey.app marketing site3.1.1 Language of Page (A)Recorded against 3.1.1 for the missing language. The same defect also failed 2.4.2 Page Titled; one row, two criteria, and this field holds one, which is a limitation of the row shape rather than of the finding.Screen reader users reaching a missing or expired result, who got the page read in whatever language their reader defaulted to, with no title to tell them where they were.None. There is nothing a reader can do about this one until we fix it.platform-engPhase 0Fixed7 September 2026

Where a row is confirmed, the registry also records the command, file or commit that confirms it, so a row nobody can trace back to evidence fails our build rather than padding this list.

No row is withheld from this table. A row can be withheld only with a written reason, which appears here in place of the row, and a withheld row with no reason fails the build. That friction is the control: shortening this list leaves a trace in review.

How this site is checked before it ships

The gate is a script in our repository: scripts/audit-self.mjs. It launches a headless Chromium, opens each page of this site that it knows about, injects axe-core 4.10 or later (the same engine every finding in our product comes from) and asks it for the five rule tags the script names: WCAG 2.0 and 2.1 at Level A and AA, plus the Level AA additions in 2.2. A violation makes the run exit non-zero, which is what stops the release: this is a gate rather than a report someone reads later.

Every page is checked at four widths: 1440, 1200, 375 and 320 CSS pixels. Neither end of that range is decoration. WCAG 1.4.10 states reflow at 320 pixels, and 320 is where a sticky bar, a wide table or a fixed-width code block starts covering something. 375 alone never catches it. At the other end, the header’s dropdown menu only renders from 1280 up, so a list that stopped at 1200 would audit the mobile sheet at every width and never once load the menu it replaces.

The phrase that does the work is “in every designed state”. A page can pass empty and fail with content, or pass collapsed and fail expanded, so states are checked separately. When the harness cannot reach one, it prints it in a “states not audited” block and the summary line says how many were missed. A gate that printed a green line for a screen it never loaded would be worse than no gate at all. The states it cannot reach today are recorded above as gap ACC-GAP-03, because the result screens are the most consequential states on this site and they are the unaudited ones.

A second script, scripts/lint-conformance.mjs, validates the report you are reading. It fails the build when the evaluation is more than 120 days old, when a surface has no claim, when a claim uses a word outside the five values, when a claim of Supports has no assistive technology pass behind it, when a known issue cites a criterion that is not in WCAG 2.2, and when a row is withheld from the table above without a written reason.

What the gate covers today

The result screens each need a scan already in that state, supplied as a fixture id on the command line. Run without fixtures (which is the usual local run) and those states are reported as skipped, never as passing.

The page states our own axe gate audits, and the states it reports as skipped, as of 8 September 2026.
Page or stateIn the gate todayWhat that means
Marketing homeAudited/ covers the hero, the scan form, the dark band and the footer, at every width the run uses.
Free scan landingAudited/scan as a visitor first sees it.
Scan landing, prefilledAuditedAn address arriving in the query string, which renders a different form state.
Scan landing, inline validation errorAuditedReached by submitting an invalid address. Client-side validation only, so it needs no fixture and burns no scan quota.
Navigation, mega-menu openAudited from 1280 upThe header dropdown is a designed state of its own: its links, its column headings and its promo panel are not in the page at all until a trigger is pressed. Below 1280 that component is not rendered, so the run reports this state as skipped rather than as passing.
Navigation, mobile sheet openAudited below 1280The same navigation as a sheet over the page, with one group expanded so the accordion’s open state is audited too. From 1280 up the hamburger is not rendered and this one reports as skipped.
LimitationsAudited/limitations, the page that carries the coverage argument.
The rest of the marketing pagesAudited/widget, /flow, /services, /pricing, /compliance, /accessibility, /about, /contact, /help, /status and /signup: every page the header and the footer name, at the same four widths.
Log inAudited/login, including its form labelling.
Not-found pageAuditedAn unmatched scan path. The run also asserts the response really is a 404, because the shell Next renders for a page-level notFound() has no lang attribute and passed nothing.
Result screen: barriers foundSkipped without a fixtureNeeds a completed scan with barriers. Seven states are checked from that one fixture, including a row expanded, each results tab, and the share and download dialogs.
Result screen: no failures with checks to reviewSkipped without a fixtureNeeds a completed scan with no violations and at least one check that needs a person.
Result screen: no automated failuresSkipped without a fixtureNeeds a completed scan with no violations and nothing to review.
Result screen: scan failedSkipped without a fixtureNeeds a scan row in the failed state.
Result screen: result expiredSkipped without a fixtureNeeds a scan past its expiry, or one whose screenshot has been purged.
Result screen: scan in progressSkipped without a fixtureNeeds a scan still queued or running.

Evidence, not a promise

What our own gate caught on our own pages

  • ACC-005 · Fixed 7 September 2026

    1.4.3 Contrast (Minimum) (AA)

    Every primary button rendered dark ink on brand green at 2.6:1, on the home page of an accessibility product. The cause was a utility name collision: the type scale was implemented as text-body-lg, text-h1 and so on, and tailwind-merge cannot tell a custom text-* utility from a text colour, so it treated them as one group and silently dropped the colour. The scale is now type-*, which cannot collide by construction.

  • ACC-006 · Fixed 7 September 2026

    2.5.8 Target Size (Minimum) (AA)

    Every control was 32 pixels tall, below both WCAG 2.5.8 and the design system's own 44 pixel floor, and navigation links sized themselves to their text. Fixed in the Button component rather than at each call site, because per-caller means the next caller gets it wrong.

  • ACC-007 · Fixed 7 September 2026

    3.1.1 Language of Page (A)

    The 404 page had no lang attribute and no title, because notFound() called from inside a page makes Next render its own error document instead of the root layout. The missing-result cases now redirect to a path that deliberately has no route, so Next renders the real root boundary and the page gets its language and its title back.

None of these were found by a reviewer being generous. Each one was written, pushed, and stopped by the run, which is the argument for having a gate at all, and the reason this section is longer than the one about our commitment. They stay on the known-issues table above with the date they were fixed.

Limits of the method itself

Separate from the issues above and from the gaps: these are limits of how we evaluate, not defects and not surfaces. Written the way we would want a vendor to write it for us. If one of these matters to you and is not moving, say so. A limitation that has been listed for a year without being worked on is a different problem from a limitation.

  • The same third applies to us

    Automated checks cover roughly one third of WCAG success criteria, and this site is checked by the same automation we sell. So a run with nothing to report means the automated third found nothing on the states it reached. It says nothing about whether our reading order matches our visual order, whether our alt text is any good, or whether a form error makes sense read aloud out of context.

  • The run collects violations, not the maybes

    The gate asks axe for violations only. Checks axe cannot decide on its own (the ones our own product reports as needing review) are not collected, so they are not counted here either way. That is a deliberate scope for a build gate and a real gap in this document.

  • The design system is light-only, on purpose

    No dark palette has been designed. The contrast figures our palette is built on (brand indigo on white, danger red on its own tint) are properties of the light palette and do not transfer, and an invented dark palette would ship contrast failures on a product that sells accessibility. If you browse with a dark-mode preference, this site stays light.

  • A page not on the gate’s list is not audited by it

    The gate opens the pages it has been given and discovers nothing on its own. Every page of this site we have actually published is on that list today, but a page added tomorrow is not covered until someone adds it there too, and neither is a state nobody wrote a step for. The printable version of a result is one we have not added. We would rather name the gap than describe the gate as if it found pages by itself.

  • We are in private beta, and some pages are still being written

    A link in the navigation can still reach a page that is not published yet. That is a broken journey for anyone, and a worse one for someone using a screen reader who has to work out whether the mistake was theirs. Four such links are on the known-issues list above as ACC-003.

Report a barrier on this site

How to tell us

Write to accessibility@latchkey.app, the first route on our contact page. It reaches the accessibility-lead role rather than a shared inbox, and it is the same address a visitor to a customer’s site can use.

You do not need to name a success criterion, and you do not need to be a customer. The page, what you were trying to do, and what your browser or assistive technology did instead is plenty. “The third link on the pricing page does nothing with a keyboard” is a good report.

Contact us about a barrier

What you can expect back

  • An acknowledgement, which we aim to send within two business days.
  • A substantive reply within five business days: whether we could reproduce it, and on what browser and assistive technology.
  • The success criterion we think it maps to, so you can disagree with us in the same vocabulary.
  • Whether it is going on the known-issues table above, who owns it, and what we intend to do next. If it does, you get the link to your own row.
  • If we are not going to fix it soon, that answer and the reason, rather than a closed ticket and silence.
What this document is not. This is our own accessibility statement and conformance report, not an audit signed by a third party, and not a VPAT. We produce those for customers as human work, and this page does not pretend to be one. Nothing here is legal advice, and a passing gate is not a determination that any site meets any legal standard. When the claims, the method or the issue list change, the version and the evaluation date at the top change with them.

This document

Version and dates
Version 1, evaluated 8 September 2026, next evaluation due 7 December 2026 on a 90 day cadence. Version 1 is the first dated report rather than the fifth. When it is re-evaluated the version goes up and the dates move with it. There is no version archive at its own address yet, so an older version of this report is not linkable today.
Owner
accessibility-lead. Barrier reports go to accessibility@latchkey.app.
Both names resolve
/accessibility-statement is a permanent redirect (HTTP 308) to this page, because both names are used in our own plan and in the site footer, and a link from either should reach the report rather than a 404.
How the freshness notice works
This page is statically generated when the site is built, so the notice above reflects the report’s age at build time rather than at the moment you load it. The backstop is the build itself: it fails once the evaluation is more than 120 days old, which is 30 days after the cadence date, so a deploy cannot carry a report that has gone stale past that window.

Version 1 · Evaluated 8 September 2026 · Next due 7 December 2026 · Target WCAG 2.2 Level AA · Owner: accessibility-lead · What the regulations require