offplan · online
Session · conv-29

Session CONV-29

In Progresssessionconv-29

Resume Prompt

Continue porting the offplan.online sales-presentation surface from HTML to React. Path 2 scaffold is live at os/design-system/sales-app/ (Next 16 + Tailwind v4 + shadcn/ui + Storybook 10 + Pannellum). Foundation is shipped + 2 of 7 modules ported (top-bar, info-panel) with stories. Next: port buyer-profile (the slide-in drawer with persona form + prefs chips + saved-units list + send-summary + agent-login), then exterior-360 (Pannellum dynamic-import in a 'use client' component, see docs/next16-tailwind4-notes.md), then hotspot / poi-detail / project-tour, then compose screen 02 at app/exterior/page.tsx. First action: start dev servers (./node_modules/.bin/next dev to bypass pnpm install pre-check, pnpm storybook) and copy Riviera imagery from Dropbox per design-system/sales-app/README.md setup section. The HTML reference is os/design-system/sales/02-exterior.html — port its visual design into features/exterior-360/Exterior360.tsx. Task list (#5-13) tracks remaining work.

Summary

Massive arc: started as "implement the design system bundle" → audited 4 live Volume Vision sales sites (tapestry/pipis/cote/lagoon) to ground the redesign → captured Nadezhda's 2026-05-08 client-feedback transcript (real Dubai developer) which shifted the IA from "building-with-dots" to "360° project hero + floorplate-first selection + buyer profile" → built four iterations of the Exterior screen as HTML mockups (v1 → v4 with Pannellum + real Riviera 360° aerial + buyer profile slide-in panel) → strategic conversation about modular architecture → Roman approved Path 2 (production React stack) → scaffolded Next.js 16 + Tailwind v4 + shadcn/ui + Storybook 10 + Pannellum → ported top-bar + info-panel modules with stories. Both Storybook (:6006) and Next.js (:3000) running clean. 5 feature modules + screen-02 compose + Code Connect to Figma still ahead.

Changes

Inputs gathered (read-only)

UX audit of live product (4 sites + 1 dead)

Client research

Plan ratified

Path 1 — HTML mockups (4 iterations of screen 02)

Path 2 — Next.js scaffold (canonical going forward)

Memory captured

Gitignore

Decisions

Path 2 over Path 1 — production React stack. Roman explicitly chose Path 2 ("Next.js + TS + Tailwind + shadcn/ui + Storybook + Code Connect — best SaaS approach"). Path 1 (HTML mockups) was completed through v4 of screen 02 with full interactions including profile slide-in panel. Path 2 is the canonical going-forward track. HTML files at os/design-system/sales/ kept as visual reference for the port — do not extend them.

Modular architecture at FEATURE level (Roman's framing) plus PRIMITIVES level. Roman's instinct: "buyer profile = one module, exterior 360° = another module, hotspots maybe their own module so they work standalone, top bar = its own module, project tour = its own module". Confirmed correct — that's exactly how senior frontend teams cut. Two-tier structure: features/<name>/ for behaviour-owning modules (top-bar, buyer-profile, exterior-360, hotspot, info-panel, poi-detail, project-tour); components/ui/ for shadcn primitives (Button, Sheet, Dialog, Input, etc.). Composition: screens/<route>/page.tsx is a thin file dropping in features.

Top-right is a SINGLE profile button, not dual chips. First implementation had two chips (agent + buyer); Roman rejected: "no, this needs to be only a single button like a profile". Correct shape: one Profile pill (icon → initials when set) opens a slide-in panel containing persona form (firstname/lastname/phone/email) + preferences (multi-select chips for beds/baths/parking/aspect + price range) + saved units list + primary "Send summary email" button + secondary "Agent login" link at the bottom. Agent identity is implicit / accessed from inside the panel.

Single canonical brandbook. Bundle's reference/brandbook-v2.html is byte-identical to local docs/brandbook/v2.html (SHA d1ba831b...). The "Hybrid Calatrava" handoff is NOT a new direction — it's the same brandbook the team's been using, packaged with colors_and_type.css tokens. No migration needed; both surfaces canonical.

Sergei's os/docs/mockups/sales-app-atelier.html (6587 lines) is NOT canonical. Roman: "a lot of this is Sergei doing, I'm not 100% happy with it. Go off the designs currently that I input in this latest conversation, then we will design our own version of the front end app." Drift evidence: uses Cormorant Garamond display vs bundle's Helvetica Neue; gold + glass-panel direction vs bundle's austere Skeleton White. Treat as historical reference only; do not extend or synthesise from it.

CRM scope = front-end UX only (option A). Roman locked: "design the buyer-facing surface — 360° hero, floorplate-first selection, buyer profile capture, persistent profile chip, save-to-profile flow, offer generation screen. CRM signals are stubbed (a clean POST contract with payload examples, ready for backend wiring later). No broker auth, no Microsoft SSO, no admin-side." Per-screen stubs use console.log('crm:event', { type, ... }) until the contract spec lands.

Path 1 v4 vs Path 2 — what survived. All visual decisions from HTML v4 ported to Path 2 token system. JS state-management replaced by React useState/controlled props. Pannellum integration pattern: 'use client' + dynamic import() inside useEffect (per Next 16 docs cheatsheet). Hotspot positions, scrim opacity, atmospheric scrim gradient, info-panel layout — all preserved.

Riviera Residences as the reference project (not Côte). Project 438. Roman provided real production CGI: 17.8 MB 360° aerial + 12 WEB renders (lobby, pool, beach, promenade, paddle court, podium lounge, yoga, sky-villa terrace, ocean-villa terrace, family pavilion). Two cascading towers, marina edge, 240 residences, fifteen sky villas, Q4 2028 handover. Project accent muted teal-blue #4A7387.

Next Steps

  1. Restart dev servers + copy Riviera imagery from Dropbox per design-system/sales-app/README.md setup section. The imagery is gitignored so a fresh clone needs the copy.
  2. Port buyer-profile — biggest module. Use os/design-system/sales/02-exterior.html lines covering .profile-panel as the visual reference. Build with shadcn Sheet primitive (slide-in drawer, accessibility for free). Stories: empty / persona-only / persona+prefs / with 1 saved unit / with 5 / send-enabled / send-disabled / agent-empty / agent-set.
  3. Port exterior-360'use client' component with dynamic import of Pannellum inside useEffect (see docs/next16-tailwind4-notes.md for the exact pattern). Receives panorama URL + hotspot list as props. Stories: loaded / loading / paused.
  4. Port hotspot — ring marker + tooltip; consumed by exterior-360 via Pannellum's cssClass mechanism. Variants: in (always-labelled) / soft (inward, hover-only) / out (square ornament, hover-only).
  5. Port poi-detail — slide-in card from hotspot click; image + eyebrow + name + copy + CTA. Build with shadcn Sheet again (right side). Stories: inward (Enter 360°) / outward (View on map).
  6. Port project-touruseProjectTour() hook + a <TourTrigger> button. Hook orchestrates auto-pan + auto-open-POI. Stories: idle / running / interrupted.
  7. Compose screen 02 at app/exterior/page.tsx — drop in TopBar + Exterior360 + InfoPanel + BuyerProfile + ProjectTour + PoiDetail. Verify visual parity with os/design-system/sales/screenshots/02-exterior-v4-default.png.
  8. Wire Code Connect to Figma — per-module .figma.ts files mapping our React components to Figma component IDs. This requires Sergei to first create the matching Figma frames; for now scaffold the boilerplate.

Open Questions

Context for next session