Files
braidsbymira/docs/superpowers/specs/2026-08-03-braids-by-mira-phase1-design.md
2026-08-03 16:14:48 +00:00

6.9 KiB

Braids by Mira — Phase 1 Design (Public Site)

Context

Braids by Mira is a beauty salon (braiding/protective styles) needing a full web presence: a marketing site with a product showcase and booking, plus an admin panel for the owner to manage products and availability. This spans two independent subsystems — a public frontend and a backend-driven admin/booking system — so the project is split into two phases:

  • Phase 1 (this spec): public-facing site — landing page, product showcase, booking flow (UI only, mock data), and a rules/policies page. No backend yet.
  • Phase 2 (future spec): real backend (auth, database, storage) powering admin product/availability management and live bookings, wired into the Phase 1 UI.

Brand identity: logo is a crown/hair silhouette on cream, in charcoal linework, tagline "Your hair, your crown." Visual direction chosen: Elegant Editorial — cream/charcoal/antique-gold palette, serif labels with a script headline accent, quiet-luxury boutique feel. Motion direction: rich scroll storytelling (parallax/reveal-on-scroll, a 3D rotating hero motif, hover-lift tilt cards).

Tech Stack

  • Existing scaffold: Vite + React 19 + TypeScript — kept as-is
  • react-router for client-side routing across 4 pages
  • Framer Motion (motion) for scroll-driven reveals, parallax, and hover micro-interactions
  • Plain CSS (CSS variables + co-located CSS modules per component) — no utility framework, to keep the custom editorial typography and palette hand-tuned
  • Mock data in typed local modules under src/data/, shaped so Phase 2 can swap them for real API calls (e.g. Supabase) with minimal rework
  • Vitest + React Testing Library for unit/component tests (Vite-native, no separate config needed)

Visual System

  • Palette: cream #F7F3EC (primary background), #EFE7D8 (secondary/alternating section background), charcoal #3A332E (ink/text), antique gold #B08D57 (accent)
  • Type: Georgia/serif for labels, nav, and body copy; an elegant script webfont (e.g. Google Fonts "Great Vibes" or similar) for hero/section headline moments only — used sparingly, not for body text
  • Motion:
    • Scroll-linked reveals (fade + rise) on section entrance via a shared ScrollReveal wrapper (Framer Motion whileInView)
    • Hero motif: a rotating/tilting 3D element built with CSS 3D transforms (not a full WebGL/Three.js scene) — reacts to scroll position, stays lightweight
    • Hover-lift tilt on product/style cards
    • Staggered entrance for card grids/lists
    • All motion respects prefers-reduced-motion: reveals degrade to instant fades, hero motif skips continuous rotation

Pages & Routing

Shared Nav (logo + route links, condenses on scroll) and Footer (contact, socials, hours) wrap all routes.

/ — Home

  1. Hero — 3D rotating motif, script headline ("Your hair, your crown"), CTAs to Book / Shop
  2. About Mira — short intro + portrait, fade-in on scroll
  3. Signature Styles — horizontal tilt-card row of services (Knotless, Boho, Locs, Cornrows); each card deep-links to /book with that service preselected (via router state)
  4. Shop Highlights — 3-4 featured products with hover-lift tilt, "Shop All" → /shop
  5. Client Love — rotating testimonial quotes
  6. Before You Book — dark charcoal banner nudging visitors to read /rules before booking
  7. Footer

/shop — Product Showcase

  • Grid of products, filterable by category (hair-care, extensions, tools, accessories)
  • Each card hover-tilts; click opens a detail view/modal (image, price, description)
  • No cart or checkout in Phase 1 — instead an "Ask about this" action opens an inquiry modal (product prefilled, contact fields, notes) ending in a styled confirmation screen. No backend call yet; UI is shaped for a Phase 2 wire-up.
  • Products with inStock: false show an "unavailable" badge and disable inquiry.

/book — Booking

Flow, driven by a single useBooking hook (local component state — no global store needed at this scope):

  1. Select a service (from mock services data; preselected if arriving via a Home deep link)
  2. Select a date
  3. Select an available time slot (from mock availability data for that date; if none available, show a friendly empty state suggesting the next available date)
  4. Enter contact info (name, phone, email, notes) with inline validation; "Confirm" disabled until a slot is picked and required fields are valid
  5. Styled confirmation screen (no real email/backend submission yet)

/rules — Salon Rules & Policies

  • Editorial-styled policy content: deposit, cancellation/lateness, guests & kids, hair prep instructions, health & safety
  • Placeholder copy drafted to be realistic and directly editable later (not Mira's verbatim wording yet)
  • "By booking you agree to these terms" note + CTA back to /book

Data Model (mock, Phase-2-ready shapes)

// src/data/products.ts
interface Product {
  id: string;
  name: string;
  category: 'hair-care' | 'extensions' | 'tools' | 'accessories';
  price: number;
  image: string;
  description: string;
  inStock: boolean;
}

// src/data/services.ts
interface Service {
  id: string;
  name: string;            // "Knotless Braids"
  durationMinutes: number;
  priceFrom: number;
  description: string;
  image: string;
}

// src/data/availability.ts
interface TimeSlot {
  date: string;   // ISO date
  time: string;   // "10:00 AM"
  available: boolean;
}

File Structure

src/
  components/
    Nav.tsx / Footer.tsx
    Hero3D.tsx           # rotating/tilting motif
    ScrollReveal.tsx      # Framer Motion whileInView wrapper
    ProductCard.tsx / ServiceCard.tsx
    InquiryModal.tsx
  pages/
    Home.tsx / Shop.tsx / Book.tsx / Rules.tsx
  data/
    products.ts / services.ts / availability.ts / rules.ts
  hooks/
    useBooking.ts
  styles/
    tokens.css            # palette + type scale as CSS variables
    (co-located *.module.css per component)
  App.tsx                 # router setup

Error Handling & Edge Cases

  • Booking form: inline validation on required fields and phone/email format; "Confirm" stays disabled until valid
  • No slots available for a chosen date → friendly empty state, suggest next available date computed from mock availability data
  • Out-of-stock products: disabled inquiry action, visible badge
  • Reduced-motion users get instant-fade equivalents instead of full parallax/rotation

Testing

  • Vitest + React Testing Library for component/unit tests: booking flow state transitions, form validation, product filtering/empty states
  • No E2E framework in Phase 1 (manual dev-server verification is sufficient for a marketing site at this stage); revisit with Playwright if Phase 2's live booking flow needs it

Out of Scope (Phase 1)

  • Admin panel, authentication, and any real backend/database/storage — Phase 2
  • Real booking submission (email/SMS/notification) — Phase 2
  • Cart/checkout/payments
  • Mira's verbatim rules text (placeholder copy used instead)