
Ui Ux Polish
- 416 installs
- 14 repo stars
- Updated March 2, 2026
- oakoss/agent-skills
ui-ux-polish is a frontend polish skill that improves spacing, typography, responsive layout, component states, and micro-interactions so web UIs feel production-ready for developers finishing feature-complete interfaces
About
ui-ux-polish is an agent skill from oakoss/agent-skills for elevating web interfaces from functional to production-quality. It guides adjustments to spacing rhythm, typographic hierarchy, responsive breakpoints, interactive states, and subtle micro-interactions that signal craft. Developers reach for ui-ux-polish after core features work but the UI still feels rough—uneven padding, weak focus states, jarring layout shifts, or flat hover feedback. The skill gives agents concrete visual refinement patterns rather than generic “make it prettier” advice, helping teams ship SaaS dashboards, marketing pages, and admin tools that read as intentionally designed.
- Spacing rhythm
- Typography scale
- Responsive layout
- Empty and error states
- Micro-interactions
Ui Ux Polish by the numbers
- 416 all-time installs (skills.sh)
- +19 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #667 of 1,880 Design & UI/UX skills by installs in the Skillselion catalog
- Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/oakoss/agent-skills --skill ui-ux-polishAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 416 |
|---|---|
| repo stars | ★ 14 |
| Last updated | March 2, 2026 |
| Repository | oakoss/agent-skills ↗ |
How do you polish a web UI to feel production-ready?
Improve spacing, typography, responsive layout, states, and micro-interactions to make web UIs feel production-ready.
Who is it for?
Frontend developers with working components who need systematic visual refinement before release or demo.
Skip if: Teams still defining product requirements, building backend-only services, or needing full brand-system creation from scratch.
When should I use this skill?
A developer has a functional web UI that needs spacing, typography, responsive, state, or micro-interaction polish before shipping.
What you get
Refined spacing scale, typography hierarchy, responsive layout fixes, interactive state styles, and micro-interaction updates.
- polished component styles
- responsive layout fixes
Files
UI/UX Polish
Iterative enhancement workflow that takes working web applications from decent to world-class. Covers desktop and mobile optimization as separate modalities, visual design patterns, and accessibility standards.
When to use: The app works correctly with basic styling in place and you want to improve visual quality through iterative refinement. Also use for applying specific design patterns (glassmorphism, neumorphism, bento grids) or auditing accessibility.
When NOT to use: The app is broken or buggy (fix bugs first), styling is fundamentally wrong (needs complete overhaul), or no basic design system exists yet.
Quick Reference
| Pattern | Technique | Key Point |
|---|---|---|
| Iterative polish | Run the same polish prompt 10+ times | Small improvements compound dramatically |
| Desktop/mobile split | Optimize each modality independently | Prevents compromises that hurt both |
| Glassmorphism | backdrop-blur-xl + bg-white/70 + border | Functional depth with legibility |
| Neumorphism | Dual-direction box shadows | Best in light mode; use borders for a11y |
| Bento grid | CSS Grid with rounded-3xl cells | Hero cell spans multiple columns/rows |
| WCAG 2.2 AA | Contrast ratios + target sizes + focus visible | 4.5:1 text, 3:1 UI, 24x24px targets |
| Reduced motion | prefers-reduced-motion: reduce | Disable animations for motion-sensitive users |
| Semantic HTML | Landmarks + heading hierarchy + native elements | Use <button> not <div role="button"> |
| Inclusive design | Multiple input methods + error forgiveness | Support keyboard, voice, and touch equally |
| Typography hierarchy | Consistent scale with clear levels | Font size, weight, and spacing rhythm |
| Spacing rhythm | Consistent padding and margin scale | Use design token multiples (4px, 8px, 16px) |
| Hover/focus states | Visible feedback on all interactive elements | Keyboard users need visible focus indicators |
| Animation/transitions | ease-out enter, ease-in exit, 100-300ms | Prefer transform/opacity for GPU compositing |
| Micro-interactions | Button press, toggle, focus, success/error | Always respect prefers-reduced-motion |
Common Mistakes
| Mistake | Correct Pattern |
|---|---|
| Running polish on a broken app | Fix all functional bugs first, then apply iterative polish |
| Making one large pass instead of many small ones | Run 10+ iterations; incremental improvements compound |
| Optimizing desktop and mobile simultaneously | Treat each as a separate modality and optimize independently |
| Stopping after changes appear minimal | Keep iterating; subtle spacing and typography tweaks add up |
| Applying glassmorphism to all elements | Use glass effects strategically on cards and modals only |
| Neumorphism without accessibility borders | Add a 1px border for low-vision users (contrast requirement) |
Ignoring prefers-reduced-motion | Always respect system motion preferences in CSS |
Using <div> with click handlers instead of <button> | Use native semantic HTML elements for built-in accessibility |
Delegation
- Desktop and mobile polish in parallel: Use
Taskagent to run separate polish passes for each modality - Visual regression verification: Use
Exploreagent to check that polish iterations have not broken layout or accessibility - Design system alignment planning: Use
Planagent to establish spacing, typography, and color patterns before polishing - Full accessibility audits: Delegate to
accessibilityskill for in-depth WCAG compliance, ARIA patterns, focus management, and screen reader testing
References
- Polish Workflow -- The iterative polish prompt, why it works, iteration protocol, and multi-agent strategies
- Design Patterns -- Glassmorphism, neumorphism, bento grids with Tailwind implementations
- Accessibility -- WCAG 2.2 AA standards, semantic HTML, ARIA, inclusive design, and reduced motion
- Animation and Micro-interactions -- CSS transitions, loading states, spring animations, page transitions, and Tailwind animation utilities
WCAG 2.2 Level AA
The Four Principles (POUR)
1. Perceivable: Provide text alternatives for non-text content 2. Operable: Make all functionality available from a keyboard 3. Understandable: Make text readable and interface predictable 4. Robust: Maximize compatibility with assistive technologies
Key Success Criteria
| Criterion | Requirement |
|---|---|
| Normal text contrast | 4.5:1 minimum |
| Large text contrast (18pt+) | 3:1 minimum |
| UI component contrast | 3:1 for borders, icons, focus rings |
| Target size | Minimum 24x24 pixels for interactive elements |
| Focus visibility | Focus indicator always visible, not obscured by sticky elements |
| Redundant entry | Do not require re-entering previously provided information |
Reduced Motion
Always respect the user's system motion preferences:
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}Semantic HTML
Landmark Elements
| Element | Purpose |
|---|---|
<header> | Global site navigation and branding |
<main> | Unique content of the page |
<nav> | Navigation links |
<aside> | Complementary content (sidebar) |
<footer> | Site-wide links and metadata |
Heading Hierarchy
- Only one
<h1>per page - Never skip heading levels (do not go from
<h2>to<h4>) - Headings create a logical outline for screen readers
Native Elements Over ARIA
The first rule of ARIA: if a native HTML element provides the semantics you need, use it instead.
<!-- Bad -->
<div role="button" onclick="handleClick()">Submit</div>
<!-- Good -->
<button type="submit">Submit</button>Essential ARIA Attributes
| Attribute | Use Case |
|---|---|
aria-label | Icon-only buttons |
aria-expanded | Accordions and dropdowns |
aria-live | Dynamic content updates (toast notifications) |
aria-invalid | Form validation errors |
aria-describedby | Additional field descriptions |
Form Accessibility
<label for="email-input">Email Address</label>
<input id="email-input" type="email" aria-describedby="email-hint" required />
<p id="email-hint">We'll never share your email.</p>Inclusive Design Patterns
Multiple Methods of Success
Provide different ways for users to achieve a goal: text search, voice input, and visual selection.
Error Forgiveness
- Provide "Undo" options for destructive actions
- Use clear, non-judgmental error messages that suggest a path forward
Cognitive Accessibility
- Use plain language and avoid unnecessary jargon
- Keep interactive elements in predictable locations
- Offer focus mode to hide non-essential UI during deep tasks
Dark/Light Mode Parity
Neither mode should feel like an afterthought. Check contrast and visual hierarchy in both modes. Use CSS variables or Tailwind theme tokens for consistent switching.
Situational Inclusion
Design for temporary and situational disabilities:
| Situation | Accommodation |
|---|---|
| Broken arm | Full keyboard navigation support |
| Noisy environment | Captions for all video content |
| Bright sunlight | High-contrast mode |
| Slow connection | Meaningful loading states |
Testing Tools
| Tool | Purpose |
|---|---|
| axe-core | Automated accessibility audits |
| Screen readers (NVDA, JAWS, VoiceOver) | Manual assistive technology testing |
| Keyboard-only navigation | Navigate entire app without a mouse |
| Color contrast analyzer | Verify contrast ratios meet WCAG |
Further Reading
For full WCAG compliance, ARIA widget patterns, focus management, screen reader testing, and form accessibility, delegate to the accessibility skill.
CSS Transition Fundamentals
Timing Functions
Choose timing functions based on the direction of motion:
| Direction | Timing Function | Reason |
|---|---|---|
| Enter/appear | ease-out | Starts fast, decelerates — feels snappy |
| Exit/disappear | ease-in | Starts slow, accelerates — feels natural |
| Move/reposition | ease-in-out | Smooth start and end for spatial movement |
| Instant feedback | linear | Consistent speed for progress indicators |
Duration Guidelines
| Category | Duration | Use Case |
|---|---|---|
| Micro | 100-150ms | Button press, toggle, color shift |
| Small | 150-300ms | Hover states, focus rings, tooltip show |
| Medium | 300-500ms | Layout shifts, accordion expand, card flip |
| Large | 500-800ms | Page transitions, modal enter, route change |
Anything over 300ms should be interruptible. Never exceed 1000ms for UI transitions.
Base Transition Pattern
.interactive-element {
transition-property: transform, opacity, box-shadow;
transition-duration: 150ms;
transition-timing-function: ease-out;
}Hover and Focus State Transitions
Button Hover
<button className="bg-blue-600 text-white px-4 py-2 rounded-lg transition-all duration-150 ease-out hover:bg-blue-700 hover:shadow-md hover:-translate-y-0.5 active:translate-y-0 active:shadow-sm">
Save Changes
</button>Card Hover with Lift Effect
<div className="rounded-2xl bg-white p-6 shadow-sm transition-all duration-200 ease-out hover:shadow-lg hover:-translate-y-1">
<h3 className="text-lg font-semibold">Card Title</h3>
</div>Focus Ring with Transition
<input className="rounded-lg border border-gray-300 px-3 py-2 transition-all duration-150 ease-out focus:border-blue-500 focus:ring-2 focus:ring-blue-500/20 focus:outline-none" />Icon Hover Rotation
<button className="group p-2 rounded-full transition-colors duration-150 hover:bg-gray-100">
<svg className="h-5 w-5 transition-transform duration-200 ease-out group-hover:rotate-12" />
</button>Loading State Patterns
Skeleton Screen
function SkeletonCard() {
return (
<div className="animate-pulse space-y-4 rounded-2xl bg-white p-6">
<div className="h-4 w-3/4 rounded bg-gray-200" />
<div className="h-4 w-1/2 rounded bg-gray-200" />
<div className="h-32 rounded-lg bg-gray-200" />
</div>
);
}Shimmer Effect
@keyframes shimmer {
0% {
background-position: -200% 0;
}
100% {
background-position: 200% 0;
}
}
.skeleton-shimmer {
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
background-size: 200% 100%;
animation: shimmer 1.5s infinite;
}Spinner with Accessible Label
<div className="flex items-center gap-2">
<svg
className="h-5 w-5 animate-spin text-blue-600"
viewBox="0 0 24 24"
fill="none"
>
<circle
className="opacity-25"
cx="12"
cy="12"
r="10"
stroke="currentColor"
strokeWidth="4"
/>
<path
className="opacity-75"
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
/>
</svg>
<span className="sr-only">Loading</span>
</div>Progress Bar
function ProgressBar({ value }: { value: number }) {
return (
<div className="h-2 w-full overflow-hidden rounded-full bg-gray-200">
<div
className="h-full rounded-full bg-blue-600 transition-all duration-300 ease-out"
style={{ width: `${Math.min(100, Math.max(0, value))}%` }}
role="progressbar"
aria-valuenow={value}
aria-valuemin={0}
aria-valuemax={100}
/>
</div>
);
}Micro-interactions
Button Press Feedback
<button className="transform rounded-lg bg-blue-600 px-4 py-2 text-white transition-all duration-100 ease-out hover:bg-blue-700 active:scale-95">
Submit
</button>Toggle Switch
function Toggle({
checked,
onChange,
}: {
checked: boolean;
onChange: (v: boolean) => void;
}) {
return (
<button
role="switch"
aria-checked={checked}
onClick={() => onChange(!checked)}
className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors duration-200 ease-out ${checked ? 'bg-blue-600' : 'bg-gray-300'}`}
>
<span
className={`inline-block h-4 w-4 rounded-full bg-white shadow-sm transition-transform duration-200 ease-out ${checked ? 'translate-x-6' : 'translate-x-1'}`}
/>
</button>
);
}Form Input Focus
<div className="group relative">
<label className="absolute -top-2.5 left-3 bg-white px-1 text-xs text-gray-500 transition-all duration-150 ease-out group-focus-within:text-blue-600">
Email
</label>
<input className="w-full rounded-lg border border-gray-300 px-3 py-2 transition-all duration-150 ease-out focus:border-blue-500 focus:ring-2 focus:ring-blue-500/20 focus:outline-none" />
</div>Success State
<div className="flex items-center gap-2 rounded-lg bg-green-50 px-4 py-3 text-green-700 animate-in fade-in slide-in-from-top-2 duration-300">
<svg className="h-5 w-5" fill="currentColor" viewBox="0 0 20 20">
<path
fillRule="evenodd"
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z"
clipRule="evenodd"
/>
</svg>
<span>Changes saved successfully</span>
</div>Error Shake
@keyframes shake {
0%,
100% {
transform: translateX(0);
}
20%,
60% {
transform: translateX(-4px);
}
40%,
80% {
transform: translateX(4px);
}
}
.shake {
animation: shake 400ms ease-out;
}Page Transition Patterns
Fade Transition
.page-enter {
opacity: 0;
}
.page-enter-active {
opacity: 1;
transition: opacity 300ms ease-out;
}
.page-exit {
opacity: 1;
}
.page-exit-active {
opacity: 0;
transition: opacity 200ms ease-in;
}Slide Transition
.slide-enter {
transform: translateX(100%);
opacity: 0;
}
.slide-enter-active {
transform: translateX(0);
opacity: 1;
transition:
transform 300ms ease-out,
opacity 300ms ease-out;
}
.slide-exit-active {
transform: translateX(-30%);
opacity: 0;
transition:
transform 200ms ease-in,
opacity 200ms ease-in;
}Cross-fade Between Views
function CrossFade({
show,
children,
}: {
show: boolean;
children: React.ReactNode;
}) {
return (
<div
className={`transition-all duration-300 ease-out ${show ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-2 pointer-events-none'}`}
>
{children}
</div>
);
}Spring Animations with CSS
Approximate spring physics using cubic-bezier. Real spring motion overshoots then settles.
Common Spring Curves
:root {
--spring-bounce: cubic-bezier(0.34, 1.56, 0.64, 1);
--spring-smooth: cubic-bezier(0.22, 1, 0.36, 1);
--spring-snappy: cubic-bezier(0.16, 1, 0.3, 1);
}Bounce-in Effect
<div className="transition-transform duration-500 [transition-timing-function:cubic-bezier(0.34,1.56,0.64,1)] hover:scale-105">
Bouncy Card
</div>Modal Enter with Spring
@keyframes spring-in {
0% {
opacity: 0;
transform: scale(0.9) translateY(8px);
}
70% {
transform: scale(1.02) translateY(-2px);
}
100% {
opacity: 1;
transform: scale(1) translateY(0);
}
}
.modal-enter {
animation: spring-in 400ms cubic-bezier(0.22, 1, 0.36, 1) forwards;
}Reduced Motion
Always respect user preferences. Provide functional alternatives, not just removal.
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}Tailwind Approach
<div className="transition-transform duration-300 hover:-translate-y-1 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
Respects user preferences
</div>JavaScript Detection
const prefersReducedMotion = window.matchMedia(
'(prefers-reduced-motion: reduce)',
).matches;Tailwind CSS Animation Utilities
Built-in Animations
| Class | Effect | Use Case |
|---|---|---|
animate-spin | Continuous rotation | Loading spinners |
animate-ping | Scale + fade out | Notification badges |
animate-pulse | Opacity oscillation | Skeleton screens |
animate-bounce | Vertical bounce | Scroll indicators |
Custom Keyframes in Tailwind Config
export default {
theme: {
extend: {
keyframes: {
'fade-in': {
'0%': { opacity: '0', transform: 'translateY(4px)' },
'100%': { opacity: '1', transform: 'translateY(0)' },
},
'slide-up': {
'0%': { transform: 'translateY(100%)' },
'100%': { transform: 'translateY(0)' },
},
},
animation: {
'fade-in': 'fade-in 300ms ease-out',
'slide-up': 'slide-up 300ms ease-out',
},
},
},
};Transition Utilities
<div className="transition-all duration-200 ease-out">All properties</div>
<div className="transition-colors duration-150">Color changes only</div>
<div className="transition-transform duration-300">Transform only</div>
<div className="transition-opacity duration-200">Opacity only</div>Performance
Compositor-Only Properties
Prefer animating properties the browser can handle on the GPU without triggering layout or paint:
| Safe (compositor) | Unsafe (triggers layout) |
|---|---|
transform | width, height |
opacity | top, left, right, bottom |
filter | margin, padding |
border-width, font-size |
Promoting to GPU Layer
.animated-element {
will-change: transform;
}Use will-change sparingly. Apply it just before the animation starts and remove it after completion. Overuse creates excessive GPU memory consumption.
Avoiding Layout Thrashing
Never read layout properties and write styles in the same synchronous block. Batch reads and writes separately, or use requestAnimationFrame.
Staggered Animations
Stagger child animations to reduce simultaneous GPU work and create visual rhythm:
<ul>
{items.map((item, i) => (
<li
key={item.id}
className="animate-fade-in opacity-0"
style={{ animationDelay: `${i * 50}ms`, animationFillMode: 'forwards' }}
>
{item.name}
</li>
))}
</ul>Glassmorphism
Glassmorphism creates depth through blur, transparency, and edge lighting. Focus on legibility and visual hierarchy rather than pure transparency effects.
The Formula
- Blur: High backdrop blur (
backdrop-blur-xl) - Transparency: Medium opacity (
bg-white/70light,bg-black/40dark) - Edge Lighting: Subtle bright border (
border-white/20)
Implementation
<div className="bg-white/70 dark:bg-slate-900/40 backdrop-blur-xl border border-white/20 dark:border-slate-800/50 rounded-2xl p-6 shadow-xl">
<h3 className="text-lg font-semibold">Glass Card</h3>
<p className="text-slate-600 dark:text-slate-400">
Content that feels integrated.
</p>
</div>Legibility Standards
Never place critical text over high-contrast glass backgrounds. Use an overlay layer with 80%+ opacity if the background image is busy.
Layering and Z-Index
- Lower layer: Subtle blur, lower opacity
- Higher layer (modal): High blur, higher opacity, prominent white border
Micro-interactions
- Add a CSS shine effect on hover to simulate moving glass
- Pair with 150ms transitions for a "liquid" response
Neumorphism
Neumorphism creates a tactile, pressed/raised effect using dual-direction shadows. Focus on restraint and accessibility.
Tailwind Custom Shadows
@theme {
--shadow-neumorphic-up: 5px 5px 10px #bebebe, -5px -5px 10px #ffffff;
--shadow-neumorphic-down:
inset 5px 5px 10px #bebebe, inset -5px -5px 10px #ffffff;
}Best Practices
- Strategic use: Apply only to buttons, toggles, and cards that need a tactile feel. Do not apply to every element.
- Accessibility: Include a 1px border (
border-slate-200/50) to define shape for low-vision users. Stark neumorphism often fails contrast tests. - Light mode only: Neumorphism works best in light mode. For dark mode, use glassmorphism instead since shadows are harder to perceive on dark backgrounds.
Interaction States
- Normal:
shadow-neumorphic-up - Active/Pressed:
shadow-neumorphic-down+ slight background darkening
Bento Grid
Bento grids organize content into modular, responsive cells with visual hierarchy through size variation.
Core Principles
- Modular cells: Each content piece lives in its own container
- Visual hierarchy: Important cells occupy more columns or rows
- Consistent spacing: Standard gap (
gap-4orgap-6) - Exaggerated rounding:
rounded-3xlis a hallmark of the bento style
Implementation
<div className="grid grid-cols-1 md:grid-cols-4 grid-rows-2 gap-4">
{/* Hero cell spans 2 columns and 2 rows */}
<div className="md:col-span-2 md:row-span-2 bg-slate-100 rounded-3xl p-8">
<h2 className="text-3xl font-bold">Main Insight</h2>
</div>
{/* Medium cell */}
<div className="md:col-span-2 bg-slate-50 rounded-3xl p-6">
<p>Metric A</p>
</div>
{/* Small cells */}
<div className="bg-white border rounded-3xl p-6">
<p>Sub-metric B</p>
</div>
<div className="bg-white border rounded-3xl p-6">
<p>Sub-metric C</p>
</div>
</div>Interaction and Depth
- Subtle scale-up on hover:
hover:scale-[1.02] - Shadow progression:
shadow-smat rest,shadow-mdon hover
Responsive Adaptation
On mobile, bento grids collapse to a single-column stack. Keep the hero cell at the top. Design each cell to be consumed in under 5 seconds with clear typography and high-contrast icons.
The Polish Prompt
This prompt drives iterative visual refinement. Run it repeatedly (10+ times) for compounding improvements:
I still think there are strong opportunities to enhance the UI/UX look and feel and to make everything work better and be more intuitive, user-friendly, visually appealing, polished, slick, and world class in terms of following UI/UX best practices like those used by Stripe, don't you agree? And I want you to carefully consider desktop UI/UX and mobile UI/UX separately while doing this and hyper-optimize for both separately to play to the specifics of each modality. I'm looking for true world-class visual appeal, polish, slickness, etc. that makes people gasp at how stunning and perfect it is in every way. Use ultrathink.Alternative: General Scrutiny
Great, now I want you to super carefully scrutinize every aspect of the application workflow and implementation and look for things that just seem sub-optimal or even wrong/mistaken to you, things that could very obviously be improved from a user-friendliness and intuitiveness standpoint, places where our UI/UX could be improved and polished to be slicker, more visually appealing, and more premium feeling and just ultra high quality, like Stripe-level apps.Why This Prompt Works
Asks for Agreement
The phrase "don't you agree?" engages the model's reasoning about whether improvements are possible, rather than just executing instructions.
Separates Desktop and Mobile
Explicitly requesting separate optimization for each modality prevents compromises that work "okay" on both but great on neither.
Sets High Standards
References to "world class", "best practices like Stripe", and "makes people gasp" anchor the model toward higher quality than generic "make it better" instructions.
Uses Extended Thinking
Extended thinking allows the model to analyze the current state thoroughly, consider multiple improvement options, and choose the highest-impact changes.
Iteration Protocol
Single Agent
1. Run the polish prompt 2. Review the changes the agent makes 3. Run the same prompt again 4. Repeat 10+ times until changes become minimal
Each pass adds incremental improvements that compound. An app after 10 passes looks dramatically better than after 1 pass.
Multiple Agents
Multiple agents can work on UI/UX polish simultaneously:
- They focus on different areas of the application
- Use file reservations to avoid conflicts
- Compound improvements faster
What the Model Typically Improves
Visual Polish
- Spacing and padding consistency
- Typography hierarchy
- Color contrast and accessibility
- Shadow and depth effects
- Border radius consistency
- Hover and focus states
Interaction Design
- Button feedback
- Loading states
- Transitions and animations
- Error state handling
- Empty state design
Mobile Optimization
- Touch target sizes (24x24px AA minimum, 44x44px recommended)
- Responsive breakpoints
- Mobile-specific navigation
- Gesture support
- Performance on mobile devices
Desktop Optimization
- Keyboard navigation
- Hover states
- Multi-column layouts
- Sidebar navigation
- Power user shortcuts
Prerequisites
Before running the polish workflow, ensure:
- App works correctly (no functional bugs)
- Basic styling is in place
- A design system or component library exists
- Ready for iterative refinement
If the app needs a complete overhaul, establish a design system and component library first.
Related skills
How it compares
Use ui-ux-polish for incremental visual refinement on existing UIs; use full design-system skills when establishing brand tokens and component libraries from zero.
FAQ
What does ui-ux-polish improve in a web app?
ui-ux-polish improves spacing, typography, responsive layout, interactive states, and micro-interactions in web UIs. The skill targets the visual and interaction details that make functional interfaces feel production-ready.
When should developers use ui-ux-polish?
Developers should use ui-ux-polish after core features work but the interface still feels rough—uneven padding, weak focus states, or flat interactions. It is a refinement pass, not initial product scoping.