← Back
Writing12 articles

Things I have written

·5 min read

Building with the Next.js App Router

The App Router changes how you think about layouts, data fetching, and rendering. Here's what I learned migrating a real project.

Read article
·4 min read

CSS Custom Properties for Runtime Theming

Tailwind utility classes are great — but for themes that change at runtime, CSS custom properties are the right primitive.

Read article
·3 min read

Marching Ants Borders in Pure CSS

That animated dashed border you see on hover? No canvas, no SVG, no JavaScript. Just four CSS gradients and a keyframe.

Read article
·6 min read

Accessibility Beyond Compliance

WCAG conformance is a floor, not a ceiling. Here's how to build experiences that genuinely include everyone.

Read article
·5 min read

Keyboard Navigation Done Right

Most keyboard navigation is an afterthought. Getting it right requires understanding focus management, not just tab order.

Read article
·4 min read

My Screen Reader Testing Workflow

You don't need to be a screen reader power user to catch the most common issues. Here's a practical testing routine.

Read article
·4 min read

Color Contrast in Practice

The 4.5:1 ratio is just the start. Here's how to build a color system that stays accessible across themes and states.

Read article
·3 min read

Semantic HTML Still Matters

Before ARIA, before JavaScript, the right HTML element is always the best accessibility tool you have.

Read article
·6 min read

Building an Inclusive Design System

How to bake accessibility into a design system at the token level, so every component inherits it by default.

Read article
·5 min read

Writing Accessible React Components

Patterns for building React components that work for everyone — from focus management to live regions.

Read article
·4 min read

Performance is an Accessibility Issue

Slow sites exclude users on low-end devices and slow networks. Performance work is inclusion work.

Read article
·4 min read

ARIA Labels and Descriptions: When to Use Which

aria-label, aria-labelledby, aria-describedby — they all add accessible names but serve different purposes.

Read article