7.3 Design Polish: Make It Look Good
The MVP is done. It works, but it probably looks like "a programmer built it" — all the features are there, but it doesn't look great.
In this section, we'll use AI to turn "functional" into "beautiful."
The Problem: Your MVP Probably Looks Like This
- Inconsistent input sizes, uneven spacing
- Only default white background and blue links
- Layout breaks on mobile
- Blank screen while loading — users don't know what's happening
- Empty state when there are no tasks — no guidance at all
These issues are common, and they're all easy to fix.
Principle 1: Consistency
The first principle of design isn't "beauty" — it's "consistency."
Have your AI do one thing: unify all spacing and colors.
Prompt:
Help me unify the entire page's design specs:
1. Spacing: all module spacing uses multiples of 8 (mb-4, mb-6, mb-8)
2. Border radius: all cards and buttons use rounded-xl (12px)
3. Colors: primary color orange-500, secondary orange-100,
text gray-800 (headings) and gray-500 (secondary text)
4. Shadows: all cards use shadow-sm, upgrade to shadow-md on hover
5. Font sizes: headings text-2xl, body text-base, secondary text-sm
Keep functionality unchanged — only modify styles.
The key to this prompt is that it gives specific values, not just "make it look nice." If you only say "beautify," the AI might go overboard. Give specific specs and it'll optimize within those constraints.
Principle 2: Visual Hierarchy
Good design makes it instantly clear where to look and what to do.
Prompt:
Optimize the page's visual hierarchy:
1. Page title should be the largest and most prominent
2. Three input fields are the visual focus, wrapped in white cards that contrast with the background
3. Save button is secondary but has the most eye-catching color
4. AI encouragement area uses a card with a light orange background
5. Stats go in the top-right corner, small but precise
Use subtle separation: distinguish cards with appropriate whitespace
rather than dividing lines.
Add Animations
Static pages feel "dead" — add some animations and they come alive.
Prompt:
Add the following micro-animations to the page:
1. On page load, cards fade in and slide up from below (using Tailwind's animate and transition)
2. When a task is checked off, add a brief scale animation (scale up then back)
3. When AI encouragement appears, add a typewriter effect (CSS animation or simple JS)
4. On button hover, slightly lift up (transform: translateY(-2px))
Implement with Tailwind CSS — don't introduce extra animation libraries.
Keep animations restrained — duration 200-300ms.
The golden rule of animation: fast, minimal, natural. 200ms is enough. Over 500ms and users will feel lag.
Responsive Design
Your app needs to work on phones too. Most people will probably open your shared link on their phone.
Prompt:
Ensure the page displays perfectly on mobile:
1. Use max-w-md to limit max width, full width on mobile
2. Input fields shouldn't be too large on mobile — reduce padding appropriately
3. Stats area goes below the main content on mobile (not top-right corner)
4. Buttons should be large enough — at least 48px tall for easy finger tapping
5. Check that no text gets truncated on small screens
6. Leave enough safe space at the bottom (iPhone bottom bar area)
Use Tailwind's responsive prefixes: sm:, md:, lg:
After saving, press F12 in the browser to open DevTools, click the phone icon in the top-left corner, and simulate different phone sizes. Make sure everything looks good at every size.
Dark Mode
A standard feature in modern apps. And Tailwind has built-in dark mode support, so it's quick to add.
Prompt:
Add dark mode support to the page:
1. Toggle dark mode using a class on the <html> tag
2. Add a toggle button (🌙/☀️ icon) in the top-right corner
3. Background: dark:bg-gray-900
4. Cards: dark:bg-gray-800
5. Text: dark:text-gray-100
6. Input fields: dark:bg-gray-700 dark:border-gray-600
7. Use localStorage to remember user preference
Ensure all elements are clearly readable in dark mode,
especially input field text and placeholders.
Loading States and Empty States
These two states are the most commonly overlooked, but they have a huge impact on user experience.
Loading State
Prompt:
Add loading states:
1. On initial page load (fetching data from Supabase), show a skeleton screen
- Three gray bars simulating input fields
- One gray block simulating the button
2. When the AI encouragement button is clicked, change button text to "Thinking..." with a spinning loading icon
3. After the save button is clicked, briefly show "Saved ✓"
Use Tailwind's animate-pulse for the skeleton effect.
Empty State
Prompt:
Add empty state design:
When no tasks have been set for today:
1. Show a friendly illustration area (use large emoji: 📝🌅✨)
2. A guidance message: "A new day begins! Set your 3 most important things for today"
3. Input fields use dashed borders, hinting "fill in here"
When the AI encouragement area has no content yet:
1. Show a semi-transparent hint card
2. Text: "After saving your tasks, click here for AI encouragement ✨"
The principle of empty state design: tell the user "here's what you can do" — don't just show nothing.
Save 80% of Your Time with a UI Component Library
If you don't want to write styles from scratch, using a component library is the smartest choice. The top recommendations for 2026:
shadcn/ui — The Most Popular Choice Right Now
It's not an npm package — it's a set of component code that gets copied directly into your project. The benefit is full control; no risk of third-party updates breaking things.
# Initialize in your Next.js project
npx shadcn@latest init
# Add the components you need
npx shadcn@latest add button
npx shadcn@latest add card
npx shadcn@latest add input
npx shadcn@latest add dialog
npx shadcn@latest add toast
Usage:
import { Button } from "@/components/ui/button"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
export default function TaskCard() {
return (
<Card className="w-full max-w-md">
<CardHeader>
<CardTitle>Today's Tasks</CardTitle>
</CardHeader>
<CardContent>
<Button className="w-full">Save Tasks</Button>
</CardContent>
</Card>
)
}
shadcn/ui is built on Tailwind CSS and Radix UI — modern styling, good accessibility, dark mode support.
Other Options
| Component Library | Characteristics | Best For |
|---|---|---|
| shadcn/ui | Copy-paste, full control, Tailwind | Top choice for Next.js projects |
| Ant Design | Most comprehensive components, great Chinese ecosystem | Admin dashboards |
| MUI (Material UI) | Google style, mature and stable | General web apps |
| daisyUI | Tailwind plugin, lightweight | Quick Tailwind-based UI |
Prompt for AI:
Refactor the current page's UI using shadcn/ui:
1. Buttons use shadcn's Button component
2. Cards use shadcn's Card component
3. Input fields use shadcn's Input component
4. Keep existing functionality — only replace UI components
Icons and Favicon
Icons: Lucide Icons
shadcn/ui's companion icon library — lightweight and good-looking:
import { Check, Star, Settings, User } from "lucide-react"
// Use directly as components
<Check className="w-5 h-5 text-green-500" />
<Star className="w-5 h-5 text-yellow-500" />
Favicon: Show Your Logo in the Browser Tab
Have AI generate an SVG favicon for you:
Generate an SVG favicon for me:
- Simple geometric shape (circle or square)
- Use the project's primary color (orange-500) as background
- White uppercase letter (first letter of the project name) in the center
- Save as app/favicon.svg
Then reference it in app/layout.tsx:
export const metadata = {
icons: {
icon: '/favicon.svg',
},
}
Font Choices
Fonts have a bigger impact on "feel" than you'd expect. Here are some free and good-looking recommendations:
| Font | Style | Best For |
|---|---|---|
| Inter | Modern, clean | Almost any web app |
| Plus Jakarta Sans | Rounded, friendly | Consumer products |
| Geist | By Vercel, minimalist | Developer tools |
| Noto Sans SC | Chinese go-to | Chinese-language interfaces |
Using it in Next.js (using Inter as an example):
// app/layout.tsx
import { Inter } from "next/font/google"
const inter = Inter({ subsets: ["latin"] })
export default function RootLayout({ children }) {
return (
<html lang="zh-CN" className={inter.className}>
<body>{children}</body>
</html>
)
}
Color Tools
Not sure what colors to use? These tools help:
- Coolors.co: Press spacebar to randomly generate color palettes — lock the ones you like
- Realtime Colors: Preview colors in real-time on an actual webpage
- Tailwind CSS Colors: Use Tailwind's built-in colors directly — no manual tweaking needed
Color selection principles:
- 1 primary color (brand color, like orange)
- 1-2 secondary colors (gray tones mainly)
- 1 accent color (for buttons and links)
- No more than 3 colors total
Before vs After
Before:
- White background + default fonts + no spacing + no animations + no loading states
- Looks like a 2005 web form
After:
- Gradient background + card layout + breathing room in spacing + subtle animations + elegant loading/empty states
- Looks like a modern 2024 web app
The difference is only in the styling code — not a single line of functionality was changed.
Design Prompt Tips Summary
| Weak Prompt | Strong Prompt |
|---|---|
| Make the page look nice | Unify spacing to multiples of 8, primary color orange-500, border radius rounded-xl |
| Add some animations | Cards fade in from 20px below on page load, duration 300ms |
| Make it work on mobile | Use max-w-md to limit width, button height at least 48px |
| Add dark mode | dark:bg-gray-900 background, dark:text-gray-100 text, localStorage for preference |
| Show loading state | Use animate-pulse for skeleton screen, three gray bars simulating inputs |
Pattern: the more specific the prompt, the better the result. Don't make AI guess what you want — tell it directly.
Chapter Summary
| Key Point | Explanation |
|---|---|
| Consistency | Unify spacing, colors, border radius, font sizes |
| Visual hierarchy | Important things big and prominent, secondary things recede |
| Animations | Fast (200-300ms), minimal, natural |
| Responsive | Mobile-first, ensure small screens work |
| Dark mode | Tailwind's dark: prefix + localStorage to remember preference |
| Loading/empty states | Tell users "loading" or "here's what you can do" |
| Prompt tips | Give specific values — don't say "make it look nice" |
The app looks good now. In the next section, we'll deploy it so the whole world can use it.
🏋️ Exercises for This Section
Exercise 1: Design Standardization (15 minutes)
Use AI to unify your project's design specs:
- Choose a primary color (recommended: Tailwind's orange-500 or blue-500)
- Use a prompt to unify spacing (multiples of 8), border radius (rounded-xl), font sizes
- Compare before and after
Exercise 2: Component Library Migration (20 minutes)
Migrate your project to shadcn/ui:
npx shadcn@latest initto initialize- Add button, card, input components
- Replace native HTML elements with shadcn components
Exercise 3: Responsive Check (10 minutes)
- Press F12 to open DevTools
- Switch to mobile view
- Use AI to fix all layout issues
Exercise 4: Empty State Design (10 minutes)
- Clear all data and see what the page looks like
- If it's blank, use AI to add friendly guidance text and icons