
Refero Design
- 5.4k installs
- 178 repo stars
- Updated August 4, 2026
- referodesign/refero_skill
refero-design is a research-first UI skill using Refero styles, screens, flows, reference locks, and anti-AI-slop quality gates.
About
The refero-design skill gives agents taste and product evidence through mandatory research before any design implementation. Three Refero layers cover styles for visual direction, screens for concrete UI patterns, and flows for multi-step journey logic. Non-negotiables require research before design, styles-first for visual work, synthesis without averaging references into a safe middle, preserved token roles, imagery guidance, reference locks with preserve and reject lists, decision ledgers tracing every major choice, and post-build visual QA. Workflows route to direct build, visual exploration with three reference-locked options, audit, or asset generation when bitmap media is required. MCP tools include refero_search_styles, refero_get_style, refero_search_screens, refero_get_screen, refero_search_flows, and refero_get_flow when configured, with bundled craft references as fallback. Quality gates confirm styles usage, anti-averaging, token role preservation, traceable decisions, and anti-AI-slop checks before handoff. Prefer this skill over generic frontend design skills when UI, landing pages, dashboards, or redesigns need evidence-backed direction.
- Mandatory research before design using Refero styles, screens, and flows layers.
- Reference lock workflow preserves primary direction traits and rejects averaged defaults.
- Decision ledger maps every major design choice to a source and token role rule.
- Routes direct build, visual exploration, audit, and asset generation workflows by task risk.
- Quality gate blocks generic AI design defaults and untraceable visual decisions.
Refero Design by the numbers
- 5,385 all-time installs (skills.sh)
- +378 installs in the week ending Aug 5, 2026 (Skillselion tracking)
- Ranked #72 of 1,880 Design & UI/UX skills by installs in the Skillselion catalog
- Security screen: MEDIUM risk (skills.sh audit)
- Data as of Aug 5, 2026 (Skillselion catalog sync)
refero-design capabilities & compatibility
- Capabilities
- refero styles screens flows research routing · reference lock and decision ledger synthesis · anti averaging and token role preservation · visual exploration and audit workflow routing · post build visual qa and anti ai slop checks
- Works with
- figma
- Use cases
- ui design · web design · frontend
What refero-design says it does
Do not average references into a safe middle.
If a major choice has no source, do not ship it as a design decision.
npx skills add https://github.com/referodesign/refero_skill --skill refero-designAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 5.4k |
|---|---|
| repo stars | ★ 178 |
| Security audit | 2 / 3 scanners passed |
| Last updated | August 4, 2026 |
| Repository | referodesign/refero_skill ↗ |
How do I design product UI grounded in real references instead of generic model design defaults?
Research-first UI and product design with Refero styles, screens, flows, reference locks, decision ledgers, and anti-AI-slop quality gates.
Who is it for?
Developers and designers creating landing pages, dashboards, or redesigns with evidence-backed UI direction.
Skip if: Skip when you need engineering-only refactors with no visual or UX design scope.
When should I use this skill?
User requests UI design, landing pages, dashboards, redesigns, or anti-AI-slop visual polish.
What you get
Reference-locked design direction with decision ledger, synthesized tokens, and validated implementation.
- Research summary and reference lock
- Decision ledger table
- Implemented UI with visual QA pass
By the numbers
- Three Refero research layers
- Reference lock with preserve and reject lists
- Quality gate with twelve confirmation checks
Files
Refero Design
Refero gives agents taste and product evidence. Use it before design work instead of relying on generic model knowledge.
Refero has three research layers:
1. Styles - visual direction and taste. 2. Screens - concrete UI patterns and product-screen decisions. 3. Flows - multi-step journey logic.
Best results come from combining layers: visual direction from styles, concrete UI patterns from screens, and sequencing from flows when the task has multiple steps.
Non-Negotiables
- Research before design work. Every design must be grounded in references before
implementation. Do not rely on the model's generic design taste.
- Use styles first for visual work when Refero MCP tools are available. If tools are
unavailable, use bundled craft references and keep the same reference-lock workflow.
- Do not copy one reference. Study several strong references and synthesize a new
direction for the user's product.
- Do not average references into a safe middle. When references conflict, choose one
dominant direction and preserve its sharp traits. Secondary references may add narrow details only.
- Do not change token meanings. If a reference says a color, font, radius, shadow,
gradient, or component is for a specific role, use it only for that role or omit it.
- Respect imagery guidance. If a style depends on photography, illustration, product
shots, or graphics, preserve the media role. Use real/generated/stock assets when available; otherwise create an intentional placeholder with art direction. Do not fake complex imagery with weak CSS, text, or decorative boxes.
- Do not use generic frontend/product design skills as a parallel design authority
when this skill is available. Refero is the design methodology; generic design skills tend to pull work back toward generic AI design.
- Research output must be specific. Name the references, describe concrete choices,
and explain what will be adapted.
- No design from vibe memory. Every major visual, layout, content, or interaction
decision must trace to Refero research, the user's brief, or a craft reference.
- Synthesize before implementation. Turn research into a concept, token direction,
and concrete decision ledger before drawing or coding.
- A brief is not a build target. Before implementation, lock either a user-provided
visual source, an existing product/design-system target, a selected generated mockup, or an explicit reference-locked direction approved for direct build.
- Use image generation only when it changes the outcome. Image generation can be slow
and may not exist in every coding environment. Use it for visual exploration, mockups, imagery, illustrations, textures, and difficult assets; skip it for small fixes, obvious production edits, or code-native UI work.
- Validate after building visual work. Compare the rendered implementation against
the locked target/reference before handoff. Fix actionable design drift instead of treating research as sufficient.
MCP Setup
This skill is useful on its own as a research-first design methodology and craft reference. Research is mandatory. Use Refero MCP for live style, screen, and flow research when available; otherwise research with bundled craft references and any user-provided references.
Typical MCP setup:
claude mcp add --transport http refero https://api.refero.design/mcp --header "Authorization: Bearer <token>"For full tool details, read references/mcp-tools.md.
Discovery
Before researching, form a short design brief. Ask only for missing information that would materially change the result; otherwise make reasonable assumptions and proceed.
Clarify:
- what is being designed
- platform: web, iOS, or both
- audience and technical level
- primary user goal
- desired feeling or brand direction
- business/user objections to overcome
- constraints: existing brand, framework, deadline, accessibility, content
- whether the task needs visual direction, concrete UI patterns, journey logic, or a mix
- whether the task should go directly to code, produce visual options first, or create
generated assets during implementation
Brief format:
Designing [WHAT] for [WHO] on [PLATFORM].
Goal: [PRIMARY USER GOAL].
Tone: [DESIRED FEELING].
Main objection/risk: [OBJECTION].
Must remember: [HOOK OR DISTINCTIVE IDEA].
Constraints: [CONSTRAINTS].
Research needed: [styles/screens/flows].
Path: [direct build / visual exploration / audit / asset generation].Workflow Routing
Choose the lightest workflow that can produce a high-quality result.
- Direct build: use for small UI fixes, clear production edits, existing design-system
work, or tasks with a concrete source to match. Research and lock the direction, then code.
- Visual exploration: use when the user asks for variants, a new visual language, a
major redesign, a landing page, or another high-visibility surface with several plausible directions. Default to three reference-locked options and ask the user to choose; see references/visual-workflow.md.
- Audit: use captured screenshots, Refero screens, or flows as evidence before critique.
- Asset generation: use generated imagery only when the reference lock requires bitmap
media that code, icons, or existing assets cannot faithfully provide; see references/visual-workflow.md.
Tool Routing
Use Styles First For Visual Work
Use refero_search_styles when the user asks to design, redesign, improve, polish, or create anything with a visual component.
A style is a semantic design reference extracted from a real web marketing/product page. It is not a screenshot and not a component library. Search results give previews; full style references from refero_get_style provide design guidance such as visual thesis, tokens, typography, layout/composition, section rhythm, spacing, elevation, surfaces, components, imagery treatment, implementation notes, and do/don't rules.
Current limitation: Refero styles currently cover web marketing/product pages such as landing pages, pricing pages, product marketing sites, editorial brand sites, and SaaS websites. They do not currently cover in-app dashboards, auth screens, settings screens, or iOS app screens as style systems. Still use styles for product UI tasks to establish visual language, then use screens/flows for product logic.
Use styles for:
- look and feel
- brand direction
- landing pages and marketing pages
- typography, palette, layout, section structure, spacing, radius, elevation, surfaces
- component treatments and sometimes component/code examples
- imagery and product screenshot treatment
- design-system inspiration
- making a generic interface feel more tasteful
Use Screens For Concrete UI Patterns
Use refero_search_screens when you need:
- a specific screen type
- a specific component or UI pattern
- page layout and content hierarchy
- copy and CTA patterns
- form/state examples
- dashboards, settings, modals, tables, pricing, empty states, auth, or product-screen details
After finding strong screens:
- use
refero_get_screenfor full details - use
refero_get_similar_screensto expand from a strong example - use
refero_get_screen_imageonly when raw screenshot inspection is needed
Use Flows For Journeys
Use refero_search_flows when the task has a before/after sequence:
- onboarding
- signup
- checkout
- subscription management
- cancellation
- account deletion
- password reset
- profile/settings changes
- any multi-step process
After finding a strong flow, use refero_get_flow for step-by-step goals, actions, system responses, and completion states.
Use Visual Workflow For Images And QA
For image generation, visual options, generated assets, and visual QA, read references/visual-workflow.md when the task needs it.
Research Workflow
1. Research Visual Direction With Styles
For any visual design task, start here.
Recommended loop:
1. Search 3-5 different visual angles. 2. Include one broad aesthetic query. 3. Include one domain/category query. 4. Include one known-brand or strong-product query when relevant. 5. Retrieve 3-4 strong styles with refero_get_style; full styles are large, so split larger research into multiple batches. 6. Compare what each style contributes. 7. Choose one primary foundation and borrow 1-2 specific details from other styles. 8. Lock the primary reference's signature traits before implementation.
Good style queries:
- editorial monochrome SaaS landing page
- warm trustworthy healthcare product marketing
- premium fintech website with restrained typography
- playful creator tool landing page with vivid accents
- developer tool website with product screenshots
- luxury ecommerce editorial product page
- productivity SaaS with airy spacing
- data infrastructure website dark technical style
- Attio editorial SaaS typography
- Linear changelog dark developer tool
- shadcn monochrome design system
Extract from styles:
- north star / visual thesis
- typography personality and type scale
- color roles and accent discipline
- spacing density and rhythm
- layout system, section rhythm, and composition patterns
- card/button/surface treatments
- borders, shadows, radius
- elevation and depth rules
- component examples and implementation/code notes when present
- imagery, graphics, illustration, or product screenshot treatment
- media asset strategy: real asset, generated/stock asset, code-native primitive, product screenshot, or placeholder
- do/don't rules
- one memorable visual move to adapt
Synthesis rule:
- Primary style: overall mood, density, and structure.
- Secondary styles: specific borrowed details.
- User context: adapt everything to the product, audience, and task.
- Do not use the average/intersection of all references. If one reference is dark, one is
acid, and one is serif, the answer is not warm cream + muted orange + polite serif.
Never present the result as "copying X". Present it as a new direction inspired by several references.
Before implementation, create a reference lock:
Primary reference/direction: [one dominant source]
Preserve: [3-5 traits that must survive: canvas, type, accent, layout, density, media]
Borrow only: [1-2 specific secondary details]
Role rules: [source token/component meanings to preserve, e.g. CTA-only, code-only, decorative-only]
Media strategy: [real/generated/stock/code-native/placeholder, with aspect ratio and art direction]
Reject: [defaults/averages that would collapse the direction]
Token commitments: [background, type, accent, radius, border/shadow, imagery treatment, with roles]If implementation drifts from the lock, stop and correct it. Do not soften distinctive traits into safer colors, safer fonts, softer radius, or generic section layouts. Reference lock is not cloning; it preserves selected traits while adapting content, brand, and interaction details to the user's product.
When combining styles, assign each source a bounded job. For example: one source may own canvas/type, another may own code-window treatment, and another may own primary CTA. Never move a token outside its source role: CTA colors stay CTA-only, syntax colors stay inside code, decorative gradients stay decorative, and card/button rules keep their specified radius, shadow, and state behavior.
If the primary style is image-led, do not replace it with text-only layout. If you cannot produce the needed image or graphic, preserve the slot with stable dimensions, aspect ratio, caption/alt text, and a short art-direction note. Build simple diagrams, icons, code windows, or geometric primitives only when they match the source style.
For substantial visual exploration, generated mockups, bitmap assets, or post-build visual QA, follow references/visual-workflow.md.
2. Research Screens For Product Details
Use screens when you need to know what the interface should contain or how real products solve a specific UI problem.
Good screen queries:
- pricing page annual monthly toggle
- feature comparison table
- dashboard empty state
- billing settings cancellation modal
- onboarding progress indicator
- 2FA setup recovery codes
- data table filters
- destructive action confirmation
Search by facts on the screen:
- page type
- component
- state
- company/product
- on-screen text
Avoid using screens as the primary style source when the task is visual. Use styles first, then screens for structure and concrete details.
Extract from screens:
- layout structure
- information hierarchy
- component choices
- CTA patterns
- content/copy patterns
- states and edge cases
- trust or conversion tactics
- concrete details worth adapting
3. Research Flows For Journey Logic
Use flows when there are multiple steps or a user changes state over time.
Good flow queries:
- signup onboarding
- checkout with promo code
- subscription cancellation
- account deletion feedback
- password reset 2FA
- workspace billing upgrade
If flow search is sparse, broaden the query. If still sparse, use screens and reconstruct the journey.
Extract from flows:
- entry point and exit state
- step count
- decisions the user makes
- friction reducers
- required confirmations
- save/recovery states
- error handling
- retention or persuasion moments
- system response at each step
Research Depth
Match depth to task risk.
For a quick visual improvement:
- 2-3 style searches
- 2-3 full styles
- 1 short synthesis
For a new landing page, brand direction, or major redesign:
- 3-5 style searches
- 3-4 full styles in one batch; use additional batches only when needed
- screen research for concrete sections/components
- clear visual direction before implementation
For a product workflow:
- styles for visual language
- screens for key states/components
- flows for sequencing
For high-stakes or ambiguous tasks:
- search from several angles
- inspect later pages
- compare strong and unusual references
- document tradeoffs before designing
Synthesis
Separate findings into three buckets.
Visual Direction
From styles:
- mood
- typography
- palette
- density
- surfaces
- imagery
- distinctive details
- do/don't rules
Output example:
Use a precise analytics SaaS foundation: white canvas, compact UI copy, restrained black
primary actions, thin borders, and product screenshots in framed panels. Borrow disciplined
accent use from another reference, but keep color rare.Product Pattern
From screens:
- what the interface needs to contain
- common layouts
- component patterns
- states
- copy and CTAs
- specific tactics
Output example:
Pricing pages commonly put the billing toggle above plan cards, highlight one plan, and
move detailed feature comparison below. We should adapt the comparison structure but keep
the hero quieter because this product sells trust, not hype.Journey Logic
From flows:
- steps
- decision points
- system responses
- user confidence and friction
- success/failure states
Output example:
Cancellation flows usually collect a reason, offer a relevant alternative, confirm the
destructive action, then state when access ends. The best flows give a clear return path.Present Findings
Do not dump every result. Give the user a short research summary before designing when the task is non-trivial.
Suggested format:
Research summary:
- Styles reviewed: [count] across [directions]
- Screens reviewed: [count], if used
- Flows reviewed: [count], if used
Visual direction:
- [primary style foundation]
- [reference lock / signature traits to preserve]
- [borrowed detail 1]
- [borrowed detail 2]
Product patterns:
- [concrete UI decisions from screens]
Journey logic:
- [flow decisions, if applicable]
Recommendation:
- [what to design and why]Before implementation, convert research into a short decision ledger:
| Decision | Source | Source rule / role | Why |
|---|---|---|---|
| [palette/type/layout/media/content choice] | [style/screen/flow/user constraint/craft rule] | [token/component/media role to preserve] | [specific rationale] |
If a major choice has no source, do not ship it as a design decision. Either research more, tie it to the user's constraints, or remove it.
Design Craft
After research, execute like a senior product designer. Use the bundled references only when relevant; do not load every file by default.
- Typography: references/typography.md
- Color: references/color.md
- Motion: references/motion.md
- Icons: references/icons.md
- Forms, focus, images, touch, performance, accessibility: references/craft-details.md
- Copywriting and persuasion: references/copywriting.md
- Anti-AI-slop checks: references/anti-ai-slop.md
Core craft rules:
- Define tokens before implementation: type scale, colors, spacing, radius, shadows.
- Preserve the primary reference's strongest traits instead of normalizing them.
- Preserve token roles from references. Do not turn a CTA accent into a background, a
code-only color into UI chrome, or a decorative gradient into an interface surface.
- Preserve imagery roles from references. Use capable assets when available; otherwise
prefer an honest, well-sized placeholder over a poor fake illustration or photo.
- Use brand-appropriate colors from research. Do not default to indigo/violet unless the
user explicitly asks for it.
- Treat "calm editorial" as a current AI-slop risk. Do not default to decorative headline
word swaps: one word or short phrase set in a different display/serif/script/italic style or accent color, warm ivory/cream canvases, or olive/clay/terracotta palettes unless research and product context justify them.
- Avoid generic hero -> features grid -> pricing -> FAQ -> CTA unless research supports it.
- Use real product evidence for copy, trust signals, objection handling, and section order.
- Create at least one memorable detail: a visual move, interaction, layout choice, or copy
detail users would remember.
- Balance headings and short display text with
text-wrap: balance; usetext-wrap: pretty
selectively for prose. Check key breakpoints for orphan words and awkward final lines.
- Keep accessibility and responsive behavior in the design, not as a late pass.
Quality Gate
Before final delivery, confirm:
- Did I use styles for visual taste?
- Did I avoid copying one style directly?
- Did I synthesize multiple references into a unique direction?
- Did I avoid averaging references into a safe centroid?
- Did I preserve the primary reference's signature traits?
- Did I preserve source token/component roles instead of repurposing them?
- Did I preserve required imagery/media roles with real assets, appropriate primitives, or intentional placeholders?
- Did I use screens when concrete UI patterns were needed?
- Did I use flows when the task had multiple steps?
- Can I name which references influenced the design and why?
- Can every major design choice be traced to a reference, user constraint, or craft rule?
- Did I produce a concept and decision ledger before implementation?
- Does the implementation avoid generic AI design defaults?
- Did I avoid decorative serif/italic/color word swaps unless reference and content role justify them?
- Does the result fit the user's product, audience, and constraints?
If the answer is no, research or refine more before delivering.
For substantial visual work, run the visual QA pass in references/visual-workflow.md before handoff.
Example
For a complete walkthrough, see references/example-workflow.md.
.DS_Store
*.skill
MIT License
Copyright (c) 2026 Refero
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
!Refero Design Skill
Refero Skill
An agent skill that makes design research mandatory before implementation: styles-first visual research, real-screen pattern research, flow reasoning, reference locks, optional visual exploration, post-build QA, and craft guidance. When Refero MCP is available, it can use curated visual styles, 150,000+ real app screens, and 6,000+ user flows from Stripe, Linear, Notion, Figma, and the best-designed products ever built.
Install
Works with Claude Code, Cursor, Gemini CLI, Lovable, and any MCP-compatible agent.
npx skills add https://github.com/referodesign/refero_skill --skill refero-designCraft knowledge loads immediately. No account required.
<details> <summary>Manual installation</summary>
git clone https://github.com/referodesign/refero_skill.git ~/.claude/skills/refero-designOn Claude.ai, add the contents of SKILL.md to your project knowledge.
</details>
---
What it does
1. Researches styles, screens, and flows — starts with visual styles for taste and direction, then uses real screens and user flows for product patterns and journey logic when live Refero MCP tools are available. 2. Extracts patterns — identifies specific design decisions and builds a reference list before touching code. 3. Routes the workflow — goes directly to code for clear edits, or creates three reference-locked directions when exploration is valuable. 4. Applies craft knowledge — uses built-in guides on typography, color, spacing, motion, icons, and copywriting. Flags anti-slop patterns before they appear. 5. Designs and validates with evidence — every decision traces back to a real product or a craft rule, and substantial visual work gets checked against the locked target before handoff.
<details> <summary>Files</summary>
SKILL.md — Research-first methodology: styles-first visual research, screen/flow routing, optional visual exploration, synthesis, craft guidance, quality gates.
Reference guides: typography.md, color.md, motion.md, icons.md, craft-details.md, anti-ai-slop.md, copywriting.md, visual-workflow.md, mcp-tools.md, example-workflow.md
</details>
---
Connect live design research
Set up Refero MCP from refero.design/mcp, then connect your tool:
<details> <summary>Claude Code</summary>
claude mcp add --transport http refero https://api.refero.design/mcp --header "Authorization: Bearer <token>"</details>
<details> <summary>Cursor</summary>
Add to .cursor/mcp.json:
{
"mcpServers": {
"refero": {
"url": "https://api.refero.design/mcp",
"headers": { "Authorization": "Bearer <token>" }
}
}
}</details>
<details> <summary>Gemini CLI</summary>
gemini mcp add --transport http refero https://api.refero.design/mcp --header "Authorization: Bearer <token>"</details>
<details> <summary>Lovable</summary>
Settings → Connectors → New MCP server → https://api.refero.design/mcp → Bearer token
</details>
<details> <summary>Other tools</summary>
URL: https://api.refero.design/mcp
Auth: Bearer <token></details>
The first time you call Refero, a browser window opens to sign in. After that it's automatic.
Contributing
To improve this skill, keep SKILL.md focused on the core workflow and put detailed, conditional guidance in references/.
License
MIT
Anti-AI-Slop Guide
Your design must NOT look AI-generated. AI interfaces converge on the same tired patterns because they optimize for "safe" and "average." Real designers make intentional, contextual choices.
---
🚨 THE #1 TELL: INDIGO/VIOLET
Every AI model defaults to indigo/violet (#6366f1, #8b5cf6, #7c3aed). It's the universal fingerprint of AI-generated design.
Why it happens: training data saturated with Tailwind's indigo. LLMs optimize for the average, and indigo IS the average.
RULE: NEVER use indigo/violet unless the brand explicitly requires it.
| Instead of | Try | Feeling |
|---|---|---|
Indigo #6366f1 | Blue #2563eb | Trust, professional |
Violet #8b5cf6 | Teal #0d9488 | Fresh, distinctive |
Purple #7c3aed | Brand color | Authentic, intentional |
---
🚨 THE #2 TELL: CARDS EVERYWHERE
Cards are the second most common AI-slop pattern. AI models wrap everything in rounded-corner boxes with shadows because it feels "safe." Real designers use cards sparingly.
RULE: Default is NO cards. Use sections, columns, dividers, or media blocks instead.
Cards are only justified when they are the container for a user interaction (clickable item, form, expandable panel). If removing the border, shadow, background, or radius doesn't hurt interaction or understanding — it's not a card, remove it.
Ask: "Is this a card because the user needs to interact with this container, or because I couldn't think of another way to group things?" If the latter — remove the card.
---
🚨 THE #3 TELL: DARK MODE BY DEFAULT
AI models default to dark backgrounds. Dark-by-default is an AI fingerprint just like indigo.
RULE: Unless the brief explicitly asks for dark — use light mode.
Dark mode is a deliberate brand choice, not a default. When a brief says nothing about color mode, light mode is the professional baseline.
---
🚨 THE #4 TELL: CALM EDITORIAL SERIF ON AUTOPILOT
Newer models often avoid obvious indigo SaaS slop by switching to another safe template: warm ivory/cream background, oversized high-contrast serif headline, one italic serif word, muted olive/clay/terracotta accents, very airy spacing, and "calm editorial" positioning regardless of the product.
This can be excellent for an editorial brand, cultural product, hospitality site, or fashion/lifestyle page. It becomes AI slop when applied by default to browsers, dev tools, enterprise SaaS, fintech, dashboards, or functional product UI without research.
RULE: Do not use the calm editorial serif + earth-tone pattern unless the product context and Refero research justify it.
Before using it, you must be able to explain: 1. Why this product needs an editorial or literary voice. 2. Why a serif display font communicates the brand better than a sans/system face. 3. Why warm ivory, olive, clay, terracotta, or other earth tones fit the audience. 4. Which references support this exact direction.
If you cannot answer those, choose a sharper product-specific direction: technical, utilitarian, high-contrast, image-led, data-dense, playful, industrial, clinical, luxury, or another style grounded in research.
Specific fingerprint to avoid: a headline where one word or short phrase is swapped into a different display/serif/script face, italicized, and/or color-shifted only to create "taste." The base headline can be serif or sans; the slop is the decorative one-word treatment. This is now a common AI default. Use contrasting word treatment only when a strong reference uses it and the content role justifies it: quotation, editorial voice, title treatment, or a real brand/type-system rule. Otherwise create distinction through layout, scale, weight, media, interaction, or a source-backed color role.
Serif fonts and earthy palettes are not banned. Autopilot "calm editorial" is.
---
🚨 THE #5 TELL: EMOJI AS ICONS
Standard emoji (😀🚀💡🎯) immediately signal "AI-generated." They're a shortcut that makes any design look cheap and unfinished.
RULE: Never use emoji unless the user explicitly asks for them.
Use instead: icon libraries (Lucide, Phosphor, Heroicons), Unicode symbols (→ • ◆), SVG graphics. Even a simple text character beats a yellow smiley in a professional UI.
---
🚨 THE #6 TELL: LEFT ACCENT STRIPE
The colored vertical bar on the left edge of a card (border-left: 4px solid <accent>). AI models add it for "visual interest" — but in shipped products this stripe is reserved for elements that carry meaning: callouts, alerts, active list items, status, priority.
RULE: Only use a side accent stripe when it communicates something — status, priority, owner, or selection. Never as decoration.
If you can't say in one word what the color means, remove the stripe.
---
🚨 THE #7 TELL: REFERENCE AVERAGING
AI models often do real research, then destroy it by averaging strong references into the safest middle point. This is how a dark workbench, acid-yellow document site, saturated orange product brand, and serif editorial page become the same warm cream canvas with muted clay accents.
RULE: Synthesis means choosing and adapting, not finding the least risky intersection.
Red flags:
- Dark canvases become cream.
- Acid or saturated accents become muted clay/olive.
- Geometric sans systems become polite serif headlines.
- Sharp/zero-radius UI becomes soft rounded cards.
- Distinctive media or layout becomes generic hero + sections.
When references conflict, choose one primary direction and preserve its signature traits. Secondary references may contribute 1-2 specific details, but they must not dilute the primary direction. A bold reference should either stay bold or be rejected; it should not be softened into average AI taste.
---
🚨 THE #8 TELL: TOKEN ROLE DRIFT
Another failure mode: the agent uses real style tokens but changes what they mean. A source says "acid yellow only for primary CTA," then the design uses it as a section background. A source says "syntax colors only inside code snippets," then those colors become UI accents. A source says "pastels are decorative atmosphere," then they become cards and controls.
RULE: A token's role is part of the token. Preserve it or do not use it.
Red flags:
- CTA-only accents used as backgrounds, borders, badges, or decorative fills.
- Code syntax colors used outside code windows.
- Decorative gradients/pastels turned into core UI surfaces.
- Source button radius or shadow recipes changed to feel safer.
- Component treatments mixed without preserving their source states.
When combining references, assign each source a bounded job and respect its rules. One source can own canvas/type, another can own code-window treatment, another can own primary CTA. The result becomes unique through composition, not by changing the meaning of tokens.
---
🚨 THE #9 TELL: FAKE GRAPHICS OR TEXT-ONLY COLLAPSE
Many strong references are image-led: photography, product screenshots, custom illustration, editorial graphics, diagrams, textures, or atmospheric media. Agents often collapse these into text, layout, and CSS decorations because they cannot generate the image. The result loses the style's main carrier.
RULE: Preserve the media role. Use a real asset, generated/stock asset, code-native primitive, product screenshot, or intentional placeholder. Do not fake complex imagery.
Good substitutes:
- Real product screenshot, provided asset, stock photo, or generated image when available.
- Code-native primitive only for simple diagrams, icons, charts, code windows, grids, or
geometric patterns that match the reference.
- Intentional placeholder when the needed asset is unavailable: fixed aspect ratio, clear
art direction, alt/caption, and enough visual space to keep the composition honest.
Red flags:
- Replacing an image-led hero with only text and buttons.
- Drawing fake photos, fake editorial art, or complex illustrations with weak CSS blobs.
- Using generic gradients or abstract shapes where the reference relies on specific media.
- Collapsing product screenshots into decorative cards with no real content.
Placeholder is acceptable when it prevents bad fake imagery. It is not acceptable when a real screenshot, simple code-native graphic, stock/generative asset, or provided asset is available and appropriate.
---
What Makes Design Look Generic
Typography symptoms:
- Same font as every other AI site, same weight throughout
- No distinction between display and body text
- One-word/short-phrase serif, italic, or color highlight used only to feel "tasteful"
- Missing letter-spacing on ALL CAPS and small text
Color symptoms:
- Default indigo/violet, gradients that don't serve function
- Warm ivory + olive/clay/terracotta chosen because it feels safe, not because it fits
- Distinctive reference colors muted into the same safe earth-tone palette
- Source colors used outside their stated role
- Perfectly even color distribution, no clear accent hierarchy
Layout symptoms:
- Perfectly symmetrical everything, cookie-cutter card grids
- Hero with left text + right image (every landing page ever)
- Calm editorial landing layout applied to products that need utility, speed, or proof
- Signature reference layouts collapsed into generic section stacks
- Centered everything with no visual tension
Visual symptoms:
- Abstract blob backgrounds, generic 3D illustrations
- Weak CSS fakes for photography, editorial art, or product imagery
- Image-led references collapsed into text-only layouts
- Effects without purpose, stock imagery that could be anywhere
---
The Antidote: Intentional Design
Typography with purpose:
- Choose fonts that match your tone from research
- Create clear hierarchy (3-4 distinct levels)
- Use weight and spacing to differentiate, not just size
Color with meaning:
- Build palette from references, not defaults
- Use dominant + sharp accent, not evenly distributed
- Make semantic colors actually semantic
Layout with intention:
- Create visual tension through asymmetry
- Use whitespace as a design element
- Break the grid intentionally (one element, not everything)
Details that distinguish:
- Custom illustrations or real photography
- Micro-interactions that reinforce brand
- Shadows and depth when they serve hierarchy
- One memorable detail users will actually remember
---
The AI Slop Detector Checklist
Before shipping any design:
□ Accent color is NOT indigo/violet
□ Cards are justified by interaction, not used as default containers
□ No decorative left/side accent stripes
□ No standard emoji used as icons
□ Color mode is light unless brief explicitly asks for dark
□ Serif display / warm editorial treatment is justified by product context
□ Earth-tone palette is research-backed, not a safe default
□ No decorative one-word serif/italic/color highlight unless research and content role justify it
□ Strong reference traits were preserved, not averaged away
□ Source token/component roles were preserved
□ Image/media roles are preserved with a real asset, appropriate primitive, or intentional placeholder
□ ALL CAPS text has letter-spacing
□ Would pass the "screenshot test" next to real products
□ Font choices are intentional and contextual
□ Colors derived from research, not defaults
□ Layout has visual interest and tension
□ No generic patterns you can't justify
□ You can explain WHY each design choice was made---
Litmus Tests
Run these against your design before shipping:
Card test: If removing border + shadow + background + radius doesn't hurt interaction or understanding → it's not a card, remove it.
Image test: If the first viewport works fine without the hero image → the image is too weak. Make it dominant or remove it.
Brand test: If the brand disappears after hiding the nav → hierarchy is too weak. Make brand louder — bigger logo, brand color in hero, distinctive typography.
Copy test: If deleting 30% of copy improves the page → keep deleting. AI over-writes; real designers edit down.
Identity test: If the first viewport could belong to any other company → branding is too weak. Add the one detail that makes this unmistakably THIS brand.
Editorial test: If replacing the logo with a coffee shop, boutique hotel, or literary magazine still makes the hero feel plausible → the design is probably generic calm editorial slop. Make the visual language specific to the actual product.
---
Safe vs. Intentional
Safe (forgettable):
- 3-column pricing because "everyone does it"
- Hero with left text + right image because "it works"
- Card grid with equal spacing because "it's clean"
- Cream background + serif headline + olive accent because it feels tasteful
Intentional (memorable):
- 2-column pricing because your product only has 2 tiers
- Full-width hero image with overlay because it fits the brand
- Asymmetrical layout because you want visual tension
- Serif editorial system because the product is actually publishing, culture, fashion, hospitality, or another content-led brand
"I chose this because [specific reason for THIS project]" beats "I chose this because everyone does it."
Color Guide
Color is the emotional backbone of UI. Get it wrong and your product looks either amateur or AI-generated. Get it right and everything feels intentional.
---
0. Context First
Before touching palettes, answer these questions:
| Question | Why It Matters |
|---|---|
| Product UI or marketing? | Product: fewer colors, more neutrals, strict semantics. Marketing: more emotion, gradients, contrast allowed. |
| Data density? | Dashboards need muted accents, high text contrast, no "glowing" colors. Content-focused UI can be softer. |
| Is brand defined? | No brand: use safe preset, refine later. Existing brand: translate brand color into system tokens, don't paint everything with it. |
Hard rule:
When in doubt — fewer colors, more neutrals, stricter purpose. Restraint beats "colorful."
This single rule eliminates 50% of AI-slop before you start.
---
1. Color Space
Why most palettes "break" when you try to extend them.
The Problem with HSL
HSL is intuitive but poorly represents perceptual brightness. A "50% lightness" yellow looks much brighter than "50% lightness" blue. This makes consistent scales nearly impossible.
The Solution: OKLCH
OKLCH (or LCH) provides perceptually uniform lightness. Steps from 50→950 actually look even.
Practical workflow:
- Generate and adjust palettes in OKLCH
- Store production values as hex
- Keep OKLCH logic as source of truth
/* OKLCH example */
--primary-500: oklch(0.55 0.2 250); /* Base */
--primary-600: oklch(0.48 0.2 250); /* Hover */
--primary-700: oklch(0.41 0.2 250); /* Active */For MVP: You can skip OKLCH. Use curated palettes (Tailwind, Radix, Open Color). But know why they work.
---
2. Palette Structure
You need 4 layers, not "30 beautiful colors."
2.1 Neutrals (Most Important)
Neutrals are 70–90% of your UI. This is where you win or lose.
Requirements:
- 10-12 steps: 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950
- Slight character (warm or cool), not colorful circus
- Consistent across light and dark themes
Scale reference:
| Step | Use | Example |
|---|---|---|
| 50 | Near-white backgrounds | #fafafa |
| 100-200 | Surfaces, cards | #f5f5f5, #e5e5e5 |
| 300-400 | Borders, dividers | #d4d4d4, #a3a3a3 |
| 500 | Placeholder text | #737373 |
| 600-700 | Secondary text | #525252, #404040 |
| 800-900 | Primary text | #262626, #171717 |
| 950 | Near-black | #0a0a0a |
Hard rules:
- Never use pure
#000on white as body text - Don't make text gray "for breathing room" — spacing creates breathing room, not faded text
2.2 Primary Accent
One brand color. It should:
- Have good contrast on both white and dark backgrounds
- Have a full scale (50–950), not just one hex
- Be used sparingly and purposefully
Typical usage:
| Step | Use |
|---|---|
| 50-100 | Tinted backgrounds |
| 500-600 | Default state |
| 600-700 | Hover state |
| 700-800 | Active/pressed state |
2.3 Semantic Colors
Usually 3-4:
- Success — Green (confirmations, completion)
- Warning — Amber/Yellow (attention needed)
- Danger — Red (errors, destructive actions)
- Info — Blue (neutral information) — optional
Important: Semantics work through pairs, not single colors.
/* Each semantic needs: */
--success: #16a34a; /* Icon, text accent */
--success-bg: #f0fdf4; /* Background */
--success-border: #86efac; /* Border */
--on-success: #ffffff; /* Text on solid success */2.4 Effects (Only If Needed)
- Gradients
- Glows
- Illustration tints
Rule: In product UI, effects should be rare and localized. Save drama for marketing.
---
3. The 60/30/10 Rule
Distribution that works for any interface:
| Percentage | Elements |
|---|---|
| 60-80% | Neutrals (backgrounds, surfaces, borders) |
| 10-20% | Text hierarchy (different gray levels) |
| 5-10% | Accents and semantics |
Component Color Limit
Maximum 2 colors per component.
If a button has brand gradient + colored border + colored shadow + colored text, it's almost always garbage.
State Changes: Structure, Not Circus
Hover and Active should be:
- Slightly darker/lighter
- Slightly more contrast
- Subtle shadow enhancement
Don't repaint every state with a new random color.
/* Good */
.button {
background: var(--primary);
}
.button:hover {
background: var(--primary-hover); /* Just darker */
}
/* Bad */
.button:hover {
background: linear-gradient(135deg, #ff6b6b, #feca57);
box-shadow: 0 0 20px #ff6b6b;
}---
4. Contrast and Readability
Not about checking boxes — about actual readability.
Minimum Requirements
| Text Type | WCAG AA Ratio |
|---|---|
| Body text (≤16px) | 4.5:1 |
| Large text (18px+ bold, 24px+ regular) | 3:1 |
| UI components, icons | 3:1 |
Common Failures
1. Secondary text too pale — The #1 issue. If it looks fine on your Retina display at noon, it fails on cheap monitors at 9pm.
2. Text on tinted backgrounds — "Almost readable" text on colored backgrounds fails in real conditions (tired eyes, ambient light, older monitors).
Practical Check
- Test secondary text on multiple devices
- If you squint and text disappears, it's too light
- Ask: "Would my parents read this easily?"
---
5. Light and Dark Themes
The Wrong Way
Inverting colors mechanically: white → black, black → white.
Result: eye-burning contrast, amateur look.
The Right Way
Dark theme gets its own neutral scale.
/* Light */
:root {
--bg: #ffffff;
--surface: #f7f7f7;
--text: #0b0b0b;
--text-muted: #5f6368;
}
/* Dark — NOT just inverted */
[data-theme="dark"] {
--bg: #0f0f0f; /* Not #000 */
--surface: #1a1a1a;
--text: #f0f0f0; /* Not #fff */
--text-muted: #a1a1a1;
}Dark Theme Elevation
In dark UI, surfaces and layers communicate through:
- Slightly lighter backgrounds for elevated elements
- Subtle borders (1px, low contrast)
- Very soft shadows or no shadows at all
[data-theme="dark"] {
--surface-elevated: #242424; /* Lighter than base */
--border: rgba(255, 255, 255, 0.1);
}Dark Mode: Technical Implementation
Browser-level settings that most developers miss:
<!-- In <head> — tells browser UI elements to use dark mode -->
<meta name="color-scheme" content="light dark">
<!-- Theme color for browser chrome, PWA, mobile address bar -->
<meta name="theme-color" content="#0f0f0f" media="(prefers-color-scheme: dark)">
<meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)">/* On <html> — fixes scrollbars, form controls, system dialogs */
:root {
color-scheme: light;
}
[data-theme="dark"] {
color-scheme: dark;
}Why this matters:
- Without
color-scheme: dark, scrollbars stay light gray on dark backgrounds - Form inputs (
<input>,<select>,<textarea>) get wrong default colors - System dialogs and autofill appear broken
Native `<select>` fix for dark mode (Windows issue):
[data-theme="dark"] select {
background-color: var(--surface-2);
color: var(--text);
}---
6. Naming Tokens
Never name tokens by color. Name by purpose.
Bad
--blue: #2563eb;
--light-blue: #eff6ff;
--dark-blue: #1e40af;Good
--primary: #2563eb;
--primary-tint: #eff6ff;
--primary-active: #1e40af;Minimum Token Set
:root {
/* Surfaces */
--bg: #ffffff;
--surface-1: #ffffff;
--surface-2: #f7f7f7;
/* Text */
--text: #0b0b0b;
--text-muted: #5f6368;
--text-subtle: #7a7f85;
/* Borders */
--border: #e6e6e6;
--border-strong: #d1d1d1;
/* Primary */
--primary: #2563eb;
--on-primary: #ffffff;
--primary-hover: #1d4ed8;
--primary-active: #1e40af;
--primary-tint: #eff6ff;
/* Semantic */
--success: #16a34a;
--warning: #f59e0b;
--danger: #ef4444;
}Key: Components should work from tokens, not hardcoded hex values.
---
7. Building a Palette from Scratch
When there's no brand yet:
Step 1: Choose Neutral Character
Decide warm or cool. This affects the entire feel.
/* Cool (tech, precision) */
--neutral-100: #f4f4f5;
/* Warm (friendly, premium) */
--neutral-100: #f5f4f2;Step 2: Choose One Primary
Requirements:
- Works on white background
- Works on dark background
- Works in buttons, links, badges
- "Strong" but not fluorescent
Test: Put your primary in a button, a text link, a badge. All three should feel right.
Step 3: Generate Scale
Use OKLCH or curated palette generators:
Step 4: Add Semantics
Choose semantic colors that don't clash with primary.
| Primary | Avoid for Success |
|---|---|
| Blue | Blue (use green) |
| Green | Yellow-green (use teal) |
| Red | Red-orange (use green) |
---
8. Gradients
Gradients are allowed when:
- They support brand identity
- They don't break readability
- They're localized (hero, illustration, small highlight)
Rules
1. Gradient is never the only way to make something visible — If removing the gradient makes the element invisible, redesign.
2. Subtle > dramatic — Direction and angle matter more than color variety.
3. Text on gradients — Ensure contrast works across the entire gradient, not just the start.
/* Acceptable */
.hero-badge {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
/* Problematic */
.card {
background: linear-gradient(90deg,
#ff6b6b, #feca57, #48dbfb, #ff9ff3);
}---
9. Anti-Patterns
Structural problems that reveal unintentional design:
🚨 THE #1 AI SLOP INDICATOR: INDIGO/VIOLET
This deserves its own section because it's THAT important.
Every LLM, every AI code generator, every design tool defaults to indigo/violet (#6366f1, #8b5cf6, or similar). This has become the universal fingerprint of AI-generated design.
Before using any purple-family color, ask: 1. Does the brand explicitly require purple? 2. Did research references use purple (and why)? 3. Is there a semantic reason (not just "looks modern")? 4. Would a senior designer question this choice?
If you can't answer YES to at least one of these—choose a different color.
Safe alternatives when you need an accent:
- Blue (
#2563eb) — trust, stability, professional - Teal (
#0d9488) — fresh, modern, distinctive - Green (
#16a34a) — growth, success, natural - Orange (
#ea580c) — energy, action, warmth - Brand-specific color from research
The rule: Indigo is BANNED unless explicitly justified by brand requirements.
Other Red Flags
- Multiple competing accents — One primary. Others should be clearly secondary or semantic
- Random hex in components — Should use tokens
- Pure black on white — Use near-black (#0b0b0b)
- Every state is a new color — Hover/active should be predictable shifts
- Dark theme = inverted — Needs separate neutrals
Quick Test
1. Is your primary color indigo/violet? (If yes, justify it or change it) 2. Can you justify your primary color choice with research? 3. How many accent colors? (Should be 1-2) 4. Are all colors from tokens, not random hex?
→ Full anti-AI-slop guide: anti-ai-slop.md
---
10. Pre-Ship Checklist
- [ ] One primary accent, not 3 "hero colors"
- [ ] Neutrals are 70-90% of the interface
- [ ] Text readable everywhere, secondary text not pale
- [ ] Hover/Active states predictable and calm
- [ ] Tokens named by purpose (bg, text, border, primary)
- [ ] Dark theme is separate, not inverted
- [ ] Semantics don't clash with primary
- [ ] No random hex in components — all from tokens
- [ ] Contrast passes WCAG AA (4.5:1 body, 3:1 large)
- [ ] Gradients are rare and localized
- [ ] `color-scheme` set on
<html>for dark mode (fixes scrollbars, inputs) - [ ] `<meta name="theme-color">` matches page background
---
Appendix: Complete Token System
Reference implementation with all tokens:
:root {
/* Neutrals (cool variant) */
--neutral-50: #fafafa;
--neutral-100: #f5f5f5;
--neutral-200: #e5e5e5;
--neutral-300: #d4d4d4;
--neutral-400: #a3a3a3;
--neutral-500: #737373;
--neutral-600: #525252;
--neutral-700: #404040;
--neutral-800: #262626;
--neutral-900: #171717;
--neutral-950: #0a0a0a;
/* Surfaces */
--bg: var(--neutral-50);
--surface-1: #ffffff;
--surface-2: var(--neutral-100);
--surface-3: var(--neutral-200);
/* Text */
--text: var(--neutral-900);
--text-muted: var(--neutral-600);
--text-subtle: var(--neutral-500);
--text-disabled: var(--neutral-400);
/* Borders */
--border: var(--neutral-200);
--border-strong: var(--neutral-300);
/* Primary (blue) */
--primary-50: #eff6ff;
--primary-100: #dbeafe;
--primary-200: #bfdbfe;
--primary-500: #3b82f6;
--primary-600: #2563eb;
--primary-700: #1d4ed8;
--primary-800: #1e40af;
--primary-900: #1e3a8a;
--primary: var(--primary-600);
--primary-hover: var(--primary-700);
--primary-active: var(--primary-800);
--primary-tint: var(--primary-50);
--on-primary: #ffffff;
/* Semantic */
--success: #16a34a;
--success-bg: #f0fdf4;
--warning: #f59e0b;
--warning-bg: #fffbeb;
--danger: #ef4444;
--danger-bg: #fef2f2;
--info: #0ea5e9;
--info-bg: #f0f9ff;
}
/* Dark theme */
[data-theme="dark"] {
--bg: #0f0f0f;
--surface-1: #171717;
--surface-2: #1f1f1f;
--surface-3: #262626;
--text: #f5f5f5;
--text-muted: #a3a3a3;
--text-subtle: #737373;
--border: rgba(255, 255, 255, 0.1);
--border-strong: rgba(255, 255, 255, 0.15);
--primary: #60a5fa;
--primary-hover: #3b82f6;
--primary-active: #2563eb;
--primary-tint: rgba(59, 130, 246, 0.15);
--on-primary: #0f0f0f;
--success-bg: rgba(22, 163, 74, 0.15);
--warning-bg: rgba(245, 158, 11, 0.15);
--danger-bg: rgba(239, 68, 68, 0.15);
--info-bg: rgba(14, 165, 233, 0.15);
}---
Color is restraint. Neutrals are 90% of the work. One accent, used purposefully, beats five competing for attention.
Copywriting Guide
How to write copy people read, trust, remember, and act on.
---
Core Belief
People do not read copy. They make decisions.
Copy is not content. Copy is an interface between a person and a next step. If text does not help someone understand, choose, or act — it actively hurts the design.
---
The Order of Great Copy
Clarity > Respect > Character — always in this order.
- Clarity: without it, copy fails
- Respect: without it, copy irritates
- Character: without it, copy is forgotten
Most bad "brand voice" starts with character and skips clarity.
---
Living Words vs Dead Words
Dead copy is abstract, generic, safe, interchangeable. Signal: it could live on 1,000 websites unchanged.
| Dead | Living |
|---|---|
| "Innovative platform" | "Create a landing page in 20 minutes. No code." |
| "Next-generation solution" | "See where users drop off in checkout." |
| "Seamless experience" | "Export to PDF and Google Docs in one click." |
| "Powerful and flexible" | "Works with Gmail and Outlook. iCloud is next." |
Rule: If a word can be removed without changing meaning, it is probably dead.
---
Universal Copy Structure
Any good piece of copy answers:
1. Context — Where is the user right now? 2. Job to be done — What are they trying to accomplish? 3. Solution — What do you offer? 4. Outcome — What changes for them? 5. Conditions — Limits, tradeoffs, requirements 6. Next step — What should they do now?
If copy feels empty, one of these is missing.
---
Info-Style Thinking
1. Facts beat adjectives: "fast" → "in 10 seconds" 2. Verbs beat nouns: "configuration" → "set up" 3. Plain word order: say what happens first, details later 4. One sentence = one idea 5. Higher stakes = calmer tone (payments, deletion, security)
---
Microcopy
Buttons
Bad: OK, Submit, Confirm
Good — action + object:
- Create project
- Save changes
- Invite teammates
- Download PDF
- Start free trial
Errors
Good errors include: (1) what happened, (2) why if useful, (3) what to do next.
| Quality | Example |
|---|---|
| Bad | "Something went wrong" |
| Better | "Couldn't save. Check your connection and try again." |
| Best | "You're offline. Reconnect to save changes." |
Empty States
Not "No data." Teach and guide: "Projects will appear here. Create your first one to get started." One CTA, not five.
---
Marketing Hero Section
Must answer instantly:
- Who is this for?
- What problem does it solve?
- What outcome do I get?
- Why should I trust it?
- What do I do next?
Example:
Headline: "Turn meeting notes into decisions."
Subhead: "Record, transcribe, and summarize calls in real time on macOS."
Proof: "English and Spanish supported. 60-minute meetings."
CTA: "Try it free"
---
Write in Scenes, Not Claims
People remember images, not abstractions.
Bad: "A better workflow for teams."
Good: "At 10:03 the PM drops a task. At 10:07 the designer has real references and a draft."
Scene template: who + where + what happens + what changes.
---
Proof Beats Hype
Trust-killing words: revolutionary, seamless, cutting-edge, best-in-class, next-generation.
Replace with: numbers, scenarios, constraints, real outputs, real limits.
Honesty increases credibility. Credibility increases impact.
---
Rhythm
Flat rhythm kills attention. Use variation: short line, longer line, short punch.
"Fewer clicks. Clearer decisions. Less arguing in Slack."
Change sentence length every 1-2 lines. One paragraph = one punch.
---
The Sticky Line Test
Every important page needs at least one line that can be screenshotted, quoted, remembered.
Patterns:
- "Not another X. Finally Y."
- "Less noise. More decisions."
- "Stop guessing. Start seeing."
If nothing is quotable, nothing sticks.
---
Product UI Copy
On dashboards, settings, and admin panels — copy exists to orient, report status, and enable action. Not to inspire, persuade, or build brand.
Principle: Orientation + Status + Action. Not Promise + Mood + Brand Voice.
Headings: Descriptive, Not Aspirational
| Wrong | Right |
|---|---|
| "Unlock Your Growth Potential" | "Revenue This Month" |
| "Your Journey Starts Here" | "Onboarding Progress" |
| "Insights That Matter" | "Search Metrics" |
| "Your Team at a Glance" | "Team Activity" |
Litmus test: If an operator scans only headings, labels, and numbers, can they understand the page? If no — rewrite.
Avoid on Operational Surfaces
- Executive-summary banners with hero numbers
- "Supercharge your pipeline", "Elevate your workflow"
- Motivational subheadings ("Let's make today count")
- Brand voice where function is needed
When Marketing Tone IS Appropriate in Product
- Empty states (first-time user)
- Onboarding flows
- Upgrade prompts
- Success celebrations
Even here: one line of warmth, then back to function.
---
Pre-Publish Checklist
1. Can a stranger understand this in 3 seconds? 2. Is "why should I care?" answered clearly? 3. Is there at least one concrete detail? 4. Can I cut 30% without losing meaning? 5. Are expectations honest (limits included)? 6. Is the next step obvious? 7. Does it sound human, not corporate?
Two or more "no" = rewrite.
---
Banned Words
Hype
revolutionary, seamless, cutting-edge, best-in-class, next-generation, world-class, game-changing, disruptive, innovative (without proof), powerful (without specifics), robust, state-of-the-art, groundbreaking
Filler
very, really, just, actually, basically, literally, simply, easily, highly, incredibly, extremely, absolutely, truly, totally
Corporate Zombie
leverage, synergy, ecosystem, paradigm, holistic, end-to-end, mission-critical, value proposition, stakeholder, thought leader, empower, optimize (in marketing), streamline (without specifics), unlock (metaphorical), drive (as in "drive growth")
AI Slop Markers
"In today's fast-paced world...", "In an era of...", "Look no further", "Say goodbye to...", "Introducing the future of...", "Reimagine...", "Supercharge your...", "Elevate your...", "Take your X to the next level", "Harness the power of..."
Craft Details Guide
Implementation details that separate polished products from rough ones. Most AI models miss these.
---
1. Focus States
Focus states are for keyboard navigation. Get them wrong and your app feels broken.
The Rule: :focus-visible, Not :focus
/* ❌ Shows focus ring on mouse click — annoying */
.button:focus {
outline: 2px solid var(--primary);
}
/* ✅ Shows focus ring only on keyboard navigation */
.button:focus-visible {
outline: 2px solid var(--primary);
outline-offset: 2px;
}Why: :focus triggers on any focus (including mouse click). :focus-visible only triggers when user is navigating with keyboard.
Never Remove Focus Without Replacement
/* ❌ NEVER — breaks keyboard navigation */
.button:focus {
outline: none;
}
/* ✅ Replace default with custom visible focus */
.button:focus-visible {
outline: none;
box-shadow: 0 0 0 2px var(--bg), 0 0 0 4px var(--primary);
}Compound Controls: :focus-within
For groups where focus on any child should highlight the parent:
/* Search input with icon */
.search-wrapper:focus-within {
border-color: var(--primary);
box-shadow: 0 0 0 3px var(--primary-tint);
}---
2. Forms
Forms are where users struggle most. These details reduce friction.
Input Types and Attributes
<!-- ✅ Correct types trigger right keyboard on mobile -->
<input type="email" inputmode="email" autocomplete="email">
<input type="tel" inputmode="tel" autocomplete="tel">
<input type="url" inputmode="url">
<input type="number" inputmode="numeric">
<!-- ✅ Meaningful names help password managers -->
<input name="email" type="email" autocomplete="email">
<input name="password" type="password" autocomplete="current-password">
<input name="new-password" type="password" autocomplete="new-password">Autocomplete Matters
| Field | autocomplete value |
|---|---|
email | |
| Password (login) | current-password |
| Password (signup) | new-password |
| Name | name |
| Phone | tel |
| Address | street-address |
| Credit card | cc-number, cc-exp, cc-csc |
| Non-auth fields | off (prevents password manager triggers) |
Never Block Paste
/* ❌ NEVER — accessibility violation, user hostile */
<input onPaste={(e) => e.preventDefault()} />
/* ✅ Let users paste */
<input />Disable Spellcheck Where Appropriate
<!-- Spellcheck off for: emails, codes, usernames, URLs -->
<input type="email" spellcheck="false">
<input name="username" spellcheck="false">
<input name="verification-code" spellcheck="false">Labels and Hit Targets
<!-- ✅ Clickable label (explicit) -->
<label for="email">Email</label>
<input id="email" type="email">
<!-- ✅ Clickable label (implicit) -->
<label>
Email
<input type="email">
</label>
<!-- ✅ Checkbox: label + control share single hit target -->
<label class="checkbox-wrapper">
<input type="checkbox">
<span>Accept terms</span>
</label>/* No dead zones between checkbox and label */
.checkbox-wrapper {
display: flex;
align-items: center;
gap: 8px;
cursor: pointer;
}Placeholder Formatting
<!-- ✅ Placeholders end with … and show format -->
<input placeholder="name@company.com…">
<input placeholder="(555) 123-4567…">
<input placeholder="Search products…">Submit Button States
/* ✅ Button enabled until request starts, then shows spinner */
<button
type="submit"
disabled={isSubmitting}
>
{isSubmitting ? <Spinner /> : 'Save Changes'}
</button>Error Handling
/* ✅ Errors inline, focus first error on submit */
<form onSubmit={handleSubmit}>
<input
ref={emailRef}
aria-invalid={errors.email ? 'true' : 'false'}
aria-describedby={errors.email ? 'email-error' : undefined}
/>
{errors.email && (
<span id="email-error" role="alert">
{errors.email}
</span>
)}
</form>Unsaved Changes Warning
// Warn before leaving with unsaved changes
useEffect(() => {
const handleBeforeUnload = (e) => {
if (hasUnsavedChanges) {
e.preventDefault();
e.returnValue = '';
}
};
window.addEventListener('beforeunload', handleBeforeUnload);
return () => window.removeEventListener('beforeunload', handleBeforeUnload);
}, [hasUnsavedChanges]);---
3. Images
Images are the #1 cause of layout shift (CLS). Fix them.
Always Set Dimensions
<!-- ❌ Causes layout shift as image loads -->
<img src="photo.jpg" alt="Product">
<!-- ✅ Reserves space, no layout shift -->
<img src="photo.jpg" alt="Product" width="400" height="300">Loading Strategy
<!-- Above the fold: load immediately -->
<img src="hero.jpg" fetchpriority="high" alt="Hero">
<!-- Below the fold: lazy load -->
<img src="feature.jpg" loading="lazy" alt="Feature">In React/Next.js
// Critical hero image
<Image src="/hero.jpg" priority alt="Hero" />
// Below fold
<Image src="/feature.jpg" loading="lazy" alt="Feature" />---
4. Touch & Mobile
Details that make mobile feel native.
Tap Delay Removal
/* Remove 300ms tap delay on mobile */
* {
touch-action: manipulation;
}Tap Highlight
/* Set intentionally, don't just disable */
button, a {
-webkit-tap-highlight-color: rgba(0, 0, 0, 0.1);
}Modal Scroll Lock
/* Prevent scroll chaining in modals/drawers */
.modal, .drawer, .sheet {
overscroll-behavior: contain;
}AutoFocus Rules
- Desktop only — avoid on mobile (opens keyboard unexpectedly)
- Single primary input per page maximum
- Must be justified — not "just because"
/* ✅ Desktop-only autofocus */
<input autoFocus={!isMobile} />---
5. Performance Patterns
Patterns that prevent jank.
Virtualize Large Lists
Lists with 50+ items should be virtualized:
// Use virtua, react-window, or similar
import { VList } from 'virtua';
<VList style={{ height: 400 }}>
{items.map(item => <Row key={item.id} data={item} />)}
</VList>Or CSS-only for simpler cases:
.long-list {
content-visibility: auto;
contain-intrinsic-size: 0 50px; /* estimated item height */
}Avoid Layout Reads in Render
/* ❌ Forces synchronous layout recalculation */
function Component() {
const height = elementRef.current.offsetHeight; // BAD
return <div style={{ marginTop: height }} />;
}
/* ✅ Use ResizeObserver or CSS */
function Component() {
const [height, setHeight] = useState(0);
useLayoutEffect(() => {
const observer = new ResizeObserver(([entry]) => {
setHeight(entry.contentRect.height);
});
observer.observe(elementRef.current);
return () => observer.disconnect();
}, []);
return <div style={{ marginTop: height }} />;
}Uncontrolled Inputs When Possible
/* ❌ Re-renders on every keystroke */
const [value, setValue] = useState('');
<input value={value} onChange={e => setValue(e.target.value)} />
/* ✅ No re-renders during typing */
<input defaultValue="" ref={inputRef} />
/* Get value on submit */
const handleSubmit = () => {
const value = inputRef.current.value;
};Preconnect to CDNs
<head>
<!-- Preconnect to asset domains -->
<link rel="preconnect" href="https://cdn.example.com">
<link rel="preconnect" href="https://fonts.googleapis.com">
<!-- Preload critical fonts -->
<link
rel="preload"
href="/fonts/inter.woff2"
as="font"
type="font/woff2"
crossorigin
>
</head>---
6. Accessibility Quick Wins
High-impact, low-effort accessibility fixes.
Semantic Elements
<!-- ❌ Div with click handler -->
<div onClick={handleClick}>Click me</div>
<!-- ✅ Proper button -->
<button onClick={handleClick}>Click me</button>
<!-- ❌ Span styled as link -->
<span onClick={navigate} className="link">Go here</span>
<!-- ✅ Proper link -->
<a href="/page">Go here</a>Keyboard Handlers
Interactive custom elements need keyboard support:
<div
role="button"
tabIndex={0}
onClick={handleClick}
onKeyDown={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
handleClick();
}
}}
>
Custom button
</div>Heading Hierarchy
<!-- ✅ Proper heading order -->
<h1>Page Title</h1>
<h2>Section</h2>
<h3>Subsection</h3>
<h2>Another Section</h2>
<!-- ❌ Skipping levels -->
<h1>Page Title</h1>
<h4>Section</h4> <!-- Wrong: skipped h2, h3 -->Scroll Margin for Anchors
/* Prevents fixed header from covering anchor targets */
[id] {
scroll-margin-top: 80px; /* height of fixed header + buffer */
}Async Updates Need Announcements
/* Toast notifications, validation messages */
<div role="status" aria-live="polite">
{message}
</div>---
7. Navigation & State
URL should reflect app state. Users expect to bookmark, share, and use back button.
URL Reflects State
/* ✅ Filters, tabs, pagination in URL */
// /products?category=shoes&sort=price&page=2
/* Use nuqs or similar for easy URL state sync */
import { useQueryState } from 'nuqs';
const [category, setCategory] = useQueryState('category');Links Support Browser Features
/* ❌ onClick navigation — breaks Cmd+click, middle-click */
<div onClick={() => navigate('/page')}>Go</div>
/* ✅ Proper link — all browser features work */
<Link href="/page">Go</Link>Destructive Actions Need Confirmation
/* ❌ Immediate destructive action */
<button onClick={deleteAccount}>Delete Account</button>
/* ✅ With confirmation */
<button onClick={() => setShowConfirmModal(true)}>Delete Account</button>
/* Or with undo window */
<button onClick={deleteWithUndo}>Delete Account</button>
// Toast: "Account deleted. Undo (10s)"---
8. Content Copy Rules
Writing that converts.
| Rule | Example |
|---|---|
| Active voice | "Install the CLI" not "The CLI will be installed" |
| Title Case for headings/buttons | "Save Changes" not "Save changes" |
| Numerals for counts | "8 deployments" not "eight deployments" |
| Specific labels | "Save API Key" not "Continue" |
| Error messages include fix | "Email invalid. Use format: name@domain.com" |
| Second person | "Your account" not "My account" |
| & over "and" (space-constrained) | "Terms & Privacy" |
---
9. Anti-Patterns Checklist
Flag these during code review:
- [ ]
user-scalable=noormaximum-scale=1— disables zoom, accessibility violation - [ ]
onPastewithpreventDefault— blocks paste, user hostile - [ ]
transition: all— performance killer, unpredictable - [ ]
outline: nonewithout:focus-visiblereplacement — breaks keyboard nav - [ ]
<div onClick>for navigation — use<a>or<Link> - [ ]
<div>or<span>as buttons — use<button> - [ ] Images without
width/height— causes CLS - [ ] Large arrays
.map()without virtualization (50+ items) - [ ] Form inputs without labels — accessibility fail
- [ ] Icon buttons without
aria-label - [ ] Hardcoded date/number formats — use
Intl.DateTimeFormat,Intl.NumberFormat - [ ]
autoFocuswithout clear justification
---
Pre-Ship Checklist
- [ ] Focus:
:focus-visiblenot:focus, never bareoutline: none - [ ] Forms: Correct
type,inputmode,autocompleteattributes - [ ] Forms: Labels on all inputs, no paste blocking
- [ ] Images:
width/heightset,loading="lazy"below fold - [ ] Touch:
touch-action: manipulation,overscroll-behavior: containin modals - [ ] Performance: Large lists virtualized, no layout reads in render
- [ ] A11y: Semantic HTML, keyboard handlers, heading hierarchy
- [ ] URLs: State reflected in URL, proper
<a>/<Link>for navigation - [ ] Copy: Active voice, specific labels, errors include fix
---
Details matter. These patterns are the difference between "works" and "feels right."
Example Workflow: SaaS Pricing Page
This walkthrough shows the expected shape of a Refero Design process. Replace the example references with actual results from the MCP during real work.
Task: design a pricing page for Northstar, a B2B analytics product for operations teams. The page must feel trustworthy, precise, and modern without looking like a generic AI SaaS template.
---
Phase 0: Discovery
Brief:
Designing a web pricing page for operations leaders and finance stakeholders.
Goal: help qualified teams choose a plan or contact sales with confidence.
Tone: precise, calm, credible, quietly premium.
Main objection/risk: unclear ROI and fear of enterprise lock-in.
Must remember: pricing feels transparent and tied to operational value.
Constraints: existing product uses dense dashboards; avoid flashy gradients.
Research needed: styles for visual language, screens for pricing structure, flows for upgrade/billing sequence.---
Phase 1: Styles Research
Start with styles because this is a visual/brand task.
Style Searches
editorial monochrome SaaS landing page
premium data infrastructure website restrained typography
developer tool website with product screenshots
productivity SaaS with airy spacing
enterprise analytics product marketingOpen 3-4 strong styles with refero_get_style; full styles are large, so split larger research into multiple batches.
Style Findings
| Reference | What It Contributes | What To Adapt |
|---|---|---|
| Style A: editorial monochrome SaaS | Strong typographic hierarchy, low color, confidence through restraint | Use a mostly neutral palette and crisp type scale |
| Style B: data infrastructure website | Dense technical credibility, grid structure, product screenshot framing | Use structured comparison tables and screenshot panels |
| Style C: productivity SaaS | Airy spacing, friendly trust, softer supporting sections | Add breathing room around plan cards and proof sections |
| Style D: premium fintech/product marketing | Subtle accent discipline, numbers presented with authority | Use exact ROI metrics and restrained accent color |
Visual Direction Synthesis
Primary foundation: data infrastructure website.
Borrowed details:
- From editorial SaaS: tighter type hierarchy and low color discipline.
- From productivity: more generous section spacing and softer proof blocks.
- From premium fintech: accent color reserved for value proof and selected plan state.
Reference lock:
Primary reference/direction: data infrastructure website.
Preserve: precise grid, compact comparison table, screenshot framing, sans-led UI,
technical confidence, restrained neutral canvas.
Borrow only: editorial type hierarchy, productivity spacing, fintech proof treatment.
Role rules: green proof accent only for selected state/value proof; product screenshot
frames only for evidence; cards use pricing-screen interaction rules, not decoration.
Media strategy: real product screenshots when available; otherwise fixed-ratio screenshot
placeholders with labels and art direction, not fake decorative app mockups.
Reject: cream editorial canvas, serif hero, muted clay/orange accent, decorative cards.
Token commitments: white/charcoal/cool-neutral canvas, sans typography, green proof
accent, 8px max radius, thin borders, product screenshots as evidence.Resulting direction:
A precise, evidence-led pricing page: white canvas, deep charcoal text, compact sans-led
headlines, thin rule lines, quiet plan cards, and exact operational metrics. Use one
muted green accent for value proof and selected actions. Product screenshots should be
framed as evidence, not decoration.---
Phase 2: Screen Research
Use screens for concrete pricing decisions after visual direction is clear.
Screen Searches
pricing page annual monthly toggle
feature comparison table SaaS pricing
usage based pricing enterprise
contact sales pricing page
pricing page ROI calculatorOpen the strongest screens with refero_get_screen. Use refero_get_similar_screens if one example is especially relevant.
Screen Findings
| Pattern | What To Look For | Decision |
|---|---|---|
| Plan cards | Number of plans, highlighted plan, CTA hierarchy | Use 3 plans; highlight Pro as default |
| Billing toggle | Placement, annual discount language, interaction clarity | Put monthly/annual toggle above cards; show exact annual savings |
| Feature comparison | Whether comparison is complete or simplified | Use compact comparison under cards with expandable details |
| Enterprise CTA | How sales motion is framed | Use "Talk to sales" for Enterprise with proof and security cues |
| ROI proof | Placement of metrics/calculator | Add ROI strip between plan cards and comparison table |
Concrete tactics to adapt:
- Put "No credit card required" near the trial CTA, not buried in FAQ.
- Show annual savings as exact value where possible, not just a percentage.
- Make Enterprise feel like a tailored plan, not a vague catch-all.
- Use a comparison table for evaluation buyers, but keep the first viewport decisive.
- Include security/procurement signals near the Enterprise CTA.
---
Phase 3: Flow Research
Use flows because pricing can lead into upgrade, checkout, or sales contact journeys.
Flow Searches
workspace billing upgrade
checkout subscription SaaS
contact sales pricing
trial signup billingOpen relevant flows with refero_get_flow.
Flow Findings
| Journey Question | Finding To Extract | Decision |
|---|---|---|
| What happens after plan selection? | Does the product ask for account, payment, or workspace first? | Trial CTA starts account creation before payment |
| How is annual billing confirmed? | Are savings and renewal dates repeated? | Repeat billing period and savings in checkout |
| How does sales contact work? | Is it calendar, form, or direct email? | Enterprise CTA opens short sales form with company size |
| How are errors/recovery handled? | Can users return to pricing without losing state? | Keep selected plan visible through signup |
---
Phase 4: Synthesis
Research Summary
Research summary:
- Styles reviewed: 5 across editorial SaaS, data infrastructure, productivity, fintech.
- Screens reviewed: pricing cards, billing toggles, feature comparison, ROI proof, enterprise CTAs.
- Flows reviewed: upgrade, checkout, sales contact.
Visual direction:
- Primary foundation: data infrastructure website.
- Reference lock: precise grid, compact comparison, sans-led UI, product evidence.
- Borrowed detail 1: editorial type hierarchy and low color discipline.
- Borrowed detail 2: fintech-style precision around numbers and proof.
Product patterns:
- 3 plan cards with Pro highlighted.
- Monthly/annual toggle above cards.
- ROI proof strip before detailed comparison.
- Enterprise CTA supported by security/procurement signals.
Journey logic:
- Trial starts account creation before payment.
- Checkout repeats selected plan, billing period, savings, and renewal date.
- Enterprise route asks only for essential qualification fields.Design Decision Ledger
| Area | Decision | Source | Source rule / role | Why |
|---|---|---|---|---|
| Palette | White, charcoal, cool neutrals, muted green accent | Style B + fintech reference + brief | Accent only for value proof and selected actions | Trustworthy and precise; avoids generic blue/purple SaaS |
| Typography | Sans-led hierarchy, tight headings, readable 15-16px body | Style B + Style A hierarchy | Use hierarchy, not decorative serif voice | Premium without becoming decorative or literary |
| Layout | Precise grid, compact comparison structure, proof near decision points | Style B + pricing screens | Grid is the core layout rule, not generic stacked sections | Keeps the page scannable for evaluation buyers |
| Media | Product screenshots as evidence panels | Style B + brief | Use real screenshots or labeled placeholders; no fake decorative mockups | Keeps proof honest without low-quality invented imagery |
| Cards | Thin borders, subtle selected state, no heavy shadows | Pricing screens + anti-slop card rule | Cards only for plan comparison and interaction | Keeps evaluation calm and scannable |
| CTA hierarchy | Pro trial primary, Enterprise sales secondary | Pricing screens + buyer journey | Primary treatment only for self-serve action | Supports self-serve and sales-led paths |
| Proof | ROI metrics near pricing, security near Enterprise | Screen research + buyer objections | Proof modules near the decision they support | Answers buyer objections where they appear |
| Memorable detail | "Operational value" strip showing saved hours/cost by plan | Brief + analytics product context | Metric strip as evidence, not decoration | Makes pricing feel tied to outcome |
---
Phase 5: Implementation Blueprint
Tokens
:root {
--font-sans: "Inter", system-ui, sans-serif;
--color-bg: #ffffff;
--color-text: #171717;
--color-muted: #6b7280;
--color-line: #e5e7eb;
--color-accent: #1f8a5b;
--color-accent-soft: #e8f5ee;
--radius-card: 8px;
--space-1: 4px;
--space-2: 8px;
--space-3: 12px;
--space-4: 16px;
--space-6: 24px;
--space-8: 32px;
--space-12: 48px;
--space-16: 64px;
}Page Structure
1. Pricing header
- Literal headline: "Pricing"
- Short value sentence tied to operations outcomes
- Monthly/annual toggle
2. Plan cards
- Starter, Pro, Enterprise
- Pro highlighted
- Exact CTA per plan
- Objection killer under primary CTA
3. Operational value strip
- Saved hours/month
- Faster reporting
- Forecast confidence
4. Feature comparison
- Compact by default
- Grouped by buyer concern
5. Enterprise proof
- Security/procurement cues
- Sales CTA
6. FAQ
- Billing, cancellation, data, procurementQuality Gate
Before shipping:
- Styles influenced the visual language.
- Screens influenced concrete pricing structure.
- Flows influenced the post-click journey.
- The page does not copy one reference directly.
- The palette does not default to generic indigo/violet.
- The first viewport makes the pricing decision clear.
- Buyer objections are handled near the relevant action.
- The page has one memorable detail tied to this product's value.
Icons & Glyphs Guide
In product UI, treat icons as typography — functional, not decorative.
---
Two Contexts
| Context | Style | Rule |
|---|---|---|
| Product UI | Clean outline or solid, one consistent set | Predictable, scalable, themeable |
| Marketing | Duotone, gradients, illustrative allowed | Never leaks into product |
---
Icon Sizing
Canvas = the bounding box icons are designed within. Most libraries use 24×24px as base, but this is convention, not law.
Display sizes depend on context:
- Small (16px): inline with body text, table cells, dense UI
- Medium (20–24px): buttons, nav items, form inputs
- Large (28–32px): feature cards, empty states, marketing
Stroke weight varies by library and style:
- Thinner (1.5px): lighter feel, works better at larger sizes
- Standard (2px): common default in Lucide, Heroicons
- Thicker (2.5px+): bolder presence, better at small sizes
Round vs square caps/joins: Round feels friendlier, modern. Square feels more technical, precise. Match your product's tone.
Key principle: Pick one library or define your own spec. Consistency matters more than specific values.
---
Optical Corrections
What separates "adequate" from "premium."
Centering: Geometric center ≠ visual center.
- Play triangles → shift right 0.5–1px
- Chevrons/arrows → shift toward point
- Test: Put icon in a circle. Looks centered? If not, adjust.
Weight: Different shapes have different visual mass at same stroke.
- Circles appear lighter than squares
- Diagonals appear thinner than horizontals
- Aim for equal visual mass, not equal measurements
---
Style Consistency
One language per product. No exceptions.
| Style | Best For |
|---|---|
| Outline | Dense UIs, data-heavy products |
| Solid | Consumer apps, clear actions |
| Variable glyphs | Design systems (SF Symbols, Material Symbols) |
Don'ts:
- ❌ Outline in nav + solid in buttons + duotone in cards
- ❌ Mixing libraries (Lucide + Heroicons = collage)
- ❌ Custom icons that ignore the system's grid/stroke
---
Icon + Text Pairing
Starting point — adjust based on visual testing:
| Text Size | Icon Size |
|---|---|
| 14–16px | 16px |
| 16–18px | 18–20px |
| Headings | 20–24px |
Alignment: Icons need align-items: center + often 0.5–1px manual tweak.
Weight harmony: Semibold text + thin icon = "from different systems." Match weights or use solid.
---
Color
Default: currentColor — inherits text color, syncs with themes automatically.
Semantic: Red (error), green (success), amber (warning) — only for status, never decoration.
Contrast: Meaningful icons need 3:1 ratio (WCAG non-text). Applies to icon buttons, toggles, status indicators.
---
Accessibility
| Type | Requirement |
|---|---|
| Action icons | aria-label on button, or visible text nearby |
| Decorative icons | aria-hidden="true" |
| Icon buttons | Hit area: 44×44px on touch, 32×32px on desktop (visual can be smaller) |
---
Pre-Ship Checklist
- [ ] 50% scale: Icons readable when zoomed out?
- [ ] Grayscale: States clear without color?
- [ ] Dark theme: Outline icons don't disappear?
- [ ] Table rows: Icons don't overpower text?
- [ ] Contrast: Icon buttons meet 3:1?
- [ ] Touch targets: 44px+ hit area?
- [ ] Consistency: Same style everywhere?
---
Libraries
For Product UI (SVG-based)
| Library | Style | When to Use |
|---|---|---|
| Lucide | Outline only | SaaS default. Clean, consistent, 24×24/2px stroke. |
| Heroicons | Outline + Solid | Tailwind projects. Two variants per icon. |
| Phosphor | 6 weights | Need weight flexibility without variable fonts. |
Variable Glyph Systems
Best when icons must match text weight dynamically.
Material Symbols (Web)
/* Include from Google Fonts, then: */
.icon {
font-family: 'Material Symbols Outlined';
font-variation-settings:
'FILL' 0, /* 0 = outline, 1 = solid */
'wght' 500, /* match your text weight */
'opsz' 24; /* optical size: 20, 24, 40, 48 */
}wght: Sync with text (400, 500, 600)opsz: Increase for smaller icons (better clarity)FILL: Toggle outline/solid per icon
SF Symbols (Apple/Native)
- Automatically matches San Francisco font weight
- Scale axis for emphasis (small/medium/large)
- Use in SwiftUI/UIKit, not web
When to Use What
| Scenario | Choice |
|---|---|
| Web SaaS, quick start | Lucide |
| Tailwind project | Heroicons |
| Need weight sync with text | Material Symbols |
| Apple native app | SF Symbols |
| Multiple weights, no variable fonts | Phosphor |
---
Icons are typography. Consistent, optical, accessible. If it doesn't read instantly—simplify.
Refero MCP Tools Reference
MCP clients may namespace tool names, but the Refero tools are exposed with the refero_ prefix. Use the exact tool names shown by the client.
Refero has three research layers:
1. Styles - visual direction and taste. 2. Screens - concrete UI patterns and product-screen decisions. 3. Flows - multi-step journey logic.
Styles
refero_search_styles
Search curated design styles using semantic search.
Use first for any task with visual direction, brand feel, typography, color, layout, spacing, elevation, components, imagery, art direction, design-system inspiration, or visual polish.
What results contain:
- style UUID
- title
- source URL
- preview image URL
- platform
- rich natural-language description of the visual language
Parameters:
| Parameter | Type | Required | Notes |
|---|---|---|---|
query | string | Yes | Semantic query for aesthetic, domain, audience, category, or brand direction. |
page | number | No | Pagination. Use later pages to explore less obvious directions. |
Good queries:
editorial monochrome SaaS landing page
warm trustworthy healthcare product marketing
premium fintech website with restrained typography
developer tool website with product screenshots
luxury ecommerce editorial product page
productivity SaaS with airy spacing
Attio editorial SaaS typography
Linear changelog dark developer toolSearch method:
- Search 3-5 different visual angles.
- Include one broad aesthetic query.
- Include one domain/category query.
- Include one known-brand or strong-product query when relevant.
- Do not stop at the first good result.
Current coverage:
- Styles currently focus on web marketing/product pages: landing pages, pricing pages,
product marketing sites, editorial brand sites, and SaaS websites.
- Styles do not currently cover in-app dashboards, auth screens, settings screens, or iOS
app screens as style systems.
- Even for product UI, use styles to establish taste and visual language, then use
screens/flows for product-specific logic.
refero_get_style
Retrieve full design style references for one or more style UUIDs.
Use after refero_search_styles to turn promising style previews into actionable design material.
What results may include:
- visual thesis / north star
- colors and usage roles
- typography and type scale
- layout guidance, section rhythm, and composition patterns
- spacing, radius, shadows, elevation, surfaces
- component treatments and sometimes component/code examples
- imagery, graphics, illustration, or product screenshot treatment
- do/don't rules
- agent prompt guidance or implementation notes
Parameters:
| Parameter | Type | Required | Notes |
|---|---|---|---|
style_id | string | Yes* | Style UUID from refero_search_styles. Exactly one of `style_id` or `style_ids` must be provided. |
style_ids | string[] | Yes* | Array of style UUIDs. Full styles are large; recommended max batch is 3-4. Exactly one of `style_id` or `style_ids` must be provided. |
response_format | enum | No | json or md. Default: md. |
How to use returned styles:
- Treat each style as a reference ingredient, not a template.
- Pick one primary foundation for mood and density.
- Borrow 1-2 specific details from other styles.
- Extract layout, component, spacing, and elevation rules, not only colors and fonts.
- Preserve source token/component roles instead of repurposing them.
- Preserve imagery/media roles. Use real/generated/stock assets when possible; use an
intentional placeholder with art direction when the needed asset is unavailable.
- Translate everything to the user's product, audience, and constraints.
Screens
refero_search_screens
Search real UI screens using semantic search.
Use for concrete interface decisions: page structure, component choices, content hierarchy, copy, states, and product-specific patterns.
Parameters:
| Parameter | Type | Required | Notes |
|---|---|---|---|
query | string | Yes | Search by screen type, UI element, pattern, state, company, or on-screen text. |
platform | enum | Yes | web for web app/site patterns, ios for mobile app patterns. |
page | number | No | Pagination. Use later pages to explore beyond obvious results. |
Good queries:
pricing page annual monthly toggle
feature comparison table
dashboard empty state
billing settings cancellation modal
onboarding progress indicator
2FA setup recovery codes
data table filters
destructive action confirmationSearch guidance:
- Search by what is literally on the screen.
- Prefer concrete UI terminology over broad aesthetic words.
- If the main query is aesthetic ("premium", "minimalist", "editorial", "dark"), search
styles first.
- Use
pagefor search pagination. Do not passlimit,image_size, or
include_similar to search tools.
refero_get_screen
Get full details for one or more screens by UUID.
Use after refero_search_screens when a result looks relevant and you need deeper metadata, descriptions, app/site info, patterns, elements, fonts, or content structure.
Parameters:
| Parameter | Type | Required | Notes |
|---|---|---|---|
screen_id | string | Yes* | One screen UUID. Use exactly one of screen_id or screen_ids. |
screen_ids | string[] | Yes* | Multiple screen UUIDs. Use exactly one of screen_id or screen_ids. |
Batching:
- Retrieve a few strong screens at a time.
- If a batch fails, retry with fewer IDs.
refero_get_similar_screens
Get visually and functionally similar screens for a screen UUID.
Use when one screen is especially relevant and you want comparable examples fast.
Parameters:
| Parameter | Type | Required | Notes |
|---|---|---|---|
screen_id | string | Yes | UUID from refero_search_screens or refero_get_screen. |
limit | number | No | Number of similar screens. Default is usually 10; max is usually 20. |
refero_get_screen_image
Get raw screenshot image content by UUID.
Use only when text metadata is not enough and you need to visually inspect the exact screenshot. This returns image content and can use more context than text tools.
Parameters:
| Parameter | Type | Required | Notes |
|---|---|---|---|
screen_id | string | Yes | UUID from refero_search_screens or refero_get_screen. |
image_size | enum | No | thumbnail or full. Default: thumbnail. |
Flows
refero_search_flows
Search user flows: connected screens showing how a user completes a task.
Use for journey logic: onboarding, checkout, signup, cancellation, upgrade, settings, account deletion, password reset, and other before/after sequences.
Parameters:
| Parameter | Type | Required | Notes |
|---|---|---|---|
query | string | Yes | Search by task, journey, company, industry, or key step. |
platform | enum | Yes | web for web app/site flows, ios for mobile app flows. |
page | number | No | Pagination. Use later pages to explore more examples. |
Good queries:
signup onboarding
checkout with promo code
subscription cancellation
account deletion feedback
password reset 2FA
workspace billing upgraderefero_get_flow
Get full details for one or more user flows.
Use after refero_search_flows to understand step-by-step goals, actions, system responses, screens, user problem, and related search queries.
Parameters:
| Parameter | Type | Required | Notes |
|---|---|---|---|
flow_id | number | Yes* | Numeric flow ID. Use exactly one of flow_id or flow_ids. |
flow_ids | number[] | Yes* | Multiple numeric flow IDs. Use exactly one of flow_id or flow_ids. |
Response Formats
Some clients expose a response_format parameter on Refero tools. Use it only when the tool schema shown by your client includes it:
md/ markdown for human-readable research notes.jsonfor structured comparison or when extracting fields programmatically.
Common Mistakes
- Do not use old
_toolsuffixed names. - Do not call
get_design_guidance; use styles/screens/flows research instead. - Do not pass
image_sizetorefero_get_screen; userefero_get_screen_imagefor raw images. - Do not pass
include_similartorefero_get_screen; userefero_get_similar_screens. - Do not use screens as the main source for visual taste when styles are available.
- Do not assume styles include dashboards, auth screens, or iOS app screens as style systems.
- Do not copy a single style directly.
If Results Are Weak
- Broaden the query.
- Remove extra adjectives or constraints.
- Search adjacent categories.
- Try a known-product or best-brand query.
- Inspect later pages.
- For sparse flows, search related screens and reconstruct the journey manually.
Motion & Micro-interactions Guide
Motion in product UI serves three purposes. If an animation doesn't do at least one—remove it.
1. Feedback — "I pressed this and it worked" 2. Continuity — "Here's where the element went and where it came from" 3. Hierarchy — "Look here, this is important"
---
0. Context First
Before adding motion, answer these questions:
| Question | Why It Matters |
|---|---|
| Product UI or marketing? | Product: subtle, fast, functional. Marketing: more expressive allowed. |
| How often is this triggered? | High-frequency (hover, typing): faster. Low-frequency (modal open): can be slower. |
| Does this help or distract? | If you can't justify the animation's purpose—don't add it. |
Hard rule:
When in doubt — shorter, subtler, or none. Motion that doesn't serve function is noise.
---
1. The Motion Pyramid
From essential to risky. Start at Level 1, add higher levels only when justified.
Level 1: Micro Feedback (Most Important)
- Hover, press, focus states
- Toggles, checkboxes, radio buttons
- Inline validation indicators
Goal: Feeling of responsiveness without noticeable animation.
Level 2: State Transitions
- Expand/collapse (accordions, details)
- Tab switches
- Modal, drawer, popover appearance
Goal: "Movement" instead of "teleportation."
Level 3: Layout Continuity
- Elements resize/reposition while maintaining context
- Reorder, filter chips, drag-and-drop
- List item add/remove
Goal: Cognitive economy—less "what just happened?"
Level 4: Expressive (Rare in Product)
- Hero animations, illustrations
- Onboarding sequences
- Marketing pages
Risk zone: Easily becomes noise. Use sparingly in product UI.
---
2. Timing That Actually Works
Forget "500ms for everything." Use purpose-based categories.
Duration Reference
| Category | Duration | Examples |
|---|---|---|
| Instant | 90–150ms | Hover, press, toggle, focus |
| State change | 160–240ms | Accordion, tabs, small panels |
| Page/large | 240–360ms | Modal, drawer, route transition |
| Complex | 360–500ms | Large layout reflow (rare, optimize if possible) |
Practical Preset (Copy-Paste Ready)
:root {
--duration-fast: 120ms;
--duration-default: 200ms;
--duration-slow: 320ms;
}Rules
- Smaller distance/amplitude → shorter duration
- Higher frequency action → shorter duration
- 500ms+ in product UI almost always feels slow
- If users do it 100x/day, make it instant
---
3. Easing: Native Feel Without Cringe
Basic Principle
| Action | Easing | Why |
|---|---|---|
| Enter (appear) | ease-out | Fast start, soft landing |
| Exit (disappear) | ease-in | Soft start, fast exit |
| State change | ease-in-out | Smooth both ways |
CSS Tokens
:root {
--ease-out: cubic-bezier(0.0, 0.0, 0.2, 1); /* Enter */
--ease-in: cubic-bezier(0.4, 0.0, 1, 1); /* Exit */
--ease-in-out: cubic-bezier(0.4, 0.0, 0.2, 1); /* Change */
/* Alternative: slightly more "alive" */
--ease-emphasized: cubic-bezier(0.2, 0.0, 0, 1);
}When to Use Spring
Spring physics work better for:
- Drag, swipe, gesture responses
- Small "bounce" feedback (use sparingly)
- Elements that feel physical
Critical: Spring must decay quickly. No prolonged "jello" effect.
// Framer Motion / Motion example
{ type: "spring", stiffness: 400, damping: 30 } // Snappy
{ type: "spring", stiffness: 200, damping: 20 } // Smooth---
4. Micro-interactions That Work
Maximum effect, minimum risk.
Buttons and Controls
| State | Animation | Duration |
|---|---|---|
| Hover | Background color shift | 120ms |
| Press | scale: 0.98 | 90–120ms |
| Focus | Ring/outline appears | 120ms |
| Disabled | No animation, just visual degradation | — |
| Loading | Clear state indicator, not just spinner | — |
.button {
transition: background-color 120ms var(--ease-out),
transform 90ms var(--ease-out);
}
.button:hover {
background-color: var(--primary-hover);
}
.button:active {
transform: scale(0.98);
}Inputs
| State | Animation | Notes |
|---|---|---|
| Focus | Border/underline highlight | No layout shift |
| Error | Light shake on submit only | Short (200ms), not on every keystroke |
| Success | Subtle checkmark or color | Don't overdo it |
Lists and Tables
| Action | Animation | Notes |
|---|---|---|
| Add row | Fade in + slide 4–8px | 200ms |
| Remove row | Fade out + collapse | 180ms |
| Reorder | Layout animation | Only if performant |
.list-item-enter {
opacity: 0;
transform: translateY(-8px);
}
.list-item-enter-active {
opacity: 1;
transform: translateY(0);
transition: all 200ms var(--ease-out);
}Modals and Drawers
| Element | Enter | Exit |
|---|---|---|
| Overlay | Fade 200ms | Fade 150ms |
| Modal | Fade + scale from 0.95 | Fade + scale to 0.95 |
| Drawer | Slide from edge | Slide to edge |
.modal {
opacity: 0;
transform: scale(0.95);
transition: opacity 200ms var(--ease-out),
transform 200ms var(--ease-out);
}
.modal.open {
opacity: 1;
transform: scale(1);
}---
5. Motion Tokens for Design Systems
Define these to prevent chaos across your team.
Minimum Token Set
:root {
/* Durations */
--duration-fast: 120ms;
--duration-default: 200ms;
--duration-slow: 320ms;
/* Easings */
--ease-out: cubic-bezier(0.0, 0.0, 0.2, 1);
--ease-in: cubic-bezier(0.4, 0.0, 1, 1);
--ease-in-out: cubic-bezier(0.4, 0.0, 0.2, 1);
/* Distances (for micro slides) */
--motion-distance-sm: 4px;
--motion-distance-md: 8px;
--motion-distance-lg: 16px;
}Component Mapping
| Component | Duration | Easing |
|---|---|---|
| Hover/press | --duration-fast | --ease-out |
| Accordion/tabs | --duration-default | --ease-in-out |
| Modal/drawer | --duration-slow | --ease-out (enter), --ease-in (exit) |
| Tooltip | --duration-fast | --ease-out |
---
6. Reduced Motion: Not Optional
Always provide a prefers-reduced-motion variant.
What to Change
| Full Motion | Reduced Motion |
|---|---|
| Slide + fade | Fade only |
| Scale + fade | Fade only |
| Spring bounce | Instant or short tween |
| Parallax | Remove entirely |
| Auto-playing loops | Pause or remove |
Implementation
/* Default: full motion */
.modal {
transform: scale(0.95);
opacity: 0;
transition: transform 200ms var(--ease-out),
opacity 200ms var(--ease-out);
}
/* Reduced motion: fade only */
@media (prefers-reduced-motion: reduce) {
.modal {
transform: none;
transition: opacity 150ms var(--ease-out);
}
}CSS Shortcut
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}---
7. Libraries and Tools
For Web/SaaS (React/Next)
| Library | Best For | Notes |
|---|---|---|
| CSS transitions | Micro feedback, simple states | Best performance, no dependencies |
| Motion / Framer Motion | Layout animations, springs, variants | Go-to for React projects |
| Web Animations API | Native, no dependencies | When minimalism is priority |
For Complex Scenarios
| Library | Best For | Notes |
|---|---|---|
| GSAP | Complex timelines, marketing | Heavy but powerful |
| Rive | Interactive illustrations, icons | Great for empty states, onboarding |
| Lottie | Illustrative animations | Watch file size and export quality |
For most SaaS products: CSS + Motion is sufficient.
---
8. Anti-Patterns
Things that instantly make motion feel cheap:
Red Flags
- ❌ 300–600ms on hover/buttons — feels sluggish
- ❌ Linear easing — robotic, unnatural
- ❌ Everything animates at once — no attention hierarchy
- ❌ Infinite loops in product screens — distracting
- ❌ Inconsistent timings — 200ms here, 400ms there, chaos
- ❌ Large movements without reduced-motion — accessibility fail
- ❌ Bounce/spring that doesn't settle — "jello" effect
- ❌ Animation for animation's sake — if you can't justify it, remove it
Critical: Never Use transition: all
/* ❌ NEVER — unpredictable, causes layout thrashing */
.button {
transition: all 200ms ease;
}
/* ✅ ALWAYS — explicit properties only */
.button {
transition: background-color 120ms var(--ease-out),
transform 90ms var(--ease-out);
}Why `transition: all` is dangerous:
- Animates properties you didn't intend (width, height, padding)
- Causes layout recalculations on every frame
- Performance killer, especially on low-end devices
- Makes debugging animation issues nearly impossible
Transform Origin
For scale/rotate animations, set transform-origin explicitly:
/* Dropdown appearing from top-right corner */
.dropdown {
transform-origin: top right;
transform: scale(0.95);
opacity: 0;
}
.dropdown.open {
transform: scale(1);
opacity: 1;
}Common origins:
- Modals:
center(default) - Dropdowns:
top leftortop right(where trigger is) - Tooltips: edge closest to trigger
- Buttons:
centerfor press effect
SVG Animation
Transforms on SVG elements behave differently. Wrap in <g>:
/* ❌ Won't work as expected */
svg path {
transform: rotate(45deg);
}
/* ✅ Works correctly */
svg g.icon-wrapper {
transform-box: fill-box;
transform-origin: center;
transform: rotate(45deg);
}Animations Must Be Interruptible
User input should be able to interrupt any animation mid-flight:
/* Animation responds to new state immediately */
.panel {
transition: transform 300ms var(--ease-out);
}
/* No need for animation-fill-mode: forwards or delays that block interaction */Quick Test
1. Does this animation serve feedback, continuity, or hierarchy? 2. Is the duration appropriate for the action frequency? 3. Does it have proper easing (not linear)? 4. Is there a reduced-motion variant? 5. Would removing it hurt the UX?
If you answered "no" to #1 or #5—remove the animation.
---
9. Pre-Ship Checklist
- [ ] Hover/press states: 90–150ms with ease-out
- [ ] State transitions: 160–240ms with ease-in-out
- [ ] Modals/drawers: 240–360ms with proper enter/exit easing
- [ ] All motion uses tokens, not random values
- [ ] Reduced motion variant tested and working
- [ ] No linear easing anywhere
- [ ] Nothing exceeds 500ms in product UI
- [ ] Every animation has a purpose (feedback/continuity/hierarchy)
- [ ] Consistent across similar components
- [ ] Performance tested on slower devices
- [ ] No `transition: all` — list properties explicitly
- [ ] `transform-origin` set for scale/rotate animations
- [ ] Animations interruptible — respond to user input mid-animation
---
Appendix: Complete Token System
Reference implementation:
:root {
/* ===== DURATIONS ===== */
--duration-instant: 0ms;
--duration-fast: 120ms;
--duration-default: 200ms;
--duration-slow: 320ms;
--duration-slower: 400ms;
/* ===== EASINGS ===== */
/* Standard (Material-inspired) */
--ease-out: cubic-bezier(0.0, 0.0, 0.2, 1);
--ease-in: cubic-bezier(0.4, 0.0, 1, 1);
--ease-in-out: cubic-bezier(0.4, 0.0, 0.2, 1);
/* Emphasized (more "alive") */
--ease-emphasized: cubic-bezier(0.2, 0.0, 0, 1);
--ease-emphasized-decel: cubic-bezier(0.05, 0.7, 0.1, 1);
/* ===== DISTANCES ===== */
--motion-distance-xs: 2px;
--motion-distance-sm: 4px;
--motion-distance-md: 8px;
--motion-distance-lg: 16px;
--motion-distance-xl: 24px;
/* ===== SPRINGS (for JS libraries) ===== */
/* Use in Framer Motion / Motion */
/* Snappy: { stiffness: 400, damping: 30 } */
/* Smooth: { stiffness: 200, damping: 20 } */
/* Bouncy: { stiffness: 300, damping: 15 } — use sparingly */
}
/* ===== REDUCED MOTION ===== */
@media (prefers-reduced-motion: reduce) {
:root {
--duration-fast: 0ms;
--duration-default: 0ms;
--duration-slow: 100ms;
--duration-slower: 100ms;
--motion-distance-sm: 0px;
--motion-distance-md: 0px;
--motion-distance-lg: 0px;
}
}---
Resources
- Material Design Motion — Easing, duration, tokens, systematic approach
- Apple HIG Motion — Platform conventions, reduced motion criteria
- Motion.dev / Framer Motion docs — Spring/tween/layout animations
- Web Animations API (MDN) — Native browser animation capabilities
---
Motion is restraint. Fast, purposeful, accessible. If you can't explain why it's there—remove it.
Typography Guide
Typography is 90% of web design. Get it right and everything else falls into place. Get it wrong and no amount of polish will save you.
---
0. Context First
Before choosing fonts, answer these questions:
| Question | Why It Matters |
|---|---|
| Work tool or marketing? | Work products need neutrality, not personality |
| Long reading or scanning? | Changes line-height and density decisions |
| B2B, B2C, or Dev tool? | Affects font character and weight choices |
Default approach:
When in doubt — go denser, simpler, and more neutral. Clarity beats decoration in most product interfaces.
This mindset helps avoid over-designed typography in functional contexts. For branding, editorial, or creative products — different rules apply.
---
1. The Safe SaaS Preset
Before customizing anything, this works:
:root {
--font-family: 'Inter', system-ui, sans-serif;
--text-base: 16px;
--line-height: 1.55;
--scale: 1.2;
--font-weight-normal: 400;
--font-weight-medium: 500;
--font-weight-semibold: 600;
--max-width: 65ch;
--text-primary: #111;
--text-secondary: rgba(0,0,0,0.7);
--text-tertiary: rgba(0,0,0,0.5);
}If you use this preset as-is, your typography is already good. Everything below is refinement.
---
2. Type Scale
A consistent scale creates visual rhythm. Pick a ratio, stick to it.
Common Ratios
| Ratio | Multiplier | Best For |
|---|---|---|
| Minor Second | 1.067 | Dense UI, dashboards |
| Major Second | 1.125 | Compact interfaces |
| Minor Third | 1.200 | General purpose — default choice |
| Major Third | 1.250 | Marketing, editorial |
| Perfect Fourth | 1.333 | Bold, expressive layouts |
| Golden Ratio | 1.618 | Rare: hero sections only |
Note: Golden Ratio is dramatic. Use only for landing page heroes, not general UI.
Practical Scale (Minor Third × 16px base)
11px — Caption, footnote
13px — Small text, metadata
16px — Body (base)
19px — Large body, lead
23px — H4
28px — H3
33px — H2
40px — H1
48px — Display
57px — HeroCSS Tokens
:root {
--text-xs: 0.6875rem; /* 11px */
--text-sm: 0.8125rem; /* 13px */
--text-base: 1rem; /* 16px */
--text-lg: 1.1875rem; /* 19px */
--text-xl: 1.4375rem; /* 23px */
--text-2xl: 1.75rem; /* 28px */
--text-3xl: 2.0625rem; /* 33px */
--text-4xl: 2.5rem; /* 40px */
--text-5xl: 3rem; /* 48px */
--text-6xl: 3.5625rem; /* 57px */
}Rule: Maximum 6-8 sizes in production. More = chaos.
---
3. Font Pairing
Most successful SaaS products use one font family. Two fonts adds complexity — make sure it's justified.
The One-Font Rule
One font + multiple weights = professional
Two fonts = requires justification
Three fonts = almost neverWhen you actually need a second font:
- Marketing/landing pages (not the app itself)
- Content-heavy products (editorial, documentation)
- There's real art direction, not just "looks nice"
If you don't have a strong reason — one font, different weights.
If You Must Pair
| Strategy | Example |
|---|---|
| Serif + Sans | Instrument Serif + Inter |
| Display + System | Cal Sans + system-ui |
| Mono accent | JetBrains Mono (code) + Inter (UI) |
Pairing rules: 1. Contrast in structure — serif with sans, not two serifs 2. Similar x-height — letters feel proportional 3. Intentional contrast — mixing eras (Didot + geometric) can work as a deliberate choice, not an accident
Safe Font Choices by Product Type
| Product | Font |
|---|---|
| SaaS / Tech | Inter, SF Pro, Geist |
| Finance / Enterprise | Inter, IBM Plex Sans |
| Startup | Inter, DM Sans, Plus Jakarta |
| Dev tools | Inter + JetBrains Mono (code) |
---
4. Text Color System
Typography in a vacuum doesn't exist. Most "bad" interfaces look bad because of color, not font choice.
The System
:root {
--text-primary: #0B0B0B; /* 100% — headlines, body */
--text-secondary: rgba(0,0,0,0.65); /* 65% — descriptions */
--text-tertiary: rgba(0,0,0,0.45); /* 45% — metadata, captions */
--text-disabled: rgba(0,0,0,0.3); /* 30% — disabled states (rare) */
}Rules That Actually Work
- Never pure black — Use
#0B0B0B–#111, not#000 - Body text minimum — Never below 60% opacity for readable text
- Fewer shades, stable usage — 3-4 text colors max, used consistently
- Disabled is rare — If you have lots of disabled text, redesign
Anti-pattern
"Let's make the text lighter for an airy feel"
This almost always destroys readability. If it doesn't pass squint test, it's too light.
Dark Mode Inversion
[data-theme="dark"] {
--text-primary: #F5F5F5;
--text-secondary: rgba(255,255,255,0.7);
--text-tertiary: rgba(255,255,255,0.5);
}---
5. Font Weight
Weight creates hierarchy. Use it deliberately.
Standard Weights
| Weight | Name | Use |
|---|---|---|
| 300 | Light | Large display text only |
| 400 | Regular | Body text, descriptions |
| 500 | Medium | UI labels, subtle emphasis |
| 600 | Semibold | Subheadings, buttons |
| 700 | Bold | Headlines, strong emphasis |
Rules
- Body text: Always 400. Never bold entire paragraphs.
- Headlines: 400–700 depending on font. Serifs often look better at 400.
- UI elements: 500 for labels, 600 for buttons.
- Small text: 400 or 500. Light weights (300) become illegible below 16px.
Weight + Size Relationship
Larger size → can use lighter weight
Smaller size → needs heavier weight
64px heading → 400 weight looks elegant
12px caption → 400 minimum, 500 preferredAnti-pattern: Using bold (700) for everything. It flattens hierarchy.
---
6. Line Height
Line height (leading) affects readability more than any other property.
Quick Reference
| Text Type | Line Height | Why |
|---|---|---|
| Body text | 1.5 – 1.7 | Optimal for reading |
| Short paragraphs | 1.4 – 1.5 | Slightly tighter is fine |
| Headlines | 1.0 – 1.2 | Tight, impactful |
| Large display | 0.9 – 1.1 | Very tight, dramatic |
| UI text | 1.2 – 1.4 | Compact but readable |
| Buttons | 1 | Single line, centered |
CSS Tokens
:root {
--leading-none: 1;
--leading-tight: 1.15;
--leading-snug: 1.3;
--leading-normal: 1.5;
--leading-relaxed: 1.7;
--leading-loose: 2;
}Principles
1. Longer lines need more leading — 80+ characters? Use 1.6–1.7 2. Shorter lines need less — 40 characters? 1.4 is fine 3. Headlines are tight — Multi-line headlines at 1.5 look broken 4. Sans-serif needs more — Add 0.1 compared to serif
---
7. Vertical Rhythm
AI-slop is almost always exposed by bad spacing between text blocks.
The Simple Rule
Line-height × 0.5 = minimum vertical spacing stepExample
Body: 16px / 1.5 → line-height = 24px
Minimum vertical step = 12px
Spacing scale: 12 / 24 / 48CSS Implementation
:root {
--space-xs: 12px; /* 0.5 × line-height */
--space-sm: 24px; /* 1 × line-height */
--space-md: 48px; /* 2 × line-height */
--space-lg: 72px; /* 3 × line-height */
}Golden Rule
Spacing matters more than font size.
Two designs with the same fonts but different spacing will look like different products. Fix spacing before tweaking fonts.
---
8. Letter Spacing (Tracking)
Letter-spacing is one of the most overlooked properties in web typography. It's a polish detail that separates refined interfaces from rough ones.
Why It Matters
Professional typography isn't just about choosing fonts—it's about the space BETWEEN letters. This single property can make the difference between "looks off" and "looks polished."
Without proper tracking:
- ALL CAPS looks cramped and cheap
- Small text becomes harder to read
- Large headlines feel loose and unprofessional
- The entire interface lacks refinement
Quick Reference
| Text Type | Size | Value | Priority |
|---|---|---|---|
| Body text | 14–18px | 0 | Default OK |
| Small text | 11–13px | 0.01em – 0.02em | REQUIRED |
| UI labels/buttons | any | 0.01em – 0.03em | REQUIRED |
| ALL CAPS | any | 0.06em – 0.10em | MANDATORY |
| Large headings | 32px+ | 0 to -0.02em | Recommended |
| Display text | 48px+ | -0.02em to -0.03em | Recommended |
Units
Always use `em`, never `px`. Em scales with font size.
CSS Tokens
:root {
--tracking-tighter: -0.02em;
--tracking-tight: -0.01em;
--tracking-normal: 0em;
--tracking-wide: 0.015em;
--tracking-wider: 0.02em;
--tracking-widest: 0.08em; /* caps */
}ALL CAPS Rule
Uppercase text usually benefits from positive letter-spacing. Default behavior for UI text:
/* ❌ WRONG — cramped, amateur, unfinished */
.badge { text-transform: uppercase; }
/* ✅ RIGHT — polished, professional */
.badge {
text-transform: uppercase;
letter-spacing: 0.08em;
}Small Text Rule — Often Forgotten
Text below 14px needs extra tracking for readability:
/* ❌ WRONG — hard to read */
.caption { font-size: 12px; }
/* ✅ RIGHT — improved readability */
.caption {
font-size: 12px;
letter-spacing: 0.015em;
}When to Tighten
Only tighten (negative values) when:
- Size is 32px+
- It's a headline, not body
- Font weight isn't light
- Problem pairs (AV, WA, To) don't collide
Pre-Implementation Checklist
Before shipping any typography:
- [ ] ALL CAPS elements have
letter-spacing: 0.06em+ - [ ] Small text (11-13px) has positive tracking
- [ ] UI labels and buttons have tracking
- [ ] Large headings (32px+) have slight negative tracking
- [ ] You didn't just skip letter-spacing entirely
---
9. Line Length (Measure)
Optimal reading width prevents eye fatigue.
Guidelines
| Content | Characters | Pixels (~16px) |
|---|---|---|
| Optimal | 50–75 | 500–700px |
| Minimum | 45 | 450px |
| Maximum | 85 | 850px |
Implementation
/* Article content */
.prose {
max-width: 65ch; /* ~65 characters */
}
/* Compact UI */
.card-description {
max-width: 45ch;
}Anti-pattern: Full-width paragraphs on desktop. Unreadable above 100 characters.
---
10. Text Polish Details
Small details that separate amateur from professional. AI models often miss these.
Punctuation
| Wrong | Right | Rule |
|---|---|---|
... | … | Use proper ellipsis character (… or …) |
" " | " " | Use curly quotes, not straight quotes |
10 MB | 10 MB | Non-breaking space between number and unit |
⌘ K | ⌘ K | Non-breaking space in keyboard shortcuts |
Loading states: Always end with … → "Loading…", "Saving…", "Processing…"
Tabular Numbers
When displaying numbers that need to align (tables, prices, stats):
.price,
.table-cell-number,
.stats-value {
font-variant-numeric: tabular-nums;
}Why: Default proportional figures make 111 narrower than 999. Tabular figures give each digit equal width — essential for columns, counters, prices.
Text Wrapping for Headings
Prevent orphaned words and awkward final lines in important text. A single word on the last line of a hero title usually looks accidental, not designed.
h1, h2, h3,
.hero-title,
.card-title {
text-wrap: balance; /* Balance short headings/display text */
}
.lead,
.prose p {
text-wrap: pretty; /* Improve prose wrapping selectively */
}Use balance for short headings, captions, pull quotes, and card titles. Use pretty for lead/body prose when typography matters more than maximum performance. Do not apply either blindly to nav, buttons, tables, badges, code, form controls, or dense UI labels.
Still inspect the actual breakpoints. If wrapping is still awkward, adjust copy, max-width, font-size, or line-height instead of trusting CSS alone.
Browser support: Modern browsers. Graceful degradation — no harm if unsupported.
Content Overflow
Text containers must handle long content:
/* Truncate single line */
.truncate {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* Clamp to N lines */
.line-clamp-2 {
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
/* Break long words (URLs, emails) */
.break-words {
overflow-wrap: break-word;
word-break: break-word;
}Critical for flex layouts: Flex children need min-width: 0 to allow text truncation:
/* ❌ Text won't truncate */
.flex-child {
flex: 1;
}
/* ✅ Text truncates properly */
.flex-child {
flex: 1;
min-width: 0;
}---
11. Responsive Typography
Font size should respond to viewport, but not linearly.
Fluid Type (Clamp)
:root {
/* Min 16px, preferred 2vw, max 20px */
--text-base: clamp(1rem, 1.5vw + 0.5rem, 1.25rem);
/* Min 32px, scales with viewport, max 56px */
--text-hero: clamp(2rem, 5vw + 1rem, 3.5rem);
}Breakpoint Adjustments
:root {
--text-base: 16px;
--text-h1: 36px;
}
@media (min-width: 768px) {
:root {
--text-h1: 48px;
}
}
@media (min-width: 1200px) {
:root {
--text-h1: 56px;
}
}What Changes
| Property | Mobile → Desktop |
|---|---|
| Base font | 16px → 16-18px |
| H1 | 32-36px → 48-64px |
| Line height | Same or slightly less |
| Letter spacing | Same |
| Line length | Shorter → longer |
---
12. Performance Typography
Beautiful typography on a slow page is bad typography.
Requirements
/* Always use font-display: swap */
@font-face {
font-family: 'Inter';
font-display: swap;
src: url('/fonts/inter.woff2') format('woff2');
}Rules
- ≤2 font families — One is better
- ≤3 weights per family — 400, 500, 600 covers 95% of needs
- Variable fonts preferred — One file, all weights
- System stack is fine — Often better than custom fonts
System Font Stack
font-family: system-ui, -apple-system, BlinkMacSystemFont,
'Segoe UI', Roboto, 'Helvetica Neue', sans-serif;This loads instantly, looks native, and is perfectly professional.
Performance Rule
If typography is beautiful but the page loads slow — it's bad typography.
---
13. AI-Slop Anti-Patterns
Things that instantly reveal AI-generated or amateur design:
Instant Red Flags
- 10+ text sizes — Scale should have 6-8 max
- Gray text on gray background — Contrast failure
- Bold in body text — Flattens hierarchy
- Centered paragraphs — Only for short marketing copy
- Decorative display font without intent — Should serve brand or product personality, not just decoration
- ALL CAPS without letter-spacing — Always needs tracking
- Inconsistent spacing — Random gaps between elements
- Too many font weights — 400/500/600 is enough
Quick Test
Look at any interface and count: 1. How many distinct font sizes? (Should be ≤8) 2. How many text colors? (Should be ≤4) 3. How many font weights? (Should be ≤4)
More than these numbers = likely AI-slop or needs editing.
---
14. Hierarchy Checklist
Clear hierarchy guides the eye. Test by squinting.
Visual Weight Stack
1. Size — Biggest impact
2. Weight — Bold vs regular
3. Color — Dark vs gray vs muted
4. Case — Caps for labels
5. Spacing — Margins create grouping
6. Style — Italic for emphasis (rare)Hierarchy Test
1. Squint test — Can you see 3 clear levels? 2. 5-second test — What do users see first? 3. Scan test — Can you skim headings?
Anti-patterns
- Everything is bold → nothing is bold
- 10 different sizes → no clear scale
- Low contrast gray → invisible hierarchy
- Italic everywhere → meaningless emphasis
---
15. Pre-Ship Checklist
- [ ] Scale: Maximum 6-8 font sizes
- [ ] Fonts: Maximum 2 families (1 is better)
- [ ] Weights: 3-4 weights maximum (400, 500, 600)
- [ ] Body: 16px+, line-height 1.5+, max-width 65ch
- [ ] Text colors: 3-4 levels (primary, secondary, tertiary)
- [ ] Headlines: Tighter leading (1.1-1.2), optional negative tracking
- [ ] ALL CAPS: Has letter-spacing 0.06em+
- [ ] Small text: 11px minimum, has positive tracking
- [ ] Contrast: Passes WCAG AA (4.5:1 body, 3:1 large)
- [ ] Performance: font-display: swap, ≤3 weights loaded
- [ ] Spacing: Consistent vertical rhythm
- [ ] Responsive: Tested at 320px, 768px, 1440px
- [ ] Hierarchy: Passes squint test
- [ ] Punctuation:
…not..., curly quotes, non-breaking spaces - [ ] Numbers:
tabular-numsin tables/stats/prices - [ ] Headings:
text-wrap: balance; no awkward one-word final lines - [ ] Prose:
text-wrap: prettyonly where typographic quality matters - [ ] Overflow: Text containers handle long content (truncate/clamp/break)
---
Appendix: Complete Token System
Reference implementation with all tokens:
:root {
/* Font Families */
--font-body: 'Inter', system-ui, sans-serif;
--font-mono: 'JetBrains Mono', monospace;
/* Font Sizes (Minor Third scale) */
--text-xs: 0.6875rem; /* 11px */
--text-sm: 0.8125rem; /* 13px */
--text-base: 1rem; /* 16px */
--text-lg: 1.1875rem; /* 19px */
--text-xl: 1.4375rem; /* 23px */
--text-2xl: 1.75rem; /* 28px */
--text-3xl: 2.0625rem; /* 33px */
--text-4xl: 2.5rem; /* 40px */
/* Font Weights */
--font-normal: 400;
--font-medium: 500;
--font-semibold: 600;
/* Line Heights */
--leading-none: 1;
--leading-tight: 1.15;
--leading-snug: 1.3;
--leading-normal: 1.55;
--leading-relaxed: 1.7;
/* Letter Spacing */
--tracking-tight: -0.01em;
--tracking-normal: 0em;
--tracking-wide: 0.015em;
--tracking-caps: 0.08em;
/* Text Colors */
--text-primary: #0B0B0B;
--text-secondary: rgba(0,0,0,0.65);
--text-tertiary: rgba(0,0,0,0.45);
--text-disabled: rgba(0,0,0,0.3);
/* Spacing (based on 24px line-height) */
--space-xs: 12px;
--space-sm: 24px;
--space-md: 48px;
--space-lg: 72px;
}---
Typography is the voice of your interface. Simple, consistent, intentional.
Security Policy
Reporting a Vulnerability
If you discover a security issue, please report it by emailing support@refero.design rather than opening a public issue.
We will respond within 48 hours and work to address the issue promptly.
Related skills
How it compares
refero-design is a research-first UI skill using Refero styles, screens, flows, reference locks, and anti-AI-slop quality gates, not a generic alternative.
FAQ
Who is refero-design for?
Developers designing product UI who need research-backed direction from Refero or bundled craft references.
When should I use refero-design?
Before implementing any visual design, landing page, dashboard, or redesign requiring reference synthesis.
Is refero-design safe to install?
Review the Security Audits panel; Refero MCP requires Authorization Bearer token when configured.