mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-09-06 17:57:43 +02:00
[eric] onboarding: claude design language (starburst mark on intro, thinking-pulse finish, starburst card emblem)
This commit is contained in:
@@ -8,6 +8,7 @@ import { useClaudeTokens } from '@/shared/styles/ThemeContext';
|
||||
import type { ClaudeTokens } from '@/shared/styles/claudeTokens';
|
||||
import { useOnboardingV3Pipeline } from './useOnboardingV3Pipeline';
|
||||
import { GRAIN_URL } from './beats/BeatShell';
|
||||
import Starburst from './Starburst';
|
||||
import BeatConnect from './beats/BeatConnect';
|
||||
import BeatApps from './beats/BeatApps';
|
||||
import BeatTheme from './beats/BeatTheme';
|
||||
@@ -63,11 +64,19 @@ const IntroBeat: React.FC<{ c: ClaudeTokens; line: string; sub?: string; onNext:
|
||||
}}
|
||||
/>
|
||||
<div style={{ position: 'absolute', inset: 0, backgroundImage: GRAIN_URL, opacity: 0.14, pointerEvents: 'none', mixBlendMode: 'overlay' }} />
|
||||
<motion.div
|
||||
initial={{ opacity: 0, scale: 0.4, rotate: -80 }}
|
||||
animate={{ opacity: 1, scale: 1, rotate: 0 }}
|
||||
transition={{ type: 'spring', stiffness: 160, damping: 18, delay: 0.2 }}
|
||||
style={{ position: 'relative', marginBottom: 22 }}
|
||||
>
|
||||
<Starburst size={44} from={c.accent.hover} to={c.accent.primary} />
|
||||
</motion.div>
|
||||
<motion.h1
|
||||
initial={{ opacity: 0, y: 16, filter: 'blur(8px)' }}
|
||||
animate={{ opacity: 1, y: 0, filter: 'blur(0px)' }}
|
||||
transition={{ duration: 0.7, delay: 0.35, ease: [0.22, 1, 0.36, 1] }}
|
||||
style={{ position: 'relative', margin: 0, fontSize: 'clamp(2.4rem, 5vw, 3.8rem)', fontWeight: 700, color: c.text.inverse, letterSpacing: '-0.02em', textAlign: 'center', padding: '0 24px' }}
|
||||
transition={{ duration: 0.7, delay: 0.45, ease: [0.22, 1, 0.36, 1] }}
|
||||
style={{ position: 'relative', margin: 0, fontSize: 'clamp(2.4rem, 5vw, 3.8rem)', fontWeight: 600, color: c.text.inverse, letterSpacing: '-0.01em', textAlign: 'center', padding: '0 24px' }}
|
||||
>
|
||||
{line}
|
||||
</motion.h1>
|
||||
@@ -202,8 +211,15 @@ const OnboardingV3Root: React.FC = () => {
|
||||
))}
|
||||
</motion.div>
|
||||
{finishing && (
|
||||
<div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', background: c.bg.page }}>
|
||||
<motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} style={{ fontSize: '1.05rem', color: c.text.tertiary }}>
|
||||
<div style={{ position: 'absolute', inset: 0, display: 'flex', flexDirection: 'column', gap: 18, alignItems: 'center', justifyContent: 'center', background: c.bg.page }}>
|
||||
<motion.div
|
||||
initial={{ opacity: 0, scale: 0.7 }}
|
||||
animate={{ opacity: [0, 1, 0.55, 1], scale: [0.7, 1, 0.92, 1], rotate: [0, 0, 22, 45] }}
|
||||
transition={{ duration: 4.5, times: [0, 0.2, 0.6, 1], repeat: 3 }}
|
||||
>
|
||||
<Starburst size={40} from={c.accent.hover} to={c.accent.pressed} />
|
||||
</motion.div>
|
||||
<motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} style={{ fontSize: '1.02rem', color: c.text.tertiary }}>
|
||||
Setting up your canvas...
|
||||
</motion.div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import React from 'react';
|
||||
|
||||
// Claude's signature asterisk mark, drawn as 8 rounded rays around a hollow center; gradient runs hover->pressed so it wears whatever accent the user picked.
|
||||
const Starburst: React.FC<{ size: number; from: string; to: string }> = ({ size, from, to }) => {
|
||||
const id = React.useId();
|
||||
return (
|
||||
<svg width={size} height={size} viewBox="-50 -50 100 100" style={{ display: 'block' }}>
|
||||
<defs>
|
||||
<linearGradient id={id} x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stopColor={from} />
|
||||
<stop offset="100%" stopColor={to} />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
{Array.from({ length: 8 }, (unused, i) => (
|
||||
<rect key={i} x={-7} y={-46} width={14} height={34} rx={7} fill={`url(#${id})`} transform={`rotate(${i * 45})`} />
|
||||
))}
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export default Starburst;
|
||||
@@ -3,6 +3,7 @@ import { motion } from 'framer-motion';
|
||||
import { Dices } from 'lucide-react';
|
||||
import type { ClaudeTokens } from '@/shared/styles/claudeTokens';
|
||||
import type { ProviderIdentity } from '../onboardingV3Api';
|
||||
import Starburst from '../Starburst';
|
||||
import BeatShell from './BeatShell';
|
||||
|
||||
const EPITHETS = [
|
||||
@@ -52,11 +53,9 @@ const BeatCard: React.FC<{
|
||||
display: 'flex', flexDirection: 'column', position: 'relative',
|
||||
}}
|
||||
>
|
||||
<div style={{
|
||||
width: 168, height: 158, alignSelf: 'flex-start',
|
||||
borderRadius: '6% 64% 6% 64%',
|
||||
background: `linear-gradient(135deg, ${c.accent.hover}, ${c.accent.primary} 70%, ${c.accent.pressed})`,
|
||||
}} />
|
||||
<div style={{ alignSelf: 'flex-start', marginLeft: -8, marginTop: -4 }}>
|
||||
<Starburst size={158} from={c.accent.hover} to={c.accent.pressed} />
|
||||
</div>
|
||||
<input
|
||||
value={name}
|
||||
onChange={(e) => setName(e.target.value.slice(0, 18))}
|
||||
|
||||
Reference in New Issue
Block a user