Color and target size
64 checksAdded after four real contrast defects were found already live.
I redesigned kousikdutta.com so a hiring manager meets two flagship stories first, and directed a build that checks every release.
Problem
The old gallery set every project at the same level and left a reviewer to piece my career together.
What I found
The job was making the strongest work easy to find without flattening the range behind it.

What I decided
The homepage answers a hiring manager first: flagship projects lead into full case studies, supporting work stays compact, and the resume is one PDF.


What I decided
Shared navigation, theme-aware media, route metadata and release checks keep every project page in one system.

What shipped
Each gate exists because an earlier release let that mistake through.
Added after four real contrast defects were found already live.
Added after the homepage was found shipping 8 MB.
Added after every route was found sharing a single image, so a shared link never showed the page it pointed at.

Added after the sitemap was found listing a noindex page and the structured data pointing at a card that no longer existed.
Added after 32 images shipped with placeholder alt like “Research overview 4,” which passed the accessibility gate and still told a screen reader nothing.
Generated on 2026-11-02 from the same build data that feeds the gates above.
generate-journal-metadatatsc -bcheck-decisionsbuild-reportvite buildpostbuildprerendercspcheck-glasscheck-a11ycheck-weightcheck-ogcheck-seocheck-altcheck-escapescheck-voiceRecomputes contrast for every color token pair in both themes against WCAG AA, and requires interactive text controls to be at least 24px tall.
scripts/check-a11y.mjsFails on any image over 300 KB, any unconverted raster, and any source model left where it would be deployed.
scripts/check-weight.mjsRequires every case study and note to ship its own social card, drawn from the site’s own type and color tokens and held under 400 KB.
scripts/check-og.mjsReads every page’s built HTML the way a crawler does, and fails on a missing or duplicate title, a description outside 120 to 160 characters, a canonical that disagrees with og:url, a card of the wrong size, JSON-LD that does not parse, or a page without exactly one h1.
scripts/check-seo.mjsFails on alt text that names a section and a counter, a filename, or a bare noun.
scripts/check-alt.mjsRequires every published design decision to include considered options, positive and negative consequences, and a kill criterion. A decision cannot ship as a preference with the cost removed.
scripts/check-decisions.mjsFails the build if any compiled CSS blurs the backdrop, so glass cannot creep back in through a refactor or a utility class.
scripts/check-glass.mjsFails on visible escape sequences and em dashes in source copy. Comments are ignored, so the gate checks what readers can actually encounter.
scripts/check-escapes.mjsFails when a log entry uses the phrases that most often give generated writing away: filler transitions, stock openers, and vocabulary nobody says out loud.
scripts/check-voice.mjsLooking back
Next time I’d put the site in front of hiring managers much earlier: the checks verify my rules, not whether a reviewer understood the work or every accessibility issue was found.
There was no brief, so I took on what nobody asks of a portfolio: a social card for every case study and note, and a build that checks contrast, alt text and its own copy before anything ships. I talk each change through out loud, Claude Code writes it, and I review every change.