Design Tools
Color Contrast, Gradients & Shadows
The checks I run before a component ships: does the text clear contrast, does the gradient band on a wide screen, and is the shadow subtle enough to go unnoticed. Each tool outputs copy-paste CSS, so nothing has to be retyped by hand.
WCAG Color Contrast Checker
AA/AAA pass-fail with the exact contrast ratio, not a guess.
CSS Gradient Generator
Linear and radial gradients with editable stops and copy-paste CSS.
CSS Box Shadow Generator
Stack and tune layered shadows, then export the full declaration.
Contrast, by the numbers
WCAG 2.2 keeps the same luminance thresholds its predecessors used. AA wants 4.5:1 for normal text and 3:1 for large text, where large means 18pt regular or 14pt bold, and the same 3:1 level covers user interface components. AAA raises that to 7:1 and 4.5:1. The checker computes the ratio from the relative luminance of the two colors, not from how far apart the hex values look, then reports pass or fail for every level plus the exact number.
That number is the useful part. It turns a style guess into a specific move.
Relative luminance, as defined in CSS Color Module Level 4, starts from linearized sRGB components rather than a perceptual scale. That is why two colors that look equally dark on screen can still fail. The same math explains the thresholds: large type gets a lower bar because bigger glyphs tolerate lower contrast, and components get the 3:1 level because interfaces are read at a glance, which is why the checker exists. The pair that looks fine is not always the pair that passes.
One gotcha people miss: the same pair that passes on white can fail on near-black, and muted grays on a #09090B background are the usual culprit. Re-check both themes.
Gradients that don’t band
The generator builds linear-gradient() and radial-gradient() with editable stops, so the syntax you copy is exactly what the browser parses, direction keyword and all. Two details separate a smooth fade from an amateur one. Interpolation happens in sRGB by default, which muddies the middle of a blend. Where the browser supports a perceptual space such as oklab, linear-gradient(in oklab, …) keeps the midpoint closer to what the eye expects. Too few stops over a long run then cause visible banding.
Add a midpoint stop if you see stripes. Two stops across a full-width banner always band.
If you actually want crisp stripes, hard stops are the trick: color 0 40%, color 40% 100% gives a clean cut with no fade. The two stops sit at the same point, so the transition has zero length. That is the pattern for progress bars, dividers and flags, and a common way to fake an angle change inside a single element. Nudge one stop and the same section switches from hard stripes to a soft blend.
Radial gradients follow the same grammar. Keep the shape and position explicit, circle at center for instance, so the result does not shift when the box resizes.
The shadow “spread” people skip
box-shadow takes offset-x, offset-y, blur, spread, then color, in that order, and that order is part of the grammar: put color first and the declaration fails to parse. The two offsets place the shadow, blur softens the edge, spread enlarges or shrinks the painted area, and color is painted last. The generator exposes all five, lets you stack several shadows, and copies the full comma-separated declaration to the clipboard. Every value has a live effect in the preview, which is the fastest way to learn what each argument actually does.
Spread is the argument most people leave at 0. Negative spread pulls the shadow inward.
Positive spread does the opposite, so a shadow reads like a border without a border. Layering order matters: earlier declarations paint on top of later ones, and the whole list applies as one property value. That is why two stacked shadows such as 0 1px 2px … and 0 8px 24px … read as one natural shadow: one tight and close, the other soft and far. Stacking is also cheaper to repaint than a single huge blur.
Watch the blur radius if the element animates. A large blur repaints a bigger area on every frame, so prefer two small shadows over one huge one.
Why these tools run in your browser
All three tools run entirely in your browser, for a simple reason: the values they produce are exactly the values the browser’s own rendering engine consumes. There is no result to upload, no server to round-trip, no intermediate format to reconcile. Contrast ratios come from the same color math the browser uses, gradients are emitted as the CSS functions the engine parses, and shadows as the property declaration it paints. The output is not a translation of the design. It is the design, in the grammar the web already speaks.
The trade-off: heavy work runs on your CPU and RAM.
For these three tools that trade-off is rarely visible, because the calculations are small. The same architecture shows its limits elsewhere on the site, where a very large file can stall the tab while it is processed. Run one check at a time and the preview stays instant.
Common mistakes to avoid
The three mistakes I see most often. Judging contrast by eye, which collapses on a dim screen because the ratios that matter are luminance-based. Testing only the light theme, when dark mode flips the effective background and takes every muted gray with it. Reusing one shadow token everywhere, when elevation should scale with the surface it lifts. Treating a big blur radius as a free upgrade, when it enlarges the repaint area and flattens the depth cue.
Check the output where it will actually run, in both themes, at the sizes you ship.
The WCAG, color and shadow references behind these design tools
The behavior these tools rely on is defined by the web standards below.
- WCAG 2.2 sets the AA and AAA contrast thresholds, including the 4.5:1 and 3:1 targets, the checker reports against.
- WCAG quick reference shows how those thresholds apply to normal text, large text and UI components.
- CSS Color Module Level 4 defines the relative luminance calculation and the oklab interpolation space used above.
- MDN: CSS gradients documents the
linear-gradient()andradial-gradient()syntax, stop positions and interpolation keyword the generator emits. - MDN: box-shadow documents the offsets, blur, spread, layering order and negative-value rules behind the shadow tool.