Skip to main content

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:

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 LibraryCharacteristicsBest For
shadcn/uiCopy-paste, full control, TailwindTop choice for Next.js projects
Ant DesignMost comprehensive components, great Chinese ecosystemAdmin dashboards
MUI (Material UI)Google style, mature and stableGeneral web apps
daisyUITailwind plugin, lightweightQuick 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:

FontStyleBest For
InterModern, cleanAlmost any web app
Plus Jakarta SansRounded, friendlyConsumer products
GeistBy Vercel, minimalistDeveloper tools
Noto Sans SCChinese go-toChinese-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 PromptStrong Prompt
Make the page look niceUnify spacing to multiples of 8, primary color orange-500, border radius rounded-xl
Add some animationsCards fade in from 20px below on page load, duration 300ms
Make it work on mobileUse max-w-md to limit width, button height at least 48px
Add dark modedark:bg-gray-900 background, dark:text-gray-100 text, localStorage for preference
Show loading stateUse 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 PointExplanation
ConsistencyUnify spacing, colors, border radius, font sizes
Visual hierarchyImportant things big and prominent, secondary things recede
AnimationsFast (200-300ms), minimal, natural
ResponsiveMobile-first, ensure small screens work
Dark modeTailwind's dark: prefix + localStorage to remember preference
Loading/empty statesTell users "loading" or "here's what you can do"
Prompt tipsGive 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:

  1. Choose a primary color (recommended: Tailwind's orange-500 or blue-500)
  2. Use a prompt to unify spacing (multiples of 8), border radius (rounded-xl), font sizes
  3. Compare before and after

Exercise 2: Component Library Migration (20 minutes)

Migrate your project to shadcn/ui:

  1. npx shadcn@latest init to initialize
  2. Add button, card, input components
  3. Replace native HTML elements with shadcn components

Exercise 3: Responsive Check (10 minutes)

  1. Press F12 to open DevTools
  2. Switch to mobile view
  3. Use AI to fix all layout issues

Exercise 4: Empty State Design (10 minutes)

  1. Clear all data and see what the page looks like
  2. If it's blank, use AI to add friendly guidance text and icons