afe36fd347
Claude Design export for SD-0001 (login + create-storefront surfaces): wf-*/hf-* screens, design-system bundle, offline preview. First artifact in the ui/designs/ collection (ecomm#8). Also ignore .DS_Store. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
142 lines
6.0 KiB
React
142 lines
6.0 KiB
React
// wf-landing.jsx — Screen 1: Landing (PUC-1). Two directions.
|
|
const { Screen: LScreen, Wordmark: LWordmark, TopBar: LTopBar, Footer: LFooter, WF_T: LT, WF_DS: LDS } = window;
|
|
const { Button: LButton, Soul: LSoul, Eyebrow: LEyebrow } = LDS;
|
|
|
|
function LogInLink({ size = 14 }) {
|
|
return <a href="#" style={{
|
|
fontFamily: LT.disp, fontWeight: 500, fontSize: size, color: LT.star,
|
|
textDecoration: 'none', textUnderlineOffset: 3,
|
|
}}>Log in</a>;
|
|
}
|
|
|
|
function LandingValue({ device }) {
|
|
const desktop = device === 'desktop';
|
|
return (
|
|
<>
|
|
<LEyebrow style={{ margin: '0 0 18px' }}>One storefront, fully yours</LEyebrow>
|
|
<h1 style={{
|
|
fontFamily: LT.disp, fontWeight: 700, letterSpacing: '-0.015em', lineHeight: 1.04,
|
|
fontSize: desktop ? 'var(--text-h1)' : 30, color: LT.star, margin: '0 0 20px',
|
|
}}>Sell online,<br />honestly.</h1>
|
|
<p style={{
|
|
fontFamily: LT.body, fontSize: desktop ? 18 : 15.5, lineHeight: 1.6, color: LT.soft,
|
|
maxWidth: 460, margin: '0 0 30px',
|
|
}}>
|
|
Claim your storefront on a platform that takes only what it takes to run —
|
|
no trial countdown, no plan wall, no data you didn't agree to give.
|
|
</p>
|
|
</>
|
|
);
|
|
}
|
|
|
|
// ── Direction A — Quiet centered ───────────────────────────────────────────
|
|
function LandingA({ device = 'desktop' }) {
|
|
const desktop = device === 'desktop';
|
|
return (
|
|
<LScreen starfield>
|
|
<LTopBar pad={desktop ? '0 40px' : '0 22px'}
|
|
left={<LWordmark size={desktop ? 26 : 22} />} right={<LogInLink />} />
|
|
<div style={{
|
|
flex: 1, display: 'flex', flexDirection: 'column',
|
|
alignItems: desktop ? 'center' : 'flex-start', justifyContent: 'center',
|
|
textAlign: desktop ? 'center' : 'left',
|
|
padding: desktop ? '0 40px' : '0 24px',
|
|
}}>
|
|
<div style={{ maxWidth: 560, display: 'flex', flexDirection: 'column', alignItems: desktop ? 'center' : 'flex-start' }}>
|
|
<div style={{ display: 'contents' }}><LandingValue device={device} /></div>
|
|
<div style={{ display: 'flex', flexDirection: 'column', alignItems: desktop ? 'center' : 'stretch', gap: 16, width: desktop ? 'auto' : '100%' }}>
|
|
<LButton variant="primary" href="#">Create your storefront →</LButton>
|
|
<a href="#" style={{ fontFamily: LT.body, fontSize: 14, color: LT.mute, textDecoration: 'none', textAlign: desktop ? 'center' : 'left' }}>
|
|
Already selling with us? <span style={{ color: LT.lilac }}>Log in</span>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<LFooter />
|
|
</LScreen>
|
|
);
|
|
}
|
|
|
|
// ── Direction B — Durable frame (split) ────────────────────────────────────
|
|
function LandingB({ device = 'desktop' }) {
|
|
const desktop = device === 'desktop';
|
|
if (!desktop) {
|
|
return (
|
|
<LScreen>
|
|
<BrandRailLite />
|
|
<div style={{ flex: 1, padding: '28px 24px', display: 'flex', flexDirection: 'column', justifyContent: 'center' }}>
|
|
<LandingValue device={device} />
|
|
<Doors />
|
|
</div>
|
|
<LFooter />
|
|
</LScreen>
|
|
);
|
|
}
|
|
return (
|
|
<LScreen style={{ flexDirection: 'row' }}>
|
|
<aside style={{
|
|
flex: '0 0 44%', background: `${window.WF_STARFIELD}, var(--wv-night)`,
|
|
borderRight: `1px solid ${LT.hair}`, padding: '44px 46px',
|
|
display: 'flex', flexDirection: 'column', justifyContent: 'space-between', overflow: 'hidden',
|
|
}}>
|
|
<LWordmark size={28} />
|
|
<div style={{ maxWidth: 380 }}>
|
|
<LSoul size="lg" tone="gold" as="p">Treat humans as humans —<br />everything else follows.</LSoul>
|
|
<p style={{ fontFamily: LT.body, fontSize: 15, lineHeight: 1.6, color: LT.mute, marginTop: 22 }}>
|
|
Honest commerce on one shared set of ethics. Your storefront is yours — to keep, to leave, to own.
|
|
</p>
|
|
</div>
|
|
<div style={{ display: 'flex', alignItems: 'center', gap: 10, fontFamily: LT.body, fontSize: 12, color: LT.mute }}>
|
|
<span style={{ width: 22, height: 1, background: LT.hair }} />
|
|
<span>A Wiggleverse line · Open Core</span>
|
|
</div>
|
|
</aside>
|
|
<div style={{ flex: 1, display: 'flex', flexDirection: 'column', justifyContent: 'center', padding: '0 70px' }}>
|
|
<LandingValue device={device} />
|
|
<Doors />
|
|
</div>
|
|
</LScreen>
|
|
);
|
|
}
|
|
|
|
function BrandRailLite() {
|
|
return (
|
|
<div style={{
|
|
background: `${window.WF_STARFIELD}, var(--wv-night)`, borderBottom: `1px solid ${LT.hair}`,
|
|
padding: '24px 24px 26px', display: 'flex', flexDirection: 'column', gap: 14,
|
|
}}>
|
|
<LWordmark size={22} />
|
|
<LSoul size="sm" tone="gold">Your storefront is yours.</LSoul>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function Doors() {
|
|
return (
|
|
<div style={{ display: 'flex', flexDirection: 'column', gap: 14, maxWidth: 440 }}>
|
|
<DoorRow primary title="Create your storefront"
|
|
desc="New here? Set up the one storefront that's yours." cta="Get started →" />
|
|
<DoorRow title="Log in"
|
|
desc="Already selling with us? Pick up where you left off." cta="Log in →" />
|
|
</div>
|
|
);
|
|
}
|
|
function DoorRow({ primary, title, desc, cta }) {
|
|
return (
|
|
<a href="#" style={{
|
|
display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 16,
|
|
padding: '18px 20px', borderRadius: 14, textDecoration: 'none',
|
|
background: primary ? 'rgba(244,199,107,.08)' : 'var(--wv-indigo)',
|
|
border: `1px solid ${primary ? 'var(--wv-gold-40)' : LT.hairCard}`,
|
|
}}>
|
|
<div>
|
|
<div style={{ fontFamily: LT.disp, fontWeight: 500, fontSize: 17, color: LT.star, marginBottom: 3 }}>{title}</div>
|
|
<div style={{ fontFamily: LT.body, fontSize: 13.5, color: LT.mute, lineHeight: 1.45 }}>{desc}</div>
|
|
</div>
|
|
<span style={{ fontFamily: LT.disp, fontWeight: 500, fontSize: 14, color: primary ? LT.gold : LT.lilac, whiteSpace: 'nowrap' }}>{cta}</span>
|
|
</a>
|
|
);
|
|
}
|
|
|
|
Object.assign(window, { LandingA, LandingB });
|