expressive-style-guide
npx skills add https://github.com/sweetretry/skills --skill expressive-style-guide
Agent 安装分布
Skill 文档
å¿«éåè
| è¦ç´ | è§è |
|---|---|
| èæ¯è² | bg-background (CSS Variable å±å®ä¹è¿é»è²è°) |
| åæ¯è² | text-foreground (CSS Variable å±å®ä¹é«äº®ç½) |
| 强è°è² | text-primary / bg-primary (åä¸åçè²) |
| åè§ | rounded-lg (8px) æ rounded-xl (12px) |
| 卿弿 | Framer Motion, Spring Physics ä¼å |
| è§è§æ¨¡å¼ | èå ç¯ / è§å·® / å½¢å / æ°å´æ¸å / é®ç½©æç¤º / æµ®å±ç»ç / 卿æç (å¯ç»å) |
| 对æ¯åº¦ | WCAG AA (â¥4.5:1)ï¼æè²èæ¯ä¸çææ¬å¿ é¡»è¾¾æ |
| 硬ç¼ç Hex | ç¦æ¢ â ç»ä»¶å±ä¸¥æ ¼ä½¿ç¨è¯ä¹ Token |
æ ¸å¿æä»¤ (Core Mandate)
æ¬è§èæ¨å¨æå»º “å½±é¢çº§è´¨æ (Cinematic UI)” æ “å¨ææç®ä¸»ä¹ (Kinetic Minimalism)”ãæ ¸å¿å¨äºå°çé¢è§ä¸ºä¸ä¸ªåæ§çæå½±èå°ï¼å©ç¨å å½±ãæè´¨åæåæºé»è¾ï¼è¿éï¼å°æ°åå 容æåè³èºæ¯åé«åº¦ã
å¼ºå¶ææ¯æ (Hard Constraints):
- UI åº:
shadcn/ui(ä» ä½ä¸ºåºå±ç»æï¼å¿ é¡»éè¿cn()åå¹¶æ ·å¼è¿è¡è§è§æçº¯ï¼ä¸¥ç¦ç¡¬ç¼ç æ ·å¼è¦çç³»ç» Token)ã - æ ·å¼å¼æ:
Tailwind CSS(ä¸¥æ ¼ä½¿ç¨è¯ä¹å Token ç±»ï¼å¨ CSS Variables å±å®ä¹å½±é¢è²å½©)ã - 卿åº:
Framer Motion(æ ¸å¿å¼æãSpring Physics 为é¦é驱å¨ï¼è¾ 以æ»å¨é©±å¨åè§å·®å¨æ)ã
ä¸ã设计å²å¦ï¼çµå½±æçèæ (Cinematic Void)
- å 容å³è±é (Content as Hero): çé¢å¿ é¡»ç»å¯¹éåãé¤äºå 容ï¼å¾çãé³ä¹ãèºæ¯åï¼æ¬èº«ï¼ææè£ 饰æ§å ç´ é½åºè¢«å¥ç¦»ã
- 黿ç»å¸ (The Dark Canvas): èæ¯éè¿ CSS Variables å®ä¹è¿é»è²è° (
--background)ï¼ç»ä»¶å±ä½¿ç¨bg-backgroundãå©ç¨æé«ç卿èå´ï¼è®©å±é¨å ç §äº§çæå§æ§ç对æ¯ã - èå°çº§è¿é (Camera Work): å¨ç»ä¸åºæ¯”跳娔æ”åå¼¹”ï¼è比平æ»çæ»è½¨ (Dolly Zoom)”æ”å½¢å (Morph)”ã
- è´¨æçè§¦è§ (Tactile Material): çé¢å¯¹è±¡åºå ·æè´¨éæå表é¢åå ï¼æ¨¡æç©çå®ä½å¨ææ¿ä¸çè´¨æã
äºãåºç¡ç³»ç» (System Foundations)
1. Token åè²å½©ç³»ç» (Cinematic Color Tokens)
ååï¼ ææè²å½©å¨ CSS Variables å±å®ä¹ï¼ç»ä»¶å±ä¸¥æ ¼ä½¿ç¨ Tailwind è¯ä¹ç±»ãç¦æ¢å¨ç»ä»¶ä»£ç ä¸åºç°ä»»ä½ç¡¬ç¼ç Hex å¼ã
CSS Variables å®ä¹ï¼å½±é¢è²è°ï¼ï¼
:root {
/* å½±é¢åºæ¯ä¸ Light Mode æå°ä½¿ç¨ï¼ä½å¿
é¡»å®ä¹ */
--background: 0 0% 98%; /* è¿ç½ */
--foreground: 0 0% 4%; /* è¿é» */
--card: 0 0% 96%;
--card-foreground: 0 0% 4%;
--primary: 220 90% 56%; /* åç强è°è² */
--primary-foreground: 0 0% 98%;
--secondary: 0 0% 92%;
--secondary-foreground: 0 0% 10%;
--muted: 0 0% 90%;
--muted-foreground: 0 0% 40%;
--accent: 0 0% 92%;
--accent-foreground: 0 0% 10%;
--border: 0 0% 85%;
--ring: 220 90% 56%;
}
.dark {
/* 影颿 ¸å¿è²è° â è¿é»é«å¯¹æ¯ */
--background: 0 0% 2%; /* è¿çº¯é»ç»å¸ */
--foreground: 0 0% 95%; /* é«äº®ç½åæ¯ */
--card: 0 0% 4%; /* å¡çå¾®æäº® */
--card-foreground: 0 0% 92%;
--primary: 220 85% 65%; /* å
è°±åç§»åç强è°è² */
--primary-foreground: 0 0% 2%;
--secondary: 0 0% 8%;
--secondary-foreground: 0 0% 88%;
--muted: 0 0% 12%;
--muted-foreground: 0 0% 55%;
--accent: 0 0% 10%;
--accent-foreground: 0 0% 90%;
--border: 0 0% 14%; /* æå¾®å¼±è¾¹ç */
--ring: 220 85% 65%;
}
ç»ä»¶å±ç¨æ³ç¤ºä¾ï¼
// â
æ£ç¡® â 使ç¨è¯ä¹ Token
<div className="bg-background text-foreground">
<div className="bg-card border-border">
<span className="text-muted-foreground">
// â ç¦æ¢ â 硬ç¼ç Hex
<div className="bg-[#030303] text-[#ffffff]">
<div style={{ background: '#000000' }}>
2. å å½±ä¸åå (Cinematic Lighting)
å
å½±ææéè¿ Token åç border å opacity 表达ï¼ç¦æ¢ç¡¬ç¼ç RGBAã
- æå
è¾¹æ¡ (Reflective Sheen): å¡çé¡¶é¨ç微弱åå
ä½¿ç¨ Token åè¾¹æ¡ï¼
- Primary Sheen:
border-t border-foreground/20(é¡¶é¨è¾¹ç¼é«äº®) - Ambient Border:
border border-border(æ´ä½å¾®å¼±è¾¹ç)
- Primary Sheen:
- æ°å´ç¯ (Ambient Glow): ä»
卿å
¶å
å¶çåºæ¯ä¸ä½¿ç¨èæ¯æ¨¡ç³å
æï¼ä¸éæåº¦æ§å¶å¨ 5-8%ï¼
bg-primary/5æbg-primary/8ä½ä¸ºå å®¹çæ°å´èæ¯
- 模ç³å±çº§: å¼¹åºå±ä½¿ç¨
backdrop-blur-xlé åè¯ä¹èæ¯è²ï¼bg-background/80 backdrop-blur-xl
3. 卿ç©çå¦ (Kinetic Physics)
Spring Physicsï¼äº¤äºé©±å¨ï¼
-
è¿é (Dolly/Morph): é对å¸å±åæ¢ï¼è¿½æ±ç¨³éä¸è¿è´¯ã
const dolly = { type: "spring", stiffness: 280, damping: 28, mass: 1 }; -
触æ (Tactile Precision): é对微交äºï¼ç¹å»ãæ¬åï¼ï¼å¿«é䏿 æ³¢å¨ã
const tactile = { type: "spring", stiffness: 380, damping: 30, mass: 0.8 }; -
æ¸ç° (Reveal): é对æ°å ç´ å ¥åºï¼ä½¿ç¨å¹³æ»ç Expo å ¬å¼ã
const reveal = { duration: 1, ease: [0.16, 1, 0.3, 1] };
æ»å¨é©±å¨å¨æ (Scroll-Driven)
-
è§å·®æ»å¨: éè¿
useScroll+useTransformå®ç°åæ¯/èæ¯å·®éç§»å¨ãconst { scrollYProgress } = useScroll({ target: ref }); const y = useTransform(scrollYProgress, [0, 1], ["0%", "-20%"]); -
é®ç½©æç¤º: éè¿
scrollYProgress驱å¨clipPathæopacityæ¸ç°ãconst opacity = useTransform(scrollYProgress, [0.2, 0.6], [0, 1]); const clipPath = useTransform(scrollYProgress, [0, 1], ["inset(100% 0 0 0)", "inset(0% 0 0 0)"] );
å ¥åºç¼æ (Stagger Orchestration)
-
å表/ç½æ ¼åå ç´ ä½¿ç¨
staggerChildrenå®ç°çº§èå ¥åºï¼const container = { animate: { transition: { staggerChildren: 0.08 } } }; const item = { initial: { opacity: 0, y: 24 }, animate: { opacity: 1, y: 0, transition: reveal } };
4. 影颿ç (Display Typography)
- Display Heading: æ é¢åºå
·ææå§æ§ç对æ¯åã
- Scale:
text-5xlè³text-9xlã - Tracking:
tracking-tighter(-0.05em+)ã - Color:
text-foreground(严ç¦ç¡¬ç¼ç ç½è²)ã
- Scale:
- Mono Secondary: ææè¾
å©ä¿¡æ¯ï¼å¹´ä»£ãå
æ°æ®ï¼å¼ºå¶ä½¿ç¨ Mono åä½ï¼å¢å¼ºå·¥ä¸ç²¾å¯æã
- Font:
JetBrains MonoæGeist Monoã - Color:
text-muted-foregroundã
- Font:
- æ£æ: è¡é«
leading-relaxed(1.625)ï¼ç¡®ä¿æè²èæ¯ä¸çå¯è¯»æ§ã
ä¸ãè§è§æ¨¡å¼èå (Visual Mode Palette)
以䏿¨¡å¼å¯ç¬ç«ä½¿ç¨æç»åå å ï¼æ ¹æ®å 容类åéæ©æä½³æé ãé¿å å¨åä¸é¡¹ç®ä¸æ»¥ç¨æææ¨¡å¼ â éæ© 2-3 ç§å»ºç«ç»ä¸çè§è§è¯è¨ã
1. èå ç¯ (Spotlight)
é¼ æ 追踪çå±é¨ç §æï¼è®©å 容ä»é»æä¸æµ®ç°ã
- éè¿
useMotionTemplate+useMotionValueè¿½è¸ªé¼ æ åæ çæradial-gradientã - å ååå¾ 240-320pxï¼ä» åå åºåæ¾ç¤ºè¾¹æ¡åç²¾ç»çº¹çã
- éç¨ï¼ å¡çç½æ ¼ãä½åç»å»ãåè½å±ç¤ºã
2. è§å·®æ»å¨ (Parallax Depth)
忝/èæ¯åå±å·®éç§»å¨ï¼åé 空é´çºµæ·±æã
- èæ¯å±ä»¥ 0.3-0.5 åéè·éæ»å¨ï¼åæ¯ä»¥ 1.0 åéã
- éè¿
useScroll+useTransformæ å°translateYã - å¯å å
scaleåæ¢æ¨¡æ”æ¨è¿ (Dolly In)”ã - éç¨ï¼ Landing Page Heroãé¿æ»å¨åäºã产åå±ç¤ºã
3. å½¢åè¿æ¸¡ (Morph Transition)
å ç´ é´çå½¢ææå¼ï¼å»ºç«ç©ºé´è¿ç»æ§ã
- 强å¶ä½¿ç¨ Framer Motion ç
layoutIdå®ç°è·¨è§å¾æ ç¼åå½¢ã - å°é¢å¾å¨ç¼©ç¥å¾ â 详æ 页é´è¿è¡å°ºå¯¸/ä½ç½®/åè§çè¿ç»æå¼ã
- æé
AnimatePresenceç¡®ä¿éåºå¨ç»å®æ´ã - éç¨ï¼ 详æ å±å¼ã导èªåæ¢ãç¶æè¿æ¸¡ã
4. æ°å´æ¸å (Ambient Gradient)
ä½é¥±ååº¦å¨ææ¸åèæ¯ï¼è¥é æ²æµ¸æ°å´ã
- 使ç¨
bg-gradient-to-*æé Token åè²å½©ï¼from-background via-muted/10 to-backgroundã - å¯éè¿
animateç¼æ ¢å¾ªç¯æ¸åè§åº¦æä½ç½® (duration: 8-15s)ã - 饱ååº¦ä¸¥æ ¼æ§å¶å¨ 5-15%ï¼ç¦æ¢é«é¥±åæ¸åã
- éç¨ï¼ é³ä¹ææ¾å¨èæ¯ãåç页æ°å´ãå è½½ç¶æã
5. é®ç½©æç¤º (Mask Reveal)
æ»å¨é©±å¨çå 容æ¸ç°ï¼åé æå§æ§çæå¹ææã
- éè¿
clipPathå¨ç»å®ç°å ä½å½¢ç¶çå±å¼æç¤ºã - æ¯æå¤ç§æç¤ºå½¢æï¼åç´æ¦é¤ãä¸å¿åæ©ã对è§çº¿åå ¥ã
- æé
opacityè¿æ¸¡é²æ¢ç¡¬è¾¹éªçã - éç¨ï¼ ç« èå ¥åºãå¾çå±ç¤ºãæ¶é´çº¿èç¹ã
6. æµ®å±ç»ç (Frosted Overlay)
æ¯ç»ç颿¿ + æ¯æ·±æ¨¡ç³ï¼å»ºç«å±çº§ä¸èç¦ã
- 颿¿ä½¿ç¨
bg-background/60 backdrop-blur-xl border border-borderã - èæ¯å±åæ¥åºç¨
scale(1.02)+blur(4px)æ¨¡ææ¯æ·±ã - æµ®å±å
¥åºä½¿ç¨
dollyspring åæ°ï¼éåºä½¿ç¨revealåæ°ã - éç¨ï¼ Modal/Dialogãä¾§è¾¹æ ã详æ å¼¹åºé¢æ¿ã
7. 微卿æç (Kinetic Typography)
æåå ¥åºçæå§æ§ç¼æï¼è®©æçæ¬èº«æä¸ºè§è§ç¦ç¹ã
- æ é¢éå/éè¯å
¥åºï¼éè¿
staggerChildren: 0.03-0.06级èã - æ¯ä¸ªå符ç¬ç«åºç¨
opacity+y+filter: blur()è¿æ¸¡ã - 大æ é¢å¯å å
scaleä» 1.1 â 1.0 ç微缩æ¾ã - éç¨ï¼ Hero æ é¢ãåç宣è¨ãç« èæ é¢ã
åãç»ä»¶å®ç° (Implementation Specs)
shadcn/ui å½±é¢åæ¹é (Cinematic Overrides)
æææ¹é éè¿ cn() åå¹¶æ ·å¼ï¼ä½¿ç¨è¯ä¹ Tokenï¼ç¦æ¢ç¡¬ç¼ç é¢è²å¼ã
Button
// Primary â é«å¯¹æ¯å¨ä½æé®
<Button className={cn(
"bg-primary text-primary-foreground",
"rounded-lg tracking-wide font-medium",
"transition-none" // ç± Framer Motion æ¥ç®¡
)}>
<motion.span whileTap={{ scale: 0.97 }} transition={tactile}>
Action
</motion.span>
</Button>
// Ghost â å½±é¢å¹½çµæé®
<Button variant="ghost" className={cn(
"text-muted-foreground hover:text-foreground",
"hover:bg-accent/50"
)}>
Secondary
</Button>
Card (å½±é¢å¡ç)
<motion.div className={cn(
"bg-card border border-border rounded-xl overflow-hidden",
"border-t-foreground/15" // é¡¶é¨åå
Sheen
)}>
{/* å°é¢å¾é»è®¤éä½äº®åº¦ï¼äº¤äºæ¶æ¢å¤ */}
<motion.img
className="w-full object-cover brightness-[0.6]"
whileHover={{ brightness: 1 }}
/>
<div className="p-6">
<h3 className="text-foreground text-lg font-semibold tracking-tight">
{title}
</h3>
<p className="text-muted-foreground text-sm font-mono mt-1">
{metadata}
</p>
</div>
</motion.div>
Dialog (å½±é¢å¼¹åºå±)
<Dialog>
<DialogOverlay className={cn(
"bg-background/80 backdrop-blur-xl"
)} />
<DialogContent className={cn(
"bg-card border border-border rounded-xl",
"shadow-none"
)}>
{/* å
å®¹ä½¿ç¨ AnimatePresence ç¼æå
¥åº */}
<AnimatePresence mode="wait">
<motion.div
initial={{ opacity: 0, y: 16 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -8 }}
transition={dolly}
>
{children}
</motion.div>
</AnimatePresence>
</DialogContent>
</Dialog>
Navigation (å½±é¢å¯¼èª)
<nav className={cn(
"fixed top-0 w-full z-50",
"bg-background/60 backdrop-blur-lg border-b border-border"
)}>
<div className="flex items-center justify-between px-8 h-16">
<span className="text-foreground font-semibold tracking-tight">
{brand}
</span>
<div className="flex gap-6 text-muted-foreground">
{links.map(link => (
<motion.a
key={link.href}
className="hover:text-foreground transition-colors"
whileHover={{ y: -1 }}
transition={tactile}
>
{link.label}
</motion.a>
))}
</div>
</div>
</nav>
é对称 Bento ç½æ ¼ (Asymmetric Grid)
ç½æ ¼æç ´ç宽åè°æ§ï¼åé è§è§èå¥ï¼
- Hero Item:
col-span-2 row-span-2â 主è§è§ç¦ç¹ã - Vertical/Square: 交éæåï¼åé è§è§èå¥ã
- Gap:
gap-4ægap-6ï¼ä½¿ç¨ Token åé´è·ã - Mobile: é´è·æå (
gap-2)ï¼ä½ä¿æè¶³å¤çå è¡¬ç©ºé´ (p-4)ã
<div className="grid grid-cols-2 md:grid-cols-4 gap-4 md:gap-6">
<div className="col-span-2 row-span-2">{/* Hero Card */}</div>
<div className="col-span-1">{/* Vertical Card */}</div>
<div className="col-span-1">{/* Square Card */}</div>
</div>
å ±äº«å ç´ è·³è½¬ (Shared Element Transition)
- 强å¶ä½¿ç¨ Framer Motion ç
layoutIdã - å°é¢å¾å¿ é¡»å¨å½¢æé´è¿è¡æ ç¼æå¼è¿æ¸¡ï¼ä¸¥ç¦åºç°é¡µé¢é´çç¬é´éªçæç¡¬åã
- æé
AnimatePresence管çç»ä»¶çå½å¨æã
<motion.div layoutId={`card-${id}`} transition={dolly}>
<motion.img layoutId={`image-${id}`} src={cover} />
</motion.div>
äºã代ç å®¡æ¥æ¸ å (The Cinematic Audit)
Token åè§
- Token Check â ç»ä»¶ä»£ç 䏿¯å¦åå¨ç¡¬ç¼ç Hex (å¦
#030303,#ffffff)ï¼ææé¢è²æ¯å¦ä½¿ç¨bg-background/text-foreground/border-borderçè¯ä¹ç±»ï¼ - CSS Variable Check â å½±é¢è²è°æ¯å¦å¨
:root/.darkç CSS Variables 䏿£ç¡®å®ä¹ï¼
è§è§ä¸æè´¨
- Lighting Logic â æ¯å¦åç使ç¨äºå å½±ææï¼æ¯å¦é¿å äºå ¨åååç §æï¼
- Material Check â ææå®¹å¨æ¯å¦å
·å¤é¡¶é¨åå
(
border-t-foreground/15)ï¼è¾¹æ¡æ¯å¦ä½¿ç¨border-borderï¼ - Imagery Authenticity â å°é¢æ¯å¦ä¸ºé«è´¨éæå½±æ 3D 渲æï¼æ¯å¦åå¨å»ä»·çç¢éææ¸åå ä½ï¼
å¨æè´¨é
- Physics Check â 交äºå¨ææ¯å¦ä½¿ç¨ Spring Physicsï¼æ¯å¦åå¨çº¿æ§æ ease-in-out å¨ç»ï¼Damping æ¯å¦è¶³å¤å¤§ä»¥ä¿è¯ç¨³å®æ§ï¼
- Continuity Check â å¾çè½¬æ¢æ¯å¦åºç¨äº
layoutIdï¼è¯¦æ é¡µå ¥åºæ¯å¦ä½¿ç¨äºAnimatePresenceï¼ - Scroll Motion Check â æ¯å¦åç使ç¨äºæ»å¨é©±å¨å¨æ (è§å·®/é®ç½©æç¤º)ï¼æ¯å¦åå¨ä¸å¿ è¦ç JS æ»å¨çå¬ï¼
模å¼å¤æ ·æ§
- Variety Check â é¡¹ç®æ¯å¦è¿åº¦ä¾èµåä¸è§è§æ¨¡å¼ (å¦ä» 使ç¨èå ç¯)ï¼æ¯å¦æ ¹æ®å 容类åéæ©äº 2-3 ç§äºè¡¥æ¨¡å¼ï¼
- Composition Check â å¤ç§æ¨¡å¼å å æ¶ï¼æ¯å¦ä¿æäºè§è§å å¶ï¼æ¯å¦åå¨è¿åº¦å å 导è´çæ§è½é®é¢æå®¡ç¾ç²å³ï¼
å¯è®¿é®æ§
- Contrast Safety â æè²èæ¯ä¸çææææ¬ (å°¤å
¶æ¯
text-muted-foreground) 对æ¯åº¦æ¯å¦ ⥠4.5:1ï¼ - Motion Safety â æ¯å¦å°é
prefers-reduced-motionï¼å¼å¯åæ¯å¦ç¦ç¨è§å·®åå¤æå ¥åºå¨ç»ï¼
åèèµæº
- 示ä¾é¡¹ç®:
example/ç®å½å å«ä¸ä¸ªå为 Aero Music ç宿´æ¼ç¤ºåºç¨ï¼å±ç¤ºäº Bento å¸å±ãèå ç¯é®ç½©åæåæºè¿éç宿´å®ç°ã
åæç¬è®° (Composition Notes)
æ¬èä¾
design-directoræè½å¨å¤é£æ ¼èååºæ¯ä¸ä½¿ç¨ãå®ä¹æ¬é£æ ¼æåä¸åªäºå±æ§æ¯ç¡¬çº¦æï¼å³ä½¿å¨æ··å模å¼ä¸ä¹ä¸å¯è¦çï¼ï¼åªäºæ¯è½¯çº¦æï¼å¯ç± Director æ ¹æ®é¡¹ç®éæ±è°æ´ï¼ã
硬约æ (Hard Constraints â ä¸å¯è¦ç)
| ID | 屿§ | è§èå¼ | çç± |
|---|---|---|---|
| E.H1 | 卿弿 | Framer Motion, Spring Physics ä¼å | å½±é¢è´¨æçæ ¸å¿é©±å¨ï¼æ¿æ¢ä¸º CSS transition å°å¤±å»å ¨é¨è§è§ç¹å¾ |
| E.H2 | æè²ç»å¸ | æ·±è²èæ¯ä½ä¸ºé»è®¤ç»å¸ï¼Expressive åºåå ï¼ | å å½±æå§æä¾èµäºæè²åºåºï¼æµ è²èæ¯æ æ³å®ç°èå ç¯ãæ°å´æ¸åçæ ¸å¿è§è§æ¨¡å¼ |
| E.H3 | Token å | ç¦æ¢ç¡¬ç¼ç Hexï¼ç»ä»¶å±ä½¿ç¨è¯ä¹ Token | è·¨é£æ ¼èåçåºç¡è®¾æ½ï¼ææé£æ ¼å ±äº«æ¤çº¦æ |
| E.H4 | å 容å³è±é | è£ é¥°æ§å ç´ å¿ é¡»éåäºå 容ï¼å¾çãé³ä¹ãä½åï¼ | æ¬é£æ ¼çæ ¸å¿å²å¦ââçé¢éåºï¼å 容ç»å° |
| E.H5 | 对æ¯åº¦ | WCAG AA (â¥4.5:1) | æ éç¢å¼ºå¶è¦æ±ï¼æè²èæ¯ä¸çæµ è²æåå°¤å ¶éè¦æ£æ¥ |
软约æ (Soft Constraints â å¯ç± Director è¦ç)
| ID | 屿§ | é»è®¤å¼ | Director å¯è°æ´èå´ | è§¦åæ¡ä»¶ |
|---|---|---|---|---|
| E.S1 | åè§ | rounded-lg (8px) / rounded-xl (12px) |
å¯éè³ rounded-md (6px) |
å½ Minimal 为项ç®ä¸»é£æ ¼ï¼Expressive ä» ç¨äºè¾ å©åºåæ¶ |
| E.S2 | 卿æ¶é¿ä¸é | 0.3â1.5sï¼å®æ´å½±é¢è¿éï¼ | ä¸éå¯éè³ 0.8s | å½é¡¹ç®æ´ä½èå¥åå¿«ï¼æ Minimal/Swiss ä¸ºä¸»é£æ ¼æ¶ |
| E.S3 | è²å½©ç©ºé´ | HSL | å¯è½¬æ¢ä¸º oklch | æ··å项ç®ä¸æ¨èç»ä¸ä½¿ç¨ oklchââæç¥ååæ§æ´å¥½ï¼æ¸åæ¥ç¼æ´èªç¶ |
| E.S4 | æè²èæ¯æåº¦ | hsl(0 0% 2%) / oklch(0.08 0 0) è¿çº¯é» |
å¯æäº®è³ oklch(0.145 0 0) â #1A1A1A |
å½éè¦ä¸ Minimal/Swiss åºåç»ä¸æè²æ¨¡å¼åºåæ¶ |
| E.S5 | é对称 Bento ç½æ ¼ | èªç±é对称å¸å± | å¯å¯¹é½å° 8pt åºçº¿ç½æ ¼ï¼å宽åé´è·ä¸º 8px åæ°ï¼ | å½ Swiss 为项ç®ä¸çä»»ä¸é£æ ¼ï¼éè¦å ¨å±ç½æ ¼å¯¹é½æ¶ |
| E.S6 | Stagger é´é | 0.08s | å¯ç¼©çè³ 0.04â0.06s | å½é¡¹ç®æ´ä½èå¥åå¿«æ¶ |
| E.S7 | è§å·®æ»å¨å¼ºåº¦ | 0.3â0.5 åéå·® | å¯éè³ 0.1â0.2 åéå·® | å½ Minimal ä¸ºä¸»é£æ ¼ï¼éè¦æ´å å¶çæ»å¨ä½éªæ¶ |