Audit the app itself: fix accessibility defects and make forks resolve their own origin - #346
Merged
Merged
Conversation
Now that anyone can fork and self-host this, several things still named the original deployment. A fork's exported READMEs credited it, its social card printed its domain, and its canonical URLs and sitemap pointed at it. siteUrl now resolves SITE_URL, then whatever Vercel reports (VERCEL_PROJECT_PRODUCTION_URL or VERCEL_URL), and only then falls back — so a fork publishes its own URLs with nothing configured. The social card prints whatever that resolves to, and the README inside an exported ZIP credits window.location.origin, which is the deployment the person actually used. Removes the PRODUCTION_URL constant, whose whole purpose was to name one host, and makes the README's origin argument required so a caller cannot silently fall back to someone else's. Two tests pin it: nothing a fork ships may contain the maintainer's deployment URL, and the origin must be read from configuration before any fallback.
The exported and published sites were measured and fixed earlier; the app itself never was. Auditing all nine public pages with Lighthouse found real failures on every one of them. The largest was a single token. --primary serves as both a button fill and as accent text, and at oklch(0.52 0.22 290) it measures 3.18:1 on the card surface - below the 4.5:1 floor - which failed 31 nodes across the app. It cannot simply be lightened: white on that same colour as a fill measures 6.11:1 and passes, and raising the lightness would break that instead. So accent text gets its own --primary-ink at oklch(0.66 0.18 290), measured at 5.87:1 worst case, and the 48 text-primary usages now point at it. Fills and borders are untouched. The three legal pages carried `prose prose-invert prose-sm` while @tailwindcss/typography was never installed, so every one of those classes was inert and the pages rendered as unstyled markup. The plugin is now a real dependency and registered. The decorative numerals behind the pipeline and feature cards were flagged at 1.06:1. aria-hidden does not exempt them, and rightly so: a low-vision sighted reader still sees them. Reaching the 3:1 large-text floor would need about white/40, which is no longer a faint watermark. They are pure decoration under WCAG 1.4.3, so they are drawn as generated content instead of text, which is how that is expressed in a way a checker agrees with. Also fixed: the editor had no main landmark, an unnamed icon-only add-section button and an unlabelled site-name input; a responsive duplicate of the "View all presets" link hid its own label at one breakpoint and left the anchor unnamed; and the sponsor button was white on pink-500 at 3.53:1, now pink-600 at 4.60:1. <Analytics /> was mounted unconditionally. The insights script only exists when Vercel serves it, so every self-hosted or local run logged a 404 and a strict MIME-type error on every page - noise for exactly the people this project is now aimed at. It is gated on the deploy environment. Measured before and after, on the built app: home acce 92 -> 100 best 96 -> 100 gallery acce 96 -> 100 best 96 -> 100 editor acce 89 -> 100 best 96 -> 100 contact acce 96 -> 100 best 96 -> 100 about acce 96 -> 100 best 96 -> 100 The contrast tests compute the ratios from the tokens rather than asserting a hex string, so they fail with the measured value when a colour regresses.
Contributor
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two things I flagged as unfinished. The deliverables were measured and fixed earlier; the app itself never was, and now that anyone can fork it, several things still named your deployment.
The accessibility audit
Ran Lighthouse against all nine public pages of the built app. Every one had real failures.
One token explained 31 of them.
--primaryis both a button fill and accent text. Atoklch(0.52 0.22 290)it measures 3.18:1 on the card surface — below the 4.5:1 floor. It can't just be lightened: white on that same colour as a fill measures 6.11:1 and passes, so raising lightness would break that instead. Accent text now has its own--primary-inkatoklch(0.66 0.18 290)— 5.87:1 worst case — and the 48text-primaryusages point at it. Fills and borders untouched.@tailwindcss/typographywas never installed. All three legal pages carriedprose prose-invert prose-sm, so every one of those classes was inert and the pages rendered as unstyled markup. Now a real dependency and registered.The decorative numerals behind the pipeline cards were flagged at 1.06:1.
aria-hiddendoesn't exempt them, and rightly so — a low-vision sighted reader still sees them. I measured what passing would take: roughlywhite/40, which is no longer a faint watermark. They're pure decoration under WCAG 1.4.3, so they're drawn as generated content rather than text, which is how that's expressed in a way a checker agrees with. Verified in isolation that the pseudo-element still renders.Also: the editor had no
<main>landmark, an unnamed add-section button and an unlabelled site-name input; a responsive duplicate of "View all presets" hid its own label at one breakpoint leaving the anchor unnamed; the sponsor button was white onpink-500at 3.53:1, nowpink-600at 4.60:1.<Analytics />was mounted unconditionally. The insights script only exists when Vercel serves it, so every self-hosted or local run logged a 404 plus a strict-MIME error on every page — noise for exactly the people this project is now aimed at. Gated on the deploy environment.Measured, before → after
Forks resolve their own origin
A fork's exported READMEs credited your deployment, its social card printed your domain, and its canonical URLs pointed at you.
siteUrlnow resolvesSITE_URL→ Vercel's own env → fallback, the social card prints whatever that resolves to, and an exported README creditswindow.location.origin.PRODUCTION_URLis gone.Verified
tsc,eslint,next buildclean; suite 213 → 223.accent text on the page surface is 3.38:1.Not changed:
/createand/editoraredisallowed in robots.txt, which caps their SEO score at 63. That's deliberate — they're the tool, not marketing pages — so I left it.