mirror of
https://github.com/ngthanhvu/kr-phim.git
synced 2026-08-10 16:07:47 +00:00
562 lines
14 KiB
Markdown
562 lines
14 KiB
Markdown
# Distinctive Frontend Design
|
|
|
|
Create visually distinctive, high-impact frontend interfaces that avoid generic "AI slop" aesthetics. This skill applies the four-vector approach: typography, color/theme, motion, and backgrounds.
|
|
|
|
## Core Principles
|
|
|
|
**Avoid distributional convergence**: Reject default choices (Inter/Roboto fonts, purple gradients, minimal animations). Instead, make bold, cohesive design decisions that create memorable interfaces.
|
|
|
|
**Think in systems**: Use CSS variables, design tokens, and coordinated choices across all four dimensions rather than isolated tweaks.
|
|
|
|
## 1. Typography - Use Extremes
|
|
|
|
### Font Weight Strategy
|
|
- **Go to extremes**: Use 100-200 (thin) vs 800-900 (black), not safe 400 vs 600
|
|
- **Create hierarchy through weight contrast**, not just size
|
|
- **Example combinations**:
|
|
- Headers: 900 weight, body: 200 weight
|
|
- Headers: 100 weight (elegant), body: 500 weight
|
|
|
|
### Font Pairing
|
|
Avoid generic system fonts. Use distinctive pairings:
|
|
|
|
```css
|
|
/* Option 1: Geometric Sans + Monospace */
|
|
--font-display: 'Space Grotesk', sans-serif;
|
|
--font-body: 'Inter', sans-serif;
|
|
--font-mono: 'JetBrains Mono', monospace;
|
|
|
|
/* Option 2: Serif Display + Sans Body */
|
|
--font-display: 'Playfair Display', serif;
|
|
--font-body: 'Source Sans 3', sans-serif;
|
|
|
|
/* Option 3: Condensed + Wide */
|
|
--font-display: 'Bebas Neue', cursive;
|
|
--font-body: 'DM Sans', sans-serif;
|
|
|
|
/* Option 4: Variable Font Extremes */
|
|
--font-main: 'Recursive', sans-serif;
|
|
/* Then use font-weight: 300-1000 range */
|
|
```
|
|
|
|
### Implementation Pattern
|
|
|
|
```css
|
|
:root {
|
|
--font-display: 'Space Grotesk', sans-serif;
|
|
--font-body: 'Inter', sans-serif;
|
|
|
|
/* Use extreme weights */
|
|
--weight-thin: 100;
|
|
--weight-light: 200;
|
|
--weight-bold: 800;
|
|
--weight-black: 900;
|
|
}
|
|
|
|
h1, h2, h3 {
|
|
font-family: var(--font-display);
|
|
font-weight: var(--weight-black);
|
|
letter-spacing: -0.03em; /* Tight tracking for bold weights */
|
|
}
|
|
|
|
body, p {
|
|
font-family: var(--font-body);
|
|
font-weight: var(--weight-light);
|
|
letter-spacing: 0.01em; /* Slight tracking for readability */
|
|
}
|
|
```
|
|
|
|
## 2. Color & Theme - Commit to Cohesion
|
|
|
|
### Strategy
|
|
- **Draw from cultural references**: Movies, art movements, IDE themes, nature
|
|
- **Use CSS variables** for systematic color application
|
|
- **Avoid**: Safe blues/purples, low-contrast pastels
|
|
|
|
### Theme Examples
|
|
|
|
```css
|
|
/* Theme 1: Cyberpunk (Blade Runner inspired) */
|
|
:root {
|
|
--bg-primary: #0a0e27;
|
|
--bg-secondary: #1a1f3a;
|
|
--accent-1: #ff2e97; /* Hot pink */
|
|
--accent-2: #00d9ff; /* Cyan */
|
|
--accent-3: #ffd700; /* Gold */
|
|
--text-primary: #e4f1ff;
|
|
--text-secondary: #8b9dc3;
|
|
}
|
|
|
|
/* Theme 2: Brutalist (Raw concrete) */
|
|
:root {
|
|
--bg-primary: #f5f5f0;
|
|
--bg-secondary: #ffffff;
|
|
--accent-1: #ff0000;
|
|
--accent-2: #000000;
|
|
--text-primary: #1a1a1a;
|
|
--border: 3px solid #000000;
|
|
}
|
|
|
|
/* Theme 3: Vaporwave */
|
|
:root {
|
|
--bg-primary: #1a0033;
|
|
--bg-secondary: #2d1b4e;
|
|
--accent-1: #ff71ce; /* Pink */
|
|
--accent-2: #01cdfe; /* Cyan */
|
|
--accent-3: #b967ff; /* Purple */
|
|
--accent-4: #05ffa1; /* Mint */
|
|
--text-primary: #fffb96;
|
|
}
|
|
|
|
/* Theme 4: Nordic Minimalism */
|
|
:root {
|
|
--bg-primary: #2e3440;
|
|
--bg-secondary: #3b4252;
|
|
--accent-1: #88c0d0; /* Frost blue */
|
|
--accent-2: #bf616a; /* Aurora red */
|
|
--accent-3: #a3be8c; /* Aurora green */
|
|
--text-primary: #eceff4;
|
|
--text-secondary: #d8dee9;
|
|
}
|
|
```
|
|
|
|
### Application Pattern
|
|
|
|
```css
|
|
body {
|
|
background: var(--bg-primary);
|
|
color: var(--text-primary);
|
|
}
|
|
|
|
.card {
|
|
background: var(--bg-secondary);
|
|
border: 1px solid var(--accent-1);
|
|
}
|
|
|
|
.cta-button {
|
|
background: var(--accent-1);
|
|
color: var(--bg-primary);
|
|
}
|
|
|
|
.highlight {
|
|
color: var(--accent-2);
|
|
}
|
|
```
|
|
|
|
## 3. Motion - Orchestrated Page Load
|
|
|
|
### Strategy
|
|
- **Prioritize page-load choreography** over scattered micro-interactions
|
|
- **Use staggered reveals** to guide attention
|
|
- **Create entrance sequences** that feel intentional
|
|
|
|
### Implementation Patterns
|
|
|
|
```css
|
|
/* Base setup: Elements start invisible */
|
|
.fade-in {
|
|
opacity: 0;
|
|
animation: fadeInUp 0.8s cubic-bezier(0.16, 1, 0.3, 1) forwards;
|
|
}
|
|
|
|
/* Stagger delays */
|
|
.stagger-1 { animation-delay: 0.1s; }
|
|
.stagger-2 { animation-delay: 0.2s; }
|
|
.stagger-3 { animation-delay: 0.3s; }
|
|
.stagger-4 { animation-delay: 0.4s; }
|
|
.stagger-5 { animation-delay: 0.5s; }
|
|
|
|
/* Smooth easing curve */
|
|
@keyframes fadeInUp {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(30px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
|
|
/* Alternative: Slide from side */
|
|
@keyframes slideInRight {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateX(-40px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateX(0);
|
|
}
|
|
}
|
|
|
|
/* Scale entrance for hero elements */
|
|
@keyframes scaleIn {
|
|
from {
|
|
opacity: 0;
|
|
transform: scale(0.9);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: scale(1);
|
|
}
|
|
}
|
|
```
|
|
|
|
### React/JavaScript Pattern
|
|
|
|
```javascript
|
|
// Add classes progressively
|
|
useEffect(() => {
|
|
const elements = document.querySelectorAll('.animate-on-load');
|
|
elements.forEach((el, index) => {
|
|
el.classList.add('fade-in', `stagger-${index + 1}`);
|
|
});
|
|
}, []);
|
|
|
|
// Or use Framer Motion
|
|
import { motion } from 'framer-motion';
|
|
|
|
const container = {
|
|
hidden: { opacity: 0 },
|
|
show: {
|
|
opacity: 1,
|
|
transition: {
|
|
staggerChildren: 0.1
|
|
}
|
|
}
|
|
};
|
|
|
|
const item = {
|
|
hidden: { opacity: 0, y: 20 },
|
|
show: { opacity: 1, y: 0 }
|
|
};
|
|
|
|
<motion.div variants={container} initial="hidden" animate="show">
|
|
<motion.h1 variants={item}>Title</motion.h1>
|
|
<motion.p variants={item}>Subtitle</motion.p>
|
|
<motion.button variants={item}>CTA</motion.button>
|
|
</motion.div>
|
|
```
|
|
|
|
## 4. Backgrounds - Atmospheric Depth
|
|
|
|
### Strategy
|
|
- **Layer gradients and patterns** instead of flat colors
|
|
- **Create depth through overlays**
|
|
- **Use subtle noise/grain** for texture
|
|
|
|
### Gradient Patterns
|
|
|
|
```css
|
|
/* Radial gradient with multiple stops */
|
|
.gradient-bg-1 {
|
|
background: radial-gradient(
|
|
circle at 20% 50%,
|
|
rgba(255, 46, 151, 0.3) 0%,
|
|
rgba(0, 217, 255, 0.2) 50%,
|
|
rgba(10, 14, 39, 1) 100%
|
|
);
|
|
}
|
|
|
|
/* Angular gradient with hard stops */
|
|
.gradient-bg-2 {
|
|
background: linear-gradient(
|
|
135deg,
|
|
#667eea 0%,
|
|
#764ba2 25%,
|
|
#f093fb 50%,
|
|
#4facfe 100%
|
|
);
|
|
}
|
|
|
|
/* Mesh gradient (layered) */
|
|
.gradient-bg-3 {
|
|
background:
|
|
radial-gradient(at 0% 0%, rgba(255, 113, 206, 0.4) 0, transparent 50%),
|
|
radial-gradient(at 100% 0%, rgba(1, 205, 254, 0.4) 0, transparent 50%),
|
|
radial-gradient(at 100% 100%, rgba(185, 103, 255, 0.4) 0, transparent 50%),
|
|
radial-gradient(at 0% 100%, rgba(5, 255, 161, 0.4) 0, transparent 50%),
|
|
#1a0033;
|
|
}
|
|
|
|
/* Noise texture overlay */
|
|
.textured-bg {
|
|
background: var(--bg-primary);
|
|
position: relative;
|
|
}
|
|
|
|
.textured-bg::before {
|
|
content: '';
|
|
position: absolute;
|
|
inset: 0;
|
|
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 400 400' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E");
|
|
opacity: 0.05;
|
|
mix-blend-mode: overlay;
|
|
}
|
|
|
|
/* Grid pattern background */
|
|
.grid-bg {
|
|
background-image:
|
|
linear-gradient(rgba(255, 255, 255, 0.05) 1px, transparent 1px),
|
|
linear-gradient(90deg, rgba(255, 255, 255, 0.05) 1px, transparent 1px);
|
|
background-size: 50px 50px;
|
|
}
|
|
```
|
|
|
|
## Workflow: Building a Distinctive Interface
|
|
|
|
When creating a new frontend interface, follow this sequence:
|
|
|
|
### 1. Choose Your Aesthetic Reference
|
|
Pick a clear inspiration: "Cyberpunk movie UI", "Nordic minimalism", "90s brutalism", "Retro-futurism", etc.
|
|
|
|
### 2. Set Up Design Tokens
|
|
|
|
```css
|
|
:root {
|
|
/* Typography */
|
|
--font-display: [distinctive font];
|
|
--font-body: [complementary font];
|
|
--weight-thin: 100;
|
|
--weight-black: 900;
|
|
|
|
/* Colors (from chosen theme) */
|
|
--bg-primary: [dark base];
|
|
--bg-secondary: [slightly lighter];
|
|
--accent-1: [bold color 1];
|
|
--accent-2: [bold color 2];
|
|
--text-primary: [high contrast];
|
|
--text-secondary: [medium contrast];
|
|
|
|
/* Motion */
|
|
--ease-out: cubic-bezier(0.16, 1, 0.3, 1);
|
|
--duration-fast: 0.3s;
|
|
--duration-base: 0.6s;
|
|
--duration-slow: 0.9s;
|
|
|
|
/* Spacing */
|
|
--space-xs: 0.5rem;
|
|
--space-sm: 1rem;
|
|
--space-md: 2rem;
|
|
--space-lg: 4rem;
|
|
--space-xl: 8rem;
|
|
}
|
|
```
|
|
|
|
### 3. Apply All Four Dimensions
|
|
|
|
```html
|
|
<!-- Example: Hero section with all four dimensions -->
|
|
<div class="hero textured-bg gradient-bg-1">
|
|
<h1 class="fade-in stagger-1" style="font-family: var(--font-display); font-weight: var(--weight-black);">
|
|
Bold Headline
|
|
</h1>
|
|
<p class="fade-in stagger-2" style="font-family: var(--font-body); font-weight: var(--weight-light);">
|
|
Supporting text with extreme weight contrast
|
|
</p>
|
|
<button class="fade-in stagger-3 cta-button">
|
|
Call to Action
|
|
</button>
|
|
</div>
|
|
```
|
|
|
|
### 4. Test Against "AI Slop" Checklist
|
|
|
|
❌ Avoid:
|
|
- Inter or Roboto as primary font
|
|
- Font weights: 400, 500, 600 (too safe)
|
|
- Purple-blue gradient backgrounds
|
|
- No page-load animation
|
|
- Flat white/gray backgrounds
|
|
- Pastel low-contrast colors
|
|
|
|
✅ Aim for:
|
|
- Distinctive font pairing
|
|
- Extreme weight contrast (100-200 vs 800-900)
|
|
- Cohesive color theme with clear reference
|
|
- Orchestrated entrance animation
|
|
- Layered/textured backgrounds
|
|
- Bold, memorable aesthetic
|
|
|
|
## Examples by Use Case
|
|
|
|
### Landing Page
|
|
- **Typography**: Display font at 900 weight, body at 200
|
|
- **Color**: Cyberpunk or retro-futurism theme
|
|
- **Motion**: Staggered hero elements (0.1s delay each)
|
|
- **Background**: Mesh gradient + noise texture
|
|
|
|
### Dashboard
|
|
- **Typography**: Monospace for data, sans-serif at 800 for headers
|
|
- **Color**: Dark mode with 2-3 accent colors for status
|
|
- **Motion**: Slide-in sidebar, fade-in cards
|
|
- **Background**: Subtle grid pattern + dark gradient
|
|
|
|
### Marketing Site
|
|
- **Typography**: Serif display (Playfair) + sans body
|
|
- **Color**: High-contrast brutalist or vibrant vaporwave
|
|
- **Motion**: Scroll-triggered reveals + parallax
|
|
- **Background**: Bold gradients with geometric overlays
|
|
|
|
### Portfolio
|
|
- **Typography**: Variable font with weight range 300-900
|
|
- **Color**: Minimal with one bold accent
|
|
- **Motion**: Project cards stagger on load
|
|
- **Background**: Radial gradient + grain texture
|
|
|
|
## Implementation Tips
|
|
|
|
1. **Always include Google Fonts or font files** - Don't assume system fonts
|
|
2. **Use CSS custom properties** - Makes theming systematic
|
|
3. **Test motion on slower devices** - Reduce animation if `prefers-reduced-motion`
|
|
4. **Provide theme variations** - Light/dark mode using same token system
|
|
5. **Document your aesthetic reference** - Helps maintain consistency
|
|
|
|
## Quick Start Template
|
|
|
|
```html
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
|
<!-- Distinctive fonts -->
|
|
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@300;700;900&family=Inter:wght@200;500&display=swap" rel="stylesheet">
|
|
|
|
<style>
|
|
:root {
|
|
/* Typography */
|
|
--font-display: 'Space Grotesk', sans-serif;
|
|
--font-body: 'Inter', sans-serif;
|
|
--weight-light: 200;
|
|
--weight-bold: 700;
|
|
--weight-black: 900;
|
|
|
|
/* Cyberpunk theme */
|
|
--bg-primary: #0a0e27;
|
|
--bg-secondary: #1a1f3a;
|
|
--accent-1: #ff2e97;
|
|
--accent-2: #00d9ff;
|
|
--text-primary: #e4f1ff;
|
|
|
|
/* Motion */
|
|
--ease: cubic-bezier(0.16, 1, 0.3, 1);
|
|
}
|
|
|
|
* {
|
|
margin: 0;
|
|
padding: 0;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
body {
|
|
font-family: var(--font-body);
|
|
font-weight: var(--weight-light);
|
|
background: var(--bg-primary);
|
|
color: var(--text-primary);
|
|
min-height: 100vh;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
/* Layered gradient background */
|
|
body::before {
|
|
content: '';
|
|
position: fixed;
|
|
inset: 0;
|
|
background: radial-gradient(
|
|
circle at 20% 50%,
|
|
rgba(255, 46, 151, 0.2) 0%,
|
|
rgba(0, 217, 255, 0.1) 50%,
|
|
transparent 100%
|
|
);
|
|
z-index: -1;
|
|
}
|
|
|
|
h1 {
|
|
font-family: var(--font-display);
|
|
font-weight: var(--weight-black);
|
|
font-size: clamp(2rem, 8vw, 5rem);
|
|
letter-spacing: -0.03em;
|
|
margin-bottom: 1rem;
|
|
}
|
|
|
|
p {
|
|
font-size: clamp(1rem, 3vw, 1.25rem);
|
|
letter-spacing: 0.01em;
|
|
margin-bottom: 2rem;
|
|
opacity: 0.9;
|
|
}
|
|
|
|
.cta {
|
|
background: var(--accent-1);
|
|
color: var(--bg-primary);
|
|
font-family: var(--font-display);
|
|
font-weight: var(--weight-bold);
|
|
padding: 1rem 2rem;
|
|
border: none;
|
|
border-radius: 0.5rem;
|
|
font-size: 1.125rem;
|
|
cursor: pointer;
|
|
transition: transform 0.2s var(--ease);
|
|
}
|
|
|
|
.cta:hover {
|
|
transform: translateY(-2px);
|
|
}
|
|
|
|
/* Staggered animations */
|
|
.fade-in {
|
|
opacity: 0;
|
|
animation: fadeInUp 0.8s var(--ease) forwards;
|
|
}
|
|
|
|
.stagger-1 { animation-delay: 0.1s; }
|
|
.stagger-2 { animation-delay: 0.2s; }
|
|
.stagger-3 { animation-delay: 0.3s; }
|
|
|
|
@keyframes fadeInUp {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(30px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.fade-in {
|
|
animation: none;
|
|
opacity: 1;
|
|
}
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<main>
|
|
<h1 class="fade-in stagger-1">Distinctive Design</h1>
|
|
<p class="fade-in stagger-2">Bold typography, cohesive colors, orchestrated motion.</p>
|
|
<button class="cta fade-in stagger-3">Get Started</button>
|
|
</main>
|
|
</body>
|
|
</html>
|
|
```
|
|
|
|
---
|
|
|
|
## When to Use This Skill
|
|
|
|
Use this skill when:
|
|
- Building landing pages, marketing sites, or portfolios
|
|
- Creating dashboards or web applications where aesthetics matter
|
|
- The user asks for "modern", "distinctive", or "eye-catching" design
|
|
- You want to avoid generic-looking interfaces
|
|
- The project needs a strong visual identity
|
|
|
|
By following these patterns, you'll create interfaces that feel intentional, memorable, and distinctively non-generic.
|