diff --git a/docs/superpowers/specs/2026-08-03-frontend-visual-overhaul-design.md b/docs/superpowers/specs/2026-08-03-frontend-visual-overhaul-design.md new file mode 100644 index 0000000..f77112e --- /dev/null +++ b/docs/superpowers/specs/2026-08-03-frontend-visual-overhaul-design.md @@ -0,0 +1,84 @@ +# Braids by Mira — Frontend Visual Overhaul Design + +## Context + +The Phase 1 public site (Home, Shop, Book, Rules) is functionally complete and passed final review, but the visual result is flat: the hero is a plain gradient circle standing in for "3D," no product/service images ever render even though the data model already carries `image` fields, sections have large dead whitespace gaps, and Book/Rules are plain text stacks with little visual hierarchy. This spec covers a full visual/motion pass across all four existing pages before Phase 2 (backend/admin) work begins. It does not add new pages, routes, or data — it makes the existing structure look and feel like the "Elegant Editorial" design intended in the Phase 1 spec. + +## Scope + +All four existing routes (`/`, `/shop`, `/book`, `/rules`) get a visual/motion upgrade. The cream/charcoal/gold palette and Georgia/script typography from the original design system are unchanged — this is a richness and polish pass, not a rebrand. The single biggest addition is a real WebGL 3D hero centerpiece, scoped to the Home page only. + +## Tech Stack Additions + +- `three`, `@react-three/fiber`, `@react-three/drei` — for the 3D hero scene. These are only imported from Home's hero component, so Vite's route-level code splitting keeps them out of the Shop/Book/Rules bundles. +- No other new dependencies. Motion elsewhere continues to use the existing `framer-motion` setup (`ScrollReveal`, `useReducedMotion`, `useScroll`/`useTransform`). + +## 3D Hero Scene + +`Hero3DScene` replaces the current `Hero3D` component on the Home page hero: + +- A `` (react-three-fiber) containing a procedural braided-crown mesh: 5–7 strands built from `TubeGeometry` following `CatmullRomCurve3` paths, arranged radially in a crown silhouette (abstract, not a literal recreation of the logo). +- Material: gold `MeshStandardMaterial` (color sampled from the `--color-gold` token), lit by one soft key light and one rim light for depth. +- Motion: continuous gentle Y-axis rotation via `useFrame`, plus additional tilt driven by scroll position (same scroll-linked approach the current `Hero3D` already uses via `useScroll`/`useTransform`, applied to the group's rotation instead of a CSS transform). +- `prefers-reduced-motion`: skip mounting the `` entirely and render the existing static gradient-circle fallback — this both respects the motion preference and avoids the WebGL cost for those users. +- The canvas is `aria-hidden="true"` since it's decorative; the hero's headline text carries the actual accessible content, consistent with the current `Hero3D` pattern. +- No 3D asset pipeline is introduced — the mesh is built entirely from code (primitive geometry + curves), so there's no `.glb`/`.gltf` file to source, store, or version. + +## Imagery + +AI-generated placeholder photography, saved as static files under `public/`, sized reasonably for web (not full-res) with no optimization pipeline beyond that — matches Phase 1's "no backend" scope: + +- `public/products/*.jpg` — one image per product (10 total), clean product-on-neutral-background style consistent with the cream/charcoal palette. +- `public/styles/*.jpg` — one image per signature style (4 total: knotless, boho, locs, cornrows), on-model shots. +- `public/about/mira-portrait.jpg` — one warm editorial-style portrait for Home's About section. +- `public/testimonials/*.jpg` — three small circular avatar images, one per testimonial. + +No changes to the `Product`/`Service` TypeScript interfaces — both already carry an `image: string` field from Phase 1; this work only points those fields at real generated files and wires the field into rendering, which never happened in Phase 1. + +**Component changes:** +- `ProductCard` and `ServiceCard` render `product.image`/`service.image` in a fixed-aspect-ratio image region above the existing text content, with a subtle hover-zoom (`transform: scale(1.05)` on hover, matching the existing hover-lift pattern already used elsewhere). +- Home's About section gets the portrait image next to (or behind, TBD at implementation time based on what reads best) the existing bio text. +- Home's testimonial blocks get the small avatar images next to each quote. + +## Page-by-Page Changes + +### Home +- Reduce dead whitespace between sections — current `ScrollReveal` sections leave large gaps; tighten section padding/margins so content reads as continuous rather than isolated islands. +- About section gains the portrait image. +- Signature Styles cards (already `ServiceCard`) gain real images via the imagery work above. +- Shop Highlights cards gain real images and upgrade from bare `
`s to using `ProductCard` styling (or an equivalent lightweight card) for visual consistency with the Shop page. +- Add a subtle parallax offset between text and background layers on scroll (background sections drift slightly slower than foreground text, via `useScroll`/`useTransform`, same toolkit already in use). + +### Shop +- `ProductCard` images (from Imagery section above) with hover-zoom. +- Tighten grid spacing/card padding for a less sparse layout. +- Category filter pills: replace the static active-color swap with a `framer-motion` `layoutId` sliding indicator so the active pill's highlight animates smoothly between filter clicks. + +### Book +- Add a visual step-progress indicator (4 steps: Service, Date & Time, Contact, Confirmed) shown as labeled dots/segments at the top of the flow, reflecting `useBooking`'s current `step` state. +- Service picker cards (`ServiceCard`) gain images via the imagery work above. +- Animate transitions between steps with `framer-motion` (slide/fade) instead of the current instant swap. + +### Rules +- Add a simple inline SVG icon per rule section (deposit, cancellation/lateness, guests & kids, hair prep, health & safety) — small, monochrome, matching the charcoal/gold palette, no icon library dependency. +- Tighten typography rhythm (spacing between title/body, section-to-section spacing). +- Stagger each rule section's entrance on scroll (extend the existing `ScrollReveal` usage with per-item delay). + +## Testing + +- `Hero3DScene` gets a test mirroring the current `Hero3D.test.tsx` pattern: asserts a `` (or its container) renders when motion is allowed, and that the static fallback renders under `prefers-reduced-motion` — WebGL internals (the actual 3D rendering) are not unit-tested, only the mount/fallback contract, consistent with how the current component is tested. +- `ProductCard`/`ServiceCard` tests are extended to assert the image renders with the correct `src` and `alt` text (derived from `product.name`/`service.name`). +- No new test infrastructure needed — same Vitest + React Testing Library setup as Phase 1. + +## Performance & Accessibility + +- `three`/`@react-three/fiber`/`@react-three/drei` are only imported from Home's hero, so they don't inflate the Shop/Book/Rules bundles (Vite's existing route-based code splitting handles this without additional configuration). +- All images get descriptive `alt` text sourced from existing product/service names — no new copy needed. +- The 3D canvas is `aria-hidden="true"`; reduced-motion users get the existing static fallback instead of a spinning WebGL scene. + +## Out of Scope + +- Real photography from Mira (placeholder AI imagery is used throughout; swapping to real photos later is just replacing files in `public/`, no code changes). +- 3D treatment anywhere beyond the Home hero (product cards, other pages) — explicitly hero-only per this spec. +- Any Phase 2 concerns: backend, admin panel, real booking/inquiry submission, image upload/management — unchanged from the Phase 1 spec's scope boundary. +- Rebranding the color palette or typography — this is a richness pass on the existing "Elegant Editorial" system, not a new visual identity.