复制安装命令
用 Codex 或 Claude 安装复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它先审查 Skill 页面再帮你安装。
复制前请先查看来源、License 和安全提示。
Put your AI agent on the growth team.
用 Codex 或 Claude 安装复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它先审查 Skill 页面再帮你安装。
复制前请先查看来源、License 和安全提示。
来源文件:README.md
Put your AI agent on the growth team.
Research customers and competitors, analyze what is working, create the next campaign, and learn from the result. Goose Skills gives Claude Code, Cursor, Codex, and other coding agents ready-to-use workflows for ads, social media, content, competitive intelligence, SEO, lead generation, and GTM.
Browse all skills at https://skills.gooseworks.ai
Works with Claude Code · Cursor · Codex
Paste this into your coding agent (Claude Code, Cursor, or Codex) and it'll set everything up:
Install the Gooseworks skills:
In the terminal, run `npx gooseworks install --all`.
Then run `npx gooseworks login` and it'll open a browser to sign in and set up the tools, then confirm it worked.
The skills can be used with /gooseworks <prompt>
Run this command in a terminal first:
npx gooseworks install --all
Then authenticate:
npx gooseworks login
Then make sure you're working inside a local folder on your machine, and then you can use the skills in Cowork like this:
Use /gooseworks skill to generate some ad creatives
Prefer to run it yourself? Use the command directly:
npx gooseworks install --all # All detected agents
This gives your coding agent access to the full catalog of 200+ skills. After installing, just ask your agent to use any skill by name.
If you want a cloud-based AI coworker that already knows all these skills and more, sign up to Gooseworks
The Brand Growth collection is a curated path through the normal Goose Skills catalog for consumer and ecommerce brand work. It is not a separate package or command: install GooseWorks once, then ask /gooseworks for the outcome you need.
| Stage | What your agent can do | Example skills |
|---|---|---|
| Research | Understand the brand, customers, competitors, audiences, creators, trends, comments, and product demand | brand-research, audience-research, comment-mining, competitor-social-research, influencer-prospecting, trend-discovery, product-demand-research |
| Analyze | Diagnose ads, creator profiles, transcripts, policy risk, landing-page message match, and unusual social performance | competitor-ad-intelligence, creator-profile-teardown, transcript-intelligence, meta-ads-analyzer, meta-ad-policy-checker, ad-to-landing-page-auditor, outlier-post-finder |
| Create | Repurpose research, remix graphic ads, make product photography and social graphics, and animate static images | content-repurposing, remix-graphic-ad-from-reference, product-photoshoot, goose-graphics, animate-image |
| Learn and iterate | Bring results back into research and analysis, then decide the next test | Re-run the relevant analysis skill with current performance and audience evidence |
ScrapeCreators powers structured public social and ad-library research behind several workflows. Signed-in GooseWorks users access it through the managed first-party proxy and do not need a separate ScrapeCreators key. The user-facing skills turn that source data into a brief, shortlist, analysis, or recommendation instead of returning raw API output.
Browse the Brand Growth collection
After installation, start with:
/gooseworks onboard me
The agent will collect the useful company context for future growth work and finish by asking what you want to do first. Existing users can skip onboarding and keep using /gooseworks exactly as they do today.
npx gooseworks search "reddit scraping" # Search the skill catalog
npx gooseworks credits # Check your credit balance
npx gooseworks update # Update to latest skill version
200+ skills across the growth stack, grouped by focus area:
| Category | What's inside |
|---|---|
| Ads | Research, build, and analyze paid campaigns across Meta and Google |
| SEO | Keyword research, content gaps, SERP analysis, technical audits |
| Lead generation | Find, enrich, and qualify prospects for your pipeline |
| Outreach | Draft, personalize, and run outbound across email and social |
| Content | Blog posts, social content, carousels, video scripts, newsletters |
| Research | Company, market, and prospect deep-dives |
| Competitive intel | Track competitor pricing, launches, positioning, and ads |
| Monitoring | Watch for mentions, signals, and changes across the web |
| Social | Scrape and analyze social platforms and audiences |
| Brand | Voice, positioning, and visual brand assets |
Browse and search every skill at skills.gooseworks.ai.
After installing, just ask your coding agent naturally:
"/gooseworks Generate static ad creatives for my brand"
"/gooseworks Use the reddit-post-finder skill to search r/startups"
"/gooseworks Use the apollo-lead-finder skill to find CTOs at AI companies"
"/gooseworks Use the competitor-intel skill to research Acme Corp"
"/gooseworks Use the goose-graphics skill to create a LinkedIn carousel about our launch"
Your agent will search the GooseWorks catalog, download the skill, and run it automatically.
git clone https://github.com/gooseworks-ai/goose-skills.git
cd goose-skills
node scripts/validate-skills.js # Validate SKILL.md + skill.meta.json contract
node scripts/build-index.js # Generate skills-index.json
node bin/goose-skills.js list # Test locally
Each skill directory must include:
SKILL.md — Skill documentation and usage guideskill.meta.json — Machine-readable metadataskill.meta.json fields:
| Field | Required | Description |
|---|---|---|
slug | Yes | Unique kebab-case identifier |
category | Yes | capabilities, composites, or playbooks |
tags | Yes | String array of category tags |
installation.base_command | Yes | Install command |
installation.supports | Yes | Array: claude, codex, cursor |
features | No | Feature flags |
github_url | No | Source repository URL |
author | No | Skill author |
example_prompt | No | Copyable prompt shown in the catalog and docs for trying the skill |
These skills run inside your coding agent, so it's worth knowing exactly what they do:
SKILL.md instructions and all scripts — lives in this repo under the MIT license. The gooseworks CLI fetches skills at runtime so recipes stay current, but the source you'd run is right here to read, diff, or pin before you run it./tmp/gooseworks-scripts/, never into your project directory. Only API requests go through GooseWorks servers; review any script before letting your agent run it.SKILL.md to tune that behavior.~/.gooseworks/credentials.json (file mode 0600). Third-party provider keys (Apify, Apollo, etc.) are held server-side — your token never touches them. All network calls are HTTPS.gooseworks install --mcp.Found something that looks off? Open an issue — we'd rather fix it in public.
MIT — see LICENSE for details.
The skill files and CLI in this repository are MIT-licensed. The GooseWorks API they connect to is a separate paid service governed by its own terms.
Built by GooseWorks
name: frontend-slides
description: Create stunning, animation-rich HTML presentations from scratch or by converting PowerPoint files. Use when the user wants to build a presentation, convert a PPT/PPTX to web, or create slides for a talk/pitch. Helps non-designers discover their aesthetic through visual exploration rather than abstract choices.Deprecated: This skill is superseded by
goose-graphics. Seeskills/composites/goose-graphics/(install withnpx goose-skills install goose-graphics). The slides format is one of seven formats in the newer skill and supports 36 style presets plus image sourcing and PNG export. This skill is retained for one release cycle before removal.
Create zero-dependency, animation-rich HTML presentations that run entirely in the browser. This skill helps non-designers discover their preferred aesthetic through visual exploration ("show, don't tell"), then generates production-quality slide decks.
This section is mandatory for ALL presentations. Every slide must be fully visible without scrolling on any screen size.
Each slide = exactly one viewport height (100vh/100dvh)
Content overflows? → Split into multiple slides or reduce content
Never scroll within a slide.
To guarantee viewport fitting, enforce these limits per slide:
| Slide Type | Maximum Content |
|---|---|
| Title slide | 1 heading + 1 subtitle + optional tagline |
| Content slide | 1 heading + 4-6 bullet points OR 1 heading + 2 paragraphs |
| Feature grid | 1 heading + 6 cards maximum (2x3 or 3x2 grid) |
| Code slide | 1 heading + 8-10 lines of code maximum |
| Quote slide | 1 quote (max 3 lines) + attribution |
| Image slide | 1 heading + 1 image (max 60vh height) |
If content exceeds these limits → Split into multiple slides
Every presentation MUST include this base CSS for viewport fitting:
/* ===========================================
VIEWPORT FITTING: MANDATORY BASE STYLES
These styles MUST be included in every presentation.
They ensure slides fit exactly in the viewport.
=========================================== */
/* 1. Lock html/body to viewport */
html, body {
height: 100%;
overflow-x: hidden;
}
html {
scroll-snap-type: y mandatory;
scroll-behavior: smooth;
}
/* 2. Each slide = exact viewport height */
.slide {
width: 100vw;
height: 100vh;
height: 100dvh; /* Dynamic viewport height for mobile browsers */
overflow: hidden; /* CRITICAL: Prevent ANY overflow */
scroll-snap-align: start;
display: flex;
flex-direction: column;
position: relative;
}
/* 3. Content container with flex for centering */
.slide-content {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
max-height: 100%;
overflow: hidden; /* Double-protection against overflow */
padding: var(--slide-padding);
}
/* 4. ALL typography uses clamp() for responsive scaling */
:root {
/* Titles scale from mobile to desktop */
--title-size: clamp(1.5rem, 5vw, 4rem);
--h2-size: clamp(1.25rem, 3.5vw, 2.5rem);
--h3-size: clamp(1rem, 2.5vw, 1.75rem);
/* Body text */
--body-size: clamp(0.75rem, 1.5vw, 1.125rem);
--small-size: clamp(0.65rem, 1vw, 0.875rem);
/* Spacing scales with viewport */
--slide-padding: clamp(1rem, 4vw, 4rem);
--content-gap: clamp(0.5rem, 2vw, 2rem);
--element-gap: clamp(0.25rem, 1vw, 1rem);
}
/* 5. Cards/containers use viewport-relative max sizes */
.card, .container, .content-box {
max-width: min(90vw, 1000px);
max-height: min(80vh, 700px);
}
/* 6. Lists auto-scale with viewport */
.feature-list, .bullet-list {
gap: clamp(0.4rem, 1vh, 1rem);
}
.feature-list li, .bullet-list li {
font-size: var(--body-size);
line-height: 1.4;
}
/* 7. Grids adapt to available space */
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(100%, 250px), 1fr));
gap: clamp(0.5rem, 1.5vw, 1rem);
}
/* 8. Images constrained to viewport */
img, .image-container {
max-width: 100%;
max-height: min(50vh, 400px);
object-fit: contain;
}
/* ===========================================
RESPONSIVE BREAKPOINTS
Aggressive scaling for smaller viewports
=========================================== */
/* Short viewports (< 700px height) */
@media (max-height: 700px) {
:root {
--slide-padding: clamp(0.75rem, 3vw, 2rem);
--content-gap: clamp(0.4rem, 1.5vw, 1rem);
--title-size: clamp(1.25rem, 4.5vw, 2.5rem);
--h2-size: clamp(1rem, 3vw, 1.75rem);
}
}
/* Very short viewports (< 600px height) */
@media (max-height: 600px) {
:root {
--slide-padding: clamp(0.5rem, 2.5vw, 1.5rem);
--content-gap: clamp(0.3rem, 1vw, 0.75rem);
--title-size: clamp(1.1rem, 4vw, 2rem);
--body-size: clamp(0.7rem, 1.2vw, 0.95rem);
}
/* Hide non-essential elements */
.nav-dots, .keyboard-hint, .decorative {
display: none;
}
}
/* Extremely short (landscape phones, < 500px height) */
@media (max-height: 500px) {
:root {
--slide-padding: clamp(0.4rem, 2vw, 1rem);
--title-size: clamp(1rem, 3.5vw, 1.5rem);
--h2-size: clamp(0.9rem, 2.5vw, 1.25rem);
--body-size: clamp(0.65rem, 1vw, 0.85rem);
}
}
/* Narrow viewports (< 600px width) */
@media (max-width: 600px) {
:root {
--title-size: clamp(1.25rem, 7vw, 2.5rem);
}
/* Stack grids vertically */
.grid {
grid-template-columns: 1fr;
}
}
/* ===========================================
REDUCED MOTION
Respect user preferences
=========================================== */
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
transition-duration: 0.2s !important;
}
html {
scroll-behavior: auto;
}
}
Before generating any presentation, mentally verify:
.slide has height: 100vh; height: 100dvh; overflow: hidden;clamp(min, preferred, max)clamp() or viewport unitsmax-height constraintsmax-height: min(50vh, 400px) or similarauto-fit with minmax() for responsive columnsIf you find yourself with too much content:
DO:
DON'T:
After generating, recommend the user test at these sizes:
First, determine what the user wants:
Mode A: New Presentation
Mode B: PPT Conversion
Mode C: Existing Presentation Enhancement
Before designing, understand the content. Ask via AskUserQuestion:
Question 1: Purpose
Question 2: Slide Count
Question 3: Content
If user has content, ask them to share it (text, bullet points, images, etc.).
CRITICAL: This is the "show, don't tell" phase.
Most people can't articulate design preferences in words. Instead of asking "do you want minimalist or bold?", we generate mini-previews and let them react.
Users can select a style in two ways:
Option A: Guided Discovery (Default)
Option B: Direct Selection
Available Presets:
| Preset | Vibe | Best For |
|---|---|---|
| Bold Signal | Confident, high-impact | Pitch decks, keynotes |
| Electric Studio | Clean, professional | Agency presentations |
| Creative Voltage | Energetic, retro-modern | Creative pitches |
| Dark Botanical | Elegant, sophisticated | Premium brands |
| Notebook Tabs | Editorial, organized | Reports, reviews |
| Pastel Geometry | Friendly, approachable | Product overviews |
| Split Pastel | Playful, modern | Creative agencies |
| Vintage Editorial | Witty, personality-driven | Personal brands |
| Neon Cyber | Futuristic, techy | Tech startups |
| Terminal Green | Developer-focused | Dev tools, APIs |
| Swiss Modern | Minimal, precise | Corporate, data |
| Paper & Ink | Literary, thoughtful | Storytelling |
First, ask how the user wants to choose their style:
Question: Style Selection Method
If "Show me options" → Continue to Step 2.1 (Mood Selection)
If "I know what I want" → Show preset picker:
Question: Pick a Preset
(If user picks one, skip to Phase 3. If they want to see more options, show additional presets or proceed to guided discovery.)
If "Use client branding" → Load client visual identity:
clients/<client-name>/brand/visual-identity.md:root custom properties as the presentation's theme variables, its typography as the font pairing, its font loading <link> tag, and its signature elements as design guidance for decorative CSS.visual-brand-extractor skill to generate the file, and continue.Question 1: Feeling
Based on their mood selection, generate 3 distinct style previews as mini HTML files in a temporary directory. Each preview should be a single title slide showing:
Preview Styles to Consider (pick 3 based on mood):
| Mood | Style Options |
|---|---|
| Impressed/Confident | "Bold Signal", "Electric Studio", "Dark Botanical" |
| Excited/Energized | "Creative Voltage", "Neon Cyber", "Split Pastel" |
| Calm/Focused | "Notebook Tabs", "Paper & Ink", "Swiss Modern" |
| Inspired/Moved | "Dark Botanical", "Vintage Editorial", "Pastel Geometry" |
IMPORTANT: Never use these generic patterns:
Instead, use distinctive choices:
Create the previews in: .claude-design/slide-previews/
.claude-design/slide-previews/
├── style-a.html # First style option
├── style-b.html # Second style option
├── style-c.html # Third style option
└── assets/ # Any shared assets
Each preview file should be:
Present to user:
I've created 3 style previews for you to compare:
**Style A: [Name]** — [1 sentence description]
**Style B: [Name]** — [1 sentence description]
**Style C: [Name]** — [1 sentence description]
Open each file to see them in action:
- .claude-design/slide-previews/style-a.html
- .claude-design/slide-previews/style-b.html
- .claude-design/slide-previews/style-c.html
Take a look and tell me:
1. Which style resonates most?
2. What do you like about it?
3. Anything you'd change?
Then use AskUserQuestion:
Question: Pick Your Style
If "Mix elements", ask for specifics.
Now generate the full presentation based on:
For single presentations:
presentation.html # Self-contained presentation
assets/ # Images, if any
For projects with multiple presentations:
[presentation-name].html
[presentation-name]-assets/
Follow this structure for all presentations:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Presentation Title</title>
<!-- Fonts (use Fontshare or Google Fonts) -->
<link rel="stylesheet" href="https://api.fontshare.com/v2/css?f[]=...">
<style>
/* ===========================================
CSS CUSTOM PROPERTIES (THEME)
Easy to modify: change these to change the whole look
=========================================== */
:root {
/* Colors */
--bg-primary: #0a0f1c;
--bg-secondary: #111827;
--text-primary: #ffffff;
--text-secondary: #9ca3af;
--accent: #00ffcc;
--accent-glow: rgba(0, 255, 204, 0.3);
/* Typography - MUST use clamp() for responsive scaling */
--font-display: 'Clash Display', sans-serif;
--font-body: 'Satoshi', sans-serif;
--title-size: clamp(2rem, 6vw, 5rem);
--subtitle-size: clamp(0.875rem, 2vw, 1.25rem);
--body-size: clamp(0.75rem, 1.2vw, 1rem);
/* Spacing - MUST use clamp() for responsive scaling */
--slide-padding: clamp(1.5rem, 4vw, 4rem);
--content-gap: clamp(1rem, 2vw, 2rem);
/* Animation */
--ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
--duration-normal: 0.6s;
}
/* ===========================================
BASE STYLES
=========================================== */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
scroll-snap-type: y mandatory;
height: 100%;
}
body {
font-family: var(--font-body);
background: var(--bg-primary);
color: var(--text-primary);
overflow-x: hidden;
height: 100%;
}
/* ===========================================
SLIDE CONTAINER
CRITICAL: Each slide MUST fit exactly in viewport
- Use height: 100vh (NOT min-height)
- Use overflow: hidden to prevent scroll
- Content must scale with clamp() values
=========================================== */
.slide {
width: 100vw;
height: 100vh; /* EXACT viewport height - no scrolling */
height: 100dvh; /* Dynamic viewport height for mobile */
padding: var(--slide-padding);
scroll-snap-align: start;
display: flex;
flex-direction: column;
justify-content: center;
position: relative;
overflow: hidden; /* Prevent any content overflow */
}
/* Content wrapper that prevents overflow */
.slide-content {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
max-height: 100%;
overflow: hidden;
}
/* ===========================================
RESPONSIVE BREAKPOINTS
Adjust content for different screen sizes
=========================================== */
@media (max-height: 600px) {
:root {
--slide-padding: clamp(1rem, 3vw, 2rem);
--content-gap: clamp(0.5rem, 1.5vw, 1rem);
}
}
@media (max-width: 768px) {
:root {
--title-size: clamp(1.5rem, 8vw, 3rem);
}
}
@media (max-height: 500px) and (orientation: landscape) {
/* Extra compact for landscape phones */
:root {
--title-size: clamp(1.25rem, 5vw, 2rem);
--slide-padding: clamp(0.75rem, 2vw, 1.5rem);
}
}
/* ===========================================
ANIMATIONS
Trigger via .visible class (added by JS on scroll)
=========================================== */
.reveal {
opacity: 0;
transform: translateY(30px);
transition: opacity var(--duration-normal) var(--ease-out-expo),
transform var(--duration-normal) var(--ease-out-expo);
}
.slide.visible .reveal {
opacity: 1;
transform: translateY(0);
}
/* Stagger children */
.reveal:nth-child(1) { transition-delay: 0.1s; }
.reveal:nth-child(2) { transition-delay: 0.2s; }
.reveal:nth-child(3) { transition-delay: 0.3s; }
.reveal:nth-child(4) { transition-delay: 0.4s; }
/* ... more styles ... */
</style>
</head>
<body>
<!-- Progress bar (optional) -->
<div class="progress-bar"></div>
<!-- Navigation dots (optional) -->
<nav class="nav-dots">
<!-- Generated by JS -->
</nav>
<!-- Slides -->
<section class="slide title-slide">
<h1 class="reveal">Presentation Title</h1>
<p class="reveal">Subtitle or author</p>
</section>
<section class="slide">
<h2 class="reveal">Slide Title</h2>
<p class="reveal">Content...</p>
</section>
<!-- More slides... -->
<script>
/* ===========================================
SLIDE PRESENTATION CONTROLLER
Handles navigation, animations, and interactions
=========================================== */
class SlidePresentation {
constructor() {
// ... initialization
}
// ... methods
}
// Initialize
new SlidePresentation();
</script>
</body>
</html>
Every presentation should include:
SlidePresentation Class — Main controller
Intersection Observer — For scroll-triggered animations
.visible class when slides enter viewportOptional Enhancements (based on style):
Comments: Every section should have clear comments explaining:
/* ===========================================
CUSTOM CURSOR
Creates a stylized cursor that follows mouse with a trail effect.
- Uses lerp (linear interpolation) for smooth movement
- Grows larger when hovering over interactive elements
=========================================== */
class CustomCursor {
constructor() {
// ...
}
}
Accessibility:
<section>, <nav>, <main>)@media (prefers-reduced-motion: reduce) {
.reveal {
transition: opacity 0.3s ease;
transform: none;
}
}
Responsive & Viewport Fitting (CRITICAL):
See the "CRITICAL: Viewport Fitting Requirements" section above for complete CSS and guidelines.
Quick reference:
.slide must have height: 100vh; height: 100dvh; overflow: hidden;clamp()When converting PowerPoint files:
Use Python with python-pptx to extract:
from pptx import Presentation
from pptx.util import Inches, Pt
import json
import os
import base64
def extract_pptx(file_path, output_dir):
"""
Extract all content from a PowerPoint file.
Returns a JSON structure with slides, text, and images.
"""
prs = Presentation(file_path)
slides_data = []
# Create assets directory
assets_dir = os.path.join(output_dir, 'assets')
os.makedirs(assets_dir, exist_ok=True)
for slide_num, slide in enumerate(prs.slides):
slide_data = {
'number': slide_num + 1,
'title': '',
'content': [],
'images': [],
'notes': ''
}
for shape in slide.shapes:
# Extract title
if shape.has_text_frame:
if shape == slide.shapes.title:
slide_data['title'] = shape.text
else:
slide_data['content'].append({
'type': 'text',
'content': shape.text
})
# Extract images
if shape.shape_type == 13: # Picture
image = shape.image
image_bytes = image.blob
image_ext = image.ext
image_name = f"slide{slide_num + 1}_img{len(slide_data['images']) + 1}.{image_ext}"
image_path = os.path.join(assets_dir, image_name)
with open(image_path, 'wb') as f:
f.write(image_bytes)
slide_data['images'].append({
'path': f"assets/{image_name}",
'width': shape.width,
'height': shape.height
})
# Extract notes
if slide.has_notes_slide:
notes_frame = slide.notes_slide.notes_text_frame
slide_data['notes'] = notes_frame.text
slides_data.append(slide_data)
return slides_data
Present the extracted content to the user:
I've extracted the following from your PowerPoint:
**Slide 1: [Title]**
- [Content summary]
- Images: [count]
**Slide 2: [Title]**
- [Content summary]
- Images: [count]
...
All images have been saved to the assets folder.
Does this look correct? Should I proceed with style selection?
Proceed to Phase 2 (Style Discovery) with the extracted content in mind.
Convert the extracted content into the chosen style, preserving:
When the presentation is complete:
Clean up temporary files
.claude-design/slide-previews/ if it existsOpen the presentation
open [filename].html to launch in browserProvide summary
Your presentation is ready!
📁 File: [filename].html
🎨 Style: [Style Name]
📊 Slides: [count]
**Navigation:**
- Arrow keys (← →) or Space to navigate
- Scroll/swipe also works
- Click the dots on the right to jump to a slide
**To customize:**
- Colors: Look for `:root` CSS variables at the top
- Fonts: Change the Fontshare/Google Fonts link
- Animations: Modify `.reveal` class timings
Would you like me to make any adjustments?
Use this guide to match animations to intended feelings:
/* Fade + Slide Up (most common) */
.reveal {
opacity: 0;
transform: translateY(30px);
transition: opacity 0.6s var(--ease-out-expo),
transform 0.6s var(--ease-out-expo);
}
.visible .reveal {
opacity: 1;
transform: translateY(0);
}
/* Scale In */
.reveal-scale {
opacity: 0;
transform: scale(0.9);
transition: opacity 0.6s, transform 0.6s var(--ease-out-expo);
}
/* Slide from Left */
.reveal-left {
opacity: 0;
transform: translateX(-50px);
transition: opacity 0.6s, transform 0.6s var(--ease-out-expo);
}
/* Blur In */
.reveal-blur {
opacity: 0;
filter: blur(10px);
transition: opacity 0.8s, filter 0.8s var(--ease-out-expo);
}
/* Gradient Mesh */
.gradient-bg {
background:
radial-gradient(ellipse at 20% 80%, rgba(120, 0, 255, 0.3) 0%, transparent 50%),
radial-gradient(ellipse at 80% 20%, rgba(0, 255, 200, 0.2) 0%, transparent 50%),
var(--bg-primary);
}
/* Noise Texture */
.noise-bg {
background-image: url("data:image/svg+xml,..."); /* Inline SVG noise */
}
/* Grid Pattern */
.grid-bg {
background-image:
linear-gradient(rgba(255,255,255,0.03) 1px, transparent 1px),
linear-gradient(90deg, rgba(255,255,255,0.03) 1px, transparent 1px);
background-size: 50px 50px;
}
/* 3D Tilt on Hover */
class TiltEffect {
constructor(element) {
this.element = element;
this.element.style.transformStyle = 'preserve-3d';
this.element.style.perspective = '1000px';
this.bindEvents();
}
bindEvents() {
this.element.addEventListener('mousemove', (e) => {
const rect = this.element.getBoundingClientRect();
const x = (e.clientX - rect.left) / rect.width - 0.5;
const y = (e.clientY - rect.top) / rect.height - 0.5;
this.element.style.transform = `
rotateY(${x * 10}deg)
rotateX(${-y * 10}deg)
`;
});
this.element.addEventListener('mouseleave', () => {
this.element.style.transform = 'rotateY(0) rotateX(0)';
});
}
}
Fonts not loading:
Animations not triggering:
.visible class is being addedScroll snap not working:
scroll-snap-type on html/bodyscroll-snap-align: startMobile issues:
Performance issues:
will-change sparinglytransform and opacity animations
评论 (0)
暂无评论,成为第一个评论者吧!