Visual Craft Standards — Expert-Level Polish
What separates expert UI from amateur UI is rarely the big idea. It is spacing discipline, optical honesty, complete states, and a system applied without exceptions. This file is the pixel-level rulebook.
The two registers
Every craft decision depends on which register you are in. Name it before polishing:
- Brand register (landing pages, marketing, portfolios — design IS the product): asymmetric compositions, fluid spacing via
clamp(), intentional grid-breaking, rhythm through contrast (tight groupings against generous separations). Safe = invisible. - Product register (apps, dashboards, tools — design serves the task): predictable grids, consistent densities, familiar patterns. Consistency IS an affordance. Theatrics undermine trust; amplification lives in clarity, not drama.
Spacing discipline
- Use a 4pt base scale, not 8pt. 8pt is too coarse — you constantly need 12px. Working set: 4, 8, 12, 16, 24, 32, 48, 64, 96px.
- Every gap comes from the scale. A random 13px gap is a defect. If a value isn't on the scale, it needs a reason or a fix.
- Name tokens by relationship (
--space-sm,--space-lg), never by value (--spacing-8). - Use
gapfor sibling spacing, not margins — it eliminates margin-collapse hacks and cleanup CSS. - Rhythm, not uniformity. Equal padding everywhere = no hierarchy. Tight grouping for related elements (8–12px between siblings); generous separation between distinct sections (48–96px). Related things sit close; unrelated things sit far.
- Vertical rhythm anchor: derive vertical spacing from the body line-height. 16px body at 1.5 = 24px unit; vertical gaps should be multiples of it.
- Density must match content: data-dense UIs run tighter; marketing surfaces need air. Cramped and wastefully sparse are both failures.
Alignment and optical corrections
Geometric correctness is not visual correctness. Experts correct for the eye:
- Text at
margin-left: 0looks indented because of letterform side-bearing. Pull large display text back with roughly-0.05emnegative margin to optically align with a hard edge. - Geometrically centered icons often look off-center. Play/triangle icons need a nudge right; directional arrows shift slightly toward their direction. Nudge only when you can see it's wrong — never speculatively.
- Icons align to adjacent text optically, not by bounding box.
- Enable a grid overlay and inspect. Hunt anything that "feels off" — feeling off is usually a 1–3px alignment defect.
Visual hierarchy
- The squint test: blur your eyes (or blur a screenshot). You must still identify the most important element, the second most important, and the groupings. If everything reads the same weight blurred, hierarchy has failed.
- Combine 2–3 dimensions for strong hierarchy — a heading that is larger AND bolder AND has more space above it. Reference thresholds:
| Tool | Strong | Weak |
|---|---|---|
| Size | ≥3:1 ratio | <2:1 ratio |
| Weight | Bold vs Regular | Medium vs Regular |
| Color | High contrast | Similar tones |
| Position | Top/left | Bottom/right |
| Space | Surrounded by whitespace | Crowded |
- Use the fewest dimensions that work. Generous whitespace alone can carry hierarchy; the most polished designs often use just space and weight. Add color/size contrast only when simpler means fail.
- The 2-second rule: the most important content on the screen should be obvious within 2 seconds.
Cards, containers, grids
- Cards are overused. Spacing and alignment create grouping naturally. Use a card only when content is truly distinct and actionable, needs grid comparison, or needs a clear interaction boundary.
- Never nest cards inside cards. Use spacing, typography, and subtle dividers inside a card.
- Break card-grid monotony: vary sizes, span columns, mix card and non-card content. Endless icon+heading+text tiles is a template tell.
- Flexbox for 1D, Grid for 2D. Don't default to Grid when
flex-wrapis simpler. repeat(auto-fit, minmax(280px, 1fr))gives breakpoint-free responsive grids. Namedgrid-template-areasfor complex page layouts, redefined per breakpoint.- Container queries for components, viewport queries for pages. A card in a narrow sidebar should compact itself regardless of viewport.
- Don't center everything. Left-aligned asymmetric composition reads as designed; a strict visible grid reads as confident. The failure mode is splitting the difference into a generic centered stack.
Depth: shadows, borders, elevation
- Shadows must be subtle. If you can clearly see it, it's probably too strong. Build a consistent scale (sm → md → lg → xl) and use elevation to reinforce hierarchy, never as decoration.
- Semantic z-index scale, never arbitrary numbers: dropdown (100) → sticky (200) → modal-backdrop (300) → modal (400) → toast (500) → tooltip (600).
z-index: 9999is a defect. - Dark mode depth comes from surface lightness, not shadows. Build a 3-step surface scale where higher elevation = lighter (e.g. 15% / 20% / 25% OKLCH lightness), same hue/chroma as the brand color.
- Borders: reduce thickness or opacity before adding more of them. Heavy alpha/transparency use is a design smell — it signals an incomplete palette and creates unpredictable contrast.
Color craft (the polish-level rules)
- Never pure gray or pure black. Add 0.005–0.015 chroma tinted toward the project's brand hue. Real surfaces always have a color cast.
- Never gray text on a colored background — it reads washed-out and dead. Use a darker shade of that background color, or transparency of the foreground.
- 60-30-10 by visual weight: ~60% neutral surfaces/whitespace, ~30% secondary (text, borders), ~10% accent. Accents work because they are rare.
- Placeholder text still needs 4.5:1 contrast. Light-gray-on-white placeholders are the #1 accessibility fail.
Touch targets and interactive completeness
- 44×44px minimum touch targets. Visual size can be smaller — expand the hit area with padding or a pseudo-element:
.icon-button { width: 24px; height: 24px; position: relative; } /* visual size */
.icon-button::before { content: ''; position: absolute; inset: -10px; } /* 44px hit area */
- Every interactive element ships all eight states: default, hover, focus-visible, active, disabled, loading, error, success. A missing state is a broken experience, not a nice-to-have.
- Focus rings: 2–3px thick, offset outside the element, ≥3:1 contrast against adjacent colors, consistent everywhere. Never
outline: nonewithout a:focus-visiblereplacement.
The polish pass (order matters)
- Never polish before functional completeness. Polish is the last step.
- Align to the design system first. Polish without alignment is decoration on drift. For every deviation, name the root cause: missing token (patch the system), one-off implementation (swap to the shared component), or conceptual misalignment (flow/IA doesn't match neighboring features — rework the flow). Fixing symptoms without naming the cause compounds drift.
- Check flow shape, not just surface. Progressive disclosure depth, modal-vs-page, save-on-blur vs explicit submit, and naming ("Workspace" here must not be "Project" there) must match adjacent features. A settings page exposing 40 fields when the rest of the app reveals 5 at a time is drift even if perfectly styled.
- Triage cosmetic vs functional. Functional (breaks/blocks/confuses) ships first; cosmetic can follow. Never perfect one corner while leaving another rough — quality must be consistent.
- Then sweep: alignment/spacing → typography (hierarchy, widows, measure) → color/contrast/tokens → all interaction states → transitions (150–300ms, ease-out family, never bounce/elastic) → copy consistency (terminology, capitalization, punctuation) → icons (one family only) → forms → edge cases (empty/error/loading/long-content) → responsive (44px targets, ≥14px mobile text, no horizontal scroll) → performance (no CLS, 60fps) → code hygiene (no console logs, dead code,
any). - Verify by using it yourself, at multiple viewports, in every state — not just the happy path. Automated detector output is defect evidence only, never proof of quality.
The full polish checklist
- Aligned to the design system; every drift named and resolved by root cause
- Flow shape and IA match neighboring features
- Visual alignment perfect at all breakpoints; spacing entirely from tokens
- Typography hierarchy consistent; no widows on headings; measure in range
- All eight interaction states implemented on every interactive element
- All transitions smooth (60fps), 150–300ms, ease-out family
- Copy consistent: one term per concept, one capitalization scheme, one punctuation rule
- Icons from a single family, consistently sized, optically aligned to text
- Forms labeled and validated; logical tab order; consistent validation timing
- Error states helpful; loading states clear; empty states welcoming with an action
- Long content, missing data, and overflow handled gracefully
- Touch targets ≥44×44px; mobile text ≥14px; no horizontal scroll
- Contrast meets WCAG AA; keyboard navigation complete; focus visible
- No console errors; no layout shift on load; reduced motion respected
- Code clean: no TODOs, console.logs, commented-out code, unused imports
Post-polish cleanup
- Swap any custom reimplementation for the design-system component it duplicates.
- Delete orphaned styles/components made obsolete by the polish.
- Promote repeated new values into tokens; consolidate duplication introduced while polishing.
Making a design quieter (restraint with precision)
Quiet is harder than loud; subtlety needs precision. Quiet ≠ generic — think luxury, not laziness.
- Desaturate to 70–85% of full saturation; let neutrals dominate; keep color as a 10% accent.
- Step weights down: 900 → 600, 700 → 500. Carry hierarchy with weight, size, space instead of color and boldness.
- Reduce borders (thinner, lower opacity, or gone), flatten layering, strip gradients/glows/multi-shadows that serve nothing.
- Shrink motion: 10–20px travel instead of 40px, ease-out-quart, remove decorative animation entirely.
- Reduce scale jumps and even out spacing extremes for calm.
- Never: flatten all hierarchy, remove all color, or erase the point of view. Restrained, not absent — the POV must survive the cuts.
Making a design bolder (impact without slop)
"Bolder" defaults to slop: cyan/purple gradients, glassmorphism, neon-on-dark, gradient metric text. Reject those first. Bold = distinctive and committed, not "more effects."
- Pick ONE hero moment and make it exceptional; amplify contrast around it (big things bigger, small things smaller).
- Typography: 3×–5× size jumps (not 1.5×); pair weight 900 with 200, not 600 with 400; distinctive faces, variable fonts, condensed/extended widths.
- Color: let one bold color own ~60% of the design; tinted neutrals; sharp accents; intentional multi-stop gradients — never the stock purple-to-blue.
- Space: 100–200px section gaps, grid-breaking hero elements, asymmetric tension, 70/30 or 80/20 splits instead of polite symmetry.
- Texture over glass: grain, halftone, duotone, geometric pattern. Not glassmorphism.
- Motion: staggered entrance choreography with 50–100ms delays, ease-out-quart/quint/expo. Never bounce or elastic — they cheapen everything.
- The test: if someone would instantly believe "AI made this bolder," it failed.
Amateur tells — the ban list
- Arbitrary spacing values; equal spacing everywhere
- Everything wrapped in cards; cards nested in cards; identical icon+heading+text grids
- Everything centered; the hero-metric template (big decorative number, small label, gradient)
- Arbitrary z-index (999/9999); visible heavy shadows; shadow-as-decoration
- Pure #000 / pure gray; gray text on colored backgrounds
- Hover-only functionality; missing focus states; sub-44px targets
- Hard-coded values where tokens exist; one-off components duplicating system ones
- Bounce/elastic easing; animation as loading camouflage
- Polishing one screen while the system-level defect stays (if spacing is off everywhere, fix the scale, not the screen)
The exit bar: every screen defensible in a high-end studio review. Zoom in. Squint. Use it yourself. The little things are the work.