top-design
Create award-winning, immersive web experiences at the level of Awwwards-featured agencies. Use when the user mentions "Awwwards quality", "make my site stunning", "scroll animations", "parallax storytelling", "cinematic web design", "portfolio site", or "brand experience". Also
Install
npx skills add https://github.com/wondelai/skills/tree/main/plugins/wondelai-skills/skills/top-design
claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install wondelai-skills@llmmart
git clone https://github.com/wondelai/skills.git
The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole wondelai/skills collection as a plugin from our marketplace. Git is the plain clone.
Skill manifest
Top-Design: Award-Winning Digital Experiences
Create websites and applications at the level of world-class digital agencies. This skill embodies the craft of studios that consistently win FWA, Awwwards, CSS Design Awards, and Webby Awards.
Core Principle
Every pixel is intentional -- nothing default, nothing accidental. The agencies you are emulating -- Locomotive, Studio Freight, AREA 17, Active Theory, Hello Monday -- share a common DNA: typography IS the design, motion creates emotion, white space is a weapon, and performance is non-negotiable (60fps or nothing).
The foundation: The gap between 8/10 and 10/10 is not skill -- it is intention. An 8/10 has good typography and smooth animations; a 10/10 has typography that makes you gasp and animations that tell stories. Every decision must answer: "Does this serve the experience, or is it just filling space?"
Scoring
Goal: 10/10. Rate any digital experience 0-10 using the rubric below -- a 10/10 would be featured on Awwwards. Always state the current score and the specific improvements needed to reach 10/10.
Scoring Rubric
| Score | Level | Description |
|---|---|---|
| 0-2 | Amateur | Default fonts, no hierarchy, generic layout, template feel |
| 3-4 | Basic | Decent typography, some hierarchy, but forgettable |
| 5-6 | Competent | Good fundamentals, clean execution, but lacks soul |
| 7-8 | Professional | Strong typography, intentional motion, clear POV |
| 9 | Exceptional | Signature moments, memorable details, near-flawless craft |
| 10 | World-class | Would win Awwwards SOTD, defines new standards |
Category Scoring (Each 0-10)
TYPOGRAPHY (Weight: 25%)
| Score | Criteria |
|---|---|
| 0-3 | System fonts, uniform scale, default tracking |
| 4-6 | Premium fonts, some scale contrast, basic hierarchy |
| 7-8 | Dramatic scale contrast (10:1+), perfect tracking, optical alignment |
| 9-10 | Typography IS the design -- gasping moments, custom/variable fonts, type as architecture |
VISUAL COMPOSITION (Weight: 25%)
| Score | Criteria |
|---|---|
| 0-3 | Centered everything, equal spacing, rigid grid, no tension |
| 4-6 | Some asymmetry, decent spacing rhythm, basic depth |
| 7-8 | Intentional grid breaks, layered elements, strong negative space |
| 9-10 | Magnetic compositions, unexpected scale shifts, elements that breathe and surprise |
MOTION & INTERACTION (Weight: 20%)
| Score | Criteria |
|---|---|
| 0-3 | No animation or default/linear motion |
| 4-6 | Basic transitions, some scroll effects |
| 7-8 | Custom easing, orchestrated reveals, purposeful parallax |
| 9-10 | Motion that tells stories, perfectly timed choreography, scroll feels invented |
COLOR & ATMOSPHERE (Weight: 15%)
| Score | Criteria |
|---|---|
| 0-3 | Random colors, pure black/white, no mood |
| 4-6 | Cohesive palette, some atmosphere |
| 7-8 | Colors feel owned, contextual shifts, intentional contrast |
| 9-10 | Colors feel invented for this project, atmosphere you can feel |
DETAILS & CRAFT (Weight: 15%)
| Score | Criteria |
|---|---|
| 0-3 | Default cursors, no hover states, generic everything |
| 4-6 | Basic hover states, some custom elements |
| 7-8 | Magnetic buttons, branded selection colors, custom cursor (if user-approved) |
| 9-10 | Every micro-detail considered -- focus states, loading, empty states, scroll indicators |
Quick Score Formula
Total = (Typography x 0.25) + (Composition x 0.25) + (Motion x 0.20) + (Color x 0.15) + (Details x 0.15)
The Seven Pillars of 10/10 Design
1. Typography as Architecture
Core concept: Typography is not decoration layered onto a design -- it IS the design. Your typeface, scale, and tracking dictate color mood, animation style, spacing rhythm, and overall personality.
Why it works: Dramatic scale contrast creates hierarchy that communicates even when blurred or seen from across the room. The tension between monumental display type and intimate body text is what makes people stop scrolling.
Key insights:
- Massive scale contrast is non-negotiable -- minimum 10:1 between display and body (e.g., 180px / 14px); viewport-filling type at the extreme
- Negative tracking on large type (-0.02em to -0.05em) tightens display into cohesive units; body needs generous line-height (1.5-1.7)
- Font selection defines tier -- premium foundries (Pangram Pangram, Dinamo, Grilli Type, Klim, Commercial Type) or quality Google alternatives (Space Grotesk, Instrument Serif, Fraunces); never Inter, Roboto, Arial, or system-ui for hero experiences
- Variable fonts enable weight animation on hover without layout shift
- Optical alignment beats mathematical alignment -- adjust visually, not just numerically
- Control every line break on headlines -- beautiful breaks require manual intervention at key breakpoints
Applications: viewport-filling display dropping hard to body (Locomotive hero); variable font with hover weight-animation (Studio Freight); serif/sans pairing at extreme scale contrast (AREA 17 editorial). Display = one statement, 3-7 words; body = 16-18px minimum, 45-75 character measure.
See references/typography.md when choosing typefaces or building the type scale -- named font pairings by style, full fluid clamp() and step-based scales, tracking/leading ladders, and font-subsetting/FOUT mechanics.
2. Layout & Composition
Core concept: Master the grid so you can break it with intention -- every violation should feel deliberate, not accidental. The rhythm of density and breathing room creates a reading experience that holds attention.
Why it works: White space is active design material that creates tension and controls pacing. Asymmetry generates visual energy that centered compositions cannot; elements that overlap or bleed with intention feel alive and confident.
Key insights:
- White space as a weapon -- amateurs fill every gap; 10/10 designers use emptiness to create tension that controls the eye
- Asymmetric balance creates interest -- offset elements from center, let images bleed beyond containers
- Unexpected scale shifts create rhythm -- alternate massive/intimate, dense/sparse for narrative pacing
- The grid paradox -- a strong underlying grid is what makes breaks meaningful; without it, breaks are chaos
Applications: offset title with bleeding imagery (margin-left: 8.33%; margin-right: -5vw); varied card sizes for intentional asymmetry (Locomotive showcases); overlapping elements for depth (Active Theory). Alternate full-width immersion with contained reading sections.
Ethical boundary: Layout experimentation must never compromise navigation clarity -- users must always know where they are and how to move forward.
See references/layout-systems.md when laying out sections or going responsive -- grid frameworks, breakpoint systems, and asymmetric/bleeding-element patterns.
3. Motion & Animation
Core concept: Every animation must answer "Why does this move?" The three laws of elite motion: purpose over decoration, custom curves (never linear), orchestration over isolation.
Why it works: Choreographed motion guides attention, communicates hierarchy, and creates emotional resonance. Custom easing curves give movement a physical quality default browser easing cannot achieve.
Key insights:
- Custom easing is mandatory --
ease,ease-in,ease-out,linearare banned; usecubic-bezier(0.16, 1, 0.3, 1)(expo out),cubic-bezier(0.25, 1, 0.5, 1)(quart out),cubic-bezier(0.87, 0, 0.13, 1)(expo in-out) - Page load follows a strict choreography -- structure (0-200ms), hero title words staggered (200-600ms), subtitle (400-800ms), navigation cascade (600-900ms), supporting elements (800-1200ms); reference holds the canonical per-element stagger values
- Animate in relationship, not isolation -- elements that move together feel cohesive and intentional
- 60fps is non-negotiable -- if an animation drops frames, simplify or remove it
Applications: choreographed staggered page-load reveal (Studio Freight); clip-path/mask image reveals on scroll-enter (AREA 17); hover weight-shifts and magnetic buttons (Dogstudio). Text lines slide up individually with stagger -- never fade in as a block; pages morph rather than cut.
Ethical boundary: Motion must never block interaction or cause motion sickness -- respect prefers-reduced-motion, keep all content accessible without animation, and justify anything longer than 1.2s.
See references/animation-patterns.md when implementing motion -- copy-pasteable scroll reveals, staggered load choreography, page transitions, and magnetic/hover micro-interactions with code.
4. Color & Contrast
Core concept: Color should feel invented for each project -- never pulled from a generic palette generator. Three approaches: monochromatic tension (95% one color, 5% accent), bold signature (own a combination), contextual shifting (palette responds to content).
Why it works: Color creates atmosphere before a single word is read. Pure black/white feel digital and lifeless; warm variants feel physical and considered. A restrained accent draws the eye exactly where intended.
Key insights:
- Never use pure black or pure white -- #0a0a0a and #fafaf9 have a physical quality that #000/#fff lack
- Build a functional hierarchy -- text-primary, text-secondary (60% opacity), text-tertiary (40%), surface, border (10%) for consistent depth
- One strong accent used sparingly (#ff4d00 or similar) beats a complex multi-color palette
- Contextual color shifts between sections create visual chapters
- Design the system for both light and dark contexts, not individual instances
Applications: monochromatic with signature accent (Locomotive: cream + black + orange spark); contextual shifting per case study (AREA 17); dark mode with one vibrant accent (Stripe: navy + purple). Drive everything from CSS custom properties (--color-dark/-light/-accent plus functional --color-text-primary/-surface); the accent appears only on CTAs, links, and single-detail moments.
See references/case-studies.md when you need a worked example of any pillar -- agency-by-agency breakdowns of real color systems, type treatments, and micro-interactions to reverse-engineer.
5. Scroll-Based Design
Core concept: Scroll is the web's primary interaction and should feel designed, not default. Treat scroll as a narrative device -- controlling pacing, creating reveals, building tension, delivering signature moments.
Why it works: Default scroll is mechanical and treats all content as equally important. When scroll position drives reveals and transitions, moving through content becomes participatory rather than passive.
Key insights:
- Smooth scroll is the foundation -- implement Lenis or Locomotive Scroll for the weighted, physical feel every award-winning site uses
- Parallax must be purposeful -- sparing, and only on decorative elements; never on text or critical content
- Pinned sections create storytelling beats -- lock a section while content transforms within it
- Horizontal scroll galleries need clear visual affordance
- Reveals should be progressive -- elements enter as they become visible, creating discovery
- Scroll velocity can modulate animation speed for a responsive feel
Applications: pinned hero with scroll-driven transformation (Apple deep-dives); horizontal scroll gallery with affordance (Studio Freight); scroll-driven animation sequences (Active Theory). Use IntersectionObserver for lightweight class toggling; reserve GSAP ScrollTrigger for complex multi-step sequences.
Ethical boundary: Scroll hijacking is hostile UX -- users must always be able to scroll at their own pace and reach all content.
See references/technical-stack.md to wire up smooth scroll (Lenis/Locomotive setup, library tradeoffs) and references/animation-patterns.md for pinning, horizontal galleries, and scroll-velocity sequences.
6. Performance & Loading
Core concept: Performance is a design constraint from day one, not an optimization step. A beautiful animation that drops frames or a stunning font that causes layout shift fails the craft test.
Why it works: Users perceive performance as quality -- instant load and fluid scroll feel premium regardless of visual complexity, while a stunning site that stutters feels broken.
Key insights:
- Subset and preload fonts -- only needed glyphs,
font-display: swaporoptional, preload critical files - Optimize images -- WebP/AVIF with fallbacks, responsive
srcset, lazy-load below the fold - GPU-accelerate animations -- only animate
transformandopacity; neverwidth,height,top,left, ormargin - CLS near zero -- reserve space for images, fonts, and dynamic content (
aspect-ratioon containers) - LCP under 2.5s -- optimize the critical rendering path for the hero
- Loading states are designed elements -- custom skeletons and progress indicators, not afterthoughts
Applications: subset/preload/swap fonts (<link rel="preload" as="font" crossorigin>); AVIF/WebP with responsive srcset (<picture> fallbacks); GPU-only animation (transform: translate3d() + opacity). Audit with Lighthouse targeting 90+; code-split and defer non-critical JS.
Ethical boundary: Fast-but-inaccessible is not a valid tradeoff -- never strip accessibility features or semantic HTML for speed.
See references/technical-stack.md when choosing libraries or hitting a perf budget -- the recommended stack and concrete font/image/animation optimization techniques.
7. Micro-Interactions
Core concept: Craft lives in the 1% most designers skip: branded selection colors, magnetic buttons, designed focus states, considered loading states, crafted error pages, correct micro-typography.
IMPORTANT: Custom cursors are OPT-IN only. Never replace the native cursor unless the user explicitly requests or confirms one -- misapplied custom cursors hurt usability and feel gimmicky. Always ask first.
Why it works: Micro-interactions signal that every pixel was considered. Individually subtle, collectively transformative -- users feel the care embedded in the experience.
Key insights:
- Custom cursor reflects brand personality, with variants on interactive elements (subject to the opt-in rule above)
- Branded
::selectioncolor that works on all backgrounds - Every link and card has a considered hover state -- scale, overlay, or meaningful transform
- Focus states are visible AND beautiful -- on-brand indicators that keyboard users can clearly see
- Loading, empty, 404, and error states are designed, helpful moments
- Micro-typography is correct -- smart quotes, en/em dashes, no orphans on headlines,
text-wrap: balanceon key text
Ethical boundary: Focus states must meet keyboard-visibility requirements even when styled on-brand, and error/empty/404 states must be genuinely helpful, not just decorative.
See references/animation-patterns.md for copy-pasteable magnetic-button, cursor, and ::selection/hover micro-interaction code.
Design Process
Work in this order -- the sequence is the discipline:
- Concept before code. Define four things first:
BRAND ESSENCE: What single word captures the soul?
VISUAL TENSION: What opposing forces create interest?
SIGNATURE MOMENT: What will people screenshot and share?
TECHNICAL AMBITION: What pushes the browser's limits?
- Design the signature moment first -- not the header. Every 10/10 project has at least one moment people stop and share (a never-seen hero animation, typography bold enough to BE the visual, a scroll sequence that tells a story). Pin it down by asking: what will people screenshot, describe to a colleague, try to reverse-engineer, and what makes it unmistakably THIS project?
- Choose the display typeface next -- it dictates the rest (Pillar 1).
- Prototype motion alongside visual design, not after -- motion is not polish (Pillar 3).
- Ship with restraint -- 3 things perfect beats 10 things mediocre. Cut ruthlessly.
Implementation Notes
- Conceptualize desktop-first, build mobile-first -- dream big, implement progressively
- Use project conventions -- if Tailwind 4+ and/or shadcn/ui are available, extend their design tokens and components as the foundation for 10/10 craft rather than fighting them
Common Mistakes
Each fix points to the pillar that defines the rule -- do not re-derive values here.
| Mistake | Why It Fails | Fix (see) |
|---|---|---|
| Inter, Roboto, Arial, or system-ui as primary typeface | Application fonts signal generic, not premium | Premium foundry or quality Google alternative (Pillar 1) |
| Uniform type scale (everything within 2x) | No hierarchy, no gasping moments | Hit the display-to-body ratio (Pillar 1) |
ease, ease-in, ease-out, or linear easing |
Mechanical, lifeless -- instantly signals amateur | Banned -- use a custom cubic-bezier (Pillar 3) |
| Animating everything simultaneously | Visual noise, no hierarchy or narrative | Stagger and sequence by importance (Pillar 3) |
| Center-aligning everything | Safe but boring -- no tension or energy | Asymmetry, grid offsets, bleeding elements (Pillar 2) |
| Equal spacing everywhere | Monotony -- the eye has nowhere to rest | Vary density: dense sections, then breathing room (Pillar 2) |
| Pure #000000 / #ffffff | Lifeless and harsh | Warm variants (Pillar 4) |
| Default browser scroll | Mechanical, treats all content equally | Smooth-scroll library (Pillar 5) |
| Purple-to-blue gradient hero | The "AI gradient" -- generic trend-following | Signature color approach specific to the project (Pillar 4) |
| No signature moment | Competent but forgettable | Design the screenshot-worthy moment FIRST (Process step 2) |
| Any emoji in professional interfaces | Signals casual/amateur craft | Custom iconography or typographic treatments |
| Parallax on text or critical content | Motion sickness, accessibility failures | Parallax only on decorative background elements (Pillar 5) |
| Animations blocking interaction | Hostile UX | Keep all animation non-blocking (Pillar 3) |
| Unmodified Font Awesome icons | Template-level design | Custom icons, or heavily customize to match brand |
| Default form styles | Breaks the illusion of craft instantly | Design every input, select, checkbox, and button (Pillar 7) |
Quick Diagnostic
Score 1 point per row answered "yes", then map the count to the Scoring Rubric band: 11-12 -> 9-10, 8-10 -> 7-8, 5-7 -> 5-6, below 5 -> 0-4. State that score.
| Question | If No | Fix (see) |
|---|---|---|
| Does the hero typography make someone pause mid-scroll? | Display type not commanding | Pillar 1 -- scale, distinctive typeface, viewport-filling |
| Would someone screenshot any section? | No signature moment | Process step 2 -- make one section extraordinary |
| Does the design still read when you blur your eyes? | Hierarchy too flat | Bigger headlines, more white space, stronger accents |
Are all easing curves custom (no ease/linear)? |
Motion feels default | Pillar 3 -- custom cubic-bezier |
| Is there asymmetric tension in the composition? | Layout feels safe | Pillar 2 -- offset, bleed, vary density |
| Do the colors feel invented for THIS project? | Generic palette | Pillar 4 -- monochromatic tension, signature, or contextual |
| Is the page load choreographed? | Elements pop in at once | Pillar 3 -- staggered reveal sequence |
| Does scroll feel custom and weighted? | Default browser scroll | Pillar 5 -- smooth-scroll library |
| Are micro-details considered (selection, focus, cursor)? | Default browser behaviors remain | Pillar 7 -- branded selection, designed focus (cursors opt-in) |
| Is CLS near zero and LCP under 2.5s? | Performance undermines quality | Pillar 6 -- subset fonts, WebP/AVIF, transform/opacity only |
| Does every animation answer "why does this move?" | Decorative motion | Pillar 3 -- cut motion with no narrative or guidance |
| Are focus states both beautiful AND accessible? | One sacrificed for the other | Pillar 7 -- on-brand indicators meeting WCAG visibility |
Further Reading
- Designing with Type by James Craig -- foundational text on typographic principles and hierarchy
- Grid Systems in Graphic Design by Josef Muller-Brockmann -- the definitive work on grid-based composition
- The Elements of Typographic Style by Robert Bringhurst -- the typographer's bible on rhythm, proportion, and craft
- Interaction of Color by Josef Albers -- essential reading on color perception and contrast
- Layout Essentials: 100 Design Principles for Using Grids by Beth Tondreau -- practical grid-based layout principles
- Awwwards Annual: The Best 365 Websites Around the World -- yearly benchmark collection for 10/10 craft
About the Author
This skill synthesizes techniques from the world's most awarded digital agencies: Locomotive (Montreal -- creators of Locomotive Scroll, masters of monochromatic tension and bold typography), Studio Freight (New York -- magnetic interactions and signature palettes), AREA 17 (New York/Paris -- contextual design systems and editorial layouts), Active Theory (Los Angeles -- WebGL and immersive 3D storytelling), and Hello Monday (Copenhagen/New York -- playful interactions for Spotify, Adidas, Google). Additional inspiration from Dogstudio, Tonik, Instrument, Resn, and the broader Awwwards, FWA, CSS Design Awards, and Webby winner community.
Files (skills)
-
references
-
animation-patterns.md 14.1 KB
# Animation Patterns Reference ## Table of Contents 1. Easing Functions 2. Page Load Sequences 3. Scroll-Triggered Animations 4. Micro-Interactions 5. Page Transitions 6. Text Animations 7. Performance Optimization --- ## 1. Easing Functions ### CSS Custom Easings (Agency Standards) ```css :root { /* Smooth exits - most common for UI */ --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1); --ease-out-quart: cubic-bezier(0.25, 1, 0.5, 1); --ease-out-quint: cubic-bezier(0.22, 1, 0.36, 1); --ease-out-circ: cubic-bezier(0, 0.55, 0.45, 1); /* Dramatic entrances */ --ease-in-expo: cubic-bezier(0.7, 0, 0.84, 0); --ease-in-quart: cubic-bezier(0.5, 0, 0.75, 0); /* Symmetric - for toggles, loops */ --ease-in-out-quint: cubic-bezier(0.83, 0, 0.17, 1); --ease-in-out-expo: cubic-bezier(0.87, 0, 0.13, 1); /* Bouncy/Elastic */ --ease-out-back: cubic-bezier(0.34, 1.56, 0.64, 1); --ease-out-elastic: cubic-bezier(0.68, -0.6, 0.32, 1.6); /* Duration standards */ --duration-fast: 150ms; --duration-normal: 300ms; --duration-slow: 500ms; --duration-slower: 800ms; --duration-slowest: 1200ms; } ``` ### GSAP Equivalent ```javascript // Common GSAP easings gsap.to(element, { duration: 1, ease: "expo.out" // Most used for reveals }); gsap.to(element, { duration: 0.8, ease: "power4.out" // Slightly faster settle }); gsap.to(element, { duration: 1.2, ease: "power2.inOut" // Symmetric movement }); // Custom ease (Locomotive-style) gsap.registerPlugin(CustomEase); CustomEase.create("smooth", "0.16, 1, 0.3, 1"); ``` --- ## 2. Page Load Sequences ### Staggered Reveal Pattern ```css /* CSS-only staggered reveal */ .reveal-item { opacity: 0; transform: translateY(60px); animation: revealUp 0.8s var(--ease-out-expo) forwards; } .reveal-item:nth-child(1) { animation-delay: 0.1s; } .reveal-item:nth-child(2) { animation-delay: 0.2s; } .reveal-item:nth-child(3) { animation-delay: 0.3s; } .reveal-item:nth-child(4) { animation-delay: 0.4s; } @keyframes revealUp { to { opacity: 1; transform: translateY(0); } } ``` ### GSAP Page Load ```javascript // Orchestrated page load const tl = gsap.timeline({ defaults: { ease: "expo.out" } }); tl.set(".page-content", { visibility: "visible" }) .from(".hero-title .word", { y: 120, opacity: 0, duration: 1.2, stagger: 0.1 }) .from(".hero-subtitle", { y: 40, opacity: 0, duration: 0.8 }, "-=0.6") .from(".hero-cta", { y: 30, opacity: 0, duration: 0.6 }, "-=0.4") .from(".nav-item", { y: -20, opacity: 0, duration: 0.5, stagger: 0.05 }, "-=0.8"); ``` ### Split Text Animation ```javascript // Using GSAP SplitText or custom splitting import { SplitText } from "gsap/SplitText"; const split = new SplitText(".hero-title", { type: "words,chars", wordsClass: "word", charsClass: "char" }); gsap.from(split.chars, { y: 100, opacity: 0, duration: 0.8, ease: "expo.out", stagger: 0.02 }); // CSS approach (manual splitting) /* HTML: <span class="char">H</span><span class="char">e</span>... */ .char { display: inline-block; opacity: 0; transform: translateY(100%); animation: charReveal 0.6s var(--ease-out-expo) forwards; } .char:nth-child(1) { animation-delay: calc(0.03s * 1); } .char:nth-child(2) { animation-delay: calc(0.03s * 2); } /* ... generate with CSS custom properties or JS */ ``` --- ## 3. Scroll-Triggered Animations ### Intersection Observer (Vanilla) ```javascript // Reusable scroll reveal const observerOptions = { root: null, rootMargin: '0px 0px -100px 0px', threshold: 0.1 }; const revealOnScroll = (entries, observer) => { entries.forEach(entry => { if (entry.isIntersecting) { entry.target.classList.add('is-visible'); observer.unobserve(entry.target); } }); }; const observer = new IntersectionObserver(revealOnScroll, observerOptions); document.querySelectorAll('[data-reveal]').forEach(el => { observer.observe(el); }); ``` ```css /* Accompanying CSS */ [data-reveal] { opacity: 0; transform: translateY(60px); transition: opacity 0.8s var(--ease-out-expo), transform 0.8s var(--ease-out-expo); } [data-reveal].is-visible { opacity: 1; transform: translateY(0); } /* Stagger children */ [data-reveal="stagger"] > * { opacity: 0; transform: translateY(40px); transition: opacity 0.6s var(--ease-out-expo), transform 0.6s var(--ease-out-expo); } [data-reveal="stagger"].is-visible > *:nth-child(1) { transition-delay: 0.1s; } [data-reveal="stagger"].is-visible > *:nth-child(2) { transition-delay: 0.2s; } [data-reveal="stagger"].is-visible > *:nth-child(3) { transition-delay: 0.3s; } [data-reveal="stagger"].is-visible > * { opacity: 1; transform: translateY(0); } ``` ### GSAP ScrollTrigger ```javascript import { gsap } from "gsap"; import { ScrollTrigger } from "gsap/ScrollTrigger"; gsap.registerPlugin(ScrollTrigger); // Fade up on scroll gsap.utils.toArray('.reveal').forEach(el => { gsap.from(el, { y: 60, opacity: 0, duration: 1, ease: "expo.out", scrollTrigger: { trigger: el, start: "top 85%", toggleActions: "play none none none" } }); }); // Parallax effect gsap.to('.parallax-bg', { yPercent: -30, ease: "none", scrollTrigger: { trigger: '.parallax-section', start: "top bottom", end: "bottom top", scrub: true } }); // Horizontal scroll section gsap.to('.horizontal-panels', { xPercent: -100 * (panels.length - 1), ease: "none", scrollTrigger: { trigger: '.horizontal-container', pin: true, scrub: 1, end: () => "+=" + document.querySelector('.horizontal-panels').offsetWidth } }); // Pin and reveal gsap.timeline({ scrollTrigger: { trigger: '.pinned-section', start: "top top", end: "+=200%", pin: true, scrub: 1 } }) .from('.pinned-title', { opacity: 0, y: 100 }) .from('.pinned-content', { opacity: 0, y: 50 }, 0.3); ``` ### Lenis Smooth Scroll + GSAP ```javascript import Lenis from '@studio-freight/lenis'; import { gsap } from 'gsap'; import { ScrollTrigger } from 'gsap/ScrollTrigger'; // Initialize Lenis const lenis = new Lenis({ duration: 1.2, easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)), direction: 'vertical', smooth: true, }); // Connect Lenis to GSAP ScrollTrigger lenis.on('scroll', ScrollTrigger.update); gsap.ticker.add((time) => { lenis.raf(time * 1000); }); gsap.ticker.lagSmoothing(0); ``` --- ## 4. Micro-Interactions ### Button Hover States ```css /* Magnetic button effect */ .magnetic-btn { position: relative; transition: transform 0.3s var(--ease-out-expo); } /* JS handles the magnetic effect, CSS handles the visual */ .magnetic-btn::before { content: ''; position: absolute; inset: 0; background: var(--color-accent); transform: scaleX(0); transform-origin: right; transition: transform 0.5s var(--ease-out-expo); } .magnetic-btn:hover::before { transform: scaleX(1); transform-origin: left; } /* Text slide effect */ .text-slide-btn { overflow: hidden; position: relative; } .text-slide-btn span { display: block; transition: transform 0.5s var(--ease-out-expo); } .text-slide-btn span::after { content: attr(data-text); position: absolute; top: 100%; left: 0; } .text-slide-btn:hover span { transform: translateY(-100%); } ``` ```javascript // Magnetic button JS document.querySelectorAll('.magnetic-btn').forEach(btn => { btn.addEventListener('mousemove', (e) => { const rect = btn.getBoundingClientRect(); const x = e.clientX - rect.left - rect.width / 2; const y = e.clientY - rect.top - rect.height / 2; gsap.to(btn, { x: x * 0.3, y: y * 0.3, duration: 0.3, ease: "power2.out" }); }); btn.addEventListener('mouseleave', () => { gsap.to(btn, { x: 0, y: 0, duration: 0.5, ease: "elastic.out(1, 0.5)" }); }); }); ``` ### Link Underline Animations ```css /* Slide in underline */ .link-underline { position: relative; } .link-underline::after { content: ''; position: absolute; bottom: 0; left: 0; width: 100%; height: 1px; background: currentColor; transform: scaleX(0); transform-origin: right; transition: transform 0.4s var(--ease-out-expo); } .link-underline:hover::after { transform: scaleX(1); transform-origin: left; } /* Draw underline */ .link-draw { background-image: linear-gradient(currentColor, currentColor); background-position: 0 100%; background-repeat: no-repeat; background-size: 0% 1px; transition: background-size 0.4s var(--ease-out-expo); } .link-draw:hover { background-size: 100% 1px; } ``` ### Card Hover Effects ```css /* 3D tilt card */ .tilt-card { transform-style: preserve-3d; transition: transform 0.5s var(--ease-out-expo); } .tilt-card:hover { transform: perspective(1000px) rotateX(5deg) rotateY(-5deg); } .tilt-card::before { content: ''; position: absolute; inset: 0; background: linear-gradient( 135deg, rgba(255,255,255,0.1) 0%, transparent 50% ); opacity: 0; transition: opacity 0.3s; } .tilt-card:hover::before { opacity: 1; } ``` --- ## 5. Page Transitions ### Basic Fade Transition ```javascript // Using Barba.js import barba from '@barba/core'; barba.init({ transitions: [{ name: 'fade', leave(data) { return gsap.to(data.current.container, { opacity: 0, duration: 0.5, ease: "power2.inOut" }); }, enter(data) { return gsap.from(data.next.container, { opacity: 0, duration: 0.5, ease: "power2.inOut" }); } }] }); ``` ### Overlay Wipe Transition ```javascript // Wipe transition with overlay barba.init({ transitions: [{ name: 'wipe', leave(data) { const tl = gsap.timeline(); tl.to('.transition-overlay', { scaleY: 1, transformOrigin: 'bottom', duration: 0.6, ease: "expo.inOut" }) .to(data.current.container, { opacity: 0, duration: 0.3 }, 0.3); return tl; }, enter(data) { const tl = gsap.timeline(); tl.set(data.next.container, { opacity: 1 }) .to('.transition-overlay', { scaleY: 0, transformOrigin: 'top', duration: 0.6, ease: "expo.inOut" }) .from('[data-reveal]', { y: 60, opacity: 0, stagger: 0.1, duration: 0.8, ease: "expo.out" }, 0.2); return tl; } }] }); ``` --- ## 6. Text Animations ### Word-by-Word Reveal ```javascript // Split and animate function animateText(element) { const text = element.textContent; const words = text.split(' '); element.innerHTML = words.map(word => `<span class="word-wrapper"><span class="word">${word}</span></span>` ).join(' '); gsap.from(element.querySelectorAll('.word'), { y: '100%', duration: 0.8, ease: "expo.out", stagger: 0.05 }); } ``` ### Scramble/Decode Effect ```javascript // Text scramble effect class TextScramble { constructor(el) { this.el = el; this.chars = '!<>-_\\/[]{}—=+*^?#________'; this.update = this.update.bind(this); } setText(newText) { const oldText = this.el.innerText; const length = Math.max(oldText.length, newText.length); const promise = new Promise(resolve => this.resolve = resolve); this.queue = []; for (let i = 0; i < length; i++) { const from = oldText[i] || ''; const to = newText[i] || ''; const start = Math.floor(Math.random() * 40); const end = start + Math.floor(Math.random() * 40); this.queue.push({ from, to, start, end }); } cancelAnimationFrame(this.frameRequest); this.frame = 0; this.update(); return promise; } update() { let output = ''; let complete = 0; for (let i = 0; i < this.queue.length; i++) { let { from, to, start, end, char } = this.queue[i]; if (this.frame >= end) { complete++; output += to; } else if (this.frame >= start) { if (!char || Math.random() < 0.28) { char = this.chars[Math.floor(Math.random() * this.chars.length)]; this.queue[i].char = char; } output += char; } else { output += from; } } this.el.innerText = output; if (complete === this.queue.length) { this.resolve(); } else { this.frameRequest = requestAnimationFrame(this.update); this.frame++; } } } ``` --- ## 7. Performance Optimization ### GPU-Accelerated Properties ```css /* ONLY animate these for 60fps */ .performant-animation { /* Good - GPU accelerated */ transform: translateX(100px); transform: translateY(100px); transform: scale(1.2); transform: rotate(45deg); opacity: 0.5; /* Bad - triggers layout/paint */ /* left: 100px; */ /* top: 100px; */ /* width: 200px; */ /* height: 200px; */ /* margin: 20px; */ /* padding: 20px; */ } /* Force GPU layer */ .will-animate { will-change: transform, opacity; transform: translateZ(0); } /* Remove will-change after animation */ .animation-complete { will-change: auto; } ``` ### Reduce Motion Support ```css @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; scroll-behavior: auto !important; } } ``` ```javascript // JS check for reduced motion const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)'); if (prefersReducedMotion.matches) { // Skip or simplify animations gsap.globalTimeline.timeScale(10); // Or skip entirely } ``` ### Lazy Animation Loading ```javascript // Only initialize animations when needed const animationObserver = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { initHeavyAnimation(entry.target); animationObserver.unobserve(entry.target); } }); }, { rootMargin: '200px' }); document.querySelectorAll('[data-heavy-animation]').forEach(el => { animationObserver.observe(el); }); ``` -
case-studies.md 12.1 KB
# Case Studies: Agency Technique Analysis ## Table of Contents 1. Locomotive (Montreal) 2. Studio Freight (New York) 3. AREA 17 (Paris/NYC) 4. Hello Monday (Copenhagen/NYC) 5. Dogstudio (Belgium/Chicago) 6. Tonik (Poland) 7. Instrument (Portland) 8. Active Theory (LA) 9. Common Patterns Across Elite Agencies --- ## 1. Locomotive (Montreal) **Signature: Smooth, refined, editorial precision** ### Technical Fingerprint ``` STACK ├── Custom scroll (Locomotive Scroll - they created it) ├── GSAP for animations ├── Custom vanilla JS ├── No heavy frameworks └── Hand-crafted CSS SIGNATURE TECHNIQUES ├── Extreme smooth scrolling with lerp ├── Parallax on almost everything (but subtle) ├── Split text animations on every headline ├── Magnetic cursor effects ├── Scale-up reveals on scroll ``` ### Design Patterns ```css /* Locomotive-style color palette */ :root { --loco-cream: #f5f2eb; --loco-black: #1a1a1a; --loco-accent: #ff5c00; } /* Their characteristic wide spacing */ .loco-section { padding: 20vh 0; } /* Massive display type */ .loco-hero-title { font-size: clamp(4rem, 15vw, 18rem); font-weight: 500; letter-spacing: -0.04em; line-height: 0.85; } ``` ### Animation Style ```javascript // Locomotive-style page reveal gsap.timeline() .from(".hero-title .word", { y: "110%", duration: 1.4, ease: "expo.out", stagger: 0.08 }) .from(".hero-meta", { opacity: 0, y: 30, duration: 0.8, ease: "expo.out" }, "-=0.8"); ``` --- ## 2. Studio Freight (New York) **Signature: Bold, typographic, tech-forward** ### Technical Fingerprint ``` STACK ├── Lenis (they created it) ├── React/Next.js ├── GSAP with custom easings ├── Three.js for 3D elements ├── Heavy WebGL use SIGNATURE TECHNIQUES ├── Massive typography as hero ├── Shader-based transitions ├── Horizontal scroll sections ├── Custom cursor interactions ├── Grid-breaking layouts ``` ### Design Patterns ```css /* Studio Freight aesthetic */ :root { --sf-black: #0e0e0e; --sf-white: #f8f8f8; --sf-rust: #c4553d; } /* Their bold type treatment */ .sf-headline { font-family: 'Monument Extended', sans-serif; font-size: clamp(3rem, 12vw, 14rem); font-weight: 800; text-transform: uppercase; letter-spacing: -0.03em; } /* Characteristic list styling */ .sf-list { font-family: 'Neue Montreal', sans-serif; font-size: 1rem; letter-spacing: 0.02em; } .sf-list li { padding: 1rem 0; border-bottom: 1px solid rgba(255,255,255,0.1); } .sf-list li::before { content: '→'; margin-right: 0.5rem; } ``` ### Their Project Card Style ```css .sf-project-card { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; padding: 2rem; background: var(--sf-black); transition: transform 0.6s cubic-bezier(0.16, 1, 0.3, 1); } .sf-project-card:hover { transform: scale(0.98); } .sf-project-card img { transition: transform 0.8s cubic-bezier(0.16, 1, 0.3, 1); } .sf-project-card:hover img { transform: scale(1.05); } ``` --- ## 3. AREA 17 (Paris/NYC) **Signature: Sophisticated, institutional, systematic** ### Technical Fingerprint ``` STACK ├── Twill (their CMS) ├── Vue.js preference ├── GSAP for animations ├── Custom design systems └── Enterprise-grade infrastructure SIGNATURE TECHNIQUES ├── Restrained animations ├── Perfect typography ├── Systematic color application ├── Accessibility-first ├── Content-driven layouts ``` ### Design Patterns ```css /* AREA 17 systematic approach */ :root { /* They use client's brand colors systematically */ --brand-primary: currentColor; --text-primary: #1a1a1a; --text-secondary: #666666; --surface: #ffffff; --border: #e5e5e5; } /* Their grid is always precise */ .a17-grid { display: grid; grid-template-columns: repeat(12, 1fr); gap: 2rem; max-width: 1440px; margin: 0 auto; padding: 0 4rem; } /* Typography hierarchy */ .a17-h1 { font-size: clamp(2.5rem, 5vw, 4rem); font-weight: 400; line-height: 1.1; letter-spacing: -0.02em; } .a17-body { font-size: 1.125rem; line-height: 1.6; max-width: 65ch; } ``` ### Animation Philosophy ```javascript // AREA 17 - restrained, purposeful // They rarely use flashy effects // Simple fade up on scroll gsap.utils.toArray('[data-reveal]').forEach(el => { gsap.from(el, { y: 40, opacity: 0, duration: 0.8, ease: "power2.out", scrollTrigger: { trigger: el, start: "top 85%" } }); }); // No stagger, no split text, just clean reveals ``` --- ## 4. Hello Monday (Copenhagen/NYC) **Signature: Playful, inventive, technically ambitious** ### Technical Fingerprint ``` STACK ├── React/Next.js ├── Three.js / WebGL heavy ├── GSAP + custom physics ├── Pixel-perfect craft └── Experimental approaches SIGNATURE TECHNIQUES ├── Custom physics simulations ├── Interactive 3D scenes ├── Particle systems ├── Sound design integration ├── Gamification elements ``` ### Design Philosophy ```css /* Hello Monday embraces bold experiments */ .hm-experimental { /* They're not afraid of: */ mix-blend-mode: difference; cursor: none; /* Custom cursor always */ /* Complex gradients */ background: radial-gradient(ellipse at 20% 80%, rgba(255,100,100,0.3) 0%, transparent 50%), radial-gradient(ellipse at 80% 20%, rgba(100,100,255,0.3) 0%, transparent 50%), linear-gradient(180deg, #0a0a0a, #1a1a2e); } /* Their type tends toward expressive */ .hm-display { font-family: 'Custom Variable Font', sans-serif; font-variation-settings: 'wght' 800, 'wdth' 125; font-size: clamp(4rem, 20vw, 20rem); } ``` ### Interactive Pattern ```javascript // Hello Monday-style interactive element class InteractiveScene { constructor() { this.mouse = { x: 0, y: 0 }; this.targetMouse = { x: 0, y: 0 }; this.lerp = 0.1; window.addEventListener('mousemove', this.onMouseMove.bind(this)); this.animate(); } onMouseMove(e) { this.targetMouse.x = (e.clientX / window.innerWidth) * 2 - 1; this.targetMouse.y = -(e.clientY / window.innerHeight) * 2 + 1; } animate() { // Smooth interpolation this.mouse.x += (this.targetMouse.x - this.mouse.x) * this.lerp; this.mouse.y += (this.targetMouse.y - this.mouse.y) * this.lerp; // Apply to 3D scene, particles, etc. requestAnimationFrame(this.animate.bind(this)); } } ``` --- ## 5. Dogstudio (Belgium/Chicago) **Signature: Emotional, immersive, story-driven** ### Technical Fingerprint ``` STACK ├── Custom solutions ├── WebGL for immersive experiences ├── GSAP animation ├── Video integration └── Performance-optimized SIGNATURE TECHNIQUES ├── Cinematic page transitions ├── Full-screen video backgrounds ├── Scroll-based storytelling ├── Sound + visual harmony ├── Cultural institution specialization ``` ### Design Patterns ```css /* Dogstudio immersive approach */ .ds-immersive-section { position: relative; height: 100vh; overflow: hidden; } .ds-video-bg { position: absolute; inset: 0; object-fit: cover; width: 100%; height: 100%; } .ds-content-overlay { position: relative; z-index: 1; display: flex; flex-direction: column; justify-content: flex-end; height: 100%; padding: 4rem; background: linear-gradient( to top, rgba(0,0,0,0.8) 0%, transparent 50% ); } /* Their navigation is often minimal */ .ds-nav { position: fixed; top: 2rem; left: 2rem; right: 2rem; display: flex; justify-content: space-between; mix-blend-mode: difference; color: white; z-index: 100; } ``` --- ## 6. Tonik (Poland) **Signature: Startup-focused, fast, modern** ### Technical Fingerprint ``` STACK ├── Webflow / Framer (no-code speed) ├── React for complex apps ├── Figma-first workflow ├── Rapid iteration └── SaaS specialization SIGNATURE TECHNIQUES ├── Bold gradient usage ├── 3D elements via Spline ├── Micro-animations everywhere ├── Dark mode preference ├── Tech startup aesthetic ``` ### Design Patterns ```css /* Tonik startup aesthetic */ :root { --tonik-bg: #0a0a0a; --tonik-surface: #141414; --tonik-border: rgba(255,255,255,0.1); --tonik-accent: linear-gradient(135deg, #6366f1, #8b5cf6); } .tonik-card { background: var(--tonik-surface); border: 1px solid var(--tonik-border); border-radius: 1rem; padding: 2rem; transition: all 0.3s ease; } .tonik-card:hover { border-color: rgba(99, 102, 241, 0.5); transform: translateY(-4px); } .tonik-gradient-text { background: var(--tonik-accent); -webkit-background-clip: text; -webkit-text-fill-color: transparent; } /* Their button style */ .tonik-btn { background: var(--tonik-accent); color: white; padding: 1rem 2rem; border-radius: 9999px; font-weight: 500; transition: transform 0.2s, box-shadow 0.2s; } .tonik-btn:hover { transform: scale(1.02); box-shadow: 0 10px 40px rgba(99, 102, 241, 0.3); } ``` --- ## 7. Instrument (Portland) **Signature: Brand-centric, polished, scalable** ### Technical Fingerprint ``` STACK ├── Enterprise frameworks ├── Design system focus ├── Accessibility-first ├── Performance optimized └── Long-term maintenance SIGNATURE TECHNIQUES ├── Brand system extension ├── Motion design language ├── Component-based design ├── Systematic spacing ├── Client brand preservation ``` ### Design Philosophy ```css /* Instrument systematic approach */ :root { /* They create extensive token systems */ --space-1: 0.25rem; --space-2: 0.5rem; --space-3: 0.75rem; --space-4: 1rem; --space-5: 1.5rem; --space-6: 2rem; --space-7: 3rem; --space-8: 4rem; --space-9: 6rem; --space-10: 8rem; /* Typography scale */ --font-size-xs: 0.75rem; --font-size-sm: 0.875rem; --font-size-md: 1rem; --font-size-lg: 1.125rem; --font-size-xl: 1.25rem; --font-size-2xl: 1.5rem; --font-size-3xl: 2rem; --font-size-4xl: 2.5rem; --font-size-5xl: 3rem; } /* Everything built from tokens */ .instrument-component { padding: var(--space-6); margin-bottom: var(--space-8); font-size: var(--font-size-md); } ``` --- ## 8. Active Theory (LA) **Signature: Technical excellence, immersive WebGL** ### Technical Fingerprint ``` STACK ├── Custom WebGL frameworks ├── Three.js mastery ├── Shader programming ├── VR/AR capabilities └── Maximum technical ambition SIGNATURE TECHNIQUES ├── Full 3D environments ├── Custom shader effects ├── Real-time rendering ├── Interactive experiences ├── Sound reactive visuals ``` --- ## 9. Common Patterns Across Elite Agencies ### Universal Techniques ``` TYPOGRAPHY ├── Custom/premium fonts (never system fonts) ├── Extreme scale contrast (10:1+ ratios) ├── Negative tracking on display type ├── Line-height varies by use case └── Text animations on key headlines ANIMATION ├── Custom easing (never linear, rarely ease) ├── Staggered reveals ├── Scroll-triggered sequences ├── Smooth scrolling (Lenis/Locomotive) └── Page transitions LAYOUT ├── 12-column base grid ├── Strategic grid breaking ├── Generous white space ├── Full-bleed imagery └── Asymmetric compositions COLOR ├── Limited palettes (2-3 colors max) ├── Bold accent usage ├── Dark mode capability ├── Contextual color shifts └── Never pure black/white INTERACTION ├── Custom cursors ├── Magnetic buttons ├── Hover state reveals ├── Micro-feedback └── Sound design (optional) PERFORMANCE ├── Optimized assets ├── Lazy loading ├── Code splitting ├── GPU acceleration └── Core Web Vitals passing ``` ### What They ALL Avoid ``` NEVER SEEN ON ELITE SITES ✗ Stock photography (unedited) ✗ Generic icons (Font Awesome default) ✗ System fonts ✗ Bootstrap/default components ✗ Lazy lorem ipsum ✗ Auto-generated layouts ✗ Cookie-cutter templates ✗ Generic loading spinners ✗ Aggressive pop-ups ✗ Cluttered footers ``` -
layout-systems.md 9.4 KB
# Layout Systems Reference ## Table of Contents 1. Grid Frameworks 2. Breakpoint Strategy 3. Compositional Techniques 4. Responsive Patterns 5. Scroll-Based Layouts --- ## 1. Grid Frameworks ### Base Grid System ```css /* 12-column fluid grid */ :root { --grid-columns: 12; --grid-gutter: clamp(1rem, 2vw, 2rem); --grid-margin: clamp(1rem, 5vw, 6rem); } .grid { display: grid; grid-template-columns: repeat(var(--grid-columns), 1fr); gap: var(--grid-gutter); padding-inline: var(--grid-margin); max-width: 1800px; margin-inline: auto; } /* Span utilities */ .col-1 { grid-column: span 1; } .col-2 { grid-column: span 2; } .col-3 { grid-column: span 3; } .col-4 { grid-column: span 4; } .col-5 { grid-column: span 5; } .col-6 { grid-column: span 6; } .col-7 { grid-column: span 7; } .col-8 { grid-column: span 8; } .col-9 { grid-column: span 9; } .col-10 { grid-column: span 10; } .col-11 { grid-column: span 11; } .col-12 { grid-column: span 12; } /* Start position */ .start-1 { grid-column-start: 1; } .start-2 { grid-column-start: 2; } .start-3 { grid-column-start: 3; } .start-4 { grid-column-start: 4; } .start-5 { grid-column-start: 5; } .start-6 { grid-column-start: 6; } .start-7 { grid-column-start: 7; } ``` ### Swiss/Modular Grid ```css /* Swiss-style asymmetric grid */ .swiss-grid { display: grid; grid-template-columns: [full-start] var(--grid-margin) [content-start] 2fr [sidebar-start] 1fr [sidebar-end] var(--grid-margin) [full-end]; gap: var(--grid-gutter); } /* Named grid areas for Swiss compositions */ .swiss-layout { display: grid; grid-template-columns: 1fr 1fr 2fr; grid-template-rows: auto 1fr auto; grid-template-areas: "header header header" "nav main main" "footer footer footer"; min-height: 100vh; } ``` ### Editorial Grid ```css /* Magazine-style editorial grid */ .editorial-grid { display: grid; grid-template-columns: [full-start] minmax(var(--grid-margin), 1fr) [wide-start] minmax(0, 200px) [content-start] min(65ch, 100%) [content-end] minmax(0, 200px) [wide-end] minmax(var(--grid-margin), 1fr) [full-end]; } .editorial-grid > * { grid-column: content; } .editorial-grid > .wide { grid-column: wide; } .editorial-grid > .full { grid-column: full; } ``` --- ## 2. Breakpoint Strategy ### Fluid-First Approach ```css /* Minimal breakpoints - rely on fluid sizing */ :root { /* Only break when necessary */ --bp-sm: 640px; /* Mobile landscape */ --bp-md: 768px; /* Tablet */ --bp-lg: 1024px; /* Desktop */ --bp-xl: 1280px; /* Large desktop */ --bp-2xl: 1536px; /* Ultra-wide */ } /* Media query mixins (conceptual) */ @media (min-width: 768px) { /* Tablet and up */ } @media (min-width: 1024px) { /* Desktop and up */ } @media (min-width: 1280px) { /* Large screens */ } /* Container queries for component-level responsiveness */ .card-container { container-type: inline-size; container-name: card; } @container card (min-width: 400px) { .card { flex-direction: row; } } ``` ### Responsive Grid Columns ```css /* Responsive column spans */ .responsive-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--grid-gutter); } @media (min-width: 768px) { .responsive-grid { grid-template-columns: repeat(8, 1fr); } } @media (min-width: 1024px) { .responsive-grid { grid-template-columns: repeat(12, 1fr); } } /* Responsive item */ .grid-item { grid-column: span 4; /* Full width mobile */ } @media (min-width: 768px) { .grid-item { grid-column: span 4; /* Half width tablet */ } } @media (min-width: 1024px) { .grid-item { grid-column: span 3; /* Quarter width desktop */ } } ``` --- ## 3. Compositional Techniques ### Asymmetric Balance ```css /* Intentionally unbalanced layout */ .asymmetric-hero { display: grid; grid-template-columns: 2fr 3fr; gap: var(--grid-gutter); align-items: end; } .asymmetric-hero .title { grid-column: 1; /* Offset from grid alignment */ margin-left: -5%; } .asymmetric-hero .media { grid-column: 2; /* Extend beyond grid */ margin-right: calc(var(--grid-margin) * -1); } ``` ### Overlap & Layer ```css /* Overlapping elements */ .overlap-composition { display: grid; grid-template-columns: repeat(12, 1fr); grid-template-rows: repeat(6, 1fr); } .overlap-composition .image { grid-column: 1 / 8; grid-row: 1 / 5; z-index: 1; } .overlap-composition .text-block { grid-column: 6 / 13; grid-row: 3 / 7; z-index: 2; background: var(--color-surface); padding: 2rem; } ``` ### Bleeding Elements ```css /* Elements that break container */ .bleed-container { max-width: 1200px; margin-inline: auto; padding-inline: var(--grid-margin); } .bleed-left { margin-left: calc(var(--grid-margin) * -1); padding-left: var(--grid-margin); /* Or extend to viewport edge */ margin-left: calc(-50vw + 50%); padding-left: calc(50vw - 50%); } .bleed-right { margin-right: calc(var(--grid-margin) * -1); padding-right: var(--grid-margin); } .bleed-full { width: 100vw; margin-left: calc(-50vw + 50%); } ``` ### Diagonal/Angular Layouts ```css /* Angled section divider */ .angled-section { position: relative; padding: 8rem 0; } .angled-section::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 100%; background: var(--color-accent); clip-path: polygon(0 10%, 100% 0, 100% 90%, 0 100%); z-index: -1; } /* Skewed container */ .skewed-container { transform: skewY(-3deg); padding: 6rem 0; } .skewed-container > * { transform: skewY(3deg); /* Counter-skew content */ } ``` --- ## 4. Responsive Patterns ### Mobile-First Hero ```css /* Hero that works mobile-first */ .hero { min-height: 100svh; display: flex; flex-direction: column; justify-content: flex-end; padding: var(--grid-margin); padding-bottom: 15vh; } .hero-title { font-size: clamp(3rem, 10vw, 12rem); line-height: 0.9; margin-bottom: 1rem; } .hero-media { position: absolute; inset: 0; z-index: -1; } @media (min-width: 1024px) { .hero { display: grid; grid-template-columns: 1fr 1fr; align-items: end; gap: var(--grid-gutter); } .hero-title { grid-column: 1 / -1; } } ``` ### Responsive Card Grid ```css /* Auto-fit responsive grid */ .card-grid { display: grid; grid-template-columns: repeat( auto-fit, minmax(min(100%, 300px), 1fr) ); gap: var(--grid-gutter); } /* Or with explicit breakpoints for control */ .card-grid-controlled { display: grid; gap: var(--grid-gutter); grid-template-columns: 1fr; /* Mobile: 1 column */ } @media (min-width: 640px) { .card-grid-controlled { grid-template-columns: repeat(2, 1fr); } } @media (min-width: 1024px) { .card-grid-controlled { grid-template-columns: repeat(3, 1fr); } } @media (min-width: 1280px) { .card-grid-controlled { grid-template-columns: repeat(4, 1fr); } } ``` ### Responsive Typography Layout ```css /* Two-column text layout */ .text-columns { columns: 1; } @media (min-width: 768px) { .text-columns { columns: 2; column-gap: var(--grid-gutter); } } /* Prevent breaks */ .text-columns h2, .text-columns h3, .text-columns figure { break-inside: avoid; } ``` --- ## 5. Scroll-Based Layouts ### Horizontal Scroll Section ```css .horizontal-scroll { display: flex; overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none; -ms-overflow-style: none; } .horizontal-scroll::-webkit-scrollbar { display: none; } .horizontal-scroll-item { flex: 0 0 80vw; scroll-snap-align: center; padding: 0 2vw; } @media (min-width: 1024px) { .horizontal-scroll-item { flex: 0 0 40vw; } } ``` ### Sticky Sidebar ```css .sticky-layout { display: grid; grid-template-columns: 1fr 300px; gap: var(--grid-gutter); align-items: start; } .sticky-sidebar { position: sticky; top: var(--grid-margin); } /* Full-height sticky */ .sticky-full { position: sticky; top: 0; height: 100vh; overflow-y: auto; } ``` ### Scroll-Triggered Layout Changes ```css /* Layout shifts based on scroll position */ .scroll-layout { --scroll-progress: 0; display: grid; grid-template-columns: calc(30% + (20% * var(--scroll-progress))) 1fr; transition: grid-template-columns 0.1s; } /* JS updates --scroll-progress from 0 to 1 */ ``` ### Pinned Section with Content Scroll ```css /* Two-panel layout with one side pinned */ .pinned-layout { display: grid; grid-template-columns: 1fr 1fr; } .pinned-panel { position: sticky; top: 0; height: 100vh; display: flex; align-items: center; justify-content: center; } .scrolling-panel { /* Content scrolls naturally */ } .scrolling-panel section { min-height: 100vh; display: flex; flex-direction: column; justify-content: center; padding: var(--grid-margin); } ``` --- ## Layout Anti-Patterns ``` AVOID THESE: ✗ Fixed pixel widths (use max-width instead) ✗ Magic numbers without explanation ✗ Breaking grid without clear purpose ✗ Horizontal scroll without indication ✗ Content touching viewport edges on mobile ✗ Equal margins everywhere (creates boredom) ✗ Centered everything (lacks visual tension) PREFER THESE: ✓ Fluid units (%, vw, clamp()) ✓ CSS custom properties for spacing ✓ Intentional grid breaks with rationale ✓ Touch-friendly scroll indicators ✓ Consistent edge margins with breathing room ✓ Varied spacing for rhythm ✓ Asymmetric compositions for interest ``` -
technical-stack.md 10.8 KB
# Technical Stack Reference ## Table of Contents 1. Core Technologies 2. Animation Libraries 3. Smooth Scrolling Solutions 4. 3D & WebGL 5. Build Tools & Frameworks 6. Performance Optimization 7. Deployment & Hosting --- ## 1. Core Technologies ### CSS Approach ``` METHODOLOGY ├── CSS Custom Properties (required) ├── Modern CSS (container queries, :has(), etc.) ├── Utility-first OR Component-based (not mixed) └── PostCSS for processing (autoprefixer, nesting) RECOMMENDED STACK ├── Plain CSS with custom properties ├── Tailwind CSS (for rapid prototyping) ├── CSS Modules (for React/Vue scoping) └── Vanilla Extract (for type-safe CSS-in-JS) ``` ### JavaScript Standards ```javascript // Modern JS features to use freely const features = { modules: true, // ES Modules asyncAwait: true, // Async/await optionalChaining: true, // obj?.prop nullishCoalescing: true, // value ?? default destructuring: true, // const { a, b } = obj spreadOperator: true, // [...arr, newItem] templateLiterals: true, // `${var}` arrowFunctions: true, // () => {} }; // Avoid const avoid = { var: true, // Use const/let callbacks: 'Use promises/async', jquery: 'Use native APIs', }; ``` --- ## 2. Animation Libraries ### GSAP (GreenSock) ``` THE INDUSTRY STANDARD ├── Power: Most capable animation library ├── Performance: Optimized for 60fps ├── Ecosystem: ScrollTrigger, SplitText, MorphSVG └── License: Free for most uses, paid for some plugins INSTALLATION npm install gsap CORE PLUGINS (free) ├── ScrollTrigger - scroll-based animations ├── Observer - scroll/touch/pointer tracking ├── Draggable - drag interactions └── MotionPath - animate along SVG paths CLUB PLUGINS (paid) ├── SplitText - text splitting for animation ├── MorphSVG - shape morphing ├── DrawSVG - line drawing effects ├── ScrollSmoother - smooth scroll + ScrollTrigger └── Flip - layout animations ``` ```javascript // GSAP initialization pattern import { gsap } from "gsap"; import { ScrollTrigger } from "gsap/ScrollTrigger"; gsap.registerPlugin(ScrollTrigger); // Set defaults gsap.defaults({ ease: "expo.out", duration: 1 }); // Basic animation gsap.to(".element", { x: 100, opacity: 1, duration: 0.8 }); // Timeline const tl = gsap.timeline(); tl.to(".first", { x: 100 }) .to(".second", { x: 100 }, "-=0.5") // overlap .to(".third", { x: 100 }, "+=0.2"); // gap ``` ### Motion (Framer Motion) ``` REACT-SPECIFIC ├── Declarative API ├── Layout animations ├── Gesture support ├── Exit animations └── Server-side rendering support INSTALLATION npm install motion ``` ```jsx // Motion usage import { motion, AnimatePresence } from "motion/react"; // Basic animation <motion.div initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} exit={{ opacity: 0 }} transition={{ duration: 0.6, ease: [0.16, 1, 0.3, 1] }} > Content </motion.div> // Scroll-triggered <motion.div initial={{ opacity: 0 }} whileInView={{ opacity: 1 }} viewport={{ once: true, margin: "-100px" }} > Reveals on scroll </motion.div> // Layout animation <motion.div layout> {/* Animates when layout changes */} </motion.div> ``` ### Anime.js ``` LIGHTWEIGHT ALTERNATIVE ├── Size: ~17KB minified ├── SVG morphing included ├── Timeline support └── Good for simpler projects INSTALLATION npm install animejs ``` ```javascript import anime from 'animejs'; anime({ targets: '.element', translateX: 250, rotate: '1turn', duration: 800, easing: 'easeOutExpo' }); // Stagger anime({ targets: '.grid-item', translateY: [50, 0], opacity: [0, 1], delay: anime.stagger(100) }); ``` --- ## 3. Smooth Scrolling Solutions ### Lenis (Recommended) ``` MODERN & LIGHTWEIGHT ├── Size: ~4KB gzipped ├── Native scroll (accessibility preserved) ├── GSAP integration ├── Performant └── Actively maintained by Studio Freight INSTALLATION npm install lenis ``` ```javascript import Lenis from 'lenis'; const lenis = new Lenis({ duration: 1.2, easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)), orientation: 'vertical', gestureOrientation: 'vertical', smoothWheel: true, wheelMultiplier: 1, touchMultiplier: 2, infinite: false, }); function raf(time) { lenis.raf(time); requestAnimationFrame(raf); } requestAnimationFrame(raf); // GSAP integration import { gsap } from 'gsap'; import { ScrollTrigger } from 'gsap/ScrollTrigger'; lenis.on('scroll', ScrollTrigger.update); gsap.ticker.add((time) => { lenis.raf(time * 1000); }); gsap.ticker.lagSmoothing(0); ``` ### Locomotive Scroll ``` FEATURE-RICH ├── Smooth scrolling ├── Parallax effects built-in ├── Data attributes for quick setup ├── Horizontal scroll support └── Heavier than Lenis INSTALLATION npm install locomotive-scroll ``` ```javascript import LocomotiveScroll from 'locomotive-scroll'; const scroll = new LocomotiveScroll({ el: document.querySelector('[data-scroll-container]'), smooth: true, multiplier: 1, lerp: 0.1 }); // Data attribute usage // <div data-scroll data-scroll-speed="2">Parallax element</div> ``` --- ## 4. 3D & WebGL ### Three.js ``` FULL 3D CAPABILITY ├── Complete 3D engine ├── Large ecosystem ├── Extensive documentation └── Performance-intensive INSTALLATION npm install three ``` ```javascript import * as THREE from 'three'; // Basic scene setup const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)); document.body.appendChild(renderer.domElement); // Animation loop function animate() { requestAnimationFrame(animate); renderer.render(scene, camera); } animate(); ``` ### React Three Fiber ``` THREE.JS FOR REACT ├── Declarative Three.js ├── React ecosystem integration ├── Easier state management └── Drei helpers library INSTALLATION npm install @react-three/fiber @react-three/drei ``` ```jsx import { Canvas } from '@react-three/fiber'; import { OrbitControls, Environment } from '@react-three/drei'; function Scene() { return ( <Canvas> <ambientLight intensity={0.5} /> <mesh> <boxGeometry /> <meshStandardMaterial color="orange" /> </mesh> <OrbitControls /> <Environment preset="city" /> </Canvas> ); } ``` ### OGL ``` LIGHTWEIGHT WEBGL ├── Size: ~30KB ├── Lower-level than Three.js ├── Better for simple effects └── Less overhead INSTALLATION npm install ogl ``` --- ## 5. Build Tools & Frameworks ### Vite (Recommended for Simple Sites) ``` FAST BUILD TOOL ├── Instant dev server ├── Native ES modules ├── Optimized production builds └── Framework agnostic SETUP npm create vite@latest ``` ### Next.js (React Apps) ``` REACT FRAMEWORK ├── Server-side rendering ├── Static site generation ├── API routes ├── Image optimization └── File-based routing SETUP npx create-next-app@latest ``` ### Astro (Content Sites) ``` CONTENT-FOCUSED ├── Zero JS by default ├── Partial hydration ├── Any framework components ├── Excellent performance └── Great for portfolios/marketing SETUP npm create astro@latest ``` ### Nuxt (Vue Apps) ``` VUE FRAMEWORK ├── SSR/SSG ├── Auto-imports ├── File-based routing └── Excellent DX SETUP npx nuxi@latest init ``` --- ## 6. Performance Optimization ### Image Optimization ``` FORMATS ├── WebP: Primary format, 25-35% smaller than JPEG ├── AVIF: Best compression, growing support ├── SVG: Icons, logos, illustrations └── JPEG/PNG: Fallbacks only TOOLS ├── Sharp (Node.js): npm install sharp ├── Squoosh: squoosh.app (browser-based) ├── ImageOptim: Desktop app (Mac) └── SVGO: SVG optimization RESPONSIVE IMAGES <picture> <source srcset="image.avif" type="image/avif"> <source srcset="image.webp" type="image/webp"> <img src="image.jpg" alt="Description" loading="lazy"> </picture> SRCSET FOR RESOLUTION <img srcset="image-400.webp 400w, image-800.webp 800w, image-1200.webp 1200w" sizes="(max-width: 600px) 400px, (max-width: 1200px) 800px, 1200px" src="image-800.webp" alt="Description" loading="lazy" > ``` ### Font Optimization ```html <!-- Preload critical fonts --> <link rel="preload" href="/fonts/display.woff2" as="font" type="font/woff2" crossorigin> <!-- Font-display strategy --> <style> @font-face { font-family: 'Display'; src: url('/fonts/display.woff2') format('woff2'); font-display: swap; /* or optional for non-critical */ unicode-range: U+0000-00FF; /* Subset to Latin */ } </style> ``` ### Code Splitting ```javascript // Dynamic imports const HeavyComponent = lazy(() => import('./HeavyComponent')); // Route-based splitting (Next.js automatic) // Each page is a separate chunk // Manual chunk with Vite // vite.config.js export default { build: { rollupOptions: { output: { manualChunks: { vendor: ['gsap', 'three'], }, }, }, }, }; ``` ### Critical CSS ```javascript // Extract critical CSS with Critters (Vite plugin) // npm install critters import critters from 'critters'; // Or inline critical styles manually <style> /* Above-the-fold styles inlined */ </style> <link rel="preload" href="/styles.css" as="style" onload="this.rel='stylesheet'"> ``` --- ## 7. Deployment & Hosting ### Recommended Platforms ``` STATIC SITES ├── Vercel: Best for Next.js, excellent DX ├── Netlify: Great for Jamstack, easy deploys ├── Cloudflare Pages: Fast edge network └── GitHub Pages: Free, simple static hosting FULL-STACK ├── Vercel: Serverless functions, edge middleware ├── Railway: Containers, databases ├── Render: Full infrastructure └── AWS Amplify: AWS ecosystem CDN FOR ASSETS ├── Cloudflare: Free tier, global ├── AWS CloudFront: Enterprise scale ├── Bunny CDN: Cost-effective, fast └── Imgix/Cloudinary: Image-specific CDN ``` ### Performance Checklist ``` PRE-LAUNCH □ Images optimized (WebP/AVIF, lazy loaded) □ Fonts subset and preloaded □ CSS/JS minified and compressed □ Gzip/Brotli compression enabled □ HTTP/2 or HTTP/3 enabled □ Cache headers configured □ Critical CSS inlined □ Unused CSS/JS removed MONITORING □ Lighthouse CI in deployment □ Core Web Vitals tracking □ Real User Monitoring (RUM) □ Error tracking (Sentry, etc.) ``` -
typography.md 8.3 KB
# Typography Reference ## Table of Contents 1. Font Pairing Strategies 2. Type Scale Systems 3. CSS Typography Techniques 4. Variable Fonts 5. Font Loading Optimization --- ## 1. Font Pairing Strategies ### The Contrast Principle Great pairings create tension through contrast in one dimension while maintaining harmony in others. **Contrast Dimensions:** - Weight (light vs. bold) - Width (condensed vs. extended) - Style (serif vs. sans) - Era (classic vs. contemporary) - Mood (serious vs. playful) ### Proven Pairings by Style **Editorial/Magazine:** ``` Display: Freight Display / Editorial New / Canela Body: Söhne / Untitled Sans / Graphik ``` **Tech/Modern:** ``` Display: Monument Extended / ABC Favorit Extended / Druk Wide Body: Inter (only acceptable here) / Suisse Int'l / Neue Montreal ``` **Luxury/Fashion:** ``` Display: Didot / Romana / Noe Display Body: Apercu / Basis Grotesque / Plain ``` **Brutalist/Raw:** ``` Display: ABC Diatype / Neue Haas Grotesk / Helvetica Now Body: Same as display (mono-font strategy) ``` **Creative/Playful:** ``` Display: Basement Grotesque / GT Maru / Gambarino Body: GT Walsheim / Gilroy / Proxima Nova ``` ### Free/Google Font Alternatives **Premium Feel, Zero Cost:** ``` Display Options: ├── Space Grotesk (geometric, techy) ├── Instrument Serif (editorial elegance) ├── Fraunces (variable, characterful) ├── Playfair Display (classic serif) ├── Cormorant Garamond (refined serif) └── Syne (bold, distinctive) Body Options: ├── Plus Jakarta Sans (clean, modern) ├── DM Sans (geometric, friendly) ├── Outfit (variable, versatile) ├── Satoshi (via Fontshare - free!) └── General Sans (via Fontshare) ``` --- ## 2. Type Scale Systems ### Fluid Typography (Preferred) ```css /* Fluid scale using clamp() */ :root { /* Base: 16px at 320px → 20px at 1440px */ --text-base: clamp(1rem, 0.857rem + 0.714vw, 1.25rem); /* Scale ratio: 1.25 (Major Third) */ --text-sm: clamp(0.8rem, 0.686rem + 0.571vw, 1rem); --text-lg: clamp(1.25rem, 1.071rem + 0.893vw, 1.563rem); --text-xl: clamp(1.563rem, 1.339rem + 1.116vw, 1.953rem); --text-2xl: clamp(1.953rem, 1.674rem + 1.395vw, 2.441rem); --text-3xl: clamp(2.441rem, 2.092rem + 1.744vw, 3.052rem); --text-4xl: clamp(3.052rem, 2.616rem + 2.18vw, 3.815rem); --text-5xl: clamp(3.815rem, 3.27rem + 2.725vw, 4.768rem); /* Hero sizes - dramatic scale */ --text-hero: clamp(4rem, 2rem + 8vw, 12rem); --text-display: clamp(3rem, 1.5rem + 6vw, 9rem); } ``` ### Step-Based Scale (Fixed Breakpoints) ```css /* Mobile-first scale */ :root { --step--2: 0.75rem; /* 12px */ --step--1: 0.875rem; /* 14px */ --step-0: 1rem; /* 16px - base */ --step-1: 1.125rem; /* 18px */ --step-2: 1.5rem; /* 24px */ --step-3: 2rem; /* 32px */ --step-4: 3rem; /* 48px */ --step-5: 4rem; /* 64px */ --step-6: 6rem; /* 96px */ --step-7: 8rem; /* 128px */ } @media (min-width: 768px) { :root { --step-4: 4rem; --step-5: 6rem; --step-6: 9rem; --step-7: 12rem; } } @media (min-width: 1280px) { :root { --step-5: 8rem; --step-6: 12rem; --step-7: 16rem; } } ``` --- ## 3. CSS Typography Techniques ### Tracking (Letter-Spacing) ```css /* Tracking scales inversely with size */ .text-hero { letter-spacing: -0.04em; /* Tight for massive text */ } .text-display { letter-spacing: -0.03em; } .text-heading { letter-spacing: -0.02em; } .text-body { letter-spacing: 0; /* Normal for body */ } .text-small { letter-spacing: 0.01em; /* Slightly open for small text */ } .text-caps { letter-spacing: 0.1em; /* Open for all-caps */ text-transform: uppercase; } ``` ### Leading (Line-Height) ```css /* Line-height based on use case */ .leading-hero { line-height: 0.9; /* Very tight for impact */ } .leading-display { line-height: 1.0; } .leading-heading { line-height: 1.1; } .leading-body { line-height: 1.6; /* Comfortable reading */ } .leading-relaxed { line-height: 1.8; /* Long-form content */ } ``` ### Advanced Techniques ```css /* Optical margin alignment */ .hanging-punctuation { hanging-punctuation: first last; } /* Font feature settings */ .tabular-nums { font-variant-numeric: tabular-nums; } .oldstyle-nums { font-variant-numeric: oldstyle-nums; } .ligatures { font-variant-ligatures: common-ligatures discretionary-ligatures; } /* Text rendering optimization */ .hero-text { text-rendering: optimizeLegibility; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } /* Preventing text wrapping issues */ .no-orphans { text-wrap: balance; /* Modern browsers */ } /* Hyphenation for justified text */ .justified { text-align: justify; hyphens: auto; hyphenate-limit-chars: 6 3 2; } ``` ### Text Masking & Gradient Text ```css /* Gradient text */ .gradient-text { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; } /* Image-filled text */ .image-text { background-image: url('/texture.jpg'); background-size: cover; -webkit-background-clip: text; -webkit-text-fill-color: transparent; } /* Animated gradient text */ .animated-gradient-text { background: linear-gradient(90deg, #ff0000, #00ff00, #0000ff, #ff0000); background-size: 300% 100%; -webkit-background-clip: text; -webkit-text-fill-color: transparent; animation: gradient-shift 8s ease infinite; } @keyframes gradient-shift { 0%, 100% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } } ``` --- ## 4. Variable Fonts ### Benefits - Single file, multiple weights/widths - Fluid animations between weights - Smaller total file size ### Implementation ```css /* Loading variable font */ @font-face { font-family: 'Inter'; src: url('/fonts/Inter-Variable.woff2') format('woff2-variations'); font-weight: 100 900; font-display: swap; } /* Using weight axis */ .light { font-variation-settings: 'wght' 300; } .regular { font-variation-settings: 'wght' 400; } .medium { font-variation-settings: 'wght' 500; } .bold { font-variation-settings: 'wght' 700; } .black { font-variation-settings: 'wght' 900; } /* Animating weight */ .hover-weight { font-variation-settings: 'wght' 400; transition: font-variation-settings 0.3s ease; } .hover-weight:hover { font-variation-settings: 'wght' 700; } /* Multiple axes */ .variable-text { font-variation-settings: 'wght' 500, /* Weight */ 'wdth' 100, /* Width */ 'ital' 0, /* Italic */ 'slnt' 0; /* Slant */ } ``` --- ## 5. Font Loading Optimization ### Critical Font Strategy ```html <!-- Preload critical fonts --> <link rel="preload" href="/fonts/display.woff2" as="font" type="font/woff2" crossorigin> <link rel="preload" href="/fonts/body.woff2" as="font" type="font/woff2" crossorigin> <!-- Inline critical @font-face --> <style> @font-face { font-family: 'Display'; src: url('/fonts/display.woff2') format('woff2'); font-weight: 700; font-display: swap; } </style> ``` ### Font Subsetting ```bash # Using pyftsubset to create subset pyftsubset "Font.ttf" \ --output-file="Font-subset.woff2" \ --flavor=woff2 \ --layout-features="kern,liga,calt" \ --unicodes="U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD" ``` ### FOUT/FOIT Prevention ```css /* Font loading classes via JavaScript */ .fonts-loading { /* Use fallback stack */ font-family: Georgia, serif; } .fonts-loaded .body-text { font-family: 'Custom Font', Georgia, serif; } /* Or use font-display */ @font-face { font-family: 'Display Font'; src: url('/fonts/display.woff2') format('woff2'); font-display: swap; /* Show fallback immediately, swap when loaded */ } @font-face { font-family: 'Body Font'; src: url('/fonts/body.woff2') format('woff2'); font-display: optional; /* Only use if already cached */ } ``` ### JavaScript Font Loading API ```javascript // Check if fonts are loaded document.fonts.ready.then(() => { document.documentElement.classList.add('fonts-loaded'); }); // Load specific font const font = new FontFace('Display', 'url(/fonts/display.woff2)'); font.load().then((loadedFont) => { document.fonts.add(loadedFont); document.body.classList.add('display-font-loaded'); }); ```
-
-
SKILL.md 22.6 KB
--- name: top-design description: 'Create award-winning, immersive web experiences at the level of Awwwards-featured agencies. Use when the user mentions "Awwwards quality", "make my site stunning", "scroll animations", "parallax storytelling", "cinematic web design", "portfolio site", or "brand experience". Also trigger when elevating a standard landing page into a memorable digital experience. Covers dramatic typography, purposeful motion, scroll-based composition, and performance-optimized animation. For foundational UI, see refactoring-ui. For type selection, see web-typography.' license: MIT metadata: author: wondelai version: "1.6.0" --- # Top-Design: Award-Winning Digital Experiences Create websites and applications at the level of world-class digital agencies. This skill embodies the craft of studios that consistently win FWA, Awwwards, CSS Design Awards, and Webby Awards. ## Core Principle **Every pixel is intentional -- nothing default, nothing accidental.** The agencies you are emulating -- Locomotive, Studio Freight, AREA 17, Active Theory, Hello Monday -- share a common DNA: typography IS the design, motion creates emotion, white space is a weapon, and performance is non-negotiable (60fps or nothing). **The foundation:** The gap between 8/10 and 10/10 is not skill -- it is intention. An 8/10 has good typography and smooth animations; a 10/10 has typography that makes you gasp and animations that tell stories. Every decision must answer: "Does this serve the experience, or is it just filling space?" ## Scoring **Goal: 10/10.** Rate any digital experience 0-10 using the rubric below -- a 10/10 would be featured on Awwwards. Always state the current score and the specific improvements needed to reach 10/10. ### Scoring Rubric | Score | Level | Description | |-------|-------|-------------| | **0-2** | Amateur | Default fonts, no hierarchy, generic layout, template feel | | **3-4** | Basic | Decent typography, some hierarchy, but forgettable | | **5-6** | Competent | Good fundamentals, clean execution, but lacks soul | | **7-8** | Professional | Strong typography, intentional motion, clear POV | | **9** | Exceptional | Signature moments, memorable details, near-flawless craft | | **10** | World-class | Would win Awwwards SOTD, defines new standards | ### Category Scoring (Each 0-10) **TYPOGRAPHY (Weight: 25%)** | Score | Criteria | |-------|----------| | 0-3 | System fonts, uniform scale, default tracking | | 4-6 | Premium fonts, some scale contrast, basic hierarchy | | 7-8 | Dramatic scale contrast (10:1+), perfect tracking, optical alignment | | 9-10 | Typography IS the design -- gasping moments, custom/variable fonts, type as architecture | **VISUAL COMPOSITION (Weight: 25%)** | Score | Criteria | |-------|----------| | 0-3 | Centered everything, equal spacing, rigid grid, no tension | | 4-6 | Some asymmetry, decent spacing rhythm, basic depth | | 7-8 | Intentional grid breaks, layered elements, strong negative space | | 9-10 | Magnetic compositions, unexpected scale shifts, elements that breathe and surprise | **MOTION & INTERACTION (Weight: 20%)** | Score | Criteria | |-------|----------| | 0-3 | No animation or default/linear motion | | 4-6 | Basic transitions, some scroll effects | | 7-8 | Custom easing, orchestrated reveals, purposeful parallax | | 9-10 | Motion that tells stories, perfectly timed choreography, scroll feels invented | **COLOR & ATMOSPHERE (Weight: 15%)** | Score | Criteria | |-------|----------| | 0-3 | Random colors, pure black/white, no mood | | 4-6 | Cohesive palette, some atmosphere | | 7-8 | Colors feel owned, contextual shifts, intentional contrast | | 9-10 | Colors feel invented for this project, atmosphere you can feel | **DETAILS & CRAFT (Weight: 15%)** | Score | Criteria | |-------|----------| | 0-3 | Default cursors, no hover states, generic everything | | 4-6 | Basic hover states, some custom elements | | 7-8 | Magnetic buttons, branded selection colors, custom cursor (if user-approved) | | 9-10 | Every micro-detail considered -- focus states, loading, empty states, scroll indicators | ### Quick Score Formula ``` Total = (Typography x 0.25) + (Composition x 0.25) + (Motion x 0.20) + (Color x 0.15) + (Details x 0.15) ``` ## The Seven Pillars of 10/10 Design ### 1. Typography as Architecture **Core concept:** Typography is not decoration layered onto a design -- it IS the design. Your typeface, scale, and tracking dictate color mood, animation style, spacing rhythm, and overall personality. **Why it works:** Dramatic scale contrast creates hierarchy that communicates even when blurred or seen from across the room. The tension between monumental display type and intimate body text is what makes people stop scrolling. **Key insights:** - Massive scale contrast is non-negotiable -- minimum 10:1 between display and body (e.g., 180px / 14px); viewport-filling type at the extreme - Negative tracking on large type (-0.02em to -0.05em) tightens display into cohesive units; body needs generous line-height (1.5-1.7) - Font selection defines tier -- premium foundries (Pangram Pangram, Dinamo, Grilli Type, Klim, Commercial Type) or quality Google alternatives (Space Grotesk, Instrument Serif, Fraunces); never Inter, Roboto, Arial, or system-ui for hero experiences - Variable fonts enable weight animation on hover without layout shift - Optical alignment beats mathematical alignment -- adjust visually, not just numerically - Control every line break on headlines -- beautiful breaks require manual intervention at key breakpoints **Applications:** viewport-filling display dropping hard to body (Locomotive hero); variable font with hover weight-animation (Studio Freight); serif/sans pairing at extreme scale contrast (AREA 17 editorial). Display = one statement, 3-7 words; body = 16-18px minimum, 45-75 character measure. See [references/typography.md](references/typography.md) when choosing typefaces or building the type scale -- named font pairings by style, full fluid `clamp()` and step-based scales, tracking/leading ladders, and font-subsetting/FOUT mechanics. ### 2. Layout & Composition **Core concept:** Master the grid so you can break it with intention -- every violation should feel deliberate, not accidental. The rhythm of density and breathing room creates a reading experience that holds attention. **Why it works:** White space is active design material that creates tension and controls pacing. Asymmetry generates visual energy that centered compositions cannot; elements that overlap or bleed with intention feel alive and confident. **Key insights:** - White space as a weapon -- amateurs fill every gap; 10/10 designers use emptiness to create tension that controls the eye - Asymmetric balance creates interest -- offset elements from center, let images bleed beyond containers - Unexpected scale shifts create rhythm -- alternate massive/intimate, dense/sparse for narrative pacing - The grid paradox -- a strong underlying grid is what makes breaks meaningful; without it, breaks are chaos **Applications:** offset title with bleeding imagery (`margin-left: 8.33%; margin-right: -5vw`); varied card sizes for intentional asymmetry (Locomotive showcases); overlapping elements for depth (Active Theory). Alternate full-width immersion with contained reading sections. **Ethical boundary:** Layout experimentation must never compromise navigation clarity -- users must always know where they are and how to move forward. See [references/layout-systems.md](references/layout-systems.md) when laying out sections or going responsive -- grid frameworks, breakpoint systems, and asymmetric/bleeding-element patterns. ### 3. Motion & Animation **Core concept:** Every animation must answer "Why does this move?" The three laws of elite motion: purpose over decoration, custom curves (never linear), orchestration over isolation. **Why it works:** Choreographed motion guides attention, communicates hierarchy, and creates emotional resonance. Custom easing curves give movement a physical quality default browser easing cannot achieve. **Key insights:** - Custom easing is mandatory -- `ease`, `ease-in`, `ease-out`, `linear` are banned; use `cubic-bezier(0.16, 1, 0.3, 1)` (expo out), `cubic-bezier(0.25, 1, 0.5, 1)` (quart out), `cubic-bezier(0.87, 0, 0.13, 1)` (expo in-out) - Page load follows a strict choreography -- structure (0-200ms), hero title words staggered (200-600ms), subtitle (400-800ms), navigation cascade (600-900ms), supporting elements (800-1200ms); reference holds the canonical per-element stagger values - Animate in relationship, not isolation -- elements that move together feel cohesive and intentional - 60fps is non-negotiable -- if an animation drops frames, simplify or remove it **Applications:** choreographed staggered page-load reveal (Studio Freight); clip-path/mask image reveals on scroll-enter (AREA 17); hover weight-shifts and magnetic buttons (Dogstudio). Text lines slide up individually with stagger -- never fade in as a block; pages morph rather than cut. **Ethical boundary:** Motion must never block interaction or cause motion sickness -- respect `prefers-reduced-motion`, keep all content accessible without animation, and justify anything longer than 1.2s. See [references/animation-patterns.md](references/animation-patterns.md) when implementing motion -- copy-pasteable scroll reveals, staggered load choreography, page transitions, and magnetic/hover micro-interactions with code. ### 4. Color & Contrast **Core concept:** Color should feel invented for each project -- never pulled from a generic palette generator. Three approaches: monochromatic tension (95% one color, 5% accent), bold signature (own a combination), contextual shifting (palette responds to content). **Why it works:** Color creates atmosphere before a single word is read. Pure black/white feel digital and lifeless; warm variants feel physical and considered. A restrained accent draws the eye exactly where intended. **Key insights:** - Never use pure black or pure white -- #0a0a0a and #fafaf9 have a physical quality that #000/#fff lack - Build a functional hierarchy -- text-primary, text-secondary (60% opacity), text-tertiary (40%), surface, border (10%) for consistent depth - One strong accent used sparingly (#ff4d00 or similar) beats a complex multi-color palette - Contextual color shifts between sections create visual chapters - Design the system for both light and dark contexts, not individual instances **Applications:** monochromatic with signature accent (Locomotive: cream + black + orange spark); contextual shifting per case study (AREA 17); dark mode with one vibrant accent (Stripe: navy + purple). Drive everything from CSS custom properties (`--color-dark/-light/-accent` plus functional `--color-text-primary/-surface`); the accent appears only on CTAs, links, and single-detail moments. See [references/case-studies.md](references/case-studies.md) when you need a worked example of any pillar -- agency-by-agency breakdowns of real color systems, type treatments, and micro-interactions to reverse-engineer. ### 5. Scroll-Based Design **Core concept:** Scroll is the web's primary interaction and should feel designed, not default. Treat scroll as a narrative device -- controlling pacing, creating reveals, building tension, delivering signature moments. **Why it works:** Default scroll is mechanical and treats all content as equally important. When scroll position drives reveals and transitions, moving through content becomes participatory rather than passive. **Key insights:** - Smooth scroll is the foundation -- implement Lenis or Locomotive Scroll for the weighted, physical feel every award-winning site uses - Parallax must be purposeful -- sparing, and only on decorative elements; never on text or critical content - Pinned sections create storytelling beats -- lock a section while content transforms within it - Horizontal scroll galleries need clear visual affordance - Reveals should be progressive -- elements enter as they become visible, creating discovery - Scroll velocity can modulate animation speed for a responsive feel **Applications:** pinned hero with scroll-driven transformation (Apple deep-dives); horizontal scroll gallery with affordance (Studio Freight); scroll-driven animation sequences (Active Theory). Use IntersectionObserver for lightweight class toggling; reserve GSAP ScrollTrigger for complex multi-step sequences. **Ethical boundary:** Scroll hijacking is hostile UX -- users must always be able to scroll at their own pace and reach all content. See [references/technical-stack.md](references/technical-stack.md) to wire up smooth scroll (Lenis/Locomotive setup, library tradeoffs) and [references/animation-patterns.md](references/animation-patterns.md) for pinning, horizontal galleries, and scroll-velocity sequences. ### 6. Performance & Loading **Core concept:** Performance is a design constraint from day one, not an optimization step. A beautiful animation that drops frames or a stunning font that causes layout shift fails the craft test. **Why it works:** Users perceive performance as quality -- instant load and fluid scroll feel premium regardless of visual complexity, while a stunning site that stutters feels broken. **Key insights:** - Subset and preload fonts -- only needed glyphs, `font-display: swap` or `optional`, preload critical files - Optimize images -- WebP/AVIF with fallbacks, responsive `srcset`, lazy-load below the fold - GPU-accelerate animations -- only animate `transform` and `opacity`; never `width`, `height`, `top`, `left`, or `margin` - CLS near zero -- reserve space for images, fonts, and dynamic content (`aspect-ratio` on containers) - LCP under 2.5s -- optimize the critical rendering path for the hero - Loading states are designed elements -- custom skeletons and progress indicators, not afterthoughts **Applications:** subset/preload/swap fonts (`<link rel="preload" as="font" crossorigin>`); AVIF/WebP with responsive `srcset` (`<picture>` fallbacks); GPU-only animation (`transform: translate3d()` + `opacity`). Audit with Lighthouse targeting 90+; code-split and defer non-critical JS. **Ethical boundary:** Fast-but-inaccessible is not a valid tradeoff -- never strip accessibility features or semantic HTML for speed. See [references/technical-stack.md](references/technical-stack.md) when choosing libraries or hitting a perf budget -- the recommended stack and concrete font/image/animation optimization techniques. ### 7. Micro-Interactions **Core concept:** Craft lives in the 1% most designers skip: branded selection colors, magnetic buttons, designed focus states, considered loading states, crafted error pages, correct micro-typography. **IMPORTANT: Custom cursors are OPT-IN only.** Never replace the native cursor unless the user explicitly requests or confirms one -- misapplied custom cursors hurt usability and feel gimmicky. Always ask first. **Why it works:** Micro-interactions signal that every pixel was considered. Individually subtle, collectively transformative -- users feel the care embedded in the experience. **Key insights:** - Custom cursor reflects brand personality, with variants on interactive elements (subject to the opt-in rule above) - Branded `::selection` color that works on all backgrounds - Every link and card has a considered hover state -- scale, overlay, or meaningful transform - Focus states are visible AND beautiful -- on-brand indicators that keyboard users can clearly see - Loading, empty, 404, and error states are designed, helpful moments - Micro-typography is correct -- smart quotes, en/em dashes, no orphans on headlines, `text-wrap: balance` on key text **Ethical boundary:** Focus states must meet keyboard-visibility requirements even when styled on-brand, and error/empty/404 states must be genuinely helpful, not just decorative. See [references/animation-patterns.md](references/animation-patterns.md) for copy-pasteable magnetic-button, cursor, and `::selection`/hover micro-interaction code. ## Design Process Work in this order -- the sequence is the discipline: 1. **Concept before code.** Define four things first: ``` BRAND ESSENCE: What single word captures the soul? VISUAL TENSION: What opposing forces create interest? SIGNATURE MOMENT: What will people screenshot and share? TECHNICAL AMBITION: What pushes the browser's limits? ``` 2. **Design the signature moment first** -- not the header. Every 10/10 project has at least one moment people stop and share (a never-seen hero animation, typography bold enough to BE the visual, a scroll sequence that tells a story). Pin it down by asking: what will people screenshot, describe to a colleague, try to reverse-engineer, and what makes it unmistakably THIS project? 3. **Choose the display typeface next** -- it dictates the rest (Pillar 1). 4. **Prototype motion alongside visual design, not after** -- motion is not polish (Pillar 3). 5. **Ship with restraint** -- 3 things perfect beats 10 things mediocre. Cut ruthlessly. ## Implementation Notes 1. **Conceptualize desktop-first, build mobile-first** -- dream big, implement progressively 2. **Use project conventions** -- if Tailwind 4+ and/or shadcn/ui are available, extend their design tokens and components as the foundation for 10/10 craft rather than fighting them ## Common Mistakes Each fix points to the pillar that defines the rule -- do not re-derive values here. | Mistake | Why It Fails | Fix (see) | |---------|-------------|-----| | Inter, Roboto, Arial, or system-ui as primary typeface | Application fonts signal generic, not premium | Premium foundry or quality Google alternative (Pillar 1) | | Uniform type scale (everything within 2x) | No hierarchy, no gasping moments | Hit the display-to-body ratio (Pillar 1) | | `ease`, `ease-in`, `ease-out`, or `linear` easing | Mechanical, lifeless -- instantly signals amateur | Banned -- use a custom cubic-bezier (Pillar 3) | | Animating everything simultaneously | Visual noise, no hierarchy or narrative | Stagger and sequence by importance (Pillar 3) | | Center-aligning everything | Safe but boring -- no tension or energy | Asymmetry, grid offsets, bleeding elements (Pillar 2) | | Equal spacing everywhere | Monotony -- the eye has nowhere to rest | Vary density: dense sections, then breathing room (Pillar 2) | | Pure #000000 / #ffffff | Lifeless and harsh | Warm variants (Pillar 4) | | Default browser scroll | Mechanical, treats all content equally | Smooth-scroll library (Pillar 5) | | Purple-to-blue gradient hero | The "AI gradient" -- generic trend-following | Signature color approach specific to the project (Pillar 4) | | No signature moment | Competent but forgettable | Design the screenshot-worthy moment FIRST (Process step 2) | | Any emoji in professional interfaces | Signals casual/amateur craft | Custom iconography or typographic treatments | | Parallax on text or critical content | Motion sickness, accessibility failures | Parallax only on decorative background elements (Pillar 5) | | Animations blocking interaction | Hostile UX | Keep all animation non-blocking (Pillar 3) | | Unmodified Font Awesome icons | Template-level design | Custom icons, or heavily customize to match brand | | Default form styles | Breaks the illusion of craft instantly | Design every input, select, checkbox, and button (Pillar 7) | ## Quick Diagnostic Score 1 point per row answered "yes", then map the count to the Scoring Rubric band: 11-12 -> 9-10, 8-10 -> 7-8, 5-7 -> 5-6, below 5 -> 0-4. State that score. | Question | If No | Fix (see) | |----------|-------|--------| | Does the hero typography make someone pause mid-scroll? | Display type not commanding | Pillar 1 -- scale, distinctive typeface, viewport-filling | | Would someone screenshot any section? | No signature moment | Process step 2 -- make one section extraordinary | | Does the design still read when you blur your eyes? | Hierarchy too flat | Bigger headlines, more white space, stronger accents | | Are all easing curves custom (no `ease`/`linear`)? | Motion feels default | Pillar 3 -- custom cubic-bezier | | Is there asymmetric tension in the composition? | Layout feels safe | Pillar 2 -- offset, bleed, vary density | | Do the colors feel invented for THIS project? | Generic palette | Pillar 4 -- monochromatic tension, signature, or contextual | | Is the page load choreographed? | Elements pop in at once | Pillar 3 -- staggered reveal sequence | | Does scroll feel custom and weighted? | Default browser scroll | Pillar 5 -- smooth-scroll library | | Are micro-details considered (selection, focus, cursor)? | Default browser behaviors remain | Pillar 7 -- branded selection, designed focus (cursors opt-in) | | Is CLS near zero and LCP under 2.5s? | Performance undermines quality | Pillar 6 -- subset fonts, WebP/AVIF, transform/opacity only | | Does every animation answer "why does this move?" | Decorative motion | Pillar 3 -- cut motion with no narrative or guidance | | Are focus states both beautiful AND accessible? | One sacrificed for the other | Pillar 7 -- on-brand indicators meeting WCAG visibility | ## Further Reading - [Designing with Type](https://www.amazon.com/Designing-Type-Essential-Typography/dp/0823014134?tag=wondelai00-20) by James Craig -- foundational text on typographic principles and hierarchy - [Grid Systems in Graphic Design](https://www.amazon.com/Grid-Systems-Graphic-Design-Communication/dp/3721201450?tag=wondelai00-20) by Josef Muller-Brockmann -- the definitive work on grid-based composition - [The Elements of Typographic Style](https://www.amazon.com/Elements-Typographic-Style-Version-4-0/dp/0881792128?tag=wondelai00-20) by Robert Bringhurst -- the typographer's bible on rhythm, proportion, and craft - [Interaction of Color](https://www.amazon.com/Interaction-Color-50th-Anniversary-Edition/dp/0300179359?tag=wondelai00-20) by Josef Albers -- essential reading on color perception and contrast - [Layout Essentials: 100 Design Principles for Using Grids](https://www.amazon.com/Layout-Essentials-Design-Principles-Using/dp/1592537073?tag=wondelai00-20) by Beth Tondreau -- practical grid-based layout principles - [Awwwards Annual: The Best 365 Websites Around the World](https://www.awwwards.com/books/) -- yearly benchmark collection for 10/10 craft ## About the Author This skill synthesizes techniques from the world's most awarded digital agencies: **Locomotive** (Montreal -- creators of Locomotive Scroll, masters of monochromatic tension and bold typography), **Studio Freight** (New York -- magnetic interactions and signature palettes), **AREA 17** (New York/Paris -- contextual design systems and editorial layouts), **Active Theory** (Los Angeles -- WebGL and immersive 3D storytelling), and **Hello Monday** (Copenhagen/New York -- playful interactions for Spotify, Adidas, Google). Additional inspiration from Dogstudio, Tonik, Instrument, Resn, and the broader Awwwards, FWA, CSS Design Awards, and Webby winner community.
Comments (0)
Sign in to join the conversation.
Reviews (0)
No reviews yet.
No comments yet.