Files
wiggleverse-ecomm-content/ui/designs/ecomm-login-and-create-storefront-designs/project/wf-storefront.jsx
T
ben.stull afe36fd347 add ui design ./ui/designs/ecomm-login-and-create-storefront-designs/
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>
2026-06-10 21:53:43 -07:00

118 lines
6.1 KiB
React

// wf-storefront.jsx — Screen 3: Create storefront (PUC-4/5/7). A/B + states.
const { Screen: FScreen, Wordmark: FWordmark, TopBar: FTopBar, AccountChip: FAccountChip,
Field: FField, Banner: FBanner, AuthCard: FAuthCard, StateBlock: FStateBlock,
WF_T: FT, WF_DS: FDS } = window;
const { Button: FButton, Soul: FSoul, Eyebrow: FEyebrow } = FDS;
function CreateForm({ s = {} }) {
return (
<>
<div>
<FEyebrow style={{ margin: '0 0 12px' }}>One storefront, fully yours</FEyebrow>
<h1 style={{ fontFamily: FT.disp, fontWeight: 700, letterSpacing: '-0.015em', fontSize: 26, color: FT.star, margin: '0 0 8px', lineHeight: 1.1 }}>Create your storefront</h1>
<p style={{ fontFamily: FT.body, fontSize: 14.5, lineHeight: 1.5, color: FT.soft, margin: 0 }}>
This is the one thing to do right now. Nothing here costs anything or commits you to anything.
</p>
</div>
{s.alreadyOwns && <FBanner title="Your account already has its storefront">
ecomm is one storefront per account today. <a href="#" style={{ color: FT.lilac, textDecoration: 'none' }}>Go to your admin </a>
</FBanner>}
<FField label="Storefront name" optional
placeholder="e.g. Studio Fern" value={s.name}
helper="You can leave this blank — we'll pick a placeholder name you can change later." />
{s.blankPreview && (
<div style={{ display: 'flex', alignItems: 'center', gap: 9, marginTop: -6, fontFamily: FT.body, fontSize: 13, color: FT.mute }}>
<span aria-hidden="true" style={{ color: FT.lilac }}></span>
Saves as <span style={{ color: FT.soft, fontStyle: 'italic', fontFamily: FT.body }}>mara's storefront”</span> — change it any time.
</div>
)}
<FButton variant="primary" href="#" disabled={s.creating}>
{s.creating ? 'Creating' : 'Create storefront'}
</FButton>
</>
);
}
// ── Direction A — centered card ────────────────────────────────────────────
function CreateA({ device = 'desktop', s = {} }) {
const desktop = device === 'desktop';
return (
<FScreen starfield>
<FTopBar pad={desktop ? '0 32px' : '0 18px'} left={<FWordmark size={desktop ? 24 : 21} />}
right={desktop ? <FAccountChip /> : <SignOutMini />} />
<div style={{ flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: desktop ? 32 : 18 }}>
<FAuthCard width={desktop ? 440 : '100%'}><CreateForm s={s} /></FAuthCard>
</div>
</FScreen>
);
}
// ── Direction B — split (the frame begins to form) ─────────────────────────
function CreateB({ device = 'desktop', s = {} }) {
const desktop = device === 'desktop';
if (!desktop) {
return (
<FScreen>
<div style={{ background: `${window.WF_STARFIELD}, var(--wv-night)`, borderBottom: `1px solid ${FT.hair}`, padding: '20px 22px', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
<FWordmark size={21} />
<SignOutMini />
</div>
<div style={{ flex: 1, padding: '24px 22px', display: 'flex', flexDirection: 'column', gap: 20, justifyContent: 'center' }}>
<CreateForm s={s} />
</div>
</FScreen>
);
}
return (
<FScreen style={{ flexDirection: 'row' }}>
<aside style={{ flex: '0 0 44%', background: `${window.WF_STARFIELD}, var(--wv-night)`, borderRight: `1px solid ${FT.hair}`, padding: '40px 46px', display: 'flex', flexDirection: 'column', justifyContent: 'space-between', overflow: 'hidden' }}>
<FWordmark size={26} />
<div style={{ maxWidth: 360 }}>
<FSoul size="lg" tone="gold" as="p">Build the<br />dictionary first.</FSoul>
<p style={{ fontFamily: FT.body, fontSize: 14.5, lineHeight: 1.6, color: FT.mute, marginTop: 20 }}>
One storefront, claimed by you. The frame you see now is the one your catalog, orders and settings will live in.
</p>
</div>
<FAccountChip />
</aside>
<div style={{ flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: '0 64px' }}>
<div style={{ width: '100%', maxWidth: 420, display: 'flex', flexDirection: 'column', gap: 20 }}>
<CreateForm s={s} />
</div>
</div>
</FScreen>
);
}
function SignOutMini() {
return <button style={{ fontFamily: FT.disp, fontWeight: 500, fontSize: 13, color: FT.star, background: 'transparent', border: 'none', cursor: 'pointer', padding: 0 }}>Sign out</button>;
}
// ── States stack ───────────────────────────────────────────────────────────
function CreateStates() {
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: 22 }}>
<FStateBlock label="Blank name" note="allowed → default generated">
<div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
<FField label="Storefront name" optional placeholder="e.g. Studio Fern"
helper="Leave blank and we'll name it for you." />
<div style={{ display: 'flex', alignItems: 'center', gap: 9, fontFamily: FT.body, fontSize: 13, color: FT.mute }}>
<span aria-hidden="true" style={{ color: FT.lilac }}>◇</span>
Saves as <span style={{ color: FT.soft, fontStyle: 'italic' }}>“mara's storefront”</span>
</div>
</div>
</FStateBlock>
<FStateBlock label="Creating" note="button busy">
<FButton variant="primary" href="#" disabled>Creating…</FButton>
</FStateBlock>
<FStateBlock label="Already owns one" note="409 · defense in depth (PUC-7)">
<FBanner title="Your account already has its storefront">
ecomm is one storefront per account today. <a href="#" style={{ color: FT.lilac, textDecoration: 'none' }}>Go to your admin </a>
</FBanner>
</FStateBlock>
</div>
);
}
Object.assign(window, { CreateA, CreateB, CreateStates });