# Wardrobe Web v3 — Commerce-Grade Design Spec (Fable ideation 2026-08-13. Executors: follow exactly; where silent, match GOAT/Grailed conventions. HARD CONSTRAINTS at bottom are law.) ## Direction From "editorial catalog file" to "premium resale-app commerce". Reference: GOAT (image-forward dark product grid, sticky buy CTA, quiet chrome), Grailed (dense grid, brand-first cards, utilitarian type). Imagery becomes the interface; chrome recedes. ## Tokens (replace current :root blocks; keep BOTH themes, DARK IS DEFAULT) Dark (default): --bg #121310 · --surface #1B1C19 · --surface2 #232420 · --ink #F2F0EA · --muted #9A978C · --line rgba(255,255,255,0.07) · --olive #A3AB79 · --indigo #96A8CC · --caution #D0A468 · --shadow 0 4px 24px rgba(0,0,0,0.45) Light: --bg #F6F5F1 · --surface #FFFFFF · --surface2 #EFEEE8 · --ink #191813 · --muted #6B685F · --line rgba(0,0,0,0.08) · --olive #57603F · --indigo #33415E · --caution #8A5A2B · --shadow 0 4px 20px rgba(0,0,0,0.08) Media-query prefers-color-scheme LIGHT overrides dark default; data-theme attrs override both (existing pattern, inverted priority). Radius: --r 12px (cards/sheets/pills), buttons 8px. NO hairline borders on cards — elevation via --shadow + surface contrast only. Hairlines remain ONLY inside sheets as dividers (--line). ## Type - UI: -apple-system, "SF Pro Text", "Helvetica Neue", sans-serif. Scale: 11 / 13 / 15 / 17 / 22 / 34. Weights 400/600/700. - Display (brand + section titles only): keep Futura stack, 700, caps, tracking 0.04em. No more full-caps body labels. - Prices + badges stay ui-monospace 12px 600 (commerce signature). ## Layout 1. APP BAR (sticky top, z50, bg --bg at 92% + backdrop-blur 12px): left: "WARDROBE WEB" Futura 15px caps. center: search input (flex-1, max 420px, pill --surface2, magnifier via CSS mask not emoji, placeholder "Search 145 pieces"). right: liked tally pill + profile initial circle (existing profbar functions relocate here). 2. NAV RAILS under app bar (sticky, two rows, horizontal scroll, no-scrollbar): Row A category pills: ALL, TEES, KNITS, SHIRTS, BOTTOMS, OUTERWEAR, FOOTWEAR, ACC — new filter dimension: sets curCat, board shows single flat grid filtered by it (cat-heads REMOVED in flat mode; ALL keeps section heads). Row B lane pills = existing data-f chips restyled (keep data-f attrs + logic; visual: pill --surface2, active = --ink bg with --bg text). "Swipe to train" becomes a Row B pill-button, olive filled. 3. HERO RAIL (replaces Today's Fit + Build sections' vertical stack): one horizontal snap-scroll rail of cards (height ~180px): card 1 "TODAY'S FIT" (ootd chips condensed, tap→existing behavior), card 2 "THE BUILD" (invested $ big, 4 mini progress bars, NEXT UP thumb), card 3 "TASTE TRAINER" (CTA card, N unrated, opens swipe). Cards: --surface, --r, --shadow, 300px wide each. 4. BOARD GRID: repeat(auto-fill, minmax(164px, 1fr)), gap 14px 20px. CARD: no border; image block aspect 1/1.25, --r top, bg --surface2, img cover; badge = overlay pill top-left (mono 9px, blurred bg); SALE/RESTOCK/OFF-SEASON = overlay pill top-right; below: brand 10px 600 caps --muted, name 13px 2-line clamp, price row (mono; was struck). Hover (pointer:fine): translateY(-4px)+shadow deepen+img scale 1.04 (overflow hidden), 200ms. LIKED state: 2px olive ring + tiny pill. Remove per-card "buy ↗" (moves to sheet). Card click → sheet (existing select()). 5. PRODUCT SHEET (restyle #fcard): desktop = right-anchored panel 440px, full height, slide-in 240ms, board dims behind (webmode stays; lines still draw to visible board area). mobile = full-screen sheet. Structure: image 55% height (contain, --surface2 bg); content: brand caps muted / name 22px 700 / why 15px muted / price row 17px mono (+was) / segmented mark row (LIKE·PASS·OWN equal thirds, --surface2 track, active fills) / BUILD A FIT secondary button / "PAIRS WITH" horizontal thumb rail (partners, tap re-centers) / sticky bottom CTA: full-width olive button "BUY AT {RETAILER} — $X" (extract retailer from URL hostname map). Close: top-right circle button + Esc + backdrop tap. 6. FORMULAS BOTTOM SHEET (restyle #panel): snap heights 40vh; rows become horizontal cards (formula name 11px caps + thumb strip); keep ids/DOM hooks (plist, ptitle, pclose). 7. SWIPE: card radius --r, shadow, buttons become 3 circles (56px: pass=outline caution X-glyph via CSS, skip small, like=olive filled check-glyph via CSS mask/pseudo — NO emoji); progress "N rated" as thin olive bar atop overlay. 8. BOARDS (themes.py CSS): same tokens/card treatment, dark default. 9. Micro: skeleton shimmer on .pimg while loading (CSS gradient anim, reduced-motion off); all transitions 200ms ease-out; focus-visible rings --indigo everywhere. ## HARD CONSTRAINTS (violating any = failed task) - DO NOT rename/remove ids or data-attrs used by JS: board, fcard, panel, plist, ptitle, pclose, ootd, ootddate, buildtrack, toolbar, q, likedtotal, exportbtn, profbar, swipe/swcard/swcount/swclose/swpass/ swlike/swskip/swipebtn, aibtn/aichat/aimsgs/aiform/aiq/aiclose, ob/obwrap, fchip[data-f], .card/.thumb/.pimg/.img-* classes, likemark/ ownmark, fit-strip/fit-thumb, o-thumb/o-chip/o-name/p-outfit. - DO NOT touch