Use this skill whenever building, editing, or reviewing user-facing software with Lovable — web apps, dashboards, marketing sites, SaaS surfaces, component libraries, or any code change that produces visual output. Triggers on requests to "build a UI", "design a page", "make a component", "improve the look", "polish this", "make it production-ready", or whenever scaffolding a new app, screen, or feature with visible surface area. Encodes Lovable's opinionated defaults for Tailwind CSS, shadcn/u…
Use this skill whenever building, editing, or reviewing user-facing software with Lovable — web apps, dashboards, marketing sites, SaaS surfaces, component libraries, or any code change that produces visual output.
Triggers on requests to "build a UI", "design a page", "make a component", "improve the look", "polish this", "make it production-ready", or whenever scaffolding a new app, screen, or feature with visible surface area.
Encodes Lovable's opinionated defaults for Tailwind CSS, shadcn/ui, oklch design tokens, typography, spacing, color, motion, accessibility, and the component patterns that hold up under real users.
Stronger alternatives
This repository is archived — consider an actively maintained alternative.
Commit to a tone, don't average across them — "Modern and clean" is a non-decision. Pick one: brutally minimal, maximalist, editorial, retro-futuristic, technical, soft-Scandi, neo-brutalist. Execute with conviction.
Restraint compounds — Negative space, a single signature move, and disciplined tokens beat ten "nice touches."
Specific over generic — Specific copy, specific imagery, specific iconography. Generic everything is the AI tell.
Tokens are law — Every visual decision lives in CSS variables. Components consume tokens, never hex.
Composition is load-bearing — Layout choices (asymmetry, density, hierarchy) carry more weight than color or font picks.
Ship interesting, never ugly — Be bold, but never at the cost of legibility or polish.
The Lovable Aesthetic
A clear point of view in the first viewport — display typography, an unexpected layout move, or a signature gradient
Semantic tokens in oklch for color, with composite tokens for gradients/shadows/transitions
shadcn/ui as the foundation, extended via variants rather than overridden inline
Motion that earns its place: one or two signature transitions, not micro-interactions on every element
Generous spacing on marketing surfaces, tight precision on app surfaces
The First Question Before Coding
Before writing any component, answer three things in one sentence each:
Purpose — Who uses this and what problem does it solve?
Tone — Named direction with a reference (e.g. "editorial like Stripe Press", "technical like Linear", "playful like Arc").
Differentiator — The one move that makes this memorable.
If you can't answer all three, generate 2–3 distinct directions for the user to pick from before building. Never silently average.
Color System
The 3–5 Color Rule
Use exactly 3–5 colors total. This constraint is what makes designs read as intentional.
Off-whites, soft tinted neutrals (never pure white)
Text
Near-black in oklch(0.13–0.20 …), never pure black
Borders/Dividers
Very subtle neutrals, often with 10–20% opacity
Success states
Greens in the teal family
Error/destructive
Warm reds, never neon
Warning states
Amber/orange tones
Color Temperature Rules
DO use analogous palettes: blue→teal, purple→pink, orange→red.
DON'T mix opposing temperatures across primary surfaces: pink→green, orange→blue, red→cyan.
Avoid purple/violet as primary unless explicitly requested or the brand calls for it. It's the AI default tell.
Gradient Rules
Avoid gradients unless the direction calls for them — solid colors are cleaner.
If gradients are used:
- Subtle accents only (hero glow, button hover, decorative blur) — never on primary text or core UI. - 2–3 color stops maximum. - Analogous colors only. - Define as a composite token (--gradient-primary), never inline.
Design Tokens — oklch + shadcn convention
Lovable projects use oklch for color (wider gamut, perceptually uniform, easy to derive variants). Define tokens in src/styles.css:
// ✅ Use gap for flex/grid
<div className="flex items-center gap-4">…</div>
<div className="grid grid-cols-3 gap-6">…</div>
// ✅ Use padding for containers
<section className="px-4 py-24 md:px-6 lg:py-32">…</section>
// ❌ Avoid space-* (less flexible, weird with wrapping)
<div className="space-y-4">…</div>
// ❌ Don't mix gap and margin on the same element
<div className="flex gap-4 mb-4">…</div>
Routes live in src/routes/ (TanStack Start file-based). Don't create src/pages/ or app/.
For content sites with multiple sections (About, Services, Pricing, Contact), create separate route files — not hash anchors on the index page. Each route gets its own <title> and meta.
Backend logic uses Lovable Cloud (database, auth, storage, edge functions) — enabled via the platform.
Component Design Principles
Single responsibility — one component, one job.
Composition over configuration — build complex UIs from small parts.
Props for customization — never hardcode values that vary.
Sensible defaults — works out of the box.
Variants over inline overrides — extend cva variants instead of className="bg-[#hex]".
// Always use focus-visible (not focus) so mouse clicks don't show rings
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
// Focus within (form groups)
"focus-within:ring-2 focus-within:ring-ring"
// Skip link
<a href="#main" className="sr-only focus:not-sr-only focus:absolute focus:top-4 focus:left-4">
Skip to content
</a>
Screen Reader Support
// SR-only text
<span className="sr-only">Open menu</span>
// Aria labels
<button aria-label="Close dialog"><X /></button>
// Live regions
<div role="status" aria-live="polite">{statusMessage}</div>
Images
<img src="…" alt="Founder Jane Doe speaking at conference" /> // informative
<img src="…" alt="" role="presentation" /> // decorative
Color Contrast
Body text ≥ 4.5:1.
Large text ≥ 3:1.
Interactive elements ≥ 3:1 against adjacent colors.
Never rely on color alone to convey state — pair with icon or text.
Keyboard Navigation
// ✅ Naturally focusable
<button onClick={…}>Clickable</button>
// ❌ Div as button — invisible to keyboard
<div onClick={…}>Clickable</div>
// ✅ If a div must be interactive
<div role="button" tabIndex={0} onClick={…} onKeyDown={(e) => e.key === "Enter" && …}>
Role Storage (Lovable Cloud)
Never store roles or admin flags in localStorage/sessionStorage. Store roles in a dedicated userroles table behind RLS, with a SECURITY DEFINERhasrole() function. Client-side flags are trivially manipulated.
Performance
Images
Lovable projects use plain <img> (Vite, not Next.js). Optimize manually:
import hero from "@/assets/hero.jpg";
<img
src={hero}
alt="…"
width={1600}
height={900}
loading="lazy" // below the fold
decoding="async"
className="aspect-video w-full object-cover"
/>;
Use loading="eager" and fetchpriority="high" only on the hero image.
// ❌ Too many colors
className="bg-purple-500 text-pink-400 border-blue-300 shadow-green-200"
// ❌ Hex / direct color in components
className="bg-white text-black"
className="bg-[#FF6B35]"
// ❌ Purple/violet as primary (unless explicitly requested)
className="bg-violet-600"
// ❌ Clashing temperature gradient
className="bg-gradient-to-r from-pink-500 to-green-500"
// ✅ Semantic tokens
className="bg-background text-foreground"
className="bg-primary text-primary-foreground"
Typography Mistakes
// ❌ Inter as the only font, no display pair
// ❌ 4 fonts on one page
// ❌ text-xs for body
// ❌ Default browser line-height on body text
// ✅
className="font-sans text-base leading-relaxed"