用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/tomevault-io/skills-registry --skill premium-web-design命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
| Use when this capability is needed.
> Use when this capability is needed.
Review architecture and API design for the vfs-s3 project. Use when the user mentions @architect, asks to review an issue's design, discuss module boundaries, API shape, or architectural decisions for vfs-s3. Also trigger when the user wants to create an ADR (Architecture Decision Record) or evaluate a technical approach for the project. Intended for dispatch from Codex automation or Claude routines; GitHub trigger phrase: @vfs-s3-bot please prepare design doc Use when this capability is needed.
基于 SOC 职业分类
正在显示 SKILL.md
| name | premium-web-design |
| description | > Use when this capability is needed. |
Create React (.jsx) components that look like they belong on Awwwards — the kind of work that makes people ask "who designed this?" These are sites where every pixel is intentional, every animation is choreographed, and the overall impression is that serious creative talent and budget were involved.
Most AI-generated websites share a recognizable DNA. Avoiding it requires knowing exactly what it looks like.
Typography sins
Color sins
Layout sins
Motion sins
Imagery & decoration sins
Premium web design communicates craft through restraint, surprise, and obsessive attention to detail.
Typography is the #1 differentiator between a $500 website and a $50,000 one.
Font selection philosophy:
Typography execution:
clamp() for fluid type scaling instead of breakpoint jumps-0.03em to -0.06em)max-width on paragraphs (45–75ch) and text-wrap: balance on headings0.1em+) for categories, dates, metadata#ffffff or #000000) feel more designed — try #FAFAF8, #F5F0EB, #1A1A1A, #0D0D0DThe #1 failure mode of this skill is producing sites that look different on the surface but share the same underlying structure — a hero, three editorial sections, a pull quote, a form, a colophon. Over a batch of sites this starts to feel like a template with different colors. Fight this actively, and deliberately.
The structural DNA uniqueness rule:
Before writing any markup, name the primary structural concept out loud — a single noun phrase, like "index manuscript" or "sticky horizontal diorama". Inside one batch of sites, no two sites may share the same primary structural concept. If the previous site was a sticky-scroll narrative, this one is not. If the previous site was a 33/67 vertical split, this one is not. The structural idea is the first thing the user notices — varying color without varying structure is cosmetic.
These are distinct primary structures. Each skill invocation should pick a concept and commit to it. Do not mix two structures into one site (it dilutes both).
position: sticky + translateX driven by scroll. (Good for: a timeline of commissions, a process in stages, a collection of artifacts.)How to pick the concept:
Layout principles (apply within whichever structural concept you pick):
8rem+ between sections.Specific micro-patterns that read as premium:
Banned repeats (within a skill session):
Nav-bar variety — a silent failure mode to watch.
The easiest default is a grid-template-columns: auto 1fr auto top bar with "brand mark on the left, something centred, something right-aligned, mix-blend-mode: difference". After three sites, it starts to read as a signature — not a design choice. In each session, vary the nav substantially:
⌘K launcher (tech-product brands — Cursor / Linear / Arc).Pick the nav that belongs to the brand and the structural DNA — do not default to the three-column top bar.
Avoid the editorial-luxury default.
This skill gravitates, under pressure, toward: warm cream ground, serif display (Fraunces / Cormorant), monospace metadata, a single brass accent, wide-tracked uppercase micro-labels, ◦ bullet symbols. It's a real aesthetic, appropriate for couture, parfumerie, haute cuisine, horlogerie. It is not appropriate for tech, AI, cybersecurity, consumer electronics, SaaS, or developer tooling — and repeatedly defaulting to it makes every site in a batch look like the same agency did them.
If the field is technology, the aesthetic should skew toward: pure-white or near-black grounds (not cream); neo-grotesque sans-serifs (Söhne-feel, Inter Tight, IBM Plex Sans, Instrument Sans) as display type; monospace used as display, not just metadata; gradient-glow edges, shipped UI screenshots, live-feeling dashboard tiles, keyboard-shortcut chips inline with copy, code blocks rendered as the hero, iridescent/chrome/glass textures rather than brass-and-paper. See Vercel, Cursor, Linear, Windsurf, Stripe, Figma, Arc, Zed, Raycast, Supabase, v0.dev, Anthropic, OpenAI.
Every website built with this skill features 3D components. This is what makes these sites stand out from flat designs. But the 3D must look professional and polished — amateur 3D is worse than no 3D.
DO NOT build 3D objects from Three.js geometric primitives (boxes, cylinders, cones, spheres). Cars built from boxes look like toys. Rockets built from cylinders look like diagrams. Fire built from cones looks terrible. Three.js primitives are only acceptable for subtle atmospheric background effects (particle fields, grid planes, floating dots) — never as the main hero visual.
Most AI-generated "premium" sites look generic because the research step is skipped or done to a depth of two sentences. A real reference pull is the single biggest quality lever in this skill.
Depth requirement: Study at least 5 real reference sites (not 2) — a mix of the most obvious industry leaders and less-famous editorial/cultural operators in the same space. The less-famous references are usually where the unique moves come from; the famous ones anchor the palette.
Starting reference sets (expand, don't stop here):
⌘K, ⌘↵), gradient glow edges, animated code blocks in hero, dashboard-tile grids, sub-section headers in small-caps monospace, <code>-styled callouts. Interactive hero often = an animated product UI snapshot, not a still image.How to do the research pass:
web_search: "[field] award-winning website", "[field] Awwwards", site:awwwards.com [field], "[field] FWA winner". At least 2 of the 5 should be less-obvious editorial/cultural references, not the industry giants.web_fetch. Pull patterns, not vibes. For each site, note specifically: primary display font, secondary body font, palette as hex approximations, structural DNA (which concept from the catalog), one signature move unique to that site.The design you build should feel like it belongs alongside these real competitors — not like it came from a different universe, and not like it's a carbon copy of any single one.
Spline (spline.design) is a 3D design platform with a large community library of professional, embeddable 3D scenes. A Spline scene only earns its place on a premium site if a visitor, glancing at it, immediately understands what it represents. A beautiful scene that has nothing to do with the subject is worse than no scene — it erodes the sense that every pixel is intentional, and reads as "some cool 3D the designer found," which is the opposite of premium.
Spline community scenes often depict real, trademarked products: a Nike Air Jordan, a Sony WH-1000XM5, an Apple Watch, a Beats Studio, a Samsung Galaxy, a Tesla Cybertruck. These are not usable for a fictional brand's website. Using them creates three compounding problems:
Rule: Before committing a Spline scene, ask: Is the object in this scene a real, identifiable product from a real brand? If yes — reject it, no matter how well-rendered it is. Look for abstract, category-representative, or original-design scenes instead:
If no non-branded alternative exists for the subject, either (a) fall back to photography of a generic, unbranded product, (b) build an SVG illustration, or (c) pick a different field.
An easy failure mode: you have a usable Spline URL in hand, and you invent a field to justify using it. This reads as desperation. "A fountain-pen ink maker" does not exist as a premium brand in the world because someone wanted one — it exists because you had a dark-fluid scene and built a house of cards around it. The prompt gives it away.
The correct order is:
my.spline.design/ and prod.spline.design/ URLs.A healthy batch of sites spans genuinely-different industries a reader recognises. A batch of sites whose shared thread is "whichever field the available Spline URLs imply" is not a portfolio — it's a rationalisation.
Within a single session / batch of sites, no two sites may use the same Spline scene URL. Reusing a scene across multiple houses reads like a stock-photo library showing through, and undoes the SKILL's entire claim that each site is its own identity.
worldplanet on one site, don't use it on the next, no matter how directly it "fits" the new field. Find a different scene.prompt.md, list the Spline URLs already used in this session by the previous sites. Confirm the new site's URL is NOT in that list.A Spline scene is acceptable only when it literally depicts the subject of the site's brand. Metaphorical links are rejected, even if they're poetic:
Before using any Spline scene, state out loud in the prompt.md: "The scene depicts X. My site's subject is X." If those two X's are not the same noun, reject the scene. The brand itself must be in the business of whatever the scene shows — not merely invoke it symbolically.
The two-second test still applies: with no caption, a viewer should name the subject of the scene. A "nice abstract composition" is not a subject.
A Spline scene has its own backdrop color and lighting mood baked into the render. If that backdrop fights the site's palette, the scene will look cut out and pasted on — amateurish, no matter how premium the 3D itself is. Before committing a scene, check:
Write down, in the prompt.md, the scene's native backdrop color and the site's ground color. If they're opposite and there's no framed-viewport treatment, pick a different scene or pick a different theme.
Never search Spline for just the topic word. A single-keyword search misses 90% of relevant scenes — most creators title their work by what's in it (wheel, tire, headlight) rather than the category.
Before searching, build a keyword map of at least 8–12 terms covering:
Also search Awwwards, Codrops, Tympanus, Dribbble, Twitter/X, and production-site HTML ("<iframe" "my.spline.design", "<spline-viewer" "scene.splinecode", site:codepen.io "my.spline.design", site:github.com "my.spline.design"). URLs found inside working iframes on live sites are guaranteed to render.
Do a minimum of three search passes:
site:my.spline.design [keyword] for every word in the keyword map.community.spline.design/tag/[keyword]."<iframe" "my.spline.design/[topic keyword]" to find URLs already embedded in live production sites.Spline has four URL formats you will encounter. Only two of them are usable as embeds.
| URL shape | What it is | Usable as embed? | How |
|---|---|---|---|
community.spline.design/file/[uuid] | Community gallery page (HTML with JS viewer) | ❌ No | Sends X-Frame-Options, blocks iframe. Also does not expose the embed URL in its HTML — the my.spline.design slug is added client-side after the user hits Share. |
app.spline.design/community/file/[uuid] | Spline editor, opened to that community file | ❌ No | Editor page, not an embed. |
my.spline.design/[slug]/ | Published HTML scene page | ✅ Yes, via iframe | <iframe src="https://my.spline.design/[slug]/"> |
prod.spline.design/[id]/scene.splinecode | Raw runtime binary | ✅ Yes, via spline-viewer | <spline-viewer url="https://prod.spline.design/[id]/scene.splinecode"> |
Critical misuse to avoid: do NOT put a .splinecode URL into an <iframe src> — it renders as a broken placeholder or a binary download. Use the web component. Conversely, do NOT put a my.spline.design/ URL into a <spline-viewer url> — the viewer expects the runtime binary, not an HTML page.
Never fabricate slugs. The community file UUID and the published scene slug are different identifiers; guessing the slug almost always 403s. If you cannot verify a URL returns HTTP 200, it doesn't exist.
Scenes shown at https://community.spline.design/file/[uuid] are not directly iframe-embeddable — the community domain sends X-Frame-Options headers that block framing, and Google does not index the underlying my.spline.design/[slug]/ URL. When search surfaces a perfect-looking community scene, you cannot simply iframe community.spline.design/file/....
Workarounds, in order of reliability:
my.spline.design/… link. This is the correct answer when you've found the ideal scene but can't extract its embed URL.my.spline.design URL they can share.Spline sizing problems have one underlying cause: the scene's internal canvas fills 100% of the container, and the space around the 3D object is filled with the scene's internal background color — which defaults to a neutral color the creator chose, not your page's ground. When you drop a scene into a tall container, the scene looks correct in the part the object occupies and looks like a solid-color void in the rest. That void is the scene's background, not a rendering bug.
The fix has three parts, always applied together:
background attribute on <spline-viewer>, or (for iframes) by picking a scene whose native backdrop already matches.Method 1 — iframe embed (for my.spline.design/[slug]/ URLs):
// Container — always defines size + overflow:hidden
<div
style={{
position: "relative",
width: "100%",
height: "100%", // or a specific value / aspect-ratio / vh
minHeight: 420, // guarantees a usable minimum
overflow: "hidden",
background: "#0A0B0F", // matches the page ground — seen during load
}}
>
{/* skeleton loader underneath — visible until Spline paints */}
<div
style={{
position: "absolute",
inset: 0,
background:
"linear-gradient(110deg, #0A0B0F 30%, #151821 50%, #0A0B0F 70%)",
backgroundSize: "200% 100%",
animation: "skl 1.8s ease-in-out infinite",
zIndex: 0,
}}
/>
<iframe
src="https://my.spline.design/[scene-slug]/"
style={{
position: "absolute", inset: 0,
width: "100%", height: "100%",
border: "none", display: "block",
zIndex: 1,
}}
title="3D Scene"
loading="lazy"
allow="autoplay; fullscreen"
/>
</div>
The iframe cannot be told what background to render — you get whatever the creator baked in. If it doesn't match your page, either (a) accept a framed-viewport treatment (surround the scene with a visible bordered card), or (b) switch to a .splinecode URL of the same scene and use the web component (below), which can override the background.
Method 2 — <spline-viewer> web component (for prod.spline.design/[id]/scene.splinecode URLs):
This is the preferred method for tech sites where theme-harmony matters, because <spline-viewer> exposes a background attribute that replaces the scene's internal background entirely.
// Inject the viewer script once per app (put in main.jsx or the first component that uses it):
useEffect(() => {
if (document.querySelector('script[data-spline-viewer]')) return;
const s = document.createElement("script");
s.type = "module";
s.src = "https://unpkg.com/@splinetool/viewer@1.9.28/build/spline-viewer.js";
s.setAttribute("data-spline-viewer", "1");
document.head.appendChild(s);
}, []);
// Then render the viewer inside a sized container.
// Use dangerouslySetInnerHTML because JSX can't parse the custom tag's `background` attribute as a color.
<div style={{ position: "relative", width: "100%", height: "100%", minHeight: 480, overflow: "hidden" }}>
<div
dangerouslySetInnerHTML={{
__html: `<spline-viewer
url="https://prod.spline.design/[id]/scene.splinecode"
background="#0A0B0F"
style="position:absolute;inset:0;width:100%;height:100%;display:block;"
></spline-viewer>`,
}}
/>
</div>
The background attribute accepts any CSS color value — #0A0B0F, transparent, rgba(11,16,20,0.9). Set it to your page's ground color. The empty area around the 3D object now blends into the page, and the "bottom half is black" problem disappears.
Not every Spline scene is a discrete 3D object. The community is full of scenes titled things like:
These scenes contain their own baked-in HTML-like text, buttons, and layout, rendered as part of the 3D composition. When you embed one, you get a full pre-designed hero inside your hero — the scene's own text fights with your page's text, and the scene's own CTA competes with yours.
Before committing a scene, read its title. If the title contains "hero section," "landing page," "UI concept," or "website template" — treat it with suspicion. Open it, look at it, and either:
If the scene renders at the wrong zoom (object tiny in a big canvas), the creator's baked-in camera is the cause. Three fixes, in order of simplicity:
transform: scale(1.4) to the inner element. The whole rendered canvas scales up; the container's overflow: hidden clips the edges. Simple, works with both iframe and web-component.setZoom() — only if you're using @splinetool/react-spline (not <spline-viewer>). The onLoad callback receives a Spline Application object with a setZoom(level) method. Call application.setZoom(1.5) on load.Spline scenes are 1–16 MB binaries. They load in 2–8 seconds on a fast connection. During that window, a blank white viewport is the worst possible experience.
Always layer a skeleton loader beneath the scene, inside the same container. The container has the skeleton as its background (via a shimmering gradient animation), the scene paints on top when it loads. No JavaScript coordination needed.
@keyframes skl {
0% { background-position: 0% 50%; }
100% { background-position: -200% 50%; }
}
The skeleton should use the page's ground color + one slightly lighter tint. Never use a white skeleton on a dark site.
Once you have a candidate scene, run these four checks. If any fails, keep searching:
curl -I [url] returns 200, not 403/404. Guessed slugs from community UUIDs almost always 403. If you can't verify a 200, the URL doesn't exist.Do not skip step 2. Slugs lie. Every Spline URL must be visually verified in a real browser before you commit a whole site's design around it.
Verifying the URL works is not the same as verifying the scene renders at the right size in your layout. Spline scenes have their own internal camera and framing — dropping one into a small viewport, a wide banner, or an awkward aspect ratio often crops the subject out of frame or shrinks it to a speck.
After you build the site, before calling it done, do this in order:
transform: scale() on the iframe, or change to a different scene positioning (stage / backdrop / companion).Common size failures and fixes:
transform: scale(1.4) on the iframe to zoom in.transform: translateX() on the iframe to recenter.background attribute.background attribute (for spline-viewer) or pick a different scene.This step is not optional. A site that contains a miscentered or wrong-sized Spline scene is strictly worse than a site with a well-composed still image.
Even the right scene fails if it's placed poorly. Pick one of these spatial logics — don't just drop the scene into a panel and hope:
If your chosen scene doesn't fit any of these with clear logic, that's a signal to find a different scene — not to wedge it in.
If no topic-relevant Spline scene can be verified after a full search, do NOT force one. And do not build a brittle "if Spline fails, swap to photo" JavaScript flip — that's a visible glitch. Instead, layer the fallback underneath the Spline viewer, so if Spline is slow or fails, the user still sees something intentional.
The hierarchy, in order:
my.spline.design/[slug]/ or prod.spline.design/[id]/scene.splinecode) that genuinely depicts the subject.Layered implementation (CSS-only fallback under Spline):
<div className="hero-stage">
{/* Layer 0 — always visible. The base fallback (photo or illustration). */}
<div className="hero-fallback" />
{/* Layer 1 — Spline paints over the fallback if/when it loads.
If Spline 404s, never loads, or is disabled, layer 0 remains visible. */}
<div
className="hero-scene"
dangerouslySetInnerHTML={{
__html: `<spline-viewer url="..." background="transparent" style="..."></spline-viewer>`
}}
/>
</div>
/* CSS */
.hero-stage { position: relative; width: 100%; height: 100%; overflow: hidden; }
.hero-fallback {
position: absolute; inset: 0;
background-image: url("https://images.unsplash.com/photo-[verified-id]?w=1800&q=85");
background-size: cover; background-position: center;
filter: saturate(0.9) contrast(1.05);
z-index: 0;
}
.hero-scene { position: absolute; inset: 0; z-index: 1; }
When Spline uses background="transparent", the empty space around the 3D object reveals the fallback photograph underneath. The page always has a visible hero — Spline is an enhancement, not a requirement.
Unsplash URLs are convenient but unverifiable without loading. A URL like https://images.unsplash.com/photo-1548484352-ea579e5233a8?w=1200&q=80 looks specific (it names a photo ID) but the photographer may have replaced or removed the file, the crop may be different from what you expect, and at a different viewport aspect ratio you may see a different subject entirely than what the photo is named for.
When using photography fallback:
If no relevant scene or photograph exists, a deterministic CSS/SVG illustration is always a valid alternative — built entirely in the page, no network dependency, always renders identically. Examples: a cross-section diagram of a CLT timber panel, Geneva-stripes on a watchmaker's bridge, a sneaker silhouette, a reactive orb built from conic gradients.
An irrelevant 3D scene, however pretty, damages the luxury impression. A considered still image or SVG illustration doesn't.
#0A0A0A, #0C1222), clean sans-serifs, minimal accent colors (white, silver, or a single restrained blue). Think SpaceX — not orange and white.Bad color choices that make sites look unprofessional:
Critical technical rules:
import React alongside hooks: import React, { useState, useEffect, useRef } from "react";<>...</>) — use <span> or <div> instead for compatibilityloading="lazy" and provide a styled loading placeholder?w=1920&q=80 parameters for Unsplash URLsalpha: true, use setPixelRatio(Math.min(window.devicePixelRatio, 2)), and clean up on unmountScrolling should feel like a directed journey, not just moving down a page.
Scroll-driven techniques:
window.scrollY and apply different multipliers to different elements.position: sticky on a container with overflow: hidden, then translateX inner content based on scroll progress.IntersectionObserver with a threshold array, or calculate progress from getBoundingClientRect().Implementation pattern for scroll progress:
const getScrollProgress = (element) => {
const rect = element.getBoundingClientRect();
const windowHeight = window.innerHeight;
return Math.max(0, Math.min(1, 1 - (rect.top / windowHeight)));
};
useEffect(() => {
let ticking = false;
const onScroll = () => {
if (!ticking) {
requestAnimationFrame(() => {
// update state based on scroll
ticking = false;
});
ticking = true;
}
};
window.addEventListener('scroll', onScroll, { passive: true });
return () => window.removeEventListener('scroll', onScroll);
}, []);
Beyond scroll-driven effects, all motion should feel directed and sequenced:
animation-delay or sequenced timers.cubic-bezier(0.16, 1, 0.3, 1) for smooth overshoots, cubic-bezier(0.77, 0, 0.175, 1) for snappy, cubic-bezier(0.33, 1, 0.68, 1) for elegant ease-out.These small things separate premium from "pretty good":
scroll-behavior: smooth or a library like Lenis8px on everything::selection) styled to match the brand// Always use a default export with no required props
export default function SiteName() {
return (
<div>
{/* Full implementation */}
</div>
);
}
Import from Google Fonts via @import in a <style> tag or use <link> in the component. Always provide a thoughtful fallback stack.
@import url('https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=DM+Sans:wght@300;400;500&display=swap');
import * as THREE from 'three'. Note: THREE.CapsuleGeometry is NOT available in r128. OrbitControls are NOT available — implement camera movement manually.<spline-viewer> web componentUse inline styles or a <style> tag within the component. CSS variables are essential for theming consistency:
:root {
--color-bg: #FAF9F6;
--color-text: #1A1A1A;
--color-text-muted: #6B6B6B;
--color-accent: #C8553D;
--font-display: 'Instrument Serif', Georgia, serif;
--font-body: 'DM Sans', -apple-system, sans-serif;
--font-mono: 'JetBrains Mono', monospace;
--space-unit: clamp(1rem, 2vw, 2rem);
}
Prefer CSS animations and IntersectionObserver for scroll-triggered effects. Use useRef and useEffect for observers, useState for animation state triggers.
const [isVisible, setIsVisible] = useState(false);
const ref = useRef(null);
useEffect(() => {
const observer = new IntersectionObserver(
([entry]) => { if (entry.isIntersecting) setIsVisible(true); },
{ threshold: 0.15 }
);
if (ref.current) observer.observe(ref.current);
return () => observer.disconnect();
}, []);
Design desktop-first for visual impact, then adapt for mobile. Use clamp() aggressively for fluid spacing and typography. Restructure layouts at breakpoints rather than just shrinking.
When a user (or this skill) drafts a prompt.md for a new site, a short prompt produces short output. The skill produces its best work when the prompt names every decision explicitly. A complete prompt contains each of the following, in order:
A prompt is "done" when every one of those 15 items has a concrete, specific answer. Vague answers ("warm palette", "some motion", "clean layout") are rejected — they are the failure mode of the SKILL.
When the user asks for a premium website:
prompt.md.site:my.spline.design [keyword], community.spline.design/tag/[keyword], production-site harvest ("<iframe" "my.spline.design", "spline-viewer" "scene.splinecode"). Accept either embed format. Check the list of Spline URLs already used by previous sites in this session — the new site's URL must not match any of them. If all available scenes have already been used, fall back to photography or SVG/CSS illustration, do not recycle. Candidate scenes must pass the four-check test: resolves 200, renders at the expected quality when loaded, subject nameable in two seconds, mood matches the brand. Never fabricate a slug. Reject scenes depicting real-branded products. Decide positioning (stage / backdrop / companion / object-in-spread) before committing.Never explain that you're "researching competitors" or "sourcing 3D" — just execute with craft. The design should speak for itself.
Source: davila7/claude-code-templates — distributed by TomeVault.